333 lines
11 KiB
Python
333 lines
11 KiB
Python
from django import forms
|
|
from django.contrib.auth.forms import UserCreationForm
|
|
from django.core.exceptions import FieldDoesNotExist
|
|
from django.forms import ModelForm
|
|
from mixins.restrictions import RestrictedFormMixin
|
|
|
|
from .models import (
|
|
Ad,
|
|
Aggregator,
|
|
Asset,
|
|
LinkGroup,
|
|
NotificationSettings,
|
|
OperatorWallets,
|
|
Platform,
|
|
Provider,
|
|
Requisition,
|
|
User,
|
|
Wallet,
|
|
)
|
|
|
|
# flake8: noqa: E501
|
|
|
|
|
|
class NewUserForm(UserCreationForm):
|
|
email = forms.EmailField(required=True)
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = (
|
|
"username",
|
|
"email",
|
|
"first_name",
|
|
"last_name",
|
|
"password1",
|
|
"password2",
|
|
)
|
|
|
|
def save(self, commit=True):
|
|
user = super(NewUserForm, self).save(commit=False)
|
|
user.email = self.cleaned_data["email"]
|
|
if commit:
|
|
user.save()
|
|
return user
|
|
|
|
|
|
class CustomUserCreationForm(UserCreationForm):
|
|
class Meta:
|
|
model = User
|
|
fields = "__all__"
|
|
|
|
|
|
class NotificationSettingsForm(RestrictedFormMixin, ModelForm):
|
|
class Meta:
|
|
model = NotificationSettings
|
|
fields = (
|
|
"ntfy_topic",
|
|
"ntfy_url",
|
|
)
|
|
help_texts = {
|
|
"ntfy_topic": "The topic to send notifications to.",
|
|
"ntfy_url": "Custom NTFY server. Leave blank to use the default server.",
|
|
}
|
|
|
|
|
|
class AggregatorForm(RestrictedFormMixin, ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super(AggregatorForm, self).__init__(*args, **kwargs)
|
|
self.fields["secret_id"].label = "Secret ID"
|
|
|
|
class Meta:
|
|
model = Aggregator
|
|
fields = (
|
|
"name",
|
|
"service",
|
|
"secret_id",
|
|
"secret_key",
|
|
"poll_interval",
|
|
"link_group",
|
|
"enabled",
|
|
)
|
|
help_texts = {
|
|
"name": "The name of the aggregator connection.",
|
|
"service": "The aggregator service to use.",
|
|
"secret_id": "The secret ID for the aggregator service.",
|
|
"secret_key": "The secret key for the aggregator service.",
|
|
"poll_interval": "The interval in seconds to poll the aggregator service.",
|
|
"link_group": "The link group to use for this aggregator connection.",
|
|
"enabled": "Whether or not the aggregator connection is enabled.",
|
|
}
|
|
|
|
|
|
class PlatformForm(RestrictedFormMixin, ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super(PlatformForm, self).__init__(*args, **kwargs)
|
|
upper = ["usd", "otp"]
|
|
for field in self.fields:
|
|
for up in upper:
|
|
if self.fields[field].label:
|
|
if up in self.fields[field].label:
|
|
self.fields[field].label = self.fields[field].label.replace(
|
|
up, up.upper()
|
|
)
|
|
|
|
class Meta:
|
|
model = Platform
|
|
fields = (
|
|
"name",
|
|
"service",
|
|
"token",
|
|
"password",
|
|
"otp_token",
|
|
"username",
|
|
"send",
|
|
"cheat",
|
|
"dummy",
|
|
"cheat_interval_seconds",
|
|
"margin",
|
|
"max_margin",
|
|
"min_margin",
|
|
"min_trade_size_usd",
|
|
"max_trade_size_usd",
|
|
"accept_within_usd",
|
|
"no_reference_amount_check_max_usd",
|
|
"base_usd",
|
|
"withdrawal_trigger",
|
|
"payees",
|
|
"link_group",
|
|
"enabled",
|
|
)
|
|
help_texts = {
|
|
"name": "The name of the platform connection.",
|
|
"service": "The platform service to use.",
|
|
"token": "The JWT auth token.",
|
|
"password": "Account password",
|
|
"otp_token": "The OTP secret key.",
|
|
"username": "Account username",
|
|
"send": "Whether or not to send messages on new trades.",
|
|
"cheat": "Whether or not to run the Autoprice cheat.",
|
|
"dummy": "When enabled, the trade escrow feature will be disabled.",
|
|
"cheat_interval_seconds": "The interval in seconds to run the Autoprice cheat.",
|
|
"margin": "The current margin. Only valid for initial ads post. Autoprice will override this.",
|
|
"max_margin": "The maximum margin to use.",
|
|
"min_margin": "The minimum margin to use.",
|
|
"min_trade_size_usd": "The minimum trade size in USD.",
|
|
"max_trade_size_usd": "The maximum trade size in USD.",
|
|
"accept_within_usd": "When a trade is wrong by less than this amount, it will be accepted.",
|
|
"no_reference_amount_check_max_usd": "When ticked, when no reference was found and a trade is higher than this amount, we will not accept payment even if it is the only one with this amount.",
|
|
"base_usd": "The amount in USD to keep in the platform.",
|
|
"withdrawal_trigger": "The amount above the base USD to trigger a withdrawal.",
|
|
"payees": "The wallet addresses to send profit concerning this platform to.",
|
|
"link_group": "The link group to use for this platform.",
|
|
"enabled": "Whether or not the platform connection is enabled.",
|
|
}
|
|
|
|
payees = forms.ModelMultipleChoiceField(
|
|
queryset=Wallet.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
help_text=Meta.help_texts["payees"],
|
|
required=False,
|
|
)
|
|
|
|
|
|
class AdForm(RestrictedFormMixin, ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super(AdForm, self).__init__(*args, **kwargs)
|
|
|
|
class Meta:
|
|
model = Ad
|
|
fields = (
|
|
"name",
|
|
"text",
|
|
"payment_details",
|
|
"payment_details_real",
|
|
"payment_method_details",
|
|
"dist_list",
|
|
"asset_list",
|
|
"provider_list",
|
|
# "platforms",
|
|
# "aggregators",
|
|
"require_feedback_score",
|
|
"account_whitelist",
|
|
"send_reference",
|
|
"visible",
|
|
"link_group",
|
|
"enabled",
|
|
)
|
|
help_texts = {
|
|
"name": "The name of the ad.",
|
|
"text": "The content of the ad.",
|
|
"payment_details": "Shown before a user opens a trade.",
|
|
"payment_details_real": "Shown after a user opens a trade.",
|
|
"payment_method_details": "Shown in the list",
|
|
"dist_list": "Currency and country, space separated, one pair per line.",
|
|
"asset_list": "List of assets to distribute ads for.",
|
|
"provider_list": "List of providers to distribute ads for.",
|
|
# "platforms": "Enabled platforms for this ad",
|
|
# "aggregators": "Enabled aggregators for this ad",
|
|
"require_feedback_score": "Mminimum feedback score for users. Set to 0 to disable.",
|
|
"account_whitelist": "List of account IDs to use, one per line.",
|
|
"send_reference": "Whether or not to send the reference on new trades.",
|
|
"visible": "Whether or not this ad is visible.",
|
|
"link_group": "The link group to use for this ad.",
|
|
"enabled": "Whether or not this ad is enabled.",
|
|
}
|
|
|
|
asset_list = forms.ModelMultipleChoiceField(
|
|
queryset=Asset.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
help_text=Meta.help_texts["asset_list"],
|
|
required=True,
|
|
)
|
|
provider_list = forms.ModelMultipleChoiceField(
|
|
queryset=Provider.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
help_text=Meta.help_texts["provider_list"],
|
|
required=True,
|
|
)
|
|
# platforms = forms.ModelMultipleChoiceField(
|
|
# queryset=Platform.objects.all(),
|
|
# widget=forms.CheckboxSelectMultiple,
|
|
# help_text=Meta.help_texts["platforms"],
|
|
# required=True,
|
|
# )
|
|
# aggregators = forms.ModelMultipleChoiceField(
|
|
# queryset=Aggregator.objects.all(),
|
|
# widget=forms.CheckboxSelectMultiple,
|
|
# help_text=Meta.help_texts["aggregators"],
|
|
# required=True,
|
|
# )
|
|
|
|
|
|
class RequisitionForm(RestrictedFormMixin, ModelForm):
|
|
class Meta:
|
|
model = Requisition
|
|
fields = (
|
|
"payment_details",
|
|
"transaction_source",
|
|
"payees",
|
|
)
|
|
|
|
help_texts = {
|
|
"payment_details": "Shown once a user opens a trade.",
|
|
"transaction_source": "Whether to check pending or booked transactions.",
|
|
"payees": "The wallet addresses to send profit concerning this requisition to.",
|
|
}
|
|
|
|
payees = forms.ModelMultipleChoiceField(
|
|
queryset=Wallet.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
help_text=Meta.help_texts["payees"],
|
|
required=False,
|
|
)
|
|
|
|
|
|
class WalletForm(RestrictedFormMixin, ModelForm):
|
|
class Meta:
|
|
model = Wallet
|
|
fields = (
|
|
"name",
|
|
"address",
|
|
)
|
|
|
|
help_texts = {
|
|
"name": "The name of the wallet.",
|
|
"address": "The XMR address to send funds to.",
|
|
}
|
|
|
|
|
|
class LinkGroupForm(RestrictedFormMixin, ModelForm):
|
|
class Meta:
|
|
model = LinkGroup
|
|
fields = (
|
|
"name",
|
|
"platform_owner_cut_percentage",
|
|
"requisition_owner_cut_percentage",
|
|
"operator_cut_percentage",
|
|
"enabled",
|
|
)
|
|
|
|
help_texts = {
|
|
"name": "The name of the link group.",
|
|
"platform_owner_cut_percentage": "The percentage of the total profit of this group to give to the platform owners.",
|
|
"requisition_owner_cut_percentage": "The percentage of the total profit of this group to give to the requisition owners.",
|
|
"operator_cut_percentage": "The percentage of the total profit of this group to give to the operator.",
|
|
"enabled": "Whether or not this link group is enabled.",
|
|
}
|
|
|
|
def clean(self):
|
|
cleaned_data = super(LinkGroupForm, self).clean()
|
|
platform_owner_cut_percentage = cleaned_data.get(
|
|
"platform_owner_cut_percentage"
|
|
)
|
|
requisition_owner_cut_percentage = cleaned_data.get(
|
|
"requisition_owner_cut_percentage"
|
|
)
|
|
operator_cut_percentage = cleaned_data.get("operator_cut_percentage")
|
|
total_sum = (
|
|
platform_owner_cut_percentage
|
|
+ requisition_owner_cut_percentage
|
|
+ operator_cut_percentage
|
|
)
|
|
if total_sum != 100:
|
|
self.add_error(
|
|
"platform_owner_cut_percentage",
|
|
f"The sum of the percentages must be 100, not {total_sum}.",
|
|
)
|
|
self.add_error(
|
|
"requisition_owner_cut_percentage",
|
|
f"The sum of the percentages must be 100, not {total_sum}.",
|
|
)
|
|
self.add_error(
|
|
"operator_cut_percentage",
|
|
f"The sum of the percentages must be 100, not {total_sum}.",
|
|
)
|
|
return
|
|
return cleaned_data
|
|
|
|
|
|
class OperatorWalletsForm(RestrictedFormMixin, ModelForm):
|
|
class Meta:
|
|
model = OperatorWallets
|
|
fields = ("payees",)
|
|
help_texts = {
|
|
"payees": "Wallets to designate as payees for this operator.",
|
|
}
|
|
|
|
payees = forms.ModelMultipleChoiceField(
|
|
queryset=Wallet.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple,
|
|
help_text=Meta.help_texts["payees"],
|
|
required=False,
|
|
)
|