Merge pull request #37086 from frappe/remove_twitter
refactor!: remove twitter integration
This commit is contained in:
commit
0fadde037a
@ -2,7 +2,7 @@
|
||||
// For license information, please see license.txt
|
||||
frappe.ui.form.on('Social Media Post', {
|
||||
validate: function(frm) {
|
||||
if (frm.doc.twitter === 0 && frm.doc.linkedin === 0) {
|
||||
if (frm.doc.linkedin === 0) {
|
||||
frappe.throw(__("Select atleast one Social Media Platform to Share on."));
|
||||
}
|
||||
if (frm.doc.scheduled_time) {
|
||||
@ -45,13 +45,6 @@ frappe.ui.form.on('Social Media Post', {
|
||||
}
|
||||
|
||||
let datasets = [], colors = [];
|
||||
if (r.message && r.message.twitter) {
|
||||
colors.push('#1DA1F2');
|
||||
datasets.push({
|
||||
name: 'Twitter',
|
||||
values: [r.message.twitter.favorite_count, r.message.twitter.retweet_count]
|
||||
});
|
||||
}
|
||||
if (r.message && r.message.linkedin) {
|
||||
colors.push('#0077b5');
|
||||
datasets.push({
|
||||
@ -104,13 +97,6 @@ frappe.ui.form.on('Social Media Post', {
|
||||
|
||||
if (frm.doc.post_status !='Deleted') {
|
||||
let html='';
|
||||
if (frm.doc.twitter) {
|
||||
let color = frm.doc.twitter_post_id ? "green" : "red";
|
||||
let status = frm.doc.twitter_post_id ? "Posted" : "Not Posted";
|
||||
html += `<div class="col-xs-6">
|
||||
<span class="indicator whitespace-nowrap ${color}"><span>Twitter : ${status} </span></span>
|
||||
</div>` ;
|
||||
}
|
||||
if (frm.doc.linkedin) {
|
||||
let color = frm.doc.linkedin_post_id ? "green" : "red";
|
||||
let status = frm.doc.linkedin_post_id ? "Posted" : "Not Posted";
|
||||
|
@ -12,14 +12,8 @@
|
||||
"scheduled_time",
|
||||
"post_status",
|
||||
"column_break_6",
|
||||
"twitter",
|
||||
"linkedin",
|
||||
"twitter_post_id",
|
||||
"linkedin_post_id",
|
||||
"content",
|
||||
"text",
|
||||
"column_break_14",
|
||||
"tweet_preview",
|
||||
"linkedin_section",
|
||||
"linkedin_post",
|
||||
"column_break_15",
|
||||
@ -28,23 +22,11 @@
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "text",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Tweet",
|
||||
"mandatory_depends_on": "eval:doc.twitter ==1"
|
||||
},
|
||||
{
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"label": "Image"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "twitter",
|
||||
"fieldtype": "Check",
|
||||
"label": "Twitter"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "linkedin",
|
||||
@ -60,12 +42,6 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.twitter ==1",
|
||||
"fieldname": "content",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Twitter"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "post_status",
|
||||
@ -75,15 +51,6 @@
|
||||
"options": "\nScheduled\nPosted\nCancelled\nDeleted\nError",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "twitter_post_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Twitter Post Id",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "linkedin_post_id",
|
||||
@ -105,14 +72,6 @@
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Share On"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "tweet_preview",
|
||||
"fieldtype": "HTML"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"depends_on": "eval:doc.linkedin==1",
|
||||
@ -152,10 +111,11 @@
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-04-14 14:24:59.821223",
|
||||
"modified": "2023-09-14 11:24:29.105683",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Social Media Post",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
@ -203,6 +163,7 @@
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "title",
|
||||
"track_changes": 1
|
||||
}
|
@ -11,7 +11,7 @@ from frappe.model.document import Document
|
||||
|
||||
class SocialMediaPost(Document):
|
||||
def validate(self):
|
||||
if not self.twitter and not self.linkedin:
|
||||
if not self.linkedin:
|
||||
frappe.throw(_("Select atleast one Social Media Platform to Share on."))
|
||||
|
||||
if self.scheduled_time:
|
||||
@ -33,10 +33,6 @@ class SocialMediaPost(Document):
|
||||
|
||||
@frappe.whitelist()
|
||||
def delete_post(self):
|
||||
if self.twitter and self.twitter_post_id:
|
||||
twitter = frappe.get_doc("Twitter Settings")
|
||||
twitter.delete_tweet(self.twitter_post_id)
|
||||
|
||||
if self.linkedin and self.linkedin_post_id:
|
||||
linkedin = frappe.get_doc("LinkedIn Settings")
|
||||
linkedin.delete_post(self.linkedin_post_id)
|
||||
@ -49,19 +45,11 @@ class SocialMediaPost(Document):
|
||||
if self.linkedin and self.linkedin_post_id:
|
||||
linkedin = frappe.get_doc("LinkedIn Settings")
|
||||
response["linkedin"] = linkedin.get_post(self.linkedin_post_id)
|
||||
if self.twitter and self.twitter_post_id:
|
||||
twitter = frappe.get_doc("Twitter Settings")
|
||||
response["twitter"] = twitter.get_tweet(self.twitter_post_id)
|
||||
|
||||
return response
|
||||
|
||||
@frappe.whitelist()
|
||||
def post(self):
|
||||
try:
|
||||
if self.twitter and not self.twitter_post_id:
|
||||
twitter = frappe.get_doc("Twitter Settings")
|
||||
twitter_post = twitter.post(self.text, self.image)
|
||||
self.db_set("twitter_post_id", twitter_post.id)
|
||||
if self.linkedin and not self.linkedin_post_id:
|
||||
linkedin = frappe.get_doc("LinkedIn Settings")
|
||||
linkedin_post = linkedin.post(self.linkedin_post, self.title, self.image)
|
||||
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
|
||||
class TestTwitterSettings(unittest.TestCase):
|
||||
pass
|
@ -1,59 +0,0 @@
|
||||
// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Twitter Settings', {
|
||||
onload: function(frm) {
|
||||
if (frm.doc.session_status == 'Expired' && frm.doc.consumer_key && frm.doc.consumer_secret){
|
||||
frappe.confirm(
|
||||
__('Session not valid, Do you want to login?'),
|
||||
function(){
|
||||
frm.trigger("login");
|
||||
},
|
||||
function(){
|
||||
window.close();
|
||||
}
|
||||
);
|
||||
}
|
||||
frm.dashboard.set_headline(__("For more information, {0}.", [`<a target='_blank' href='https://docs.erpnext.com/docs/user/manual/en/CRM/twitter-settings'>${__('click here')}</a>`]));
|
||||
},
|
||||
refresh: function(frm) {
|
||||
let msg, color, flag=false;
|
||||
if (frm.doc.session_status == "Active") {
|
||||
msg = __("Session Active");
|
||||
color = 'green';
|
||||
flag = true;
|
||||
}
|
||||
else if(frm.doc.consumer_key && frm.doc.consumer_secret) {
|
||||
msg = __("Session Not Active. Save doc to login.");
|
||||
color = 'red';
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
frm.dashboard.set_headline_alert(
|
||||
`<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<span class="indicator whitespace-nowrap ${color}"><span class="hidden-xs">${msg}</span></span>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
}
|
||||
},
|
||||
login: function(frm) {
|
||||
if (frm.doc.consumer_key && frm.doc.consumer_secret){
|
||||
frappe.dom.freeze();
|
||||
frappe.call({
|
||||
doc: frm.doc,
|
||||
method: "get_authorize_url",
|
||||
callback : function(r) {
|
||||
window.location.href = r.message;
|
||||
}
|
||||
}).fail(function() {
|
||||
frappe.dom.unfreeze();
|
||||
});
|
||||
}
|
||||
},
|
||||
after_save: function(frm) {
|
||||
frm.trigger("login");
|
||||
}
|
||||
});
|
@ -1,102 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2020-01-30 10:29:08.562108",
|
||||
"doctype": "DocType",
|
||||
"documentation": "https://docs.erpnext.com/docs/user/manual/en/CRM/twitter-settings",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"account_name",
|
||||
"profile_pic",
|
||||
"oauth_details",
|
||||
"consumer_key",
|
||||
"column_break_5",
|
||||
"consumer_secret",
|
||||
"access_token",
|
||||
"access_token_secret",
|
||||
"session_status"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Account Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "oauth_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "OAuth Credentials"
|
||||
},
|
||||
{
|
||||
"fieldname": "consumer_key",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "API Key",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "consumer_secret",
|
||||
"fieldtype": "Password",
|
||||
"in_list_view": 1,
|
||||
"label": "API Secret Key",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "profile_pic",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "session_status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"label": "Session Status",
|
||||
"options": "Expired\nActive",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "access_token",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Access Token",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "access_token_secret",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Access Token Secret",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"image_field": "profile_pic",
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-18 15:18:07.900031",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Twitter 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
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import json
|
||||
|
||||
import frappe
|
||||
import tweepy
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_url_to_form
|
||||
from frappe.utils.file_manager import get_file_path
|
||||
|
||||
|
||||
class TwitterSettings(Document):
|
||||
@frappe.whitelist()
|
||||
def get_authorize_url(self):
|
||||
callback_url = (
|
||||
"{0}/api/method/erpnext.crm.doctype.twitter_settings.twitter_settings.callback?".format(
|
||||
frappe.utils.get_url()
|
||||
)
|
||||
)
|
||||
auth = tweepy.OAuth1UserHandler(
|
||||
self.consumer_key, self.get_password(fieldname="consumer_secret"), callback_url
|
||||
)
|
||||
try:
|
||||
redirect_url = auth.get_authorization_url()
|
||||
return redirect_url
|
||||
except (tweepy.TweepyException, tweepy.HTTPException) as e:
|
||||
frappe.msgprint(_("Error! Failed to get request token."))
|
||||
frappe.throw(
|
||||
_("Invalid {0} or {1}").format(frappe.bold("Consumer Key"), frappe.bold("Consumer Secret Key"))
|
||||
)
|
||||
|
||||
def get_access_token(self, oauth_token, oauth_verifier):
|
||||
auth = tweepy.OAuth1UserHandler(
|
||||
self.consumer_key, self.get_password(fieldname="consumer_secret")
|
||||
)
|
||||
auth.request_token = {"oauth_token": oauth_token, "oauth_token_secret": oauth_verifier}
|
||||
|
||||
try:
|
||||
auth.get_access_token(oauth_verifier)
|
||||
self.access_token = auth.access_token
|
||||
self.access_token_secret = auth.access_token_secret
|
||||
api = self.get_api()
|
||||
user = api.me()
|
||||
profile_pic = (user._json["profile_image_url"]).replace("_normal", "")
|
||||
|
||||
frappe.db.set_value(
|
||||
self.doctype,
|
||||
self.name,
|
||||
{
|
||||
"access_token": auth.access_token,
|
||||
"access_token_secret": auth.access_token_secret,
|
||||
"account_name": user._json["screen_name"],
|
||||
"profile_pic": profile_pic,
|
||||
"session_status": "Active",
|
||||
},
|
||||
)
|
||||
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = get_url_to_form("Twitter Settings", "Twitter Settings")
|
||||
except (tweepy.TweepyException, tweepy.HTTPException) as e:
|
||||
frappe.msgprint(_("Error! Failed to get access token."))
|
||||
frappe.throw(_("Invalid Consumer Key or Consumer Secret Key"))
|
||||
|
||||
def get_api(self):
|
||||
# authentication of consumer key and secret
|
||||
auth = tweepy.OAuth1UserHandler(
|
||||
self.consumer_key, self.get_password(fieldname="consumer_secret")
|
||||
)
|
||||
# authentication of access token and secret
|
||||
auth.set_access_token(self.access_token, self.access_token_secret)
|
||||
|
||||
return tweepy.API(auth)
|
||||
|
||||
def post(self, text, media=None):
|
||||
if not media:
|
||||
return self.send_tweet(text)
|
||||
|
||||
if media:
|
||||
media_id = self.upload_image(media)
|
||||
return self.send_tweet(text, media_id)
|
||||
|
||||
def upload_image(self, media):
|
||||
media = get_file_path(media)
|
||||
api = self.get_api()
|
||||
media = api.media_upload(media)
|
||||
|
||||
return media.media_id
|
||||
|
||||
def send_tweet(self, text, media_id=None):
|
||||
api = self.get_api()
|
||||
try:
|
||||
if media_id:
|
||||
response = api.update_status(status=text, media_ids=[media_id])
|
||||
else:
|
||||
response = api.update_status(status=text)
|
||||
|
||||
return response
|
||||
|
||||
except (tweepy.TweepyException, tweepy.HTTPException) as e:
|
||||
self.api_error(e)
|
||||
|
||||
def delete_tweet(self, tweet_id):
|
||||
api = self.get_api()
|
||||
try:
|
||||
api.destroy_status(tweet_id)
|
||||
except (tweepy.TweepyException, tweepy.HTTPException) as e:
|
||||
self.api_error(e)
|
||||
|
||||
def get_tweet(self, tweet_id):
|
||||
api = self.get_api()
|
||||
try:
|
||||
response = api.get_status(tweet_id, trim_user=True, include_entities=True)
|
||||
except (tweepy.TweepyException, tweepy.HTTPException) as e:
|
||||
self.api_error(e)
|
||||
|
||||
return response._json
|
||||
|
||||
def api_error(self, e):
|
||||
content = json.loads(e.response.content)
|
||||
content = content["errors"][0]
|
||||
if e.response.status_code == 401:
|
||||
self.db_set("session_status", "Expired")
|
||||
frappe.db.commit()
|
||||
frappe.throw(
|
||||
content["message"],
|
||||
title=_("Twitter Error {0} : {1}").format(e.response.status_code, e.response.reason),
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def callback(oauth_token=None, oauth_verifier=None):
|
||||
if oauth_token and oauth_verifier:
|
||||
twitter_settings = frappe.get_single("Twitter Settings")
|
||||
twitter_settings.get_access_token(oauth_token, oauth_verifier)
|
||||
frappe.db.commit()
|
||||
else:
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = get_url_to_form("Twitter Settings", "Twitter Settings")
|
@ -339,6 +339,7 @@ execute:frappe.defaults.clear_default("fiscal_year")
|
||||
erpnext.patches.v15_0.remove_exotel_integration
|
||||
erpnext.patches.v14_0.single_to_multi_dunning
|
||||
execute:frappe.db.set_single_value('Selling Settings', 'allow_negative_rates_for_items', 0)
|
||||
execute:frappe.delete_doc('DocType', 'Twitter Settings', ignore_missing=True)
|
||||
erpnext.patches.v15_0.correct_asset_value_if_je_with_workflow
|
||||
erpnext.patches.v15_0.delete_woocommerce_settings_doctype
|
||||
# below migration patch should always run last
|
||||
|
Loading…
x
Reference in New Issue
Block a user