def get_timezone(request): tz = request.GET.get("timezone", None) if tz: result = None try: pytz.timezone(tz) result = tz except Exception: if tz.startswith(" "): tz = tz.replace(" ", "+") for tzdata in get_timezones(): if str(tzdata["offset"]) == tz or tzdata["repr"] == tz: result = tzdata["name"] break if result: if "update" in request.GET: if request.user.is_authenticated: request.user.coder.timezone = result request.user.coder.save() else: request.session["timezone"] = result return return result if request.user.is_authenticated: return request.user.coder.timezone return request.session.get("timezone", settings.DEFAULT_TIME_ZONE_)
def search(request, **kwargs): query = request.GET.get('query', None) if not query or not isinstance(query, str): return HttpResponseBadRequest('invalid query') count = int(request.GET.get('count', django_settings.DEFAULT_COUNT_QUERY_)) count = min(count, django_settings.DEFAULT_COUNT_LIMIT_) page = int(request.GET.get('page', 1)) if query == 'themes': ret = {} for t in django_settings.THEMES_: ret[t] = t.title() return JsonResponse(ret) elif query == 'timezones': ret = {} for tz in get_timezones(): ret[tz["name"]] = f'{tz["name"]} {tz["repr"]}' return JsonResponse(ret) elif query == 'resources': qs = Resource.objects.all() if 'regex' in request.GET: qs = qs.filter(get_iregex_filter(request.GET['regex'], 'host')) qs = qs.order_by('-n_accounts', 'pk') qs = qs[(page - 1) * count:page * count] ret = [{'id': r.id, 'text': r.host, 'icon': r.icon} for r in qs] elif query == 'resources-for-add-account' and request.user.is_authenticated: coder = request.user.coder coder_accounts = coder.account_set.filter(resource=OuterRef('pk')) qs = Resource.objects \ .annotate(has_coder_account=Exists(coder_accounts)) \ .annotate(has_multi=F('module__multi_account_allowed')) \ .annotate(disabled=Case( When(module__isnull=True, then=Value(True)), When(has_coder_account=True, has_multi=False, then=Value(True)), default=Value(False), output_field=BooleanField(), )) if 'regex' in request.GET: qs = qs.filter(get_iregex_filter(request.GET['regex'], 'host')) qs = qs.order_by('disabled', 'pk') qs = qs[(page - 1) * count:page * count] ret = [{ 'id': r.id, 'text': r.host, 'disabled': r.disabled, } for r in qs] elif query == 'accounts-for-add-account' and request.user.is_authenticated: coder = request.user.coder qs = Account.objects.all() resource = request.GET.get('resource') if resource: qs = qs.filter(resource__id=int(resource)) else: qs = qs.select_related('resource') order = ['disabled'] if 'user' in request.GET: re_search = request.GET.get('user') exact_qs = qs.filter(key__iexact=re_search) if exact_qs.exists(): qs = exact_qs else: qs = qs.filter(get_iregex_filter(re_search, 'key', 'name')) search_striped = re_search.rstrip('$').lstrip('^') qs = qs.annotate(match=Case( When(Q(key__iexact=search_striped) | Q(name__iexact=search_striped), then=Value(True)), default=Value(False), output_field=BooleanField(), )) order.append('-match') qs = qs.annotate( has_multi=F('resource__module__multi_account_allowed')) qs = qs.annotate(disabled=Case( When(coders=coder, then=Value(True)), When(coders__isnull=False, has_multi=False, then=Value(True)), default=Value(False), output_field=BooleanField(), )) qs = qs.order_by(*order, 'pk') qs = qs[(page - 1) * count:page * count] ret = [] for r in qs: fields = { 'id': r.key, 'text': f'{r.key} - {r.name}' if r.name and r.key.find(r.name) == -1 else r.key, 'disabled': r.disabled, } if not resource: fields['text'] += f', {r.resource.host}' fields['resource'] = { 'id': r.resource.pk, 'text': r.resource.host } ret.append(fields) elif query == 'organization': qs = Organization.objects.all() name = request.GET.get('name') if name: qs = qs.filter( Q(name__icontains=name) | Q(name_ru__icontains=name) | Q(abbreviation__icontains=name)) qs = qs[(page - 1) * count:page * count] ret = [{'id': o.name, 'text': o.name} for o in qs] elif query == 'team': qs = Team.objects.all() name = request.GET.get('name') if name: qs = qs.filter(name__icontains=name) event = kwargs.get('event') if event: qs = qs.filter(event=event) qs = qs.annotate( disabled=Case(When(status=TeamStatus.NEW, then=Value(False)), default=Value(True), output_field=BooleanField())).order_by( 'disabled', '-modified', 'pk') qs = qs[(page - 1) * count:page * count] ret = [{ 'id': r.id, 'text': r.name, 'disabled': r.disabled } for r in qs] elif query == 'country': qs = list(countries) name = request.GET.get('name') if name: name = name.lower() qs = [(c, n) for c, n in countries if name in n.lower()] qs = qs[(page - 1) * count:page * count] ret = [{'id': c, 'text': n} for c, n in qs] elif query == 'notpast': title = request.GET.get('title') qs = Contest.objects.filter(title__iregex=verify_regex(title), end_time__gte=timezone.now()) qs = qs[(page - 1) * count:page * count] ret = [{'id': c.id, 'text': c.title} for c in qs] elif query == 'field-to-select': contest = get_object_or_404(Contest, pk=request.GET.get('cid')) text = request.GET.get('text') field = request.GET.get('field') assert '__' not in field if field == 'languages': qs = contest.info.get('languages', []) qs = ['any' ] + [q for q in qs if not text or text.lower() in q.lower()] elif field == 'rating': qs = ['rated', 'unrated'] else: field = f'addition__{field}' qs = contest.statistics_set if text: qs = qs.filter(**{f'{field}__icontains': text}) qs = qs.distinct(field).values_list(field, flat=True) qs = qs[(page - 1) * count:page * count] ret = [{'id': f, 'text': f} for f in qs] elif query == 'coders': qs = Coder.objects.all() if 'regex' in request.GET: qs = qs.filter(get_iregex_filter(request.GET['regex'], 'username')) order = ['-n_accounts', 'pk'] if request.user.is_authenticated: qs = qs.annotate( iam=Case(When(pk=request.user.coder.pk, then=Value(0)), default=Value(1), output_field=IntegerField())) order.insert(0, 'iam') qs = qs.order_by(*order, 'pk') qs = qs[(page - 1) * count:page * count] ret = [{'id': r.id, 'text': r.username} for r in qs] elif query == 'accounts': qs = Account.objects.all() if request.GET.get('resource'): qs = qs.filter(resource_id=int(request.GET.get('resource'))) order = ['-n_contests', 'pk'] if 'regex' in request.GET: re_search = request.GET['regex'] exact_qs = qs.filter(key__iexact=re_search) if exact_qs.exists(): qs = exact_qs else: qs = qs.filter(get_iregex_filter(re_search, 'key', 'name')) search_striped = re_search.rstrip('$').lstrip('^') qs = qs.annotate(match=Case( When(Q(key__iexact=search_striped) | Q(name__iexact=search_striped), then=Value(True)), default=Value(False), output_field=BooleanField(), )) order.insert(0, '-match') qs = qs.select_related('resource') qs = qs.order_by(*order, 'pk') qs = qs[(page - 1) * count:page * count] ret = [{ 'id': r.id, 'text': f'{r.key}, {r.name}, {r.resource.host}' if r.name else f'{r.key}, {r.resource.host}' } for r in qs] else: return HttpResponseBadRequest('invalid query') result = { 'items': ret, 'more': len(ret) and len(ret) == count, } return HttpResponse(json.dumps(result, ensure_ascii=False), content_type="application/json")
def search(request, **kwargs): query = request.GET.get('query', None) if not query or not isinstance(query, str): return HttpResponseBadRequest('invalid query') count = int(request.GET.get('count', 10)) page = int(request.GET.get('page', 1)) if query == 'timezones': ret = {} for tz in get_timezones(): ret[tz["name"]] = f'{tz["name"]} {tz["repr"]}' return JsonResponse(ret) elif query == 'resources-for-add-account': coder = request.user.coder coder_accounts = coder.account_set.filter(resource=OuterRef('pk')) qs = Resource.objects \ .annotate(has_coder_account=Exists(coder_accounts)) \ .annotate(has_multi=F('module__multi_account_allowed')) \ .annotate(disabled=Case( When(module__isnull=True, then=Value(True)), When(has_coder_account=True, has_multi=False, then=Value(True)), default=Value(False), output_field=BooleanField(), )) if 'regex' in request.GET: qs = qs.filter(get_iregex_filter(request.GET['regex'], 'host')) qs = qs.order_by('disabled', 'pk') total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [{ 'id': r.id, 'text': r.host, 'disabled': r.disabled, } for r in qs] elif query == 'accounts-for-add-account': coder = request.user.coder qs = Account.objects.all() resource = request.GET.get('resource') if resource: qs = qs.filter(resource__id=int(resource)) else: qs = qs.select_related('resource') if 'user' in request.GET: qs = qs.filter( get_iregex_filter(request.GET.get('user'), 'key', 'name')) qs = qs.annotate(has_multi=F('resource__module__multi_account_allowed')) \ qs = qs.annotate(disabled=Case( When(coders=coder, then=Value(True)), When(coders__isnull=False, has_multi=False, then=Value(True)), default=Value(False), output_field=BooleanField(), )) qs = qs.order_by('disabled') total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [] for r in qs: fields = { 'id': r.key, 'text': f'{r.key} - {r.name}' if r.name and r.key.find(r.name) == -1 else r.key, 'disabled': r.disabled, } if not resource: fields['text'] += f', {r.resource.host}' fields['resource'] = { 'id': r.resource.pk, 'text': r.resource.host } ret.append(fields) elif query == 'organization': qs = Organization.objects.all() name = request.GET.get('name') if name: qs = qs.filter( Q(name__icontains=name) | Q(name_ru__icontains=name) | Q(abbreviation__icontains=name)) total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [{'id': o.name, 'text': o.name} for o in qs] elif query == 'team': qs = Team.objects.all() name = request.GET.get('name') if name: qs = qs.filter(name__icontains=name) event = kwargs.get('event') if event: qs = qs.filter(event=event) qs = qs.annotate( disabled=Case(When(status=TeamStatus.NEW, then=Value(False)), default=Value(True), output_field=BooleanField())).order_by( 'disabled', '-modified') total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [{ 'id': r.id, 'text': r.name, 'disabled': r.disabled } for r in qs] elif query == 'country': qs = list(countries) name = request.GET.get('name') if name: name = name.lower() qs = [(c, n) for c, n in countries if name in n.lower()] total = len(qs) qs = qs[(page - 1) * count:page * count] ret = [{'id': c, 'text': n} for c, n in qs] elif query == 'notpast': title = request.GET.get('title') qs = Contest.objects.filter(title__iregex=verify_regex(title), end_time__gte=timezone.now()) total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [{'id': c.id, 'text': c.title} for c in qs] elif query == 'field-to-select': contest = get_object_or_404(Contest, pk=request.GET.get('cid')) text = request.GET.get('text') field = request.GET.get('field') assert '__' not in field if field == 'languages': qs = contest.info.get('languages', []) qs = [[q] for q in qs if not text or text.lower() in q.lower()] total = len(qs) else: field = f'addition__{field}' qs = contest.statistics_set if text: qs = qs.filter(**{f'{field}__icontains': text}) qs = qs.distinct(field).values_list(field) total = qs.count() qs = qs[(page - 1) * count:page * count] ret = [{'id': f[0], 'text': f[0]} for f in qs] else: return HttpResponseBadRequest('invalid query') result = { 'items': ret, 'more': page * count <= total, } return HttpResponse(json.dumps(result, ensure_ascii=False), content_type="application/json")
def change(request): name = request.POST.get("name", None) value = request.POST.get("value", None) if value in ["true", "false"]: value = "1" if value == "true" else "0" user = request.user coder = user.coder if coder.id != int(request.POST.get("pk", -1)): return HttpResponseBadRequest("invalid pk") if name == "theme": if value not in django_settings.THEMES_: return HttpResponseBadRequest("invalid theme name") if value == 'default': coder.settings.pop('theme') else: coder.settings['theme'] = value coder.save() elif name == "timezone": if value not in (tz["name"] for tz in get_timezones()): return HttpResponseBadRequest("invalid timezone name") coder.timezone = value coder.save() elif name == "check-timezone": if value not in [ "0", "1", ]: return HttpResponseBadRequest("invalid check timezone value") coder.settings["check_timezone"] = int(value) coder.save() elif name == "time-format": try: format_time(timezone.now(), value) except Exception as e: return HttpResponseBadRequest(e) coder.settings["time_format"] = value if value == "": coder.settings.pop("time_format") coder.save() elif name == "add-to-calendar": if value not in django_settings.ACE_CALENDARS_.keys(): return HttpResponseBadRequest("invalid add-to-calendar value") coder.settings["add_to_calendar"] = value coder.save() elif name == "event-limit-calendar": value = request.POST.get("value", None) if value not in ["true", "false"]: if not value.isdigit() or len(value) > 2 or int(value) < 1 or int( value) >= 20: return HttpResponseBadRequest( "invalid event-limit-calendar value") coder.settings["event_limit_calendar"] = value coder.save() elif name == "share-to-category": categories = [k for k, v in coder.get_notifications()] if value != 'disable' and value not in categories: return HttpResponseBadRequest("invalid share-to-category value") coder.settings["share_to_category"] = value coder.save() elif name == "view-mode": if value in ["0", "1"]: value = "list" if value == "1" else "calendar" if value not in [ "list", "calendar", ]: return HttpResponseBadRequest("invalid view mode") coder.settings["view_mode"] = value coder.save() elif name in [ "hide-contest", "all-standings", "open-new-tab", "group-in-list", "calendar-filter-long" ]: if value not in [ "0", "1", ]: return HttpResponseBadRequest(f"invalid {name} value") key = name.replace('-', '_') coder.settings[key] = int(value) coder.save() elif name == "email": if value not in (token.email for token in coder.token_set.all()): return HttpResponseBadRequest("invalid email") user.email = value user.save() elif name == "country": coder.country = value coder.save() elif name == "custom-countries": country = request.POST.get("country", None) if country not in django_settings.CUSTOM_COUNTRIES_: return HttpResponseBadRequest( f"invalid custom country '{country}'") if value not in django_settings.CUSTOM_COUNTRIES_[country]: return HttpResponseBadRequest( f"invalid custom value '{value}' for country '{country}'") with transaction.atomic(): coder.settings.setdefault('custom_countries', {})[country] = value coder.save() for account in coder.account_set.prefetch_related('coders'): update_account_by_coders(account) elif name == "filter": try: field = "Filter id" id_ = int(request.POST.get("value[id]", -1)) filter_ = Filter.objects.get(pk=id_, coder=coder) filter_.name = request.POST.get("value[name]", "").strip().replace( "'", "") or None field = "Duration" duration_from = request.POST.get("value[duration][from]", None) filter_.duration_from = int( duration_from ) if duration_from and duration_from != "NaN" else None duration_to = request.POST.get("value[duration][to]", None) filter_.duration_to = int( duration_to) if duration_to and duration_to != "NaN" else None if filter_.duration_from and filter_.duration_to and filter_.duration_from > filter_.duration_to: raise Exception("{from} should be less or equal {to}") field = "Regex" regex = request.POST.get("value[regex]", None) if regex: re.compile(regex) Contest.objects.filter(title__regex=regex).first() filter_.regex = regex if regex else None field = "Inverse regex" filter_.inverse_regex = request.POST.get("value[inverse_regex]", "false") == "true" if filter_.inverse_regex and not filter_.regex: raise Exception("inverse set but regex is empty") field = "To show" filter_.to_show = request.POST.get("value[to_show]", "false") == "true" field = "Resources" filter_.resources = list( map(int, request.POST.getlist("value[resources][]", []))) if Resource.objects.filter( pk__in=filter_.resources).count() != len( filter_.resources): raise Exception("invalid id") field = "Contest" contest_id = request.POST.get("value[contest]", None) if contest_id: filter_.contest = Contest.objects.get(pk=contest_id) else: filter_.contest = None field = "Resources and contest" if not filter_.resources and not filter_.contest: raise Exception("empty") categories = [c['id'] for c in coder.get_categories()] field = "Categories" filter_.categories = request.POST.getlist("value[categories][]", []) if not all([c in categories for c in filter_.categories]): raise Exception("invalid value(s)") if len(filter_.categories) == 0: raise Exception("empty") filter_.save() except Exception as e: return HttpResponseBadRequest("%s: %s" % (field, e)) elif name == "add-filter": if coder.filter_set.count() >= 50: return HttpResponseBadRequest( "reached the limit number of filters") filter_ = Filter.objects.create(coder=coder) return HttpResponse(json.dumps(filter_.dict()), content_type="application/json") elif name == "delete-filter": try: id_ = int(request.POST.get("id", -1)) filter_ = Filter.objects.get(pk=id_, coder=coder) filter_.delete() except Exception as e: return HttpResponseBadRequest(e) elif name in ( "delete-notification", "reset-notification", ): try: id_ = int(request.POST.get("id", -1)) n = Notification.objects.get(pk=id_, coder=coder) if name == "delete-notification": n.delete() elif name == "reset-notification": n.last_time = timezone.now() n.save() except Exception as e: return HttpResponseBadRequest(e) elif name == "first-name": if not value: return HttpResponseBadRequest("empty first name") user.first_name = value user.save() elif name == "last-name": if not value: return HttpResponseBadRequest("empty last name") user.last_name = value user.save() elif name == "first-name-native": if not value: return HttpResponseBadRequest( "empty first name in native language") coder.first_name_native = value coder.save() elif name == "last-name-native": if not value: return HttpResponseBadRequest("empty last name in native language") coder.last_name_native = value coder.save() elif name == "add-account": if not value: return HttpResponseBadRequest("empty account value") try: resource_id = int(request.POST.get("resource")) resource = Resource.objects.get(pk=resource_id) account = Account.objects.get(resource=resource, key=value) if account.coders.filter(pk=coder.id).first(): raise Exception('Account is already connect to this coder') module = Module.objects.filter(resource=resource).first() if not module or not module.multi_account_allowed: if coder.account_set.filter(resource=resource).exists(): raise Exception('Allow only one account for this resource') if account.coders.count(): raise Exception('Account is already connect') account.coders.add(coder) account.save() return HttpResponse(json.dumps(account.dict()), content_type="application/json") except Exception as e: return HttpResponseBadRequest(e) elif name == "delete-account": if not value: return HttpResponseBadRequest("empty account value") try: host = request.POST.get("resource") account = Account.objects.get(resource__host=host, key=value) account.coders.remove(coder) except Exception as e: return HttpResponseBadRequest(e) elif name == "pre-delete-user": class RollbackException(Exception): pass try: with transaction.atomic(): n_accounts = user.coder.account_set.count() user.coder.account_set.clear() _, delete_info = user.delete() if n_accounts: delete_info.setdefault('ranking.Account_coders', n_accounts) delete_info = [(k, v) for k, v in delete_info.items() if v] delete_info.sort(key=lambda d: d[1], reverse=True) raise RollbackException() except RollbackException: pass delete_info = '\n'.join(f'{k}: {v}' for k, v in delete_info) return JsonResponse({'status': 'ok', 'data': delete_info}) elif name == "delete-user": username = request.POST.get("username") if username != user.username: return HttpResponseBadRequest( f"invalid username: found '{username}', expected '{user.username}'" ) with transaction.atomic(): user.delete() else: return HttpResponseBadRequest("unknown query") return HttpResponse("accepted")
def change(request): name = request.POST.get("name", None) value = request.POST.get("value", None) if value in ["true", "false"]: value = "1" if value == "true" else "0" user = request.user coder = user.coder if coder.id != int(request.POST.get("pk", -1)): return HttpResponseBadRequest("invalid pk") if name == "timezone": if value not in (tz["name"] for tz in get_timezones()): return HttpResponseBadRequest("invalid timezone name") coder.timezone = value coder.save() elif name == "check-timezone": if value not in [ "0", "1", ]: return HttpResponseBadRequest("invalid check timezone value") coder.settings["check_timezone"] = int(value) coder.save() elif name == "time-format": try: format_time(timezone.now(), value) except Exception as e: return HttpResponseBadRequest(e) coder.settings["time_format"] = value if value == "": coder.settings.pop("time_format") coder.save() elif name == "add-to-calendar": if value not in django_settings.ACE_CALENDARS_.keys(): return HttpResponseBadRequest("invalid addtocalendar value") coder.settings["add_to_calendar"] = value coder.save() elif name == "view-mode": if value in ["0", "1"]: value = "list" if value == "1" else "calendar" if value not in [ "list", "calendar", ]: return HttpResponseBadRequest("invalid view mode") coder.settings["view_mode"] = value coder.save() elif name in [ "hide-contest", "all-standings", "open-new-tab", "group-in-list", "calendar-filter-long" ]: if value not in [ "0", "1", ]: return HttpResponseBadRequest(f"invalid {name} value") key = name.replace('-', '_') coder.settings[key] = int(value) coder.save() elif name == "email": if value not in (token.email for token in coder.token_set.all()): return HttpResponseBadRequest("invalid email") user.email = value user.save() elif name == "country": coder.country = value coder.save() elif name == "filter": try: field = "Filter id" id_ = int(request.POST.get("value[id]", -1)) filter_ = Filter.objects.get(pk=id_, coder=coder) filter_.name = request.POST.get("value[name]", "").strip().replace( "'", "") or None field = "Duration" duration_from = request.POST.get("value[duration][from]", None) filter_.duration_from = int( duration_from ) if duration_from and duration_from != "NaN" else None duration_to = request.POST.get("value[duration][to]", None) filter_.duration_to = int( duration_to) if duration_to and duration_to != "NaN" else None if filter_.duration_from and filter_.duration_to and filter_.duration_from > filter_.duration_to: raise Exception("{from} should be less or equal {to}") field = "Regex" regex = request.POST.get("value[regex]", None) if regex: re.compile(regex) Contest.objects.filter(title__regex=regex).first() filter_.regex = regex if regex else None field = "Inverse regex" filter_.inverse_regex = request.POST.get("value[inverse_regex]", "false") == "true" if filter_.inverse_regex and not filter_.regex: raise Exception("inverse set but regex is empty") field = "To show" filter_.to_show = request.POST.get("value[to_show]", "false") == "true" field = "Resources" filter_.resources = list( map(int, request.POST.getlist("value[resources][]", []))) if Resource.objects.filter( pk__in=filter_.resources).count() != len( filter_.resources): raise Exception("invalid id") field = "Contest" contest_id = request.POST.get("value[contest]", None) if contest_id: filter_.contest = Contest.objects.get(pk=contest_id) else: filter_.contest = None field = "Resources and contest" if not filter_.resources and not filter_.contest: raise Exception("empty") categories = coder.get_categories() field = "Categories" filter_.categories = request.POST.getlist("value[categories][]", []) if not all([c in categories for c in filter_.categories]): raise Exception("invalid value(s)") if len(filter_.categories) == 0: raise Exception("empty") filter_.save() except Exception as e: return HttpResponseBadRequest("%s: %s" % (field, e)) elif name == "add-filter": if coder.filter_set.count() >= 50: return HttpResponseBadRequest( "reached the limit number of filters") filter_ = Filter.objects.create(coder=coder) return HttpResponse(json.dumps(filter_.dict()), content_type="application/json") elif name == "delete-filter": try: id_ = int(request.POST.get("id", -1)) filter_ = Filter.objects.get(pk=id_, coder=coder) filter_.delete() except Exception as e: return HttpResponseBadRequest(e) elif name in ( "delete-notification", "reset-notification", ): try: id_ = int(request.POST.get("id", -1)) n = Notification.objects.get(pk=id_, coder=coder) if name == "delete-notification": n.delete() elif name == "reset-notification": n.last_time = timezone.now() n.save() except Exception as e: return HttpResponseBadRequest(e) elif name == "first-name": if not value: return HttpResponseBadRequest("empty first name") user.first_name = value user.save() elif name == "last-name": if not value: return HttpResponseBadRequest("empty last name") user.last_name = value user.save() elif name == "first-name-native": if not value: return HttpResponseBadRequest( "empty first name in native language") coder.first_name_native = value coder.save() elif name == "last-name-native": if not value: return HttpResponseBadRequest("empty last name in native language") coder.last_name_native = value coder.save() elif name == "add-account": if not value: return HttpResponseBadRequest("empty account value") try: resource_id = int(request.POST.get("resource")) resource = Resource.objects.get(pk=resource_id) account = Account.objects.get(resource=resource, key=value) if account.coders.filter(pk=coder.id).first(): raise Exception('Account is already connect to this coder') module = Module.objects.filter(resource=resource).first() if not module or not module.multi_account_allowed: if coder.account_set.filter(resource=resource).exists(): raise Exception('Allow only one account for this resource') if account.coders.count(): raise Exception('Account is already connect') account.coders.add(coder) account.save() return HttpResponse(json.dumps(account.dict()), content_type="application/json") except Exception as e: return HttpResponseBadRequest(e) elif name == "delete-account": if not value: return HttpResponseBadRequest("empty account value") try: host = request.POST.get("resource") account = Account.objects.get(resource__host=host, key=value) account.coders.remove(coder) except Exception as e: return HttpResponseBadRequest(e) else: return HttpResponseBadRequest("unknown query") return HttpResponse("accepted")