localcosmos-server 0.24.9__py3-none-any.whl → 0.24.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -206,6 +206,16 @@ class ContactUserSerializer(serializers.Serializer):
206
206
  subject = serializers.CharField()
207
207
  message = serializers.CharField(min_length=10)
208
208
 
209
+
210
+ class ContactStaffSerializer(serializers.Serializer):
211
+
212
+ name = serializers.CharField()
213
+ email = serializers.EmailField()
214
+ subject = serializers.CharField(required=False, allow_blank=True)
215
+ message = serializers.CharField(min_length=10)
216
+ page = serializers.CharField(required=False)
217
+ website = serializers.CharField(required=False, allow_blank=True) # honeypot field
218
+
209
219
 
210
220
  #################################################################################################
211
221
  #
@@ -15,6 +15,9 @@ urlpatterns = [
15
15
  # contact user
16
16
  path('<uuid:app_uuid>/contact-user/<uuid:user_uuid>/', views.ContactUser.as_view(),
17
17
  name='api_contact_user'),
18
+ # contact staff
19
+ path('<uuid:app_uuid>/contact-staff/', views.ContactStaff.as_view(),
20
+ name='api_contact_staff'),
18
21
  # JSON WebToken
19
22
  path('<uuid:app_uuid>/token/', views.TokenObtainPairViewWithClientID.as_view(), name='token_obtain_pair'),
20
23
  path('<uuid:app_uuid>/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
@@ -34,11 +34,12 @@ from localcosmos_server.taxonomy.lazy import LazyAppTaxon
34
34
  from .serializers import (LocalcosmosUserSerializer, RegistrationSerializer, PasswordResetSerializer,
35
35
  TokenObtainPairSerializerWithClientID, ServerContentImageSerializer,
36
36
  LocalcosmosPublicUserSerializer, ContactUserSerializer, TaxonProfileSerializer,
37
- TaxonProfileMinimalSerializer)
37
+ TaxonProfileMinimalSerializer, ContactStaffSerializer)
38
38
 
39
39
  from .permissions import OwnerOnly, AppMustExist, ServerContentImageOwnerOrReadOnly
40
40
 
41
- from localcosmos_server.mails import (send_registration_confirmation_email, send_user_contact_email)
41
+ from localcosmos_server.mails import (send_registration_confirmation_email, send_user_contact_email,
42
+ send_staff_email)
42
43
 
43
44
  from localcosmos_server.datasets.models import Dataset
44
45
  from localcosmos_server.models import UserClients
@@ -435,6 +436,35 @@ class ContactUser(APIView):
435
436
  return Response(serializer.data, status=status.HTTP_200_OK)
436
437
 
437
438
  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
439
+
440
+
441
+ class ContactStaff(APIView):
442
+ '''
443
+ Contact Localcosmos Staff
444
+ - [POST] delivers an email to the staff
445
+ '''
446
+
447
+ permission_classes = ()
448
+ parser_classes = (CamelCaseJSONParser,)
449
+ renderer_classes = (CamelCaseJSONRenderer,)
450
+ serializer_class = ContactStaffSerializer
451
+
452
+ def post(self, request, *args, **kwargs):
453
+
454
+ serializer = self.serializer_class(data=request.data)
455
+
456
+ if serializer.is_valid():
457
+
458
+ if serializer.data.get('website', '') != '':
459
+ # honeypot field filled
460
+ return Response('', status=status.HTTP_200_OK)
461
+
462
+ # send mail
463
+ send_staff_email(kwargs['app_uuid'], serializer.data['name'], serializer.data['email'],
464
+ serializer.data.get('subject', ''), serializer.data['message'],)
465
+ return Response(serializer.data, status=status.HTTP_200_OK)
466
+
467
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
438
468
 
439
469
  ##################################################################################################################
440
470
  #
@@ -7,7 +7,7 @@ from django.utils.translation import gettext as _
7
7
 
8
8
  FROM_EMAIL = settings.DEFAULT_FROM_EMAIL
9
9
 
10
- from localcosmos_server.models import App
10
+ from localcosmos_server.models import App, LocalcosmosUser
11
11
 
12
12
  import re
13
13
 
@@ -101,4 +101,53 @@ def send_user_contact_email(app_uuid, sender, receiver, subject, message):
101
101
  msg = EmailMultiAlternatives(subject, text_message, from_email=from_email, to=[to], headers=headers)
102
102
  msg.attach_alternative(html_message, 'text/html')
103
103
 
104
- msg.send()
104
+ msg.send()
105
+
106
+
107
+ def send_staff_email(app_uuid, sender_name, sender_email, subject, message):
108
+
109
+ app = App.objects.get(uuid=app_uuid)
110
+ frontend = app.get_frontend()
111
+
112
+ staff_users = LocalcosmosUser.objects.filter(is_staff=True, is_active=True)
113
+ receivers = [u.email for u in staff_users]
114
+
115
+ support_email = None
116
+ if frontend and 'configuration' in frontend['userContent'] and 'supportEmail' in frontend['userContent']['configuration']:
117
+ support_email = frontend['userContent']['configuration']['supportEmail']
118
+
119
+ headers = {
120
+ 'Reply-To': sender_email
121
+ }
122
+
123
+ legal_notice_url = reverse('legal_notice', kwargs={'app_uid':app.uid}, urlconf='localcosmos_server.urls')
124
+ privacy_statement_url = reverse('privacy_statement', kwargs={'app_uid':app.uid},
125
+ urlconf='localcosmos_server.urls')
126
+
127
+
128
+ ctx = {
129
+ 'sender_name' : sender_name,
130
+ 'sender_email' : sender_email,
131
+ 'receiver' : receivers,
132
+ 'app' : app,
133
+ 'site' : Site.objects.get_current(),
134
+ 'subject': subject,
135
+ 'message': message,
136
+ 'legal_notice_url' : legal_notice_url,
137
+ 'privacy_statement_url' : privacy_statement_url,
138
+ 'support_email': support_email,
139
+ }
140
+
141
+ from_email = FROM_EMAIL
142
+ to = receivers
143
+
144
+ text_message = render_to_string('email/contact_staff.txt', ctx)
145
+ html_message = get_template('email/contact_staff.html').render(ctx)
146
+
147
+ subject = '[{0}] {1}'.format(app.name, subject)
148
+
149
+ msg = EmailMultiAlternatives(subject, text_message, from_email=from_email, to=to, headers=headers)
150
+ msg.attach_alternative(html_message, 'text/html')
151
+
152
+ msg.send()
153
+
@@ -75,8 +75,11 @@ function ajaxify(container_id){
75
75
  var contentType = 'application/x-www-form-urlencoded; charset=UTF-8';
76
76
  var processData = true;
77
77
  }
78
-
79
- submit_button.attr('disabled','disabled');
78
+
79
+ // only disable button if it has not the class nodisable
80
+ if (!submit_button.hasClass('nodisable')) {
81
+ submit_button.attr('disabled','disabled');
82
+ }
80
83
 
81
84
  $.ajax({
82
85
  type: form.attr('method'),
@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
3
3
 
4
4
  from localcosmos_server.taxonomy.lazy import LazyAppTaxon
5
5
 
6
- from localcosmos_server.taxonomy.widgets import (TaxonAutocompleteWidget, SelectTaxonWidget, ListToLazyTaxon)
6
+ from localcosmos_server.taxonomy.widgets import (TaxonAutocompleteWidget, SelectTaxonWidget, HiddenTaxonWidget, ListToLazyTaxon)
7
7
 
8
8
  '''
9
9
  A field that returns a LazyTaxon instance
@@ -100,3 +100,24 @@ class SelectTaxonField(LazyTaxonField, forms.MultiValueField):
100
100
 
101
101
  super().__init__(fields, *args, require_all_fields=True, **kwargs)
102
102
 
103
+
104
+
105
+ class HiddenTaxonField(LazyTaxonField, forms.MultiValueField):
106
+
107
+ lazy_taxon_class = LazyAppTaxon
108
+
109
+ def __init__(self, *args, **kwargs):
110
+
111
+ include_descendants = kwargs.pop('include_descendants', False)
112
+
113
+ self.widget = HiddenTaxonWidget(include_descendants=include_descendants)
114
+
115
+ fields = [
116
+ forms.CharField(), # taxon_source
117
+ forms.CharField(), # taxon_latname
118
+ forms.CharField(required=False), # taxon_author
119
+ forms.CharField(), # name_uuid
120
+ forms.CharField(), # taxon_nuid
121
+ ]
122
+
123
+ super().__init__(fields, *args, require_all_fields=True, **kwargs)
@@ -216,3 +216,26 @@ class SelectTaxonWidget(ListToLazyTaxon, MultiWidget):
216
216
  value = self.get_lazy_taxon(value)
217
217
  return value
218
218
 
219
+
220
+
221
+ class HiddenTaxonWidget(MultiWidget):
222
+ def __init__(self, attrs=None, include_descendants=False):
223
+ widgets = [
224
+ HiddenInput(), # taxon_source
225
+ HiddenInput(), # taxon_latname
226
+ HiddenInput(), # taxon_author
227
+ HiddenInput(), # name_uuid
228
+ HiddenInput(), # taxon_nuid
229
+ ]
230
+ if include_descendants:
231
+ widgets.append(HiddenInput()) # include_descendants
232
+ super().__init__(widgets, attrs)
233
+
234
+ def decompress(self, lazy_taxon):
235
+
236
+ if lazy_taxon:
237
+ data_list = [lazy_taxon.taxon_source, lazy_taxon.taxon_latname, lazy_taxon.taxon_author,
238
+ str(lazy_taxon.name_uuid), lazy_taxon.taxon_nuid]
239
+ return data_list
240
+
241
+ return []
@@ -0,0 +1,358 @@
1
+ {% load i18n static countries %}
2
+
3
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml">
5
+ <head>
6
+ <meta name="viewport" content="width=device-width" />
7
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
8
+ <title>{% trans 'Registration confirmation' %}</title>
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
13
+ box-sizing: border-box;
14
+ font-size: 14px;
15
+ }
16
+
17
+ img {
18
+ max-width: 100%;
19
+ }
20
+
21
+ body {
22
+ -webkit-font-smoothing: antialiased;
23
+ -webkit-text-size-adjust: none;
24
+ width: 100% !important;
25
+ height: 100%;
26
+ line-height: 1.6em;
27
+ /* 1.6em * 14px = 22.4px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */
28
+ /*line-height: 22px;*/
29
+ }
30
+
31
+ /* Let's make sure all tables have defaults */
32
+ table td {
33
+ vertical-align: top;
34
+ }
35
+
36
+
37
+ body {
38
+ background-color: #f6f6f6;
39
+ }
40
+
41
+ .body-wrap {
42
+ background-color: #f6f6f6;
43
+ width: 100%;
44
+ }
45
+
46
+ .container {
47
+ display: block !important;
48
+ max-width: 600px !important;
49
+ margin: 0 auto !important;
50
+ /* makes it centered */
51
+ clear: both !important;
52
+ }
53
+
54
+ .content {
55
+ max-width: 600px;
56
+ margin: 0 auto;
57
+ display: block;
58
+ padding: 20px;
59
+ }
60
+
61
+ /* -------------------------------------
62
+ HEADER, FOOTER, MAIN
63
+ ------------------------------------- */
64
+ .main {
65
+ background-color: #fff;
66
+ border: 1px solid #e9e9e9;
67
+ border-radius: 3px;
68
+ }
69
+
70
+ .content-wrap {
71
+ padding: 20px;
72
+ }
73
+
74
+ .content-block {
75
+ padding: 0 0 20px;
76
+ }
77
+
78
+ .header {
79
+ width: 100%;
80
+ margin-bottom: 20px;
81
+ }
82
+
83
+ .footer {
84
+ width: 100%;
85
+ clear: both;
86
+ color: #999;
87
+ padding: 20px;
88
+ }
89
+ .footer p, .footer a, .footer td {
90
+ color: #999;
91
+ font-size: 12px;
92
+ }
93
+
94
+ /* -------------------------------------
95
+ TYPOGRAPHY
96
+ ------------------------------------- */
97
+ h1, h2, h3 {
98
+ font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
99
+ color: #000;
100
+ margin: 20px 0 0;
101
+ line-height: 1.2em;
102
+ font-weight: 400;
103
+ }
104
+
105
+ h1 {
106
+ font-size: 32px;
107
+ font-weight: 500;
108
+ /* 1.2em * 32px = 38.4px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */
109
+ /*line-height: 38px;*/
110
+ }
111
+
112
+ h2 {
113
+ font-size: 24px;
114
+ /* 1.2em * 24px = 28.8px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */
115
+ /*line-height: 29px;*/
116
+ }
117
+
118
+ h3 {
119
+ font-size: 18px;
120
+ /* 1.2em * 18px = 21.6px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */
121
+ /*line-height: 22px;*/
122
+ }
123
+
124
+ h4 {
125
+ font-size: 14px;
126
+ font-weight: 600;
127
+ }
128
+
129
+ p, ul, ol {
130
+ margin-bottom: 10px;
131
+ font-weight: normal;
132
+ }
133
+ p li, ul li, ol li {
134
+ margin-left: 5px;
135
+ list-style-position: inside;
136
+ }
137
+
138
+ /* -------------------------------------
139
+ LINKS & BUTTONS
140
+ ------------------------------------- */
141
+ a {
142
+ color: #348eda;
143
+ text-decoration: underline;
144
+ }
145
+
146
+ .btn-primary {
147
+ text-decoration: none;
148
+ color: #FFF;
149
+ background-color: #348eda;
150
+ border: solid #348eda;
151
+ border-width: 10px 20px;
152
+ line-height: 2em;
153
+ /* 2em * 14px = 28px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */
154
+ /*line-height: 28px;*/
155
+ font-weight: bold;
156
+ text-align: center;
157
+ cursor: pointer;
158
+ display: inline-block;
159
+ border-radius: 5px;
160
+ text-transform: capitalize;
161
+ }
162
+
163
+ /* -------------------------------------
164
+ OTHER STYLES THAT MIGHT BE USEFUL
165
+ ------------------------------------- */
166
+ .last {
167
+ margin-bottom: 0;
168
+ }
169
+
170
+ .first {
171
+ margin-top: 0;
172
+ }
173
+
174
+ .aligncenter {
175
+ text-align: center;
176
+ }
177
+
178
+ .alignright {
179
+ text-align: right;
180
+ }
181
+
182
+ .alignleft {
183
+ text-align: left;
184
+ }
185
+
186
+ .clear {
187
+ clear: both;
188
+ }
189
+
190
+ /* -------------------------------------
191
+ ALERTS
192
+ Change the class depending on warning email, good email or bad email
193
+ ------------------------------------- */
194
+ .alert {
195
+ font-size: 16px;
196
+ color: #fff;
197
+ font-weight: 500;
198
+ padding: 20px;
199
+ text-align: center;
200
+ border-radius: 3px 3px 0 0;
201
+ }
202
+ .alert a {
203
+ color: #fff;
204
+ text-decoration: none;
205
+ font-weight: 500;
206
+ font-size: 16px;
207
+ }
208
+ .alert.alert-warning {
209
+ background-color: #FF9F00;
210
+ }
211
+ .alert.alert-bad {
212
+ background-color: #D0021B;
213
+ }
214
+ .alert.alert-good {
215
+ background-color: #68B90F;
216
+ }
217
+
218
+ /* -------------------------------------
219
+ INVOICE
220
+ Styles for the billing table
221
+ ------------------------------------- */
222
+ .invoice {
223
+ margin: 40px auto;
224
+ text-align: left;
225
+ width: 80%;
226
+ }
227
+ .invoice td {
228
+ padding: 5px 0;
229
+ }
230
+ .invoice .invoice-items {
231
+ width: 100%;
232
+ }
233
+ .invoice .invoice-items td {
234
+ border-top: #eee 1px solid;
235
+ }
236
+ .invoice .invoice-items .total td {
237
+ border-top: 2px solid #333;
238
+ border-bottom: 2px solid #333;
239
+ font-weight: 700;
240
+ }
241
+
242
+ /* -------------------------------------
243
+ RESPONSIVE AND MOBILE FRIENDLY STYLES
244
+ ------------------------------------- */
245
+ @media only screen and (max-width: 640px) {
246
+ body {
247
+ padding: 0 !important;
248
+ }
249
+
250
+ h1, h2, h3, h4 {
251
+ font-weight: 800 !important;
252
+ margin: 20px 0 5px !important;
253
+ }
254
+
255
+ h1 {
256
+ font-size: 22px !important;
257
+ }
258
+
259
+ h2 {
260
+ font-size: 18px !important;
261
+ }
262
+
263
+ h3 {
264
+ font-size: 16px !important;
265
+ }
266
+
267
+ .container {
268
+ padding: 0 !important;
269
+ width: 100% !important;
270
+ }
271
+
272
+ .content {
273
+ padding: 0 !important;
274
+ }
275
+
276
+ .content-wrap {
277
+ padding: 10px !important;
278
+ }
279
+
280
+ .invoice {
281
+ width: 100% !important;
282
+ }
283
+ }
284
+ </style>
285
+
286
+ </head>
287
+
288
+ <body itemscope itemtype="http://schema.org/EmailMessage">
289
+
290
+ <table class="body-wrap">
291
+ <tr>
292
+ <td></td>
293
+ <td class="container" width="600">
294
+ <div class="content">
295
+ <table class="main" width="100%" cellpadding="0" cellspacing="0">
296
+ <tr>
297
+ <td class="content-wrap aligncenter">
298
+ <table width="100%" cellpadding="0" cellspacing="0">
299
+ <tr>
300
+ <td>
301
+ <table width="100%">
302
+ <tr>
303
+ <td width="70%" class="alignleft" style="vertical-align:middle;">
304
+ &nbsp;
305
+ </td>
306
+ <td width="30%" class="alignright">
307
+ <img src="http://{{ site.domain }}{% static 'images/local_cosmos_logo_40.png' %}" height="40" />
308
+ </td>
309
+ </tr>
310
+ </table>
311
+ </td>
312
+ </tr>
313
+ <tr>
314
+ <td class="aligncenter">
315
+ <h2>{% blocktrans with username=sender_name %}Message from {{ username }}{% endblocktrans %}</h2>
316
+ </td>
317
+ </tr>
318
+ <tr>
319
+ <td class="content-block">
320
+ <br>
321
+ <h3>{{ subject }}</h3>
322
+ <br><br>
323
+
324
+ {{ message }}<br><br>
325
+
326
+ <p>
327
+ {% blocktrans with username=sender_name email=sender_email %}Reply to {{ username }}: {{ email }}{% endblocktrans %}
328
+ </p>
329
+ </td>
330
+ </tr>
331
+ </table>
332
+ </td>
333
+ </tr>
334
+ </table>
335
+ <div class="footer">
336
+ <table width="100%">
337
+ {% if support_email %}
338
+ <tr>
339
+ <td class="aligncenter content-block">
340
+ {% trans 'Questions?' %} E-Mail <a href="mailto:{{ support_email }}">{{ support_email }}</a>
341
+ </td>
342
+ </tr>
343
+ {% endif %}
344
+ <tr>
345
+ <td class="aligncenter content-block">
346
+ <a href="https://{{ site.domain }}{{ legal_notice_url }}" target="_blank">{% trans 'Legal notice' %}</a> &nbsp; &nbsp;
347
+ <a href="https://{{ site.domain }}{{ privacy_statement_url }}" target="_blank">{% trans 'Privacy statement' %}</a>
348
+ </td>
349
+ </tr>
350
+ </table>
351
+ </div></div>
352
+ </td>
353
+ <td></td>
354
+ </tr>
355
+ </table>
356
+
357
+ </body>
358
+ </html>
@@ -0,0 +1,21 @@
1
+ {% load i18n %}
2
+ {% load i18n %}
3
+ {{ app.name }}
4
+
5
+ {% blocktrans with username=sender_name %}Message from {{ username }}{% endblocktrans %}
6
+
7
+ {{ subject }}
8
+
9
+ ---------------------------------------------------------------------------=
10
+ ------------
11
+ {{ message }}
12
+
13
+ ---------------------------------------------------------------------------=
14
+ ------------
15
+ {% blocktrans with username=sender_name email=sender_email %}Reply to {{ username }}: {{ email }}{% endblocktrans %}
16
+
17
+
18
+ ---------------------------------------------------------------------------=
19
+ ---------------------------
20
+ {% trans 'Legal notice' %}: https://{{ site.domain }}{{ legal_notice_url }}
21
+ {% trans 'Privacy statement' %}: https://{{ site.domain }}{{ privacy_statement_url }}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localcosmos_server
3
- Version: 0.24.9
3
+ Version: 0.24.11
4
4
  Summary: LocalCosmos Private Server. Run your own server for localcosmos.org apps.
5
5
  Home-page: https://github.com/SiSol-Systems/localcosmos-server
6
6
  Author: Thomas Uher
@@ -7,7 +7,7 @@ localcosmos_server/fields.py,sha256=w_3cPm7kV_DBVlzPO2cDogMWAs-tf9MqwjHh8glpMrc,
7
7
  localcosmos_server/forms.py,sha256=pKEsEzhBuQkN8AFl0cuMb7SuZIGRYgM7fH4vEXVphxQ,13103
8
8
  localcosmos_server/generic_views.py,sha256=OCsah0mRc58rAb55f_hrFXSZoGrOaB1IlJs-VOP7gAg,9565
9
9
  localcosmos_server/global_urls.py,sha256=Us4i_tc3I1PlGxB37EBh2I8n7-7mbJu9DaGEd4kKET0,3673
10
- localcosmos_server/mails.py,sha256=EK5MwQSfQmsz55PDtlwJ6ZlMLUqFJ-TTDBvu1SP6tAA,3653
10
+ localcosmos_server/mails.py,sha256=erHQrBtGPBCf3M3thY-w1diL-w8-Scvm9nS0EpKrGRQ,5369
11
11
  localcosmos_server/middleware.py,sha256=2U-e_za1kC0YRD8XyHyh21OrcbEnD4shx0Zj2qNeMyU,931
12
12
  localcosmos_server/models.py,sha256=TcWLO3rxc7Xj2Pj8KHBS9XH9aaLOTdGD8MQ2VKUwG-A,40726
13
13
  localcosmos_server/permission_rules.py,sha256=Xww9bG2HD_lmXiMCBraxJbaJwPOon8tqtcdvk0xokiw,1833
@@ -37,9 +37,9 @@ localcosmos_server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
37
37
  localcosmos_server/api/anycluster_schema_urls.py,sha256=nVa9-1pf6a1F-LNYaN3im9xy9LkebIxp0eaJs-Bwvok,1219
38
38
  localcosmos_server/api/examples.py,sha256=o9MyhwcsOKUI1YstEKQ7bFHM5nrVjy873WQcH_OTL-s,309
39
39
  localcosmos_server/api/permissions.py,sha256=HLToMDOGIMYWsRbM1asgw5NUGz7ukABrqGLSJxZEaXI,1303
40
- localcosmos_server/api/serializers.py,sha256=C7yZgyIBrJ9ZaVI2MSx-JpbrYVI5uL0NPdkuH2ty_cg,22487
41
- localcosmos_server/api/urls.py,sha256=YwGSsvIofYWMPuO1e69VEo2W6oOM6TWU4vrv_Z9DuRk,2282
42
- localcosmos_server/api/views.py,sha256=1RSz7r5fGs0VC1fmu0VAk6N6BZ3wncv3fxkOVmY3MOM,26686
40
+ localcosmos_server/api/serializers.py,sha256=dHUfORehvYnE00MJRHpaAwTRuTjVu63ImFTOjgL_5iQ,22885
41
+ localcosmos_server/api/urls.py,sha256=hmqZpCHL4JDS5bn3SoIydPuJq3Bcc-ci3FfVm1mDRc4,2411
42
+ localcosmos_server/api/views.py,sha256=kQmy9rZxbh88ijujGVgS9J-8Y7zJnoCq8_iomtnLjWI,27790
43
43
  localcosmos_server/api/example_files/taxon_profile.json,sha256=SeWCnsAHQejKZoKxBVEelcETd3emYYkuDXjkvJFSUlU,4861
44
44
  localcosmos_server/app_admin/__init__.py,sha256=lMCpmLuBfqI0C1-T9gs-O3BPnl0Kg4L2hPlHDI-uPGs,73
45
45
  localcosmos_server/app_admin/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
@@ -944,7 +944,7 @@ localcosmos_server/static/localcosmos_server/interactive-image-field/Interactive
944
944
  localcosmos_server/static/localcosmos_server/js/ajax_file_input.js,sha256=lF9gSbLwV0COAnTboWSQBws8BJGHnlnsOMzci-pDOW4,1239
945
945
  localcosmos_server/static/localcosmos_server/js/bootstrap3-typeahead.js,sha256=qL2G4PGoEFnnWHBa7FLLDgkv7SWWTUViAIbgdML9HQ4,22466
946
946
  localcosmos_server/static/localcosmos_server/js/django-ajax-csrf.js,sha256=y6yRBzfURudBpPMwaPmL1UbPRyLVHp7Oh3EJBSL8BzQ,1570
947
- localcosmos_server/static/localcosmos_server/js/django-ajax.js,sha256=Vgyx6q0WdnP549IpQXSpcCc_j-kApVpsGOT9MpDkf_8,2176
947
+ localcosmos_server/static/localcosmos_server/js/django-ajax.js,sha256=-MgCdL2r-pC30_SLAGfSTuIwBqXdSy9wGSzMC1tOzIw,2288
948
948
  localcosmos_server/static/localcosmos_server/js/jquery-datasettaxon-autocomplete.js,sha256=ixTb5ItV5ktkiX1UNVbKVbRANJDeHdNAriutJtGm4qc,1172
949
949
  localcosmos_server/static/localcosmos_server/js/jquery-taxon-autocomplete.js,sha256=RPzfhK4Ncv_frrRyz1Phd1t_Uyy0ynovuK3eynM9jpc,3946
950
950
  localcosmos_server/static/localcosmos_server/js/jquery-user-autocomplete.js,sha256=Mg54Aesc-Uz-ZzKUgquLn-w2ulR6-nMb6fqPMEnP_F4,1006
@@ -2557,13 +2557,13 @@ localcosmos_server/static/phosphor-icons/youtube-logo.svg,sha256=fB9Vuc9r9KUVPOq
2557
2557
  localcosmos_server/taxonomy/AppTaxonSearch.py,sha256=OixiqMD9rASgLdpuW2I5ZqNLkCRjTdjFNNyd1CaEA34,5085
2558
2558
  localcosmos_server/taxonomy/TaxonManager.py,sha256=kc-T3edXw_kbw-guhEtF5Q00tL_WG636OtuuuCbupQA,11979
2559
2559
  localcosmos_server/taxonomy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2560
- localcosmos_server/taxonomy/fields.py,sha256=UWoRSDq5C0wByECugDXs_Upz-GDsEirj2Fi9p9aDJz8,3045
2560
+ localcosmos_server/taxonomy/fields.py,sha256=7u_XYk3l-DK6Znoa1nAJshOJWBTfqbODOHeVFuhk1bM,3715
2561
2561
  localcosmos_server/taxonomy/forms.py,sha256=EvEGvbGAq8c0hwSO-FUdPiwODHNG1PjF5OKcZ9rAIv4,1602
2562
2562
  localcosmos_server/taxonomy/generic.py,sha256=xfDZr1eWTJZyy-5rLt07t45wfkIEWkr6soFshxzO5wc,7163
2563
2563
  localcosmos_server/taxonomy/lazy.py,sha256=kSZ-vmt36EE4n3-4Ad6_OXJcFKcDG90_f_KDDJooy1E,13575
2564
2564
  localcosmos_server/taxonomy/urls.py,sha256=HuAZJJrfltJpw3icjezG6aIHMYGbTidWPQzffzz7j_4,742
2565
2565
  localcosmos_server/taxonomy/views.py,sha256=tKHiYIaksj_aqaKHpx1nYoIIospgZhmrSyYm1wKy2RA,5524
2566
- localcosmos_server/taxonomy/widgets.py,sha256=Gv-6oLjXa0RyHq2osY4ZhEh6C6LlAWExPorqBSPX3-4,6570
2566
+ localcosmos_server/taxonomy/widgets.py,sha256=6WZhbKxyo5HXybwK0kPs2Yn33Vptz-wKGigdyL2Wl6U,7338
2567
2567
  localcosmos_server/template_content/Templates.py,sha256=lGKsQxjywy60nxvYz02Z5C618-H4H73XyGd2oxHx87Y,7296
2568
2568
  localcosmos_server/template_content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2569
2569
  localcosmos_server/template_content/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
@@ -2717,6 +2717,8 @@ localcosmos_server/templates/el_pagination/page_link.html,sha256=bGnXzdHoWF39B5g
2717
2717
  localcosmos_server/templates/el_pagination/previous_link.html,sha256=dpHGyKEKdKozmuVy5JWYD4iuYrNt3iLsEL-JPk1KuKo,187
2718
2718
  localcosmos_server/templates/el_pagination/show_more.html,sha256=vP2Cyf8bErEGgAiXvKaOaonKT7UUobVi1nuxMk8mcaI,429
2719
2719
  localcosmos_server/templates/el_pagination/show_pages.html,sha256=yP_GhLW0YqOHDV3tXwR9MYQtzuEElxiX04YAZLJHzbg,267
2720
+ localcosmos_server/templates/email/contact_staff.html,sha256=GZsmVbuY3ls4tMOGHJdlSyTOc2GM2i1cQbmRL6KBhW8,7605
2721
+ localcosmos_server/templates/email/contact_staff.txt,sha256=c3_q16FXb8ceVcIgB00BffeJKMcZhW38LyL9LI_hqZY,734
2720
2722
  localcosmos_server/templates/email/contact_user.html,sha256=L1woPKmvOrMcBGBcAvPulH7sWKn8BkpDF5dUmDNTU4A,7613
2721
2723
  localcosmos_server/templates/email/contact_user.txt,sha256=VzKH9-nm0ofYg2fp9eOgXgSwLcGOvmv2W0ZITnm0ibY,726
2722
2724
  localcosmos_server/templates/email/registration_confirmation.html,sha256=ALF2M-mmdMXy-kJJmaLyUrjLoZUeI0ShMewUTLFV50s,7657
@@ -2777,8 +2779,8 @@ localcosmos_server/tests/mixins.py,sha256=2k-zCrqndwQLABNULDWRftROij3kwhW_bTiV6r
2777
2779
  localcosmos_server/tests/test_forms.py,sha256=axF1v-T0NGR16St3hueQAuREb2sbWzajdNFQDpFeYqI,9767
2778
2780
  localcosmos_server/tests/test_models.py,sha256=h4d70Ps0hLbcgL6rL1OV_6zxJ_ewDfHgvzJTJDw1m6E,33000
2779
2781
  localcosmos_server/tests/test_views.py,sha256=SaEuAFAfapsSJi1_R6WEgp41MB03sPruCIy_hJ_oGwc,4308
2780
- localcosmos_server-0.24.9.dist-info/licenses/LICENCE,sha256=VnxALPSxXoU59rlNeRdJtwS_nU79IFpVWsZZCQUM4Mw,1086
2781
- localcosmos_server-0.24.9.dist-info/METADATA,sha256=dLFwzSZeyrNNTATEnMjQVPinv_HpI05B9oxpTCnT1KI,1686
2782
- localcosmos_server-0.24.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2783
- localcosmos_server-0.24.9.dist-info/top_level.txt,sha256=hNVjlPGCtXvUF5CJY5HOFA_Dh5fYivfqVSyFMUDkqPY,19
2784
- localcosmos_server-0.24.9.dist-info/RECORD,,
2782
+ localcosmos_server-0.24.11.dist-info/licenses/LICENCE,sha256=VnxALPSxXoU59rlNeRdJtwS_nU79IFpVWsZZCQUM4Mw,1086
2783
+ localcosmos_server-0.24.11.dist-info/METADATA,sha256=Ju41rDZ2U_S490bvvj7PRxs9a_xgCDmq754UQAkiKK8,1687
2784
+ localcosmos_server-0.24.11.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
2785
+ localcosmos_server-0.24.11.dist-info/top_level.txt,sha256=hNVjlPGCtXvUF5CJY5HOFA_Dh5fYivfqVSyFMUDkqPY,19
2786
+ localcosmos_server-0.24.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5