def _subscriptions_view_POST(request): form = NewSubscriptionForm(request.POST) if not form.is_valid(): return bad_request('Invalid subscription data.', errors=form.errors) email = form.cleaned_data.get('email') my_email = form.cleaned_data.get('my_email') slack_url = form.cleaned_data.get('slack_url') slack_channel_name = form.cleaned_data.get('slack_channel_name') sub = None if email: sub = appstore_sales_report_subscriptions.create_email_subscription(request.user, email) elif my_email: sub = appstore_sales_report_subscriptions.create_my_email_subscription(request.user) elif slack_channel_name: sub = appstore_sales_report_subscriptions.create_slack_channel_subscription(request.user, slack_channel_name) elif slack_url: sub = appstore_sales_report_subscriptions.create_slack_subscription(request.user, slack_url) if not sub: return bad_request('Subscription already exists.') new_flags = [] if not request.user.flags.has_sales_monitor: new_flags.append('has_sales_monitor') if new_flags: request.user.set_flags(new_flags) return api_response({ 'subscription': sub.to_dict(), })
def get_sales_metrics_view(request): requested_date = request.GET.get('requested_date') if requested_date: try: requested_date = float(requested_date) requested_date = date.fromtimestamp(requested_date) except ValueError: return bad_request('Invalid `requsted_date`') if not requested_date: requested_date = itunes_connect.get_freshest_sales_report_date() vendor = itunes_connect.get_chosen_vendor_for_user(request.user) if not vendor: return bad_request('No iTunes vendor chosen for this user yet.') status = itunes_connect.report_status_for_vendor_date(vendor, requested_date) if status == itunes_connect.REPORT_STATUS_AVAILABLE: app_sales_metrics, total_sales_metrics = itunes_connect.get_sales_metrics(vendor, requested_date) for app_metrics in app_sales_metrics: app_metrics['app'] = app_metrics['app'].to_dict() else: app_sales_metrics, total_sales_metrics = None, None return api_response({ 'status': status, 'appSalesMetrics': app_sales_metrics, 'totalSalesMetrics': total_sales_metrics, 'date': APIModel.date_to_api_date(requested_date), 'vendor': vendor.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 signup(request): if request.user.is_authenticated(): return bad_request('You are already signed in.') user_form = UserSignupForm(request.POST) if not user_form.is_valid(): return bad_request(message='Invalid user signup data', errors=user_form.errors) email = user_form.cleaned_data.get('email') password = user_form.cleaned_data['password'] user = users.create_user(user_form.cleaned_data['first_name'], user_form.cleaned_data['last_name'], email=email, password=password) if not user: logging.warn('Unaccounted for signup error with signup data: %r', user_form.cleaned_data) return bad_request( 'Could not create a user with the given credentials.') return api_response({ 'user': user.to_dict(), })
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 request_verification_email(request): email = None if 'email' in request.POST or not request.user.is_authenticated(): # Should this be a separate form? Meh. form = ResetPasswordForm(request.POST) if not form.is_valid(): return bad_request('Bad email verification request', errors=form.errors) email = form.cleaned_data['email'] if request.user.is_authenticated(): unverified_emails = users.get_unverified_emails(request.user) if not unverified_emails: return bad_request('No unverified emails for this account.') if not email: email = unverified_emails[0] elif email not in unverified_emails: return bad_request('Could not find this unverified email address.') success = users.request_verification_email(email) if not success: return bad_request('Could not request a verification email. Has the email already been verified?') return ok_response()
def get_sales_metrics_view(request): requested_date = request.GET.get('requested_date') if requested_date: try: requested_date = float(requested_date) requested_date = date.fromtimestamp(requested_date) except ValueError: return bad_request('Invalid `requsted_date`') if not requested_date: requested_date = itunes_connect.get_freshest_sales_report_date() vendor = itunes_connect.get_chosen_vendor_for_user(request.user) if not vendor: return bad_request('No iTunes vendor chosen for this user yet.') status = itunes_connect.report_status_for_vendor_date( vendor, requested_date) if status == itunes_connect.REPORT_STATUS_AVAILABLE: app_sales_metrics, total_sales_metrics = itunes_connect.get_sales_metrics( vendor, requested_date) for app_metrics in app_sales_metrics: app_metrics['app'] = app_metrics['app'].to_dict() else: app_sales_metrics, total_sales_metrics = None, None return api_response({ 'status': status, 'appSalesMetrics': app_sales_metrics, 'totalSalesMetrics': total_sales_metrics, 'date': APIModel.date_to_api_date(requested_date), 'vendor': vendor.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 emails_view(request): user_emails = list(request.user.emails_set.all()) if request.method == 'GET': return api_response({ 'emails': [email.to_dict() for email in user_emails], }) if len([e for e in user_emails if not e.verified]) > 3: return bad_request('Cannot add another unverified email address.', errors={'email': ['Too many unverified email addresses.']}) form = EmailForm(request.POST) if not form.is_valid(): return bad_request('Invalid email address.', errors=form.errors) new_email = form.cleaned_data['email'] if new_email in [e.email for e in user_emails]: return bad_request('Cannot add an email you already have.', errors={'email': ['Account already associated with that address.']}) email = users.associate_user_with_email(request.user, new_email, verified=False) if not email: return bad_request('Email is already in use.', errors={'email': ['Sorry, that email is already in use.']}, status=409) return api_response({ 'email': email.to_dict(), })
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 _create_image_view(request): if settings.IS_PRODUCTION: referer = request.META.get('HTTP_REFERER', '') if not any(referer.startswith(ap) for ap in ACCEPTABLE_PREFIXES): logging.info('Blocked request with missing referer') return bad_request() try: gae_id = int(request.POST['upload_id']) except (KeyError, ValueError, TypeError): gae_id = None if not gae_id: return bad_request('Please include `upload_id`.') user = None if request.user.is_authenticated(): user = request.user image_result = fn(gae_id, user) if image_result.bad_request: return bad_request('Invalid image provided.') if image_result.server_error: return unavailable_response() image = image_result.image return api_response({ 'image': image.to_dict() })
def request_verification_email(request): email = None if 'email' in request.POST or not request.user.is_authenticated(): # Should this be a separate form? Meh. form = ResetPasswordForm(request.POST) if not form.is_valid(): return bad_request('Bad email verification request', errors=form.errors) email = form.cleaned_data['email'] if request.user.is_authenticated(): unverified_emails = users.get_unverified_emails(request.user) if not unverified_emails: return bad_request('No unverified emails for this account.') if not email: email = unverified_emails[0] elif email not in unverified_emails: return bad_request('Could not find this unverified email address.') success = users.request_verification_email(email) if not success: return bad_request( 'Could not request a verification email. Has the email already been verified?' ) return ok_response()
def _websites_view_POST(request): itunes_id = request.POST.get('itunes_id') country = request.POST.get('country', 'us') if itunes_id and country: itunes_app = appstore.get_app_by_itunes_id(itunes_id, country) else: itunes_app = None post_data = { 'template': '1', 'frame_screenshots': 'white', } # Create website from iTunes info. if itunes_app: name, tagline = text.app_name_tagline(itunes_app.name) post_data.update({ 'itunes_id': itunes_app.itunes_id, 'country': itunes_app.country, 'app_name': name, 'tagline': tagline, 'long_description': itunes_app.description, }) for k, v in request.POST.items(): post_data[k] = v or post_data.get(k, '') form = AppWebsiteForm(post_data) if not form.is_valid(): logging.info('Website creation problem: %s', 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).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(): return bad_request('Invalid screenshots provided.') new_website = AppWebsite(user=request.user) _assign_properties_from_dict(new_website, form.cleaned_model_data()) new_website.save() # ADD ASSOCIATED SCREENSHOTS iphone_screenshots = screenshots_form.cleaned_data.get('iphone_screenshot_ids', []) if iphone_screenshots: websites.update_website_screenshots(new_website, iphone_screenshots, 'iPhone') request.user.set_flags(['has_websites']) return api_response({ 'website': new_website.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 reset_password_view(request): form = ResetPasswordForm(request.POST) if not form.is_valid(): return bad_request('Bad reset password request', errors=form.errors) success = users.request_reset_password_email(form.cleaned_data['email']) if not success: return bad_request('Could not find a user with that email address') return ok_response()
def email_set_primary_view(request): form = EmailForm(request.POST) if not form.is_valid(): return bad_request('Invalid email provided.', errors=form.errors) if not users.make_email_primary(request.user, form.cleaned_data['email']): return bad_request('Could not promote email address to primary.') return api_response({ 'emails': [e.to_dict() for e in request.user.emails_set.all()], })
def email_delete_view(request): form = EmailForm(request.POST) if not form.is_valid(): return bad_request('Invalid email provided.', errors=form.errors) if not users.disassociate_user_with_email(request.user, form.cleaned_data['email']): return bad_request('Could not disassociate that email address.') return api_response({ 'emails': [e.to_dict() for e in request.user.emails_set.all()], })
def choose_vendor_view(request): vendor_id = request.POST.get('vendor_id') if not vendor_id: return bad_request() vendor = ItunesConnectVendor.find_by_encrypted_id(vendor_id) if not vendor or vendor.user_id != request.user.id: return bad_request() itunes_connect.choose_vendor(request.user, vendor) return ok_response()
def unsubscribe_view(request): form = UnsubscribeForm(request.POST) if not form.is_valid(): return bad_request('Bad unsub request', errors=form.errors) token = form.cleaned_data['token'] success = users.unsubscribe_with_token(token) if not success: return bad_request('Invalid token data.') return ok_response()
def verify_email_view(request): form = VerifyEmailForm(request.POST) if not form.is_valid(): return bad_request('Bad verification request', errors=form.errors) token = form.cleaned_data['token'] success = users.verify_email_from_token(token) if not success: return bad_request('Invalid token data.') return ok_response()
def user_details(request): def _build_response(): user = User.get_cached(request.user.id) flags = {} for flag in users.USER_EDITABLE_USER_FLAGS: flags[flag] = bool(getattr(user.flags, flag)) return api_response({ 'user': user.to_dict(), 'emails': [email.to_dict() for email in user.emails_set.all()], 'settings': flags }) if request.method != 'POST': return _build_response() # Get an exclusive lock on this user. user = User.objects.select_for_update().get(pk=request.user.id) # Edit details. flag_updates = {} for flag in users.USER_EDITABLE_USER_FLAGS: if flag in request.POST: flag_value = request.POST[flag] if flag_value not in ('1', '0'): return bad_request( message='Bad flag value.', errors={flag: 'Provided value should be "1" or "0"'}) flag_updates[flag] = (flag_value == '1') if flag_updates: users.update_user_flags(user, flag_updates) form = UserDetailsEditForm(request.POST) if not form.is_valid(): return bad_request(message='Invalid edit fields.', errors=form.errors) update_fields = [] if 'first_name' in request.POST: user.first_name = form.cleaned_data['first_name'] update_fields.append('first_name') if 'last_name' in request.POST: user.last_name = form.cleaned_data['last_name'] update_fields.append('last_name') if update_fields: user.save(update_fields=update_fields) return _build_response()
def reset_password_finish_view(request): form = SetNewPasswordForm(request.POST) if not form.is_valid(): return bad_request('Bad reset password request', errors=form.errors) token = form.cleaned_data['token'] password = form.cleaned_data['password'] success = users.reset_password_with_email_token(token, password) if not success: return bad_request('Invalid token data.') return ok_response()
def screenshot_set_duplicate_view(request, set_id=None): my_set, _ = screenshots.get_set_and_shots_by_encrypted_id(request.user, set_id) if not my_set or request.user.id != my_set.user.id: return bad_request('You dont have premissions.') form = NewSetForm(request.POST) if not form.is_valid(): return bad_request('Invalid new set.', errors=form.errors) new_set = screenshots.duplicate_set(my_set, form.cleaned_data['name'], form.cleaned_data['version'], form.cleaned_data['platform']) return api_response({ 'set': new_set.to_dict() })
def _configs_view_POST(request): form = CreateRuleForm(request.POST) if not form.is_valid(): logging.info('Invalid rules: %s POST: %s', dict(form.errors), dict(request.POST)) return bad_request(message='Invalid rule parameters.', errors=form.errors) key = form.cleaned_data['key'] del form.cleaned_data['key'] bundle_id = form.cleaned_data['bundle_id'] # Create the app row if it doesn't exist so we can populate the "my apps" dropdown. app = sdk_apps.decorated_app_by_bundle_id(request.user, bundle_id) if not app.config: app.config = True app.save(update_fields=['products']) rules = runtime_config.rules_for_user_key(request.user, key, bundle_id) kind = None if 'kind' in form.cleaned_data: kind = form.cleaned_data['kind'] del form.cleaned_data['kind'] if rules and rules[0].kind != kind: return bad_request( 'Key already exists as a different `kind`; cannot change type.' ) elif rules: kind = rules[0].kind if not kind: return bad_request('Please provide a `kind` for this key.') value_form = ValueForm(kind, request.POST) if not value_form.is_valid(): return bad_request(message='Invalid rule `value`.', errors=form.errors) value = value_form.cleaned_data['value'] rule = runtime_config.create_rule(request.user, key, kind, value, **form.cleaned_data) if not request.user.flags.has_config: request.user.set_flags(['has_config']) return api_response({ 'rule': rule.to_dict(), })
def connect_slack_view(request): code = request.POST.get('code') service = request.POST.get('service') onboarding = request.POST.get('onboarding') == '1' if not (code and service): return bad_request( 'Please provide a `code` from the Slack OAuth2 endpoint, LK `service` to connect, and `onboarding` status.' ) success = slack.associate_user_with_slack(request.user, code, service, onboarding) if not success: return bad_request('Could not fetch a slack token with that `code`.') return ok_response()
def user_details(request): def _build_response(): user = User.get_cached(request.user.id) flags = {} for flag in users.USER_EDITABLE_USER_FLAGS: flags[flag] = bool(getattr(user.flags, flag)) return api_response({ 'user': user.to_dict(), 'emails': [email.to_dict() for email in user.emails_set.all()], 'settings': flags }) if request.method != 'POST': return _build_response() # Get an exclusive lock on this user. user = User.objects.select_for_update().get(pk=request.user.id) # Edit details. flag_updates = {} for flag in users.USER_EDITABLE_USER_FLAGS: if flag in request.POST: flag_value = request.POST[flag] if flag_value not in ('1', '0'): return bad_request(message='Bad flag value.', errors={flag: 'Provided value should be "1" or "0"'}) flag_updates[flag] = (flag_value == '1') if flag_updates: users.update_user_flags(user, flag_updates) form = UserDetailsEditForm(request.POST) if not form.is_valid(): return bad_request(message='Invalid edit fields.', errors=form.errors) update_fields = [] if 'first_name' in request.POST: user.first_name = form.cleaned_data['first_name'] update_fields.append('first_name') if 'last_name' in request.POST: user.last_name = form.cleaned_data['last_name'] update_fields.append('last_name') if update_fields: user.save(update_fields=update_fields) return _build_response()
def config_interpolated_view(request): token_id = request.GET.get('token') if token_id: user = tokens.user_by_token(token_id) else: user = request.user if not (user and user.is_authenticated()): return unauthorized_request( 'Please provide `token` or `access_token`.') form = GetConfigForm(request.GET) if not form.is_valid(): return bad_request('Invalid options for config interpolation', errors=form.errors) user_labels = form.cleaned_data.get('sdk_user_labels') if user_labels: user_labels = ','.split(user_labels) config = runtime_config.interpolated_config_for_user( user, form.cleaned_data['namespace'], form.cleaned_data['bundle_id'], version=form.cleaned_data['version'], build=form.cleaned_data['build'], ios_version=form.cleaned_data['ios_version'], debug=form.cleaned_data['debug'], sdk_user_labels=user_labels) return api_response({ 'config': config, })
def config_interpolated_view(request): token_id = request.GET.get('token') if token_id: user = tokens.user_by_token(token_id) else: user = request.user if not (user and user.is_authenticated()): return unauthorized_request('Please provide `token` or `access_token`.') form = GetConfigForm(request.GET) if not form.is_valid(): return bad_request('Invalid options for config interpolation', errors=form.errors) user_labels = form.cleaned_data.get('sdk_user_labels') if user_labels: user_labels = ','.split(user_labels) config = runtime_config.interpolated_config_for_user( user, form.cleaned_data['namespace'], form.cleaned_data['bundle_id'], version=form.cleaned_data['version'], build=form.cleaned_data['build'], ios_version=form.cleaned_data['ios_version'], debug=form.cleaned_data['debug'], sdk_user_labels=user_labels) return api_response({ 'config': config, })
def _app_view_POST(request, app): form = EditSDKAppForm(request.POST) if not form.is_valid(): return bad_request('Invalid edits provided.', errors=form.errors) if form.cleaned_data.get('itunes_country'): itunes_id, country = form.cleaned_data.get( 'itunes_id'), form.cleaned_data.get('itunes_country') appstore_app = appstore.get_app_by_itunes_id(itunes_id, country) if not appstore_app: return bad_request( 'Invalid `itunes_id` or `itunes_country` provided.') if app.appstore_app and app.appstore_app.id != appstore_app.id: return bad_request('Cannot change `itunes_id` once it is set.') app.itunes_country = country app.save(update_fields=['itunes_county']) display_name = form.cleaned_data.get('display_name') or None if 'display_name' in request.POST: # Allow removing this field to default to appstore info / bundle id. app.display_name = display_name app.save(update_fields=['display_name']) super_freq, super_time = form.cleaned_data.get( 'super_freq'), form.cleaned_data.get('super_time') if super_freq: session_user_labels.set_super_config(app, super_freq, super_time) # TODO(Taylor): Figure out a better place to set this. if not request.user.flags.has_super_users: request.user.set_flags(['has_super_users']) if 'config_parent_id' in request.POST: # can also be None if removing parent. app.config_parent = form.cleaned_data.get('config_parent_id') app.save(update_fields=['config_parent']) for sdk_product in SDKProduct.kinds(): if sdk_product in request.POST: setattr(app, sdk_product, form.cleaned_data[sdk_product]) app.save(update_fields=['products']) return api_response({ 'app': app.to_dict(), })
def subscription_unsubscribe_token_view(request): sub = itunes_connect.subscription_from_unsubscribe_token(request.POST.get('token', '')) if not sub: return bad_request('Could not find subscription with that `token`.') appstore_sales_report_subscriptions.disable_subscription(sub) return ok_response()
def subscription_unsubscribe_token_view(request): sub = appstore_review_notify.subscription_from_unsubscribe_token(request.POST.get('token', '')) if not sub: return bad_request('Could not find subscription with that `token`.') appstore_review_subscriptions.disable_subscription(sub) return ok_response()
def delete_account_view(request): email = request.POST.get('email') if email != request.user.email: return bad_request('Please provide the current account email address, `email`.') destructive.delete_account(request.user) return ok_response()
def disconnect_itunes_view(request): connected_email = itunes_connect.itunes_credentials_email_for_user_id(request.user.id) if not connected_email: return bad_request('No connection to remove.') destructive.delete_itunes_connection_and_imports(request.user) return ok_response()
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 _subscriptions_view_POST(request): form = NewSubscriptionForm(request.POST) if not form.is_valid(): return bad_request('Invalid subscription data.', errors=form.errors) email = form.cleaned_data.get('email') my_email = form.cleaned_data.get('my_email') slack_url = form.cleaned_data.get('slack_url') slack_channel_name = form.cleaned_data.get('slack_channel_name') twitter_app_connection = form.cleaned_data.get('twitter_app_connection_id') app = form.cleaned_data.get('app_id') if app and not twitter_app_connection: try: twitter_app_connection = TwitterAppConnection.objects.get(user=request.user, app=app, enabled=True) except TwitterAppConnection.DoesNotExist: return bad_request('Invalid `app_id`, not already connected to twitter.') sub = None if email: sub = appstore_review_subscriptions.create_email_subscription(request.user, email) elif my_email: sub = appstore_review_subscriptions.create_my_email_subscription(request.user) elif slack_channel_name: sub = appstore_review_subscriptions.create_slack_channel_subscription(request.user, slack_channel_name) elif slack_url: sub = appstore_review_subscriptions.create_slack_subscription(request.user, slack_url) elif twitter_app_connection: sub = appstore_review_subscriptions.create_twitter_subscription_from_connection(twitter_app_connection) if not sub: return bad_request('Subscription already exists.') new_flags = [] if not request.user.flags.has_review_monitor: new_flags.append('has_review_monitor') if sub.twitter_connection_id and not request.user.flags.has_review_monitor_tweets: new_flags.append('has_review_monitor_tweets') if new_flags: request.user.set_flags(new_flags) return api_response({ 'subscription': sub.to_dict(), })
def _configs_view_POST(request): form = CreateRuleForm(request.POST) if not form.is_valid(): logging.info('Invalid rules: %s POST: %s', dict(form.errors), dict(request.POST)) return bad_request(message='Invalid rule parameters.', errors=form.errors) key = form.cleaned_data['key'] del form.cleaned_data['key'] bundle_id = form.cleaned_data['bundle_id'] # Create the app row if it doesn't exist so we can populate the "my apps" dropdown. app = sdk_apps.decorated_app_by_bundle_id(request.user, bundle_id) if not app.config: app.config = True app.save(update_fields=['products']) rules = runtime_config.rules_for_user_key(request.user, key, bundle_id) kind = None if 'kind' in form.cleaned_data: kind = form.cleaned_data['kind'] del form.cleaned_data['kind'] if rules and rules[0].kind != kind: return bad_request('Key already exists as a different `kind`; cannot change type.') elif rules: kind = rules[0].kind if not kind: return bad_request('Please provide a `kind` for this key.') value_form = ValueForm(kind, request.POST) if not value_form.is_valid(): return bad_request(message='Invalid rule `value`.', errors=form.errors) value = value_form.cleaned_data['value'] rule = runtime_config.create_rule(request.user, key, kind, value, **form.cleaned_data) if not request.user.flags.has_config: request.user.set_flags(['has_config']) return api_response({ 'rule': rule.to_dict(), })
def disconnect_itunes_view(request): connected_email = itunes_connect.itunes_credentials_email_for_user_id( request.user.id) if not connected_email: return bad_request('No connection to remove.') destructive.delete_itunes_connection_and_imports(request.user) return ok_response()
def subscription_unsubscribe_token_view(request): sub = itunes_connect.subscription_from_unsubscribe_token( request.POST.get('token', '')) if not sub: return bad_request('Could not find subscription with that `token`.') appstore_sales_report_subscriptions.disable_subscription(sub) return ok_response()
def delete_account_view(request): email = request.POST.get('email') if email != request.user.email: return bad_request( 'Please provide the current account email address, `email`.') destructive.delete_account(request.user) return ok_response()
def _app_view_POST(request, app): form = EditSDKAppForm(request.POST) if not form.is_valid(): return bad_request('Invalid edits provided.', errors=form.errors) if form.cleaned_data.get('itunes_country'): itunes_id, country = form.cleaned_data.get('itunes_id'), form.cleaned_data.get('itunes_country') appstore_app = appstore.get_app_by_itunes_id(itunes_id, country) if not appstore_app: return bad_request('Invalid `itunes_id` or `itunes_country` provided.') if app.appstore_app and app.appstore_app.id != appstore_app.id: return bad_request('Cannot change `itunes_id` once it is set.') app.itunes_country = country app.save(update_fields=['itunes_county']) display_name = form.cleaned_data.get('display_name') or None if 'display_name' in request.POST: # Allow removing this field to default to appstore info / bundle id. app.display_name = display_name app.save(update_fields=['display_name']) super_freq, super_time = form.cleaned_data.get('super_freq'), form.cleaned_data.get('super_time') if super_freq: session_user_labels.set_super_config(app, super_freq, super_time) # TODO(Taylor): Figure out a better place to set this. if not request.user.flags.has_super_users: request.user.set_flags(['has_super_users']) if 'config_parent_id' in request.POST: # can also be None if removing parent. app.config_parent = form.cleaned_data.get('config_parent_id') app.save(update_fields=['config_parent']) for sdk_product in SDKProduct.kinds(): if sdk_product in request.POST: setattr(app, sdk_product, form.cleaned_data[sdk_product]) app.save(update_fields=['products']) return api_response({ 'app': app.to_dict(), })
def _apps_view_POST(request): form = CreateSDKAppForm(request.POST) if not form.is_valid(): return bad_request('Invalid create app parameters.', errors=form.errors) bundle_id = form.cleaned_data.get('bundle_id') if bundle_id: app = sdk_apps.create_or_fetch_sdk_app_with_bundle_id( request.user, bundle_id) if app.appstore_app: # Edge case: Creating app store app again later, from bundle ID appstore_app_info.decorate_app(app.appstore_app, app.appstore_app_country) else: itunes_id, country = form.cleaned_data.get( 'itunes_id'), form.cleaned_data.get('itunes_country') appstore_app = appstore.get_app_by_itunes_id(itunes_id, country) if not appstore_app: return bad_request( 'Invalid `itunes_id` or `itunes_country` provided.') app = sdk_apps.create_or_decorate_sdk_app_with_appstore_app( request.user, appstore_app) display_name = form.cleaned_data.get('display_name') if display_name: app.display_name = display_name app.save(update_fields=['display_name']) config_parent_app = form.cleaned_data.get('config_parent_id') if config_parent_app: app.config_parent = config_parent_app app.save(update_fields=['config_parent']) for sdk_product in SDKProduct.kinds(): if sdk_product in request.POST: setattr(app, sdk_product, form.cleaned_data[sdk_product]) app.save(update_fields=['products']) return api_response({ 'app': app.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 _apps_view_GET(request): form = ListAppsForm(request.GET) if not form.is_valid(): return bad_request('Invalid list parameters.', errors=form.errors) cleaned_data = {k: v for k, v in form.cleaned_data.items() if k in request.GET} apps = sdk_apps.my_decorated_apps(request.user, **cleaned_data) return api_response({ 'apps': [a.to_dict() for a in apps], })
def tweet_review(request): twitter_handle = request.POST['twitter_handle'] review_id = request.POST['review_id'] review = AppStoreReview.find_by_encrypted_id(review_id) tweet_text = request.POST['tweet_text'] if twitter_handle and review and tweet_text: success = twitter.tweet_review(request.user, twitter_handle, review, tweet_text) if success: return ok_response() return bad_request()
def _apps_view_POST(request): itunes_id = request.POST.get('itunes_id') country = request.POST.get('country') if not country or country not in appstore.APPSTORE_COUNTRIES_BY_CODE: return bad_request('Provide a valid `country`') if request.POST.get('include_related') == '1': apps = appstore.get_app_and_related_by_itunes_id(itunes_id, country) if not apps: return bad_request('Invalid `itunes_id` provided.') else: app = appstore.get_app_by_itunes_id(itunes_id, country) if not app: return bad_request('Invalid `itunes_id` provided.') apps = [app] appstore.mark_interested_in_apps(request.user, apps, country) return api_response({'apps': [a.to_dict() for a in apps]})