Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- javascript:(function(){const MAX_IMAGES_PER_POST=10;function replaceDomain(e){return e.replace(/^(https?:\/\/)([^\/]+)/,"$1bsky.app")}function cleanText(e){return e?e.replace(/<a href="([^"]+)"[^>]*>([^<]+)<\/a>/g,(match,url,text)=>(url.startsWith('/')?`[U][URL=https://bsky.app${url}]${text}[/URL][/U]`:`[U][URL=${url}]${text}[/URL][/U]`)).replace(/<br\s*\/?>/g,"\n").replace(/<[^>]+>/g,"").trim():""}function extractMedia(e){const images=Array.from(e.querySelectorAll('img[src*="cdn.bsky.app"]')).map(e=>e.src).filter(e=>!e.includes("/avatar_thumbnail/")),videoSources=new Set([...Array.from(e.querySelectorAll("video source[src]")).map(e=>e.src),...Array.from(e.querySelectorAll("video[src]")).map(e=>e.src)]);return{images,videos:Array.from(videoSources)}}function showToast(e){const t=document.createElement("div");t.style.cssText="position:fixed;bottom:20px;left:20px;padding:10px 20px;background:#333;color:#fff;border-radius:4px;z-index:10000;font-family:Arial,sans-serif;font-size:14px;opacity:1;transition:opacity 1s;box-shadow:0 2px 5px rgba(0,0,0,0.3)";t.innerText=e;document.body.appendChild(t);setTimeout(()=>{t.style.opacity="0";setTimeout(()=>document.body.removeChild(t),1000)},2000)}function createPostCountPrompt(e){const t=document.createElement("div");t.style.cssText="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;display:flex;justify-content:center;align-items:center";const r=document.createElement("div");r.style.cssText="background:white;padding:20px;border-radius:8px;box-shadow:0 0 10px rgba(0,0,0,0.3);text-align:center";const n=document.createElement("input");n.type="text";n.value="12";n.style.cssText="font-size:30px;width:100px;text-align:center;margin-bottom:20px";const o=document.createElement("div");o.style.cssText="display:grid;grid-template-columns:repeat(3,1fr);gap:10px";"1234567890".split("").forEach(e=>{const t=document.createElement("button");t.textContent=e;t.style.cssText="font-size:20px;padding:10px;cursor:pointer";t.onclick=()=>n.value+=e;o.appendChild(t)});const p=document.createElement("div");p.style.cssText="display:flex;gap:10px;margin-bottom:20px";[1,2,10,25,35,50].forEach(num=>{const b=document.createElement("button");b.textContent=num;b.style.cssText="font-size:16px;padding:8px;cursor:pointer";b.onclick=()=>n.value=num;p.appendChild(b)});const s=document.createElement("button");s.textContent="Clear";s.style.cssText="font-size:18px;margin-top:10px;padding:10px 20px;cursor:pointer";s.onclick=()=>n.value="";const a=document.createElement("button");a.textContent="Set Number of Posts";a.style.cssText="font-size:18px;margin-top:20px;padding:10px 20px;cursor:pointer";a.onclick=()=>{const o=parseInt(n.value,10);isNaN(o)||o<=0?showToast("Please enter a valid number."):(document.body.removeChild(t),e(o))};r.append(n,p,o,s,a);t.appendChild(r);document.body.appendChild(t)}async function getEmbedUrl(threadData){let url=null;const post=threadData?.thread?.post;if(post?.embed?.$type==="app.bsky.embed.video#view"&&post.embed.playlist){url=post.embed.playlist;console.log("Found playlist (main):",url)}else if(post?.record?.embed?.$type==="app.bsky.embed.video"&&post.author.did&&post.record.embed.video.ref?.$link){url=constructVideoUrl(post.author.did,post.record.embed.video);console.log("Constructed URL (main):",url)}return url}function constructVideoUrl(did,videoEmbed){if(videoEmbed.mimeType==="video/webm")return`https://bsky.social/xrpc/com.atproto.sync.getBlob?did=${encodeURIComponent(did)}&cid=${encodeURIComponent(videoEmbed.ref.$link)}`;return`https://video.bsky.app/watch/${encodeURIComponent(did)}/${encodeURIComponent(videoEmbed.ref.$link)}/playlist.m3u8`}function getPostUrlFromElement(e,handle){const timestampLink=e.querySelector('[data-testid="postTimestamp"] a[href*="/post/"]');if(timestampLink&×tampLink.href.includes(`/profile/${handle}/post/`)){return timestampLink.href.split('?')[0]}const handleLink=e.querySelector(`a[href*="/profile/${handle}/post/"]`);if(handleLink){return handleLink.href.split('?')[0]}const anyPostLink=e.querySelector('a[href*="/post/"]');if(anyPostLink){return anyPostLink.href.split('?')[0]}return null}async function extractPost(e,isActivePost=false,mainHandle=null,isQuotedPost=false){if(!(e instanceof Element))return console.error("Invalid post element:",e),{text:"",author:"",url:"",threadData:null,isQuotedPost:isQuotedPost};const t=e.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a"),r=t?.textContent?.trim()||"Unknown",n=e.querySelector('div[data-word-wrap="1"]')||e.querySelector('[data-testid="postText"]');let o=n?cleanText(n.innerHTML||n.textContent):"",s=e.getAttribute("data-testid")?.match(/postThreadItem-by-(.+)/)?.[1],a=null;if(isActivePost){a=replaceDomain(window.location.href.split("?")[0]);}else if(s){a=getPostUrlFromElement(e,s)||"";}let i=null;if(a&&e.querySelector('video')){const postId=a.split('/').pop();const apiUri=`at://${s}/app.bsky.feed.post/${postId}`,t=`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(apiUri)}&depth=1`;try{const e=await fetch(t);i=e.ok?await e.json():null;if(i)console.log("API data for",a,":",i);}catch(e){console.warn("API fetch failed, skipping thread data:",e);}}const l=extractMedia(e);l.images.slice(0,MAX_IMAGES_PER_POST).forEach(e=>o+=`\n[img]${e}[/img]`);if(i){const videoUrl=await getEmbedUrl(i);if(videoUrl)o+=`\n[U][URL]${videoUrl}[/URL][/U]`;}const normalizeUrl=(url)=>(url.startsWith('/')?`https://bsky.app${url}`:url).replace(/\/+$/,"").toLowerCase();const c=new Set(Array.from(e.querySelectorAll("a[href]")).map(e=>normalizeUrl(e.href)).filter(e=>e.startsWith("http")&&!e.includes("/post/")&&!e.includes("/profile/")&&!o.includes(e)));c.forEach(e=>o+=`\n[U][URL]${e}[/URL][/U]`);const d=e.querySelector('[role="link"][aria-label*="Post by"]');let quotedUrl=null;if(d&&!isQuotedPost){const t=d.querySelector('div[data-word-wrap="1"]')?.innerHTML||"";if(t){const quotedText=cleanText(t),quotedHandle=d.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a")?.textContent?.trim()||"Unknown",quotedPostId=d.querySelector('a[href*="/post/"]')?.href.split('/').pop().split('?')[0];if(quotedText){o+=`\n\n[QUOTED POST]\nπΊ ${quotedHandle}\n${quotedText}`;let quotedVideoUrl=null;if(quotedPostId){const quotedUri=`at://${quotedHandle}/app.bsky.feed.post/${quotedPostId}`,quotedApi=`https://public.api.bsky.app/xrpc/app.bsky.feed.getPostThread?uri=${encodeURIComponent(quotedUri)}&depth=0`;try{const res=await fetch(quotedApi);const quotedData=res.ok?await res.json():null;if(quotedData?.thread?.post?.record?.embed?.$type==="app.bsky.embed.video"&"edData?.thread?.post?.author?.did&"edData?.thread?.post?.record?.embed?.video?.ref?.$link){quotedVideoUrl=constructVideoUrl(quotedData.thread.post.author.did,quotedData.thread.post.record.embed.video);console.log("Quoted video URL (API):",quotedVideoUrl);}}catch(e){console.warn("Quoted post API fetch failed:",e);}}if(!quotedVideoUrl&&d.querySelector('video[poster]')){const poster=d.querySelector('video[poster]').getAttribute('poster');if(poster.includes('video.bsky.app/watch/')){const parts=poster.split('/');quotedVideoUrl=`https://video.bsky.app/watch/${parts[4]}/${parts[5]}/playlist.m3u8`;console.log("Quoted video URL (poster fallback):",quotedVideoUrl);}}if(!quotedVideoUrl&&d.querySelector('video[src^="blob:"]')){quotedVideoUrl=d.querySelector('video[src^="blob:"]').src;console.log("Quoted video URL (blob fallback):",quotedVideoUrl);}if(quotedVideoUrl)o+=`\n[U][URL]${quotedVideoUrl}[/URL][/U]`;}quotedUrl=quotedPostId?`https://bsky.app/profile/${quotedHandle}/post/${quotedPostId}`:"";const r=extractMedia(d);r.images.slice(0,MAX_IMAGES_PER_POST).forEach(e=>o+=`\n[img]${e}[/img]`);}}if(i?.thread?.post?.record?.embed?.record&&!isQuotedPost){const qText=cleanText(i.thread.post.record.embed.record.value?.text||"");if(qText){o+=`\n\n[QUOTED POST]\nπΊ ${i.thread.post.record.embed.record.uri.split('/')[2]}\n${qText}`;if(i.thread.post.record.embed.record.value?.embed?.$type==="app.bsky.embed.video"){const quotedVideoUrl=constructVideoUrl(i.thread.post.record.embed.record.uri.split('/')[2],i.thread.post.record.embed.record.value.embed.video);o+=`\n[U][URL]${quotedVideoUrl}[/URL][/U]`;console.log("Quoted video URL from embed:",quotedVideoUrl);}}quotedUrl=`https://bsky.app/profile/${i.thread.post.record.embed.record.uri.split('/')[2]}/post/${i.thread.post.record.embed.record.uri.split('/')[4]}`;}return{text:o,author:s?`πΊ ${s}`:"",url:a,threadData:i,quotedUrl,isQuotedPost:isQuotedPost}}async function extractPosts(requestedCount){const allPosts=Array.from(document.querySelectorAll('[data-testid^="postThreadItem-by-"], [data-testid="postThreadItem"]'));if(!allPosts.length)return void showToast("No posts found on this page.");const currentPostId=window.location.href.split('/').pop().split('?')[0];let activePost=allPosts.find(p=>p.querySelector(`a[href*="/post/${currentPostId}"]`));if(!activePost){showToast("Active post not found. Using first post.");activePost=allPosts[0];}const activeIndex=allPosts.indexOf(activePost);const{text:activeText,author:activeAuthor,url:activeUrl,threadData:activeThreadData,quotedUrl:activeQuotedUrl}=await extractPost(activePost,true);const r=activePost.querySelector(".css-146c3p1.r-dnmrzs.r-1udh08x.r-1udbk01.r-3s2u2q.r-1iln25a"),n=r?.textContent?.trim()||document.querySelector('[data-testid="profileHandle"]')?.textContent?.trim()||"";if(!n)return void showToast("Could not determine main username.");let postsToProcess=[activePost],parentUrl=null,parentText=null,parentAuthor=null,quotedPostUrl=activeQuotedUrl;if(activeThreadData?.thread?.post?.reply?.parent){const parentUri=activeThreadData.thread.post.reply.parent.uri;const parentAuthorUri=parentUri.split('/')[2];const parentId=parentUri.split('/')[4];parentUrl=`https://bsky.app/profile/${parentAuthorUri}/post/${parentId}`;parentText=cleanText(activeThreadData.thread.post.reply.parent.value?.text||"");parentAuthor=`πΊ ${parentAuthorUri}`;const parentQuotedPost=activeThreadData.thread.post.reply.parent.embed?.record;if(parentQuotedPost){const qText=cleanText(parentQuotedPost.value?.text||"");if(qText)parentText+=`\n\n[QUOTED POST]\nπΊ ${parentQuotedPost.uri.split('/')[2]}\n${qText}`;quotedPostUrl=`https://bsky.app/profile/${parentQuotedPost.uri.split('/')[2]}/post/${parentQuotedPost.uri.split('/')[4]}`;}postsToProcess=[{text:parentText,author:parentAuthor,url:parentUrl}];}const remainingCount=requestedCount-postsToProcess.length;if(remainingCount>0){const replyPosts=allPosts.slice(activeIndex+1,activeIndex+1+remainingCount);postsToProcess=[...postsToProcess,...replyPosts];}let mainPostUrls=new Set([activeUrl]);if(parentAuthor===activeAuthor&&parentUrl)mainPostUrls.add(parentUrl);for(const post of postsToProcess){if(post instanceof Element){const{url:postUrl,author:postAuthor}=await extractPost(post,false,n);if(postUrl&&postAuthor===`πΊ ${n}`&&postUrl!==activeUrl&&postUrl!==parentUrl){mainPostUrls.add(postUrl);}}}let s=parentText?[{author:parentAuthor,text:parentText}]:[],a=0,i=parentText?1:0,l=[];for(const[r,c]of postsToProcess.entries()){let postElement=c;let extractedData=c;if(c instanceof Element){extractedData=await extractPost(c,c===activePost,n);}const{text:d,author:p,url:u,isQuotedPost}=extractedData;if(!d&&!u&&!extractMedia(postElement).images.length)continue;if(!isQuotedPost){s.push({author:p,text:d});a+=(d.match(/\[img\]/g)||[]).length;i++;}if(a>=20||r===postsToProcess.length-1){const hasThreads=parentUrl&&parentUrl!==activeUrl||[...mainPostUrls].some(u=>u!==activeUrl)||quotedPostUrl&"edPostUrl!==activeUrl;l.push(`${activeUrl||replaceDomain(window.location.href.split("?")[0])}${hasThreads?`\n[SPOILER="Threads Continued"]${parentUrl&&parentUrl!==activeUrl?`\n${parentUrl}`:""}${[...mainPostUrls].filter(u=>u!==activeUrl).length>0?`\n${[...mainPostUrls].filter(u=>u!==activeUrl).join("\n")}`:""}${quotedPostUrl&"edPostUrl!==activeUrl?`\n${quotedPostUrl}`:""}\n[/SPOILER]`:""}\n[SPOILER="full text & large images"]\n\n${s.map((e,t)=>`${t+1}/${s.length}\n${e.author}\n${e.text}`).join("\n\n")}\n\n[COLOR=rgb(184,49,47)][B][SIZE=5]To post tweets in this format, more info here: [URL]https://www.thecoli.com/threads/tips-and-tricks-for-posting-the-coli-megathread.984734/post-52211196[/URL][/SIZE][/B][/COLOR]\n[/SPOILER]`);s=parentText?[{author:parentAuthor,text:parentText}]:[];a=0;}}if(s.length&&!l.length){const hasThreads=parentUrl&&parentUrl!==activeUrl||[...mainPostUrls].some(u=>u!==activeUrl)||quotedPostUrl&"edPostUrl!==activeUrl;l.push(`${activeUrl||replaceDomain(window.location.href.split("?")[0])}${hasThreads?`\n[SPOILER="Threads Continued"]${parentUrl&&parentUrl!==activeUrl?`\n${parentUrl}`:""}${[...mainPostUrls].filter(u=>u!==activeUrl).length>0?`\n${[...mainPostUrls].filter(u=>u!==activeUrl).join("\n")}`:""}${quotedPostUrl&"edPostUrl!==activeUrl?`\n${quotedPostUrl}`:""}\n[/SPOILER]`:""}\n[SPOILER="full text & large images"]\n\n${s.map((e,t)=>`${t+1}/${s.length}\n${e.author}\n${e.text}`).join("\n\n")}\n\n[COLOR=rgb(184,49,47)][B][SIZE=5]To post tweets in this format, more info here: [URL]https://www.thecoli.com/threads/tips-and-tricks-for-posting-the-coli-megathread.984734/post-52211196[/URL][/SIZE][/B][/COLOR]\n[/SPOILER]`);}const c=l.join("\n\n[threads continued]\n\n"),d=document.createElement("textarea");d.value=c;document.body.appendChild(d);d.select();document.execCommand("copy");document.body.removeChild(d);showToast(`Copied: ${i} posts`)}createPostCountPrompt(extractPosts)})();
Advertisement
Add Comment
Please, Sign In to add comment