Commit 1201a02
Changed files (3)
src
src/preview/instagram.py
@@ -1,17 +1,15 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-
-from datetime import datetime
-from zoneinfo import ZoneInfo
+from typing import Literal
from bs4 import BeautifulSoup
-from glom import glom
+from glom import flatten, glom
from loguru import logger
from pyrogram.client import Client
from pyrogram.types import Message
from bridge.social import send_to_social_media_bridge
-from config import API, DB, DOWNLOAD_DIR, PROVIDER, PROXY, TELEGRAM_UA, TOKEN, TZ
+from config import API, DB, DOWNLOAD_DIR, PROVIDER, PROXY, TELEGRAM_UA, TOKEN
from database.database import get_db
from messages.database import copy_messages_from_db, save_messages
from messages.progress import modify_progress
@@ -19,7 +17,7 @@ from messages.sender import send2tg
from messages.utils import blockquote, summay_media
from multimedia import is_valid_video_or_audio, validate_img
from networking import download_file, download_media, hx_req
-from utils import readable_count, true
+from utils import readable_count, true, ts_to_dt
async def preview_instagram(
@@ -28,6 +26,9 @@ async def preview_instagram(
url: str = "",
db_key: str = "",
*,
+ post_type: Literal["p", "story", "reel"] = "p",
+ post_id: str = "",
+ username: str = "",
instagram_provider: str = PROVIDER.INSTAGRAM,
instagram_comments: bool = True,
show_author: bool = True,
@@ -58,7 +59,7 @@ async def preview_instagram(
succ = False
resp = {}
if "tikhub" in instagram_provider: # try tikhub
- api_url = API.TIKHUB_INSTAGRAM + url
+ api_url = f"{API.TIKHUB_INSTAGRAM_STORY}{username}" if post_type == "story" else f"{API.TIKHUB_INSTAGRAM}{url}"
logger.info(f"Preview Instagram TikHub for {api_url}")
headers = {"authorization": f"Bearer {TOKEN.TIKHUB}", "accept": "application/json"}
resp = await hx_req(api_url, headers=headers, check_keys=["data"], check_kv={"code": 200})
@@ -70,6 +71,9 @@ async def preview_instagram(
return
data = resp["data"]
+ if post_type == "story":
+ await preview_story(client, message, data, username, post_id, db_key=db_key, **kwargs)
+ return
# parse media
media = []
if data.get("video_url"): # reel
@@ -94,8 +98,7 @@ async def preview_instagram(
if metadata_node := glom(data, "edge_media_to_caption.edges.0", default=None):
if true(show_pubdate) and (ts := glom(metadata_node, "node.created_at", default=0)):
- dt = datetime.fromtimestamp(float(ts)).astimezone(ZoneInfo(TZ))
- create_time = f"{dt:%Y-%m-%d %H:%M:%S}"
+ create_time = f"{ts_to_dt(ts):%Y-%m-%d %H:%M:%S}"
texts += f"🕒{create_time}\n"
if true(show_statistics) and statistics:
texts += f"{statistics}\n"
@@ -121,6 +124,36 @@ async def preview_instagram(
await save_messages(messages=sent_messages, key=db_key)
+async def preview_story(client: Client, message: Message, data: dict, username: str, post_id: str, db_key: str, **kwargs):
+ items = flatten(glom(data, "reels_media.*.items", default=[]))
+ item = next((x for x in items if glom(x, "pk", default="") == post_id), None)
+ url = f"https://www.instagram.com/stories/{username}/{post_id}"
+ if not item:
+ await modify_progress(text=f"❌Instagram解析失败, 请访问{url}查看原始内容", force_update=True, **kwargs)
+ return
+
+ create_ts = glom(item, "taken_at", default=0)
+ expiring_ts = glom(item, "expiring_at", default=0)
+ texts = ""
+ fullname = glom(item, "story_music_stickers.0.display_artist", default=username)
+ media = []
+ if img_url := glom(item, "image_versions2.candidates.0.url", default=""):
+ media.append({"photo": download_file(img_url, proxy=PROXY.INSTAGRAM, **kwargs)})
+ if video_url := glom(item, "video_versions.0.url", default=""):
+ media.append({"video": download_file(video_url, proxy=PROXY.INSTAGRAM, **kwargs)})
+
+ texts += f"🏞**[{fullname}]({url})**"
+ if create_ts:
+ texts += f"\n🕒{ts_to_dt(create_ts):%Y-%m-%d %H:%M:%S}"
+ if expiring_ts:
+ texts += f"\n🔥{ts_to_dt(expiring_ts):%Y-%m-%d %H:%M:%S}"
+ await modify_progress(text=f"⏬正在下载:\n{summay_media(media)}", force_update=True, **kwargs)
+ media = await download_media(media, **kwargs)
+ sent_messages = await send2tg(client, message, texts=texts.strip(), media=media, **kwargs)
+ await modify_progress(del_status=True, **kwargs)
+ await save_messages(messages=sent_messages, key=db_key)
+
+
async def preview_ddinstagram(client: Client, message: Message, url: str, post_type: str, post_id: str, *, instagram_provider: str, **kwargs):
"""Preview instagram link in the message via DDInstagram.
src/config.py
@@ -124,6 +124,7 @@ class API:
TIKHUB = os.getenv("TIKHUB", "https://api.tikhub.io")
TIKHUB_FREE = os.getenv("TIKHUB_FREE", "https://api.douyin.wtf")
TIKHUB_INSTAGRAM = os.getenv("TIKHUB_INSTAGRAM_API", "https://api.tikhub.io/api/v1/instagram/v1/fetch_post_by_url?post_url=")
+ TIKHUB_INSTAGRAM_STORY = os.getenv("TIKHUB_INSTAGRAM_STORY_API", "https://api.tikhub.io/api/v1/instagram/v3/get_user_stories?username=")
TIKHUB_TWITTER = os.getenv("TIKHUB_TWITTER_API", "https://api.tikhub.io/api/v1/twitter/web/fetch_post_comments?tweet_id=")
TIKHUB_WEIBO_VIDEO = os.getenv("TIKHUB_WEIBO_VIDEO_API", "https://api.tikhub.io/api/v1/weibo/web/fetch_short_video_data?share_text=")
TIKHUB_WECHAT = os.getenv("TIKHUB_WECHAT", "https://api.tikhub.io/api/v1/wechat_mp/web/fetch_mp_article_detail_json?url=")
src/networking.py
@@ -315,6 +315,9 @@ async def match_social_media_link(text: str, *, flatten_first: bool = True) -> d
# https://www.instagram.com/yifaer_chen/p/DEzv9x-vzOn/
if matched := re.search(r"(https?://)?(www\.)?instagram\.com/[a-zA-Z0-9_.]+/(:?|p|reel)/([^.。,,/\s]+)", text):
return {"post_type": matched.group(3), "post_id": matched.group(4), "url": https_url(matched.group(0)), "db_key": bare_url(matched.group(0)), "platform": "instagram"}
+ # https://www.instagram.com/stories/laufey/3891120377355460527
+ if matched := re.search(r"(https?://)?(www\.)?instagram\.com/stories/([a-zA-Z0-9_.]+)/(\d+)", text):
+ return {"post_type": "story", "post_id": matched.group(4), "username": matched.group(3), "url": https_url(matched.group(0)), "db_key": bare_url(matched.group(0)), "platform": "instagram"}
# https://x.com/taylorswift13/status/1794805688696275131
# https://twitter.com/taylorswift13/status/1794805688696275131