Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 20 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -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 <[email protected]> and contributors, 2013
Expand Down
154 changes: 94 additions & 60 deletions btsyncindicator.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -20,9 +21,15 @@
# <http://www.gnu.org/licenses/>
#
import gobject
import gtk
import appindicator


try:
hasIndicator = True
import appindicator
except ImportError:
hasIndicator = False

import gtk
import urllib

"""
Expand All @@ -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)
Expand All @@ -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):
Expand Down Expand Up @@ -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']
Expand All @@ -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):
"""
Expand All @@ -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)
Expand Down Expand Up @@ -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><div[^>]+>([^<]+)</div></html>")
html = self.get_response_text(response)
Expand All @@ -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()

Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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",
Expand All @@ -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()