1717import uuid
1818from pathlib import Path
1919
20- VERSION = "1.2 .0"
20+ VERSION = "1.3 .0"
2121CONFIG_DIR = Path .home () / ".config" / "image-upload-transit"
2222
2323IMAGE_EXTENSIONS = {".jpg" , ".jpeg" , ".png" , ".gif" , ".webp" , ".avif" , ".heic" , ".bmp" , ".tiff" , ".tif" , ".svg" }
2727MAX_IMAGE_SIZE = 25 * 1024 * 1024 # 25 MB
2828MAX_VIDEO_SIZE = 100 * 1024 * 1024 # 100 MB
2929
30- BUCKET_PROD = "transit-uploads-production"
31- BUCKET_STAGING = "transit-uploads-staging"
32- URL_PROD = "https://img.transitapp.com"
33- URL_STAGING = "https://img-staging.transitapp.com"
30+ BUCKET = "image-upload-cli-tool"
31+ BASE_URL = "https://img.transitapp.com"
3432
3533OP_VAULT = "Shared"
36- OP_ITEM_PROD = "image-upload-transit Service Account (Production)"
37- OP_ITEM_STAGING = "image-upload-transit Service Account (Staging)"
34+ OP_ITEM = "image-upload-transit Service Account (Production)"
3835
3936
4037class CredentialsError (Exception ):
@@ -65,11 +62,9 @@ def check_op_cli() -> None:
6562 raise CredentialsError ("Not signed in to 1Password. Run: op signin" )
6663
6764
68- def get_credentials (is_staging : bool = False , force_refresh : bool = False ) -> dict :
65+ def get_credentials (force_refresh : bool = False ) -> dict :
6966 """Fetch credentials from 1Password, caching to file."""
70- env_name = "staging" if is_staging else "production"
71- credentials_file = CONFIG_DIR / f"credentials-{ env_name } .json"
72- op_item = OP_ITEM_STAGING if is_staging else OP_ITEM_PROD
67+ credentials_file = CONFIG_DIR / "credentials.json"
7368
7469 if not force_refresh and credentials_file .exists ():
7570 with open (credentials_file ) as f :
@@ -78,7 +73,7 @@ def get_credentials(is_staging: bool = False, force_refresh: bool = False) -> di
7873 check_op_cli ()
7974
8075 result = subprocess .run (
81- ["op" , "item" , "get" , op_item , "--vault" , OP_VAULT , "--format" , "json" ],
76+ ["op" , "item" , "get" , OP_ITEM , "--vault" , OP_VAULT , "--format" , "json" ],
8277 capture_output = True ,
8378 text = True ,
8479 )
@@ -192,7 +187,7 @@ def get_access_token(credentials: dict) -> str:
192187 raise CredentialsError (f"Failed to obtain access token: { e } " )
193188
194189
195- def upload_file (filepath : str , bucket : str , base_url : str , credentials : dict ) -> str :
190+ def upload_file (filepath : str , credentials : dict ) -> str :
196191 """Validate file, generate short ID, upload to GCS, return URL."""
197192 path , ext = validate_file (filepath )
198193 short_id = uuid .uuid4 ().hex [:8 ]
@@ -208,7 +203,7 @@ def upload_file(filepath: str, bucket: str, base_url: str, credentials: dict) ->
208203 file_data = f .read ()
209204
210205 upload_url = (
211- f"https://storage.googleapis.com/upload/storage/v1/b/{ bucket } /o"
206+ f"https://storage.googleapis.com/upload/storage/v1/b/{ BUCKET } /o"
212207 f"?uploadType=media&name={ urllib .parse .quote (object_name )} "
213208 )
214209
@@ -226,7 +221,7 @@ def upload_file(filepath: str, bucket: str, base_url: str, credentials: dict) ->
226221 except urllib .error .URLError as e :
227222 raise ValueError (f"Upload failed: { e } " )
228223
229- return f"{ base_url } /{ object_name } "
224+ return f"{ BASE_URL } /{ object_name } "
230225
231226
232227def main () -> int :
@@ -238,7 +233,6 @@ def main() -> int:
238233Examples:
239234 %(prog)s image.png Upload a single image
240235 %(prog)s *.jpg Upload multiple images
241- %(prog)s -s screenshot.png Upload to staging environment
242236 %(prog)s --json photo.jpg Output result as JSON (for scripting/agents)
243237
244238JSON Output Format (--json):
@@ -252,7 +246,6 @@ def main() -> int:
252246 formatter_class = argparse .RawDescriptionHelpFormatter ,
253247 )
254248 parser .add_argument ("files" , nargs = "*" , help = "Files to upload" )
255- parser .add_argument ("-s" , "--staging" , action = "store_true" , help = "Use staging environment" )
256249 parser .add_argument ("-v" , "--version" , action = "version" , version = f"%(prog)s { VERSION } " )
257250 parser .add_argument ("--json" , action = "store_true" , help = "Output results as JSON (one object per line, for scripting/agents)" )
258251 parser .add_argument ("--refresh-credentials" , action = "store_true" , help = "Force re-fetch credentials from 1Password" )
@@ -274,12 +267,11 @@ def output_result(file: str, url: str = None, err: str = None) -> None:
274267
275268 if args .refresh_credentials and not args .files :
276269 try :
277- get_credentials (is_staging = args .staging , force_refresh = True )
278- env_name = "staging" if args .staging else "production"
270+ get_credentials (force_refresh = True )
279271 if args .json :
280- print (json .dumps ({"action" : "refresh_credentials" , "environment" : env_name , " success" : True }))
272+ print (json .dumps ({"action" : "refresh_credentials" , "success" : True }))
281273 else :
282- success (f "Credentials refreshed for { env_name } " )
274+ success ("Credentials refreshed" )
283275 return 0
284276 except CredentialsError as e :
285277 if args .json :
@@ -292,11 +284,8 @@ def output_result(file: str, url: str = None, err: str = None) -> None:
292284 parser .print_help ()
293285 return 1
294286
295- bucket = BUCKET_STAGING if args .staging else BUCKET_PROD
296- base_url = URL_STAGING if args .staging else URL_PROD
297-
298287 try :
299- credentials = get_credentials (is_staging = args . staging , force_refresh = args .refresh_credentials )
288+ credentials = get_credentials (force_refresh = args .refresh_credentials )
300289 except CredentialsError as e :
301290 if args .json :
302291 print (json .dumps ({"error" : str (e ), "success" : False }))
@@ -307,7 +296,7 @@ def output_result(file: str, url: str = None, err: str = None) -> None:
307296 exit_code = 0
308297 for filepath in args .files :
309298 try :
310- url = upload_file (filepath , bucket , base_url , credentials )
299+ url = upload_file (filepath , credentials )
311300 output_result (filepath , url = url )
312301 except ValueError as e :
313302 output_result (filepath , err = str (e ))
0 commit comments