feat: Track Youtube interactions via Video DocType
diff --git a/erpnext/utilities/doctype/video/video.js b/erpnext/utilities/doctype/video/video.js
index 056bd3c..4dd4e67 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 5d2cc13..a6c0f3f 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 3c17b56..263884a 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 0000000..e69de29
--- /dev/null
+++ b/erpnext/utilities/doctype/video_settings/__init__.py
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 0000000..b217afe
--- /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 0000000..9ac8b9e
--- /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 0000000..0a0efd9
--- /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 0000000..7008066
--- /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 0000000..e69de29
--- /dev/null
+++ b/erpnext/utilities/report/__init__.py
diff --git a/erpnext/utilities/report/youtube_interactions/__init__.py b/erpnext/utilities/report/youtube_interactions/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/utilities/report/youtube_interactions/__init__.py
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 0000000..f194cca
--- /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 0000000..a40247b
--- /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 0000000..169d071
--- /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 912d61f..872d78c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,6 +7,7 @@
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