diff --git a/.gitignore b/.gitignore index dd736c5..96b1dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ config.py flask_session/* -__pycache__/ \ No newline at end of file +__pycache__/ +venv/ +.env diff --git a/dev-server-start.cmd b/dev-server-start.cmd new file mode 100644 index 0000000..59a5083 --- /dev/null +++ b/dev-server-start.cmd @@ -0,0 +1,40 @@ +@echo off +cd %~dp0 + +setlocal enabledelayedexpansion + +REM Define the length of the random hex string +set "hex_length=128" + +REM Initialize the hex characters +set "hex_chars=0123456789abcdef" + +REM Variable to store the random hex string +set "random_hex=" + +REM Loop until the required length is reached +for /L %%i in (1,1,%hex_length%) do ( + REM Generate a random number between 0 and 15 + set /a "rand=((!random! * !random! + !random! %% 281 * %%i) + !time:~-2!) %% 16" + rem echo !rand! + + REM Get the hex character from hex_chars based on the random number + for %%r in (!rand!) do set "random_hex=!random_hex!!hex_chars:~%%r,1!" +) + +if not exist "config.py" ( + echo #!/bin/env python3 > config.py + echo SECRET_KEY = "%random_hex%" >> config.py +) + + +if not exist "venv/Scripts/activate.bat" ( + python3.exe -m venv venv +) + +call venv/Scripts/activate.bat +python3 -m pip install -r requirements.txt + +python3 server.py + +endlocal diff --git a/dev-server-start.sh b/dev-server-start.sh new file mode 100755 index 0000000..a8988ef --- /dev/null +++ b/dev-server-start.sh @@ -0,0 +1,27 @@ +#!/bin/env bash +set -o pipefail +set -e + +function main() +{ + cd "$(dirname "$0")" + if [[ ! -f "config.py" ]] + then + local SECRET_KEY="$(head -c 4096 /dev/urandom | sha512sum | sed 's/ .*//')" + cat > config.py << EOF +#!/bin/env python3 +SECRET_KEY = "$SECRET_KEY" +EOF + + fi + if [[ ! -f "venv/bin/activate" ]] + then + python3 -m venv venv + fi + . venv/bin/activate + python3 -m pip install -r requirements.txt + + python3 server.py +} + +main diff --git a/prod-server-start.sh b/prod-server-start.sh new file mode 100755 index 0000000..acf3c46 --- /dev/null +++ b/prod-server-start.sh @@ -0,0 +1,37 @@ +#!/bin/env bash +set -o pipefail +set -e + +function main() +{ + cd "$(dirname "$0")" + if [[ ! -f "config.py" ]] + then + local SECRET_KEY="$(head -c 4096 /dev/urandom | sha512sum | sed 's/ .*//')" + cat > config.py << EOF +#!/bin/env python3 +SECRET_KEY = "$SECRET_KEY" +EOF + + fi + if [[ ! -f "venv/bin/activate" ]] + then + python3 -m venv venv + fi + . venv/bin/activate + python3 -m pip install -r requirements.txt + + if [[ -e .env ]] + then + . .env + fi + + if [[ -n "$LISTEN" ]] + then + APP_BIND="--bind $LISTEN" + fi + + gunicorn $APP_BIND wsgi:app +} + +main diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5bfd94d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +flask +flask_session +atproto +argparse +requests +gunicorn diff --git a/server.py b/server.py old mode 100644 new mode 100755 index 42c3887..9b958dc --- a/server.py +++ b/server.py @@ -1,3 +1,4 @@ +#!/bin/env python3 from flask import Flask, request, render_template, redirect, flash, session from flask_session import Session from atproto import Client, models @@ -128,44 +129,44 @@ def send_thread (thread, request): firstPost=True str_nb_posts = str(len(thread)) langs = [request.form.get("lang")] - + print("nb posts : "+str_nb_posts) - + client = Client() login=session["name"] password=session["password"] - + print("- Envoi_thread : ", thread) print("form : "+str(request.form)); - + if (connection(client, login, password) == 0): for index, post in enumerate(thread): #print("index : "+str(index)) numerotation = str(index+1)+"/"+str_nb_posts - + try: # Trying to get an alt for this post alts = request.form.getlist("alt"+str(index+1)) #print("alts : ", alts) except Exception: alts = "" # no alt for this post #print("pas de alt récupéré") - + #print("input_images"+str(index+1)) images = request.files.getlist("input_images"+str(index+1)) print(images); - + if (firstPost): # Sending of the first post, which doesn't reference any post - + embed_images = [] facet = parse_facets(client, post) # print("facets : " + str(facet)) - + # Send with embed (images) if (images[0].filename != ""): embed_images = create_embed_images(client, images, alts, embed_images) - + print("Premier post avec une image") embed = models.AppBskyEmbedImages.Main(images=embed_images) print("embed : " + str(embed)) @@ -176,7 +177,7 @@ def send_thread (thread, request): record=models.AppBskyFeedPost.Main(created_at=client.get_current_time_iso(), text=post, embed=embed, langs=langs, facets=facet), ) )) - + # Send without embed (images) else: print("Premier post sans image") @@ -187,23 +188,23 @@ def send_thread (thread, request): record=models.AppBskyFeedPost.Main(created_at=client.get_current_time_iso(), text=post, langs=langs, facets=facet), ) )) - + print ("root_post_ref : " + str(root_post_ref)) - + parent_post_ref = root_post_ref # The first post ref becomes the ref for the parent post firstPost=False else: # Sending of another post, replying to the previous one - + embed_images = [] facet = parse_facets(client, post) # print("facets : " + str(facet)) - + if (images[0].filename != ""): # If there is images print("Post avec images") - embed_images = create_embed_images(client, images, alts, embed_images) + embed_images = create_embed_images(client, images, alts, embed_images) embed = models.AppBskyEmbedImages.Main(images=embed_images) - + parent_post_ref = models.create_strong_ref(client.com.atproto.repo.create_record( models.ComAtprotoRepoCreateRecord.Data( repo=client.me.did, @@ -220,9 +221,9 @@ def send_thread (thread, request): record=models.AppBskyFeedPost.Main(created_at=client.get_current_time_iso(), text=post, reply=models.AppBskyFeedPost.ReplyRef(parent=parent_post_ref, root=root_post_ref), langs=langs, facets=facet), ) )) - + print("- Post "+numerotation+" envoyé") - + # Once all the thread has been sent : we get the first post's url to return it post_id = re.match(r"^.*\/(.*)$", root_post_ref.uri).group(1) post_url = "https://bsky.app/profile/"+session.get("name")+"/post/"+post_id @@ -262,7 +263,7 @@ def parse_facets(client:Client, text: str) -> List[Dict]: except Exception as error: # if handle couldn't be resolved, just skip it! will be text in the post print("Error trying to resolve handle " + m["handle"] + " :", error) continue - + did = resp["did"] facets.append( { @@ -307,7 +308,7 @@ def parse_urls(text: str) -> List[Dict]: } ) return spans - + def parse_mentions(text: str) -> List[Dict]: spans = [] # regex based on: https://atproto.com/specs/handle#handle-identifier-syntax @@ -321,7 +322,7 @@ def parse_mentions(text: str) -> List[Dict]: "handle": m.group(1)[1:].decode("UTF-8"), } ) - return spans - + return spans + if __name__ == '__main__': - app.run(debug=True) \ No newline at end of file + app.run(debug=True) diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..1f160b8 --- /dev/null +++ b/wsgi.py @@ -0,0 +1,4 @@ +#!/bin/env python +from server import app +if __name__ == '__main__': + app.run()