HubicGTK: Check-in [805668c104]

HubicGTK is a system tray icon for hubiC, the online storage service by OVH SAS.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial commit, import from divers repository
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:805668c104bc4c5a74b4f0fc5c3a558334aa79fc
User & Date: milouse 2015-08-21 07:53:00
Context
2015-09-09
17:38
Little update to Makefile check-in: ed8992fd0e user: milouse tags: trunk
2015-08-21
07:53
Initial commit, import from divers repository check-in: 805668c104 user: milouse tags: trunk
07:41
initial empty check-in check-in: e1ec555f5d user: milouse tags: trunk
Changes

Added .fossil-settings/binary-glob.



>
1
*

Added .fossil-settings/ignore-glob.















>
>
>
>
>
>
>
1
2
3
4
5
6
7
*.~
*.mo
*.git
nantes/keys.php
nantes/img/lignes/
nantes/img/icon*
nantes/img/favicon.ico

Added LICENSE.



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
        DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.

Added Makefile.







































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
DEST=/usr
L10N=fr en_US
PKGNAME=hubic-gtk
PKGVER=0.5.2
FOSSIL=no

all: build install

build:
	cp $(PKGNAME).py $(PKGNAME)
	sed -i "s|HUBIC_ICONS_PATH = os.path.dirname(os.path.realpath(__file__))|HUBIC_ICONS_PATH = '$(DEST)/share/icons/hicolor/16x16/status'|" $(PKGNAME)
	sed -i "s|HUBIC_L10N_PATH = './po'|HUBIC_L10N_PATH = '$(DEST)/share/locale'|" $(PKGNAME)
	sed -i "s|HUBIC_STATUS_VERSION = 'dev'|HUBIC_STATUS_VERSION = '$(PKGVER)'|" $(PKGNAME)

install: install-bin install-lang

install-bin:
	install -d -m755	$(DEST)/bin
	install -d -m755	$(DEST)/share/applications
	install -d -m755	$(DEST)/share/licenses/$(PKGNAME)
	install -d -m755	$(DEST)/share/icons/hicolor/16x16/status

	install -D -m755 $(PKGNAME)         $(DEST)/bin/$(PKGNAME)
	install -D -m644 hubic_busy.png     $(DEST)/share/icons/hicolor/16x16/status/hubic_busy.png
	install -D -m644 hubic_error.png    $(DEST)/share/icons/hicolor/16x16/status/hubic_error.png
	install -D -m644 $(PKGNAME).desktop $(DEST)/share/applications
	install -D -m644 LICENSE            $(DEST)/share/licenses/$(PKGNAME)/LICENSE

install-lang:
	for lang in $(L10N) ; do \
	  install -d -m755 $(DEST)/share/locale/$$lang/LC_MESSAGES ; \
	  msgfmt -o $(DEST)/share/locale/$$lang/LC_MESSAGES/hubic-gtk.mo	po/$$lang/LC_MESSAGES/hubic-gtk.po ; \
	done

uninstall:
	rm $(DEST)/bin/$(PKGNAME)
	rm $(DEST)/share/icons/hicolor/16x16/hubic_busy.png
	rm $(DEST)/share/icons/hicolor/16x16/hubic_error.png
	rm $(DEST)/share/applications/$(PKGNAME).desktop

	for lang in $(L10N) ; do \
	  rm $(DEST)/share/locale/$$lang/LC_MESSAGES/hubic-gtk.mo ; \
	done


OLDVER != sed -n "s/pkgver=\([\d.]*\)/\1/p" archlinux/PKGBUILD
OLDREL != sed -n "s/pkgrel=\(\d*\)/\1/p" archlinux/PKGBUILD
ifeq ($(OLDVER), $(PKGVER))
	PKGREL != expr $(OLDREL) + 1
else
	PKGREL = 1
endif

dist: sha1sum
	sed -i "s/pkgver=.*/pkgver=$(PKGVER)/" archlinux/PKGBUILD ; \
	sed -i "s/pkgrel=.*/pkgrel=$(PKGREL)/" archlinux/PKGBUILD

sha1sum: SHA1SUM = $(shell sha1sum archlinux/$(PKGNAME)-$(PKGVER).tar.gz | cut -d' ' -f1)
sha1sum: $(PKGNAME)-$(PKGVER).tar.gz
	sed -i "s/_fossilver=.*/_fossilver=$(shell echo $(SHA1SUM) | cut -c1-10)/" archlinux/PKGBUILD
	sed -i "s/sha1sums=.*/sha1sums=('$(SHA1SUM)')/" archlinux/PKGBUILD

$(PKGNAME)-$(PKGVER).tar.gz:
	cd ../ ; tar czf hubic-gtk/archlinux/$(PKGNAME)-$(PKGVER).tar.gz hubic-gtk --exclude archlinux

clean:
	rm $(PKGNAME)

Added README.md.





















































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
HubicGTK
========

About
-----

HubicGTK is a system tray icon for [hubiC](https://www.hubic.com),
the online storage service by OVH SAS.

It draws its inspiration from the bundled Dropbox system tray icon.

It is developped in pygtk, thus it depends on python2, gtk2, dbus, xdg
and notify bindings for python. It is released under the terms of the
[WTF Public License](http://www.wtfpl.net/)

Get it
------

The last version is 0.5. You can get it [here](http://projects.depar.is/divers/raw/hubic-gtk/archlinux/hubic-gtk-0.5.tar.gz?name=641a085d76)

Usage
-----

The program should run out of the box. Just type the following
commands:

    $ tar xzf hubic-gtk-x.x.x.tar.gz
    $ cd hubic-gtk
    $ ./hubic-gtk.py

If you want to install it system wide, you can use the provided
Makefile:

    $ sudo make

or

    $ make build
    $ su -
    # cd /previous/extracted/path
    # make install

And start it with the `hubic-gtk` command.

You can install it elsewhere if needed, just pass the target root as a
parameter to make. For example:

    $ make build DEST=~/.local
    $ make install DEST=~/.local
    $ .local/bin/hubic-gtk &

or

    $ make build DEST=/opt/hubic-gtk
    $ sudo make install DEST=/opt/hubic-gtk
    $ /opt/hubic-gtk/bin/hubic-gtk &


Configuration
-------------

HubicGTK use a per-user configuration file located in
`$XDG_CONFIG_HOME/hubiC/status_icon.conf`. It is a generic
[configuration file](https://en.wikipedia.org/wiki/Ini_file), which
follows this structure:

    [general]
    notify = True
    hubic_dir = ~/Hubic

    [much_secret_wow_not_see]
    encfs_config = ~/.config/.myhubicsecret.encfs6.xml
    encfs_passfile = ~/.config/.myhubicsecret.encfs.pass
    mount_point = ~/Private/Hubic

The `general` section refers to preferences of the status icon. Any
other section must refer to as many existing encfs containers.

The program does not depend on this per-user configuration file. If no
config file is found for the current user or if a configuration option
is missing in your configuration file, the program follows its default
rules, which are:

    [general]
    notify = False
    show_all_message = False
    file_browser = xdg-open {0}
    prefix_unit = binary

Your default `hubic_dir` is retrieved from dbus at first run.

### General section

- The **`notify`** option specifies if notification bubbles should be
  shown for each hubiC events. The default value is True, but as it
  may generate a lot of noise, you can set it to false to deactivate
  it.
  Please note it is an intended behaviour that the program still
  notify you about encfs events, even if this option is set to False.
  You can also set this option by toggling the `Show notification
  messages` checkbox in the `Last messages` submenu.
- The **`show_all_messages`** restrains the last messages submenu to the
  last 10 messages if it is set to False.
- The **`hubic_dir`** option specifies the path to your synchronized
  folder. This is an attempt to not make a dbus call when the
  programme start to find this path, as this single dbus call will
  consecutively start hubiC. If this option is not set, the first time
  the program ask hubiC to indicates its path, the later is saved for
  future usage and a configuration file is created if needed.
- The **`prefix_unit`** option specifies the file size unit used through
  the application. For now it could be `decimal` or anything else. In
  this last case, the fallback or default mode is [binary
  prefix](https://en.wikipedia.org/wiki/Binary_prefix).
- The **`file_browser`** option overwrite the default use of xdg_open to
  open parent folder of synchronised files appearing in the status
  messages.

### Encfs sections

As we lived in a world where citizen censorship and mass surveillance
is common, it is a good practice to crypt our private data. Many
different systems exist, like [TrueCrypt](http://www.truecrypt.org/)
or [EncFS](http://www.arg0.net/encfs). I chose to add encfs features
to this program as it is, at my sense, the most practical way to crypt
data on such cloud storage services.

By the way, the aim of HubicGTK is NOT to help you create encfs
container, but just to help you mounting these containers. To do so,
just add the correct sections to your configuration file and the
corresponding enfs volume will show up in the hubiC status menu.

The name of the configuration file's section must be the relative path
to your hubiC synchronised folder. Given `~/Hubic` being your hubiC
synchronized folder, if your encfs container is stored
in `~/Hubic/my_private_folder`, the section name must be
`[my_private_folder]`. If it is in `~/Hubic/Documents/very_secret`,
the section name must be `[Documents/very_secret]`.

For each of your encfs containers, the following options are
available:

- **`mount_point`**: the path to a folder, which will be used as a mount
  point. This folder must exist and must be empty.
- **`open_folder_at_mount`**: indicates if the program should open your
  private folder just after having mounted it or not. It uses
  `xdg-open` or the value of the `file_browser` option in the
  `general` section.
- **`encfs_config`**: the path to the encfs config file. It is good
  practice to store it anyway but NOT in a cloud synchronized
  place. If you want to share an encfs folder between two different
  devices, copy this file on an usb stick and put it somewhere in
  your profile directories.
- **`encfs_passphrase`**: the secret phrase to uncrypt your encfs
  container. Obviously this phrase will not be encrypted in the
  HubicGTK config file, so use it with big precaution.
- **`encfs_passfile`**: the path to a file containing only your encfs
  secret pass phrase. The file content must not be encrypted as its
  content is directly passed to the encfs command line. To enforce the
  security on this file, you can do a `chmod 600 mysecretfile` on it
  to prevent any other user of your computer to access its content.
- if neither a encfs_passphrase, nor an encfs_passfile option is
  present in your config file, HubicGTK will prompt you for a
  password each time you will mount an encfs container. It is the
  safer option if you do not want to keep your secret pass phrase
  written somewhere in your computer.

Here is a complete example of an encfs section, regarding a container
staying in `~/Hubic/much_secret_wow_not_see`:

    [much_secret_wow_not_see]
    encfs_config = ~/.config/.myhubicsecret.encfs6.xml
    encfs_passfile = ~/.config/.myhubicsecret.encfs.pass
    mount_point = ~/Private/Hubic


Contributions
-------------

All contributions are welcome. Just clone take the code and do WTF you
want with.

A special attention will be given to any translation help. You can
either:

- [download the main .pot file](http://projects.depar.is/divers/raw/hubic-gtk/po/hubic-gtk.pot?name=tip) or
- ask to become member of [the project on transifex](https://www.transifex.com/projects/p/hubicstatus/) (all demands will be honoured)

Added archlinux/PKGBUILD.





















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# $Id: pkgbuild-mode.el,v 1.23 2007/10/20 16:02:14 juergen Exp $
# Maintainer: Étienne Deparis <etienne@depar.is>
pkgname=hubic-gtk
pkgver=0.5.2
pkgrel=1
_fossilver=04979bad8c
pkgdesc="An attempt to get a status icon for Hubic on Linux"
arch=('any')
url="http://projects.depar.is/divers/doc/tip/hubic-gtk/README.md"
license=('custom:WTFPL')
depends=('hubic' 'python2' 'pygtk' 'python2-dbus' 'python2-notify' 'python2-xdg')
install=$pkgname.install
source=($pkgname-$pkgver.tar.gz::http://projects.depar.is/divers/raw/hubic-gtk/archlinux/$pkgname-$pkgver.tar.gz?name=$_fossilver)
sha1sums=('04979bad8c2c01faa5da724cafd9200737587d7c')

build(){
  cd $srcdir/$pkgname
  make build
}

package() {
  cd $srcdir/$pkgname
  make install DEST=$pkgdir/usr
}

# vim:set ts=2 sw=2 et:

Added archlinux/hubic-gtk-0.3.4.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.4.0.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.4.1.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.4.2.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.5.1.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.5.2.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk-0.5.tar.gz.

cannot compute difference between binary files

Added archlinux/hubic-gtk.install.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
post_install() {
    gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}

post_upgrade() {
    post_install
}

post_remove() {
    post_install
}

Added generate_translations.













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env bash

PROJECT_NAME=HubicGTK
PROJECT_VERSION=${PROJECT_VERSION:-"dev"}
PROJECT_CONTACT_MAIL=bugs@depar.is
DOMAIN_NAME=hubic-gtk
PO_ROOT=${PO_ROOT:-"./po"}

if [ "$1" = "init" ]; then
    if [ ! -d "${PO_ROOT}" ]; then
        mkdir "${PO_ROOT}"
    fi
    if [ -f "${PO_ROOT}/${DOMAIN_NAME}.pot" ]; then
        rm "${PO_ROOT}/${DOMAIN_NAME}.pot"
    fi

    xgettext --language=Python --keyword=_ --keyword=N_ \
        --copyright-holder="$PROJECT_NAME volunteers" \
        --package-name=$PROJECT_NAME --package-version=$PROJECT_VERSION \
        --msgid-bugs-address=$PROJECT_CONTACT_MAIL \
        --output=${DOMAIN_NAME}.pot ${DOMAIN_NAME}.py

    sed -i "s|SOME DESCRIPTIVE TITLE.|$PROJECT_NAME Translation Effort|" ${DOMAIN_NAME}.pot
    sed -i "s|Content-Type: text/plain; charset=CHARSET|Content-Type: text/plain; charset=UTF-8|" ${DOMAIN_NAME}.pot
    mv ${DOMAIN_NAME}.pot "${PO_ROOT}/"

elif [ "$1" = "create" ]; then
    mkdir -p "${PO_ROOT}/$2/LC_MESSAGES/"
    msginit -l $2 -i "${PO_ROOT}/${DOMAIN_NAME}.pot" -o "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.po"

elif [ "$1" = "compile" ]; then
    msgfmt -o "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.mo" "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.po"

elif [ "$1" = "update" ]; then
    # commande à base de msgmerge pour mettre à jour une langue.
    cp "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.po" "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.old.po"
    msgmerge --lang $2 -o "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.po" "${PO_ROOT}/$2/LC_MESSAGES/$DOMAIN_NAME.old.po" ${PO_ROOT}/${DOMAIN_NAME}.pot
fi

Added hubic-gtk.desktop.





















>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
[Desktop Entry]
Name=hubiC Status
GenericName=Network Storage Status Icon
Comment=hubiC is an online storage platform provided by OVH. This is a status icon for the main executable
Exec=hubic-gtk
Icon=/usr/share/icons/hicolor/128x128/hubic.png
Terminal=false
Type=Application
Categories=Network;
StartupNotify=false

Added hubic-gtk.py.

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
#!/usr/bin/env python2
# -*- coding: utf-8;mode: python -*-

# python stuff
import os
import pwd
import time
import shlex
import subprocess
import ConfigParser

# other stuff
import gtk
import dbus
from dbus.mainloop.glib import DBusGMainLoop
import pynotify
from xdg.BaseDirectory import xdg_config_home

HUBIC_ICONS_PATH = os.path.dirname(os.path.realpath(__file__))
HUBIC_STATUS_VERSION = 'dev'
HUBIC_L10N_PATH = './po'

import gettext
gettext.install('hubic-gtk', HUBIC_L10N_PATH)

HUBIC_POSSIBLE_STATUS = {
    'Idle': _('Idle'),
    'Busy': _('Busy'),
    'Paused': _('Paused'),
    'Connecting': _('Connecting'),
    'NotConnected': _('NotConnected'),
    'Synchronized': _('Synchronized'),
    'Unsynchronized': _('Unsynchronized'),
    'NoStatus': _('NoStatus'),
    'Error': _('Error'),
    'Starting': _('Starting'),
    'Killed': _('Killed')
}

def get_bool_conf_option(config, section, option):
    if config.has_option(section, option):
        v = config.get(section, option)
        return str(v).lower() in ('yes', 'true', 't', '1')
    return False


class FileFolderHelper:
    def __init__(self, config, hubic_dir):
        self.config = config
        self.hubic_dir = hubic_dir

        self.folder_opener = 'xdg-open {0}'
        if self.config.has_section('general') and self.config.has_option('general', 'file_browser'):
            self.folder_opener = self.config.get('general', 'file_browser')


    def set_hubic_dir(self, hubic_dir):
        self.hubic_dir = hubic_dir


    def open_folder(self, path):
        raw_argv = shlex.split(self.folder_opener.format(path))
        subprocess.Popen(raw_argv)
        # os.spawnvp(os.P_NOWAIT, raw_argv[0], raw_argv)


    def crunch_path(self, file_path):
        if self.hubic_dir != '' and file_path[:len(self.hubic_dir)] == self.hubic_dir:
            file_path = file_path[len(self.hubic_dir):]

            if file_path[0] != '/':
                file_path = '/' + file_path

            if len(file_path) > 60:
                file_path = file_path[:30] + ' (...) ' + file_path[-30:]

            return '[HubicRoot]' + file_path

        return file_path


    def format_task(self, work, crunch = False):
        workfile = work[1]
        if crunch:
            workfile = self.crunch_path(workfile)
        else:
            workfile = os.path.basename(work[1])

        if work[4] != -1 and work[5] != -1:
            completness = round((work[4] * 100.0) / work[5], 1)
            return '{0} ({1}%)'.format(workfile, completness)

        return workfile


    def file_size(self, file_size):
        # I know that 1byte != 1octet, but here it makes sense... so
        # Number used for conversion come from https://fr.wikipedia.org/wiki/Octet
        # default prefix_unit is 'binary'
        kilo_unit = 1024.0
        kilo_symbol = 'Kio'
        mega_unit = 1048576.0
        mega_symbol = 'Mio'
        giga_unit = 1073741824.0
        giga_symbol = 'Gio'
        tera_unit = 1099511627776.0
        tera_symbol = 'Tio'

        if self.config.has_section('general') and self.config.has_option('general', 'prefix_unit'):
            if self.config.get('general', 'prefix_unit') == 'decimal':
                kilo_unit = float(1e3)
                kilo_symbol = 'Ko'
                mega_unit = float(1e6)
                mega_symbol = 'Mo'
                giga_unit = float(1e9)
                giga_symbol = 'Go'
                tera_unit = float(1e12)
                tera_symbol = 'To'

        if file_size >= tera_unit:
            used_gibi = round(file_size / tera_unit, 2)
            used_unit = tera_symbol
        elif file_size >= giga_unit:
            used_gibi = round(file_size / giga_unit, 2)
            used_unit = giga_symbol
        elif file_size >= mega_unit:
            used_gibi = round(file_size / mega_unit, 2)
            used_unit = mega_symbol
        else:
            used_gibi = round(file_size / kilo_unit, 2)
            used_unit = kilo_symbol

        return (used_gibi, used_unit)



class EncfsMenu:
    def __init__(self, config, hubic_dir):
        self.config = config
        self.hubic_dir = hubic_dir


    def password_prompt(self):
        prompt_dialog = gtk.MessageDialog(
            None,
            gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
            gtk.MESSAGE_QUESTION,
            gtk.BUTTONS_OK,
            _('Pease enter your password')
        )
        prompt_dialog.set_default_response(gtk.RESPONSE_OK)
        pass_entry = gtk.Entry()
        pass_entry.set_visibility(False)
        pass_entry.set_activates_default(True)
        prompt_dialog.vbox.pack_end(pass_entry, True, True, 5)
        prompt_dialog.show_all()
        prompt_dialog.run()
        password = pass_entry.get_text()
        prompt_dialog.destroy()
        return password


    def build_menu(self, menu):
        encfs_repos = self.config.sections()
        if len(encfs_repos) > 1:
            encfs_menu = gtk.Menu()

            for sec in self.config.sections():
                if sec != 'general' and self.config.has_option(sec, 'mount_point'):
                    mount_point = os.path.expanduser(self.config.get(sec, 'mount_point'))
                    if subprocess.call(['grep', '-q', mount_point, '/etc/mtab']) == 0:
                        mi_button = gtk.MenuItem(_('Umount {0}').format(mount_point))
                        mi_button.connect('activate', self.encfs_action, 'umount', sec)
                    else:
                        mi_button = gtk.MenuItem(_('Mount {0}').format(mount_point))
                        mi_button.connect('activate', self.encfs_action, 'mount', sec)
                    mi_button.show()
                    encfs_menu.append(mi_button)

            encfs_menu_button = gtk.MenuItem(_('Encrypted repositories'))
            encfs_menu_button.show()
            encfs_menu_button.set_submenu(encfs_menu)
            menu.append(encfs_menu_button)

            sep = gtk.SeparatorMenuItem()
            sep.show()
            menu.append(sep)


    def notify(self, msg, urgency=pynotify.URGENCY_NORMAL):
        pynotify.init(_('HubicStatus Secure Repositories'))
        nota = pynotify.Notification(
            _('HubicStatus Secure Repositories'),
            msg
        )
        nota.set_urgency(urgency)
        nota.show()


    def encfs_action(self, widget, action, section):
        mount_point = os.path.expanduser(self.config.get(section, 'mount_point'))
        origin = os.path.join(self.hubic_dir, section)

        if not self.config.has_option(section, 'encfs_config'):
            self.notify(
                _('No config file path declared for {0}').format(section),
                pynotify.URGENCY_CRITICAL
            )
            return False

        encfs_config_file = os.path.expanduser(self.config.get(section, 'encfs_config'))


        if action == 'mount':
            if os.path.isdir(mount_point) and len(os.listdir(mount_point)) > 0:
                self.notify(
                    _('{0} already exists in your file system but is NOT an empty folder. Please fix it and then retry to mount {1}').format(mount_point, origin),
                    pynotify.URGENCY_CRITICAL
                )
                return False
            elif os.path.exists(mount_point) and not os.path.isdir(mount_point):
                self.notify(
                    _('{0} already exists in your file system but is NOT an empty folder. Please fix it and then retry to mount {1}').format(mount_point, origin),
                    pynotify.URGENCY_CRITICAL
                )
                return False
            elif not os.path.exists(mount_point):
                os.makedirs(mount_point)

            password = ''
            if self.config.has_option(section, 'encfs_passphrase'):
                password = self.config.get(section, 'encfs_passphrase')

            elif self.config.has_option(section, 'encfs_passfile'):
                pass_file = os.path.expanduser(self.config.get(section, 'encfs_passfile'))
                if os.access(pass_file, os.R_OK):
                    with open(pass_file) as fp:
                        password = fp.read()
                        fp.close()

                else:
                    self.notify(
                        _('Error while reading your password from {0}. Please check if everything is OK before retrying.').format(pass_file),
                        pynotify.URGENCY_CRITICAL
                    )
                    return False
            else:
                password = self.password_prompt()

            password = password.strip()
            encfs_mount_cmd = 'echo "{0}" | ENCFS6_CONFIG="{1}" encfs -S "{2}" "{3}"'.format(password, encfs_config_file, origin, mount_point)

            if subprocess.call(encfs_mount_cmd, shell=True) == 0:
                self.notify(_('{0} correctly mounted').format(mount_point))
                if get_bool_conf_option(self.config, section, 'open_folder_at_mount'):
                    folder_heler = FileFolderHelper(self.config, self.hubic_dir)
                    folder_helper.open_folder(mount_point)

            else:
                self.notify(
                    _('An error occured while mounting {0}').format(mount_point),
                    pynotify.URGENCY_CRITICAL
                )

        else:
            if subprocess.call(['fusermount', '-u', mount_point]) == 0:
                self.notify(_('{0} successfully umounted').format(mount_point))

            else:
                self.notify(
                    _('An error occured while umounting {0}').format(mount_point),
                    pynotify.URGENCY_CRITICAL
                )



class SystrayIconApp:
    def __init__(self):
        self.config = ConfigParser.ConfigParser()
        self.config.read(os.path.join(xdg_config_home, 'hubiC', 'status_icon.conf'))

        self.tray = gtk.StatusIcon()
        self.hubic_state = 'Killed'
        self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_error.png'))
        self.tray.set_tooltip(HUBIC_POSSIBLE_STATUS[self.hubic_state])
        self.tray.connect('popup-menu', self.on_right_click)
        self.tray.connect('activate', self.on_left_click)

        self.last_messages = []
        self.show_messages = False
        self.hubic_dir = ''

        if self.config.has_section('general'):
            self.show_messages = get_bool_conf_option(self.config, 'general', 'notify')
            self.show_all_messages = get_bool_conf_option(self.config, 'general', 'show_all_messages')

            if self.config.has_option('general', 'hubic_dir'):
                self.hubic_dir = os.path.expanduser(self.config.get('general', 'hubic_dir'))

        self.ff_helper = FileFolderHelper(self.config, self.hubic_dir)

        DBusGMainLoop(set_as_default=True)
        if subprocess.call(['pgrep', '-u' + pwd.getpwuid(os.getuid())[0], '-f', 'mono.*hubiC']) == 0:
            self.initialize_dbus_infos()


    def initialize_dbus_infos(self):
        self.hubic_state = 'Starting'
        self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_busy.png'))
        self.tray.set_tooltip(HUBIC_POSSIBLE_STATUS[self.hubic_state])

        dbus.SystemBus().add_signal_receiver(self.on_networking_change, dbus_interface = 'org.freedesktop.NetworkManager', signal_name = 'StateChanged')

        self.session_bus = dbus.SessionBus()
        self.session_bus.add_signal_receiver(self.on_file_change, dbus_interface = 'com.hubic.account', signal_name = 'ItemChanged')
        self.session_bus.add_signal_receiver(self.on_state_change, dbus_interface = 'com.hubic.general', signal_name = 'StateChanged')
        self.session_bus.add_signal_receiver(self.on_message, dbus_interface = 'com.hubic.general', signal_name = 'Messages')

        self.hubic_account_obj = self.session_bus.get_object('com.hubiC', '/com/hubic/Account')
        self.hubic_account_iface = dbus.Interface(self.hubic_account_obj, 'com.hubic.account')
        self.hubic_general_obj = self.session_bus.get_object('com.hubiC', '/com/hubic/General')
        self.hubic_general_iface = dbus.Interface(self.hubic_general_obj, 'com.hubic.general')

        self.ff_helper.set_hubic_dir(self.get_hubic_dir())
        self.on_state_change('Starting', self.hubic_general_obj.Get('com.hubic.general', 'CurrentState'))


    def get_hubic_dir(self):
        if self.hubic_dir == '':
            self.hubic_dir = self.hubic_account_obj.Get('com.hubic.account', 'SynchronizedDir')

            if not self.config.has_section('general'):
                self.config.add_section('general')

            self.config.set('general', 'hubic_dir', self.hubic_dir)

            with open(os.path.join(xdg_config_home, 'hubiC', 'status_icon.conf'), 'wb') as configfile:
                self.config.write(configfile)
                configfile.close()

        return self.hubic_dir


    def on_networking_change(self, state):
        if self.hubic_state != 'Killed' and self.hubic_state != 'Starting':
            if state == 70:
                # Connectivity is up and not only local
                self.last_messages.append((
                    '',
                    _('{0} Resume Hubic as network is up').format(
                        time.strftime("[%d/%m/%Y %H:%M]")
                    )
                ))
                self.hubic_account_iface.SetPauseState(False)
            elif self.hubic_state != 'Paused':
                self.last_messages.append((
                    '',
                    _('{0} Pause Hubic as network connectivity seems to be down').format(
                        time.strftime("[%d/%m/%Y %H:%M]")
                    )
                ))
                self.hubic_account_iface.SetPauseState(True)


    def on_state_change(self, old_state, new_state):
        if new_state == 'NotConnected' and old_state == 'Connecting':
            self.hubic_process(None, 'stop')
            return

        self.hubic_state = new_state
        tray_tooltip = HUBIC_POSSIBLE_STATUS[self.hubic_state]

        if self.hubic_state == 'Busy':
            self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_busy.png'))
            current_works = self.hubic_account_obj.Get('com.hubic.account', 'RunningOperations')

            if len(current_works) > 0:
                tray_tooltip = '{0} – {1}'.format(
                    tray_tooltip,
                    self.ff_helper.format_task(current_works[0])
                )

        elif self.hubic_state == 'Connecting':
            self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_busy.png'))

        elif self.hubic_state == 'Idle':
            self.tray.set_from_file('/usr/share/icons/hicolor/16x16/hubic.png')

        else:
            self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_error.png'))

        self.tray.set_tooltip(tray_tooltip)


    def on_file_change(self, file_path):
        [status, isPublished, canBePublished] = self.hubic_account_iface.GetItemStatus(file_path)
        message = self.ff_helper.crunch_path(file_path) + ': ' + HUBIC_POSSIBLE_STATUS[status]
        self.last_messages.append((file_path, time.strftime("[%d/%m/%Y %H:%M]") + ' ' + message))

        if self.show_messages:
            pynotify.init('HubicStatus')
            nota = pynotify.Notification('HubicStatus', message)
            nota.show()


    def on_message(self, urgency, message, file_path):
        if file_path != '':
            [status, isPublished, canBePublished] = self.hubic_account_iface.GetItemStatus(file_path)
            info_message = message + "\n" + self.ff_helper.crunch_path(file_path) + ': ' + HUBIC_POSSIBLE_STATUS[status]
        else:
            info_message = message

        self.last_messages.append((file_path, time.strftime("[%d/%m/%Y %H:%M]") + ' ' + info_message))

        if self.show_messages or urgency == 2 or urgency == 3:
            pynotify.init('HubicStatus')
            nota = pynotify.Notification('HubicStatus', message)

            if urgency == 1 or urgency == 2:
                nota.set_urgency(pynotify.URGENCY_NORMAL)
            elif urgency == 3:
                nota.set_urgency(pynotify.URGENCY_CRITICAL)
            else:
                nota.set_urgency(pynotify.URGENCY_LOW)

            nota.show()


    def on_right_click(self, icon, event_button, event_time):
        self.make_menu(event_button, event_time)


    def on_left_click(self, event):
        if self.hubic_dir != False:
            self.ff_helper.open_folder(self.get_hubic_dir())


    def make_menu(self, event_button, event_time):
        menu = gtk.Menu()

        current_state_info = gtk.MenuItem(HUBIC_POSSIBLE_STATUS[self.hubic_state])
        current_state_info.set_state(gtk.STATE_INSENSITIVE)
        current_state_info.show()
        menu.append(current_state_info)

        if self.hubic_state == 'Busy' or self.hubic_state == 'Idle':
            total = self.hubic_account_obj.Get('com.hubic.account', 'TotalBytes')
            used = self.hubic_account_obj.Get('com.hubic.account', 'UsedBytes')
            used_percent = round((used * 100.0) / total, 1)

            used_size_info = self.ff_helper.file_size(used)
            total_size_info = self.ff_helper.file_size(total)

            current_state_info = gtk.MenuItem(
                _('{0} {1} ({2}%) used on {3} {4} total').format(
                    used_size_info[0],
                    used_size_info[1],
                    used_percent,
                    total_size_info[0],
                    total_size_info[1]
                )
            )
            current_state_info.set_state(gtk.STATE_INSENSITIVE)
            current_state_info.show()
            menu.append(current_state_info)

            if self.hubic_state == 'Busy':
                downspeed = self.ff_helper.file_size(self.hubic_general_obj.Get('com.hubic.general', 'CurrentDownloadSpeed'))
                upspeed = self.ff_helper.file_size(self.hubic_general_obj.Get('com.hubic.general', 'CurrentUploadSpeed'))
                current_state_info = gtk.MenuItem(
                    _('Up: {0} {1}/s – Down: {2} {3}/s').format(
                        upspeed[0],
                        upspeed[1],
                        downspeed[0],
                        downspeed[1]
                    )
                )
                current_state_info.set_state(gtk.STATE_INSENSITIVE)
                current_state_info.show()
                menu.append(current_state_info)

                current_works = self.hubic_account_obj.Get('com.hubic.account', 'RunningOperations')
                if len(current_works) > 0:
                    workmenu = gtk.Menu()

                    for work_tuple in current_works:
                        mi_button = gtk.MenuItem(self.ff_helper.format_task(work_tuple))
                        mi_button.show()
                        workmenu.append(mi_button)

                    queue_status = self.hubic_account_obj.Get('com.hubic.account', 'QueueStatus')
                    total_items = queue_status[0] + queue_status[1] + queue_status[2]
                    up_infos = self.ff_helper.file_size(queue_status[3])
                    down_infos = self.ff_helper.file_size(queue_status[4])
                    mi_button = gtk.MenuItem(
                        _('{0} waiting ({1} {2} up – {3} {4} down)').format(
                            total_items,
                            up_infos[0],
                            up_infos[1],
                            down_infos[0],
                            down_infos[1]
                        )
                    )
                    mi_button.show()
                    workmenu.append(mi_button)

                    messages_info_button = gtk.MenuItem(_('Current transfers'))
                    messages_info_button.show()
                    messages_info_button.set_submenu(workmenu)
                    menu.append(messages_info_button)


        if self.hubic_state == 'Killed':
            start_button = gtk.ImageMenuItem(_('Start Hubic'))
            start_button_icon = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
            start_button.set_image(start_button_icon)
            start_button.show()
            menu.append(start_button)
            start_button.connect('activate', self.hubic_process, 'start')

        else:
            if self.hubic_state == 'Paused':
                pause_button = gtk.ImageMenuItem(_('Resume synchronization'))
                pause_button_icon = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
                pause_button.connect('activate', self.hubic_process, 'resume')
            else:
                pause_button = gtk.ImageMenuItem(_('Suspend synchronization'))
                pause_button_icon = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_MENU)
                pause_button.connect('activate', self.hubic_process, 'pause')

            pause_button.set_image(pause_button_icon)
            pause_button.show()
            menu.append(pause_button)

            stop_button = gtk.ImageMenuItem(_('Stop Hubic'))
            stop_button_icon = gtk.image_new_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
            stop_button.set_image(stop_button_icon)
            stop_button.show()
            menu.append(stop_button)
            stop_button.connect('activate', self.hubic_process, 'stop')

        sep = gtk.SeparatorMenuItem()
        sep.show()
        menu.append(sep)

        messages_info = gtk.Menu()

        mi_button = gtk.CheckMenuItem(_('Show notification messages'))
        mi_button.set_active(self.show_messages)
        mi_button.show()
        messages_info.append(mi_button)
        mi_button.connect('toggled', self.toggle_show_messages)

        sep = gtk.SeparatorMenuItem()
        sep.show()
        messages_info.append(sep)

        messages_to_show = self.last_messages
        if not self.show_all_messages:
            messages_to_show = self.last_messages[-10:]

        for file_path, mi in messages_to_show:
            mi_button = gtk.MenuItem(mi)
            mi_button.show()
            messages_info.append(mi_button)
            if file_path != '':
                mi_button.connect('activate', self.open_parent_dir, file_path)

        messages_info_button = gtk.MenuItem(_('Last messages'))
        messages_info_button.show()
        messages_info_button.set_submenu(messages_info)
        menu.append(messages_info_button)

        sep = gtk.SeparatorMenuItem()
        sep.show()
        menu.append(sep)

        # Encfs submenu
        encfs_menu = EncfsMenu(self.config, self.get_hubic_dir())
        encfs_menu.build_menu(menu)

        # show about dialog
        about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
        about.show()
        menu.append(about)
        about.connect('activate', self.show_about_dialog)

        # add quit item
        quit_button = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        quit_button.show()
        menu.append(quit_button)
        quit_button.connect('activate', self.kthxbye)

        menu.popup(None, None, gtk.status_icon_position_menu,
                   event_button, event_time, self.tray)


    def toggle_show_messages(self, widget):
        self.show_messages = widget.get_active()
        if not self.config.has_section('general'):
            self.config.add_section('general')

        self.config.set('general', 'notify', self.show_messages)

        with open(os.path.join(xdg_config_home, 'hubiC', 'status_icon.conf'), 'wb') as configfile:
            self.config.write(configfile)
            configfile.close()


    def open_parent_dir(self, widget, file_path):
        dir_open = self.get_hubic_dir()
        if os.path.isdir(file_path):
            dir_open = file_path

        elif os.path.isfile(file_path):
            dir_open = os.path.dirname(file_path)

        else:
            file_path = os.path.dirname(file_path)
            if os.path.isdir(file_path):
                dir_open = file_path

        self.ff_helper.open_folder(dir_open)


    def hubic_process(self, widget, action):
        if self.hubic_state == 'Killed':
            if action == 'start':
                subprocess.call(['hubic', 'start'])
                self.initialize_dbus_infos()
            else:
                print 'Dafuq did I just read?'

        else:
            if action == 'stop':
                self.hubic_general_iface.Stop()
                self.hubic_state = 'Killed'
                self.tray.set_tooltip(HUBIC_POSSIBLE_STATUS[self.hubic_state])
                self.tray.set_from_file(os.path.join(HUBIC_ICONS_PATH, 'hubic_error.png'))

            elif action == 'pause':
                self.hubic_account_iface.SetPauseState(True)

            elif action == 'resume':
                self.hubic_account_iface.SetPauseState(False)

            else:
                print 'Dafuq did I just read?'


    def  show_about_dialog(self, widget):
        about_dialog = gtk.AboutDialog()
        about_dialog.set_destroy_with_parent(True)
        about_dialog.set_icon_name ("HubicGTK")
        about_dialog.set_name('HubicGTK')
        about_dialog.set_comments(_("An attempt to get a status icon for hubiC on Gnu/Linux and provide an easy way to manage your encfs synchronised folders."))
        about_dialog.set_logo(gtk.gdk.pixbuf_new_from_file('/usr/share/icons/hicolor/128x128/hubic.png'))
        about_dialog.set_version(HUBIC_STATUS_VERSION)
        hubic_version = "\n\n" + subprocess.check_output('hubic help | head -n2', shell=True)
        about_dialog.set_copyright(_("HubicGTK is released under the WTF public license\nStatus icons use famfamfam silk icons, released under CC By 2.5 license") + hubic_version)
        about_dialog.set_authors(['Étienne Deparis <etienne@depar.is>'])
        about_dialog.run()
        about_dialog.destroy()


    def kthxbye(self, widget):
        gtk.main_quit()


if __name__ == "__main__":
    SystrayIconApp()
    gtk.main()

Added hubic_busy.png.

cannot compute difference between binary files

Added hubic_error.png.

cannot compute difference between binary files

Added po/en_US/LC_MESSAGES/hubic-gtk.mo.

cannot compute difference between binary files

Added po/en_US/LC_MESSAGES/hubic-gtk.po.

















































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# HubicStatus Translation Effort
# Copyright (C) 2014 HubicStatus volunteers
# This file is distributed under the same license as the HubicStatus package.
# Étienne Deparis <etienne@depar.is>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: HubicStatus 0.3\n"
"Report-Msgid-Bugs-To: bugs@depar.is\n"
"POT-Creation-Date: 2015-08-06 14:32+0200\n"
"PO-Revision-Date: 2015-08-06 14:33+0200\n"
"Last-Translator: Étienne Deparis <etienne@depar.is>\n"
"Language-Team: English\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.2\n"

#: hubic-gtk.py:27
msgid "Idle"
msgstr "Up to date"

#: hubic-gtk.py:28
msgid "Busy"
msgstr "Busy"

#: hubic-gtk.py:29
msgid "Paused"
msgstr "Paused"

#: hubic-gtk.py:30
msgid "Connecting"
msgstr "Connecting"

#: hubic-gtk.py:31
msgid "NotConnected"
msgstr "Not connected"

#: hubic-gtk.py:32
msgid "Synchronized"
msgstr "Synchronized"

#: hubic-gtk.py:33
msgid "Unsynchronized"
msgstr "Unsynchronized"

#: hubic-gtk.py:34
msgid "NoStatus"
msgstr "File is filtered out or outside of hubiC folder"

#: hubic-gtk.py:35
msgid "Error"
msgstr "Error"

#: hubic-gtk.py:36
msgid "Starting"
msgstr "Starting"

#: hubic-gtk.py:37
msgid "Killed"
msgstr "Killed"

#: hubic-gtk.py:149
msgid "Pease enter your password"
msgstr "Pease enter your password"

#: hubic-gtk.py:172
#, python-brace-format
msgid "Umount {0}"
msgstr "Umount {0}"

#: hubic-gtk.py:175
#, python-brace-format
msgid "Mount {0}"
msgstr "Mount {0}"

#: hubic-gtk.py:180
msgid "Encrypted repositories"
msgstr "Encrypted repositories"

#: hubic-gtk.py:191 hubic-gtk.py:193
msgid "HubicStatus Secure Repositories"
msgstr "HubicStatus Secure Repositories"

#: hubic-gtk.py:206
#, python-brace-format
msgid "No config file path declared for {0}"
msgstr "No config file path declared for {0}"

#: hubic-gtk.py:217 hubic-gtk.py:223
#, python-brace-format
msgid ""
"{0} already exists in your file system but is NOT an empty folder. Please "
"fix it and then retry to mount {1}"
msgstr ""
"{0} already exists in your file system but is NOT an empty folder. Please "
"fix it and then retry to mount {1}"

#: hubic-gtk.py:243
#, python-brace-format
msgid ""
"Error while reading your password from {0}. Please check if everything is OK "
"before retrying."
msgstr ""
"Error while reading your password from {0}. Please check if everything is OK "
"before retrying."

#: hubic-gtk.py:254
#, python-brace-format
msgid "{0} correctly mounted"
msgstr "{0} correctly mounted"

#: hubic-gtk.py:261
#, python-brace-format
msgid "An error occured while mounting {0}"
msgstr "An error occured while mounting {0}"

#: hubic-gtk.py:267
#, python-brace-format
msgid "{0} successfully umounted"
msgstr "{0} successfully umounted"

#: hubic-gtk.py:271
#, python-brace-format
msgid "An error occured while umounting {0}"
msgstr "An error occured while umounting {0}"

#: hubic-gtk.py:350
#, python-brace-format
msgid "{0} Resume Hubic as network is up"
msgstr "{0} Resume hubiC as network is up"

#: hubic-gtk.py:358
#, python-brace-format
msgid "{0} Pause Hubic as network connectivity seems to be down"
msgstr "{0} Pause hubiC as network connectivity seems to be down"

#: hubic-gtk.py:455
#, python-brace-format
msgid "{0} {1} ({2}%) used on {3} {4} total"
msgstr "{0} {1} ({2}%) used on {3} {4} total"

#: hubic-gtk.py:471
#, python-brace-format
msgid "Up: {0} {1}/s – Down: {2} {3}/s"
msgstr "Up: {0} {1}/s – Down: {2} {3}/s"

#: hubic-gtk.py:496
#, python-brace-format
msgid "{0} waiting ({1} {2} up – {3} {4} down)"
msgstr "{0} waiting ({1} {2} up – {3} {4} down)"

#: hubic-gtk.py:507
msgid "Current transfers"
msgstr "Current transfers"

#: hubic-gtk.py:514
msgid "Start Hubic"
msgstr "Start hubiC"

#: hubic-gtk.py:523
msgid "Resume synchronization"
msgstr "Resume synchronization"

#: hubic-gtk.py:527
msgid "Suspend synchronization"
msgstr "Suspend synchronization"

#: hubic-gtk.py:535
msgid "Stop Hubic"
msgstr "Stop hubiC"

#: hubic-gtk.py:548
msgid "Show notification messages"
msgstr "Show notification messages"

#: hubic-gtk.py:569
msgid "Last messages"
msgstr "Last messages"

#: hubic-gtk.py:656
msgid ""
"An attempt to get a status icon for hubiC on Gnu/Linux and provide an easy "
"way to manage your encfs synchronised folders."
msgstr ""
"An attempt to get a status icon for hubiC on Gnu/Linux and provide an easy "
"way to manage your encfs synchronised folders."

#: hubic-gtk.py:660
msgid ""
"HubicGTK is released under the WTF public license\n"
"Status icons use famfamfam silk icons, released under CC By 2.5 license"
msgstr ""
"HubicGTK is released under the WTF public license\n"
"Status icons use famfamfam silk icons, released under CC By 2.5 license"

#~ msgid "An attempt to get a status icon for Hubic on Linux"
#~ msgstr "An attempt to get a status icon for Hubic on Linux"

Added po/fr/LC_MESSAGES/hubic-gtk.mo.

cannot compute difference between binary files

Added po/fr/LC_MESSAGES/hubic-gtk.po.























































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# HubicStatus Translation Effort
# Copyright (C) 2014 HubicStatus volunteers
# This file is distributed under the same license as the HubicStatus package.
# Étienne Deparis <etienne@depar.is>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: HubicStatus 0.3\n"
"Report-Msgid-Bugs-To: bugs@depar.is\n"
"POT-Creation-Date: 2015-08-06 14:32+0200\n"
"PO-Revision-Date: 2015-08-06 14:32+0200\n"
"Last-Translator: Étienne Deparis <etienne@depar.is>\n"
"Language-Team: French <traduc@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Poedit 1.8.2\n"

#: hubic-gtk.py:27
msgid "Idle"
msgstr "À jour"

#: hubic-gtk.py:28
msgid "Busy"
msgstr "Occupé"

#: hubic-gtk.py:29
msgid "Paused"
msgstr "En pause"

#: hubic-gtk.py:30
msgid "Connecting"
msgstr "Connexion en cours"

#: hubic-gtk.py:31
msgid "NotConnected"
msgstr "Non connecté"

#: hubic-gtk.py:32
msgid "Synchronized"
msgstr "Synchronisé"

#: hubic-gtk.py:33
msgid "Unsynchronized"
msgstr "Désynchronisé"

#: hubic-gtk.py:34
msgid "NoStatus"
msgstr "Le fichier est filtré ou en dehors de votre dossier hubiC"

#: hubic-gtk.py:35
msgid "Error"
msgstr "ERREUR"

#: hubic-gtk.py:36
msgid "Starting"
msgstr "Démarrage"

#: hubic-gtk.py:37
msgid "Killed"
msgstr "Arrêté"

#: hubic-gtk.py:149
msgid "Pease enter your password"
msgstr "Merci d'entrer votre mot de passe"

#: hubic-gtk.py:172
#, python-brace-format
msgid "Umount {0}"
msgstr "Démonter {0}"

#: hubic-gtk.py:175
#, python-brace-format
msgid "Mount {0}"
msgstr "Monter {0}"

#: hubic-gtk.py:180
msgid "Encrypted repositories"
msgstr "Dossiers cryptés"

#: hubic-gtk.py:191 hubic-gtk.py:193
msgid "HubicStatus Secure Repositories"
msgstr "HubicStatus Dossiers protégés"

#: hubic-gtk.py:206
#, python-brace-format
msgid "No config file path declared for {0}"
msgstr "Aucun chemin valide n'a été déclaré pour le fichier de config de {0}"

#: hubic-gtk.py:217 hubic-gtk.py:223
#, python-brace-format
msgid ""
"{0} already exists in your file system but is NOT an empty folder. Please "
"fix it and then retry to mount {1}"
msgstr ""
"{0} existe déjà dans votre système de fichier mais n'est PAS un dossier "
"vide. Merci d'effectuer les actions nécessaires avant de retenter de monter "
"{1}."

#: hubic-gtk.py:243
#, python-brace-format
msgid ""
"Error while reading your password from {0}. Please check if everything is OK "
"before retrying."
msgstr ""
"Une erreur est survenue lors de la lecture de votre mot de passe depuis {0}. "
"Merci de vérifier que le fichier est bien accessible avant de réessayer."

#: hubic-gtk.py:254
#, python-brace-format
msgid "{0} correctly mounted"
msgstr "{0} correctement monté"

#: hubic-gtk.py:261
#, python-brace-format
msgid "An error occured while mounting {0}"
msgstr "Une erreur est survenue lors du montage de {0}"

#: hubic-gtk.py:267
#, python-brace-format
msgid "{0} successfully umounted"
msgstr "{0} correctement démonté"

#: hubic-gtk.py:271
#, python-brace-format
msgid "An error occured while umounting {0}"
msgstr "Une erreur est survenue lors du démontage de {0}"

#: hubic-gtk.py:350
#, python-brace-format
msgid "{0} Resume Hubic as network is up"
msgstr "{0} hubiC est relancé car le réseau est de nouveau accessible"

#: hubic-gtk.py:358
#, python-brace-format
msgid "{0} Pause Hubic as network connectivity seems to be down"
msgstr "{0} hubiC est passé en pause car le réseau n'est plus accessible"

#: hubic-gtk.py:455
#, python-brace-format
msgid "{0} {1} ({2}%) used on {3} {4} total"
msgstr "{0} {1} ({2}%) utilisé sur un total de {3} {4}"

#: hubic-gtk.py:471
#, python-brace-format
msgid "Up: {0} {1}/s – Down: {2} {3}/s"
msgstr "Débit montant : {0} {1}/s – Descendant : {2} {3}/s"

#: hubic-gtk.py:496
#, python-brace-format
msgid "{0} waiting ({1} {2} up – {3} {4} down)"
msgstr "{0} en attente ({1} {2} montant – {3} {4} descendant)"

#: hubic-gtk.py:507
msgid "Current transfers"
msgstr "Transferts actuels"

#: hubic-gtk.py:514
msgid "Start Hubic"
msgstr "Démarrer hubiC"

#: hubic-gtk.py:523
msgid "Resume synchronization"
msgstr "Relancer la synchronisation"

#: hubic-gtk.py:527
msgid "Suspend synchronization"
msgstr "Suspendre la synchronisation"

#: hubic-gtk.py:535
msgid "Stop Hubic"
msgstr "Arrêter hubiC"

#: hubic-gtk.py:548
msgid "Show notification messages"
msgstr "Afficher les messages de notification"

#: hubic-gtk.py:569
msgid "Last messages"
msgstr "Derniers messages"

#: hubic-gtk.py:656
msgid ""
"An attempt to get a status icon for hubiC on Gnu/Linux and provide an easy "
"way to manage your encfs synchronised folders."
msgstr ""
"Un essai d'icône de statut pour hubiC sous Gnu/Linux permettant également de "
"gérer vos dossiers synchronisés chiffrés avec encfs."

#: hubic-gtk.py:660
msgid ""
"HubicGTK is released under the WTF public license\n"
"Status icons use famfamfam silk icons, released under CC By 2.5 license"
msgstr ""
"HubicGTK est disponible selon les termes de la WTF public license\n"
"Les icônes de statuts utilisent les icônes Silk de famfamfam,\n"
"disponibles selon les termes d'un contrat Creative Commons Attribution en "
"version 2.5"

#~ msgid "An attempt to get a status icon for Hubic on Linux"
#~ msgstr "Un essai pour avoir une icône de statut pour hubiC sous Gnu/Linux"

Added po/hubic-gtk.pot.

























































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# HubicGTK Translation Effort
# Copyright (C) YEAR HubicGTK volunteers
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: HubicGTK 0.5\n"
"Report-Msgid-Bugs-To: bugs@depar.is\n"
"POT-Creation-Date: 2015-08-06 14:32+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: hubic-gtk.py:27
msgid "Idle"
msgstr ""

#: hubic-gtk.py:28
msgid "Busy"
msgstr ""

#: hubic-gtk.py:29
msgid "Paused"
msgstr ""

#: hubic-gtk.py:30
msgid "Connecting"
msgstr ""

#: hubic-gtk.py:31
msgid "NotConnected"
msgstr ""

#: hubic-gtk.py:32
msgid "Synchronized"
msgstr ""

#: hubic-gtk.py:33
msgid "Unsynchronized"
msgstr ""

#: hubic-gtk.py:34
msgid "NoStatus"
msgstr ""

#: hubic-gtk.py:35
msgid "Error"
msgstr ""

#: hubic-gtk.py:36
msgid "Starting"
msgstr ""

#: hubic-gtk.py:37
msgid "Killed"
msgstr ""

#: hubic-gtk.py:149
msgid "Pease enter your password"
msgstr ""

#: hubic-gtk.py:172
#, python-brace-format
msgid "Umount {0}"
msgstr ""

#: hubic-gtk.py:175
#, python-brace-format
msgid "Mount {0}"
msgstr ""

#: hubic-gtk.py:180
msgid "Encrypted repositories"
msgstr ""

#: hubic-gtk.py:191 hubic-gtk.py:193
msgid "HubicStatus Secure Repositories"
msgstr ""

#: hubic-gtk.py:206
#, python-brace-format
msgid "No config file path declared for {0}"
msgstr ""

#: hubic-gtk.py:217 hubic-gtk.py:223
#, python-brace-format
msgid ""
"{0} already exists in your file system but is NOT an empty folder. Please "
"fix it and then retry to mount {1}"
msgstr ""

#: hubic-gtk.py:243
#, python-brace-format
msgid ""
"Error while reading your password from {0}. Please check if everything is OK "
"before retrying."
msgstr ""

#: hubic-gtk.py:254
#, python-brace-format
msgid "{0} correctly mounted"
msgstr ""

#: hubic-gtk.py:261
#, python-brace-format
msgid "An error occured while mounting {0}"
msgstr ""

#: hubic-gtk.py:267
#, python-brace-format
msgid "{0} successfully umounted"
msgstr ""

#: hubic-gtk.py:271
#, python-brace-format
msgid "An error occured while umounting {0}"
msgstr ""

#: hubic-gtk.py:350
#, python-brace-format
msgid "{0} Resume Hubic as network is up"
msgstr ""

#: hubic-gtk.py:358
#, python-brace-format
msgid "{0} Pause Hubic as network connectivity seems to be down"
msgstr ""

#: hubic-gtk.py:455
#, python-brace-format
msgid "{0} {1} ({2}%) used on {3} {4} total"
msgstr ""

#: hubic-gtk.py:471
#, python-brace-format
msgid "Up: {0} {1}/s – Down: {2} {3}/s"
msgstr ""

#: hubic-gtk.py:496
#, python-brace-format
msgid "{0} waiting ({1} {2} up – {3} {4} down)"
msgstr ""

#: hubic-gtk.py:507
msgid "Current transfers"
msgstr ""

#: hubic-gtk.py:514
msgid "Start Hubic"
msgstr ""

#: hubic-gtk.py:523
msgid "Resume synchronization"
msgstr ""

#: hubic-gtk.py:527
msgid "Suspend synchronization"
msgstr ""

#: hubic-gtk.py:535
msgid "Stop Hubic"
msgstr ""

#: hubic-gtk.py:548
msgid "Show notification messages"
msgstr ""

#: hubic-gtk.py:569
msgid "Last messages"
msgstr ""

#: hubic-gtk.py:656
msgid ""
"An attempt to get a status icon for hubiC on Gnu/Linux and provide an easy "
"way to manage your encfs synchronised folders."
msgstr ""

#: hubic-gtk.py:660
msgid ""
"HubicGTK is released under the WTF public license\n"
"Status icons use famfamfam silk icons, released under CC By 2.5 license"
msgstr ""