restructuring
This commit is contained in:
parent
8b10203ed3
commit
bafb8db06f
13 changed files with 4 additions and 4 deletions
271
Linux/Bungloo.py
271
Linux/Bungloo.py
|
@ -1,271 +0,0 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
import os, sys, pickle, subprocess, shutil
|
||||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
|
||||
RUNNING_LOCAL = os.path.basename(__file__) == "Bungloo.py"
|
||||
|
||||
if RUNNING_LOCAL:
|
||||
import Windows, Helper
|
||||
else:
|
||||
from bungloo import Windows, Helper
|
||||
|
||||
class Bungloo:
|
||||
|
||||
def __init__(self):
|
||||
self.app = QtGui.QApplication(sys.argv)
|
||||
self.new_message_windows = []
|
||||
self.controller = Controller(self)
|
||||
self.console = Console()
|
||||
|
||||
self.preferences = Windows.Preferences(self)
|
||||
self.preferences.show()
|
||||
|
||||
self.oauth_implementation = Windows.Oauth(self)
|
||||
|
||||
if self.controller.stringForKey("user_access_token") != "":
|
||||
self.authentification_succeded()
|
||||
|
||||
self.app.exec_()
|
||||
|
||||
def resources_path(self):
|
||||
if RUNNING_LOCAL:
|
||||
return os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
else:
|
||||
return Helper.Helper.get_resource_path()
|
||||
|
||||
def resources_uri(self):
|
||||
return "file://localhost/" + os.path.abspath(os.path.join(self.resources_path(), "WebKit"))
|
||||
|
||||
def login_with_entity(self, entity):
|
||||
self.controller.setStringForKey(entity, "entity")
|
||||
self.oauth_implementation.login()
|
||||
|
||||
def authentification_succeded(self):
|
||||
self.preferences.hide()
|
||||
if hasattr(self, "oauth_implementation"):
|
||||
self.oauth_implementation.hide()
|
||||
self.preferences.active(False)
|
||||
self.init_web_views()
|
||||
|
||||
def init_web_views(self):
|
||||
if not hasattr(self, "timeline"):
|
||||
self.timeline = Windows.Timeline(self)
|
||||
else:
|
||||
self.timeline.evaluateJavaScript("start('timeline')")
|
||||
self.timeline.show()
|
||||
self.find_entity = Windows.FindEntity(self)
|
||||
|
||||
def find_entity_show(self):
|
||||
self.find_entity.show()
|
||||
|
||||
def timeline_show(self):
|
||||
self.timeline.show()
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.onTimeline();")
|
||||
|
||||
def mentions_show(self):
|
||||
self.controller.unreadMentions(0)
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.onMentions();")
|
||||
|
||||
def conversation_show(self):
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.onConversation();")
|
||||
|
||||
def profile_show(self):
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.onEntityProfile();")
|
||||
|
||||
def search_show(self):
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.onSearch();")
|
||||
|
||||
def open_about(self):
|
||||
self.controller.openURL("http://jabs.nu/bungloo")
|
||||
|
||||
def log_out(self):
|
||||
self.oauth_implementation.log_out()
|
||||
self.timeline.hide()
|
||||
self.preferences.show()
|
||||
self.timeline.evaluateJavaScript("bungloo.sidebar.logout()")
|
||||
|
||||
|
||||
class Controller(QtCore.QObject):
|
||||
|
||||
def __init__(self, app):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.app = app
|
||||
|
||||
oldpath = os.path.expanduser('~/.bungloo/')
|
||||
if os.path.isdir(oldpath):
|
||||
shutil.copytree(oldpath, os.path.expanduser('~/.config/bungloo/'))
|
||||
shutil.rmtree(os.path.expanduser('~/.bungloo/'))
|
||||
|
||||
if not os.path.exists(os.path.expanduser("~/.config/bungloo/")):
|
||||
os.makedirs(os.path.expanduser("~/.config/bungloo/"))
|
||||
|
||||
self.config_path = os.path.expanduser('~/.config/bungloo/bungloo.cfg')
|
||||
|
||||
if os.access(self.config_path, os.R_OK):
|
||||
with open(self.config_path, 'r') as f:
|
||||
self.config = pickle.load(f)
|
||||
else:
|
||||
print self.config_path + " is not readable"
|
||||
self.config = {}
|
||||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def setStringForKey(self, string, key):
|
||||
string, key = str(string), str(key)
|
||||
self.config[key] = string
|
||||
try:
|
||||
with open(self.config_path, 'w+') as f:
|
||||
pickle.dump(self.config, f)
|
||||
except IOError as e:
|
||||
print self.config_path + " is not writable"
|
||||
print "I/O error({0}): {1}".format(e.errno, e.strerror)
|
||||
|
||||
@QtCore.pyqtSlot(str, result=str)
|
||||
def stringForKey(self, key):
|
||||
key = str(key)
|
||||
if key in self.config:
|
||||
return self.config[key]
|
||||
else:
|
||||
return ""
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def openAuthorizationURL(self, url):
|
||||
self.app.oauth_implementation.handle_authentication(str(url))
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def openURL(self, url):
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))
|
||||
|
||||
def openQURL(self, url):
|
||||
QtGui.QDesktopServices.openUrl(url)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
def loggedIn(self):
|
||||
self.app.authentification_succeded()
|
||||
|
||||
@QtCore.pyqtSlot(int)
|
||||
def unreadMentions(self, count):
|
||||
script = "bungloo.sidebar.setUnreadMentions({});".format(int(count))
|
||||
self.app.timeline.evaluateJavaScript(script)
|
||||
|
||||
@QtCore.pyqtSlot(str, str, str, str)
|
||||
def notificateUserAboutMentionFromNameWithPostIdAndEntity(self, text, name, post_id, entity):
|
||||
try:
|
||||
subprocess.check_output(['kdialog', '--passivepopup', name + ' mentioned you: ' + text])
|
||||
except OSError:
|
||||
try:
|
||||
subprocess.check_output(['notify-send', '-i', 'dialog-information', name + ' mentioned you on Tent', text])
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def openNewMessageWidow(self, string):
|
||||
new_message_window = Windows.NewPost(self.app)
|
||||
new_message_window.show()
|
||||
new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||
self.app.new_message_windows.append(new_message_window)
|
||||
|
||||
@QtCore.pyqtSlot(str, str, str, bool)
|
||||
def openNewMessageWindowInReplyTostatusIdwithStringIsPrivate(self, entity, status_id, string, is_private):
|
||||
new_message_window = Windows.NewPost(self.app)
|
||||
new_message_window.inReplyToStatusIdWithString(entity, status_id, string)
|
||||
new_message_window.setIsPrivate(is_private)
|
||||
new_message_window.show()
|
||||
new_message_window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||
self.app.new_message_windows.append(new_message_window)
|
||||
|
||||
def sendMessage(self, message):
|
||||
text = message.text
|
||||
text = unicode.replace(text, "\\", "\\\\")
|
||||
text = unicode.replace(text, "\"", "\\\"")
|
||||
text = unicode.replace(text, "\n", "\\n")
|
||||
|
||||
in_reply_to_status_id = ""
|
||||
if message.inReplyTostatusId is not None:
|
||||
in_reply_to_status_id = message.inReplyTostatusId
|
||||
|
||||
in_reply_to_entity = ""
|
||||
if message.inReplyToEntity is not None:
|
||||
in_reply_to_entity = message.inReplyToEntity
|
||||
|
||||
locationObject = "null"
|
||||
#if (post.location) {
|
||||
# locationObject = [NSString stringWithFormat:@"[%f, %f]", post.location.coordinate.latitude, post.location.coordinate.longitude];
|
||||
#}
|
||||
|
||||
imageFilePath = "null"
|
||||
if message.imageFilePath is not None:
|
||||
mimeType = subprocess.check_output(['file', '-b', '--mime', message.imageFilePath]).split(";")[0]
|
||||
base64 = open(message.imageFilePath, "rb").read().encode("base64").replace("\n", "")
|
||||
imageFilePath = "\"data:{};base64,{}\"".format(mimeType, base64)
|
||||
|
||||
isPrivate = "false";
|
||||
if message.isPrivate:
|
||||
isPrivate = "true"
|
||||
|
||||
func = u"bungloo.timeline.sendNewMessage(\"{}\", \"{}\", \"{}\", {}, {}, {});".format(text, in_reply_to_status_id, in_reply_to_entity, locationObject, imageFilePath, isPrivate)
|
||||
self.app.timeline.evaluateJavaScript(func)
|
||||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def showConversationForPostIdandEntity(self, postId, entity):
|
||||
func = "bungloo.sidebar.onConversation(); bungloo.conversation.showStatus('{}', '{}');".format(postId, entity)
|
||||
self.app.timeline.evaluateJavaScript(func)
|
||||
self.app.timeline.show()
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def showProfileForEntity(self, entity):
|
||||
func = "bungloo.sidebar.onEntityProfile(); bungloo.entityProfile.showProfileForEntity('{}');".format(entity)
|
||||
self.app.timeline.evaluateJavaScript(func)
|
||||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def notificateViewsAboutDeletedPostWithIdbyEntity(self, post_id, entity):
|
||||
f = ".postDeleted('{}', '{}')".format(post_id, entity);
|
||||
func = "bungloo.timeline" + f + ";"
|
||||
func += "bungloo.mentions" + f + ";"
|
||||
func += "bungloo.conversation" + f + ";"
|
||||
func += "bungloo.entityProfile" + f + ";"
|
||||
|
||||
self.app.timeline.evaluateJavaScript(func)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def authentificationDidNotSucceed(self, errorMessage):
|
||||
msgBox = QtGui.QMessageBox()
|
||||
msgBox.setText(errorMessage)
|
||||
msgBox.exec_()
|
||||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def alertTitleWithMessage(self, title, message):
|
||||
msgBox = QtGui.QMessageBox()
|
||||
msgBox.setText(title)
|
||||
msgBox.setInformativeText(message)
|
||||
msgBox.exec_()
|
||||
|
||||
def logout(self, sender):
|
||||
print "logout is not implemented yet"
|
||||
|
||||
|
||||
class Console(QtCore.QObject):
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def log(self, string):
|
||||
print "<js>: " + unicode(string)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def error(self, string):
|
||||
print "<js ERROR>: " + unicode(string)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def warn(self, string):
|
||||
print "<js WARN>: " + unicode(string)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def notice(self, string):
|
||||
print "<js NOTICE>: " + unicode(string)
|
||||
|
||||
@QtCore.pyqtSlot(str)
|
||||
def debug(self, string):
|
||||
print "<js DEBUG>: " + unicode(string)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Bungloo()
|
160
Linux/Helper.py
160
Linux/Helper.py
|
@ -1,160 +0,0 @@
|
|||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
|
||||
from PyQt4.QtCore import QTimer, QVariant, SIGNAL
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||
from PyQt4.QtWebKit import QWebView
|
||||
|
||||
import os
|
||||
|
||||
import array
|
||||
|
||||
class Helper:
|
||||
@classmethod
|
||||
def get_resource_path(cls):
|
||||
return os.path.dirname(__file__)
|
||||
|
||||
class WebPage(QtWebKit.QWebPage):
|
||||
def __init__(self, parent=0, app=None):
|
||||
super(QtWebKit.QWebPage, self).__init__(parent)
|
||||
self.setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateExternalLinks)
|
||||
self.app = app
|
||||
|
||||
def javaScriptConsoleMessage(self, message, lineNumber, sourceId):
|
||||
print str(message) + " on line: " + str(lineNumber) + " Source: " + str(sourceId)
|
||||
|
||||
def checkRequest(self, request):
|
||||
print request
|
||||
|
||||
|
||||
class WebViewCreator(QtWebKit.QWebView):
|
||||
def __init__(self, app, local=True, parent=None):
|
||||
if parent != None:
|
||||
QtGui.QWidget.__init__(self)
|
||||
else:
|
||||
QtGui.QWidget.__init__(self)
|
||||
|
||||
self.app = app
|
||||
self.is_local = local
|
||||
self.connect(self, SIGNAL("linkClicked (const QUrl&)"), self.app.controller.openQURL)
|
||||
self.setPage(WebPage(self, self.app))
|
||||
|
||||
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self.customContextMenuRequested.connect(self.context_menu_requested)
|
||||
self.actions = []
|
||||
|
||||
def copy_link():
|
||||
self.page().triggerAction(QtWebKit.QWebPage.CopyLinkToClipboard)
|
||||
self.action_copy_link = QtGui.QAction('Copy Lin&k', self, triggered=copy_link)
|
||||
|
||||
def context_menu_requested(self, point):
|
||||
context_menu = QtGui.QMenu()
|
||||
|
||||
for action in self.actions:
|
||||
if action.isEnabled():
|
||||
context_menu.addAction(action)
|
||||
|
||||
frame = self.page().currentFrame()
|
||||
|
||||
hit_test = frame.hitTestContent(point)
|
||||
if unicode(hit_test.linkUrl().toString()):
|
||||
context_menu.addAction(self.action_copy_link)
|
||||
|
||||
if self.settings().testAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled):
|
||||
context_menu.addSeparator()
|
||||
context_menu.addAction(self.pageAction(QtWebKit.QWebPage.InspectElement))
|
||||
|
||||
context_menu.exec_(self.mapToGlobal(point))
|
||||
|
||||
def load_local(self, callback=None):
|
||||
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True)
|
||||
self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalStorageEnabled, True)
|
||||
self.loadFinished.connect(lambda ok: self.load_finished(ok, callback))
|
||||
|
||||
frame = self.page().mainFrame()
|
||||
frame.addToJavaScriptWindowObject("controller", self.app.controller)
|
||||
frame.addToJavaScriptWindowObject("__console", self.app.console)
|
||||
|
||||
url = self.app.resources_uri() + "/index.html"
|
||||
self.load(QtCore.QUrl(url))
|
||||
|
||||
def load_url(self, url, callback=None):
|
||||
self.loadFinished.connect(lambda ok: self.load_finished(ok, callback))
|
||||
self.load(QtCore.QUrl(url))
|
||||
|
||||
def load_finished(self, ok, callback=None):
|
||||
frame = self.page().mainFrame()
|
||||
if self.is_local:
|
||||
frame.evaluateJavaScript("var OS_TYPE = 'linux';")
|
||||
|
||||
js_plugin_path = os.path.expanduser('~/.bungloo/Plugin.js')
|
||||
if os.access(js_plugin_path, os.R_OK):
|
||||
func = "setTimeout(function() { loadJsPlugin('file://localhost/" + js_plugin_path + "') }, 1000);"
|
||||
frame.evaluateJavaScript(func)
|
||||
|
||||
css_plugin_path = os.path.expanduser('~/.bungloo/Plugin.css')
|
||||
if os.access(css_plugin_path, os.R_OK):
|
||||
func = "setTimeout(function() { loadCssPlugin('file://localhost/" + css_plugin_path + "') }, 1000);"
|
||||
frame.evaluateJavaScript(func)
|
||||
|
||||
if callback:
|
||||
callback(ok)
|
||||
|
||||
|
||||
class NetworkAccessManager(QNetworkAccessManager):
|
||||
|
||||
def __init__(self, old_manager, bungloo_callback):
|
||||
QNetworkAccessManager.__init__(self)
|
||||
|
||||
self.bungloo_callback = bungloo_callback
|
||||
|
||||
self.old_manager = old_manager
|
||||
self.setCache(old_manager.cache())
|
||||
self.setCookieJar(old_manager.cookieJar())
|
||||
self.setProxy(old_manager.proxy())
|
||||
self.setProxyFactory(old_manager.proxyFactory())
|
||||
|
||||
def createRequest(self, operation, request, data):
|
||||
if request.url().scheme() != "bungloo":
|
||||
return QNetworkAccessManager.createRequest(self, operation, request, data)
|
||||
else:
|
||||
self.bungloo_callback(request.url())
|
||||
return QNetworkAccessManager.createRequest(self, QNetworkAccessManager.GetOperation, QNetworkRequest(QtCore.QUrl()))
|
||||
|
||||
class PostModel:
|
||||
|
||||
def __init__(self):
|
||||
self.text = None
|
||||
self.inReplyTostatusId = None
|
||||
self.inReplyToEntity = None
|
||||
self.location = None
|
||||
self.imageFilePath = None
|
||||
self.isPrivate = False
|
||||
|
||||
class RestorableWindow(QtGui.QMainWindow):
|
||||
|
||||
def __init__(self, action, app):
|
||||
self.action = action
|
||||
self.app = app
|
||||
QtGui.QMainWindow.__init__(self)
|
||||
self.restoreGeometry(QtCore.QByteArray.fromRawData(self.app.controller.stringForKey("mainWindowGeometry-" + self.action)))
|
||||
self.restoreState(QtCore.QByteArray.fromRawData(self.app.controller.stringForKey("mainWindowState-" + self.action)))
|
||||
|
||||
def closeEvent(self, event):
|
||||
self._saveGeometry()
|
||||
|
||||
def _saveGeometry(self):
|
||||
self.app.controller.setStringForKey(self.saveGeometry(), "mainWindowGeometry-" + self.action)
|
||||
self.app.controller.setStringForKey(self.saveState(), "mainWindowState-" + self.action)
|
||||
|
||||
def hide(self):
|
||||
self._saveGeometry()
|
||||
QtGui.QMainWindow.close(self)
|
||||
|
||||
def sizeHint(self):
|
||||
return QtCore.QSize(300, 500)
|
||||
|
||||
def show(self):
|
||||
QtGui.QMainWindow.show(self)
|
||||
self.activateWindow()
|
||||
self.raise_()
|
459
Linux/Windows.py
459
Linux/Windows.py
|
@ -1,459 +0,0 @@
|
|||
from PyQt4 import QtCore, QtGui, QtWebKit
|
||||
import Helper, urllib, urllib2
|
||||
|
||||
class Preferences:
|
||||
|
||||
def __init__(self, app):
|
||||
|
||||
self.app = app
|
||||
|
||||
# window
|
||||
self.window = QtGui.QMainWindow()
|
||||
self.window.setWindowTitle("Preferences")
|
||||
self.window.resize(480, 186)
|
||||
self.window.setMinimumSize(480, 186)
|
||||
self.window.setMaximumSize(480, 186)
|
||||
|
||||
# image view
|
||||
image = QtGui.QPixmap(self.app.resources_path() + "/images/Icon.png")
|
||||
image_view = QtGui.QLabel(self.window)
|
||||
image_view.setGeometry(20, 20, 146, 146)
|
||||
image_view.setPixmap(image)
|
||||
image_view.setScaledContents(True)
|
||||
|
||||
self.window.setWindowIcon(QtGui.QIcon(image))
|
||||
|
||||
# info text
|
||||
info_text = QtGui.QLabel(self.window)
|
||||
info_text.setGeometry(194, 60, 262, 17)
|
||||
info_text.setText("Add your entity to log in:")
|
||||
|
||||
# login button
|
||||
button = QtGui.QPushButton(self.window)
|
||||
button.setText("Login")
|
||||
button.setGeometry(390, 109, 72, 32)
|
||||
button.setAutoDefault(True)
|
||||
self.window.connect(button, QtCore.SIGNAL('clicked()'), self.on_login_button_clicked)
|
||||
|
||||
# text field
|
||||
self.text_field = QtGui.QLineEdit(self.window)
|
||||
self.text_field.setPlaceholderText("https://example.tent.is")
|
||||
self.text_field.setGeometry(194, 84, 262, 22)
|
||||
self.window.connect(self.text_field, QtCore.SIGNAL('returnPressed()'), self.on_login_button_clicked)
|
||||
entity = self.app.controller.stringForKey("entity")
|
||||
if entity:
|
||||
self.text_field.setText(entity)
|
||||
|
||||
# activity_indicator
|
||||
self.activity_indicator = QtGui.QProgressBar(self.window)
|
||||
self.activity_indicator.setMinimum(0)
|
||||
self.activity_indicator.setMaximum(0)
|
||||
self.activity_indicator.setGeometry(310, 114, 72, 22)
|
||||
|
||||
self.active(False)
|
||||
|
||||
|
||||
def quit(self, wiget, foo):
|
||||
self.window.hide()
|
||||
self.app.quit(self)
|
||||
|
||||
def on_login_button_clicked(self):
|
||||
self.active(True)
|
||||
self.app.login_with_entity(self.text_field.text())
|
||||
|
||||
def show(self):
|
||||
self.window.show()
|
||||
|
||||
def hide(self):
|
||||
self.window.hide()
|
||||
|
||||
def active(self, active):
|
||||
if active:
|
||||
self.activity_indicator.show()
|
||||
else:
|
||||
self.activity_indicator.hide()
|
||||
|
||||
|
||||
class Timeline:
|
||||
|
||||
def __init__(self, app, action="timeline", title="Bungloo"):
|
||||
self.app = app
|
||||
self.action = action
|
||||
self.title = title
|
||||
|
||||
self.window = Helper.RestorableWindow(action, self.app)
|
||||
self.window.setWindowTitle(title)
|
||||
self.window.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png"))
|
||||
|
||||
self.webView = Helper.WebViewCreator(self.app, True, self.window)
|
||||
self.webView.load_local(self.load_finished)
|
||||
self.window.setCentralWidget(self.webView)
|
||||
|
||||
self.initUI()
|
||||
|
||||
self.webView.triggerPageAction(QtWebKit.QWebPage.InspectElement)
|
||||
|
||||
def moveWindow(self, x=0, y=0):
|
||||
self.show()
|
||||
geo = self.window.geometry()
|
||||
self.window.move(geo.x() + x, geo.y() + y)
|
||||
self.hide()
|
||||
|
||||
|
||||
def initUI(self):
|
||||
menubar = self.window.menuBar()
|
||||
|
||||
newPostAction = QtGui.QAction("&New Post", self.window)
|
||||
newPostAction.setShortcut("Ctrl+N")
|
||||
newPostAction.setStatusTip("Open new post window")
|
||||
newPostAction.triggered.connect(self.app.controller.openNewMessageWidow)
|
||||
|
||||
findEntityAction = QtGui.QAction("&Open Profile for Entity ...", self.window)
|
||||
findEntityAction.setShortcut("Ctrl+u")
|
||||
findEntityAction.setStatusTip("Find entity and open its profile view")
|
||||
findEntityAction.triggered.connect(self.app.find_entity_show)
|
||||
|
||||
logOutAction = QtGui.QAction("&Log Out", self.window)
|
||||
logOutAction.setStatusTip("Log out from this entity")
|
||||
logOutAction.triggered.connect(self.app.log_out)
|
||||
|
||||
exitAction = QtGui.QAction("&Exit", self.window)
|
||||
exitAction.setShortcut("Ctrl+Q")
|
||||
exitAction.setStatusTip("Exit Bungloo")
|
||||
exitAction.triggered.connect(QtGui.qApp.quit)
|
||||
|
||||
fileMenu = menubar.addMenu("&File")
|
||||
fileMenu.addAction(newPostAction)
|
||||
fileMenu.addAction(findEntityAction)
|
||||
fileMenu.addSeparator()
|
||||
fileMenu.addAction(logOutAction)
|
||||
fileMenu.addAction(exitAction)
|
||||
|
||||
timelineAction = QtGui.QAction("&Timeline", self.window)
|
||||
timelineAction.setShortcut("Ctrl+1")
|
||||
timelineAction.setStatusTip("Show Timeline")
|
||||
timelineAction.triggered.connect(self.app.timeline_show)
|
||||
|
||||
mentionsAction = QtGui.QAction("&Mentions", self.window)
|
||||
mentionsAction.setShortcut("Ctrl+2")
|
||||
mentionsAction.setStatusTip("Show Mentions")
|
||||
mentionsAction.triggered.connect(self.app.mentions_show)
|
||||
|
||||
conversationAction = QtGui.QAction("&Conversation", self.window)
|
||||
conversationAction.setShortcut("Ctrl+3")
|
||||
conversationAction.setStatusTip("Show Conversation")
|
||||
conversationAction.triggered.connect(self.app.conversation_show)
|
||||
|
||||
profileAction = QtGui.QAction("&Profile", self.window)
|
||||
profileAction.setShortcut("Ctrl+4")
|
||||
profileAction.setStatusTip("Show Profile")
|
||||
profileAction.triggered.connect(self.app.profile_show)
|
||||
|
||||
searchAction = QtGui.QAction("&Search", self.window)
|
||||
searchAction.setShortcut("Ctrl+5")
|
||||
searchAction.setStatusTip("Show Search")
|
||||
searchAction.triggered.connect(self.app.search_show)
|
||||
|
||||
windowMenu = menubar.addMenu("&View")
|
||||
windowMenu.addAction(timelineAction)
|
||||
windowMenu.addAction(mentionsAction)
|
||||
windowMenu.addAction(conversationAction)
|
||||
windowMenu.addAction(profileAction)
|
||||
windowMenu.addAction(searchAction)
|
||||
|
||||
aboutAction = QtGui.QAction("&About Bungloo", self.window)
|
||||
aboutAction.setStatusTip("Open about page in Webbrowser")
|
||||
aboutAction.triggered.connect(self.app.open_about)
|
||||
|
||||
developerExtrasAction = QtGui.QAction("&Developer Extras", self.window)
|
||||
developerExtrasAction.setStatusTip("Activate webkit inspector")
|
||||
developerExtrasAction.triggered.connect(self.developer_extras)
|
||||
|
||||
helpMenu = menubar.addMenu("&Help")
|
||||
helpMenu.addAction(aboutAction)
|
||||
helpMenu.addAction(developerExtrasAction)
|
||||
|
||||
def show(self):
|
||||
self.window.show()
|
||||
#self.window.raise_()
|
||||
#QtGui.qApp.setActiveWindow(self.window)
|
||||
def close(self):
|
||||
self.window.close()
|
||||
|
||||
def hide(self):
|
||||
self.window.hide()
|
||||
|
||||
def load_finished(self, widget):
|
||||
script = "function HostAppGo() { start('" + self.action + "'); }"
|
||||
self.webView.page().mainFrame().evaluateJavaScript(script)
|
||||
|
||||
def set_window_title(self, title):
|
||||
self.window.setWindowTitle(title)
|
||||
|
||||
def evaluateJavaScript(self, func):
|
||||
return self.webView.page().mainFrame().evaluateJavaScript(func)
|
||||
|
||||
def developer_extras(self, widget):
|
||||
QtWebKit.QWebSettings.globalSettings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
|
||||
|
||||
|
||||
class Oauth:
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.core = Helper.WebViewCreator(self.app)
|
||||
self.core.load_local(self.load_finished)
|
||||
|
||||
def load_finished(self, ok):
|
||||
if ok:
|
||||
script = "function HostAppGo() { start('oauth'); }"
|
||||
self.core.page().mainFrame().evaluateJavaScript(script)
|
||||
|
||||
def login(self):
|
||||
script = "bungloo.oauth.authenticate();"
|
||||
self.core.page().mainFrame().evaluateJavaScript(script)
|
||||
|
||||
def log_out(self):
|
||||
script = "bungloo.oauth.logout()";
|
||||
self.core.page().mainFrame().evaluateJavaScript(script)
|
||||
|
||||
def handle_authentication(self, url):
|
||||
self.auth_view = Helper.WebViewCreator(self.app)
|
||||
self.auth_view.setWindowTitle("Authentication")
|
||||
|
||||
old_manager = self.auth_view.page().networkAccessManager()
|
||||
new_manager = Helper.NetworkAccessManager(old_manager, self.bungloo_callback)
|
||||
new_manager.authenticationRequired.connect(self.authentication_required)
|
||||
self.auth_view.page().setNetworkAccessManager(new_manager)
|
||||
self.auth_view.show()
|
||||
self.auth_view.load_url(url)
|
||||
return False
|
||||
|
||||
def authentication_required(self, reply, authenticator):
|
||||
|
||||
dialog = Login()
|
||||
|
||||
def callback():
|
||||
authenticator.setUser(dialog.textName.text())
|
||||
authenticator.setPassword(dialog.textPass.text())
|
||||
|
||||
dialog.setInfo(reply.url(), authenticator.realm())
|
||||
dialog.accepted.connect(callback)
|
||||
|
||||
dialog.exec_()
|
||||
|
||||
def bungloo_callback(self, url):
|
||||
script = "bungloo.oauth.requestAccessToken('" + url.toString() + "');"
|
||||
self.core.page().mainFrame().evaluateJavaScript(script)
|
||||
|
||||
def hide(self):
|
||||
if hasattr(self, "auth_view"):
|
||||
self.auth_view.hide()
|
||||
|
||||
|
||||
class Login(QtGui.QDialog):
|
||||
def __init__(self):
|
||||
QtGui.QDialog.__init__(self)
|
||||
self.setWindowTitle("Login")
|
||||
|
||||
self.label = QtGui.QLabel(self)
|
||||
self.label.setText("The Server requires a username and password.")
|
||||
|
||||
self.textName = QtGui.QLineEdit(self)
|
||||
|
||||
self.textPass = QtGui.QLineEdit(self)
|
||||
self.textPass.setEchoMode(QtGui.QLineEdit.Password);
|
||||
#self.textPass.setInputMethodHints(Qt.ImhHiddenText | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase)
|
||||
|
||||
self.buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok)
|
||||
self.buttons.accepted.connect(self.accept)
|
||||
|
||||
layout = QtGui.QVBoxLayout(self)
|
||||
layout.addWidget(self.label)
|
||||
layout.addWidget(self.textName)
|
||||
layout.addWidget(self.textPass)
|
||||
layout.addWidget(self.buttons)
|
||||
|
||||
def setInfo(self, url, realm):
|
||||
pass
|
||||
#self.buttonLogin.clicked.connect(callback)
|
||||
#self.label.setText("The server " + url.host() + " requires a username and password.")
|
||||
|
||||
class FindEntity(QtGui.QDialog):
|
||||
def __init__(self, app):
|
||||
QtGui.QDialog.__init__(self)
|
||||
|
||||
self.app = app
|
||||
|
||||
self.setWindowTitle("Open Profile ...")
|
||||
self.label = QtGui.QLabel(self)
|
||||
self.label.setText("Open the profile of the entity:")
|
||||
|
||||
self.textEntity = QtGui.QLineEdit(self)
|
||||
|
||||
self.button = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok)
|
||||
self.button.accepted.connect(self.openProfile)
|
||||
|
||||
layout = QtGui.QVBoxLayout(self)
|
||||
layout.addWidget(self.label)
|
||||
layout.addWidget(self.textEntity)
|
||||
layout.addWidget(self.button)
|
||||
|
||||
def openProfile(self):
|
||||
self.app.controller.showProfileForEntity(self.textEntity.text())
|
||||
self.hide()
|
||||
|
||||
|
||||
class NewPost(Helper.RestorableWindow):
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
Helper.RestorableWindow.__init__(self, "newpost", self.app)
|
||||
|
||||
self.setWindowIcon(QtGui.QIcon(self.app.resources_path() + "/images/Icon.png"))
|
||||
|
||||
self.textInput = QtGui.QPlainTextEdit(self)
|
||||
self.setCentralWidget(self.textInput)
|
||||
self.textInput.textChanged.connect(self.onChanged)
|
||||
|
||||
self.setWindowTitle("New Post")
|
||||
self.resize(300, 150)
|
||||
self.setMinimumSize(100, 100)
|
||||
self.initUI()
|
||||
|
||||
self.setIsPrivate(False)
|
||||
self.status_id = None
|
||||
self.reply_to_entity = None
|
||||
self.imageFilePath = None
|
||||
|
||||
def initUI(self):
|
||||
newPostAction = QtGui.QAction("&New Post", self)
|
||||
newPostAction.setShortcut("Ctrl+N")
|
||||
newPostAction.setStatusTip("Open new post window")
|
||||
newPostAction.triggered.connect(self.app.controller.openNewMessageWidow)
|
||||
|
||||
sendPostAction = QtGui.QAction("&Send Post", self)
|
||||
sendPostAction.setShortcut("Ctrl+Return")
|
||||
sendPostAction.setStatusTip("Send post")
|
||||
sendPostAction.triggered.connect(self.sendMessage)
|
||||
|
||||
hideAction = QtGui.QAction("&Close Window", self)
|
||||
hideAction.setShortcut("Ctrl+W")
|
||||
hideAction.setStatusTip("Close this window")
|
||||
hideAction.triggered.connect(self.close)
|
||||
|
||||
exitAction = QtGui.QAction("&Exit", self)
|
||||
exitAction.setShortcut("Ctrl+Q")
|
||||
exitAction.setStatusTip("Exit Bungloo")
|
||||
exitAction.triggered.connect(QtGui.qApp.quit)
|
||||
|
||||
menubar = self.menuBar()
|
||||
fileMenu = menubar.addMenu("&File")
|
||||
fileMenu.addAction(newPostAction)
|
||||
fileMenu.addAction(sendPostAction)
|
||||
fileMenu.addAction(hideAction)
|
||||
fileMenu.addSeparator()
|
||||
fileMenu.addAction(exitAction)
|
||||
|
||||
togglePrivateAction = QtGui.QAction("&Toggle Private", self)
|
||||
togglePrivateAction.setShortcut("Ctrl+P")
|
||||
togglePrivateAction.setStatusTip("Toogle if private post")
|
||||
togglePrivateAction.triggered.connect(self.toggleIsPrivate)
|
||||
|
||||
addImageAction = QtGui.QAction("Add &Image", self)
|
||||
addImageAction.setShortcut("Ctrl+I")
|
||||
addImageAction.setStatusTip("Add image to post")
|
||||
addImageAction.triggered.connect(self.openFileDialog)
|
||||
|
||||
editMenu = menubar.addMenu("&Edit")
|
||||
editMenu.addAction(togglePrivateAction)
|
||||
editMenu.addAction(addImageAction)
|
||||
|
||||
aboutAction = QtGui.QAction("&About Bungloo", self)
|
||||
aboutAction.setStatusTip("Open about page in Webbrowser")
|
||||
aboutAction.triggered.connect(self.app.open_about)
|
||||
|
||||
helpMenu = menubar.addMenu("&Help")
|
||||
helpMenu.addAction(aboutAction)
|
||||
|
||||
|
||||
self.statusBar().showMessage('256')
|
||||
|
||||
self.addButton = QtGui.QToolButton()
|
||||
self.addButton.setToolTip("Add photo")
|
||||
self.addButton.clicked.connect(self.openFileDialog)
|
||||
self.addButton.setAutoRaise(True)
|
||||
#addIcon = QtGui.QIcon.fromTheme("insert-image", QtGui.QIcon(self.app.resources_path() + "/images/Actions-insert-image-icon.png"))
|
||||
addIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_138_picture.png")
|
||||
self.addButton.setIcon(addIcon)
|
||||
self.statusBar().addPermanentWidget(self.addButton)
|
||||
|
||||
self.isPrivateButton = QtGui.QToolButton()
|
||||
self.isPrivateButton.setToolTip("Make private")
|
||||
self.isPrivateButton.clicked.connect(self.toggleIsPrivate)
|
||||
self.isPrivateButton.setAutoRaise(True)
|
||||
#self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Lock-icon.png")
|
||||
self.isPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_203_lock.png")
|
||||
#self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/Lock-Unlock-icon.png")
|
||||
self.isNotPrivateIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_204_unlock.png")
|
||||
self.isPrivateButton.setIcon(self.isNotPrivateIcon)
|
||||
self.statusBar().addPermanentWidget(self.isPrivateButton)
|
||||
|
||||
self.sendButton = QtGui.QToolButton()
|
||||
self.sendButton.setToolTip("Send")
|
||||
self.sendButton.clicked.connect(self.sendMessage)
|
||||
self.sendButton.setAutoRaise(True)
|
||||
#sendIcon = QtGui.QIcon.fromTheme("mail-send", QtGui.QIcon(self.app.resources_path() + "/images/send-icon.png"))
|
||||
sendIcon = QtGui.QIcon(self.app.resources_path() + "/images/glyphicons_123_message_out.png")
|
||||
self.sendButton.setIcon(sendIcon)
|
||||
self.statusBar().addPermanentWidget(self.sendButton)
|
||||
|
||||
def setIsPrivate(self, is_private):
|
||||
self.isPrivate = is_private
|
||||
icon = self.isNotPrivateIcon
|
||||
if self.isPrivate:
|
||||
icon = self.isPrivateIcon
|
||||
|
||||
self.isPrivateButton.setIcon(icon)
|
||||
|
||||
def toggleIsPrivate(self):
|
||||
self.setIsPrivate(not self.isPrivate)
|
||||
|
||||
def inReplyToStatusIdWithString(self, reply_to, status_id, string):
|
||||
self.reply_to_entity = reply_to
|
||||
self.status_id = status_id
|
||||
self.textInput.setPlainText(string)
|
||||
|
||||
cursor = self.textInput.textCursor()
|
||||
cursor.movePosition(QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor)
|
||||
cursor.movePosition(QtGui.QTextCursor.Start, QtGui.QTextCursor.KeepAnchor)
|
||||
cursor.movePosition(QtGui.QTextCursor.EndOfLine, QtGui.QTextCursor.KeepAnchor)
|
||||
self.textInput.setTextCursor(cursor)
|
||||
|
||||
def onChanged(self):
|
||||
count = 256 - len(self.textInput.toPlainText())
|
||||
self.statusBar().showMessage(str(count))
|
||||
|
||||
def sendMessage(self):
|
||||
count = len(self.textInput.toPlainText())
|
||||
if count > 0 and count <= 256:
|
||||
message = Helper.PostModel()
|
||||
message.text = unicode(self.textInput.toPlainText().toUtf8(), "utf-8")
|
||||
message.inReplyTostatusId = self.status_id
|
||||
message.inReplyToEntity = self.reply_to_entity
|
||||
message.location = None
|
||||
message.imageFilePath = self.imageFilePath
|
||||
message.isPrivate = self.isPrivate
|
||||
self.app.controller.sendMessage(message)
|
||||
self.close()
|
||||
else:
|
||||
QtGui.qApp.beep()
|
||||
|
||||
def openFileDialog(self):
|
||||
fileNamePath = QtGui.QFileDialog.getOpenFileName(self, "Choose a image", "", "Images (*.png *.gif *.jpg *.jpeg)")
|
||||
if len(fileNamePath) > 0:
|
||||
self.imageFilePath = str(fileNamePath)
|
||||
else:
|
||||
self.imageFilePath = None
|
||||
|
||||
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
VERSION="1.3.0"
|
||||
DEPLOYPATH="bungloo-${VERSION}"
|
||||
LINUXPATH=".."
|
||||
SHAREDPATH="../.."
|
||||
QTPATH="../Qt"
|
||||
SHAREDPATH=".."
|
||||
DISTPATH=dist
|
||||
|
||||
rm -rf $DEPLOYPATH
|
||||
|
@ -14,8 +14,8 @@ mkdir -p $DEPLOYPATH/bin
|
|||
mkdir -p $DEPLOYPATH/bungloo
|
||||
touch $DEPLOYPATH/bungloo/__init__.py
|
||||
|
||||
cp $LINUXPATH/Bungloo.py $DEPLOYPATH/bin/bungloo
|
||||
cp $LINUXPATH/Helper.py $LINUXPATH/Windows.py $DEPLOYPATH/bungloo
|
||||
cp $QTPATH/Bungloo.py $DEPLOYPATH/bin/bungloo
|
||||
cp $QTPATH/Helper.py $QTPATH/Windows.py $DEPLOYPATH/bungloo
|
||||
cat setup.py.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/setup.py
|
||||
cat Makefile.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/Makefile
|
||||
cat bungloo.desktop.exmp | sed -e "s/{VERSION}/${VERSION}/g" > $DEPLOYPATH/bungloo.desktop
|
Reference in a new issue