source: lliurex-gdrive/trunk/fuentes/lliurex-gdrive-indicator.install/usr/bin/lliurexGdriveIndicator @ 4034

Last change on this file since 4034 was 4034, checked in by jrpelegrina, 4 years ago

End initial release

  • Property svn:executable set to *
File size: 11.6 KB
Line 
1#!/usr/bin/env python
2
3import gi
4gi.require_version('Gtk', '3.0')
5from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject, GLib
6gi.require_version('AppIndicator3', '0.1')
7from gi.repository import AppIndicator3 as appindicator
8
9import os
10import threading
11import subprocess
12import sys
13import gettext
14import json
15import random
16import notify2
17
18
19import pyinotify
20from pyinotify import WatchManager, Notifier, ThreadedNotifier, EventsCodes, ProcessEvent
21
22import signal
23signal.signal(signal.SIGINT, signal.SIG_DFL)
24
25import lliurex.lliurexgdrive
26
27import gettext
28gettext.textdomain('lliurex-gdrive')
29_ = gettext.gettext
30
31LOCK_INDICATOR="/tmp/lgdIndicator.lock"
32LOCK_GUI="/tmp/lgdGUI.lock"
33RSRC="/usr/share/lliurex-gdrive/"
34MOUNT_ON_IMAGE=RSRC+"rsrc/mount_on.png"
35MOUNT_OFF_IMAGE=RSRC+"rsrc/mount_off.png"
36MOUNT_WARNING_IMAGE=RSRC+"rsrc/mount_warning.png"
37SP1=RSRC+"rsrc/sp1.png"
38SP2=RSRC+"rsrc/sp2.png"
39SP3=RSRC+"rsrc/sp3.png"
40SP4=RSRC+"rsrc/sp4.png"
41
42TIME_CHECK_STATUS=900000
43
44class LlliurexGdriveIndicator:
45
46        WATCH_DIR=os.path.expanduser("~/.config/lliurex-google-drive-profiles/configProfiles")
47       
48        def __init__(self,icon_name):
49               
50                self.LliurexGoogleDriveManager=lliurex.lliurexgdrive.LliurexGoogleDriveManager()
51                self.app_indicator=appindicator.Indicator.new("lliurex-gdrive",icon_name,appindicator.IndicatorCategory.APPLICATION_STATUS)
52                self.app_indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
53                self.menu = Gtk.Menu()
54               
55                self.menu.add_events(Gdk.EventMask.ALL_EVENTS_MASK)
56                self.app_indicator.set_menu(self.menu)
57               
58                self.profiles_info=self.LliurexGoogleDriveManager.profiles_config.copy()
59                self.current_status={}
60
61                       
62                self.createLockToken()
63                self.check_initial_connection()
64                self.populate_menu()
65                self.start_inotify()
66                self.sync_threads={}
67                self.result_sync_threads={}
68                self.profile_clicked=[]
69                self.sp_cont={}
70                self.sp_img={}
71                self.checking_status=False
72               
73
74                GLib.timeout_add(TIME_CHECK_STATUS,self.check_status)
75               
76        #def __init__
77
78        def check_initial_connection(self):
79               
80                self.initial_connection=self.LliurexGoogleDriveManager.check_google_connection()
81                return
82
83        def generate_sync_threads(self,profile):
84               
85                id=int(random.random()*1000)           
86                t=threading.Thread(target=self.check_sync,args=(id,profile))
87                t.daemon=True
88                t.start()
89                self.sync_threads[id]={}
90                self.sync_threads[id]["thread"]=t
91                self.result_sync_threads[id]={}
92                return id
93       
94        def init_connect_thread(self):
95               
96                self.check_connect_t=threading.Thread(target=self.check_connect)
97                self.check_connect_t.daemon=True
98                self.check_connect_t.start()
99               
100        def createLockToken(self):
101
102                #self.lockpath=os.path(LOCK_INDICATOR)
103                if not os.path.exists(LOCK_INDICATOR):
104                        f=open(LOCK_INDICATOR,'w')
105                        f.close
106
107        #def createLockToken
108                       
109        def start_inotify(self):
110
111                t=threading.Thread(target=self._inotify)
112                t.daemon=True
113                t.start()
114
115        #def start_inotif
116
117
118        def _inotify(self):
119               
120               
121                wm=WatchManager()
122                mask=pyinotify.IN_CLOSE_WRITE
123                       
124                class Process_handler(ProcessEvent):
125                               
126                        def __init__(self,main):
127                               
128                                self.main=main
129                               
130                        def process_IN_CLOSE_WRITE(self,event):
131
132                                self.main.update_info()
133                                self.main.initial_connection=True
134                                for profile in self.main.update_profiles:
135                                        if not profile in self.main.profiles_info:
136                                                mountpoint=self.main.update_profiles[profile]["mountpoint"]
137                                                self.main.add_menu_item(profile,mountpoint)
138
139                                for item in self.main.menu.get_children():
140                                        if item.profile !="":
141                                                if not item.profile in self.main.update_profiles:
142                                                        self.main.menu.remove(item)     
143                               
144                                self.main.profiles_info=self.main.update_profiles.copy()
145                                self.main.menu.show_all()                                       
146                                                               
147       
148                notifier=Notifier(wm,Process_handler(self))
149                wdd=wm.add_watch(LlliurexGdriveIndicator.WATCH_DIR,mask,rec=True)
150                       
151                while True:
152                        try:
153                                       
154                                notifier.process_events()
155                                if notifier.check_events():
156                                        notifier.read_events()
157                               
158                        except Exception as e:
159                                notifier.stop()
160                                       
161                return False
162       
163        #def _inotify
164
165        def update_info(self):
166
167                f=open(self.LliurexGoogleDriveManager.config_file)
168
169                try:
170                        self.update_profiles=json.load(f)
171                except:
172                        self.update_profiles={}
173               
174                f.close()
175
176        #def update_info       
177       
178        def add_menu_item(self,profile,mountpoint):
179
180                if self.initial_connection:
181                        status_info=self.LliurexGoogleDriveManager.check_mountpoint_status(mountpoint)
182                        info=self.item_status_info(status_info)
183                        self.current_status[profile]=status_info["status"]     
184                else:
185                        status_info={}
186                        status_info['status']=None
187                        status_info['size']=0
188                        status_info['used']=0
189                        info=self.item_status_info(status_info)
190                        self.current_status[profile]=None
191                               
192                label_item=profile     
193                item=Gtk.ImageMenuItem()
194                item.set_label(label_item)
195                item.set_image(info["img"])
196                item.set_tooltip_text(info["tooltip"])
197                item.profile=profile
198                item.size=False
199                item.status=True
200                item.set_always_show_image(True)
201                item.connect("activate",self.item_clicked,profile)
202                self.menu.insert(item,0)
203
204               
205                item=Gtk.MenuItem()
206                label_item=info["used_size"]
207                item.set_label(label_item)
208                item.profile=profile
209                item.size=True
210                item.status=False
211                self.menu.insert(item,1)
212
213                item=Gtk.MenuItem()
214                label_item=_("Open folder")
215                item.set_label(label_item)
216                item.connect("activate",self.open_folder,profile)
217                item.profile=profile
218                item.size=False
219                item.status=False
220                self.menu.insert(item,2)
221
222                item=Gtk.SeparatorMenuItem()
223                item.profile=profile
224                item.size=False
225                item.status=False
226                self.menu.insert(item,3)
227
228        #def add_menu_item     
229
230
231        def populate_menu(self,empty=True):
232               
233               
234                if empty:
235                        for c in self.menu.get_children():
236                                self.menu.remove(c)
237               
238               
239                for profile in self.profiles_info:
240                        mountpoint=self.profiles_info[profile]["mountpoint"]
241                        self.add_menu_item(profile,mountpoint)
242                       
243                       
244                item=Gtk.ImageMenuItem()
245                label_item=_("Open Lliurex GDrive")
246                item.set_label(label_item)
247                img=Gtk.Image()
248                img.set_from_stock(Gtk.STOCK_PREFERENCES,Gtk.IconSize.MENU)
249                item.set_image(img)
250                item.set_always_show_image(True)
251                item.connect("activate",self.open_gui)
252                item.profile=""
253                item.size=False
254                item.status=False
255                self.menu.append(item)
256
257                item=Gtk.ImageMenuItem()
258                img=Gtk.Image()
259                img.set_from_stock(Gtk.STOCK_CLOSE,Gtk.IconSize.MENU)
260                item.set_image(img)
261                item.set_always_show_image(True)
262                label_item=_("Close")
263                item.set_label(label_item)
264                item.connect("activate",self.quit)
265                item.profile=""
266                item.size=False
267                item.status=False
268                self.menu.append(item)
269
270
271                self.menu.show_all()
272               
273               
274        #def populate_menu
275       
276       
277        def item_clicked(self,widget,profile):
278       
279                if profile not in self.profile_clicked:
280                        self.profile_clicked.append(profile)
281                        id=self.generate_sync_threads(profile)
282                        self.sp_cont[id]=0
283                        self.sp_img[id]=Gtk.Image.new_from_file(SP1)
284                        GLib.timeout_add(100,self.pulsate_check_sync,id,widget,profile)
285                       
286               
287        #def item_clicked
288
289        def spinner_sync(self,id):
290       
291                if self.sp_cont[id]>40:
292                        self.sp_cont[id]=0
293                       
294                if self.sp_cont[id]==0:
295                        img=Gtk.Image.new_from_file(SP1)
296                        self.sp_img[id]=img
297                elif self.sp_cont[id]==10:
298                        img=Gtk.Image.new_from_file(SP2)
299                        self.sp_img[id]=img                     
300                elif self.sp_cont[id]==20:
301                        img=Gtk.Image.new_from_file(SP3)
302                        self.sp_img[id]=img
303                elif self.sp_cont[id]==30:
304                        img=Gtk.Image.new_from_file(SP4)
305                        self.sp_img[id]=img
306                               
307               
308                       
309        def pulsate_check_sync(self,id,widget,profile):
310               
311               
312                if self.sync_threads[id]["thread"].is_alive():
313                        self.spinner_sync(id)
314                        widget.set_image(self.sp_img[id])
315                        widget.set_tooltip_text(_("Applying changes..."))       
316                        self.sp_cont[id]=self.sp_cont[id]+1
317                        return True
318               
319                else:
320                        self.profile_clicked.remove(profile)
321                        self.current_status[profile]=self.result_sync_threads[id]["status_info"]["status"]     
322                        if self.result_sync_threads[id]["status_mod"]["result"]==False:
323                                if self.result_sync_threads[id]["status_mod"]["code"]==8:
324                                        message=_("Error: Unable to connect with google")       
325                                else:
326                                        status=self.current_status[profile]
327                                        if status:
328                                                action=_("dismount")
329                                        else:
330                                                action=_("mount")       
331                                        message=_("Error: Unable to ") + action + " " 
332                        else:
333                                if self.result_sync_threads[id]["status_mod"]["code"]==9:
334                                        message=_("Status updated. Now you can change it")
335                                else:
336                                        message=_("Changes applied successfully")
337                       
338                        self.show_message(profile + ": " + message)
339                       
340                        info=self.item_status_info(self.result_sync_threads[id]["status_info"])
341                       
342                        for item in self.menu.get_children():
343                                        if item.size:
344                                                if item.profile==profile:
345                                                        item.set_label(info["used_size"])
346                               
347                        widget.set_tooltip_text(info["tooltip"])
348                        widget.set_image(info["img"])   
349                        self.sync_threads.pop(id)
350                        self.sp_cont.pop(id)
351                        self.sp_img.pop(id)
352                        self.result_sync_threads.pop(id)
353               
354                return False
355                       
356       
357        def     check_sync(self,id,profile):
358               
359                mountpoint=self.profiles_info[profile]["mountpoint"]
360
361                current_status=self.current_status[profile]
362               
363                self.result_sync_threads[id]["status_mod"],self.result_sync_threads[id]["status_info"]=self.LliurexGoogleDriveManager.sync_profile(profile,mountpoint,current_status)
364
365
366                #self.result_connect_threads[id]["value"]=self.LliurexGoogleDriveManager.check_google_connection()
367       
368        def open_folder(self,widget,profile):
369
370               
371                mountpoint=self.profiles_info[profile]["mountpoint"]
372                cmd="caja " + mountpoint.encode("utf-8")
373
374                os.system(cmd) 
375
376        #def open_folder       
377
378        def open_gui(self,widget):
379               
380                if not os.path.exists(LOCK_GUI):
381                        cmd='/usr/bin/lliurex-gdrive' +"&" 
382                        os.system(cmd)
383
384        #def open_gui
385               
386        def item_status_info(self,status_info):
387       
388                size=status_info["size"]
389                used=status_info["used"]
390
391                if status_info['status']==None:
392                        img=Gtk.Image.new_from_file(MOUNT_WARNING_IMAGE)
393                        tooltip=_("Without connection. Clicked to update")
394                        used_size=_("Used: not available")
395               
396                elif    status_info["status"]:
397                        img=Gtk.Image.new_from_file(MOUNT_ON_IMAGE)
398                        tooltip=_("Mounted. Clicked to dismount now")
399                        used_size=_("Used: %s of %s")%(used,size)
400               
401                else:
402                        img=Gtk.Image.new_from_file(MOUNT_OFF_IMAGE)
403                        tooltip=_("Dismounted. Clicked to mount now")
404                        used_size=_("Used: not available")     
405
406                return {"img":img ,"tooltip":tooltip, "used_size":used_size}   
407
408        #def item_status_info                   
409
410        def check_status(self):
411               
412                if not self.checking_status:
413                        self.checking_status=True
414                        self.init_connect_thread()
415                        GLib.timeout_add(100,self.get_status_info,id)
416
417                return True
418               
419               
420        #def check_status
421       
422        def get_status_info(self,id):
423               
424                if self.check_connect_t.is_alive():
425                        return True
426               
427                else:   
428                        self.checking_status=False
429                        #self.connect_threads.pop(id)
430                        for profile in self.profiles_info:
431                                if self.connection:
432                                        mountpoint=self.profiles_info[profile]["mountpoint"]
433                                        status_info=self.LliurexGoogleDriveManager.check_mountpoint_status(mountpoint)
434                                else:
435                                        status_info={}
436                                        status_info['status']=None
437                                        status_info['size']=0
438                                        status_info['used']=0
439                                       
440                                info=self.item_status_info(status_info)
441                                self.current_status[profile]=status_info["status"]
442                                                               
443                                for item in self.menu.get_children():
444                                        if item.profile==profile:
445                                                if item.size:
446                                                        item.set_label(info["used_size"])
447                                                if item.status:
448                                                        item.set_tooltip_text(info["tooltip"])
449                                                        item.set_image(info["img"])
450               
451                #self.result_connect_threads.pop(id)           
452                return False   
453                                       
454        def check_connect(self):
455               
456                self.connection=self.LliurexGoogleDriveManager.check_google_connection()
457
458       
459        def show_message(self,message):
460                notify2.init("test")
461                n=notify2.Notification("Lliurex-GDrive",message,"gdrive")
462                n.show()
463                return
464                               
465       
466        def cleanIndicatorLock(self):
467
468                if os.path.exists(LOCK_INDICATOR):
469                        os.remove(LOCK_INDICATOR)
470
471        #def cleanIndicatorLock                 
472       
473        def quit(self,widget):
474
475                self.cleanIndicatorLock()
476                Gtk.main_quit() 
477
478        #def quit       
479
480       
481#class LlliurexGdriveIndicator
482
483if __name__=="__main__":
484       
485        lliurexgdrive=LlliurexGdriveIndicator("gdrive")
486        GObject.threads_init()
487        Gtk.main()
488       
Note: See TracBrowser for help on using the repository browser.