Skip to content

Commit eca6375

Browse files
committed
Merge branch 'release/v1.10.0'
2 parents 1e2ee1f + b1bf7db commit eca6375

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1722
-490
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ test:
107107
mv lib/neo4j/data/graph.db lib/neo4j/data/graph.db.backup || true
108108
# Start a brand new database
109109
make startdb
110-
./manage.py syncdb -v 0 --noinput --traceback --pythonpath=. --settings=app.settings_tests
110+
-python manage.py syncdb -v 0 --noinput --traceback --pythonpath=. --settings=app.settings_tests
111111
# Launch test with coverage
112112
-python -W ignore::DeprecationWarning manage.py test $(TEST) --pythonpath=. --settings=app.settings_tests --traceback
113113
# Stop database in order to restore it

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[License](https://github.com/jplusplus/detective.io/blob/master/LICENSE)
66
[Test coverage](https://coveralls.io/r/jplusplus/detective.io)
77
[Documentation](http://docs.detective.io/en/latest/)
8-
*Version 1.9.0 Baboon*
8+
*Version 1.10.0 Caribou*
99

1010
## Installation
1111

app/detective/admin.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from app.detective.models import QuoteRequest
33
from app.detective.models import Topic
44
from app.detective.models import TopicSkeleton
5+
from app.detective.models import TopicDataSet
56
from app.detective.models import TopicToken
67
from app.detective.models import SearchTerm
78
from app.detective.models import Article
@@ -76,7 +77,7 @@ def formfield_for_choice_field(self, db_field, request, **kwargs):
7677
model_name = getattr(model._meta, "verbose_name").title()
7778
subset = []
7879
# Retreive every relationship field for this model
79-
for field in utils.get_model_fields(model):
80+
for field in utils.iterate_model_fields(model):
8081
if field["type"] != 'AutoField':
8182
choice = [ field["name"], field["verbose_name"].title(), ]
8283
# Add ... at the end ot the relationship field
@@ -180,6 +181,27 @@ class TopicSkeletonAdmin(admin.ModelAdmin):
180181

181182
admin.site.register(TopicSkeleton, TopicSkeletonAdmin)
182183

184+
class TopicDataSetForm(forms.ModelForm):
185+
target_plans = forms.MultipleChoiceField(choices=PLANS_CHOICES)
186+
187+
def __init__(self, *args, **kwargs):
188+
super(TopicDataSetForm, self).__init__(*args, **kwargs)
189+
instance = kwargs.get('instance', None)
190+
if instance:
191+
self.initial['target_plans'] = instance.selected_plans()
192+
193+
class TopicDataSetAdmin(admin.ModelAdmin):
194+
form = TopicDataSetForm
195+
list_display = ("title", "description_stripped", "_plans", "_skeletons")
196+
197+
def _skeletons(self, instance):
198+
return ', '.join(instance.selected_skeletons())
199+
200+
def _plans(self, instance):
201+
return ', '.join(instance.selected_plans())
202+
203+
admin.site.register(TopicDataSet, TopicDataSetAdmin)
204+
183205
class ArticleAdmin(admin.ModelAdmin):
184206
save_on_top = True
185207
prepopulated_fields = {'slug': ('title',)}

app/detective/individual.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
# -*- coding: utf-8 -*-
33
from app.detective import register, graph
44
from app.detective.neomatch import Neomatch
5-
from app.detective.utils import import_class, to_underscores, get_model_topic, get_leafs_and_edges, get_topic_from_request, get_model_fields
6-
from app.detective.utils import get_model_fields as utils_get_model_fields
5+
from app.detective.utils import import_class, to_underscores, get_model_topic, get_leafs_and_edges, get_topic_from_request, iterate_model_fields, topic_cache
76
from app.detective.topics.common.models import FieldSource
7+
from app.detective.topics.common.user import UserResource
88
from app.detective.models import Topic
99
from django.conf.urls import url
10+
from django.contrib.auth.models import User
1011
from django.core.exceptions import ObjectDoesNotExist, ValidationError
1112
from django.core.paginator import Paginator, InvalidPage
1213
from django.core.urlresolvers import reverse
@@ -83,9 +84,6 @@ def delete_detail(self, object_list, bundle):
8384

8485
def delete_list(self, object_list, bundle):
8586
return False
86-
# if not self.check_contribution_permission(object_list, bundle, 'delete'):
87-
# raise Unauthorized("Sorry, only staff or contributors can delete resource.")
88-
# return True
8987

9088
class IndividualMeta:
9189
list_allowed_methods = ['get', 'post', 'put']
@@ -134,6 +132,7 @@ def prepend_urls(self):
134132
url(r"^(?P<resource_name>%s)/search%s$" % params, self.wrap_view('get_search'), name="api_get_search"),
135133
url(r"^(?P<resource_name>%s)/mine%s$" % params, self.wrap_view('get_mine'), name="api_get_mine"),
136134
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/patch%s$" % params, self.wrap_view('get_patch'), name="api_get_patch"),
135+
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/authors%s$" % params, self.wrap_view('get_authors'), name="api_get_authors"),
137136
url(r"^(?P<resource_name>%s)/bulk_upload%s$" % params, self.wrap_view('bulk_upload'), name="api_bulk_upload"),
138137
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/graph%s$" % params, self.wrap_view('get_graph'), name="api_get_graph"),
139138
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/relationships%s$" % params, self.wrap_view('get_relationships'), name="api_get_relationships"),
@@ -300,6 +299,8 @@ def obj_create(self, bundle, **kwargs):
300299
# Create an object to build the bundle
301300
obj = node.properties
302301
obj["id"] = node.id
302+
# update the cache
303+
topic_cache.incr_version(request.current_topic)
303304
# Return a new bundle
304305
return self.build_bundle(obj=model._neo4j_instance(node), data=obj, request=request)
305306

@@ -334,13 +335,12 @@ def alter_detail_data_to_serialize(self, request, bundle, nested=False):
334335
# If the nested parameter is True, this set
335336
node_to_retreive = set()
336337
# Resolve relationships manualy
337-
model_fields = get_model_fields(model)
338338
for field in fields:
339339
# Get relationships for this fields
340340
field_rels = [ rel for rel in node_rels[:] if rel.type == field._type]
341341
# Filter relationships to keep only the well oriented relationships
342342
# get the related field informations
343-
related_field = [f for f in model_fields if "rel_type" in f and f["rel_type"] == field._type and "name" in f and f["name"] == field._BoundRelationship__attname]
343+
related_field = [f for f in iterate_model_fields(model) if "rel_type" in f and f["rel_type"] == field._type and "name" in f and f["name"] == field._BoundRelationship__attname]
344344
if related_field:
345345
# Note (edouard): check some assertions in case I forgot something
346346
assert len(related_field) == 1, related_field
@@ -584,10 +584,6 @@ def get_patch(self, request, **kwargs):
584584
bundle = self.build_bundle(request=request)
585585
# User allowed to update this model
586586
self.authorized_update_detail(self.get_object_list(bundle.request), bundle)
587-
# Current model
588-
model = self.get_model()
589-
# Fields
590-
fields = { x['name'] : x for x in utils_get_model_fields(model) }
591587
# Get the node's data using the rest API
592588
try: node = connection.nodes.get(pk)
593589
# Node not found
@@ -678,6 +674,10 @@ def get_patch(self, request, **kwargs):
678674
# We simply update the node property
679675
# (the value is already validated)
680676
else:
677+
# Current model
678+
model = self.get_model()
679+
# Fields
680+
fields = { x['name'] : x for x in iterate_model_fields(model) }
681681
if field_name in fields:
682682
if 'is_rich' in fields[field_name]['rules'] and fields[field_name]['rules']['is_rich']:
683683
data[field_name] = field_value = bleach.clean(field_value,
@@ -688,10 +688,37 @@ def get_patch(self, request, **kwargs):
688688
'a': ("href", "target")
689689
})
690690
node.set(field_name, field_value)
691-
691+
# update the cache
692+
topic_cache.incr_version(request.current_topic)
692693
# And returns cleaned data
693694
return self.create_response(request, data)
694695

696+
697+
def get_authors(self, request, **kwargs):
698+
pk = kwargs["pk"]
699+
# This should be a POST request
700+
self.method_check(request, allowed=['get'])
701+
self.throttle_check(request)
702+
# User must be authentication
703+
self.is_authenticated(request)
704+
bundle = self.build_bundle(request=request)
705+
# User allowed to update this model
706+
self.authorized_read_detail(self.get_object_list(bundle.request), bundle)
707+
# Get the node's data using the rest API
708+
try: node = connection.nodes.get(pk)
709+
# Node not found
710+
except client.NotFoundError: raise Http404("Not found.")
711+
# Get the authors ids
712+
authors_ids = node.properties.get("_author", [])
713+
# Find them in the database
714+
authors = User.objects.filter(id__in=authors_ids).select_related("profile")
715+
resource = UserResource()
716+
# Create a bundle with each resources
717+
bundles = [resource.build_bundle(obj=a, request=request) for a in authors]
718+
data = [resource.full_dehydrate(bundle) for bundle in bundles]
719+
# We ask for relationship properties
720+
return resource.create_response(request, data)
721+
695722
def get_relationships(self, request, **kwargs):
696723
# Extract node id from given node uri
697724
def node_id(uri) : return re.search(r'(\d+)$', uri).group(1)

app/detective/management/commands/orphans.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ def handle(self, *args, **options):
3838
try:
3939
for Model in topic.get_models():
4040
try:
41-
fields = utils.get_model_fields(Model)
42-
for field in fields:
41+
for field in utils.iterate_model_fields(Model):
4342
if field["rel_type"] and field["direction"] == "out" and "through" in field["rules"]:
4443
ids= []
4544
for entity in Model.objects.all():

0 commit comments

Comments
 (0)