diff --git a/README.md b/README.md index 867119a..42659c8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,22 @@ -btsyncindicator +btGtkTray =============== -**BitTorrent Sync indicator for Linux desktops** +**BitTorrent Sync Tray Application for Linux desktops** +This is a shameless port of https://github.com/marxjohnson/btsyncindicator +Origionally coded for Gnome libindicator, I've ported it over to gtk2 now pretty much all other non-gnome users +should be able to use the app without issues. I'll try to keep up with Mark's changes since most of the code is his. + +``` +Depends: + python2.x (tested on 2.7) + gtk+2 + pygtk + responses (the python library) + of course you will need btsync for linux +``` + + ``` usage: btsyncindicator.py [-h] [--config CONFIG] [--iconpath ICONPATH] [-v] [--log LOG] @@ -15,56 +29,25 @@ optional arguments: --log LOG Set logging level ``` -* Displays an application indicator for BitTorrent Sync on Linux desktops. +* Displays an Gtk 2 System Tray Icon for BitTorrent Sync on Linux desktops. * Shows syncing folders and the status of connected peers. * Allows you copy the secret for each folder to the clipboard. ### Contributions welcome -I'm not actively developing the indicator at the moment but am keeping an eye on bug reports and will test and merge pull requests. If you'd like to contribute, please raise a bug in the tracker, I'll be notified and get back to you. - ## Installation -The recommended installation method is using the [Debian and Ubuntu Desktop Packages for BitTorrent Sync](http://forum.bittorrent.com/topic/19560-debian-and-ubuntu-desktop-packages-for-bittorrent-sync/) which includes the indicator. - -### Ubuntu/Debian (i386, and amd64) -``` -sudo add-apt-repository ppa:tuxpoldo/btsync -sudo apt-get update -sudo apt-get install btsync-user -``` -If you get a *command not found* error, run `sudo apt-get install python-software-properties software-properties-common` first. - -The indicator will start on login with BitTorrent Sync. - -### Debian (i386, amd64, powerpc, armel, and armhf) -``` -sudo gpg --keyserver pgp.mit.edu --recv-keys 6BF18B15 -sudo gpg --armor --export 6BF18B15 | sudo apt-key add - -sudo echo deb http://debian.yeasoft.net/btsync $(lsb_release -cs) main contrib non-free >> /etc/apt/sources.list.d/btsync.list -sudo echo deb-src http://debian.yeasoft.net/btsync $(lsb_release -cs) main contrib non-free >> /etc/apt/sources.list.d/btsync.list -sudo apt-get update -sudo apt-get install btsync-user -``` -The indicator will start on login with BitTorrent Sync. - -### Arch Linux -btsyncindicator is available in the [AUR](https://aur.archlinux.org). -``` -sudo packer -S --noedit --noconfirm btsyncindicator -``` - -### Other distributions -The indicator is not packaged for other distros. You will have to [download BitTorrent Sync](http://labs.bittorrent.com/experiments/sync.html), then download and run the indicator seperately: +The BtSyncGtkTray is not packaged for any distros. You will have to [download BitTorrent Sync](http://labs.bittorrent.com/experiments/sync.html), then download and run the this app seperately: ``` cd ~/ -git clone https://github.com/marxjohnson/btsyncindicator.git +git clone https://github.com/Teknocrat/btsyncGtkTray.git ~/btsyncindicator/btsyncindicator.py` ``` You may want to make it start on login. ## Documentation + The API used by the indicator is (partially) documented on the [GitHub Wiki](https://github.com/marxjohnson/btsyncindicator/wiki) Copyright Mark Johnson and contributors, 2013 diff --git a/btsyncindicator.py b/btsyncindicator.py index 6ebe99a..7b78b65 100755 --- a/btsyncindicator.py +++ b/btsyncindicator.py @@ -1,9 +1,10 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # coding=utf-8 # # Copyright 2013 Mark Johnson +# Authors: Mark Johnson # -# Authors: Mark Johnson and Contributors (see CREDITS) +# Ported to GTK, by Harvey Mittens # # Based on the PyGTK Application Indicators example by Jono Bacon # and Neil Jagdish Patel @@ -20,9 +21,15 @@ # # import gobject -import gtk -import appindicator + +try: + hasIndicator = True + import appindicator +except ImportError: + hasIndicator = False + +import gtk import urllib """ @@ -36,7 +43,7 @@ print "To install, try:" print "sudo apt-get install python-requests" print "If python-requests isn't found, try:" - print "sudo apt-get install python-pip && sudo pip install requests" + print "sudo apt -get install python-pip && sudo pip install requests" print "If apt-get isn't available, use your system's package manager or install pip manually:" print "http://www.pip-installer.org/en/latest/installing.html" exit(1) @@ -52,9 +59,6 @@ import subprocess from contextlib import contextmanager -VERSION = '0.13' -TIMEOUT = 2 # seconds - @contextmanager def file_lock(lock_file): if os.path.exists(lock_file): @@ -96,23 +100,34 @@ def load_config(self): logging.info('Config loaded') -class BtSyncIndicator: +VERSION = '0.13' +TIMEOUT = 2 # seconds + +class BtSyncTrayIcon: def __init__(self,btconf): """ - Initialise the indicator, load the config file, - intialise some properties and set up the basic + Initialize the TrayIcon, load the config file, + initialize some properties and set up the basic menu """ + if hasIndicator : + self.ind = appindicator.Indicator ("btsync-indicator", + "btsync", + appindicator.CATEGORY_APPLICATION_STATUS, + args.iconpath) + self.ind.set_status (appindicator.STATUS_ACTIVE) + self.ind.set_attention_icon ("btsync-attention") - self.ind = appindicator.Indicator ("btsync-indicator", - "btsync", - appindicator.CATEGORY_APPLICATION_STATUS, - args.iconpath) - self.ind.set_status (appindicator.STATUS_ACTIVE) - self.ind.set_attention_icon ("btsync-attention") + self.config = btconf.config + self.detect_btsync_user() + else: + self.tray = gtk.StatusIcon() + self.tray.set_name("btsync-tray") + self.tray.set_title("btsync-tray") + self.tray.set_from_file(args.iconpath) - self.config = btconf.config - self.detect_btsync_user() + self.config = btconf.config + self.btsync_user = True if 'login' in self.config['webui']: login = self.config['webui']['login'] @@ -134,30 +149,41 @@ def __init__(self,btconf): self.count = 0 self.menu_setup() - self.ind.set_menu(self.menu) + + if hasIndicator : + self.ind.set_menu(self.menu) + else: + self.tray.connect("popup-menu", self.right_click_event) def detect_btsync_user(self): - # If we have dpkg in $PATH, Determine whether the script was installed with - # the btsync-user package if it is, we can use the packages btsync management - # scripts for some extra features - try: - have_dpkg = False - for p in os.environ["PATH"].split(os.pathsep): - if os.path.exists(os.path.join(p, 'dpkg')): - have_dpkg = True - - if have_dpkg: - output = subprocess.check_output(["dpkg", "-S", os.path.abspath(__file__)]) - else: - output = "" - - if (output.find("btsync-user") > -1): - self.btsync_user = True - else: - self.btsync_user = False - except subprocess.CalledProcessError, e: - self.btsync_user = False - return self.btsync_user + # If we have dpkg in $PATH, Determine whether the script was installed with + # the btsync-user package if it is, we can use the packages btsync management + # scripts for some extra features + try: + have_dpkg = False + for p in os.environ["PATH"].split(os.pathsep): + if os.path.exists(os.path.join(p, 'dpkg')): + have_dpkg = True + + if have_dpkg: + output = subprocess.check_output(["dpkg", "-S", os.path.abspath(__file__)]) + else: + output = "" + + if (output.find("btsync-user") > -1): + self.btsync_user = True + else: + self.btsync_user = False + except subprocess.CalledProcessError, e: + self.btsync_user = False + return self.btsync_user + if hasIndicator == False : + def right_click_event(self, icon, button, time): + + def pos(menu, icon): + return (gtk.status_icon_position_menu(menu, icon)) + + self.menu.popup(None, None, pos, button, time ) def menu_setup(self): """ @@ -171,10 +197,10 @@ def menu_setup(self): self.sep1.show() self.menu.append(self.sep1) - if self.btsync_user: + if self.btsync_user: filepath = self.config['storage_path']+'/paused' self.pause_item = gtk.CheckMenuItem("Pause Syncing") - self.pause_item.set_active(os.path.isfile(filepath)) + self.pause_item.set_active(os.path.isfile(filepath)) self.pause_item_handler = self.pause_item.connect("activate", self.toggle_pause) self.pause_item.show() self.menu.append(self.pause_item) @@ -225,7 +251,7 @@ def setup_session(self): tokenurl = self.urlroot+'token.html' logging.info('Requesting Token from ' + tokenurl) response = requests.post(tokenurl, params=tokenparams, auth=self.auth) - response.raise_for_status() + response.raise_for_status() logging.info('Token response ' + str(response)) regex = re.compile("]+>([^<]+)") html = self.get_response_text(response) @@ -249,8 +275,8 @@ def setup_session(self): for a in actions: params = {'token': self.token, 'action': a} response = requests.get(self.urlroot, params=params, cookies=self.cookies, auth=self.auth) - response.raise_for_status() - self.info[a] = json.loads(self.get_response_text(response)) + response.raise_for_status() + self.info[a] = json.loads(self.get_response_text(response)) self.clear_error() @@ -270,6 +296,7 @@ def setup_session(self): self.show_error("Communication Error "+response.status_code) return True + def check_status(self): """ Gets the current status of btsync and updates the menu accordingly @@ -292,15 +319,14 @@ def check_status(self): self.pause_item.disconnect(self.pause_item_handler) self.pause_item.set_active(os.path.isfile(filepath)) self.pause_item_handler = self.pause_item.connect("activate", self.toggle_pause) - if (os.path.isfile(filepath)): - logging.info('BitTorrent Sync is paused. Cleaning menu') - self.show_error("BitTorrent Sync is paused") - self.folderitems = {} - self.status = { 'folders': [] } - gtk.timeout_add(5000, self.setup_session) - return False - - try: + if (os.path.isfile(filepath)): + logging.info('BitTorrent Sync is paused. Cleaning menu') + self.show_error("BitTorrent Sync is paused") + self.folderitems = {} + self.status = { 'folders': [] } + gtk.timeout_add(5000, self.setup_session) + return False + try: logging.info('Requesting status') params = {'token': self.token, 'action': 'getsyncfolders'} response = requests.get(self.urlroot, params=params, cookies=self.cookies, auth=self.auth) @@ -355,6 +381,9 @@ def check_status(self): gtk.timeout_add(5000, self.setup_session) return True + + + def check_activity(self, folders): """ Given the current folder list from the server, determines @@ -444,13 +473,14 @@ def build_folder_menu(self, folder): readwrite.show() menu.append(readwrite) - readonly = gtk.MenuItem('Get Read Only Secret') readonly.connect("activate", self.copy_secret, readonlysecret) - + readonly.show() menu.append(readonly) + + return menu def update_folder_menu(self, folder): @@ -575,7 +605,11 @@ def set_icon(self, variant): Changes the icon to the given variant """ logging.debug('Setting icon to '+args.iconpath+'/btsync'+variant) - self.ind.set_icon('btsync'+variant) + if hasIndicator : + self.ind.set_icon('btsync'+variant) + else: + self.tray.set_from_file(args.iconpath+'btsync'+variant+'.png') + return False def open_webui(self, widget): @@ -662,7 +696,7 @@ def quit(self, widget): if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--config', - default=os.environ['HOME']+'/.btsync.conf', + default=os.environ['HOME']+'/.sync/config.conf', help="Location of BitTorrent Sync config file") parser.add_argument('--iconpath', default=os.path.dirname(os.path.realpath(__file__))+"/icons", @@ -688,6 +722,6 @@ def quit(self, widget): btconf = BtSyncConfig() with file_lock(btconf.config['storage_path'] + '/indicator.lock'): - indicator = BtSyncIndicator(btconf) + indicator = BtSyncTrayIcon(btconf) indicator.main()