Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # -*- coding: utf-8 -*-
- # KDE Insync Applet - beta11
- # by Brett Hartshorn : brett@insynchq.com
- # Copyright Insynchq Pte. Ltd., ("Insync") | http://www.insynchq.com
- # License: GNU GPL v2
- import os, sys, webbrowser
- import functools
- from PyQt4 import Qt
- from PyQt4.QtCore import QObject, SIGNAL, QString, QUrl, QTimer
- from PyQt4.QtGui import QGraphicsLinearLayout, QIcon, QMenu, QWidget, QPushButton, QGraphicsScene
- from PyKDE4.kdeui import KStatusNotifierItem
- from PyKDE4 import kdecore
- import socket, json
- DEBUG = '--debug' in sys.argv
- def ipc_insync( **kw ):
- #print('<ipc-insync>',kw)
- data = json.dumps( kw )
- socket_file = u'/tmp/insync%r.sock' % os.getuid()
- if not os.path.exists(socket_file):
- print('WARN: insync socket not found')
- return None
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- sock.connect(socket_file)
- except:
- return
- sock.send(data)
- res = sock.recv(4096)
- sock.close()
- if res.strip():
- return json.loads(res.strip())
- else:
- return None
- App = Qt.QApplication(sys.argv)
- def on_quit():
- print('<kde applet exit>')
- try: ipc_insync( command='EXIT' )
- except: pass
- App.quit()
- QObject.connect(
- App,
- SIGNAL("lastWindowClosed()"),
- on_quit,
- )
- def open_insync():
- print('<running insync>')
- if DEBUG:
- os.system( 'xterm -e insync --kde --plasmoid &' )
- else:
- os.system( 'insync --kde --plasmoid &' )
- STATE_IDLE = 'UNLINKED'
- STATE_SYNCED = 'SYNCED'
- STATE_SYNCING = 'SYNCING'
- STATE_OFFLINE = 'OFFLINE'
- STATE_ERROR = 'ERROR'
- STATE_ERROR_YELLOW = 'WARNING'
- ICONS = {
- STATE_OFFLINE: 'applet-offline',
- STATE_IDLE: 'applet-idle',
- STATE_SYNCED: 'alternate-synced',
- STATE_SYNCING: 'alternate-syncing',
- STATE_ERROR: 'alternate-error',
- STATE_ERROR_YELLOW: 'alternate-partial-error'
- }
- class Notifer(QObject):
- def poll_status(self):
- status = ipc_insync( command='GET-STATUS' )
- if status == self._prev_status: return
- self._prev_status = status
- name = ICONS[ status ]
- path = '/usr/share/icons/insync/icons/%s.png' %name
- icon = QIcon(path)
- self.tray.setIconByPixmap(icon)
- self.tray.setToolTipSubTitle( status )
- def __init__(self, parent=None):
- QObject.__init__(self, parent)
- self._menus = {}
- self._prev_status = None
- self.tray = KStatusNotifierItem(self)
- self.tray.setTitle("Insync")
- self.tray.setToolTipTitle("Insync")
- self.tray.setToolTipSubTitle("Status...")
- self.tray.setCategory(KStatusNotifierItem.Communications)
- self.tray.setIconByPixmap(QIcon("/usr/share/icons/insync/icons/applet-idle.png"))
- self.tray.setStatus(KStatusNotifierItem.Active)
- self.tray.setToolTipIconByPixmap(QIcon("/usr/share/icons/insync/icons/insync.png"))
- #self.widget = self.tray.associatedWidget()
- self.menu = menu = self.tray.contextMenu()
- print(menu, dir(menu))
- self.tray.setAssociatedWidget(menu) # make KSNI open menu on left or right click
- # this will not work if using "tray.setAssociatedWidget(menu)" - this only works with left click anyways.
- #QObject.connect(self.tray,SIGNAL("activateRequested(bool,QPoint)"),self.trayToggle)
- ## if about to show menu, rebuild the sub menus ##
- QObject.connect(menu, SIGNAL("aboutToShow()"),self._rebuild_menu)
- self.timer = QTimer()
- QObject.connect(self.timer, SIGNAL("timeout()"), self.poll_status)
- self.timer.start(2000)
- ###############################################################
- def _rebuild_menu(self):
- print('rebuilding menu')
- state = ipc_insync( command='GET-STATE')
- if state:
- self._rebuild_menu_main(state)
- else:
- self._rebuild_menu_open()
- def _rebuild_menu_open(self):
- self.menu.clear(); self._menus = {}
- action = self.menu.addAction( QIcon("/usr/share/icons/insync/icons/insync.png"), 'Run Insync' )
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- open_insync,
- )
- action = self.menu.addAction( 'Quit')
- QObject.connect( action, SIGNAL("triggered()"), on_quit )
- def _rebuild_menu_main_helper(self):
- self.menu.clear(); self._menus = {}
- menu = self.menu
- #icon = QIcon("/usr/share/icons/oxygen/16x16/categories/applications-internet.png")
- icon = QIcon("/usr/share/icons/oxygen/16x16/places/folder-documents.png")
- action = menu.addAction( icon, 'Open Insync Folder')
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- lambda : ipc_insync( command='OPEN-INSYNC-FOLDER' )
- )
- icon = QIcon("/usr/share/icons/oxygen/16x16/categories/applications-internet.png")
- action = menu.addAction( icon, 'Go to Insync Web')
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- lambda : webbrowser.open('http://www.insynchq.com')
- )
- menu.addSeparator()
- ############################## menus ############################
- icon = QIcon("/usr/share/icons/insync/icons/bubble-icon.png")
- self._menus['recent'] = menu.addMenu(icon, 'Recent Changes')
- icon = QIcon("/usr/share/icons/insync/icons/user-icon.png")
- self._menus['actions'] = menu.addMenu(icon, 'Actions Required')
- icon = QIcon("/usr/share/icons/insync/icons/error-icon.png")
- self._menus['errors'] = menu.addMenu(icon, 'Error Messages')
- menu.addSeparator()
- self._paused = False
- self._pause_action = action = menu.addAction( 'Pause Syncing')
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- self._pause_resume_insync
- )
- menu.addSeparator()
- self._menus['account'] = menu.addMenu('Account Information')
- #menu.addAction( 'Account Information')
- #menu.addTitle( 'Settings')
- action = menu.addAction( 'Support')
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- lambda : webbrowser.open('http://support.insynchq.com')
- )
- action = menu.addAction( 'Quit')
- QObject.connect( action, SIGNAL("triggered()"), on_quit )
- def _pause_resume_insync( self ):
- action = self._pause_action
- if self._paused:
- self._paused = False
- ipc_insync( command='RESUME' )
- action.setText( 'Pause Syncing')
- else:
- self._paused = True
- ipc_insync( command='PAUSE' )
- action.setText( 'Resume Syncing')
- def _rebuild_menu_main(self, state):
- if not self._menus: self._rebuild_menu_main_helper()
- if DEBUG: print(state)
- for menu in self._menus.values(): menu.clear()
- for key in 'recent actions errors'.split():
- menu = self._menus[ key ]
- if not state[key]:
- menu.addAction( '(no updates)' )
- for key in 'recent actions account'.split():
- if not state[key]: continue
- menu = self._menus[ key ]
- for info, method in state[key]:
- action = menu.addAction( info )
- #callback = eval( 'lambda : ipc_insync( method=%s )' %method)
- callback = functools.partial(ipc_insync, action=method)
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- callback,
- )
- ######## add new account #################
- menu = self._menus['account']
- action = menu.addAction('Connect another Google account')
- callback = functools.partial(ipc_insync, command='ADD-ACCOUNT')
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- callback,
- )
- ##############################
- if state['errors']:
- menu = self._menus['errors']
- assert len(state['errors'])==3
- retry, errors, other = state['errors']
- if retry:
- assert len(retry)==2
- info, method = retry
- action = menu.addAction(info)
- callback = functools.partial(ipc_insync, action=method)
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- callback,
- )
- for err in errors:
- info, method = err
- action = menu.addAction(info)
- callback = functools.partial(ipc_insync, action=method)
- QObject.connect(
- action,
- SIGNAL("triggered()"),
- callback,
- )
- if other: menu.addAction( other )
- if __name__ == '__main__':
- notifer = Notifer()
- App.exec_()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement