Initial commit

This commit is contained in:
lluni 2022-12-09 00:04:01 +01:00
commit 56e8c3e066
Signed by: lluni
GPG key ID: ACEEB468BC325D35
7 changed files with 174 additions and 0 deletions

13
.env.example Normal file
View file

@ -0,0 +1,13 @@
REDDIT_USER_AGENT="Reddit Mastodon Crossposter"
REDDIT_AUTH_URL=""
REDDIT_AUTH_TOKEN=""
REDDIT_REFRESH_TOKEN=""
REDDIT_CLIENT_ID=""
REDDIT_CLIENT_SECRET=""
MASTODON_URL=""
MASTODON_EMAIL=""
MASTODON_PASSWORD=""
MASTODON_USER_ID=""
MASTODON_APP_NAME=""
MASTODON_USER_SECRET="usercred.secret"
MASTODON_CLIENT_SECRET="clientcred.secret"

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
.vscode
.env
usercred.secret
clientcred.secret
post_toots.sh

23
README.md Normal file
View file

@ -0,0 +1,23 @@
# Reddit Mastodon Crossposter
## Usage
1. Install conda env with `conda env create -f environment.yml`.
2. Initialize PRAW with e.g. `reddit.py` (please refer to the [PRAW docs](https://praw.readthedocs.io)).
3. Initialize Mastodon.py with e.g. `masto.py` (please refer to the [Mastodon.py docs](https://mastodonpy.readthedocs.io)).
4. Set all `.env` variables if there are any remaining.
5. Create an `post_toots.sh` and make it executable:
```sh
#!/bin/bash
conda activate reddit
python "/absolute/path/to/script.py"
conda deactivate
```
6. Open the a (user) cronjob editor with `crontab -e` and add the line `0 * * * * /absolute/path/to/post_toots.sh > /dev/null 2>&1`. This cronjob runs hourly and the command outputs are not mailed to the user. Alternatively, `2>&1` can be ommited for debugging purposes if the error outputs should be mailed to the user.

10
environment.yml Normal file
View file

@ -0,0 +1,10 @@
name: reddit
channels:
- conda-forge
- defaults
dependencies:
- praw
- pip:
- mastodon-py==1.5.2
- python-dotenv==0.21.0
- wget==3.2

29
masto.py Normal file
View file

@ -0,0 +1,29 @@
"""Initialize Mastodon.py, login the account and register an application"""
from dotenv import load_dotenv
from mastodon import Mastodon
from os import getenv
# load .env
load_dotenv()
# register application
Mastodon.create_app(
getenv("MASTODON_APP_NAME"),
api_base_url = str(getenv("MASTODON_URL")),
to_file = getenv("MASTODON_CLIENT_SECRET")
)
# login
mastodon = Mastodon(
client_id = getenv("MASTODON_CLIENT_SECRET"),
api_base_url = getenv("MASTODON_URL")
)
mastodon.log_in(
getenv("MASTODON_USERNAME"),
getenv("MASTODON_PASSWORD"),
to_file = getenv("MASTODON_USER_SECRET")
)
# test toot
mastodon.toot("Hello World")

23
reddit.py Normal file
View file

@ -0,0 +1,23 @@
"""Initialize PRAW"""
import praw
from dotenv import load_dotenv
from os import getenv
# load .env
load_dotenv()
# initialize reddit
reddit = praw.Reddit(
client_id = getenv("REDDIT_CLIENT_ID"),
client_secret = getenv("REDDIT_CLIENT_SECRET"),
redirect_uri = "http://localhost:8080", # does not matter what is here
user_agent = getenv("REDDIT_USER_AGENT")
)
# get auth URL
# print(reddit.auth.url(scopes=["identity", "read"], state="...", duration="permanent"))
# get refresh token
# print(reddit.auth.authorize(getenv("REDDIT_AUTH_TOKEN")))
# print(reddit.user.me())

71
script.py Normal file
View file

@ -0,0 +1,71 @@
"""Main script to toot a new post"""
import praw, wget
from dotenv import load_dotenv
from mastodon import Mastodon
from os import getenv, remove
from os.path import getsize
# load .env
load_dotenv()
# initialize reddit
reddit = praw.Reddit(
client_id = getenv("REDDIT_CLIENT_ID"),
client_secret = getenv("REDDIT_CLIENT_SECRET"),
redirect_uri = "http://localhost:8080", # does not matter what is here
user_agent = getenv("REDDIT_USER_AGENT")
)
# initialize mastodon
mastodon = Mastodon(
access_token = getenv("MASTODON_USER_SECRET"),
api_base_url = getenv("MASTODON_URL")
)
# get recent posts to check for duplicates
last_posts = mastodon.account_statuses(getenv("MASTODON_USER_ID"), limit=15)
for submission in reddit.subreddit("ich_iel").top(time_filter="day", limit=10):
# skip post if it is a stickied post
if (submission.stickied):
continue
# check if the post has been posted before
already_posted = False
for posted_submission in last_posts:
if submission.permalink in posted_submission["content"]:
already_posted = True
break
if already_posted:
continue
# check if text only
if submission.is_self:
status_text = submission.title + "\n\ngeposted von u/" + submission.author.name + "\n" + submission.permalink + "\n\n" + submission.selftext
mastodon.status_post(status_text, visibility="unlisted")
# check if reddit video
elif "v.redd.it" in submission.url:
url = submission.media["reddit_video"]["fallback_url"]
url = url.split("?")[0]
filename = wget.download(url)
print()
# check if video file is small enough for the server (10MB)
if getsize(filename) < 10*1000000:
media = mastodon.media_post(filename)
status_text = submission.title + "\n\ngeposted von u/" + submission.author.name + "\nhttps://reddit.com" + submission.permalink
mastodon.status_post(status_text, media_ids=media["id"], visibility="unlisted")
else:
status_text = submission.title + "\n\nGeposteter Videolink: " + url + "\n\ngeposted von u/" + submission.author.name + "\n" + submission.permalink + "\n\n" + submission.selftext
mastodon.status_post(status_text, visibility="unlisted")
remove(filename)
else:
filename = wget.download(submission.url)
print()
media = mastodon.media_post(filename)
status_text = submission.title + "\n\ngeposted von u/" + submission.author.name + "\nhttps://reddit.com" + submission.permalink
mastodon.status_post(status_text, media_ids=media["id"], visibility="unlisted")
remove(filename)
break