Skip to content

Instantly share code, notes, and snippets.

@ashwinvis
Last active July 13, 2019 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ashwinvis/c94eb4f6bab60cc633627575d507fda8 to your computer and use it in GitHub Desktop.
Save ashwinvis/c94eb4f6bab60cc633627575d507fda8 to your computer and use it in GitHub Desktop.
View statistics and organize your Mastodon following into lists
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
mastodon-archive
ipykernel
pandas
matplotlib
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile
#
asn1crypto==0.24.0 # via cryptography
backcall==0.1.0 # via ipython
certifi==2018.10.15 # via requests
cffi==1.11.5 # via cryptography
chardet==3.0.4 # via requests
cryptography==2.3.1 # via http-ece, mastodon.py
cycler==0.10.0 # via matplotlib
decorator==4.3.0 # via ipython, mastodon.py, traitlets
html2text==2018.1.9 # via mastodon-archive
http-ece==1.0.5 # via mastodon.py
idna==2.7 # via cryptography, requests
ipykernel==5.1.1
ipython-genutils==0.2.0 # via traitlets
ipython==7.6.1 # via ipykernel
jedi==0.14.0 # via ipython
jupyter-client==5.3.1 # via ipykernel
jupyter-core==4.5.0 # via jupyter-client
kiwisolver==1.1.0 # via matplotlib
mastodon-archive==1.1.0
mastodon.py==1.3.1 # via mastodon-archive
matplotlib==3.1.1
numpy==1.16.4 # via matplotlib, pandas
pandas==0.24.2
parso==0.5.0 # via jedi
pexpect==4.7.0 # via ipython
pickleshare==0.7.5 # via ipython
progress==1.4 # via mastodon-archive
prompt-toolkit==2.0.9 # via ipython
ptyprocess==0.6.0 # via pexpect
pycparser==2.19 # via cffi
pygments==2.4.2 # via ipython
pyparsing==2.4.0 # via matplotlib
python-dateutil==2.7.3 # via jupyter-client, mastodon.py, matplotlib, pandas
pytz==2018.5 # via mastodon.py, pandas
pyzmq==18.0.2 # via jupyter-client
requests==2.19.1 # via mastodon.py
six==1.11.0 # via cryptography, cycler, mastodon.py, prompt-toolkit, python-dateutil, traitlets
tornado==6.0.3 # via ipykernel, jupyter-client
traitlets==4.3.2 # via ipykernel, ipython, jupyter-client, jupyter-core
urllib3==1.23 # via requests
wcwidth==0.1.7 # via prompt-toolkit
# The following packages are considered to be unsafe in a requirements file:
# setuptools==41.0.1 # via ipython, kiwisolver
# -*- coding: utf-8 -*-
"""Bin followers by frecency
Some of the code snippet is copied as is from mastodon_archive.core.login with
minor modification to *.secret filenames. Therefor:
Copyright (C) 2019 Ashwin Vishnu Mohanan <ashwinvis+gh@protonmail.com>
Copyright (C) 2017-2018 Alex Schroeder <alex@gnu.org>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
"""
import os
import sys
from dataclasses import dataclass
from mastodon import Mastodon
from mastodon_archive import core
# FIXME: Change username and domain url
username = "ashwinvis"
domain = "mastodon.acc.sunet.se"
@dataclass
class args:
"""Mimic args for mastodon-archive CLI"""
user = f"{username}@{domain}"
pace = False
def login(scope="r"):
global username
global domain
if len(scope) == "r":
from mastodon_archive.core import read
return read(args)
else:
client_secret = domain + ".rw.client.secret"
user_secret = domain + ".rw.user." + username + ".secret"
scopes = ["read", "write", "follow"]
pace = hasattr(args, "pace") and args.pace
(username, domain) = args.user.split("@")
url = "https://" + domain
# client_secret = domain + '.client.secret'
# user_secret = domain + '.user.' + username + '.secret'
mastodon = None
if not os.path.isfile(client_secret):
print("Registering app")
Mastodon.create_app(
"mastodon-organize",
api_base_url=url,
scopes=scopes,
to_file=client_secret,
)
if not os.path.isfile(user_secret):
print("This app needs access to your Mastodon account.")
mastodon = Mastodon(client_id=client_secret, api_base_url=url)
url = mastodon.auth_request_url(
client_id=client_secret, scopes=scopes
)
print("Visit the following URL and authorize the app:")
print(url)
print("Then paste the access token here:")
token = sys.stdin.readline().rstrip()
try:
# on the very first login, --pace has no effect
mastodon.log_in(code=token, to_file=user_secret, scopes=scopes)
except Exception as e:
print(
"Sadly, that did not work. On some sites, this login mechanism"
)
print(
"(namely OAuth) seems to be broken. There is an alternative"
)
print(
"if you are willing to trust us with your password just this"
)
print("once. We need it just this once in order to get an access")
print(
"token. We won't save it. If you don't want to try this, use"
)
print(
"Ctrl+C to quit. If you want to try it, please provide your"
)
print("login details.")
sys.stdout.write("Email: ")
sys.stdout.flush()
email = sys.stdin.readline().rstrip()
sys.stdout.write("Password: ")
sys.stdout.flush()
password = sys.stdin.readline().rstrip()
# on the very first login, --pace has no effect
mastodon.log_in(
username=email,
password=password,
to_file=user_secret,
scopes=scopes,
)
else:
if pace:
# in case the user kept running into a General API problem
mastodon = Mastodon(
client_id=client_secret,
access_token=user_secret,
api_base_url=url,
ratelimit_method="pace",
ratelimit_pacefactor=0.9,
request_timeout=300,
)
else:
# the defaults are ratelimit_method='wait',
# ratelimit_pacefactor=1.1, request_timeout=300
mastodon = Mastodon(
client_id=client_secret,
access_token=user_secret,
api_base_url=url,
)
return mastodon
def get_data():
status_file = domain + ".user." + username + ".json"
data = core.load(status_file, required=True, quiet=True)
return data
def get_list(mastodon, title):
"""Returns a list by title"""
list = [
list_dict for list_dict in mastodon.lists() if list_dict["title"] == title
]
if list:
return list.pop()
else:
return mastodon.list_create(title)
def list_accounts_addrm(mastodon, list_id, account_ids_new):
"""Fill a list with the prescribed accounts and remove accounts which are not mentioned."""
accounts_present = mastodon.list_accounts(list_id)
account_ids_present = set(acct["id"] for acct in accounts_present)
account_ids_new = set(account_ids_new)
ids_to_rm = account_ids_present - account_ids_new
ids_to_add = account_ids_new - account_ids_present
if ids_to_rm:
print("Deleting from list", list_id, ids_to_rm)
mastodon.list_accounts_delete(list_id, ids_to_rm)
if ids_to_add:
print("Adding to list", list_id, ids_to_add)
mastodon.list_accounts_add(list_id, ids_to_add)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment