Containerized app with docker and docker compose. Moved default db location to subdirectory.

This commit is contained in:
Jacob Michelsen
2023-09-16 11:55:34 +02:00
parent 7ac750e740
commit e1542a4d6f
10 changed files with 97 additions and 4 deletions

4
.gitignore vendored
View File

@@ -1,3 +1,5 @@
__pycache__
database.json
database.bak
database.bak
.env
dbhost/

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
# Use latest alpine-derived Python base image
FROM python:3-alpine
# Move to app directory
# Install requirements
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Copy source to app directory
COPY . .
# Make sure run script is executable
RUN chmod +rxxx ./run.sh
CMD sh run.sh

View File

@@ -10,4 +10,7 @@ In the settings.py you can also disable posting to twitter or mastodon if you on
The file settings.py now also allows (mis)using blueskys language function by designating a language that when set can be used to decide if a specific post should or should not be crossposted. More info can be found in the file.
## Running with Docker
The included Dockerfile and docker-compose file can be used to run the service in a docker container. Configuration options can be set in the docker-compose file, added to an .env file (see env.example) or injected as environment variables in some other way. An additional configuration option, RUN_INTERVAL, is provided to set the interval in seconds for which to check for new posts.
Bluesky Crossposter™©® developed by denvitadrogen

14
auth.py
View File

@@ -1,3 +1,5 @@
import os
# All necessary tokens, passwords, etc.
# Your bluesky handle should include your instance, so for example handle.bsky.social if you are on the main one.
bsky_handle = ""
@@ -13,4 +15,14 @@ MASTODON_TOKEN = ""
TWITTER_APP_KEY = ""
TWITTER_APP_SECRET = ""
TWITTER_ACCESS_TOKEN = ""
TWITTER_ACCESS_TOKEN_SECRET = ""
TWITTER_ACCESS_TOKEN_SECRET = ""
# Override settings with environment variables if they exist
bsky_handle = os.environ.get('BSKY_HANDLE') if os.environ.get('BSKY_HANDLE') else bsky_handle
bsky_password = os.environ.get('BSKY_PASSWORD') if os.environ.get('BSKY_PASSWORD') else bsky_password
MASTODON_INSTANCE = os.environ.get('MASTODON_INSTANCE') if os.environ.get('MASTODON_INSTANCE') else MASTODON_INSTANCE
MASTODON_TOKEN = os.environ.get('MASTODON_TOKEN') if os.environ.get('MASTODON_TOKEN') else MASTODON_TOKEN
TWITTER_APP_KEY = os.environ.get('TWITTER_APP_KEY') if os.environ.get('TWITTER_APP_KEY') else TWITTER_APP_KEY
TWITTER_APP_SECRET = os.environ.get('TWITTER_APP_SECRET') if os.environ.get('TWITTER_APP_SECRET') else TWITTER_APP_SECRET
TWITTER_ACCESS_TOKEN = os.environ.get('TWITTER_ACCESS_TOKEN') if os.environ.get('TWITTER_ACCESS_TOKEN') else TWITTER_ACCESS_TOKEN
TWITTER_ACCESS_TOKEN_SECRET = os.environ.get('TWITTER_ACCESS_TOKEN_SECRET') if os.environ.get('TWITTER_ACCESS_TOKEN_SECRET') else TWITTER_ACCESS_TOKEN_SECRET

0
db/.gitkeep Normal file
View File

24
docker-compose.yml Normal file
View File

@@ -0,0 +1,24 @@
version: '3.8'
services:
crossposter:
build: .
environment:
BSKY_HANDLE:
BSKY_PASSWORD:
MASTODON_INSTANCE:
MASTODON_TOKEN:
TWITTER_APP_KEY:
TWITTER_APP_SECRET:
TWITTER_ACCESS_TOKEN:
TWITTER_ACCESS_TOKEN_SECRET:
TWITTER_CROSSPOSTING:
MASTODON_CROSSPOSTING:
LOGGING:
POST_DEFAULT:
MASTODON_LANG:
TWITTER_LANG:
MAX_RETRIES:
RUN_INTERVAL:
POST_TIME_LIMIT:
volumes:
- ./dbhost:/db

17
env.example Normal file
View File

@@ -0,0 +1,17 @@
BSKY_HANDLE=
BSKY_PASSWORD=
MASTODON_INSTANCE=
MASTODON_TOKEN=
TWITTER_APP_KEY=
TWITTER_APP_SECRET=
TWITTER_ACCESS_TOKEN=
TWITTER_ACCESS_TOKEN_SECRET=
TWITTER_CROSSPOSTING=
MASTODON_CROSSPOSTING=
LOGGING=
POST_DEFAULT=
MASTODON_LANG=
TWITTER_LANG=
MAX_RETRIES=
RUN_INTERVAL=
POST_TIME_LIMIT=

View File

@@ -5,9 +5,9 @@
basePath = "/"
# Path to the database file. If you want it somewhere other than directly in the base path you can
# either write the entire path manually, or just add the rest of the path on top of the basePath.
databasePath = basePath + "database.json"
databasePath = basePath + "db/" + "database.json"
# Path to backup of database.
backupPath = basePath + "database.bak"
backupPath = basePath + "db/" + "database.bak"
# Path for storing logs
logPath = basePath + "logs/"
# Path to folder for temporary storage of images

7
run.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
# Run once per hour if nothing else has been specified in environment variables
while :; do
python crosspost.py
sleep ${RUN_INTERVAL:-3600}
done

View File

@@ -1,3 +1,5 @@
import os
# Enables/disables crossposting to twitter and mastodon
# Accepted values: True, False
Twitter = True
@@ -26,3 +28,13 @@ maxRetries = 5
# Sets max time limit (in hours) for fetching posts. If no database exists, all posts within this time
# period will be posted.
postTimeLimit = 12
# Override settings with environment variables if they exist
Twitter = os.environ.get('TWITTER_CROSSPOSTING').lower() == 'true' if os.environ.get('TWITTER_CROSSPOSTING') else Twitter
Mastodon = os.environ.get('MASTODON_CROSSPOSTING').lower() == 'true' if os.environ.get('MASTODON_CROSSPOSTING') else Mastodon
Logging = os.environ.get('LOGGING').lower() == 'true' if os.environ.get('LOGGING') else Logging
postDefault = os.environ.get('POST_DEFAULT').lower() == 'true' if os.environ.get('POST_DEFAULT') else postDefault
mastodonLang = os.environ.get('MASTODON_LANG') if os.environ.get('MASTODON_LANG') else mastodonLang
twitterLang = os.environ.get('TWITTER_LANG') if os.environ.get('TWITTER_LANG') else twitterLang
maxRetries = int(os.environ.get('MAX_RETRIES')) if os.environ.get('MAX_RETRIES') else maxRetries
postTimeLimit = int(os.environ.get('POST_TIME_LIMIT')) if os.environ.get('POST_TIME_LIMIT') else postTimeLimit