From 9ce38de439ebd2a240539542a8de40f8ae2d2417 Mon Sep 17 00:00:00 2001 From: marination Date: Mon, 7 Sep 2020 13:27:17 +0530 Subject: [PATCH] chore: Key Validation and restructure - Added API Key validation in Video Settings - Moved Statistics section above description in Video - Moved id retrieving from URL to py side - Removed js side calls, added section toggling in js - Restructured Code --- erpnext/utilities/doctype/video/video.js | 28 ++------ erpnext/utilities/doctype/video/video.json | 10 +-- erpnext/utilities/doctype/video/video.py | 71 +++++++++---------- .../doctype/video_settings/video_settings.py | 16 ++++- 4 files changed, 61 insertions(+), 64 deletions(-) diff --git a/erpnext/utilities/doctype/video/video.js b/erpnext/utilities/doctype/video/video.js index c2994ecc962..9cb5a155ade 100644 --- a/erpnext/utilities/doctype/video/video.js +++ b/erpnext/utilities/doctype/video/video.js @@ -3,29 +3,15 @@ frappe.ui.form.on('Video', { 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.events.toggle_youtube_statistics_section(frm); 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.get_video_stats", - args: { - docname: frm.doc.name, - youtube_id: youtube_id - } - }); + toggle_youtube_statistics_section: (frm) => { + if (frm.doc.provider === "YouTube") { + frappe.db.get_single_value("Video Settings", "enable_youtube_tracking").then( val => { + frm.toggle_display("youtube_tracking_section", val); + }); + } } }); diff --git a/erpnext/utilities/doctype/video/video.json b/erpnext/utilities/doctype/video/video.json index a6c0f3f82a9..11df56c77da 100644 --- a/erpnext/utilities/doctype/video/video.json +++ b/erpnext/utilities/doctype/video/video.json @@ -14,15 +14,15 @@ "column_break_4", "publish_date", "duration", - "section_break_7", - "description", - "image", "youtube_tracking_section", "like_count", "view_count", "col_break", "dislike_count", - "comment_count" + "comment_count", + "section_break_7", + "description", + "image" ], "fields": [ { @@ -122,7 +122,7 @@ ], "image_field": "image", "links": [], - "modified": "2020-08-02 04:26:16.345569", + "modified": "2020-09-04 12:59:28.283622", "modified_by": "Administrator", "module": "Utilities", "name": "Video", diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py index a2a4a7b745b..2299f95f76b 100644 --- a/erpnext/utilities/doctype/video/video.py +++ b/erpnext/utilities/doctype/video/video.py @@ -5,49 +5,48 @@ from __future__ import unicode_literals import frappe import json +import re from frappe.model.document import Document +from frappe import _ from six import string_types from pyyoutube import Api class Video(Document): - pass + def validate(self): + self.set_youtube_statistics() + + def set_youtube_statistics(self): + tracking_enabled = frappe.db.get_single_value("Video Settings", "enable_youtube_tracking") + if self.provider == "YouTube" and not tracking_enabled: + return + + api_key = frappe.db.get_single_value("Video Settings", "api_key") + youtube_id = get_id_from_url(self.url) + api = Api(api_key=api_key) + + try: + video = api.get_video_by_id(video_id=youtube_id) + video_stats = video.items[0].to_dict().get('statistics') + + self.like_count = video_stats.get('likeCount') + self.view_count = video_stats.get('viewCount') + self.dislike_count = video_stats.get('dislikeCount') + self.comment_count = video_stats.get('commentCount') + + except Exception: + title = "Failed to Update YouTube Statistics for Video: {0}".format(self.name) + frappe.log_error(title + "\n\n" + frappe.get_traceback(), title=title) @frappe.whitelist() -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 +def get_id_from_url(url): ''' - if isinstance(update, string_types): - update = json.loads(update) + Returns video id from url - api_key = frappe.db.get_single_value("Video Settings", "api_key") - api = Api(api_key=api_key) + :param youtube url: String URL + ''' + if not isinstance(url, string_types): + frappe.throw(_("URL can only be a string"), title=_("Invalid URL")) - try: - video = api.get_video_by_id(video_id=youtube_id) - video_stats = video.items[0].to_dict().get('statistics') - 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') - } - - 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) #nosec - frappe.db.commit() - except: - message = "Please make sure you are connected to the Internet" - frappe.log_error(message + "\n\n" + frappe.get_traceback(), "Failed to Update YouTube Statistics for Video: {0}".format(docname)) \ No newline at end of file + pattern = re.compile(r'[a-z\:\//\.]+(youtube|youtu)\.(com|be)/(watch\?v=|embed/|.+\?v=)?([^"&?\s]{11})?') + id = pattern.match(url) + return id.groups()[-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 index 70080669097..36fb54f0150 100644 --- a/erpnext/utilities/doctype/video_settings/video_settings.py +++ b/erpnext/utilities/doctype/video_settings/video_settings.py @@ -3,8 +3,20 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe +from frappe import _ from frappe.model.document import Document +from apiclient.discovery import build class VideoSettings(Document): - pass + def validate(self): + self.validate_youtube_api_key() + + def validate_youtube_api_key(self): + if self.enable_youtube_tracking and self.api_key: + try: + build("youtube", "v3", developerKey=self.api_key) + except Exception: + title = _("Failed to Authenticate the API key.") + frappe.log_error(title + "\n\n" + frappe.get_traceback(), title=title) + frappe.throw(title + " Please check the error logs.", title=_("Invalid Credentials")) \ No newline at end of file