@@ -103,6 +103,11 @@ def submit_new_app():
103103 appinfo_valid , appinfo_validation_error = is_valid_appinfo (appinfo )
104104 if not appinfo_valid :
105105 return jsonify (error = f"The appinfo.json in your pbw file has the following error: { appinfo_validation_error } " , e = "invalid.appinfocontent" ), 400
106+
107+ if params ["type" ] == "watchface" and not appinfo ["watchapp" ]["watchface" ]:
108+ return jsonify (error = f"You selected the app type 'Watchface'. This does not match the configuration in your appinfo.json" , e = "invalid.appinfocontent" ), 400
109+ elif params ["type" ] == "watchapp" and appinfo ["watchapp" ]["watchface" ]:
110+ return jsonify (error = f"You selected the app type 'Watch App'. This does not match the configuration in your appinfo.json" , e = "invalid.appinfocontent" ), 400
106111
107112 # Check app doesn't already exist
108113 try :
@@ -139,7 +144,6 @@ def submit_new_app():
139144
140145 # Remove any platforms with no screenshots
141146 screenshots = {k : v for k , v in screenshots .items () if v }
142-
143147 app_obj = App (
144148 id = id_generator .generate (),
145149 app_uuid = appinfo ['uuid' ],
@@ -157,7 +161,7 @@ def submit_new_app():
157161 hearts = 0 ,
158162 releases = [],
159163 icon_large = upload_asset (request .files ['large_icon' ], request .files ["large_icon" ].content_type ),
160- icon_small = upload_asset (request .files ['small_icon' ], request .files ["small_icon" ].content_type ) if 'small_icon' in params else '' ,
164+ icon_small = upload_asset (request .files ['small_icon' ], request .files ["small_icon" ].content_type ) if 'small_icon' in request . files else '' ,
161165 source = params ['source' ] if 'source' in params else "" ,
162166 title = params ['title' ],
163167 type = params ['type' ],
@@ -180,7 +184,7 @@ def submit_new_app():
180184 algolia_index .partial_update_objects ([algolia_app (app_obj )], { 'createIfNotExists' : True })
181185
182186 try :
183- announce_new_app (app_obj )
187+ announce_new_app (app_obj , pbw . is_generated () )
184188 except Exception :
185189 # We don't want to fail just because Discord is being weird
186190 print ("Discord is being weird" )
@@ -309,7 +313,7 @@ def submit_new_release(app_id):
309313 db .session .commit ()
310314
311315 try :
312- announce_release (app , release_new )
316+ announce_release (app , release_new , pbw . is_generated () )
313317 except Exception :
314318 # We don't want to fail just because Discord webhook is being weird
315319 print ("Discord is being weird" )
@@ -522,6 +526,68 @@ def delete_banner(app_id, platform, banner_id):
522526 db .session .commit ()
523527 return jsonify (success = True , message = f"Deleted banner { banner_id } " , id = banner_id , platform = platform )
524528
529+ @devportal_api .route ('/app/<app_id>/icons' , methods = ['GET' ])
530+ def get_app_icons (app_id ):
531+ try :
532+ app = App .query .filter (App .id == app_id ).one ()
533+ except NoResultFound as e :
534+ return jsonify (error = "Unknown app" , e = "app.notfound" ), 404
535+
536+
537+ return jsonify (small = app .icon_small , large = app .icon_large )
538+
539+ @devportal_api .route ('/app/<app_id>/icon/<size>' , methods = ['GET' ])
540+ def get_app_icon (app_id , size ):
541+ if size not in ("large" , "small" ):
542+ return jsonify (error = "Invalid icon size. Expected 'small' or 'large'." , e = "size.invalid" ), 404
543+
544+ try :
545+ app = App .query .filter (App .id == app_id ).one ()
546+ except NoResultFound as e :
547+ return jsonify (error = "Unknown app" , e = "app.notfound" ), 404
548+
549+ out = app .icon_small if size == "small" else app .icon_large
550+ return jsonify (out )
551+
552+ @devportal_api .route ('/app/<app_id>/icon/<size>' , methods = ['POST' ])
553+ def new_app_icon (app_id , size ):
554+ if size not in ("large" , "small" ):
555+ return jsonify (error = "Invalid icon size. Expected 'small' or 'large'." , e = "size.invalid" ), 404
556+
557+ try :
558+ app = App .query .filter (App .id == app_id ).one ()
559+ except NoResultFound as e :
560+ return jsonify (error = "Unknown app" , e = "app.notfound" ), 404
561+
562+ # Check we own the app
563+ if not is_users_developer_id (app .developer_id ):
564+ return jsonify (error = "You do not have permission to modify that app" , e = "permission.denied" ), 403
565+
566+ # Get the image, this is a single image API
567+ if "icon" in request .files :
568+ new_image = request .files ["icon" ]
569+ else :
570+ return jsonify (error = "Missing file: icon" , e = "icon.missing" ), 400
571+
572+ # Check it's a valid image file
573+ if not is_valid_image_file (new_image ):
574+ return jsonify (error = "Illegal image type" , e = "icon.illegalvalue" ), 400
575+
576+ # Check it's the correct size
577+ if not is_valid_image_size (new_image , f"{ size } _icon" ):
578+ max_w , max_h = get_max_image_dimensions ("icon" )
579+ return jsonify (error = "Invalid image size" , e = "icon.illegaldimensions" , message = f"Image should be { max_w } x{ max_h } " ), 400
580+
581+ new_image_id = upload_asset (new_image , new_image .content_type )
582+ if size == "large" :
583+ app .icon_large = new_image_id
584+ elif size == "small" :
585+ app .icon_small = new_image_id
586+ db .session .commit ()
587+
588+ return jsonify (success = True , id = new_image_id , size = size )
589+
590+
525591
526592@devportal_api .route ('/wizard/rename/<developer_id>' , methods = ['POST' ])
527593def wizard_rename_developer (developer_id ):
0 commit comments