maybe a fork of sparrowhe's "bluesky circle" webapp, to frontend only?

fix & chore: Docker, deps, filter, fs

+9
.dockerignore
··· 1 + lib/ 2 + lib64 3 + include/ 4 + bin/ 5 + share/ 6 + pyvenv.cfg 7 + static/ 8 + test.py 9 + *.png
-1
.gitignore
··· 176 176 static/ 177 177 test.py 178 178 *.png 179 - config.py
+10
Dockerfile
··· 1 + FROM python:3.12.7 2 + 3 + WORKDIR /usr/src/app 4 + COPY requirements.txt ./ 5 + RUN pip install --no-cache-dir -r requirements.txt 6 + COPY . . 7 + 8 + #CMD [ "gunicorn", "-w", "4", "--bind", "0.0.0.0" , "app:app" ] 9 + CMD ["flask", "run", "--port=8000", "--host=0.0.0.0"] 10 + EXPOSE 8000
-1
avatar/parse_friends.py
··· 1 1 from PIL import Image, ImageOps, ImageDraw 2 - import numpy as np 3 2 import math 4 3 import requests 5 4 from io import BytesIO
+3
avatar/routes.py
··· 13 13 client = at_client_extension.get_client() 14 14 15 15 handle = request.form.get('handle') 16 + # filter invisible characters 17 + handle = ''.join(filter(lambda x: x.isprintable(), handle)) 18 + handle.replace('@', '') 16 19 friends_data = parse_friends(client, handle) 17 20 center = client.get_profile(handle) 18 21 center_avatar_url = center.avatar
+9 -8
avatar/utils.py
··· 1 1 import requests 2 2 from PIL import Image, ImageOps, ImageDraw 3 3 from io import BytesIO 4 - import numpy as np 5 4 import math 6 5 import os 7 6 7 + PI=3.14 8 8 9 9 def check_cache_img(url): 10 + # Check if the cache path not exists 11 + if not os.path.join('static', 'avatars'): 12 + os.makedirs(os.path.join('static', 'avatars')) 13 + 10 14 # Check if the image is already cached 11 15 cache_path = os.path.join('static', 'avatars', os.path.basename(url.split('/')[-1]+'.jpg')) 12 16 if os.path.exists(cache_path): 13 17 return cache_path 14 18 return None 15 19 16 - def load_image_as_circle(image_url, radius, proxies={ 17 - 'https': 'http://127.0.0.1:7897', 18 - 'http': 'http://127.0.0.1:7897' 19 - }): 20 + def load_image_as_circle(image_url, radius, proxies=None): 20 21 try: 21 22 # Add proxy support in the request 22 23 if check_cache_img(image_url): ··· 87 88 avatar_size = avatar_radius * 2 # Diameter for resizing 88 89 89 90 # Calculate how many avatars fit in the current circle 90 - num_in_current_circle = int(2 * np.pi * radius / (avatar_size)) # Adjusted based on avatar size 91 - theta_step = 2 * np.pi / num_in_current_circle # Angle between avatars 92 - rotation_offset = layer * (np.pi / 12) # Rotate 15 degrees for each layer 91 + num_in_current_circle = int(2 * PI * radius / (avatar_size)) # Adjusted based on avatar size 92 + theta_step = 2 * PI / num_in_current_circle # Angle between avatars 93 + rotation_offset = layer * (PI / 12) # Rotate 15 degrees for each layer 93 94 94 95 for i in range(num_in_current_circle): 95 96 if friend_idx >= len(sorted_friends):
+11
config.py
··· 1 + import os 2 + 3 + class Config: 4 + """Configuration class for the Flask app.""" 5 + BASE_DIR = os.path.abspath(os.path.dirname(__file__)) 6 + UPLOAD_FOLDER = os.path.join(BASE_DIR, 'static/avatars') 7 + 8 + # BlueSky login credentials 9 + BLUESKY_HANDLE = os.getenv('BLUESKY_HANDLE', '') 10 + BLUESKY_PASSWORD = os.getenv('BLUESKY_PASSWORD', '') 11 + BLUESKY_BASE = os.getenv('BLUESKY_BASE', '')
-11
config.py.example
··· 1 - import os 2 - 3 - class Config: 4 - """Configuration class for the Flask app.""" 5 - BASE_DIR = os.path.abspath(os.path.dirname(__file__)) 6 - UPLOAD_FOLDER = os.path.join(BASE_DIR, 'static/avatars') 7 - 8 - # BlueSky login credentials 9 - BLUESKY_HANDLE = '' 10 - BLUESKY_PASSWORD = '' 11 - BLUESKY_BASE = ''
+2 -1
requirements.txt
··· 1 1 Flask==2.3.2 2 2 Pillow==10.0.0 3 3 requests==2.31.0 4 - numpy==1.23.5 4 + atproto==0.0.54 5 + gunicorn==23.0.0