From ccf4ab9f852f7af8cf669abd1bd664d9e15dfc58 Mon Sep 17 00:00:00 2001 From: marination Date: Sun, 2 Aug 2020 16:26:36 +0530 Subject: [PATCH] chore: Added Interactions Report and behaviour fixes - Youtube Interactions Report with Chart and Summary - Statistics change in doc on refresh and get updated in db as well --- erpnext/utilities/doctype/video/video.js | 11 +-- erpnext/utilities/doctype/video/video.py | 27 ++++++- .../youtube_interactions.js | 13 ++- .../youtube_interactions.py | 79 ++++++++++++++----- 4 files changed, 97 insertions(+), 33 deletions(-) diff --git a/erpnext/utilities/doctype/video/video.js b/erpnext/utilities/doctype/video/video.js index 4dd4e67a7f..c2994ecc96 100644 --- a/erpnext/utilities/doctype/video/video.js +++ b/erpnext/utilities/doctype/video/video.js @@ -21,17 +21,10 @@ frappe.ui.form.on('Video', { var youtube_id = frm.doc.url.match(expression)[1]; frappe.call({ - method: "erpnext.utilities.doctype.video.video.update_video_stats", + method: "erpnext.utilities.doctype.video.video.get_video_stats", args: { + docname: frm.doc.name, youtube_id: youtube_id - }, - callback: (r) => { - var result = r.message; - var fields = ['like_count', 'view_count', 'dislike_count', 'comment_count']; - fields.forEach((field) => { - frm.doc[field] = result[field]; - }) - frm.refresh_fields(); } }); } diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py index 263884a93d..bea7904609 100644 --- a/erpnext/utilities/doctype/video/video.py +++ b/erpnext/utilities/doctype/video/video.py @@ -5,24 +5,43 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document +from six import string_types from pyyoutube import Api class Video(Document): pass @frappe.whitelist() -def update_video_stats(youtube_id): - ''' +def get_video_stats(docname, youtube_id, update=True): + '''Returns/Sets video statistics + :param docname: Name of Video :param youtube_id: Unique ID from URL + :param update: Updates db stats value if True, else returns statistics ''' + if isinstance(update, string_types): + update = json.loads(update) + api_key = frappe.db.get_single_value("Video Settings", "api_key") api = Api(api_key=api_key) video = api.get_video_by_id(video_id=youtube_id) video_stats = video.items[0].to_dict().get('statistics') - return { + stats = { 'like_count' : video_stats.get('likeCount'), 'view_count' : video_stats.get('viewCount'), 'dislike_count' : video_stats.get('dislikeCount'), 'comment_count' : video_stats.get('commentCount') - } \ No newline at end of file + } + + if not update: + return stats + + frappe.db.sql(""" + UPDATE `tabVideo` + SET + like_count = %(like_count)s, + view_count = %(view_count)s, + dislike_count = %(dislike_count)s, + comment_count = %(comment_count)s + WHERE name = {0}""".format(frappe.db.escape(docname)), stats) + frappe.db.commit() \ No newline at end of file diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.js b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js index f194cca834..6e3e4e6980 100644 --- a/erpnext/utilities/report/youtube_interactions/youtube_interactions.js +++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js @@ -4,6 +4,17 @@ frappe.query_reports["YouTube Interactions"] = { "filters": [ - + { + fieldname: "from_date", + label: __("From Date"), + fieldtype: "Date", + default: frappe.datetime.add_months(frappe.datetime.now_date(), -12), + }, + { + fieldname:"to_date", + label: __("To Date"), + fieldtype: "Date", + default: frappe.datetime.now_date(), + } ] }; diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.py b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py index 169d0716b0..3516a35097 100644 --- a/erpnext/utilities/report/youtube_interactions/youtube_interactions.py +++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py @@ -4,11 +4,16 @@ from __future__ import unicode_literals import frappe from frappe import _ +from frappe.utils import flt def execute(filters=None): + if not frappe.db.get_single_value("Video Settings", "enable_youtube_tracking") or not filters: + return [], [] + columns = get_columns() - data = get_data() - return columns, data + data = get_data(filters) + chart_data, summary = get_chart_summary_data(data) + return columns, data, None, chart_data, summary def get_columns(): return [ @@ -22,25 +27,25 @@ def get_columns(): "label": _("Title"), "fieldname": "title", "fieldtype": "Data", - "width": 100 + "width": 200 }, { - "label": _("Provider"), - "fieldname": "provider", - "fieldtype": "Data", + "label": _("Duration"), + "fieldname": "duration", + "fieldtype": "Duration", "width": 100 }, { "label": _("Views"), "fieldname": "view_count", "fieldtype": "Float", - "width": 100 + "width": 200 }, { "label": _("Likes"), "fieldname": "like_count", "fieldtype": "Float", - "width": 100 + "width": 200 }, { "label": _("Dislikes"), @@ -49,24 +54,60 @@ def get_columns(): "width": 100 }, { - "label": _("Views"), - "fieldname": "view_count", + "label": _("Comments"), + "fieldname": "comment_count", "fieldtype": "Float", "width": 100 - }, - { - "label": _("Like:Dislike Ratio"), - "fieldname": "ratio", - "fieldtype": "Data", - "width": 100 } ] -def get_data(): +def get_data(filters): return frappe.db.sql(""" SELECT - publish_date, title, provider, + publish_date, title, provider, duration, view_count, like_count, dislike_count, comment_count FROM `tabVideo` WHERE view_count is not null - ORDER BY view_count desc""") \ No newline at end of file + and publish_date between %(from_date)s and %(to_date)s + ORDER BY view_count desc""", filters, as_dict=1) + +def get_chart_summary_data(data): + labels, likes, views = [], [], [] + total_views = 0 + + for row in data: + labels.append(row.get('title')) + likes.append(row.get('like_count')) + views.append(row.get('view_count')) + total_views += flt(row.get('view_count')) + + + chart_data = { + "data" : { + "labels" : labels, + "datasets" : [ + { + "name" : "Likes", + "values" : likes + }, + { + "name" : "Views", + "values" : views + } + ] + }, + "type": "bar", + "barOptions": { + "stacked": 1 + }, + } + + summary = [ + { + "value": total_views, + "indicator": "Blue", + "label": "Total Views", + "datatype": "Float", + } + ] + return chart_data, summary \ No newline at end of file