Created
December 2, 2024 04:08
-
-
Save jph00/e98a0ebe61091a7d914acf0d6c50c64e to your computer and use it in GitHub Desktop.
Unfollow bsky non-mutuals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"metadata": {}, | |
"id": "00324ac4", | |
"cell_type": "markdown", | |
"source": "# Remove bsky non-mutual follows" | |
}, | |
{ | |
"metadata": {}, | |
"id": "4cc30be4", | |
"cell_type": "markdown", | |
"source": "You'll need to pip install fastprogress and atproto." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "e45d6bc4", | |
"cell_type": "code", | |
"source": "from fastcore.utils import *\nfrom fastcore.xtras import *\nfrom atproto import Client\nfrom fastprogress.fastprogress import master_bar, progress_bar", | |
"execution_count": 65, | |
"outputs": [] | |
}, | |
{ | |
"metadata": {}, | |
"id": "3dc1eb44", | |
"cell_type": "markdown", | |
"source": "Create a file \".env\" containing one line: `bsky_pass=...`, in the same directory." | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "f6f46131", | |
"cell_type": "code", | |
"source": "env = parse_env(fn='.env')\ncli = Client()\npv = cli.login('howard.fm', env['bsky_pass'])\ndid = pv.did", | |
"execution_count": 66, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "c587f69b", | |
"cell_type": "code", | |
"source": "pv.posts_count,pv.followers_count,pv.follows_count", | |
"execution_count": 67, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 67, | |
"data": { | |
"text/plain": "(246, 15061, 979)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "b500e1af", | |
"cell_type": "code", | |
"source": "def at_paged(did, meth):\n \"Return all pages of results from some method\"\n resp = None\n while True:\n resp = meth(did, cursor=resp.cursor if resp else None)\n yield resp\n if not resp.cursor: return", | |
"execution_count": 68, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "7659876c", | |
"cell_type": "code", | |
"source": "posts = L(at_paged(did, cli.get_author_feed)).attrgot('feed').concat()", | |
"execution_count": 74, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "350bdd43", | |
"cell_type": "code", | |
"source": "posts[-2].post.record", | |
"execution_count": 86, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 86, | |
"data": { | |
"text/plain": "Record(created_at='2023-05-08T03:17:47.510Z', text='👋🏽', embed=None, entities=None, facets=None, labels=None, langs=None, reply=ReplyRef(parent=Main(cid='bafyreib7cq47fgqz7fpa4kdlwuz3m7ukdcfyftkev75kldvaorrqqennle', uri='at://did:plc:cn7lps422rbgdpsh3dg5e5c2/app.bsky.feed.post/3jv6axng6re2r', py_type='com.atproto.repo.strongRef'), root=Main(cid='bafyreib7cq47fgqz7fpa4kdlwuz3m7ukdcfyftkev75kldvaorrqqennle', uri='at://did:plc:cn7lps422rbgdpsh3dg5e5c2/app.bsky.feed.post/3jv6axng6re2r', py_type='com.atproto.repo.strongRef'), py_type='app.bsky.feed.post#replyRef'), tags=None, py_type='app.bsky.feed.post')" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "be262711", | |
"cell_type": "code", | |
"source": "fws = L(at_paged(did, cli.get_follows))", | |
"execution_count": 45, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "001687b2", | |
"cell_type": "code", | |
"source": "frs = L(at_paged(did, cli.get_followers))", | |
"execution_count": 46, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "84f21a27", | |
"cell_type": "code", | |
"source": "following = fws.attrgot('follows').concat()\nfollowers = frs.attrgot('followers').concat()", | |
"execution_count": 47, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "09849316", | |
"cell_type": "code", | |
"source": "len(following),len(followers)", | |
"execution_count": 48, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 48, | |
"data": { | |
"text/plain": "(2144, 15016)" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "ef988087", | |
"cell_type": "code", | |
"source": "to_unfollow = set(following.attrgot('did')) - set(followers.attrgot('did'))\nlen(to_unfollow)", | |
"execution_count": 52, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 52, | |
"data": { | |
"text/plain": "1172" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"id": "e2d72b5d", | |
"cell_type": "code", | |
"source": "followd = {o.did:o.viewer.following for o in following}", | |
"execution_count": 59, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"scrolled": true | |
}, | |
"id": "1497b747", | |
"cell_type": "code", | |
"source": "for fdid in progress_bar(to_unfollow):\n try: cli.unfollow(followd[fdid])\n except Exception as e: print(f\"Could not unfollow {fdid}: {e}\")", | |
"execution_count": 61, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "<IPython.core.display.HTML object>", | |
"text/html": "\n<style>\n /* Turns off some styling */\n progress {\n /* gets rid of default border in Firefox and Opera. */\n border: none;\n /* Needs to be in here for Safari polyfill so background images work as expected. */\n background-size: auto;\n }\n progress:not([value]), progress:not([value])::-webkit-progress-bar {\n background: repeating-linear-gradient(45deg, #7e7e7e, #7e7e7e 10px, #5c5c5c 10px, #5c5c5c 20px);\n }\n .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n background: #F44336;\n }\n</style>\n" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": "<IPython.core.display.HTML object>", | |
"text/html": "\n <div>\n <progress value='1172' class='' max='1172' style='width:300px; height:20px; vertical-align: middle;'></progress>\n 100.00% [1172/1172 04:56<00:00]\n </div>\n " | |
}, | |
"metadata": {} | |
} | |
] | |
} | |
], | |
"metadata": { | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/jph00/741542588aa121794473e4fec3a41635" | |
}, | |
"gist": { | |
"id": "741542588aa121794473e4fec3a41635", | |
"data": { | |
"description": "Unfollow bsky non-mutuals", | |
"public": true | |
} | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python" | |
}, | |
"language_info": { | |
"name": "python", | |
"version": "3.11.8", | |
"mimetype": "text/x-python", | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"pygments_lexer": "ipython3", | |
"nbconvert_exporter": "python", | |
"file_extension": ".py" | |
}, | |
"toc": { | |
"base_numbering": 1, | |
"nav_menu": { | |
"height": "387.791px", | |
"width": "214.794px" | |
}, | |
"number_sections": true, | |
"sideBar": true, | |
"skip_h1_title": false, | |
"title_cell": "Table of Contents", | |
"title_sidebar": "Contents", | |
"toc_cell": false, | |
"toc_position": {}, | |
"toc_section_display": true, | |
"toc_window_display": false | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment