diff options
Diffstat (limited to 'scudcloud-1.1/lib/wrapper.py')
-rw-r--r-- | scudcloud-1.1/lib/wrapper.py | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/scudcloud-1.1/lib/wrapper.py b/scudcloud-1.1/lib/wrapper.py new file mode 100644 index 0000000..9d1c348 --- /dev/null +++ b/scudcloud-1.1/lib/wrapper.py @@ -0,0 +1,183 @@ +import sys, subprocess, os, json, tempfile +from urllib import request +from urllib.parse import urlparse +from resources import Resources +from PyQt4 import QtWebKit, QtGui, QtCore +from PyQt4.Qt import QApplication, QKeySequence, QTimer +from PyQt4.QtCore import QBuffer, QByteArray, QUrl +from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings +from PyQt4.QtNetwork import QNetworkProxy + +class Wrapper(QWebView): + + highlights = 0 + icon = None + name = '' + + def __init__(self, window): + self.configure_proxy() + QWebView.__init__(self) + self.window = window + with open(Resources.get_path("scudcloud.js"), "r") as f: + self.js = f.read() + self.setZoomFactor(self.window.zoom) + self.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks) + self.urlChanged.connect(self._urlChanged) + self.loadStarted.connect(self._loadStarted) + self.loadFinished.connect(self._loadFinished) + self.linkClicked.connect(self._linkClicked) + self.page().featurePermissionRequested.connect(self.permissionRequested) + self.addActions() + + def permissionRequested(self, frame, feature): + self.page().setFeaturePermission(frame, feature, QWebPage.PermissionGrantedByUser) + self.overrideNotifications() + + def configure_proxy(self): + proxy = urlparse(os.environ.get('http_proxy') or os.environ.get('HTTP_PROXY')) + if proxy.hostname is not None and proxy.port is not None: + q_network_proxy = QNetworkProxy(QNetworkProxy.HttpProxy, proxy.hostname, proxy.port) + if proxy.username is not None: + q_network_proxy.setUser(proxy.username) + if proxy.password is not None: + q_network_proxy.setPassword(proxy.password) + QNetworkProxy.setApplicationProxy(q_network_proxy) + + def addActions(self): + self.pageAction(QWebPage.SetTextDirectionDefault).setVisible(False) + self.pageAction(QWebPage.SetTextDirectionLeftToRight).setVisible(False) + self.pageAction(QWebPage.SetTextDirectionRightToLeft).setVisible(False) + self.pageAction(QWebPage.Undo).setShortcuts(QKeySequence.Undo) + self.pageAction(QWebPage.Redo).setShortcuts(QKeySequence.Redo) + self.pageAction(QWebPage.Cut).setShortcuts(QKeySequence.Cut) + self.pageAction(QWebPage.Copy).setShortcuts(QKeySequence.Copy) + self.pageAction(QWebPage.Paste).setShortcuts(QKeySequence.Paste) + self.pageAction(QWebPage.Back).setShortcuts(QKeySequence.Back) + self.pageAction(QWebPage.Forward).setShortcuts(QKeySequence.Forward) + self.pageAction(QWebPage.Reload).setShortcuts(QKeySequence.Refresh) + + def contextMenuEvent(self, event): + menu = QtGui.QMenu(self) + if self.window.speller.initialized: + hit = self.page().currentFrame().hitTestContent(event.pos()) + element = hit.element() + if hit.isContentEditable() and not hit.isContentSelected() and element.attribute("type") != "password": + self.window.speller.populateContextMenu(menu, element) + pageMenu = self.page().createStandardContextMenu() + if pageMenu is not None: + for a in pageMenu.actions(): + if a.isSeparator(): + menu.addSeparator() + elif a.isVisible(): + menu.addAction(a) + del pageMenu + menu.exec_(event.globalPos()) + + def call(self, function, arg=None): + if isinstance(arg, str): + arg = "'"+arg+"'" + if arg is None: + arg = "" + return self.page().currentFrame().evaluateJavaScript("ScudCloud."+function+"("+arg+");") + + def _loadStarted(self): + # Some custom CSS to clean/fix UX + self.settings().setUserStyleSheetUrl(QUrl.fromLocalFile(Resources.get_path("resources.css"))) + + def _urlChanged(self, qUrl): + url = qUrl.toString() + # Some integrations/auth will get back to /services with no way to get back to chat + if Resources.SERVICES_URL_RE.match(url): + self.systemOpen(url) + self.load(QUrl("https://"+qUrl.host()+"/messages/general")) + + def _loadFinished(self, ok=True): + # Starting the webkit-JS bridge + self.page().currentFrame().addToJavaScriptWindowObject("desktop", self) + # Loading ScudCloud JS client + self.page().currentFrame().evaluateJavaScript(self.js) + self.window.statusBar().hide() + + def systemOpen(self, url): + subprocess.call(('xdg-open', url)) + + def _linkClicked(self, qUrl): + url = qUrl.toString() + handle_link = ( + Resources.SIGNIN_URL == url or + Resources.MAINPAGE_URL_RE.match(url) or + Resources.MESSAGES_URL_RE.match(url) or + Resources.SSO_URL_RE.match(url) or + url.startswith("https://accounts.google.com/o/oauth")) + if handle_link: + self.load(qUrl) + else: + self.systemOpen(url) + + def preferences(self): + self.window.show() + self.call("preferences") + + def createSnippet(self): + self.call("createSnippet") + + def team(self): + return self.call("getCurrentTeam") + + def logout(self): + self.call("logout") + + def help(self): + self.call("help") + + def helpCenter(self): + subprocess.call(('xdg-open', "https://slack.zendesk.com/hc/en-us")) + + def about(self): + subprocess.call(('xdg-open', "https://github.com/raelgc/scudcloud")) + + def listChannels(self): + return self.call("listChannels") + + def openChannel(self, menuitem, timestamp): + self.call("join", menuitem.property_get("id")) + self.window.show() + + @QtCore.pyqtSlot(int, int) + def count(self, highlight, unread): + self.highlights = highlight + self.window.count() + + @QtCore.pyqtSlot(str) + def populate(self, serialized): + data = json.loads(serialized) + self.window.teams(data['teams']) + if self.window.current() == self: + self.window.quicklist(data['channels']) + self.name = data['teams'][0]['team_name'] + filename, headers = request.urlretrieve(data['icon'], tempfile.gettempdir()+'/'+self.name+'.png') + self.icon = filename + + @QtCore.pyqtSlot(bool) + def enableMenus(self, enabled): + self.window.enableMenus(enabled) + + @QtCore.pyqtSlot(bool) + def pasted(self, checked): + clipboard = QApplication.clipboard() + mime = clipboard.mimeData() + if mime.hasImage(): + pixmap = clipboard.pixmap() + byteArray = QByteArray() + buffer = QBuffer(byteArray) + pixmap.save(buffer, "PNG") + self.call("setClipboard", str(byteArray.toBase64(), sys.stdout.encoding)) + + @QtCore.pyqtSlot(str, str) + def sendMessage(self, title, message): + erase = ['['+self.name.lower()+'] in ', '['+self.name.lower()+'] from '] + for s in erase: + title = str(title).replace(s, '', 1) + self.window.notify(title, str(message), self.icon) + + |