diff --git a/erpnext/utilities/doctype/video/video.js b/erpnext/utilities/doctype/video/video.js index 056bd3ccd6..4dd4e67a7f 100644 --- a/erpnext/utilities/doctype/video/video.js +++ b/erpnext/utilities/doctype/video/video.js @@ -2,7 +2,37 @@ // For license information, please see license.txt frappe.ui.form.on('Video', { - // refresh: function(frm) { + refresh: function (frm) { + if (frm.doc.provider === "YouTube") { + frappe.db.get_single_value("Video Settings", "enable_youtube_tracking").then(value => { + if (value) { + frm.events.get_video_stats(frm); + } else { + frm.set_df_property('youtube_tracking_section', 'hidden', true); + } + }); + } - // } + frm.add_custom_button("Watch Video", () => frappe.help.show_video(frm.doc.url, frm.doc.title)); + }, + + get_video_stats: (frm) => { + const expression = '(?:youtube.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu.be/)([^"&?\\s]{11})'; + var youtube_id = frm.doc.url.match(expression)[1]; + + frappe.call({ + method: "erpnext.utilities.doctype.video.video.update_video_stats", + args: { + 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.json b/erpnext/utilities/doctype/video/video.json index 5d2cc13348..a6c0f3f82a 100644 --- a/erpnext/utilities/doctype/video/video.json +++ b/erpnext/utilities/doctype/video/video.json @@ -15,7 +15,14 @@ "publish_date", "duration", "section_break_7", - "description" + "description", + "image", + "youtube_tracking_section", + "like_count", + "view_count", + "col_break", + "dislike_count", + "comment_count" ], "fields": [ { @@ -37,7 +44,6 @@ { "fieldname": "url", "fieldtype": "Data", - "in_list_view": 1, "label": "URL", "reqd": 1 }, @@ -48,11 +54,12 @@ { "fieldname": "publish_date", "fieldtype": "Date", + "in_list_view": 1, "label": "Publish Date" }, { "fieldname": "duration", - "fieldtype": "Data", + "fieldtype": "Duration", "label": "Duration" }, { @@ -62,13 +69,60 @@ { "fieldname": "description", "fieldtype": "Text Editor", - "in_list_view": 1, "label": "Description", "reqd": 1 + }, + { + "fieldname": "like_count", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Likes", + "no_copy": 1, + "read_only": 1 + }, + { + "fieldname": "view_count", + "fieldtype": "Float", + "in_list_view": 1, + "label": "Views", + "no_copy": 1, + "read_only": 1 + }, + { + "fieldname": "col_break", + "fieldtype": "Column Break" + }, + { + "fieldname": "dislike_count", + "fieldtype": "Float", + "label": "Dislikes", + "no_copy": 1, + "read_only": 1 + }, + { + "fieldname": "comment_count", + "fieldtype": "Float", + "label": "Comments", + "no_copy": 1, + "read_only": 1 + }, + { + "fieldname": "image", + "fieldtype": "Attach Image", + "hidden": 1, + "label": "Image", + "no_copy": 1 + }, + { + "depends_on": "eval:doc.provider==\"YouTube\"", + "fieldname": "youtube_tracking_section", + "fieldtype": "Section Break", + "label": "Youtube Statistics" } ], + "image_field": "image", "links": [], - "modified": "2020-07-21 19:29:46.603734", + "modified": "2020-08-02 04:26:16.345569", "modified_by": "Administrator", "module": "Utilities", "name": "Video", diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py index 3c17b560f3..263884a93d 100644 --- a/erpnext/utilities/doctype/video/video.py +++ b/erpnext/utilities/doctype/video/video.py @@ -3,8 +3,26 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe from frappe.model.document import Document +from pyyoutube import Api class Video(Document): pass + +@frappe.whitelist() +def update_video_stats(youtube_id): + ''' + :param youtube_id: Unique ID from URL + ''' + 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 { + '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 diff --git a/erpnext/utilities/doctype/video_settings/__init__.py b/erpnext/utilities/doctype/video_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/utilities/doctype/video_settings/test_video_settings.py b/erpnext/utilities/doctype/video_settings/test_video_settings.py new file mode 100644 index 0000000000..b217afe3d8 --- /dev/null +++ b/erpnext/utilities/doctype/video_settings/test_video_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +# import frappe +import unittest + +class TestVideoSettings(unittest.TestCase): + pass diff --git a/erpnext/utilities/doctype/video_settings/video_settings.js b/erpnext/utilities/doctype/video_settings/video_settings.js new file mode 100644 index 0000000000..9ac8b9ec16 --- /dev/null +++ b/erpnext/utilities/doctype/video_settings/video_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Video Settings', { + // refresh: function(frm) { + + // } +}); diff --git a/erpnext/utilities/doctype/video_settings/video_settings.json b/erpnext/utilities/doctype/video_settings/video_settings.json new file mode 100644 index 0000000000..0a0efd9a53 --- /dev/null +++ b/erpnext/utilities/doctype/video_settings/video_settings.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "creation": "2020-08-02 03:50:21.339609", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "enable_youtube_tracking", + "api_key" + ], + "fields": [ + { + "default": "0", + "fieldname": "enable_youtube_tracking", + "fieldtype": "Check", + "label": "Enable YouTube Tracking" + }, + { + "depends_on": "eval:doc.enable_youtube_tracking", + "fieldname": "api_key", + "fieldtype": "Data", + "label": "API Key", + "mandatory_depends_on": "eval:doc.enable_youtube_tracking" + } + ], + "issingle": 1, + "links": [], + "modified": "2020-08-02 03:56:49.673870", + "modified_by": "Administrator", + "module": "Utilities", + "name": "Video Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/utilities/doctype/video_settings/video_settings.py b/erpnext/utilities/doctype/video_settings/video_settings.py new file mode 100644 index 0000000000..7008066909 --- /dev/null +++ b/erpnext/utilities/doctype/video_settings/video_settings.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +# import frappe +from frappe.model.document import Document + +class VideoSettings(Document): + pass diff --git a/erpnext/utilities/report/__init__.py b/erpnext/utilities/report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/utilities/report/youtube_interactions/__init__.py b/erpnext/utilities/report/youtube_interactions/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.js b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js new file mode 100644 index 0000000000..f194cca834 --- /dev/null +++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["YouTube Interactions"] = { + "filters": [ + + ] +}; diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.json b/erpnext/utilities/report/youtube_interactions/youtube_interactions.json new file mode 100644 index 0000000000..a40247b6df --- /dev/null +++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 0, + "creation": "2020-08-02 05:05:00.457093", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2020-08-02 05:05:00.457093", + "modified_by": "Administrator", + "module": "Utilities", + "name": "YouTube Interactions", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Video", + "report_name": "YouTube Interactions", + "report_type": "Script Report", + "roles": [ + { + "role": "All" + }, + { + "role": "System Manager" + } + ] +} \ No newline at end of file diff --git a/erpnext/utilities/report/youtube_interactions/youtube_interactions.py b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py new file mode 100644 index 0000000000..169d0716b0 --- /dev/null +++ b/erpnext/utilities/report/youtube_interactions/youtube_interactions.py @@ -0,0 +1,72 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ + +def execute(filters=None): + columns = get_columns() + data = get_data() + return columns, data + +def get_columns(): + return [ + { + "label": _("Published Date"), + "fieldname": "publish_date", + "fieldtype": "Date", + "width": 100 + }, + { + "label": _("Title"), + "fieldname": "title", + "fieldtype": "Data", + "width": 100 + }, + { + "label": _("Provider"), + "fieldname": "provider", + "fieldtype": "Data", + "width": 100 + }, + { + "label": _("Views"), + "fieldname": "view_count", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Likes"), + "fieldname": "like_count", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Dislikes"), + "fieldname": "dislike_count", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Views"), + "fieldname": "view_count", + "fieldtype": "Float", + "width": 100 + }, + { + "label": _("Like:Dislike Ratio"), + "fieldname": "ratio", + "fieldtype": "Data", + "width": 100 + } + ] + +def get_data(): + return frappe.db.sql(""" + SELECT + publish_date, title, provider, + 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 diff --git a/requirements.txt b/requirements.txt index 912d61f7a6..872d78caa3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ plaid-python==3.4.0 pycountry==19.8.18 PyGithub==1.44.1 python-stdnum==1.12 +python-youtube==0.6.0 taxjar==1.9.0 tweepy==3.8.0 Unidecode==1.1.1