Skip to content

Commit 4715766

Browse files
authored
Merge pull request #531 from wellfire/add-data
Updated P2P functionality & extra commands
2 parents 028d368 + 1e3115d commit 4715766

6 files changed

Lines changed: 181 additions & 8 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"""
2+
Management command to add a superuser with CLI args including UserProfile
3+
4+
This should only be used to programmatically create superusers with *initial*
5+
passwords, to be changed after creation.
6+
7+
Usage:
8+
9+
django-admin.py add_super_user --email="someone@hello.com" --password="COOLPASSWORD"
10+
11+
"""
12+
13+
from django.contrib.auth import get_user_model
14+
from django.core.management.base import BaseCommand
15+
16+
from orb.models import UserProfile
17+
18+
19+
class Command(BaseCommand):
20+
21+
def add_arguments(self, parser):
22+
parser.add_argument(
23+
'--email',
24+
dest='email',
25+
help='Email address',
26+
required=True,
27+
)
28+
parser.add_argument(
29+
'--password',
30+
dest='password',
31+
help='Initial password',
32+
required=True,
33+
)
34+
35+
def handle(self, *args, **options):
36+
37+
username = options.get('email')
38+
39+
try:
40+
user = get_user_model().objects.get(username=username)
41+
except get_user_model().DoesNotExist:
42+
get_user_model().objects.create_superuser(
43+
username,
44+
password=options.get('password'),
45+
email=options.get('email'),
46+
)
47+
UserProfile.objects.create(user=user)
48+
self.stdout.write("Create new user '{}'".format(username))
49+
else:
50+
self.stdout.write("Found existing user '{}'".format(username))
51+

orb/models.py

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import itertools
12
import os
23
import uuid
34

@@ -11,6 +12,9 @@
1112
from django.db.models import Avg, Count
1213
from django.utils.translation import ugettext_lazy as _
1314
from modeltranslation.utils import build_localized_fieldname
15+
from typing import Any
16+
from typing import Dict
17+
from typing import Iterable
1418

1519
from orb import signals
1620
from orb.analytics.models import UserLocationVisualization
@@ -151,7 +155,9 @@ def update_from_api(self, api_data):
151155

152156
import_user = get_import_user()
153157

154-
for attr, value in api_data.iteritems():
158+
cleaned_api_data = clean_api_data(api_data, 'attribution', 'description', 'title')
159+
160+
for attr, value in cleaned_api_data.iteritems():
155161
setattr(self, attr, value)
156162

157163
self.update_user = import_user
@@ -172,6 +178,7 @@ def create_from_api(cls, api_data, peer=None):
172178
the Resource object created
173179
174180
"""
181+
175182
resource_files = api_data.pop('files', [])
176183
languages = api_data.pop('languages', [])
177184
tags = api_data.pop('tags', [])
@@ -181,18 +188,37 @@ def create_from_api(cls, api_data, peer=None):
181188

182189
import_user = get_import_user()
183190

184-
resource = cls.resources.create(source_peer=peer, create_user=import_user, update_user=import_user, **api_data)
191+
cleaned_api_data = clean_api_data(api_data, 'attribution', 'description', 'title')
192+
193+
resource = cls.resources.create(
194+
source_peer=peer,
195+
create_user=import_user,
196+
update_user=import_user,
197+
**cleaned_api_data
198+
)
185199

186200
ResourceURL.objects.bulk_create([
187-
ResourceURL.from_url_data(resource, resource_url_data, import_user)
201+
ResourceURL.from_url_data(
202+
resource,
203+
clean_api_data(resource_url_data, "description", "title"),
204+
import_user,
205+
)
188206
for resource_url_data in resource_urls
189207
] + [
190-
ResourceURL.from_file_data(resource, resource_file_data, import_user)
208+
ResourceURL.from_file_data(
209+
resource,
210+
clean_api_data(resource_file_data, "description", "title"),
211+
import_user,
212+
)
191213
for resource_file_data in resource_files
192214
])
193215

194216
for tag_data in tags:
195-
ResourceTag.create_from_api_data(resource, tag_data['tag'], user=import_user)
217+
ResourceTag.create_from_api_data(
218+
resource,
219+
clean_api_data(tag_data['tag'], "category", "description", "name", "summary"),
220+
user=import_user,
221+
)
196222

197223
return resource
198224

@@ -668,6 +694,10 @@ def create_from_api_data(cls, resource, api_data, user=None):
668694
for field in category_fields
669695
}
670696

697+
for field in api_data.keys():
698+
if field.startswith("category"):
699+
del api_data[field]
700+
671701
category, created = Category.objects.get_or_create(name=category_name, defaults=category_name_translations)
672702

673703
api_data['category'] = category
@@ -903,3 +933,33 @@ def get_import_user():
903933
user.save()
904934
return user
905935

936+
937+
def clean_api_data(data, *fields):
938+
# type: (Dict[unicode, Any], Iterable[unicode]) -> Dict[unicode, Any]
939+
"""
940+
Returns API resource data with unusable translations filtered
941+
942+
Args:
943+
data: original API data
944+
*fields: translated field names
945+
946+
Returns:
947+
same API data with unsupported translations dropped
948+
949+
"""
950+
language_codes = [l[0].replace('-', '_') for l in settings.LANGUAGES]
951+
supported_field_translations = [
952+
"{}_{}".format(field, language)
953+
for (field, language) in itertools.product(fields, language_codes)
954+
]
955+
def allowed_field(test_field):
956+
# type: (unicode) -> bool
957+
if test_field != 'id' or test_field in fields or test_field in supported_field_translations:
958+
return True
959+
return not any([test_field.startswith(f) for f in fields])
960+
961+
return {
962+
key: value
963+
for key, value in data.items()
964+
if allowed_field(key)
965+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
Management command to add a peer to the local list of peers.
3+
4+
The command will return exit code 0 if added OR the peer already exists, and
5+
1 for any other error.
6+
7+
Usage:
8+
9+
django-admin.py add_peer https://some.host.org --user=username --key=APIKEY --name=SomeHost
10+
11+
"""
12+
13+
from django.core.management.base import BaseCommand
14+
from django.core.validators import URLValidator
15+
from django.core.validators import ValidationError
16+
17+
from orb.peers.models import Peer
18+
19+
20+
class Command(BaseCommand):
21+
22+
def add_arguments(self, parser):
23+
parser.add_argument('host')
24+
parser.add_argument(
25+
'--name',
26+
dest='name',
27+
help='Name of the peer',
28+
required=True,
29+
)
30+
parser.add_argument(
31+
'--user',
32+
dest='user',
33+
help='API username',
34+
required=True,
35+
)
36+
parser.add_argument(
37+
'--key',
38+
dest='key',
39+
help='API key',
40+
required=True,
41+
)
42+
43+
def handle(self, *args, **options):
44+
host = options.get('host')
45+
46+
try:
47+
URLValidator()(host)
48+
except ValidationError as err:
49+
self.stderr.write("The host name '{}' is not a valid host URL".format(host))
50+
exit(1)
51+
52+
peer, created = Peer.objects.get_or_create(host=host, defaults={
53+
'name': options.get('name'),
54+
'api_user': options.get('user'),
55+
'api_key': options.get('key'),
56+
})
57+
58+
if not created:
59+
self.stdout.write("Found existing peer for '{}', not updating".format(host))
60+
else:
61+
self.stdout.write("Created new peer '{}'".format(peer))

orb/peers/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ def default_writer(value):
9090

9191
total_count, resource_list = self.client.list_resources(**filters)
9292

93-
for api_resource in resource_list:
93+
for initial_api_resource in resource_list:
94+
api_resource = self.client.get_resource_by_id(initial_api_resource['id'])
9495
try:
9596
local_resource = Resource.resources.get(guid=api_resource['guid'])
9697
except Resource.DoesNotExist:

orb/profiles/models.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
21
# Create your models here.

requirements/base.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ dj_database_url==0.4.2
3535

3636
dicttoxml==1.7.4
3737

38-
git+https://github.com/mPowering/orb-api-python.git@v0.1.1#orb_api
38+
git+https://github.com/mPowering/orb-api-python.git@v1.1.0#orb_api
3939

4040
Markdown==2.6.9
4141
enum34==1.1.6
42+
typing==3.6.1

0 commit comments

Comments
 (0)