Tagged Asset: Added metadata
Video duration, Project link and pretty date
This commit is contained in:
parent
4cf93f00f6
commit
199f37c5d7
@ -1,4 +1,5 @@
|
||||
import base64
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
import pymongo.errors
|
||||
@ -8,6 +9,7 @@ from flask import current_app, Blueprint, request
|
||||
from pillar.api.nodes import eve_hooks
|
||||
from pillar.api.utils import str2id, jsonify
|
||||
from pillar.api.utils.authorization import check_permissions, require_login
|
||||
from pillar.web.utils import pretty_date
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
blueprint = Blueprint('nodes_api', __name__)
|
||||
@ -63,6 +65,13 @@ def tagged(tag=''):
|
||||
# Build the (cached) list of tagged nodes
|
||||
agg_list = _tagged(tag)
|
||||
|
||||
for node in agg_list:
|
||||
if node.get('video_duration_seconds'):
|
||||
node['video_duration'] = datetime.timedelta(seconds=node['video_duration_seconds'])
|
||||
|
||||
if node.get('_created') is not None:
|
||||
node['pretty_created'] = pretty_date(node['_created'])
|
||||
|
||||
# If the user is anonymous, no more information is needed and we return
|
||||
if current_user.is_anonymous:
|
||||
return jsonify(agg_list)
|
||||
@ -99,11 +108,26 @@ def _tagged(tag: str):
|
||||
'foreignField': '_id',
|
||||
'as': '_project',
|
||||
}},
|
||||
{'$lookup': {
|
||||
'from': 'files',
|
||||
'localField': 'properties.file',
|
||||
'foreignField': '_id',
|
||||
'as': '_file',
|
||||
}},
|
||||
{'$unwind': '$_file'},
|
||||
{'$unwind': '$_project'},
|
||||
{'$match': {'_project.is_private': False}},
|
||||
{'$addFields': {
|
||||
'project._id': '$_project._id',
|
||||
'project.name': '$_project.name',
|
||||
'project.url': '$_project.url',
|
||||
'video_duration_seconds': {'$arrayElemAt': ['$_file.variations.duration', 0]},
|
||||
}},
|
||||
|
||||
# Don't return the entire project for each node.
|
||||
{'$project': {'_project': False}},
|
||||
|
||||
# Don't return the entire project/file for each node.
|
||||
{'$project': {'_project': False,
|
||||
'_file': False}
|
||||
},
|
||||
{'$sort': {'_created': -1}}
|
||||
])
|
||||
|
||||
|
@ -64,6 +64,14 @@ class PillarJSONEncoder(json.JSONEncoder):
|
||||
if isinstance(obj, datetime.datetime):
|
||||
return obj.strftime(RFC1123_DATE_FORMAT)
|
||||
|
||||
if isinstance(obj, datetime.timedelta):
|
||||
hours, seconds = divmod(obj.seconds, 3600)
|
||||
minutes, seconds = divmod(seconds, 60)
|
||||
if hours > 0:
|
||||
return f'{hours:02}:{minutes:02}:{seconds:02}'
|
||||
else:
|
||||
return f'{minutes:02}:{seconds:02}'
|
||||
|
||||
if isinstance(obj, bson.ObjectId):
|
||||
return str(obj)
|
||||
|
||||
|
@ -145,6 +145,11 @@ $card-progress-height: 5px
|
||||
padding: 1px 5px
|
||||
z-index: 1
|
||||
|
||||
.card-label
|
||||
&.right
|
||||
right: 5px
|
||||
left: auto
|
||||
|
||||
.card
|
||||
&.active
|
||||
.card-title
|
||||
|
@ -484,7 +484,13 @@ class TaggedNodesTest(AbstractPillarTest):
|
||||
super().setUp(**kwargs)
|
||||
|
||||
self.pid, _ = self.ensure_project_exists()
|
||||
self.file_id, _ = self.ensure_file_exists()
|
||||
self.file_id, _ = self.ensure_file_exists(file_overrides={
|
||||
'variations': [
|
||||
{'format': 'mp4',
|
||||
'duration': 3661 # 01:01:01
|
||||
},
|
||||
],
|
||||
})
|
||||
self.uid = self.create_user()
|
||||
|
||||
from pillar.api.utils import utcnow
|
||||
@ -635,6 +641,38 @@ class TaggedNodesTest(AbstractPillarTest):
|
||||
for node in resp:
|
||||
self.assertNotIn('view_progress', node)
|
||||
|
||||
def test_tagged_nodes_metadata(self):
|
||||
from datetime import timedelta
|
||||
|
||||
base_node = {
|
||||
'name': 'Just a node name',
|
||||
'project': self.pid,
|
||||
'description': '',
|
||||
'node_type': 'asset',
|
||||
'user': self.uid,
|
||||
}
|
||||
base_props = {'status': 'published',
|
||||
'file': self.file_id,
|
||||
'content_type': 'video',
|
||||
'order': 0}
|
||||
|
||||
self.create_node({
|
||||
'_created': self.fake_now - timedelta(minutes=5),
|
||||
# 'एनिमेशन' is 'animation' in Hindi.
|
||||
'properties': {'tags': ['एनिमेशन'], **base_props},
|
||||
**base_node,
|
||||
})
|
||||
|
||||
with self.app.app_context():
|
||||
with mock.patch('pillar.api.utils.utcnow') as mock_utcnow:
|
||||
mock_utcnow.return_value = self.fake_now
|
||||
url = flask.url_for('nodes_api.tagged', tag='एनिमेशन')
|
||||
resp = self.get(url).json[0]
|
||||
self.assertEquals('01:01:01', resp['video_duration'])
|
||||
self.assertEquals('Unittest project', resp['project']['name'])
|
||||
self.assertEquals('default-project', resp['project']['url'])
|
||||
self.assertEquals('5m ago', resp['pretty_created'])
|
||||
|
||||
|
||||
class NodesReferencedByProjectTest(AbstractPillarTest):
|
||||
def setUp(self, **kwargs):
|
||||
|
Loading…
x
Reference in New Issue
Block a user