update requipments.txt

This commit is contained in:
horhik 2021-11-23 10:38:49 +03:00
commit 497d04ad2d
13 changed files with 157 additions and 37 deletions

2
.gitignore vendored
View File

@ -1,3 +1,5 @@
*~
already_posted.txt
src/__pycache__/
.venv
.env.sh

0
Dockerfile Normal file → Executable file
View File

72
Docs.md Normal file
View File

@ -0,0 +1,72 @@
# Instagram2Fedi Docs 📜
## How to use
You can use Instagram2Fedi via docker or just like a python script
### With Docker 🐋
Specify your variables in `./env.sh` and then run `./run.sh`
You can modify `docker run` arguments in `./run.sh`
### Just a python script 🐍
Run `pip3 install -r requirements.txt` and then run `./insta2fedi`.
Specify your arguments. You should use `--use-docker 0`.
For example:
``` bash
./insta2fedi --use-docker false --instagram-user <instagram username> --instance <instance domain> --token <OAuth token> --check-interval 10 --post-interval 10 --use-mastodon 4
# will check for new post each 10 seconds
```
## Command line arguments 🖥
`--use-mastodon` - set not positive number (`0`, `-1`...) if your instance don't have max image count limit.
For example, default maximum photo count in mastodon is `4`
---
`--instance` - Your instance url
---
`--instagram-user` - Your instagram user name.
---
`--token` - Your OAuth token
---
`--check-interval` - Interval in seconds how often to check for new posts
---
`--post-interval` - Interval in seconds between posting new fetched posts.
If theres more than one new post, sets with which time interval should it post them
---
`--fetch-count` - How many new posts to select
---
`--use-docker` - If you're running it via docker container, set to `1` or `True`
## Default values ⚙
Default values are:
``` bash
--instance None
--instagram-user None
--token None
--check-interval 3600
--post-interval 3600
--fetch-count 10
--use-mastodon 4
--use-docker True
```

0
LICENSE Normal file → Executable file
View File

18
README.md Normal file → Executable file
View File

@ -1,22 +1,24 @@
# Instagram2Fedi <span><img width="50px" src="https://upload.wikimedia.org/wikipedia/commons/9/93/Fediverse_logo_proposal.svg"></span>
Simple python 🐍 script for crossposting from instagram to Mastodon/Pixelfed
Simple tool for crossposting posts from instagram to Mastodon/Pixelfed.
## Installing
## Using without docker
See [Docs.md](./Docs.md)
Just clone repo, build a docker container and run it
## Using with Docker
Just clone repo, specify variables and run it.
You can write all needed variables in `./env.sh` and then do `source ./run.sh`
``` bash
git clone https://github.com/horhik/instagram2fedi
cd instagram2fedi
docker build -t $YOUR_CONTAINER_NAME .
docker container run -it -d -v $(pwd):/app $YOUR_CONTAINER_NAME $I2M_INSTAGRAM_USER $I2M_INSTANCE $I2M_TOKEN
nano ./env.sh
source ./run.sh
```
You can write all needed variables in `./env.sh` and then do `source ./run.sh`
![image](https://user-images.githubusercontent.com/46262811/131577640-a3103ff2-af37-422d-96f1-60f1acdef939.png)
![screenshot](./img.png)

7
env.sh
View File

@ -1,8 +1,13 @@
#!/bin/sh
#!b/in/sh
# Required
export YOUR_CONTAINER_NAME=
export I2M_INSTAGRAM_USER=
export I2M_INSTANCE=
export I2M_TOKEN=
export I2M_CHECK_INTERVAL=3600 #1 hour
export I2M_POST_INTERVAL=3600 #1 hour
export I2M_USE_MASTODON=4 #max carousel length is 4, if there's no limit set to -1
export I2M_FETCH_COUNT=5 # how many instagram posts to fetch per check_interval

BIN
img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

2
insta2fedi Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
python3 src/main.py $@

2
run.sh
View File

@ -1,3 +1,3 @@
#!/bin/sh
source ./env.sh
docker build -t $YOUR_CONTAINER_NAME .; docker container run -it -v $(pwd):/app $YOUR_CONTAINER_NAME --instagram-user $I2M_INSTAGRAM_USER --instance $I2M_INSTANCE --token $I2M_TOKEN
docker build -t $YOUR_CONTAINER_NAME .; docker container run -it -v $(pwd):/app $YOUR_CONTAINER_NAME --use-docker 1 --instagram-user $I2M_INSTAGRAM_USER --instance $I2M_INSTANCE --token $I2M_TOKEN --check-interval $I2M_CHECK_INTERVAL --post-interval $I2M_POST_INTERVAL --fetch-count $I2M_FETCH_COUNT --use-mastodon $I2M_USE_MASTODON

View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import datetime
from colorama import Fore, Back, Style
def process_arguments(args, defaults):
count = 1
@ -11,28 +13,24 @@ def process_arguments(args, defaults):
defaults["token"] = args[count + 1]
elif (args[count] == "--check-interval"):
defaults["check-interval"] = args[count + 1]
defaults["check-interval"] = int(args[count + 1])
elif (args[count] == "--post-interval"):
defaults["post-interval"] = args[count + 1]
defaults["post-interval"] = int(args[count + 1])
elif (args[count] == "--fetch-count"):
defaults["fetch-count"] = args[count + 1]
defaults["fetch-count"] = int(args[count + 1])
elif (args[count] == "--using-mastodon"):
elif (args[count] == "--use-mastodon"):
defaults["carousel-limit"] = int(args[count + 1])
elif (args[count] == "--use-docker"):
defaults["use-docker"] = args[count + 1]
else:
print(Fore.RED + '❗ -> Wrong Argument Name!...')
print(Style.RESET_ALL)
print(datetime.datetime.now())
count +=2
return defaults
#fuck this shit im out''
#teenagers scare the living shit out of me
#deeeespaaaacito quero esperanto de despacito
#хорошо всё будет хорошо
#и камнем вниииз
#u kinda smell *smif* like a BAKA
#Yeren Yegaaaaaaa!!!!!!!!!

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from colorama import Fore, Back, Style
import datetime
def split_array(arr, size):
count = len(arr) // size + 1
@ -14,9 +16,10 @@ def try_to_get_carousel(array, post):
return urls
print(Fore.GREEN + "🎠 > Found carousel!")
print(Style.RESET_ALL)
print(datetime.datetime.now())
except Exception as e:
print(Fore.RED + "🎠💥 > No carousel :( \n", e)
print(Style.RESET_ALL)
print(datetime.datetime.now())
return array

View File

@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
import os
import sys
import time
import datetime
import json
from mastodon import Mastodon
from colorama import Fore, Back, Style
@ -11,9 +13,6 @@ from arguments import process_arguments
from network import get_new_posts
id_filename = "/app/already_posted.txt"
with open(id_filename, "a") as f:
f.write("\n")
print(sys.argv)
print("ARGUMENTS")
@ -24,13 +23,24 @@ default_settings = {
"check-interval": 3600,
"post-interval": 3600,
"fetch-count" : 10,
"carousel-limit": 4
"carousel-limit": 4,
"use-docker": True
}
settings = process_arguments(sys.argv, default_settings)
print(settings)
agree = [1, True, "true", "True", "yes", "Yes"]
if (agree.count(settings["use-docker"])):
id_filename = "/app/already_posted.txt"
else:
id_filename = "./already_posted.txt"
with open(id_filename, "a") as f:
f.write("\n")
fetched_user = settings["instagram-user"]
mastodon_instance = settings["instance"]
mastodon_token = settings["token"]
@ -42,19 +52,16 @@ post_interval = settings["post-interval"]#1m
using_mastodon = settings["carousel-limit"] > 0;
mastodon_carousel_size = settings["carousel-limit"]
print(Fore.GREEN + '🚀 > Connecting to Instagram...')
print(Style.RESET_ALL)
L = Instaloader()
profile = Profile.from_username(L.context, fetched_user)
print(Fore.GREEN + '🚀 > Connecting to Mastodon/Pixelfed...')
print(Style.RESET_ALL)
print(datetime.datetime.now())
mastodon = Mastodon(
access_token = mastodon_token,
api_base_url = mastodon_instance
# api_base_url = 'https://pixelfed.tokyo/'
)
while True:
get_new_posts(mastodon, profile, mastodon_carousel_size, post_limit, id_filename, using_mastodon, mastodon_carousel_size, post_interval, fetched_user)
get_new_posts(mastodon, mastodon_carousel_size, post_limit, id_filename, using_mastodon, mastodon_carousel_size, post_interval, fetched_user)
time.sleep(time_interval_sec)

View File

@ -1,44 +1,63 @@
# -*- coding: utf-8 -*-
from colorama import Fore, Back, Style
import requests
import time
import datetime
from already_posted import already_posted, mark_as_posted
from converters import split_array, try_to_get_carousel
import hashlib
from instaloader import Profile, Instaloader, LatestStamps
def get_instagram_user(user):
L = Instaloader()
print(Fore.GREEN + '🚀 > Connecting to Instagram...')
print(Style.RESET_ALL)
print(datetime.datetime.now())
return Profile.from_username(L.context, user)
def get_image(url):
try:
print(Fore.YELLOW + "🚀 > Downloading Image...", url)
print(Style.RESET_ALL)
print(datetime.datetime.now())
response = requests.get(url)
response.raw.decode_content = True
print(Fore.GREEN + "✨ > Downloaded!")
print(Style.RESET_ALL)
print(datetime.datetime.now())
return response.content
except Exception as e:
print(Fore.RED + "💥 > Failed to download image. \n", e)
print(Style.RESET_ALL)
print(datetime.datetime.now())
def upload_image_to_mastodon(url, mastodon):
try:
print(Fore.YELLOW + "🐘 > Uploading Image...")
print(Style.RESET_ALL)
print(datetime.datetime.now())
media = mastodon.media_post(media_file = get_image(url), mime_type = "image/jpeg") # sending image to mastodon
print(Fore.GREEN + "✨ > Uploaded!")
print(Style.RESET_ALL)
print(datetime.datetime.now())
return media["id"]
except Exception as e:
print(Fore.RED + "💥 > failed to upload image to mastodon. \n", e)
print(Style.RESET_ALL)
print(datetime.datetime.now())
def toot(urls, title, mastodon, fetched_user ):
try:
print(Fore.YELLOW + "🐘 > Creating Toot...", title)
print(Style.RESET_ALL)
print(datetime.datetime.now())
ids = []
for url in urls:
ids.append(upload_image_to_mastodon(url, mastodon))
@ -51,28 +70,38 @@ def toot(urls, title, mastodon, fetched_user ):
except Exception as e:
print(Fore.RED + "😿 > Failed to create toot \n", e)
print(Style.RESET_ALL)
print(datetime.datetime.now())
def get_new_posts(mastodon, profile, mastodon_carousel_size, post_limit, already_posted_path, using_mastodon, carousel_size, post_interval, fetched_user):
def get_new_posts(mastodon, mastodon_carousel_size, post_limit, already_posted_path, using_mastodon, carousel_size, post_interval, fetched_user):
# fetching user profile to get new posts
profile = get_instagram_user(fetched_user)
# get list of all posts
posts = profile.get_posts()
stupidcounter = 0
for post in posts:
stupidcounter += 1
url_arr = try_to_get_carousel([post.url], post)
if stupidcounter <= post_limit:
# checking only `post_limit` last posts
if stupidcounter < post_limit:
stupidcounter += 1
if already_posted(str(post.mediaid), already_posted_path):
print(Fore.YELLOW + "🐘 > Already Posted ", post.url)
print(Style.RESET_ALL)
print(datetime.datetime.now())
continue
print("Posting... ", post.url)
print(datetime.datetime.now())
if using_mastodon:
urls_arr = split_array(url_arr, carousel_size)
for urls in urls_arr:
toot(urls, post.caption, mastodon, fetched_user)
else:
toot(url_arr, post.caption, mastodon, fetched_user)
mark_as_posted(str(post.mediaid), already_posted_path)
mark_as_posted(str(post.mediaid), already_posted_path)
time.sleep(post_interval)
else:
return
break
print(Fore.GREEN + "✨ > Fetched All")
print(Style.RESET_ALL)
print(datetime.datetime.now())