Initial commit
This commit is contained in:
commit
56e8c3e066
7 changed files with 174 additions and 0 deletions
13
.env.example
Normal file
13
.env.example
Normal 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
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
.vscode
|
||||
.env
|
||||
usercred.secret
|
||||
clientcred.secret
|
||||
post_toots.sh
|
23
README.md
Normal file
23
README.md
Normal 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
10
environment.yml
Normal 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
29
masto.py
Normal 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
23
reddit.py
Normal 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
71
script.py
Normal 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
|
||||
|
Loading…
Reference in a new issue