From 872faddba8f33a419c1402b8b118347fc20ee955 Mon Sep 17 00:00:00 2001 From: John Eskew Date: Thu, 13 Nov 2014 14:29:22 -0500 Subject: [PATCH] Add created_on and created_by to asset metadata storage. https://openedx.atlassian.net/browse/PLAT-278 --- .../xmodule/xmodule/assetstore/__init__.py | 47 +++++++++++++------ .../xmodule/xmodule/modulestore/__init__.py | 6 +-- .../modulestore/tests/test_assetstore.py | 32 ++++++++----- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/common/lib/xmodule/xmodule/assetstore/__init__.py b/common/lib/xmodule/xmodule/assetstore/__init__.py index 6c0464a405..f1e74ba2d3 100644 --- a/common/lib/xmodule/xmodule/assetstore/__init__.py +++ b/common/lib/xmodule/xmodule/assetstore/__init__.py @@ -5,8 +5,7 @@ Classes representing asset metadata. from datetime import datetime import pytz from contracts import contract, new_contract -from bisect import bisect_left, bisect_right -from opaque_keys.edx.keys import CourseKey, AssetKey +from opaque_keys.edx.keys import AssetKey new_contract('AssetKey', AssetKey) new_contract('datetime', datetime) @@ -26,12 +25,19 @@ class AssetMetadata(object): # Default type for AssetMetadata objects. A constant for convenience. ASSET_TYPE = 'asset' - @contract(asset_id='AssetKey', basename='basestring|None', internal_name='basestring|None', locked='bool|None', contenttype='basestring|None', - fields='dict | None', curr_version='basestring|None', prev_version='basestring|None', edited_by='int|None', edited_on='datetime|None') + @contract(asset_id='AssetKey', + basename='basestring|None', internal_name='basestring|None', + locked='bool|None', contenttype='basestring|None', + thumbnail='basestring|None', fields='dict|None', + curr_version='basestring|None', prev_version='basestring|None', + created_by='int|None', created_on='datetime|None', + edited_by='int|None', edited_on='datetime|None') def __init__(self, asset_id, basename=None, internal_name=None, - locked=None, contenttype=None, thumbnail=None, fields=None, + locked=None, contenttype=None, + thumbnail=None, fields=None, curr_version=None, prev_version=None, + created_by=None, created_on=None, edited_by=None, edited_on=None, field_decorator=None,): """ @@ -60,8 +66,12 @@ class AssetMetadata(object): self.thumbnail = thumbnail self.curr_version = curr_version self.prev_version = prev_version + now = datetime.now(pytz.utc) self.edited_by = edited_by - self.edited_on = edited_on or datetime.now(pytz.utc) + self.edited_on = edited_on or now + # created_by and created_on should only be set here. + self.created_by = created_by + self.created_on = created_on or now self.fields = fields or {} def __repr__(self): @@ -70,7 +80,8 @@ class AssetMetadata(object): self.basename, self.internal_name, self.locked, self.contenttype, self.fields, self.curr_version, self.prev_version, - self.edited_by, self.edited_on + self.edited_by, self.edited_on, + self.created_by, self.created_on )) def update(self, attr_dict): @@ -99,10 +110,14 @@ class AssetMetadata(object): 'contenttype': self.contenttype, 'thumbnail': self.thumbnail, 'fields': self.fields, - 'curr_version': self.curr_version, - 'prev_version': self.prev_version, - 'edited_by': self.edited_by, - 'edited_on': self.edited_on + 'edit_info': { + 'curr_version': self.curr_version, + 'prev_version': self.prev_version, + 'edited_by': self.edited_by, + 'edited_on': self.edited_on, + 'created_by': self.created_by, + 'created_on': self.created_on + } } @contract(asset_doc='dict|None') @@ -120,7 +135,9 @@ class AssetMetadata(object): self.contenttype = asset_doc['contenttype'] self.thumbnail = asset_doc['thumbnail'] self.fields = asset_doc['fields'] - self.curr_version = asset_doc['curr_version'] - self.prev_version = asset_doc['prev_version'] - self.edited_by = asset_doc['edited_by'] - self.edited_on = asset_doc['edited_on'] + self.curr_version = asset_doc['edit_info']['curr_version'] + self.prev_version = asset_doc['edit_info']['prev_version'] + self.edited_by = asset_doc['edit_info']['edited_by'] + self.edited_on = asset_doc['edit_info']['edited_on'] + self.created_by = asset_doc['edit_info']['created_by'] + self.created_on = asset_doc['edit_info']['created_on'] diff --git a/common/lib/xmodule/xmodule/modulestore/__init__.py b/common/lib/xmodule/xmodule/modulestore/__init__.py index 84968eff6b..987df6eea2 100644 --- a/common/lib/xmodule/xmodule/modulestore/__init__.py +++ b/common/lib/xmodule/xmodule/modulestore/__init__.py @@ -364,15 +364,15 @@ class ModuleStoreAssetInterface(object): return None # Determine the proper sort - with defaults of ('displayname', SortOrder.ascending). - sort_field = 'filename' + key_func = itemgetter('filename') sort_order = ModuleStoreEnum.SortOrder.ascending if sort: if sort[0] == 'uploadDate': - sort_field = 'edited_on' + key_func = lambda x: x['edit_info']['edited_on'] if sort[1] == ModuleStoreEnum.SortOrder.descending: sort_order = ModuleStoreEnum.SortOrder.descending - all_assets = SortedListWithKey(course_assets.get(asset_type, []), key=itemgetter(sort_field)) + all_assets = SortedListWithKey(course_assets.get(asset_type, []), key=key_func) num_assets = len(all_assets) start_idx = start diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py index cd224bc2fc..ea7a627d9a 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_assetstore.py @@ -47,11 +47,13 @@ class TestMongoAssetMetadataStorage(unittest.TestCase): """ Make a single test asset metadata. """ + now = datetime.now(pytz.utc) return AssetMetadata( asset_loc, internal_name='EKMND332DDBK', basename='pictures/historical', contenttype='image/jpeg', locked=False, fields={'md5': '77631ca4f0e08419b70726a447333ab6'}, - edited_by=ModuleStoreEnum.UserID.test, edited_on=datetime.now(pytz.utc), + edited_by=ModuleStoreEnum.UserID.test, edited_on=now, + created_by=ModuleStoreEnum.UserID.test, created_on=now, curr_version='v1.0', prev_version='v0.95' ) @@ -66,17 +68,23 @@ class TestMongoAssetMetadataStorage(unittest.TestCase): """ Setup assets. Save in store if given """ - asset_fields = ('filename', 'internal_name', 'basename', 'locked', 'edited_by', 'edited_on', 'curr_version', 'prev_version') + asset_fields = ( + 'filename', 'internal_name', 'basename', 'locked', + 'edited_by', 'edited_on', 'created_by', 'created_on', + 'curr_version', 'prev_version' + ) + now = datetime.now(pytz.utc) + user_id = ModuleStoreEnum.UserID.test all_asset_data = ( - ('pic1.jpg', 'EKMND332DDBK', 'pix/archive', False, ModuleStoreEnum.UserID.test, datetime.now(pytz.utc), '14', '13'), - ('shout.ogg', 'KFMDONSKF39K', 'sounds', True, ModuleStoreEnum.UserID.test, datetime.now(pytz.utc), '1', None), - ('code.tgz', 'ZZB2333YBDMW', 'exercises/14', False, ModuleStoreEnum.UserID.test * 2, datetime.now(pytz.utc), 'AB', 'AA'), - ('dog.png', 'PUPY4242X', 'pictures/animals', True, ModuleStoreEnum.UserID.test * 3, datetime.now(pytz.utc), '5', '4'), - ('not_here.txt', 'JJJCCC747', '/dev/null', False, ModuleStoreEnum.UserID.test * 4, datetime.now(pytz.utc), '50', '49'), - ('asset.txt', 'JJJCCC747858', '/dev/null', False, ModuleStoreEnum.UserID.test * 4, datetime.now(pytz.utc), '50', '49'), - ('roman_history.pdf', 'JASDUNSADK', 'texts/italy', True, ModuleStoreEnum.UserID.test * 7, datetime.now(pytz.utc), '1.1', '1.01'), - ('weather_patterns.bmp', '928SJXX2EB', 'science', False, ModuleStoreEnum.UserID.test * 8, datetime.now(pytz.utc), '52', '51'), - ('demo.swf', 'DFDFGGGG14', 'demos/easy', False, ModuleStoreEnum.UserID.test * 9, datetime.now(pytz.utc), '5', '4'), + ('pic1.jpg', 'EKMND332DDBK', 'pix/archive', False, user_id, now, user_id, now, '14', '13'), + ('shout.ogg', 'KFMDONSKF39K', 'sounds', True, user_id, now, user_id, now, '1', None), + ('code.tgz', 'ZZB2333YBDMW', 'exercises/14', False, user_id * 2, now, user_id * 2, now, 'AB', 'AA'), + ('dog.png', 'PUPY4242X', 'pictures/animals', True, user_id * 3, now, user_id * 3, now, '5', '4'), + ('not_here.txt', 'JJJCCC747', '/dev/null', False, user_id * 4, now, user_id * 4, now, '50', '49'), + ('asset.txt', 'JJJCCC747858', '/dev/null', False, user_id * 4, now, user_id * 4, now, '50', '49'), + ('roman_history.pdf', 'JASDUNSADK', 'texts/italy', True, user_id * 7, now, user_id * 7, now, '1.1', '1.01'), + ('weather_patterns.bmp', '928SJXX2EB', 'science', False, user_id * 8, now, user_id * 8, now, '52', '51'), + ('demo.swf', 'DFDFGGGG14', 'demos/easy', False, user_id * 9, now, user_id * 9, now, '5', '4'), ) for i, asset in enumerate(all_asset_data): @@ -204,6 +212,8 @@ class TestMongoAssetMetadataStorage(unittest.TestCase): DISALLOWED_ATTRS = ( ('asset_id', 'IAmBogus'), + ('created_by', 'Smith'), + ('created_on', datetime.now(pytz.utc)), ) UNKNOWN_ATTRS = (