This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

first working version

+92 -18
+92 -18
src/main.py
··· 1 - #!/usr/bin/env python3 2 1 import os 3 2 import json 4 3 import logging 4 + import requests 5 + import magic 5 6 from datetime import datetime 6 7 from dotenv import load_dotenv 7 8 from atproto import Client, models 9 + from atproto.exceptions import BadRequestError 8 10 9 11 # Define the paths 10 12 BASE_DIR = os.path.abspath(os.path.dirname(__file__)) ··· 24 26 console_handler.setFormatter(formatter) 25 27 logging.getLogger().addHandler(console_handler) 26 28 29 + 30 + def ensure_https(url): 31 + if not url.startswith("http://") and not url.startswith("https://"): 32 + return "https://" + url 33 + if url.startswith("http://"): 34 + return "https://" + url[7:] 35 + return url 36 + 37 + 38 + def is_endpoint_alive(url): 39 + health_url = f"{url.rstrip('/')}/xrpc/_health" 40 + try: 41 + response = requests.get(health_url, timeout=5) 42 + return response.status_code == 200 43 + except requests.RequestException as e: 44 + logging.error(f"Health check failed for {health_url}: {e}") 45 + return False 46 + 47 + 48 + def fetch_blob(did, cid, endpoint): 49 + url = f"{endpoint}/xrpc/com.atproto.sync.getBlob?did={did}&cid={cid}" 50 + try: 51 + response = requests.get(url, timeout=5) 52 + response.raise_for_status() 53 + return response.content 54 + except requests.RequestException as e: 55 + logging.error(f"Failed to fetch blob {cid} for DID {did}: {e}") 56 + return None 57 + 58 + 59 + def get_blob_metadata(cid, did, endpoint): 60 + blob_data = fetch_blob(did, cid, endpoint) 61 + if blob_data is None: 62 + return None 63 + 64 + mime = magic.Magic(mime=True) 65 + mime_type = mime.from_buffer(blob_data) 66 + size = len(blob_data) 67 + 68 + return { 69 + "$type": "blob", 70 + "ref": {"$link": cid}, 71 + "mimeType": mime_type, 72 + "size": size, 73 + } 74 + 27 75 def main(): 28 76 logging.info("Starting avatar update script...") 29 77 ··· 36 84 endpoint = os.getenv("ENDPOINT") 37 85 handle = os.getenv("HANDLE") 38 86 password = os.getenv("PASSWORD") 87 + did = os.getenv("DID") 39 88 40 - if not (endpoint and handle and password): 41 - logging.error("Missing environment variables. Ensure ENDPOINT, HANDLE, and PASSWORD are set in .env file.") 89 + if not (endpoint and handle and password and did): 90 + logging.error( 91 + "Missing environment variables. Ensure ENDPOINT, HANDLE, PASSWORD, and DID are set in .env file." 92 + ) 93 + return 94 + 95 + endpoint = ensure_https(endpoint) 96 + if not is_endpoint_alive(endpoint): 97 + logging.error(f"Endpoint {endpoint} is not responding.") 42 98 return 43 99 44 100 try: ··· 60 116 client = Client(endpoint) 61 117 62 118 try: 63 - profile = client.login(handle, password) 64 - logging.info(f"Authentication successful. Welcome, {profile.display_name}") 65 - did = profile.did 66 - logging.info(f"User DID: {did}") 119 + client.login(handle, password) 120 + logging.info("Authentication successful.") 67 121 except Exception as e: 68 122 logging.error(f"Authentication failed: {e}") 69 123 return 70 124 71 - updated_profile_data = { 72 - "$type": "app.bsky.actor.profile", 73 - "avatar": { 74 - "cid": new_blob_cid 75 - } 76 - } 125 + try: 126 + current_profile_record = client.app.bsky.actor.profile.get( 127 + client.me.did, "self" 128 + ) 129 + current_profile = current_profile_record.value 130 + swap_record_cid = current_profile_record.cid 131 + except BadRequestError: 132 + current_profile = swap_record_cid = None 133 + 134 + old_description = old_display_name = None 135 + if current_profile: 136 + old_description = current_profile.description 137 + old_display_name = current_profile.display_name 138 + 139 + blob_metadata = get_blob_metadata(new_blob_cid, did, endpoint) 77 140 78 - logging.debug(f"Updated profile data: {updated_profile_data}") 141 + if blob_metadata is None: 142 + logging.error(f"Could not retrieve metadata for blob CID: {new_blob_cid}") 143 + return 79 144 80 145 try: 81 146 client.com.atproto.repo.put_record( 82 - repo=did, 83 - collection="app.bsky.actor.profile", 84 - rkey="self", 85 - record=updated_profile_data 147 + models.ComAtprotoRepoPutRecord.Data( 148 + collection=models.ids.AppBskyActorProfile, 149 + repo=client.me.did, 150 + rkey="self", 151 + swap_record=swap_record_cid, 152 + record=models.AppBskyActorProfile.Record( 153 + avatar=blob_metadata, 154 + banner=current_profile.banner if current_profile else None, 155 + description=old_description, 156 + display_name=old_display_name, 157 + ), 158 + ) 86 159 ) 87 160 logging.info("Avatar updated successfully!") 88 161 except Exception as e: 89 162 logging.error(f"Failed to update profile record: {e}") 163 + 90 164 91 165 if __name__ == "__main__": 92 166 main()