def app_delete_view(request, country=None, app_id=None): app = AppStoreApp.find_by_encrypted_id(app_id) if not app: return not_found() if not country or country not in appstore.APPSTORE_COUNTRIES_BY_CODE: return not_found() success = appstore.mark_not_interested_in_app(request.user, app, country) if not success: return not_found() return ok_response()
def screenshot_delete_shot_view(request, set_id=None, shot_id=None): my_set, shots = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id) if not my_set: return not_found() shot = [s for s in shots if s.encrypted_id == shot_id] if not shot: return not_found() shot = shot[0] screenshots.delete_shot_in_set(my_set, shot) return ok_response()
def website_page_by_domain_view(request, domain=None, slug=None): website = AppWebsite.objects.filter(domain=domain).first() if not website or website.delete_time: return not_found() page = None if slug: page = AppWebsitePage.objects.filter(website=website.id, slug=slug).first() if not page: return not_found() return api_response({ 'website': website.to_dict(), 'page': page and page.to_dict(), })
def archive_download_view(request, basename=None): logging.info('basename: %s', basename) filename = os.path.join(screenshot_bundler.LOCAL_ARCHIVE_DIR, basename) if not os.path.isfile(filename): return not_found() if not os.path.abspath(filename).startswith(screenshot_bundler.LOCAL_ARCHIVE_DIR): return not_found() wrapper = FileWrapper(file(filename)) response = HttpResponse(wrapper, content_type='application/zip') response['Content-Length'] = os.path.getsize(filename) response['Content-Disposition'] = 'attachment; filename=%s' % basename return response
def _website_page_view_GET(request, website_id, slug): website_id = AppWebsite.decrypt_id(website_id) if not website_id: return not_found() website = (AppWebsite.objects.filter(id=website_id).select_related( 'icon', 'background', 'logo').first()) if not website or website.delete_time: return not_found() page = AppWebsitePage.objects.get(website=website_id, slug=slug) if not page: return not_found() return api_response({'website': website.to_dict(), 'page': page.to_dict()})
def _website_view_GET(request, website_id): website_id = AppWebsite.decrypt_id(website_id) if not website_id: return not_found() website = (AppWebsite.objects.filter(id=website_id).select_related( 'icon', 'background', 'logo').first()) if not website or website.delete_time: return not_found() get_website_and_pages = request.GET.get('get_website_and_pages', False) return api_response({ 'website': website.to_dict(get_website_and_pages), })
def config_rule_view(request, rule_id): rule = RuntimeConfigRule.objects.filter( id=RuntimeConfigRule.decrypt_id(rule_id), user_id=request.user.id).first() if not rule: return not_found() if request.method == 'POST': target_form = EditRuleForm(request.POST) if not target_form.is_valid(): return bad_request('Invalid edit config values.', errors=target_form.errors) cleaned_data = target_form.cleaned_data if 'value' in request.POST: value_form = ValueForm(rule.kind, request.POST) if not value_form.is_valid(): return bad_request('Invalid edit config values.', errors=value_form.errors) cleaned_data.update(value_form.cleaned_data) # strip out arguments that were not present in the actual POSTbody. cleaned_data = { k: v for k, v in cleaned_data.items() if k in request.POST } runtime_config.update_rule(rule, **cleaned_data) return api_response({ 'rule': rule.to_dict(), })
def screenshot_set_add_shot_view(request, set_id=None): my_set = screenshots.get_set_by_encrypted_id(request.user, set_id) if not my_set: return not_found() if my_set.shot_count >= 5: return bad_request('Maximum number of shots in this set already.') form = CreateUpdateShotForm(request.POST) if not form.is_valid(): logging.warn('Invalid shot data: %s', dict(form.errors)) return bad_request('Invalid shot data.', errors=form.errors) if not form.cleaned_data.get('screenshot_image_id'): return bad_request('Please supply `screenshot_image_id`.') fields = form.cleaned_data post_keys = set(request.POST.keys()) for key in fields.keys(): if key not in post_keys: # default from the form del fields[key] fields['screenshot_image'] = fields['screenshot_image_id'] del fields['screenshot_image_id'] if 'background_image_id' in fields: fields['background_image'] = fields['background_image_id'] del fields['background_image_id'] shot = screenshots.create_shot_in_set(request.user, my_set, **fields) return api_response({ 'shot': shot.to_dict(), })
def screenshot_set_create_bundle_view(request, set_id=None): my_set, shots = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id, enable_logged_out=False) if not my_set: return not_found() upload_ids = request.POST.getlist('upload_id') or [] try: upload_ids = [long(i) for i in upload_ids] except (ValueError, TypeError): logging.info('invalid upload_ids: %s (set id: %s)', upload_ids, set_id) return bad_request('Invalid `upload_id`, each should be long integer.') if not upload_ids: logging.info('upload ids: %s body: %s %s %s', upload_ids, request.body, request.POST, request.method) return bad_request('Invalid `upload_id`, each should be a GAE upload ID.') upload_names = filter(lambda n: n and n.strip(), request.POST.getlist('upload_name') or []) if len(upload_ids) != len(upload_names): logging.info('invalid upload_names: %s upload_ids: %s (set id: %s)', upload_ids, upload_names, set_id) return bad_request('Invalid `upload_name`, each should be an upload filename corresponding to the `upload_id` provided.') hq = request.POST.get('hq') == '1' bundle = screenshot_bundler.build_screenshot_bundle(my_set, request.user, upload_ids, upload_names, hq=hq) if not bundle: return unavailable_response() return api_response({ 'bundleId': bundle.encrypted_id, })
def config_rule_view(request, rule_id): rule = RuntimeConfigRule.objects.filter( id=RuntimeConfigRule.decrypt_id(rule_id), user_id=request.user.id).first() if not rule: return not_found() if request.method == 'POST': target_form = EditRuleForm(request.POST) if not target_form.is_valid(): return bad_request('Invalid edit config values.', errors=target_form.errors) cleaned_data = target_form.cleaned_data if 'value' in request.POST: value_form = ValueForm(rule.kind, request.POST) if not value_form.is_valid(): return bad_request('Invalid edit config values.', errors=value_form.errors) cleaned_data.update(value_form.cleaned_data) # strip out arguments that were not present in the actual POSTbody. cleaned_data = {k: v for k, v in cleaned_data.items() if k in request.POST} runtime_config.update_rule(rule, **cleaned_data) return api_response({ 'rule': rule.to_dict(), })
def subscription_delete_view(request, subscription_id=None): sub = appstore_sales_report_subscriptions.get_user_subscription_by_encrypted_id(request.user, subscription_id) if not sub: return not_found() appstore_sales_report_subscriptions.disable_subscription(sub) return ok_response()
def screenshot_set_delete_view(request, set_id=None): my_set, _ = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id) if not my_set: return not_found() screenshots.delete_my_set(request.user, my_set) return ok_response()
def token_view(request, token_id=None): token = tokens.get_my_token_by_encrypted_id(request.user, token_id) if not token: return not_found() return api_response({ 'token': token.to_dict(), })
def subscription_delete_view(request, subscription_id=None): sub = appstore_review_subscriptions.get_user_subscription_by_encrypted_id(request.user, subscription_id) if not sub: return not_found() appstore_review_subscriptions.disable_subscription(sub) return ok_response()
def user_by_id(request, user_id=None): user = User.find_by_encrypted_id(user_id) if not user: return not_found() return api_response({ 'user': user.to_minimal_dict() })
def delete_website_view(request, website_id=None): website = AppWebsite.find_by_encrypted_id(website_id, user_id=request.user.id, for_update=True) if not website or website.delete_time: return not_found() websites.delete_website(website) return ok_response()
def _screenshot_set_view_GET(request, set_id=None): the_set, shots = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id, enable_logged_out=True) if not the_set: return not_found() return api_response({ 'set': the_set.to_dict(), 'shots': [shot.to_dict() for shot in shots], })
def _website_view_POST(request, website_id): website = AppWebsite.find_by_encrypted_id(website_id, user_id=request.user.id, for_update=True) if not website or website.delete_time: return not_found() # FORM VALIDATION form = EditAppWebsiteForm(request.POST) if not form.is_valid(): logging.info('Website edit problem (id=%s): %s', website.encrypted_id, dict(form.errors)) return bad_request('Invalid website data.', errors=form.errors) domain = form.cleaned_data.get('domain') if domain: in_use_website = AppWebsite.objects.filter(domain=domain).exclude( id=website.id).count() if in_use_website: return bad_request('Invalid website data', errors={'domain': ['Domain already in use.']}) screenshots_form = AppWebsiteScreenshotsForm(request.POST) if not screenshots_form.is_valid(): logging.info('Website screenshots problem (id=%s): %s', website.encrypted_id, dict(screenshots_form.errors)) return bad_request('Invalid screenshots provided.', errors=screenshots_form.errors) # ASSIGN MODIFIED PROPERTIES # Only assign values that were actually passed in the POSTbody. _assign_properties_from_dict( website, form.cleaned_model_data(filter_values=request.POST)) # UPDATE ASSOCIATED SCREENSHOTS iphone_screenshots = screenshots_form.cleaned_data.get( 'iphone_screenshot_ids', []) if iphone_screenshots: websites.update_website_screenshots(website, iphone_screenshots, 'iPhone') # UPDATE HOSTED PAGES hosted_pages = EditPageForm(request.POST) if not hosted_pages.is_valid(): return bad_request('Invalid website data.', errors=hosted_pages.errors) for field in hosted_pages: # Check if this field was actually included in the POSTdata with this request. if field.name in request.POST: websites.create_or_update_hosted_page(website, field.name, field.value()) website.save() return api_response({'website': website.to_dict()})
def _website_view_GET(request, website_id): website_id = AppWebsite.decrypt_id(website_id) if not website_id: return not_found() website = ( AppWebsite.objects .filter(id=website_id) .select_related('icon', 'background', 'logo') .first() ) if not website or website.delete_time: return not_found() get_website_and_pages = request.GET.get('get_website_and_pages', False) return api_response({ 'website': website.to_dict(get_website_and_pages), })
def screenshot_delete_override(request, set_id=None, shot_id=None, device_type=None): override = screenshots.get_shot_override_by_encrypted_id(request.user, shot_id, device_type) if not override: return not_found() screenshots.delete_override_image(override) return ok_response()
def _single_card_view(request, app_id_or_bundle_id=None, **kwargs): app_id = SDKApp.decrypt_id(app_id_or_bundle_id) if not app_id: app_id = SDKApp.objects.filter(user=request.user, bundle_id=app_id_or_bundle_id).values_list('id', flat=True).first() app = sdk_apps.decorated_app_by_id(app_id) if not (app and app.user_id == request.user.id): return not_found() return fn(request, app, **kwargs)
def config_rule_delete_view(request, rule_id): rule = RuntimeConfigRule.objects.filter( id=RuntimeConfigRule.decrypt_id(rule_id), user_id=request.user.id).first() if not rule: return not_found() runtime_config.update_namespace_status(rule.user, rule.bundle_id, rule.namespace) rule.delete() return ok_response()
def review_view(request, review_id=None): review = AppStoreReview.find_by_encrypted_id(review_id) if not review: return not_found() app = review.app appstore_app_info.decorate_app(app, review.country) return api_response({ 'review': review.to_dict(), 'apps': {app.encrypted_id: app.to_dict()} })
def screenshot_set_bundle_status_view(request, bundle_id=None): bundle = ScreenshotBundle.find_by_encrypted_id(bundle_id, user_id=request.user.id) if not bundle: return not_found() if bundle.url: return api_response({'status': 'ready'}) if bundle.create_time < datetime.now() - timedelta(minutes=30): return api_response({'status': 'error'}) return api_response({'status': 'building'})
def _website_page_view_GET(request, website_id, slug): website_id = AppWebsite.decrypt_id(website_id) if not website_id: return not_found() website = ( AppWebsite.objects .filter(id=website_id) .select_related('icon', 'background', 'logo') .first() ) if not website or website.delete_time: return not_found() page = AppWebsitePage.objects.get(website=website_id, slug=slug) if not page: return not_found() return api_response({ 'website': website.to_dict(), 'page': page.to_dict() })
def _single_card_view(request, app_id_or_bundle_id=None, **kwargs): app_id = SDKApp.decrypt_id(app_id_or_bundle_id) if not app_id: app_id = SDKApp.objects.filter( user=request.user, bundle_id=app_id_or_bundle_id).values_list( 'id', flat=True).first() app = sdk_apps.decorated_app_by_id(app_id) if not (app and app.user_id == request.user.id): return not_found() return fn(request, app, **kwargs)
def screenshot_shot_view(request, set_id=None, shot_id=None): my_set, shots = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id) if not my_set: return not_found() shot = [s for s in shots if s.encrypted_id == shot_id] if not shot: return not_found() shot = shot[0] if request.method == 'GET': return api_response({ 'shot': shot.to_dict(), }) form = CreateUpdateShotForm(request.POST) if not form.is_valid(): return bad_request('Invalid update shot data.', errors=form.errors) fields = form.cleaned_data post_keys = set(request.POST.keys()) for key in fields.keys(): if key not in post_keys: # default from the form del fields[key] if 'screenshot_image_id' in fields: fields['screenshot_image'] = fields['screenshot_image_id'] del fields['screenshot_image_id'] if 'background_image_id' in fields: fields['background_image'] = fields['background_image_id'] del fields['background_image_id'] screenshots.update_shot(shot, **fields) return api_response({ 'shot': shot.to_dict(), })
def user_view(request, sdk_user_id=None): user = request.user sdk_user = SDKUser.find_by_encrypted_id(sdk_user_id) if not sdk_user or sdk_user.user_id != user.id: return not_found() app = sdk_apps.decorated_app_by_id(sdk_user.app_id) raw_labels = request.GET.get('raw_labels') == '1' days_active = sessions.days_active_for_user(sdk_user) return api_response({ 'user': sdk_user.to_dict(include_raw_labels=raw_labels), 'clientUser': sdk_user.to_client_dict(), 'daysActive': days_active, 'app': app.to_dict(), })
def summary_view(request, country=None, app_id=None): app_info = appstore_fetch.app_info_with_id(app_id, country) if not app_info: return not_found() try: related_app_infos = appstore_fetch.related_app_infos_with_developer_id(app_info.developer_id, country) except: logging.exception('Problem fetching related app info') related_app_infos = [] return api_response({ 'app': app_info.to_dict(), 'related': [ai.to_tiny_dict() for ai in related_app_infos if ai.itunes_id != app_info.itunes_id], })
def subscription_view(request, subscription_id=None): sub = appstore_review_subscriptions.get_user_subscription_by_encrypted_id(request.user, subscription_id) if not sub: return not_found() if request.method == 'GET': return api_response({ 'subscription': sub.to_dict(), }) if request.POST.get('filter_good'): do_filter = request.POST['filter_good'] == '1' appstore_review_subscriptions.mark_subscription_filtered_good(sub, do_filter) return api_response({ 'subscription': sub.to_dict(), })
def screenshot_create_override(request, set_id=None, shot_id=None, device_type=None): image_id = request.POST.get('image_id') # Check for shot & image my_shot, image = screenshots.get_shot_and_override_image_by_encrypted_id(request.user, shot_id, image_id); # return if they neither exist if not my_shot or not image: return not_found() # otherwise create / udate a unique override image for the specified device_type override_image = screenshots.create_or_update_override_image(my_shot.screenshot_set, my_shot, image, device_type) return api_response({ 'override':override_image.to_dict() })
def _website_view_POST(request, website_id): website = AppWebsite.find_by_encrypted_id(website_id, user_id=request.user.id, for_update=True) if not website or website.delete_time: return not_found() # FORM VALIDATION form = EditAppWebsiteForm(request.POST) if not form.is_valid(): logging.info('Website edit problem (id=%s): %s', website.encrypted_id, dict(form.errors)) return bad_request('Invalid website data.', errors=form.errors) domain = form.cleaned_data.get('domain') if domain: in_use_website = AppWebsite.objects.filter(domain=domain).exclude(id=website.id).count() if in_use_website: return bad_request('Invalid website data', errors={'domain': ['Domain already in use.']}) screenshots_form = AppWebsiteScreenshotsForm(request.POST) if not screenshots_form.is_valid(): logging.info('Website screenshots problem (id=%s): %s', website.encrypted_id, dict(screenshots_form.errors)) return bad_request('Invalid screenshots provided.', errors=screenshots_form.errors) # ASSIGN MODIFIED PROPERTIES # Only assign values that were actually passed in the POSTbody. _assign_properties_from_dict(website, form.cleaned_model_data(filter_values=request.POST)) # UPDATE ASSOCIATED SCREENSHOTS iphone_screenshots = screenshots_form.cleaned_data.get('iphone_screenshot_ids', []) if iphone_screenshots: websites.update_website_screenshots(website, iphone_screenshots, 'iPhone') # UPDATE HOSTED PAGES hosted_pages = EditPageForm(request.POST) if not hosted_pages.is_valid(): return bad_request('Invalid website data.', errors=hosted_pages.errors) for field in hosted_pages: # Check if this field was actually included in the POSTdata with this request. if field.name in request.POST: websites.create_or_update_hosted_page(website, field.name, field.value()) website.save() return api_response({'website': website.to_dict()})
def screenshot_set_download_bundle_view(request, set_id=None): set_id = ScreenshotSet.decrypt_id(set_id) if not set_id: return not_found() bundle_id = request.GET.get('bundle_id') bundle = ScreenshotBundle.find_by_encrypted_id(bundle_id, screenshot_set_id=set_id) if not bundle: return bad_request('Could not find that bundle.') # Enable logged-out user access by token. if not (request.user.is_authenticated() and request.user.id == bundle.user_id): token = request.GET.get('token') user = users.get_user_by_email_token(token) if (not user) or user.id != bundle.user_id: return bad_request('Invalid token for this bundle.') return api_response({ 'downloadUrl': screenshot_bundler.build_download_url(bundle), })
def summary_view(request, country=None, app_id=None): app_info = appstore_fetch.app_info_with_id(app_id, country) if not app_info: return not_found() try: related_app_infos = appstore_fetch.related_app_infos_with_developer_id( app_info.developer_id, country) except: logging.exception('Problem fetching related app info') related_app_infos = [] return api_response({ 'app': app_info.to_dict(), 'related': [ ai.to_tiny_dict() for ai in related_app_infos if ai.itunes_id != app_info.itunes_id ], })
def user_by_id(request, user_id=None): user = User.find_by_encrypted_id(user_id) if not user: return not_found() return api_response({'user': user.to_minimal_dict()})