Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updates

  • Loading branch information...
commit 873580e6e3866cc6290136316d7b7906b506d5c3 1 parent 9363e29
@igniteflow igniteflow authored
View
8 openkm/admin.py
@@ -0,0 +1,8 @@
+from django.contrib import admin
+
+import openkm
+
+
+class OpenKMEventAdmin(admin.ModelAdmin):
+ pass
+admin.site.register(openkm.models.OpenKMEvent, OpenKMEventAdmin)
View
61 openkm/client.py
@@ -1,4 +1,6 @@
-import sys, logging
+import sys
+import logging
+import datetime
from functools import wraps
from django.conf import settings
@@ -8,6 +10,7 @@
import exceptions
+from openkm.services import OpenKMAuditService
logging.getLogger('suds.client').setLevel(logging.INFO)
PATH = settings.OPENKM['configuration']['Path']
@@ -40,9 +43,6 @@ def wrapped(*args, **kwargs):
raise exception, exception(e), tb
return wraps(fn)(wrapped)
-def get_service(class_name):
- return Client(OPENKM_WSDLS[class_name]).service
-
def get_client(class_name):
return Client(OPENKM_WSDLS[class_name])
@@ -54,13 +54,13 @@ def get_token():
class BaseService(object):
- def __init__(self, start_session=True, class_name=None):
+ def __init__(self, start_session=True, class_name=None, log_events=True):
if not class_name:
class_name = self.__class__.__name__
- self.service = get_service(class_name)
self.client = get_client(class_name)
- if start_session:
- self.token = get_token()
+ self.service = self.client.service
+ self.token = get_token() if start_session else None
+ self.log_events = log_events if log_events else None
class Auth(BaseService):
@@ -155,7 +155,6 @@ def rename(self, doc_path, new_name):
"""
return self.service.rename(token=self.token, docPath=doc_path, newName=new_name)
-
def move(self, doc_path, new_name):
"""
Move a document to another location in the repository.
@@ -165,7 +164,6 @@ def move(self, doc_path, new_name):
"""
return self.service.move(token=self.token, docPath=doc_path, newName=new_name)
-
def get_properties(self, doc_path):
"""
Obtain document properties from the repository.
@@ -184,21 +182,33 @@ def set_properties(self, doc):
return self.service.setProperties(token=self.token, doc=doc)
- def set_content(self, doc_path, content):
+ def set_content(self, doc_path, content, comment=None):
"""
Set document content in the repository.
:param doc_path string
:param content byte array (Java)
+ :param comment string
:return none
+
"""
- return self.service.setContent(token=self.token, docPath=doc_path, content=content)
+ if not comment:
+ comment = "No comment"
+ return self.service.setContent(token=self.token, docPath=doc_path, content=content, comment=comment)
- def get_content(self, doc_path, checkout):
+ def get_content(self, doc_path, checkout=False):
+ """Obtain document content from the repository.
+ :param doc_path string
+ :param checkout boolean
+ """
+ return self.service.getContent(token=self.token, docPath=doc_path, checkout=checkout)
+
+ def get_content_by_uuid(self, uuid, checkout=False):
"""Obtain document content from the repository.
:param doc_path string
:param checkout boolean
"""
+ doc_path = self.get_path(uuid)
return self.service.getContent(token=self.token, docPath=doc_path, checkout=checkout)
@@ -228,14 +238,19 @@ def cancel_checkout(self, doc_path):
"""
return self.service.cancelCheckout(token=self.token, docPath=doc_path)
+ def force_cancel_checkout(self, doc_path):
+ return self.service.forceCancelCheckout(token=self.token, docPath=doc_path)
- def checkin(self, doc_path):
+ def force_unlock(self, doc_path):
+ return self.service.forceUnlock(token=self.token, docPath=doc_path)
+
+ def checkin(self, doc_path, comment='Document update'):
"""
Check in the document to create a new version.
:param doc_path string
:return A version object with the properties of the new generated version.
"""
- return self.service.checkin(token=self.token, docPath=doc_path)
+ return self.service.checkin(token=self.token, docPath=doc_path, comment=comment)
def get_version_history(self, doc_path):
@@ -307,9 +322,10 @@ def create_document(self, content, data):
"""
if not hasattr(self.service, 'createDocument'):
raise AttributeError('createDocument is not available on your instance of OpenKM')
+ if self.log_events:
+ OpenKMAuditService().record_update(self.token, content, occured=datetime.datetime.now())
return self.service.createDocument(token=self.token, content=content, data=data)
-
def update_document(self, data):
"""
Custom web service to update a document and all associated metadata in a single call
@@ -318,8 +334,21 @@ def update_document(self, data):
"""
if not hasattr(self.service, 'updateDocument'):
raise AttributeError('updateDocument is not available on your instance of OpenKM')
+ if self.log_events:
+ OpenKMAuditService().record_create(self.token, data, occured=datetime.datetime.now())
return self.service.updateDocument(token=self.token, data=data)
+ def preview_document(self, uuid, format, version=None):
+ """
+ Custom web service to get PDF preview of document given a uuid, format and version
+ """
+ if not hasattr(self.service, 'previewDocument'):
+ raise AttributeError('previewDocument is not available on your instance of OpenKM')
+ return self.service.previewDocument(token=self.token, uuid=uuid, format=format, version=version)
+
+ def get_categories(self):
+ return self.service.getCategories(token=self.token)
+
class Search(BaseService):
"""Methods related to repository search. """
View
22 openkm/facades.py
@@ -325,15 +325,15 @@ def get_language_label(self, language_code):
return 'English'
def update_options_list(self, options, new_value):
- for option in options:
- print option.label, '==', new_value
- if (option.label == new_value) or (option.value == new_value):
- option.selected = True
- print('Updating option[%s].selected to True', option.label)
- else:
- option.selected = False
+ for option in options:
+ print option.label, '==', new_value
+ if (option.label == new_value) or (option.value == new_value):
+ option.selected = True
+ print('Updating option[%s].selected to True', option.label)
+ else:
+ option.selected = False
- return options
+ return options
def update_document_on_openkm(self, node_path, group_name, properties):
self.property_group.remove_group(node_path, group_name)
@@ -408,10 +408,10 @@ def generate_path_dependencies(self, folders):
def build_path(self, dependencies, root_path=settings.OPENKM['configuration']['UploadRoot']):
"""
- Check if root folder exists, then dependencies in order. If they don't exist then they are
- created.
+ Check if root folder exists, then dependencies in order. If they don't exist then they are
+ created.
:param dependencies: (list of strings) eg. ['sports', 'football']
- :param root_path: (string - optional) eg. '/okm:root/'
+ :param root_path: (string - optional) eg. '/okm:root/'
"""
folder = client.Folder()
repository = client.Repository()
View
72 openkm/models.py
@@ -1,12 +1,15 @@
import datetime
import operator
import logging
+import pickle
from django.db import models
from django.conf import settings
from django.db.models import Q
+from django.template.defaultfilters import filesizeformat
+from django.forms import forms
-import facades
+import openkm
class OpenKmMetadata(models.Model):
@@ -19,6 +22,7 @@ class OpenKmMetadata(models.Model):
okm_permissions = models.CharField(max_length=255, blank=True, null=True)
okm_subscribed = models.CharField(max_length=255, blank=True, null=True)
okm_uuid = models.CharField(max_length=255, blank=True, null=True)
+ okm_latest_version = models.CharField(max_length=255, default='None')
class Meta:
abstract = True
@@ -38,9 +42,11 @@ def custom_path_query(self, and_predicates, or_predicates):
return []
return [resource.okm_uuid for resource in query_set]
except TypeError, e:
- logging.exception(e)
+ logging.debug(e)
except AttributeError, e:
- logging.exception(e)
+ logging.debug(e)
+ except Exception, e:
+ logging.debug(e)
def get_custom_queryset(self, and_predicates, or_predicates):
@@ -49,6 +55,7 @@ def get_custom_queryset(self, and_predicates, or_predicates):
:param or_predicates: list of OR query arguments eg. ['Latin-America', 'EMEA']
:returns queryset
"""
+
if and_predicates:
and_predicates_list = self._build_and_predicate_list(and_predicates)
and_list = [Q(x) for x in and_predicates_list]
@@ -73,9 +80,11 @@ def get_custom_queryset(self, and_predicates, or_predicates):
return query_set
except TypeError, e:
- logging.exception(e)
+ logging.debug(e)
except AttributeError, e:
- logging.exception(e)
+ logging.debug(e)
+ except Exception, e:
+ logging.debug(e)
def _build_and_predicate_list(self, arguments):
args = []
@@ -87,7 +96,7 @@ def _build_and_predicate_list(self, arguments):
return args
def _build_or_predicate_list(self, arguments):
- return [('okm_path__icontains', '/%s' % argument) for argument in arguments]
+ return [('okm_path__icontains', '%s' % argument) for argument in arguments]
class OpenKmFolderList(OpenKmMetadata):
@@ -104,14 +113,33 @@ class Meta:
verbose_name_plural = verbose_name
+class OpenKmFileField(models.FileField):
+ def __init__(self, *args, **kwargs):
+ self.max_upload_size = kwargs.pop("max_upload_size")
+
+ super(OpenKmFileField, self).__init__(*args, **kwargs)
+
+ def clean(self, *args, **kwargs):
+ data = super(OpenKmFileField, self).clean(*args, **kwargs)
+
+ file = data.file
+ try:
+ if file._size > self.max_upload_size:
+ raise forms.ValidationError('Please keep filesize under %s. Current filesize %s' % (filesizeformat(self.max_upload_size), filesizeformat(file._size)))
+ except AttributeError:
+ pass
+
+ return data
+
+
class OpenKmDocument(OpenKmMetadata):
okm_filename = models.CharField(max_length=255, blank=True, null=True)
- file = models.FileField(max_length=255, upload_to='resources/%Y/%m/%d/', blank=True, null=True, help_text="Upload a file from your local machine")
+ # file = OpenKmFileField(max_length=255, max_upload_size=104857600, upload_to='resources/%Y/%m/%d/', blank=True, null=True, help_text="Upload a file from your local machine")
def upload_to_openkm(self, file_obj, taxonomy=[]):
"""Uploads the document to the OpenKM server """
- document_manager = facades.DocumentManager()
+ document_manager = openkm.facades.DocumentManager()
return document_manager.create(file_obj, taxonomy=taxonomy)
def set_model_fields(self, openkm_document):
@@ -120,15 +148,17 @@ def set_model_fields(self, openkm_document):
by OpenKM to identify the resource
"""
self.okm_author = openkm_document.author if openkm_document.author else ''
- self.okm_created = openkm_document.created
+ # self.okm_created = openkm_document.created
+ self.okm_created = datetime.datetime.now()
self.okm_path = openkm_document.path
self.okm_permissions = openkm_document.permissions
self.okm_subscribed = openkm_document.subscribed
self.okm_uuid = openkm_document.uuid
+ self.okm_latest_version = openkm_document.actualVersion.name
if hasattr(self, 'mime_type'):
self.mime_type = openkm_document.mimeType
- file_system = facades.FileSystem()
+ file_system = openkm.facades.FileSystem()
self.okm_filename = file_system.get_file_name_from_path(openkm_document.path)
def __unicode__(self):
@@ -147,11 +177,21 @@ def okm_date_string(self, date):
"""
if not isinstance(date, datetime.date):
raise Exception('Argument must be a datetime.date object')
- return date.strftime('%Y-%m-%dT00:00:00.356+01:00')
-
-
-
-
-
+ # return date.strftime('%Y-%m-%dT00:00:00.356+01:00')
+ return date.strftime('%Y%m%d%H%M%S')
+
+
+class OpenKMEvent(models.Model):
+ occured = models.DateTimeField()
+ recorded = models.DateTimeField(auto_now_add=True, null=True, blank=True)
+ token = models.CharField(max_length=255, blank=True, null=True)
+ content = models.TextField(blank=True, null=True)
+ extra = models.TextField(blank=True, null=True)
+
+ def save(self, *args, **kwargs):
+ # import ipdb; ipdb.set_trace()
+ if self.content:
+ self.content = pickle.dumps(self.content)
+ super(OpenKMEvent, self).save(*args, **kwargs)
View
30 openkm/services.py
@@ -0,0 +1,30 @@
+from openkm import models
+
+
+class OpenKMAuditService(object):
+
+ def record_update(self, token, content, occured):
+ """
+ token (string)
+ content (instance of document) as returned by
+ openkm.client.Document.create_document_content_object
+ occured (datetime.datetime)
+ """
+ return models.OpenKMEvent.objects.create(
+ token=token,
+ content=content,
+ occured=occured
+ )
+
+ def record_create(self, token, content, occured):
+ """
+ token (string)
+ content (instance of document) as returned by
+ openkm.client.Document.create_document_content_object
+ occured (datetime.datetime)
+ """
+ return models.OpenKMEvent.objects.create(
+ token=token,
+ content=content,
+ occured=occured
+ )
View
146 openkm/sync.py
@@ -1,6 +1,8 @@
import logging
+import re
logger = logging.getLogger( __name__ )
+
from django.conf import settings
from django.db import transaction
@@ -138,10 +140,12 @@ def get_objects_from_m2m_model(self, document, related_model_class):
Accepts a Document and a single class object of a many-to-many field
:returns queryset the related model objects associated with the given document
"""
- method_name = '%s' % related_model_class.__name__.lower()
- _set = getattr(document, method_name)
-
- return _set.all()
+ try:
+ method_name = '%s' % related_model_class.__name__.lower()
+ _set = getattr(document, method_name)
+ return _set.all()
+ except Exception, e:
+ logger.debug(e)
def get_related_objects_from_model(self, document, related_model_name):
"""
@@ -174,18 +178,22 @@ def prepare_properties_dict(self, map, document):
:param document: Django model object instance
:returns dict
"""
- map['okg:customProperties']['okp:customProperties.title'] = [document.name]
- map['okg:customProperties']['okp:customProperties.description'] = [document.description]
- map['okg:customProperties']['okp:customProperties.languages'] = [self.get_language(document)]
- map['okg:customProperties']['okp:customProperties.contentOwner'] = [self.get_content_owner(document)]
+ map['okg:customProperties']['okp:customProperties.title'] = [xml_clean(document.name)]
+ map['okg:customProperties']['okp:customProperties.description'] = [xml_clean(document.description)]
+ map['okg:customProperties']['okp:customProperties.languages'] = [xml_clean(self.get_language(document))]
+ map['okg:customProperties']['okp:customProperties.contentOwner'] = [xml_clean(self.get_content_owner(document))]
map['okg:customProperties']['okp:customProperties.expirationDate'] = [document.okm_date_string(document.expire)]
map['okg:customProperties']['okp:customProperties.public'] = [self.is_public(document)]
- map['okg:salesProperties']['okp:salesProperties.assetType'] = [self.get_asset_type(document)]
+ map['okg:salesProperties']['okp:salesProperties.assetType'] = [xml_clean(self.get_asset_type(document))]
+ # These will only exist if the user has the correct permissions to add them to the document in the first place
+ map['okg:gsaProperties']['okp:gsaProperties.publisherNotes'] = [document.notes]
+ map['okg:gsaProperties']['okp:gsaProperties.publishNow'] = [document.publish_now]
map['okg:gsaProperties']['okp:gsaProperties.gsaPublishedStatus'] = [self.get_published_status(document)]
map['okg:gsaProperties']['okp:gsaProperties.startDate'] = [document.okm_date_string(document.publish)]
map['okg:gsaProperties']['okp:gsaProperties.expirationDate'] = [document.okm_date_string(document.expire)]
+
return map
def is_public(self, document):
@@ -199,9 +207,17 @@ def get_language(self, document):
def get_asset_type(self, document):
if document.type:
- parts = document.type.name.split()
- parts[0] = parts[0].lower()
- return ''.join(parts)
+ parts = document.type.name.lower().replace('&', '').split()
+ stripped_parts = [part.strip() for part in parts]
+ i = 1
+
+ for i, word in enumerate(stripped_parts):
+ if i > 0:
+ stripped_parts[i] = word.capitalize()
+
+ asset_type = ''.join(stripped_parts)
+ logger.debug('Asset type: %s' % asset_type)
+ return asset_type
else:
return ''
@@ -239,6 +255,7 @@ def populate_property_group(self, properties_dict):
return property_groups
def django_to_openkm_improved(self, document):
+ #import ipdb; ipdb.set_trace()
map = settings.OPENKM['properties']
properties_dict = self.prepare_properties_dict(map, document)
return self.populate_property_group(properties_dict)
@@ -341,17 +358,28 @@ def __init__(self):
self.dir = facades.DirectoryListing()
self.repository = client.Repository()
- def execute(self, klass):
+ def update_categories(self, klass):
"""
:param klass: OpenKMFolderlist class object
"""
klass.objects.all().delete()
- xpath_query = '/jcr:root/okm:categories//element(*)'
- search = facades.SearchManager()
- type = 'xpath'
- folders = search.by_statement(xpath_query, type)
- print('%s folders returned for query: %s' % (len(folders.item), xpath_query))
- self.save(folders, klass)
+ document = client.Document()
+ categories = document.get_categories()
+
+ for folder in categories:
+ try:
+ folder_obj = klass.objects.create(okm_uuid=folder.uuid)
+ folder_obj.okm_author = folder.author
+ #folder_obj.okm_created = folder.created
+ folder_obj.okm_has_childs = folder.hasChildren
+ folder_obj.okm_path = utils.strip_runs_of_whitespace(folder.path)
+ folder_obj.okm_permissions = folder.permissions
+ folder_obj.okm_subscribed = folder.subscribed
+ folder_obj.save()
+ except Exception, e:
+ logger.exception(e)
+
+ print('%s folders returned from DMS' % len(categories))
print('%s folders now in local folder list' % klass.objects.count())
def get_list_of_root_paths(self):
@@ -375,16 +403,16 @@ def save(self, folders, klass):
try:
cl = klass.objects.create(okm_uuid=folder.uuid)
cl.okm_author = folder.author
- cl.okm_created = folder.created
- cl.okm_has_childs = folder.hasChilds
- cl.okm_path = utils.strip_runs_of_whitespace(folder.path)
+ # cl.okm_created = folder.created
+ cl.okm_has_childs = folder.hasChildren
+ cl.okm_path = utils.strip_runs_of_whitespace(folder.path)
cl.okm_permissions = folder.permissions
cl.okm_subscribed = folder.subscribed
cl.save()
except UnicodeEncodeError, e:
- logging.exception(e)
+ logging.debug(e)
except Exception, e:
- logging.exception(e)
+ logging.debug(e)
elif hasattr(folder, 'document'):
logging.error('This is a document, not a folder')
@@ -434,7 +462,7 @@ def execute(self, document, folderlist_document_class, taxonomy=False):
self.categories(document, folderlist_document_class)
self.properties(document)
except Exception, e:
- logger.exception(e)
+ logger.debug(e)
def improved_execute(self, document, openkm_folderlist_class, taxonomy=False):
CustomDjangoToOpenKM(asset=document).execute(openkm_folderlist_class, taxonomy=False)
@@ -499,7 +527,7 @@ def get_category_uuids(self, document, openkm_folderlist_class):
and_predicates = ['categories', mapped_category_name]
fields = self.sync_categories.get_objects_from_m2m_model(document, related_model_class)
or_predicates = [field.__unicode__() for field in fields]
- category_uuids += openkm_folderlist_class.objects.custom_path_query(and_predicates, or_predicates)
+ category_uuids += openkm_folderlist_class.objects.custom_path_query(and_predicates, or_predicates)
return category_uuids
def get_categories(self, document, openkm_folderlist_class):
@@ -509,21 +537,26 @@ def get_categories(self, document, openkm_folderlist_class):
"""
categories = []
for related_model_class in settings.OPENKM['categories'].keys():
- mapped_category_name = self.category_map(related_model_class.__name__)
- if not mapped_category_name:
- print 'Category not found'
- continue
- and_predicates = ['categories', mapped_category_name]
- fields = self.sync_categories.get_objects_from_m2m_model(document, related_model_class)
- or_predicates = [self._normalise_string(field.__unicode__()) for field in fields]
- categories += openkm_folderlist_class.objects.get_custom_queryset(and_predicates, or_predicates)
+ try:
+ mapped_category_name = self.category_map(related_model_class.__name__)
+ if not mapped_category_name:
+ print 'Category not found'
+ continue
+ and_predicates = ['categories', mapped_category_name]
+ fields = self.sync_categories.get_objects_from_m2m_model(document, related_model_class)
+ or_predicates = [self._normalise_string(field.__unicode__()) for field in fields]
+ categories_temp = openkm_folderlist_class.objects.get_custom_queryset(and_predicates, or_predicates)
+ if not categories_temp:
+ categories_temp = []
+ categories += categories_temp
+ except Exception, e:
+ logger.debug(e)
return categories
def _normalise_string(self, _str):
"""
Replace/remove chars to match those accepted by OpenKM
"""
- _str = _str.replace('/', '--')
_str = _str.replace("'", ' ') # apostrophes to spaces
disallowed_chars = ('[', ']', ':')
for char in disallowed_chars:
@@ -605,6 +638,7 @@ def _get_taxonomy(self, taxonomy):
def add_categories(self, openkm_folderlist_class):
categories = []
categories = self.get_categories(self.asset, openkm_folderlist_class)
+
if self.asset.is_linked_asset():
source_path = self.asset.get_dms_source_path()
categories += openkm_folderlist_class.objects.filter(okm_path=source_path)
@@ -615,12 +649,26 @@ def add_properties(self):
return sync_properties.django_to_openkm_improved(self.asset)
def create(self, data):
+ """
+ If this is a link, then create the link file and attach it to the asset object
+ """
content = facades.DocumentManager().convert_file_content_to_binary_for_transport(self.asset.file)
okm_document = self.document_client.create_document(content, data)
return okm_document
def update(self, data):
- return self.document_client.update_document(data)
+ """
+ Updates an existing document: metadata and content
+ """
+ if self.asset.source != self.asset.CMI: # direct request from Will to not update CMI
+ doc_path = self.asset.okm_path
+
+ try:
+ content = facades.DocumentManager().convert_file_content_to_binary_for_transport(self.asset.file)
+ self.document_client.set_content(doc_path=doc_path, content=content)
+ self.document_client.update_document(data)
+ except Exception, e:
+ logger.exception(e)
def get_or_create(self, data):
okm_document = self.update(data) if self.asset.okm_uuid else self.create(data)
@@ -635,12 +683,18 @@ def execute(self, folderlist_document_class, taxonomy=None):
execute() if you are using standard OpenKM
"""
data = self.get_data()
- data.document.path = self.build_path(taxonomy=taxonomy)
- data.document.keywords = self.asset.tags.split(',')
+ data.document.path = self.asset.okm_path if self.asset.okm_path else self.build_path(taxonomy=taxonomy)
+ data.document.keywords = [xml_clean(tag) for tag in self.asset.tags.split(',')]
data.document.categories = self.add_categories(folderlist_document_class)
data.properties = self.add_properties()
self.get_or_create(data)
+ def fetch_preview(self, format, version=None):
+ '''
+ Completely custom method for fetching documents for preview.
+ '''
+ return self.document_client.preview_document(self.asset.okm_uuid, format, version)
+
class OpenKmToDjango(SyncDocument):
@@ -687,7 +741,7 @@ def categories(self, document, okm_document):
category_bin = self.add_category_to_dict(model_name, object_name, category_bin)
except ValueError, e:
- logger.exception(e)
+ logger.debug(e)
print 'Category bin: ', category_bin
@@ -706,10 +760,10 @@ def categories(self, document, okm_document):
[_set.add(obj) for obj in objects]
except AttributeError, e:
print e
- logger.exception(e)
+ logger.debug(e)
except Exception, e:
print e
- logger.exception(e)
+ logger.debug(e)
def sanitize_task_description(self, task):
@@ -733,7 +787,7 @@ def add_category_to_dict(self, category_name, object_name, category_bin):
related_class = utils.find_key(settings.OPENKM['categories'], category_name) # get the related class to document
if not related_class:
- logger.error('%s not found in OPENKM[\'categories\']', category_name)
+ logger.debug('%s not found in OPENKM[\'categories\']', category_name)
return category_bin
if related_class not in category_bin:
@@ -745,3 +799,11 @@ def add_category_to_dict(self, category_name, object_name, category_bin):
def properties(self, document):
sync_properties = SyncProperties()
sync_properties.openkm_to_django(document)
+
+
+def xml_clean(value):
+ # todo: re.sub != string.translate - fix this
+ if value is None:
+ value = ''
+ remove_re = re.compile(u'[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]')
+ return remove_re.sub('', value)
View
2  openkm/tests.py
@@ -320,7 +320,7 @@ def setUp(self):
def test_get_category_root_object_structure(self):
category_root = self.category.get_category_root()
- attrs = ('author', 'created', 'hasChilds', 'path', 'permissions', 'subscribed', 'uuid')
+ attrs = ('author', 'created', 'hasChildren', 'path', 'permissions', 'subscribed', 'uuid')
for attr in attrs:
self.assertTrue(hasattr(category_root, attr), msg="%s is not an attribute of the object returned \
by category root" % attr)
View
30 openkm/views.py
@@ -1,25 +1,39 @@
import StringIO
from django.http import HttpResponse
+from django.utils import encoding
import client, utils
-def get_document_by_uuid(request, uuid):
+
+class DocumentWrapper(object):
+ document = None
+ content = None
+ response = None
+
+
+def get_document_by_uuid(request, uuid, extra_info=False):
"""
- Returns a document from OpenKM
+ Returns a tuple.
+ (HttpResponse object that can be returned to provide the file for download,
+ the file name (string),
+ the file object)
"""
+ document_wrapper = DocumentWrapper()
+
# get path from the uuid, and from that get the content
document = client.Document()
document_path = document.get_path(uuid)
- doc_meta = document.get_properties(document_path)
+ document_wrapper.document = document.get_properties(document_path)
java_byte_array = document.get_content(document_path, False)
# convert the string back to binary
file_obj = StringIO.StringIO(java_byte_array)
- document = utils.java_byte_array_to_binary(file_obj)
+ document_wrapper.content = utils.java_byte_array_to_binary(file_obj)
# set the headers and return the file
- file_name = doc_meta.path.split("/")[-1]
- response = HttpResponse(document, doc_meta.mimeType)
- response['Content-Disposition'] = 'attachment; filename=%s' % file_name
- return response
+ file_name = document_wrapper.document.path.split("/")[-1]
+ document_wrapper.response = HttpResponse(document_wrapper.content, document_wrapper.document.mimeType)
+ document_wrapper.response['Content-Disposition'] = 'attachment; filename=%s' % encoding.smart_str(file_name, encoding='ascii', errors='ignore')
+
+ return document_wrapper
Please sign in to comment.
Something went wrong with that request. Please try again.