This repository has been archived by the owner on Apr 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
my_twit.py
266 lines (184 loc) · 9.61 KB
/
my_twit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#!/usr/bin/python
# coding: utf-8
import sys
import os
from PyQt5 import QtGui, QtCore, QtWidgets
import webbrowser
import time
from functions import removeHtml
from twitter.api import Twitter
from twitter.oauth import OAuth, write_token_file, read_token_file
from log import MyLog
import constants
import functions
class MyTwit(QtWidgets.QDialog):
"""Module to authenticate the user on Twitter. Allows to tweet"""
# http://www.adrianjock.com/twitter-myth-url-shorteners/
# https://dev.twitter.com/faq#3
# https://dev.twitter.com/rest/reference/get/help/configuration
def __init__(self, title, link, graphical=None, parent=None):
super(MyTwit, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.parent = parent
# Remove html tags from the title
self.title = removeHtml(title)
self.link = link
self.graphical = graphical
self.resource_dir, self.DATA_PATH = functions.getRightDirs()
if parent is None:
self.l = MyLog("activity.log")
else:
self.l = self.parent.l
self.CONSUMER_KEY = 'IaTVXKtZ7uBjzcVWzsVmMYKtP'
self.CONSUMER_SECRET = '8hsz0Zj3CupFfvJMAhpG3UjMLs7HZjGywRsjRJI8IcjIA4NrEk'
self.MY_TWITTER_CREDS = self.DATA_PATH + '/config/twitter_credentials'
self.initUI()
self.defineSlots()
# If no credentials, try to get them
if not os.path.exists(self.MY_TWITTER_CREDS):
authentified = self.openAuthPage()
# No credentials obtained, exit
if not authentified:
return
self.setTweetText()
self.show()
def openAuthPage(self):
"""Method to open the web page which gives the PIN code for
authentication. When done, verify the pin code and write the
keys into a local file. The user won't have to do the dance each
time he wants to tweet"""
twitter = Twitter(auth=OAuth('', '', self.CONSUMER_KEY,
self.CONSUMER_SECRET),
format='', api_version=None)
token, token_secret = self.parseOauthTokens(twitter.oauth.request_token(oauth_callback="oob"))
self.l.debug("Opening authentication URL")
oauth_url = ('https://api.twitter.com/oauth/authorize?oauth_token=' + token)
try:
r = webbrowser.open(oauth_url)
# Sometimes the last command can print some
# crap. Wait a bit so it doesn't mess up the next
# prompt.
time.sleep(2)
if not r:
raise Exception()
except Exception as e:
QtWidgets.QMessageBox.critical(self, "Authentication", "ChemBrows could not open a web page.\nVisit {} to get the PIN code".format(oauth_url),
QtWidgets.QMessageBox.Ok,defaultButton=QtWidgets.QMessageBox.Ok)
self.l.error("Authentication URL not opened")
self.l.error("openAuthPage: {}".format(e), exc_info=True)
return False
pin = QtWidgets.QInputDialog.getText(self, "PIN verification","Enter the PIN to authenticate yourself")
# If OK wasn't pressed, exit
if not pin[1]:
return False
oauth_verifier = pin[0]
twitter = Twitter(auth=OAuth(token, token_secret, self.CONSUMER_KEY,
self.CONSUMER_SECRET),
format='', api_version=None)
try:
oauth_token, oauth_secret = self.parseOauthTokens(twitter.oauth.access_token(oauth_verifier=oauth_verifier))
except Exception as e:
QtWidgets.QMessageBox.critical(self, "Authentication", "Impossible to obtain tokens",
QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
self.l.error("openAuthPage, no tokens : {}".format(e),
exc_info=True)
return False
self.l.debug("Writing authentication file")
write_token_file(self.MY_TWITTER_CREDS, oauth_token, oauth_secret)
self.twitter = Twitter(auth=OAuth(oauth_token, oauth_secret,
self.CONSUMER_KEY, self.CONSUMER_SECRET))
return True
def parseOauthTokens(self, result):
"""Original function from the twitter.oauth_dance module.
Don't really know what it does (probably parsing)..."""
for r in result.split('&'):
k, v = r.split('=')
if k == 'oauth_token':
oauth_token = v
elif k == 'oauth_token_secret':
oauth_token_secret = v
return oauth_token, oauth_token_secret
def setTweetText(self):
"""Method to shorten the title if it is too long"""
# All links are 23 characters long, even the shorter ones
len_data = 23
# If graphical abstract included, shorten the title of 24 characters
# https://dev.twitter.com/rest/reference/get/help/configuration
try:
if self.check_graphical.checkState() == 2:
len_data += 24
except AttributeError:
pass
LEN_TWEET = constants.LEN_TWEET
# -1 for 1 space, -10 for #ChemBrows
if len(self.title) >= LEN_TWEET - len_data - 1 - 10:
title = self.title[:LEN_TWEET - len_data - 1 - 10 - 3].rstrip()
title += "..."
else:
title = self.title + " "
self.text_tweet.setText(title + self.link)
def postTweet(self):
"""Simple method to post a tweet"""
oauth_token, oauth_secret = read_token_file(self.MY_TWITTER_CREDS)
try:
if self.check_graphical.checkState() == 2:
t_up = Twitter(domain='upload.twitter.com',
auth=OAuth(oauth_token, oauth_secret,
self.CONSUMER_KEY,
self.CONSUMER_SECRET))
with open(self.DATA_PATH + "/graphical_abstracts/{}".format(self.graphical), "rb") as image:
imagedata = image.read()
id_img = t_up.media.upload(media=imagedata)["media_id_string"]
else:
self.l.debug("No image, check box not checked")
id_img = None
except AttributeError:
self.l.debug("No image, no check box at all")
id_img = None
twitter = Twitter(auth=OAuth(oauth_token, oauth_secret,
self.CONSUMER_KEY, self.CONSUMER_SECRET))
text = self.text_tweet.toPlainText() + " #ChemBrows"
if id_img is None:
try:
twitter.statuses.update(status=text)
except Exception as e:
QtWidgets.QMessageBox.critical(self, "Twitter error", "ChemBrows could not tweet that.\nYour tweet is probably too long: {} chara.".format(len(text)),
QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
self.l.error('postTweet: {}'.format(e), exc_info=True)
else:
try:
twitter.statuses.update(status=text, media_ids=id_img)
except Exception as e:
QtWidgets.QMessageBox.critical(self, "Twitter error", "ChemBrows could not tweet that.\nYour tweet is probably too long: {} chara.".format(len(text)),
QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
self.l.error("postTweet: {}".format(e), exc_info=True)
self.close()
def defineSlots(self):
"""Establish the slots"""
# If next pressed, go to next slide
self.ok_button.clicked.connect(self.postTweet)
# Quit the tuto at any moment
self.cancel_button.clicked.connect(self.done)
def initUI(self):
"""Handles the display"""
self.text_tweet = QtWidgets.QTextEdit()
self.cancel_button = QtWidgets.QPushButton("Cancel", self)
self.ok_button = QtWidgets.QPushButton("Tweet me !", self)
self.hbox_buttons = QtWidgets.QHBoxLayout()
self.vbox_global = QtWidgets.QVBoxLayout()
# Display a check box to let the user choose
# if he wants the graphical abstract to be displayed
if self.graphical is not None:
self.check_graphical = QtWidgets.QCheckBox("Include graphical abstract")
self.check_graphical.setCheckState(2)
self.check_graphical.stateChanged.connect(self.setTweetText)
self.hbox_buttons.addWidget(self.check_graphical)
self.hbox_buttons.addWidget(self.cancel_button)
self.hbox_buttons.addWidget(self.ok_button)
self.vbox_global.addWidget(self.text_tweet)
self.vbox_global.addLayout(self.hbox_buttons)
self.setLayout(self.vbox_global)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# obj = MyTwit(parent, "Mesoporous Ni<small><sub>60</sub></small>Fe<small><sub>30</sub></small>Mn<small><sub>10</sub></small>-alloy based metal/metal oxide composite thick films as highly active and robust oxygen evolution catalysts", "http://pubs.rsc.org/en/Content/ArticleLanding/2016/EE/C5EE02509E", "http pubs rsc org services images rscpubs eplatform service freecontent imageservice svc imageservice image ga id c5ee02509e")
obj = MyTwit("<span class=\"hlFld-Title\">Molecular Rift: Virtual Reality for Drug Designers</span>", "http://dx.doi.org/10.1021/acs.jcim.5b00544", "http pubs acs org appl literatum publisher achs journals content jcisd8 0 jcisd8 ahead of print acs jcim 5b00544 20151111 images medium ci 2015 00544d_0015 gif")