add copy on api, add skeleton for api tests + remove django 1.9 warnings (as much as possible)
--- a/.settings/org.eclipse.core.resources.prefs Mon Jul 20 19:12:18 2015 +0200
+++ b/.settings/org.eclipse.core.resources.prefs Wed Jul 22 15:01:51 2015 +0200
@@ -1,4 +1,5 @@
eclipse.preferences.version=1
+encoding//src/ldt/ldt/api/ldt/tests/tests_project.py=utf-8
encoding//src/ldt/ldt/indexation/backends/elasticsearch_backend.py=utf-8
encoding//src/ldt/ldt/indexation/highlighter.py=utf-8
encoding//src/ldt/ldt/indexation/models.py=utf-8
@@ -6,6 +7,7 @@
encoding//src/ldt/ldt/indexation/search_indexes.py=utf-8
encoding//src/ldt/ldt/indexation/signals.py=utf-8
encoding//src/ldt/ldt/indexation/tests.py=utf-8
+encoding//src/ldt/ldt/ldt_utils/apps.py=utf-8
encoding//src/ldt/ldt/ldt_utils/events.py=utf-8
encoding//src/ldt/ldt/ldt_utils/migrations/0001_initial.py=utf-8
encoding//src/ldt/ldt/ldt_utils/views/ldt_json.py=utf-8
@@ -13,6 +15,7 @@
encoding//src/ldt/ldt/management/commands/synciri.py=utf-8
encoding//src/ldt/ldt/management/commands/updateiriurlinprojects.py=utf-8
encoding//src/ldt/ldt/management/utils.py=utf-8
+encoding//src/ldt/ldt/security/apps.py=utf-8
encoding//src/ldt/ldt/test/test_runner.py=utf-8
encoding//src/ldt/ldt/text/migrations/0001_initial.py=utf-8
encoding//src/ldt/ldt/user/migrations/0001_initial.py=utf-8
--- a/src/ldt/ldt/api/ldt/resources/project.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/api/ldt/resources/project.py Wed Jul 22 15:01:51 2015 +0200
@@ -1,19 +1,3 @@
-import logging
-
-from django import VERSION as django_version
-from django.db import transaction
-from django.conf import settings
-from django.conf.urls import url
-from django.contrib.auth.models import Group
-from django.core.exceptions import ObjectDoesNotExist
-from guardian.shortcuts import assign_perm
-from tastypie import fields, http
-from tastypie.authorization import Authorization
-from tastypie.exceptions import BadRequest
-from tastypie.resources import Bundle, ModelResource, ALL
-from tastypie.utils import dict_strip_unicode_keys
-from distutils.util import strtobool
-
from ldt.api.ldt.authentication import (SessionAuthentication,
MultiAuthentication, ApiKeyAuthentication)
from ldt.api.ldt.resources import ContentResource
@@ -22,6 +6,19 @@
from ldt.ldt_utils.models import Project
from ldt.security import protect_models, unprotect_models
from ldt.security.permissionchecker import check_object_perm_for_user
+import logging
+
+from django import VERSION as django_version
+from django.conf import settings
+from django.conf.urls import url
+from django.core.exceptions import ObjectDoesNotExist
+from django.db import transaction
+from guardian.shortcuts import assign_perm
+from tastypie import fields, http
+from tastypie.authorization import Authorization
+from tastypie.exceptions import BadRequest
+from tastypie.resources import Bundle, ModelResource, ALL
+from tastypie.utils import dict_strip_unicode_keys
logger = logging.getLogger(__name__)
@@ -31,7 +28,7 @@
owner = fields.ForeignKey(UserResource, 'owner')
class Meta:
allowed_methods = ['get', 'post', 'put']
- authorization = Authorization() # BE CAREFUL WITH THAT, it's unsecure
+ authorization = Authorization() # BE CAREFUL WITH THAT, it's unsecure
authentication = MultiAuthentication(ApiKeyAuthentication(), SessionAuthentication())
resource_name = 'projects'
queryset = Project.objects.all()
@@ -43,19 +40,19 @@
}
# In the future version :
# detail_uri_name = 'ldt_id'
-
-
+
+
def get_object_list(self, request):
return Project.safe_objects.all()
-
+
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<ldt_id>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
-
+
def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_list'):
if bundle_or_obj is None:
- return super(ProjectResource, self).get_resource_uri(bundle_or_obj,url_name)
+ return super(ProjectResource, self).get_resource_uri(bundle_or_obj, url_name)
kwargs = {
'resource_name': self._meta.resource_name,
'api_name': self._meta.api_name
@@ -65,56 +62,64 @@
else:
kwargs['ldt_id'] = bundle_or_obj.ldt_id
return self._build_reverse_url("api_dispatch_detail", kwargs=kwargs)
-
+
# Create a new project. Used with post_detail and with no ldt_id in the url
# If there is a "source" argument in the data with a valid id, then it will create a copy of the source project
# Additionally if there is also a "publish" argument in the data, the copied project will immediately be published
+ # Note: namespace + prefix for iri cinelab extensions : @prefix iricle:http://ns.iri-research.org/cle/1.0#
@transaction.atomic
def obj_create(self, bundle, **kwargs):
request = bundle.request
-
+
if request is None:
raise BadRequest("Request object must be passed as an argument")
unprotect_models()
+ #logger.debug("Bundle : %r", bundle)
+ #logger.debug("Bundle data : %r", bundle.data)
# if source is not none then try copy
- if bundle.data["source"] is not None:
- try:
- source_proj = Project.objects.get(ldt_id=bundle.data['source'])
+ if "source" in request.GET and request.GET["source"]:
+ #make sure taht the content-type is application/cinelab
+ content_type = request.META.get('CONTENT_TYPE', None)
+ if not "application/cinelab" in content_type:
+ raise BadRequest("The contenttype MUST be application/cinelab")
+ try:
+ source_proj = Project.objects.get(ldt_id=request.GET['source'])
except ObjectDoesNotExist:
raise BadRequest("Source project could not be found")
- publish_bool = False
- if check_object_perm_for_user(source_proj, "change_project", request.user):
- bundle.data["title"] = bundle.data.get("title", source_proj.title)
- bundle.data["description"] = bundle.data.get("description", source_proj.description)
- publish_bool = bool(strtobool(bundle.data.get('publish', 'false').lower()))
- else:
- raise BadRequest("User has no right to change the project.")
- bundle.obj = source_proj.copy_project(user=request.user, title=bundle.data["title"], description=bundle.data["description"])
- if publish_bool:
- bundle.obj.publish()
- else:
+ if not check_object_perm_for_user(source_proj, "view_project", request.user):
+ raise BadRequest("User has no right to view the project.")
+ logger.debug('Data : %r' % bundle.data)
+ title = bundle.data.get('title' , "") or source_proj.title
+ description = bundle.data.get('description', "") or source_proj.description
+ bundle.obj = source_proj.copy_project(user=request.user, title=title, description=description)
+ if bundle.data.get('state', -1) >= 0:
+ bundle.obj.state = bundle.data.get('state', -1)
+ bundle.obj.save()
+ else:
bundle = super(ProjectResource, self).obj_create(bundle, **kwargs)
# Assign permission for the owner
assign_perm('view_project', request.user, bundle.obj)
assign_perm('change_project', request.user, bundle.obj)
# Since the project is published by default, we assign permission for the everyone group
- everyone = Group.objects.get(name=settings.PUBLIC_GROUP_NAME)
- assign_perm('ldt_utils.view_project', everyone, bundle.obj)
+
+ if bundle.data.get('state', -1) == Project.PUBLISHED:
+ bundle.obj.publish()
+
protect_models()
return bundle
-
-
+
+
# Prevent for put_list and delete all objects.
def obj_delete_list(self, bundle, **kwargs):
raise BadRequest("PUT with a list of projects is forbidden.")
-
-
+
+
def hydrate_image(self, bundle):
image_data = bundle.data.get('image', None)
if image_data and image_data.startswith(settings.MEDIA_URL):
bundle.data['image'] = image_data[len(settings.MEDIA_URL):]
return bundle
-
+
# Updates an existing project. Used with post_detail and with a ldt_id in the url
@transaction.atomic
def post_detail(self, request, **kwargs):
@@ -131,16 +136,16 @@
deserialized = self.deserialize(request, body, format=request.META.get('CONTENT_TYPE', 'application/json'))
deserialized = self.alter_deserialized_detail_data(request, deserialized)
bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized), request=request)
-
+
try:
# We have to check if the user can change the project BEFORE calling obj_update
proj = Project.objects.get(ldt_id=bundle.data['ldt_id'])
if check_object_perm_for_user(proj, "change_project", request.user):
- # Even if the user has the guardian right to change the project,
+ # Even if the user has the guardian right to change the project,
# tastypie's save_m2m will raise an error. So we unprotect just for this saving.
unprotect_models()
# Here we hack self.obj_update because it bugs : add request object to data and makes self.obj_get bug.
- #updated_bundle = self.obj_update(bundle, request=request, **self.remove_api_resource_names(kwargs))
+ # updated_bundle = self.obj_update(bundle, request=request, **self.remove_api_resource_names(kwargs))
try:
bundle.obj = self.obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs))
except ObjectDoesNotExist:
@@ -151,7 +156,7 @@
protect_models()
else:
raise BadRequest("User has no right to change the project.")
-
+
if not self._meta.always_return_data:
return http.HttpAccepted()
else:
@@ -161,5 +166,5 @@
except Exception as e:
return http.HttpBadRequest("Datas are not correct.\nError = " + str(e) + "\n")
return http.HttpResponse("Done")
-
-
\ No newline at end of file
+
+
--- a/src/ldt/ldt/api/ldt/resources/tag.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/api/ldt/resources/tag.py Wed Jul 22 15:01:51 2015 +0200
@@ -32,10 +32,10 @@
content_ids = request.GET.get('contents', '')
segment_ids = request.GET.get('segments', '')
# We define the number of steps in weight int
- try:
- weight_steps = int(request.GET.get('steps', 10))
- except:
- weight_steps = 10
+# try:
+# weight_steps = int(request.GET.get('steps', 10))
+# except:
+# weight_steps = 10
tags_cloud = None
if content_ids=="all" or segment_ids=="all":
#tags_cloud = Tag.objects.cloud_for_model(Segment, steps=weight_steps)
--- a/src/ldt/ldt/api/ldt/serializers/cinelabserializer.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/api/ldt/serializers/cinelabserializer.py Wed Jul 22 15:01:51 2015 +0200
@@ -1,13 +1,14 @@
-from django.conf import settings
+import json
from ldt.ldt_utils.models import Content, Project
from ldt.ldt_utils.projectserializer import ProjectJsonSerializer
from ldt.ldt_utils.utils import generate_uuid
from ldt.utils.url import reverse_prefix
+import math
+
+from django.conf import settings
+import lxml.etree
from tastypie.exceptions import NotFound, BadRequest
from tastypie.serializers import Serializer
-import json
-import lxml.etree
-import math
class CinelabSerializer(Serializer):
@@ -68,20 +69,17 @@
else:
ldt_id = generate_uuid()
# default state = (1, 'edition') OR (2, 'published')
- state = 2
+ state = meta.get('iricle:status', 2)
contents = [reverse_prefix("api_dispatch_detail", kwargs={"api_name":"1.0", "resource_name":"contents", "iri_id":c["id"]}) for c in cinelab["medias"]]
owner_uri = reverse_prefix("api_dispatch_detail", kwargs={"api_name":"1.0", "resource_name":"users", "username":meta["dc:creator"]})
- ldt = lxml.etree.tostring(self.cinelab_to_ldt(cinelab), pretty_print=True)
+ ldt = lxml.etree.tostring(self.cinelab_to_ldt(cinelab, ldt_id), pretty_print=True)
s = {"description": meta["dc:description"], "ldt_id": ldt_id, "title": meta["dc:title"],
"created_by": meta["dc:creator"], "changed_by": meta["dc:contributor"], "creation_date": meta["dc:created"], "modification_date": meta["dc:modified"],
"contents": contents, "owner": owner_uri, "state":state, "ldt":ldt}
- #s = '{"description": "", "ldt": "<iri><project/><medias/><annotations/><displays/><edits/></iri>", "000ldt_id": "gen_by_tc","title": "aaa GEN BY TC"}'
- #s = '{"description": "", "ldt": "<iri><project/><medias/><annotations/><displays/><edits/></iri>", "title": "aaaGEN BY TC"}'
- #return json.loads(json.dumps(s))
return s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/api/ldt/tests/__init__.py Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,1 @@
+from .tests_project import *
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/api/ldt/tests/tests_project.py Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Jul 21, 2015
+
+@author: ymh
+'''
+import logging
+
+from tastypie.test import ResourceTestCase, TestApiClient
+from ldt.api.ldt.serializers.cinelabserializer import CinelabSerializer
+from django.core.urlresolvers import reverse
+from ldt.ldt_utils.models import Project
+import json
+
+
+logger = logging.getLogger(__name__)
+
+class ProjectTest(ResourceTestCase):
+
+ fixtures = ['tests/api/projects_user.json', 'tests/api/projects_project.json']
+
+ def get_credentials(self):
+ result = self.api_client.client.login(username='admin',password='admin')
+ return result
+
+
+ def setUp(self):
+ self.api_client = TestApiClient(CinelabSerializer())
+ self.get_credentials()
+ self.copy_project_json = json.dumps({
+ "meta": {
+ "dc:creator": "admin",
+ "dc:contributor": "admin",
+ "dc:title": "New title TEST",
+ "dc:created":"2015-07-21T10:10:09Z",
+ "dc:modified":"2015-07-21T10:10:09Z",
+ "dc:description": "New description TEST",
+ "iricle:status": 3
+ },
+ "views": [],
+ "lists": [],
+ "annotation-types": [],
+ "medias": [],
+ "tags": [],
+ "annotations": []
+ })
+
+
+ def tearDown(self):
+ pass
+
+ def testCopy(self):
+ resp = self.api_client.client.post("%s?source=c0bc66fa-2eca-11e5-a518-58b035f6b93d" % reverse('api_dispatch_list',kwargs={'api_name':'1.0', 'resource_name':'projects'}), content_type='application/cinelab', data=self.copy_project_json)
+ self.assertHttpCreated(resp)
+ location = resp['Location']
+ self.assertIsNotNone(location, "Location should not be null")
+ ldt_id = location.split('/')[-2]
+ self.assertRegexpMatches(ldt_id, "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", "should match a guid")
+
+ self.assertEqual(3, Project.objects.count(), "should have 3 projects now" )
+
+ project = Project.objects.get(ldt_id=ldt_id)
+
+ self.assertEqual("New title TEST", project.title, "title must be New title TEST and is : %s" % project.title)
+ self.assertEqual("New description TEST", project.description, "description must be New description TEST and is : %s" % project.description)
+ self.assertEqual(3, project.state, "status must be 3 and is : %r " % project.state)
+
+ def testContentType(self):
+ resp = self.api_client.client.post("%s?source=c0bc66fa-2eca-11e5-a518-58b035f6b93d" % reverse('api_dispatch_list',kwargs={'api_name':'1.0', 'resource_name':'projects'}), content_type='application/json', data=self.copy_project_json)
+ self.assertHttpBadRequest(resp)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/fixtures/tests/api/projects_project.json Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,81 @@
+[
+{
+ "fields": {
+ "external_permalink": "",
+ "src_hash": "1c9ed788ed12fb16f869d7539b37e2b7d13c76f2d86137902f5091866b76f602bb89ed08d0c2ef890655ee3ebb44b95914fc06eefba1ab2fd76f04bc98b67175",
+ "videopath": "",
+ "update_date": "2015-07-20T10:33:23.985Z",
+ "external_publication_url": "",
+ "external_src_url": "",
+ "creator": null,
+ "creation_date": "2015-07-20T10:33:23.985Z",
+ "media_creation_date": null,
+ "mimetype_field": "",
+ "duration": null,
+ "title": "",
+ "src": "http://localhost/%7Eymh/remie/remieplt/short/1",
+ "external_id": "",
+ "description": ""
+ },
+ "model": "ldt_utils.media",
+ "pk": 1
+},
+{
+ "fields": {
+ "update_date": "2015-07-20T10:33:26.065Z",
+ "front_project": 1,
+ "description": "",
+ "title": "alma",
+ "content_creation_date": "2015-07-20T12:33:12Z",
+ "image": "thumbnails/contents/content_default_icon.png",
+ "media_obj": 1,
+ "creation_date": "2015-07-20T10:33:24.040Z",
+ "iri_id": "b3c22994-2eca-11e5-bd56-58b035f6b93d",
+ "authors": [],
+ "duration": 480000,
+ "iriurl": "b3c22994-2eca-11e5-bd56-58b035f6b93d/b3c22994-2eca-11e5-bd56-58b035f6b93d.iri"
+ },
+ "model": "ldt_utils.content",
+ "pk": 1
+},
+{
+ "fields": {
+ "ldt_id": "c0bc66fa-2eca-11e5-a518-58b035f6b93d",
+ "description": "",
+ "modification_date": "2015-07-20T10:33:25.885Z",
+ "title": "front project : alma",
+ "changed_by": "admin",
+ "created_by": "admin",
+ "creation_date": "2015-07-20T10:33:25.651Z",
+ "state": 2,
+ "ldt": "<iri>\n <project abstract=\"\" title=\"front project : alma\" user=\"admin\" id=\"c0bc66fa-2eca-11e5-a518-58b035f6b93d\"/>\n <medias>\n <media id=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\" src=\"ldt/b3c22994-2eca-11e5-bd56-58b035f6b93d/b3c22994-2eca-11e5-bd56-58b035f6b93d.iri\" video=\"\" pict=\"\" extra=\"\"/>\n </medias>\n <annotations>\n <content id=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\">\n <ensemble title=\"Personal cutting\" id=\"g_c0d84063-2eca-11e5-baca-58b035f6b93d\" author=\"undefined\" abstract=\"\" idProject=\"c0bc66fa-2eca-11e5-a518-58b035f6b93d\">\n <decoupage author=\"perso\" id=\"c_c0d845f8-2eca-11e5-9895-58b035f6b93d\">\n <title>chapitrage</title>\n <abstract/>\n <elements/>\n </decoupage>\n <decoupage author=\"perso\" id=\"c_c0d8495e-2eca-11e5-a3e0-58b035f6b93d\">\n <title>contributions</title>\n <abstract/>\n <elements/>\n </decoupage>\n </ensemble>\n </content>\n </annotations>\n <displays>\n <display id=\"0\" title=\"Init view\" idsel=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\" tc=\"0\" zoom=\"0\" scroll=\"0\" infoBAB=\"\">\n <content id=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\">\n <decoupage idens=\"g_c0d84063-2eca-11e5-baca-58b035f6b93d\" id=\"c_c0d845f8-2eca-11e5-9895-58b035f6b93d\" tagSelect=\"\"/>\n <decoupage idens=\"g_c0d84063-2eca-11e5-baca-58b035f6b93d\" id=\"c_c0d8495e-2eca-11e5-a3e0-58b035f6b93d\" tagSelect=\"\"/>\n </content>\n </display>\n </displays>\n <edits/>\n</iri>\n",
+ "owner": 1,
+ "image": "thumbnails/contents/content_default_icon.png",
+ "contents": [
+ 1
+ ]
+ },
+ "model": "ldt_utils.project",
+ "pk": 1
+},
+{
+ "fields": {
+ "ldt_id": "cc6fc526-2eca-11e5-afed-58b035f6b93d",
+ "description": "",
+ "modification_date": "2015-07-20T10:33:45.341Z",
+ "title": "test remie",
+ "changed_by": "admin",
+ "created_by": "admin",
+ "creation_date": "2015-07-20T10:33:45.282Z",
+ "state": 1,
+ "ldt": "<iri>\n <project abstract=\"\" title=\"test remie\" user=\"admin\" id=\"cc6fc526-2eca-11e5-afed-58b035f6b93d\"/>\n <medias>\n <media id=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\" src=\"ldt/b3c22994-2eca-11e5-bd56-58b035f6b93d/b3c22994-2eca-11e5-bd56-58b035f6b93d.iri\" video=\"\" pict=\"\" extra=\"\"/>\n </medias>\n <annotations/>\n <displays>\n <display id=\"0\" title=\"Init view\" idsel=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\" tc=\"0\" zoom=\"0\" scroll=\"0\" infoBAB=\"\">\n <content id=\"b3c22994-2eca-11e5-bd56-58b035f6b93d\"/>\n </display>\n </displays>\n <edits/>\n</iri>\n",
+ "owner": 1,
+ "image": "thumbnails/projects/project_default_icon.png",
+ "contents": [
+ 1
+ ]
+ },
+ "model": "ldt_utils.project",
+ "pk": 2
+}
+]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/fixtures/tests/api/projects_user.json Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,52 @@
+[
+{
+ "fields": {
+ "name": "everyone",
+ "permissions": []
+ },
+ "model": "auth.group",
+ "pk": 1
+},
+{
+ "fields": {
+ "username": "AnonymousUser",
+ "first_name": "",
+ "last_name": "",
+ "language": "en",
+ "image": "thumbnails/users/user_default_icon.png",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "last_login": null,
+ "groups": [],
+ "user_permissions": [],
+ "password": "",
+ "email": "",
+ "date_joined": "2015-05-28T17:06:05.936Z"
+ },
+ "model": "user.ldtuser",
+ "pk": -1
+},
+{
+ "fields": {
+ "username": "admin",
+ "first_name": "",
+ "last_name": "",
+ "language": "en",
+ "image": "thumbnails/users/user_default_icon.png",
+ "is_active": true,
+ "is_superuser": true,
+ "is_staff": true,
+ "last_login": "2015-07-20T10:34:41.234Z",
+ "groups": [
+ 1
+ ],
+ "user_permissions": [],
+ "password": "pbkdf2_sha256$20000$kz1N5zuKcBJC$JXcRbvgMw+jBRhnAbTbnUkA0kYlI+8xHJdJOWZpsHUU=",
+ "email": "a@m.in",
+ "date_joined": "2015-05-28T22:07:22.018Z"
+ },
+ "model": "user.ldtuser",
+ "pk": 1
+}
+]
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/__init__.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/ldt_utils/__init__.py Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,2 @@
+
+default_app_config = 'ldt.ldt_utils.apps.LdtUtilsConfig'
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/apps.py Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Jul 22, 2015
+
+@author: ymh
+'''
+
+from django.apps import AppConfig
+
+class LdtUtilsConfig(AppConfig):
+ name = 'ldt.ldt_utils'
+ verbose_name = 'Ldt ldt utils'
+
+ def ready(self):
+ from ldt.ldt_utils.events import post_project_save
+ from ldt.ldt_utils.contentindexer import index_project
+ post_project_save.connect(index_project)
--- a/src/ldt/ldt/ldt_utils/contentindexer.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/ldt_utils/contentindexer.py Wed Jul 22 15:01:51 2015 +0200
@@ -1,18 +1,18 @@
from StringIO import StringIO
-from django.contrib.contenttypes.models import ContentType
-from django.dispatch import receiver
from ldt import settings
from ldt.indexation import object_delete, object_insert, object_run_index
-from ldt.ldt_utils.events import post_project_save
from ldt.ldt_utils.models import Segment, Content, Project
from ldt.ldt_utils.stat import update_stat_project, add_annotation_to_stat
from ldt.ldt_utils.utils import reduce_text_node
from ldt.utils.url import request_with_auth
-from taggit.models import Tag, TaggedItem
+import logging
+
+from django.apps import apps
+from django.contrib.contenttypes.models import ContentType
+import lxml.etree # @UnresolvedImport
from taggit.utils import parse_tags
-import lxml.etree #@UnresolvedImport
-import logging
+
logger = logging.getLogger(__name__)
def Property(func):
@@ -69,6 +69,8 @@
def index_ensemble(self, ensemble, content, project=None):
ensembleId = ensemble.get(u"id", None)
ctp = ContentType.objects.get_for_model(Segment)
+ TaggedItem = apps.get_model('taggit', 'TaggedItem')
+ Tag = apps.get_model('taggit', 'Tag')
for decoupageNode in ensemble.getchildren():
if decoupageNode.tag != "decoupage" or decoupageNode.get(u"id", None) in self.decoupage_blacklist:
@@ -163,6 +165,7 @@
# Prepare taggeditems
ti = []
+
for s in self.__segment_cache:
s.tag_list = self.__segment_tags_cache[s.id_hash]
for t in self.__segment_tags_cache[s.id_hash]:
@@ -243,7 +246,6 @@
for ensemble in content.getchildren():
self.index_ensemble(ensemble, content_obj, project)
-@receiver(post_project_save)
def index_project(**kwargs):
must_reindex = kwargs.get("must_reindex", True)
if must_reindex and settings.AUTO_INDEX_AFTER_SAVE:
--- a/src/ldt/ldt/ldt_utils/tests/tests_content.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/ldt_utils/tests/tests_content.py Wed Jul 22 15:01:51 2015 +0200
@@ -5,17 +5,14 @@
Replace these with more appropriate tests for your application.
"""
+from ldt.ldt_utils.models import Content, Media
+from ldt.test.client import Client
+from ldt.test.testcases import TestCase
import logging
import os
from django.conf import settings
from django.contrib.auth import get_user_model
-from django.contrib.auth.models import User
-from django.utils._os import WindowsError
-
-from ldt.ldt_utils.models import Content, Media
-from ldt.test.client import Client
-from ldt.test.testcases import TestCase
logger = logging.getLogger(__name__)
--- a/src/ldt/ldt/ldt_utils/views/content.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/ldt_utils/views/content.py Wed Jul 22 15:01:51 2015 +0200
@@ -5,7 +5,7 @@
from django.core.urlresolvers import reverse
from django.db import transaction
from django.forms.models import model_to_dict
-from django.forms.util import ErrorList
+from django.forms.utils import ErrorList
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
--- a/src/ldt/ldt/security/__init__.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/security/__init__.py Wed Jul 22 15:01:51 2015 +0200
@@ -1,8 +1,9 @@
+from ldt.security.permissionchecker import check_object_perm_for_user
+
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.signals import request_started
-from ldt.security.permissionchecker import check_object_perm_for_user
try:
@@ -10,6 +11,8 @@
except ImportError:
from django.utils._threading_local import local
+default_app_config = 'ldt.security.apps.LdtSecurityConfig'
+
_thread_locals = local()
# The function that protect models is called on the first
@@ -109,5 +112,3 @@
if not _models_are_protected:
protect_models()
-request_started.connect(protect_models_request)
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/security/apps.py Wed Jul 22 15:01:51 2015 +0200
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+'''
+Created on Jul 21, 2015
+
+@author: ymh
+'''
+
+from django.apps import AppConfig
+from django.core.signals import request_started
+
+
+class LdtSecurityConfig(AppConfig):
+ name = 'ldt.security'
+ verbose_name = 'Ldt security'
+
+ def ready(self):
+ from ldt.security import protect_models_request
+ request_started.connect(protect_models_request)
\ No newline at end of file
--- a/src/ldt/ldt/security/permissionchecker.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/security/permissionchecker.py Wed Jul 22 15:01:51 2015 +0200
@@ -1,6 +1,6 @@
+from django.apps import apps
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
-from guardian.models import UserObjectPermission, GroupObjectPermission
def check_object_perm_for_user(obj, perm_name, user):
@@ -16,6 +16,7 @@
can_change = False
# Check for the user
try:
+ UserObjectPermission = apps.get_model('guardian.UserObjectPermission')
uop = UserObjectPermission.objects.get(user=user, content_type=content_type, permission=perm, object_pk=obj.pk)
if uop:
can_change = True
@@ -24,6 +25,7 @@
# Check for user's groups if necessary
if not can_change:
try:
+ GroupObjectPermission = apps.get_model('guardian.GroupObjectPermission')
gop = GroupObjectPermission.objects.filter(group__user=user, content_type=content_type, permission=perm, object_pk=obj.pk)
if gop and len(gop)>0:
can_change = True
--- a/src/ldt/ldt/templatetags/taggit_extras_ldt.py Mon Jul 20 19:12:18 2015 +0200
+++ b/src/ldt/ldt/templatetags/taggit_extras_ldt.py Wed Jul 22 15:01:51 2015 +0200
@@ -2,30 +2,28 @@
from taggit-templatetags. This app is very useful but does not
"""
+import logging
+
from django import template
-from django.db import models
+from django.contrib.contenttypes.models import ContentType
from django.db.models import Count
-from django.core.exceptions import FieldError
-
+from django.utils.safestring import SafeText
+from taggit_templatetags import settings
+from templatetag_sugar.parser import Name, Variable, Constant, Optional
from templatetag_sugar.register import tag
-from templatetag_sugar.parser import Name, Variable, Constant, Optional, Model
+from django.apps import apps
-from taggit import VERSION as TAGGIT_VERSION
-from taggit.managers import TaggableManager
-from taggit.models import TaggedItem, Tag
-from taggit_templatetags import settings
-from django.utils.safestring import SafeText
-from django.contrib.contenttypes.models import ContentType
T_MAX = getattr(settings, 'TAGCLOUD_MAX', 6.0)
T_MIN = getattr(settings, 'TAGCLOUD_MIN', 1.0)
register = template.Library()
-import logging
logger = logging.getLogger(__name__)
def get_queryset(forvar=None):
+ TaggedItem = apps.get_model('taggit', 'TaggedItem')
+ Tag = apps.get_model('taggit', 'Tag')
if None == forvar:
# get all tags
queryset = Tag.objects.all()