source: air-manager/trunk/fuentes/air-manager/src/InstallBox.py @ 7408

Last change on this file since 7408 was 7408, checked in by Juanma, 21 months ago

fix icon

File size: 10.6 KB
Line 
1#!/usr/bin/env python3
2
3
4import gi
5gi.require_version('Gtk', '3.0')
6from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject,GLib
7
8import copy
9import gettext
10import Core
11
12#import Dialog
13import dialog
14import time
15import threading
16import os
17from os.path import splitext
18import subprocess
19import tempfile
20
21import airmanager.airmanager as installer
22
23import gettext
24gettext.textdomain('air-manager')
25_ = gettext.gettext
26
27
28
29RSRC="/usr/share/air-manager/rsrc/"
30
31CSS_FILE=RSRC + "air-manager.css"
32DROP_FILE=RSRC+"drop_file.png"
33DROP_CORRECT=RSRC+"drop_file_correct.png"
34DROP_INCORRECT=RSRC+"drop_file_incorrect.png"
35DRAG_ACTION = Gdk.DragAction.COPY
36GTK_SPACING=6
37
38class InstallBox(Gtk.VBox):
39       
40        def __init__(self):
41                Gtk.VBox.__init__(self)
42                self.DROP_CORRECT=RSRC+"drop_file_correct.png"
43                self.pb=GdkPixbuf.Pixbuf()
44                self.air_file=''
45               
46                self.core=Core.Core.get_core()
47                self.commonFunc=CommonFunc()
48               
49                builder=Gtk.Builder()
50                builder.set_translation_domain('air-manager')
51                ui_path=RSRC + "air-manager.ui"
52                builder.add_from_file(ui_path)
53
54                self.lbl_air=builder.get_object("install_label")
55                self.lbl_air.props.halign=Gtk.Align.START
56                #Declared here because DropArea needs this references
57                self.img_icon=Gtk.Image()
58                self.pb=self.img_icon.get_pixbuf()
59                self.lbl_drop=Gtk.Label()
60
61                self.main_box=builder.get_object("install_data_box")
62                self.drop=builder.get_object("btn_drop")
63                self.drop.set_name("BTN_MENU")
64                self.drop.connect('clicked',self._filechooser)
65                self.drop_label=builder.get_object("drop_label")
66               
67                self.install_button=builder.get_object("install_button")
68                self.install_label=builder.get_object("install_label")
69               
70                self.check_window=builder.get_object("check_window")
71                self.check_label=builder.get_object("check_label")
72                self.check_pbar=builder.get_object("check_pbar")
73
74                drop_param=[self.install_label,self.install_button]
75                self.drop_area=DropArea(drop_param)
76                self.drop_area.set_info_widgets(self.lbl_drop,self.img_icon)
77                drop_box=Gtk.Box(spacing=12)
78                msg=_("<b>Drag</b> an air file\nor <b>click</b> to choose")
79                self.lbl_drop.set_markup(msg)
80                drop_box.add(self.lbl_drop)
81                drop_box.add(self.drop_area)
82                drop_box.props.halign=Gtk.Align.CENTER
83                self.drop.add(drop_box) 
84                self.drop.set_margin_top(12)
85                               
86                self.img_icon.set_from_file(RSRC+"air-installer_icon.png")
87                self.pb=self.img_icon.get_pixbuf()
88
89                lbl_text=_("Click to <b>select an icon</b> for the app or use the app's default icon")
90                lbl_icon=Gtk.Label()
91                lbl_icon.props.halign=Gtk.Align.END
92                lbl_icon.props.hexpand=False
93                lbl_icon.set_markup(lbl_text)
94                lbl_icon.set_name('label')
95                lbl_icon.set_max_width_chars(20)
96                lbl_icon.set_width_chars(20)
97                lbl_icon.set_line_wrap(True)
98
99                self.box_icon=Gtk.Box(spacing=6)
100                self.box_icon.add(lbl_icon)
101                self.box_icon.add(self.img_icon)
102
103                self.btn_icon=builder.get_object('btn_icon')
104                self.btn_icon.set_name("BTN_MENU")
105                self.box_icon.props.halign=Gtk.Align.CENTER
106                self.btn_icon.add(self.box_icon)
107                self.btn_icon.set_margin_top(12)
108
109
110                self.pack_start(self.main_box,True,True,0)
111       
112                self.add_text_targets()
113                self.connect_signals()
114                self.set_css_info()
115                self.install_button.set_sensitive(False)
116                self.btn_icon.connect("clicked",self._set_app_icon)
117                GObject.threads_init()
118        #def __init__
119
120        def _debug(self,msg):
121                print("InstallBox: %s"%msg)
122        #def _debug
123
124        def _filechooser(self,*args):
125                dw=Gtk.FileChooserDialog(_("Select air package"),None,Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
126                dw.set_action(Gtk.FileChooserAction.OPEN)
127                file_filter=Gtk.FileFilter()
128                file_filter.add_pattern('*.air')
129                file_filter.set_name("Air files")
130                dw.add_filter(file_filter)
131                air_chooser=dw.run()
132                if air_chooser==Gtk.ResponseType.OK:
133                        self.install_label.set_text('')
134                        self.drop_area.air_file=dw.get_filename()
135                        self.drop_area.set_from_file(DROP_CORRECT)
136                        self.install_button.set_sensitive(True)
137                        self.lbl_drop.set_markup(_("<b>Selected app:</b>\n%s")%os.path.basename(self.drop_area.air_file))
138                        air_info=installer.AirManager().get_air_info(self.drop_area.air_file)
139                        self.img_icon.set_from_pixbuf(air_info['pb'])
140                        self.pb=air_info['pb']
141                dw.destroy()
142        #def _filechooser
143
144        def add_text_targets(self):
145                self.drop_area.drag_dest_set_target_list(None)
146                self.drop_area.drag_dest_add_text_targets()
147        #def add_text_targets
148       
149        def _set_app_icon(self,widget):
150               
151                def _update_preview(*arg):
152                        if dw.get_preview_filename():
153                                if os.path.isfile(dw.get_preview_filename()):
154                                        pb=GdkPixbuf.Pixbuf.new_from_file_at_scale(dw.get_preview_filename(),64,-1,True)
155                                        img_preview.set_from_pixbuf(pb)
156                                        img_preview.show()
157                        else:
158                                img_preview.hide()
159
160                dw=Gtk.FileChooserDialog(_("Select icon"),None,Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
161                dw.set_action(Gtk.FileChooserAction.OPEN)
162                img_preview=Gtk.Image()
163                img_preview.set_margin_right(GTK_SPACING)
164                file_filter=Gtk.FileFilter()
165                file_filter.add_pixbuf_formats()
166                file_filter.set_name("images")
167                dw.add_filter(file_filter)
168                dw.set_preview_widget(img_preview)
169                img_preview.show()
170                dw.set_use_preview_label(False)
171                dw.set_preview_widget_active(True)
172                dw.connect("update-preview",_update_preview)
173                new_icon=dw.run()
174                if new_icon==Gtk.ResponseType.OK:
175                        self.pb=GdkPixbuf.Pixbuf.new_from_file_at_scale(dw.get_filename(),64,-1,True)
176                        self.img_icon.set_from_pixbuf(self.pb)
177                dw.destroy()
178        #def _set_app_icon
179 
180        def connect_signals(self):
181                self.install_button.connect("clicked",self.accept_install_clicked)
182        #def connect_signals   
183
184        def set_css_info(self):
185                self.style_provider=Gtk.CssProvider()
186
187                f=Gio.File.new_for_path(CSS_FILE)
188                self.style_provider.load_from_file(f)
189
190                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
191                self.check_label.set_name("MSG_LABEL")
192        #def set_css_info       
193
194        def accept_install_clicked(self,widget):
195                self.install_label.set_text("")
196                tmp_icon=tempfile.mkstemp()[1]
197                self._debug(tmp_icon)
198                #Copy the icon to temp folder
199                self.pb=self.img_icon.get_pixbuf()
200                self.pb.savev(tmp_icon,'png',[""],[""])
201                air_file=self.drop_area.air_file
202                self.install_t=threading.Thread(target=self.install,args=[air_file,tmp_icon])
203                self.install_t.daemon=True
204                self.install_t.start()
205                self.check_window.show_all()
206                GLib.timeout_add(100,self.pulsate_install)
207        #def accept_install_clicked     
208
209        def pulsate_install(self):
210                if self.install_t.is_alive():
211                        self.check_pbar.pulse()
212                        return True
213
214                else:
215                        self.check_window.hide()
216                        if self.install_err:
217                                self.install_label.set_name("MSG_LABEL")
218                                msg=self.commonFunc.get_msg(self.install_err)
219                        else:
220                                self.install_label.set_name("MSG_ERROR_LABEL")
221                                msg=self.commonFunc.get_msg(0)
222                               
223                        self.install_label.set_text(msg)
224                       
225                        return False
226        #def pulsate_install           
227
228        def install(self,air_file,icon):
229                self.install_err=True
230                subprocess.check_call(['/usr/bin/xhost','+'])
231                try:
232                        ins=subprocess.check_call(['pkexec','/usr/bin/air-helper-installer.py','install',air_file,icon])
233                        self.install_err=False
234                except Exception as e:
235                        self._debug(e)
236                subprocess.check_output(["xdg-mime","install","/usr/share/mime/packages/x-air-installer.xml"])
237                subprocess.check_output(["xdg-mime","default","/usr/share/applications/air-installer.desktop","/usr/share/mime/packages/x-air-installer.xml"],input=b"")
238                subprocess.check_call(['/usr/bin/xhost','-'])
239        #def install
240       
241 #class InstallBox     
242
243               
244class DropArea(Gtk.Image):
245
246        def __init__(self,drop_param):
247                self.dbg=True
248                self.drop=False
249                self.commonFunc=CommonFunc()
250                self.install_label=drop_param[0]
251                self.install_button=drop_param[1]
252                Gtk.Image.__init__(self)
253                Gtk.Image.set_from_file(self,DROP_FILE)
254                self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)
255                self.air_file=''
256                self.info_label=''
257               
258                self.connect("drag-data-received", self.on_drag_data_received)
259
260                self.text=""
261    #def __init__               
262       
263        def _debug(self,msg):
264                if self.dbg:
265                        print("DropArea: %s"%msg)
266        #def _debug
267
268        def set_info_widgets(self,gtkLabel,gtkImg):
269                self.info_label=gtkLabel
270                self.img_icon=gtkImg
271
272        def on_drag_data_received(self, widget, drag_context, x,y, data,info, time):
273                self.drop=True
274                text = data.get_text()
275                text=text.strip().split("//")
276               
277                text[1]=text[1].replace('%20',' ')
278                self._debug("Checking %s"%text[1])
279                check=self.commonFunc.check_extension(text[1])
280
281                if check["status"]:
282                        self.install_label.set_text('')
283                        Gtk.Image.set_from_file(self,DROP_CORRECT)
284                        self.install_button.set_sensitive(True)
285                        self.air_file=text[1]
286                        if self.info_label:
287                                self.info_label.set_markup(_("<b>Selected app:</b>\n%s")%os.path.basename(self.air_file))
288                        air_info=installer.AirManager().get_air_info(self.air_file)
289                        self.img_icon.set_from_pixbuf(air_info['pb'])
290                        self.pb=air_info['pb']
291                        self._debug("File %s"%self.air_file)
292                else:
293                        Gtk.Image.set_from_file(self,DROP_INCORRECT)
294                        self.install_button.set_sensitive(False)
295                        self.air_file=''
296                       
297                param={'status':check['status'],'code':check['code'],'file_name':text[1],'install_label':self.install_label,'install_button':self.install_button}
298                self.commonFunc.manage_outputinfo(**param)     
299        #def on_drag_data_received
300       
301#class DropArea         
302
303
304class CommonFunc():
305
306        def _debug(self,msg):
307                print("%s"%msg)
308
309        def check_extension(self,file_name):
310                result={}
311                result["status"]=""
312                result["code"]=""
313               
314                if file_name ==None:
315                        result["status"]=False
316                        result["code"]=0
317                else:
318                        try:   
319                                if file_name.endswith('.air'):
320                                        result["status"]=True
321                                else:
322                                        result["status"]=False
323                                        result["code"]=1
324                        except:
325                                result["status"]=False
326                                result["code"]=2
327                                print ("Unable to detect extension"     )
328                self._debug(result)
329                return result   
330        #def check_extension   
331
332        def manage_outputinfo(self,**kwargs):
333                if kwargs:
334                        path=os.path.dirname(kwargs['file_name'])
335        #def manage_ouputinfo   
336
337        def get_msg(self,code):
338                msg_text=''     
339                if code==0:
340                        msg_text=_("Installation successful")   
341                               
342                elif code==1:
343                        msg_text=_("Error: File with incorret extension .air is required")
344
345                elif code==2:
346                        msg_text=_("Error: Unable to detect file extension")
347
348                elif code==3:
349                        msg_text=_("Error: Output path is not owned by user")   
350
351                elif code==4:
352                        msg_text=_("Error: No file upload to install")
353                elif code==10:
354                        msg_text=_("Error: Table not found in input file")
355
356                elif code==11:
357                        msg_text=_("Error: Problem ocurred while importing input file")
358
359                elif code==12:
360                        msg_text=_("Error: Problem exporting input file to csv")
361
362                elif code==13:
363                        msg_text=_("Error: Problem generating intermediate sql file")
364
365                elif code==14:
366                        msg_text=_("Error: Problem generating output file")
367       
368                elif code==15:
369                        msg_text=_("Error: No table in input file to virtual table")
370
371                elif code==16:
372                        msg_text=_("Error: Couldn't fetch data from table")
373                return msg_text         
374        #def get_msg   
Note: See TracBrowser for help on using the repository browser.