@@ -46,10 +46,28 @@ def sha256sum(filename):
4646 h .update (chunk )
4747 return h .hexdigest ()
4848
49+ def check_file_exists (dbx , dropbox_path ):
50+ try :
51+ dbx .files_get_metadata (dropbox_path )
52+ return True
53+ except dropbox .exceptions .ApiError :
54+ return False
55+
56+ def get_or_create_shared_link (dbx , dropbox_path ):
57+ try :
58+ links = dbx .sharing_list_shared_links (path = dropbox_path ).links
59+ if links :
60+ return make_direct_download_link (links [0 ].url )
61+ else :
62+ link_metadata = dbx .sharing_create_shared_link_with_settings (dropbox_path )
63+ return make_direct_download_link (link_metadata .url )
64+ except dropbox .exceptions .ApiError as e :
65+ print (f"⚠️ Could not get or create shared link for { dropbox_path } : { e } " )
66+ return None
67+
4968def upload_to_dropbox (local_path , dropbox_folder , access_token ):
5069 dbx = dropbox .Dropbox (access_token )
5170 filename = os .path .basename (local_path )
52-
5371 # Upload path: /<codename>/<filename>
5472 dropbox_path = f"/{ dropbox_folder } /{ filename } " .replace ("//" , "/" )
5573
@@ -67,7 +85,6 @@ def upload_to_dropbox(local_path, dropbox_folder, access_token):
6785 offset = CHUNK_SIZE
6886 with tqdm (total = file_size , unit = 'B' , unit_scale = True , desc = 'Uploading' ) as pbar :
6987 pbar .update (CHUNK_SIZE )
70-
7188 while offset < file_size :
7289 chunk = f .read (CHUNK_SIZE )
7390 if (file_size - offset ) <= CHUNK_SIZE :
@@ -80,29 +97,17 @@ def upload_to_dropbox(local_path, dropbox_folder, access_token):
8097 cursor .offset = offset
8198 pbar .update (len (chunk ))
8299
83- try :
84- link_metadata = dbx .sharing_create_shared_link_with_settings (dropbox_path )
85- except dropbox .exceptions .ApiError as e :
86- if e .error .is_shared_link_already_exists ():
87- links = dbx .sharing_list_shared_links (path = dropbox_path ).links
88- if links :
89- link_metadata = links [0 ]
90- else :
91- print ("⚠️ Failed to retrieve existing shared link." )
92- sys .exit (1 )
93- else :
94- print (f"❌ Failed to create shared link: { e } " )
95- sys .exit (1 )
96-
97- direct_link = make_direct_download_link (link_metadata .url )
98- print ("✅ Direct Download Link:" )
99- print (direct_link )
100- return direct_link
100+ return get_or_create_shared_link (dbx , dropbox_path )
101101
102102def main ():
103+ args = sys .argv [1 :]
104+ no_upload = "--no-upload" in args
105+ codename_arg = next ((arg for arg in args if not arg .startswith ("--" )), None )
106+
103107 access_token = load_access_token ()
108+ dbx = dropbox .Dropbox (access_token )
104109
105- codename = input ("Enter device codename (e.g. PL2, miatoll): " ).strip ()
110+ codename = codename_arg . strip () if codename_arg else input ("Enter device codename (e.g. PL2, miatoll): " ).strip ()
106111 ota_dir = os .path .join ("out" , "target" , "product" , codename )
107112
108113 try :
@@ -115,9 +120,12 @@ def main():
115120 print (f"❌ No OTA zip found in { ota_dir } matching pattern AndroidOne-*{ codename } -*.zip" )
116121 sys .exit (1 )
117122
118- filename = files [0 ]
119- file_path = os .path .join (ota_dir , filename )
120- print (f"📦 Found OTA package: { file_path } " )
123+ ota_filename = files [0 ]
124+ ota_filepath = os .path .join (ota_dir , ota_filename )
125+ dropbox_path = f"/{ codename } /{ ota_filename } "
126+ print (f"📦 Found OTA package: { ota_filepath } " )
127+
128+ android_exp_files = [f for f in os .listdir (ota_dir ) if f .startswith ("AndroidExperience" )]
121129
122130 build_prop = os .path .join (ota_dir , "system" , "build.prop" )
123131 datetime = "UNKNOWN"
@@ -128,29 +136,51 @@ def main():
128136 datetime = line .strip ().split ("=" )[1 ]
129137 break
130138
131- file_id = sha256sum (file_path )
132- file_size = os .path .getsize (file_path )
133- version = "15" # Adjust this if needed
134-
135- dropbox_link = upload_to_dropbox (file_path , codename , access_token )
139+ version = "15"
140+ ota_file_id = sha256sum (ota_filepath )
141+ ota_file_size = os .path .getsize (ota_filepath )
136142
137- output_dir = os .path .join (SCRIPT_DIR , "devices" )
138- os .makedirs (output_dir , exist_ok = True )
139- output_file = os .path .join (output_dir , f"{ codename } .json" )
143+ if no_upload :
144+ print ("⏩ --no-upload specified, skipping all uploads..." )
145+ if check_file_exists (dbx , dropbox_path ):
146+ print (f"ℹ️ OTA file exists on Dropbox: { dropbox_path } " )
147+ ota_link = get_or_create_shared_link (dbx , dropbox_path ) or "LINK_NOT_FOUND"
148+ else :
149+ print (f"⚠️ OTA file not found on Dropbox at { dropbox_path } " )
150+ ota_link = "NOT_FOUND_ON_DROPBOX"
151+ else :
152+ if check_file_exists (dbx , dropbox_path ):
153+ print (f"✅ File already exists on Dropbox: { dropbox_path } " )
154+ ota_link = get_or_create_shared_link (dbx , dropbox_path )
155+ else :
156+ print ("⬆️ File not found on Dropbox, proceeding to upload..." )
157+ ota_link = upload_to_dropbox (ota_filepath , codename , access_token )
158+
159+ if android_exp_files :
160+ recovery_path = os .path .join (ota_dir , "recovery.img" )
161+ if os .path .isfile (recovery_path ):
162+ print ("🔍 AndroidExperience file detected, uploading recovery.img (no JSON entry)..." )
163+ upload_to_dropbox (recovery_path , codename , access_token )
164+ else :
165+ print ("⚠️ recovery.img NOT found — skipping." )
140166
141167 ota_json = {
142168 "response" : [
143169 {
144170 "datetime" : datetime ,
145- "filename" : filename ,
146- "id" : file_id ,
147- "size" : file_size ,
148- "url" : dropbox_link ,
171+ "filename" : ota_filename ,
172+ "id" : ota_file_id ,
173+ "size" : ota_file_size ,
174+ "url" : ota_link ,
149175 "version" : version
150176 }
151177 ]
152178 }
153179
180+ output_dir = os .path .join (SCRIPT_DIR , "devices" )
181+ os .makedirs (output_dir , exist_ok = True )
182+ output_file = os .path .join (output_dir , f"{ codename } .json" )
183+
154184 with open (output_file , "w" ) as f :
155185 json .dump (ota_json , f , indent = 2 )
156186
0 commit comments