import datetime import re from pathlib import PurePath from src.config import Configuration from src.lib.artist import get_artist from src.lib.post import ( get_fileserver_for_value, get_post, get_post_comments, get_post_revisions, get_posts_incomplete_rewards, is_post_flagged, patch_inline_img, ) from src.lib.posts import Post from src.utils.utils import images_pattern, sanitize_html from flask import session video_extensions = Configuration().webserver["ui"]["video_extensions"] def ready_post_props(post: Post): service = post["service"] artist_id = post["user"] post_id = post["id"] if service in ("patreon",): if post["file"] and post["attachments"] and post["file"] == post["attachments"][0]: post["attachments"] = post["attachments"][1:] if service in ("fansly", "onlyfans"): posts_incomplete_rewards = get_posts_incomplete_rewards(post_id, artist_id, service) if posts_incomplete_rewards: post["incomplete_rewards"] = "This post is missing paid rewards from a higher tier or payment." if post["service"] == "onlyfans": try: rewards_info_text = ( f"{posts_incomplete_rewards["incomplete_attachments_info"]["media_count"]} media, " f"{posts_incomplete_rewards["incomplete_attachments_info"]["photo_count"]} photos, " f"{posts_incomplete_rewards["incomplete_attachments_info"]["video_count"]} videos, " f"for {posts_incomplete_rewards["incomplete_attachments_info"]["price"]}$." ) post["incomplete_rewards"] += "\n" + rewards_info_text except Exception: pass elif post["service"] == "fansly": try: rewards_info_text = ( f"Downloaded:{posts_incomplete_rewards["incomplete_attachments_info"]["complete"]} " f"Missing:{posts_incomplete_rewards["incomplete_attachments_info"]["incomplete"]}" ) post["incomplete_rewards"] += "\n" + rewards_info_text except Exception: pass previews = [] attachments = [] videos = [] if "path" in post["file"]: if images_pattern.search(post["file"]["path"]): previews.append( { "type": "thumbnail", "server": get_fileserver_for_value(f"/data{post["file"]["path"]}"), "name": post["file"].get("name"), "path": post["file"]["path"], } ) else: file_extension = PurePath(post["file"]["path"]).suffix name_extension = PurePath(post["file"].get("name") or "").suffix # filename without extension stem = PurePath(post["file"]["path"]).stem attachments.append( { "server": get_fileserver_for_value(f"/data{post["file"]["path"]}"), "name": post["file"].get("name"), "extension": file_extension, "name_extension": name_extension, "stem": stem, "path": post["file"]["path"], } ) if len(post.get("embed") or []): previews.append( { "type": "embed", "url": post["embed"]["url"], "subject": post["embed"]["subject"], "description": post["embed"]["description"], } ) for attachment in post["attachments"]: if images_pattern.search(attachment["path"]): previews.append( { "type": "thumbnail", "server": get_fileserver_for_value(f"/data{attachment["path"]}"), "name": attachment["name"], "path": attachment["path"], } ) else: file_extension = PurePath(attachment["path"]).suffix name_extension = PurePath(attachment.get("name") or "").suffix # filename without extension stem = PurePath(attachment["path"]).stem attachments.append( { "server": get_fileserver_for_value(f"/data{attachment["path"]}"), "name": attachment.get("name"), "extension": file_extension, "name_extension": name_extension, "stem": stem, "path": attachment["path"], } ) for i, attachment in enumerate(attachments): if attachment["extension"] in video_extensions: videos.append( { "index": i, "path": attachment["path"], "name": attachment.get("name"), "extension": attachment["extension"], "name_extension": attachment["name_extension"], "server": get_fileserver_for_value(f"/data{attachment["path"]}"), } ) if post.get("poll") is not None: post["poll"]["total_votes"] = sum(choice["votes"] for choice in post["poll"]["choices"]) post["poll"]["created_at"] = datetime.datetime.fromisoformat(post["poll"]["created_at"]) if post["poll"]["closes_at"]: post["poll"]["closes_at"] = datetime.datetime.fromisoformat(post["poll"]["closes_at"]) if (captions := post.get("captions")) is not None: for file_hash, caption_data in captions.items(): for preview_data in [preview for preview in previews if preview.get("path") == file_hash]: if isinstance(caption_data, dict): preview_data["caption"] = caption_data.get("text") or "" elif isinstance(caption_data, list): preview_data["caption"] = " ".join(each.get("text") or "" for each in caption_data) for video in [video for video in videos if video["path"] == file_hash]: if isinstance(caption_data, dict): video["caption"] = caption_data.get("text") or "" elif isinstance(caption_data, list): video["caption"] = " ".join(each.get("text") or "" for each in caption_data) props = { "service": service, "artist": get_artist(service, artist_id), "flagged": is_post_flagged(service, artist_id, post_id), "revisions": get_post_revisions(service, artist_id, post_id), } real_post = post if not post.get("revision_id") else get_post(service, artist_id, post_id) all_revisions = [real_post] + props["revisions"] for set_prev_next_revision in (post, *props["revisions"]): set_prev_next_revision["prev"] = real_post["prev"] set_prev_next_revision["next"] = real_post["next"] if props["revisions"]: last_date = real_post["added"] for i, rev in enumerate(all_revisions[:-1]): rev["added"] = all_revisions[i + 1]["added"] props["revisions"][-1]["added"] = last_date if real_post["service"] == "fanbox": top_rev_stripped = all_revisions[0].copy() top_rev_stripped.pop("file") top_rev_stripped.pop("added") top_rev_stripped.pop("revision_id", None) for fanbox_attachment in top_rev_stripped["attachments"]: if 41 >= len(fanbox_attachment["name"]) >= 39: fanbox_attachment.pop("name", None) for duplicated_check_rev in all_revisions[1:]: duplicated_check_rev_file_stripped = duplicated_check_rev.copy() duplicated_check_rev_file_stripped.pop("file") duplicated_check_rev_file_stripped.pop("added") duplicated_check_rev_file_stripped.pop("revision_id", None) for fanbox_attachment in duplicated_check_rev_file_stripped["attachments"]: if 41 >= len(fanbox_attachment["name"]) >= 39: fanbox_attachment.pop("name", None) if duplicated_check_rev_file_stripped == top_rev_stripped: all_revisions.remove(duplicated_check_rev) else: top_rev_stripped = duplicated_check_rev_file_stripped if isinstance(post["tags"], str): post["tags"] = [tag.strip('"') for tag in post["tags"][1:-1].split(",")] props["revisions"] = list(reversed([(i, rev) for i, rev in enumerate(reversed(all_revisions))])) comments = get_post_comments(post_id, service) if post["service"] == "fanbox": post["content"] = DOWNLOAD_URL_FANBOX_REGEX.sub("", post["content"]) post["content"] = sanitize_html(post["content"], allow_iframe=post["service"] == "fanbox") if post["service"] == "boosty": post["content"] = patch_inline_img(post["content"]) return attachments, comments, previews, videos, props DOWNLOAD_URL_FANBOX_REGEX = re.compile(r"")