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

Last change on this file since 7407 was 7407, checked in by Juanma, 2 years ago

install mime at user level

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