Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
George | f5cceda106 | |
Neil Carpenter | 4a0de99672 | |
Neil Carpenter | 16c76af0c0 | |
George | 2db531d2aa | |
neilcar | a5912cee3c | |
neilcar | 04e2d13247 | |
neilcar | 519e6beafa | |
George | 44783e0343 | |
GunChleoc | 79da06cf2e | |
George | e7b8423dc8 |
|
@ -0,0 +1,94 @@
|
|||
name: Docker
|
||||
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
# Publish semver tags as releases.
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: ghcr.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
# This is used to complete the identity challenge
|
||||
# with sigstore/fulcio when running outside of PRs.
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Install the cosign tool except on PR
|
||||
# https://github.com/sigstore/cosign-installer
|
||||
- name: Install cosign
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: sigstore/cosign-installer@f3c664df7af409cb4873aa5068053ba9d61a57b6 #v2.6.0
|
||||
with:
|
||||
cosign-release: 'v1.13.1'
|
||||
|
||||
|
||||
# Workaround: https://github.com/docker/build-push-action/issues/461
|
||||
- name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
|
||||
|
||||
# Login against a Docker registry except on PR
|
||||
# https://github.com/docker/login-action
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Build and push Docker image with Buildx (don't push on PR)
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
|
||||
# Sign the resulting Docker image digest except on PRs.
|
||||
# This will only write to the public Rekor transparency log when the Docker
|
||||
# repository is public to avoid leaking data. If you would like to publish
|
||||
# transparency data even for private images, pass --force to cosign below.
|
||||
# https://github.com/sigstore/cosign
|
||||
- name: Sign the published Docker image
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: "true"
|
||||
# This step uses the identity token to provision an ephemeral certificate
|
||||
# against the sigstore community Fulcio instance.
|
||||
run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} cosign sign {}@${{ steps.build-and-push.outputs.digest }}
|
10
Docs.md
10
Docs.md
|
@ -3,7 +3,7 @@
|
|||
## How to use
|
||||
You can use Instagram2Fedi via docker or just like a python script
|
||||
|
||||
** Note: ** _Since somewhen it's seems not possible to fetch any data from instagram anonymously (maybe i'm wrong and there's a solution, I'll be very happy to know about it). Due that you unfortunately have to had an instagram accound and provide login and password to this script_
|
||||
** Note: ** _Credentials can be complicated. Running without Instagram credentials (`user-name` and `user-password`) appears to work for a short period of time but will, eventually, fail. Providing credentials will work unless Instagram issues a challenge. Recommend leaving `user-name` blank if running as a scheduled job (`--scheduled`) and providing them otherwise._
|
||||
### With Docker 🐋
|
||||
|
||||
Specify your variables in `./env.sh` and then run `./run.sh`
|
||||
|
@ -66,6 +66,14 @@ If theres more than one new post, sets with which time interval should it post t
|
|||
|
||||
`--use-docker` - If you're running it via docker container, set to `1` or `True`
|
||||
|
||||
---
|
||||
|
||||
`--scheduled` - If set, Instagram2Fedi runs once instead of sleeping for `check-interval` and running forever. This is intended for use as a `cron` job. No additional parameter is needed, just add `--scheduled`.
|
||||
|
||||
---
|
||||
|
||||
`--verbose` - If set, output all logs including secrets. No additional parameter is needed, just add `--scheduled`.
|
||||
|
||||
|
||||
## Default values ⚙
|
||||
Default values are:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
_Guys... Instagram is sh*t. Even [bibliogram](https://www.reddit.com/r/privacy/comments/wrczxc/bibliogram_is_being_discontinued/) is being discontinued. If you're able to migrate you proile to any fediverse instance or contact to person, whose instagram you'd like to crosspost and ask him to post to fediverse to, it wil be the best desicion_
|
||||
|
||||
# Instagram2Fedi <span><img width="50px" src="https://upload.wikimedia.org/wikipedia/commons/9/93/Fediverse_logo_proposal.svg"></span>
|
||||
|
||||
Simple tool for crossposting posts from instagram to Mastodon/Pixelfed.
|
||||
|
|
|
@ -11,17 +11,30 @@ instance = os.environ.get("I2M_INSTANCE")
|
|||
token = os.environ.get("I2M_TOKEN")
|
||||
check_interval = os.environ.get("I2M_CHECK_INTERVAL") #1 hour
|
||||
post_interval = os.environ.get("I2M_POST_INTERVAL") #1 hour
|
||||
use_mastodon = os.environ.get("I2M_USE_MASTODON") #max carouse is 4, if there's no limit set to -1
|
||||
use_mastodon = os.environ.get("I2M_USE_MASTODON") #max carousel is 4, if there's no limit set to -1
|
||||
fetch_count = os.environ.get("I2M_FETCH_COUNT") # how many instagram posts to fetch per check_interval
|
||||
print('instagram', instagram_user)
|
||||
print('instagram', instance)
|
||||
print(token)
|
||||
print(check_interval)
|
||||
print(post_interval)
|
||||
print(use_mastodon)
|
||||
print(fetch_count)
|
||||
print(user_name)
|
||||
print(user_password)
|
||||
if os.environ.get("I2M_SCHEDULED") == "True":
|
||||
scheduled_run = True # run continuously (if False) or a single time (if True)
|
||||
else:
|
||||
scheduled_run = False
|
||||
if os.environ.get("I2M_VERBOSE") == "True": # verbose output
|
||||
verbose_output = True
|
||||
else:
|
||||
verbose_output = False
|
||||
|
||||
if verbose_output:
|
||||
print('instagram', instagram_user)
|
||||
print('instagram', instance)
|
||||
print(token)
|
||||
print(check_interval)
|
||||
print(post_interval)
|
||||
print(use_mastodon)
|
||||
print(fetch_count)
|
||||
print(user_name)
|
||||
print(user_password)
|
||||
print(scheduled_run)
|
||||
print(verbose_output)
|
||||
|
||||
|
||||
|
||||
def flags(args, defaults):
|
||||
|
@ -52,6 +65,12 @@ def flags(args, defaults):
|
|||
defaults["user-name"] = args[count + 1]
|
||||
elif (args[count] == "--user-password"):
|
||||
defaults["user-password"] = args[count + 1]
|
||||
elif (args[count] == "--scheduled"):
|
||||
defaults["scheduled"] = True
|
||||
count -= 1
|
||||
elif (args[count] == "--verbose"):
|
||||
defaults["verbose"] = True
|
||||
count -= 1
|
||||
|
||||
else:
|
||||
print(Fore.RED + '❗ -> Wrong Argument Name!...')
|
||||
|
@ -75,7 +94,8 @@ def process_arguments(args, defaults):
|
|||
defaults["post-interval"] = int(post_interval) if post_interval != '' and post_interval else None
|
||||
defaults["fetch-count"] = int(fetch_count) if fetch_count != '' and fetch_count else None
|
||||
defaults["carousel-limit"] = int(use_mastodon) if use_mastodon != '' and use_mastodon else None
|
||||
defaults["carousel-limit"] = int(use_mastodon) if use_mastodon != '' and use_mastodon else None
|
||||
defaults["scheduled"] = bool(scheduled_run) if scheduled_run else False
|
||||
defaults["verbose"] = bool(verbose_output) if verbose_output else False
|
||||
#print(Fore.RED + '❗ -> Missing Argument ')
|
||||
#print(Style.RESET_ALL)
|
||||
#print(datetime.datetime.now())
|
||||
|
|
20
src/main.py
20
src/main.py
|
@ -13,9 +13,6 @@ from arguments import process_arguments
|
|||
from network import get_new_posts
|
||||
|
||||
|
||||
|
||||
print(sys.argv)
|
||||
print("ARGUMENTS")
|
||||
default_settings = {
|
||||
"instance": None,
|
||||
"instagram-user": None,
|
||||
|
@ -23,18 +20,27 @@ default_settings = {
|
|||
"user-password": None,
|
||||
"token": None,
|
||||
"check-interval": 3600,
|
||||
"post-interval": 3600,
|
||||
"post-interval": 60,
|
||||
"fetch-count" : 10,
|
||||
"carousel-limit": 4,
|
||||
"scheduled": False,
|
||||
"verbose": False
|
||||
}
|
||||
|
||||
settings = process_arguments(sys.argv, default_settings)
|
||||
|
||||
print('SETTINGS' , settings)
|
||||
verbose = settings["verbose"]
|
||||
|
||||
if verbose:
|
||||
print("ARGUMENTS")
|
||||
print(sys.argv)
|
||||
print('SETTINGS' , settings)
|
||||
|
||||
agree = [1, True, "true", "True", "yes", "Yes"]
|
||||
if (os.environ.get("USE_DOCKER")):
|
||||
id_filename = "/app/already_posted.txt"
|
||||
elif (os.environ.get("USE_KUBERNETES")):
|
||||
id_filename = "/data/already_posted.txt"
|
||||
else:
|
||||
id_filename = "./already_posted.txt"
|
||||
|
||||
|
@ -52,6 +58,8 @@ post_interval = settings["post-interval"]#1m
|
|||
|
||||
using_mastodon = settings["carousel-limit"] > 0;
|
||||
mastodon_carousel_size = settings["carousel-limit"]
|
||||
scheduled = settings["scheduled"]
|
||||
|
||||
|
||||
user = {
|
||||
"name": settings["user-name"],
|
||||
|
@ -68,4 +76,6 @@ mastodon = Mastodon(
|
|||
)
|
||||
while True:
|
||||
get_new_posts(mastodon, mastodon_carousel_size, post_limit, id_filename, using_mastodon, mastodon_carousel_size, post_interval, fetched_user, user)
|
||||
if scheduled:
|
||||
break
|
||||
time.sleep(time_interval_sec)
|
||||
|
|
|
@ -14,8 +14,10 @@ def get_instagram_user(user, fetched_user):
|
|||
print(Fore.GREEN + 'TEST 🚀 > Connecting to Instagram...')
|
||||
print(Style.RESET_ALL)
|
||||
print(datetime.datetime.now())
|
||||
print("USER USER USER!!!!!!!!!!!!!1", user)
|
||||
L.login(user["name"], user["password"])
|
||||
|
||||
if user["name"] != None:
|
||||
print("USER USER USER!!!!!!!!!!!!!", user["name"])
|
||||
L.login(user["name"], user["password"])
|
||||
return Profile.from_username(L.context, fetched_user)
|
||||
|
||||
def get_image(url):
|
||||
|
@ -62,7 +64,7 @@ def toot(urls, title, mastodon, fetched_user ):
|
|||
ids = []
|
||||
for url in urls:
|
||||
ids.append(upload_image_to_mastodon(url, mastodon))
|
||||
post_text = str(title) + "\n" + "crosposted from https://instagram.com/"+fetched_user # creating post text
|
||||
post_text = str(title) + "\n" # creating post text
|
||||
post_text = post_text[0:1000]
|
||||
if(ids):
|
||||
print(ids)
|
||||
|
|
Loading…
Reference in New Issue