forked from gumptioncom/mc-coal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
forms.py
190 lines (152 loc) · 5.79 KB
/
forms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
from google.appengine.api import urlfetch
from google.appengine.ext import ndb
import pytz
from wtforms import fields, validators, widgets
from models import Server, User, MinecraftDownload
class StringListField(fields.Field):
widget = widgets.TextInput()
def __init__(self, label='', validators=None, remove_duplicates=True, **kwargs):
super(StringListField, self).__init__(label, validators, **kwargs)
self.remove_duplicates = remove_duplicates
def _value(self):
if self.data:
return u', '.join(self.data)
else:
return u''
def process_data(self, value):
if value:
self.data = [x.strip() for x in value]
else:
self.data = []
if self.remove_duplicates:
self.data = list(self._remove_duplicates(self.data))
def process_formdata(self, valuelist):
if valuelist:
self.data = [x.strip() for x in valuelist[0].split(',')]
else:
self.data = []
if self.remove_duplicates:
self.data = list(self._remove_duplicates(self.data))
@classmethod
def _remove_duplicates(cls, seq):
d = {}
for item in seq:
if item and item not in d:
d[item] = True
yield item
class UniqueShortName(object):
def __init__(self, server=None):
self.server = server
def __call__(self, form, field):
server = self.server or form.server
short_name = field.data
key = None
try:
key = ndb.Key(urlsafe=short_name)
except:
pass
if key is not None:
raise validators.ValidationError("Short name can't be a valid key string".format(short_name))
s = Server.get_by_short_name(short_name)
if s is not None:
if server is None or s.key != server.key:
raise validators.ValidationError(
"Short name '{0}' is already assigned to another server".format(short_name)
)
class UniqueUsername(object):
def __call__(self, form, field):
username = field.data
u = User.lookup(username=username)
if u is not None:
raise validators.ValidationError("Username '{0}' is already assigned to a user".format(username))
class UniqueUsernames(object):
def __init__(self, user=None):
self.user = user
def __call__(self, form, field):
user = self.user or form.user
usernames = field.data
for username in usernames:
u = User.lookup(username=username)
if u is not None:
if user is None or u.key != user.key:
raise validators.ValidationError("Username '{0}' is already assigned to a user".format(username))
class AtLeastOneAdmin(object):
def __call__(self, form, field):
if not field.data and form.user.admin and User.is_single_admin():
raise validators.ValidationError("Can't demote this user. There must always be at least one admin user.")
class ValidTimezone(object):
def __call__(self, form, field):
timezone = field.data
try:
pytz.timezone(timezone)
except:
raise validators.ValidationError("Not a valid timezone".format(timezone))
class UniquePort(object):
def __init__(self, server=None):
self.server = server
def __call__(self, form, field):
server = self.server or form.server
port = field.data
if port:
port = int(port)
if port in Server.reserved_ports(ignore_server=server):
raise validators.ValidationError("Port {0} is already reserved for another server".format(port))
class UniqueVersion(object):
def __call__(self, form, field):
version = field.data
md = MinecraftDownload.lookup(version)
if md is not None:
raise validators.ValidationError("Minecraft version '{0}' is already assigned".format(version))
class VersionUrlExists(object):
def __call__(self, form, field):
url = field.data
result = urlfetch.fetch(url=url, method=urlfetch.HEAD)
if result.status_code >= 400:
raise validators.ValidationError("Error ({0}) fetching url".format(result.status_code))
class RestfulStringField(fields.StringField):
def process_data(self, value):
if value:
self.data = value
else:
self.data = None
def process_formdata(self, valuelist):
if valuelist:
self.data = valuelist[0]
else:
self.data = None
class RestfulBooleanField(fields.BooleanField):
def process_data(self, value):
if value is not None:
b = value.lower()
if b and (b[0] == 'n' or b[0] == 'f' or b[0] == '0'):
self.data = False
else:
self.data = bool(value)
else:
self.data = self.default
def process_formdata(self, valuelist):
if valuelist:
b = valuelist[0].lower()
if b and (b[0] == 'n' or b[0] == 'f' or b[0] == '0'):
self.data = False
else:
self.data = bool(valuelist[0])
else:
self.data = self.default
class RestfulSelectField(fields.SelectField):
def process_data(self, value):
try:
if value is not None:
self.data = self.coerce(value)
else:
self.data = None
except (ValueError, TypeError):
self.data = None
def process_formdata(self, valuelist):
if valuelist:
try:
self.data = self.coerce(valuelist[0])
except ValueError:
raise ValueError(self.gettext('Invalid Choice: could not coerce'))
else:
self.data = None