Documenting a bit

This commit is contained in:
clerie 2019-07-30 21:06:25 +02:00
parent a427173739
commit 498164ac25
3 changed files with 38 additions and 14 deletions

View File

@ -1,12 +1,12 @@
# Mastodon Hashtag Spreader # Mastodon Hashtag Spreader
For the #GPN19 my Mastodon instance fem.social wants to get all posts of the hashtag. Most users of this event are connected to the instance chaos.social. For the #GPN19 my Mastodon instance [fem.social](https://fem.social) wants to get all posts of the hashtag. Most users of this event are connected to the instance [chaos.social](https://chaos.social).
## Our solution ## Our solution
We have a script on one of our servers, streaming all posts of one hashtag from chaos.socail and putting the url of the post to the search entry of our own instance. The url will get fetched by our instace and the resulting post is added to our hashtag timeline. We have a script on one of our servers, streaming all posts of one hashtag from chaos.socail and putting the url of the post to the search entry of our own instance. The url will get fetched by our instace and the resulting post is added to our hashtag timeline.
## Installing ## Installation
``` ```bash
pip3 install Mastodon.py pip3 install Mastodon.py
git clone https://github.com/clerie/mastodon-hashtag-spreader.git git clone https://github.com/clerie/mastodon-hashtag-spreader.git
cd mastodon-hashtag-spreader/ cd mastodon-hashtag-spreader/
@ -14,6 +14,16 @@ cp config.json.example config.json
nano config.json nano config.json
``` ```
Edit config for your needs. Edit config for your needs.
``` ```bash
python3 hashtag-spreader.py python3 hashtag-spreader.py
``` ```
## Scopes
To get this script work, you need an application token on each instance you want to get connected to.
The needed scopes are depending on the role of the instace.
### Source
* `read:statuses`
### Drain
* `read:search`

View File

@ -1,7 +1,7 @@
{ {
"instances": { "instances": {
"chaos.social": "secret", "chaos.social": "access-token",
"fem.social": "secret" "fem.social": "access-token"
}, },
"spreads": [ "spreads": [
{ {

View File

@ -10,35 +10,47 @@ def print_status(status):
print("from: @" + status["account"]["acct"]) print("from: @" + status["account"]["acct"])
class TootListener(StreamListener): class TootListener(StreamListener):
"""
Listener class, handling incoming statuses
"""
def __init__(self, source, drain): def __init__(self, source, drain):
self.source = source self.source = source # Source instance Mastodon object
self.drain = drain self.drain = drain # Drain instance Mastodon object
def on_update(self, status): def on_update(self, status):
# Just printing some stuff to make it look beautiful in terminal
# More for debugging than anything else
print("") print("")
print("--") print("--")
print("RECIEVE " + self.source.api_base_url + "") print("RECIEVE " + self.source.api_base_url + "")
print_status(status) print_status(status)
print("SEARCH " + self.drain.api_base_url + "") print("SEARCH " + self.drain.api_base_url + "")
# Searching for the URL of the incoming status in our drain instance
try: try:
search = self.drain.search(status.url) search = self.drain.search(status.url)
for s in search["statuses"]: for s in search["statuses"]:
print_status(s) print_status(s)
except: except:
print("failed") print("failed")
print("--") print("--")
class HashtagSpreader(Thread): class HashtagSpreader(Thread):
"""
Thread class, streaming one hashtag from one the source instance and searching for the post URL in the drain instance
"""
def __init__(self, source, drain, hashtag): def __init__(self, source, drain, hashtag):
Thread.__init__(self) Thread.__init__(self) # Configure the thread
self.source = source self.source = source # Source instance Mastodon object
self.drain = drain self.drain = drain # Drain instance Mastodon object
self.hashtag = hashtag self.hashtag = hashtag # The hashtag (without #) as a string, we want to stream
def run(self): def run(self):
tootListener = TootListener(self.source, self.drain) tootListener = TootListener(self.source, self.drain)
self.source.stream_hashtag(self.hashtag, tootListener) self.source.stream_hashtag(self.hashtag, tootListener) # Stream our hashtag
if __name__ == "__main__": if __name__ == "__main__":
instances = {} instances = {}
@ -48,14 +60,16 @@ if __name__ == "__main__":
config = json.load(f) config = json.load(f)
if config: if config:
# Create Mastodon objects for every instance
for instance in config["instances"]: for instance in config["instances"]:
instances[instance] = Mastodon(access_token = config["instances"][instance], api_base_url = "https://" + instance) instances[instance] = Mastodon(access_token = config["instances"][instance], api_base_url = "https://" + instance)
# Create threads for every hashtag of a relation
for spread in config["spreads"]: for spread in config["spreads"]:
if spread["source"] in instances and spread["drain"] in instances: if spread["source"] in instances and spread["drain"] in instances:
for hashtag in spread["hashtags"]: for hashtag in spread["hashtags"]:
threads.append(HashtagSpreader(instances[spread["source"]], instances[spread["drain"]], hashtag)) threads.append(HashtagSpreader(instances[spread["source"]], instances[spread["drain"]], hashtag))
# Start all threads
for thread in threads: for thread in threads:
thread.start() thread.start()