source: lliurex-store/trunk/fuentes/lliurex-store-gui/usr/share/lliurex-store/lliurex-store-gui/DetailsBox.py @ 7721

Last change on this file since 7721 was 7721, checked in by Juanma, 18 months ago

Availabe snaps are loaded from available sections

File size: 16.3 KB
Line 
1import gi
2gi.require_version('Gtk', '3.0')
3
4from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio,GLib
5import Screenshot
6import ImageManager
7
8import Core
9
10import signal
11signal.signal(signal.SIGINT, signal.SIG_DFL)
12
13import time
14import threading
15from subprocess import Popen
16import os
17import html2text
18
19import gettext
20gettext.textdomain('lliurex-store')
21_ = gettext.gettext
22
23
24
25class DetailsBox(Gtk.VBox):
26
27        def __init__(self):
28               
29                Gtk.VBox.__init__(self)
30               
31                self.core=Core.Core.get_core()
32               
33                self.banner_full_size=250
34                self.screenshot_small=100
35                self.banner_small=135
36                self.icon_size=64
37               
38                self.details_max_width=25
39                self.app_max_width=8
40                self.short_description_max_width=10
41               
42                self.full_info_box=Gtk.HBox()
43                self.pack_start(self.full_info_box,True,True,5)
44               
45                # ####### LEFT SIDE ######
46               
47                self.app_details=Gtk.VBox()
48                self.app_details.set_margin_left(10)
49                self.app_details.set_margin_bottom(10)
50                self.app_details.set_margin_top(5)
51                self.full_info_box.pack_start(self.app_details,False,False,0)
52
53                self.app_banner=Screenshot.ScreenshotNeo()
54                self.app_banner.set_size_request(self.banner_full_size,self.banner_full_size)
55
56                self.app_details.pack_start(self.app_banner,False,False,0)
57                self.install_button=Gtk.Button()
58                self.install_button_label=Gtk.Label(_("Install"))
59                self.install_button.add(self.install_button_label)
60                self.install_button.connect("clicked",self.install_clicked)
61               
62                vbox=Gtk.VBox()
63                self.install_label=Gtk.Label(_("Installing..."))
64                vbox.pack_start(self.install_label,False,False,0)
65                vbox.set_valign(Gtk.Align.FILL)
66                vbox.set_halign(Gtk.Align.FILL)
67               
68                self.install_label.set_halign(Gtk.Align.START)
69                self.install_pbar=Gtk.ProgressBar()
70                self.install_pbar.set_valign(Gtk.Align.FILL)
71                self.install_pbar.set_halign(Gtk.Align.FILL)
72                vbox.pack_start(self.install_pbar,True,True,0)
73
74                hbox=Gtk.HBox()
75                self.uninstall_button=Gtk.Button(_("Uninstall"))
76                self.uninstall_button.connect("clicked",self.uninstall_clicked)
77                self.open_button=Gtk.Button(_("Open"))
78                self.open_button.connect("clicked",self.open_clicked)
79                self.open_button.set_margin_right(10)
80                hbox.pack_start(self.open_button,True,True,0)
81                hbox.pack_start(self.uninstall_button,True,True,0)
82               
83                self.install_stack=Gtk.Stack()
84                self.install_stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
85                self.install_stack.set_transition_duration(500)
86                self.install_stack.add_titled(self.install_button,"install","Install")
87                self.install_stack.add_titled(vbox,"progress","Progress")
88                self.install_stack.add_titled(hbox,"installed","Open/Uninstall")
89               
90                self.app_details.pack_start(self.install_stack,False,False,10)
91               
92                self.details_label=Gtk.Label("Details")
93                self.details_label.set_alignment(0,0.5)
94                self.details_label.set_margin_left(0)
95                self.app_details.pack_start(self.details_label,False,False,0)
96               
97                self.details_divider=Gtk.HBox()
98                self.details_divider.set_size_request(0,1)
99                self.app_details.pack_start(self.details_divider,False,False,5)
100               
101                self.version_label=Gtk.Label(_("Version"))
102                self.version_label.set_alignment(0,0.5)
103                self.category_label=Gtk.Label(_("Category"))
104                self.category_label.set_alignment(0,0.5)
105                self.license_label=Gtk.Label(_("License"))
106                self.license_label.set_alignment(0,0.5)
107                self.size_label=Gtk.Label(_("Size"))
108                self.size_label.set_alignment(0,0.5)
109                self.website_label=Gtk.Label(_("Website"))
110                self.website_label.set_alignment(0,0.5)
111
112                self.version_value_label=Gtk.Label()
113                self.version_value_label.set_alignment(1,0.5)
114                self.version_value_label.set_max_width_chars(self.details_max_width)
115                self.version_value_label.set_ellipsize(Pango.EllipsizeMode.END)
116                self.category_value_label=Gtk.Label()
117                self.category_value_label.set_alignment(1,0.5)
118                self.category_value_label.set_max_width_chars(self.details_max_width)
119                self.category_value_label.set_ellipsize(Pango.EllipsizeMode.END)
120                self.license_value_label=Gtk.Label()
121                self.license_value_label.set_alignment(1,0.5)
122                self.license_value_label.set_max_width_chars(self.details_max_width)
123                self.license_value_label.set_ellipsize(Pango.EllipsizeMode.END)
124                self.size_value_label=Gtk.Label()
125                self.size_value_label.set_alignment(1,0.5)
126                self.size_value_label.set_max_width_chars(self.details_max_width)
127                self.size_value_label.set_ellipsize(Pango.EllipsizeMode.END)
128                self.website_value_label=Gtk.Label()
129                self.website_value_label.set_alignment(1,0.5)
130                self.website_value_label.set_max_width_chars(self.details_max_width)
131                self.website_value_label.set_ellipsize(Pango.EllipsizeMode.END)
132               
133                hbox=Gtk.HBox()
134                hbox.pack_start(self.version_label,False,False,0)
135                hbox.pack_end(self.version_value_label,False,False,0)
136                self.app_details.pack_start(hbox,False,False,0)
137                hbox=Gtk.HBox()
138                hbox.pack_start(self.category_label,False,False,0)
139                hbox.pack_end(self.category_value_label,False,False,0)
140                self.app_details.pack_start(hbox,False,False,0)
141                hbox=Gtk.HBox()
142                hbox.pack_start(self.license_label,False,False,0)
143                hbox.pack_end(self.license_value_label,False,False,0)
144                self.app_details.pack_start(hbox,False,False,0)
145                hbox=Gtk.HBox()
146                hbox.pack_start(self.size_label,False,False,0)
147                hbox.pack_end(self.size_value_label,False,False,0)
148                self.app_details.pack_start(hbox,False,False,0)
149                hbox=Gtk.HBox()
150                hbox.pack_start(self.website_label,False,False,0)
151                hbox.pack_end(self.website_value_label,False,False,0)
152                self.app_details.pack_start(hbox,False,False,0)
153               
154               
155                # ############# #
156               
157                # ####### RIGHT SIDE ######
158               
159                self.app_details_r=Gtk.VBox()
160                self.app_details_r.set_margin_top(5)
161                self.full_info_box.pack_start(self.app_details_r,True,True,20)
162               
163                hbox=Gtk.HBox()
164                self.app_icon=Screenshot.ScreenshotNeo()
165                self.app_icon.set_size_request(64,64)
166               
167                hbox.pack_start(self.app_icon,False,False,0)
168               
169                self.app_name_label=Gtk.Label("")
170                self.app_name_label.set_max_width_chars(self.app_max_width)
171                self.app_name_label.set_ellipsize(Pango.EllipsizeMode.END)
172                self.app_name_label.set_alignment(0,1)
173                self.short_description_label=Gtk.Label("")
174                self.short_description_label.set_alignment(0,0)
175                self.short_description_label.set_max_width_chars(self.short_description_max_width)
176                self.short_description_label.set_ellipsize(Pango.EllipsizeMode.END)
177               
178                vbox=Gtk.VBox()
179                vbox.pack_start(self.app_name_label,True,True,0)
180                vbox.pack_start(self.short_description_label,True,True,0)
181                hbox.pack_start(vbox,True,True,5)
182               
183                self.app_details_r.pack_start(hbox,False,False,0)
184               
185                self.full_description_label=Gtk.Label()
186                self.full_description_label.set_margin_right(10)
187                self.full_description_label.set_alignment(0,1)
188                self.full_description_label.set_justify(Gtk.Justification.FILL)
189                self.full_description_label.set_line_wrap(True)
190                self.full_description_label.set_valign(Gtk.Align.START)
191                self.full_description_label.set_halign(Gtk.Align.FILL)
192               
193                sw=Gtk.ScrolledWindow()
194                sw.set_shadow_type(Gtk.ShadowType.NONE)
195                sw.set_overlay_scrolling(True)
196                sw.set_kinetic_scrolling(True)
197                vp=Gtk.Viewport()
198                sw.add(vp)
199                sw.set_size_request(0,100)
200                vp.add(self.full_description_label)
201               
202                self.app_details_r.pack_start(sw,True,True,10)
203               
204                self.description_divider=Gtk.HBox()
205                self.description_divider.set_size_request(0,1)
206                self.description_divider.set_valign(Gtk.Align.START)
207                self.app_details_r.pack_start(self.description_divider,False,False,5)
208               
209                ss_sw=Gtk.ScrolledWindow()
210                ss_sw.set_shadow_type(Gtk.ShadowType.NONE)
211                ss_vp=Gtk.Viewport()
212               
213                ss_sw.add(ss_vp)
214               
215                self.screenshots_box=Gtk.HBox()
216               
217                ss_sw.set_size_request(0,130)
218                vbox=Gtk.VBox()
219                vbox.pack_start(self.screenshots_box,True,False,0)
220                ss_vp.add(vbox)
221                self.app_details_r.set_valign(Gtk.Align.FILL)
222                self.app_details_r.pack_start(ss_sw,False,False,5)
223               
224               
225                # ####################### #
226               
227                # ## RELATED #######
228               
229                related_vbox=Gtk.VBox()
230                related_vbox.set_margin_left(10)
231               
232                self.related_label=Gtk.Label(_("Related"))
233                self.related_label.set_alignment(0,1)
234               
235                related_vbox.pack_start(self.related_label,False,False,0)
236                               
237                self.related_divider=Gtk.HBox()
238                self.related_divider.set_size_request(0,1)
239                self.related_divider.set_margin_right(20)
240                related_vbox.pack_start(self.related_divider,False,False,5)
241               
242                self.related_sw=Gtk.ScrolledWindow()
243                self.related_sw.set_shadow_type(Gtk.ShadowType.NONE)
244                self.related_sw.set_size_request(0,self.banner_small+40)
245                self.related_sw.set_margin_right(20)
246                related_vp=Gtk.Viewport()
247                self.related_sw.add(related_vp)
248               
249                self.related_box=Gtk.HBox()
250                self.related_box.set_margin_bottom(10)
251               
252                related_vp.add(self.related_box)
253               
254                related_vbox.pack_start(self.related_sw,False,False,5)
255                self.pack_start(related_vbox,True,True,0)
256               
257                # #################
258
259                self.set_css_info()
260               
261        #def  init
262       
263        def set_package_info(self,pkg):
264               
265                info={}
266               
267                info["image_url"]=pkg["banner_small"]
268                info["image_id"]=pkg["package"]+"_banner_small"
269                info["x"]=self.banner_full_size
270                info["y"]=self.banner_full_size
271                info["aspect_ratio"]=False
272                info["name"]=pkg["package"].capitalize()
273                info["installed"]=True if pkg["state"]=="installed" else False
274               
275                if pkg["banner_small"] !=None:
276                        self.app_banner.download_image(info)
277                else:
278                        info["name"]=None
279                        if os.path.exists(self.core.tmp_store_dir+info["image_id"]):
280                               
281                                info["image_path"]=self.core.tmp_store_dir+info["image_id"]
282                                self.app_banner.set_from_file(info)
283                        else:
284                                info["image_path"]=self.core.resources.get_icon(pkg)
285                       
286                                self.app_banner.create_banner_from_file(info)
287               
288                self.version_value_label.set_text(pkg["version"])
289                self.category_value_label.set_text(pkg["category"])
290                self.license_value_label.set_text(pkg["license"])
291                try:
292                        size= "{:.2f} MB".format(float(pkg["size"])/1000000) 
293                        self.size_value_label.set_text(size)
294                except:
295                        pass
296                self.website_value_label.set_markup("<a href=\"%s\">%s</a>"%(pkg["homepage"],pkg["homepage"]))
297                self.app_name_label.set_text(pkg["name"])
298                self.short_description_label.set_text(pkg["summary"])
299                h=html2text.HTML2Text()
300                h.body_width=500
301                txt=h.handle(pkg["description"])
302                txt=txt.replace("&lt;", "<")
303                txt=txt.replace("&gt;", ">")
304                txt=txt.replace("&amp;", "&")
305                self.full_description_label.set_text(txt)
306               
307                if info["installed"]:
308                        self.install_stack.set_visible_child_name("installed")
309                else:
310                        self.install_stack.set_visible_child_name("install")
311                       
312               
313                info["image_path"]=self.core.resources.get_icon(pkg)
314                info["image_id"]=pkg["icon"]+"_icon"
315                info["x"]=self.icon_size
316                info["y"]=self.icon_size
317               
318                self.app_icon.set_from_file(info)
319               
320                for s in self.screenshots_box.get_children():
321                        self.screenshots_box.remove(s)
322               
323                count=0
324                for v in pkg["videos"]:
325                       
326                        image=Screenshot.ScreenshotNeo()
327                        info["video_url"]=v["url"].replace("http://metadata.tanglu.org/appstream/media/xenial/","").replace("https://www.youtube.com/watch?v=","https://www.youtube.com/embed/")
328                        info["image_url"]=v["preview"]
329                        info["image_id"]=pkg["package"]+"_video_"+str(count)
330                        info["x"]=self.screenshot_small
331                        info["y"]=self.screenshot_small
332                       
333                        image.set_video_info(info)
334                       
335                        b=Gtk.Button()
336                        b.set_name("RELATED_BUTTON")
337                        b.add(image)
338                        self.screenshots_box.pack_start(b,False,False,5)
339                       
340                        count+=1
341                       
342                count=0
343                for s in pkg["screenshots"]:
344                       
345                        image=Screenshot.ScreenshotNeo()
346                        i={}
347                       
348                        i["image_url"]=s
349                        i["image_id"]=pkg["package"]+"_screenshot_"+str(count)
350                        i["x"]=self.screenshot_small
351                        i["y"]=self.screenshot_small
352                        i["aspect_ratio"]=False
353                                               
354                        image.download_image(i)
355                        b=Gtk.Button()
356                        b.set_name("RELATED_BUTTON")
357                        b.add(image)
358                        self.screenshots_box.pack_start(b,False,False,5)
359                        count+=1
360               
361                self.screenshots_box.show_all()
362
363                for p in self.related_box.get_children():
364                        self.related_box.remove(p)
365                       
366                for p in pkg["related_packages"]:
367                       
368                        image=Screenshot.ScreenshotNeo()
369
370                        i={}
371                        i["image_id"]=p["package"]+"_banner_small"
372                        i["x"]=self.banner_small
373                        i["y"]=self.banner_small
374                        i["name"]=p["package"].capitalize()
375                        i["package"]=p["package"]
376                        i["icon"]=p["icon"]
377                        i["component"]=p["component"]
378
379                        if p["banner"]!=None:
380                                i["image_url"]=p["banner"]
381                                i["custom_frame"]=False
382                        else:
383                                i["image_path"]=self.core.resources.get_icon(p)
384                                i["custom_frame"]=True
385                               
386                        if not i["custom_frame"]:
387                                image.download_image(i)
388                        else:
389                                i["force_text"]=True
390                                image.create_banner_from_file(i)
391                       
392                        b=Gtk.Button()
393                        b.add(image)
394                        b.set_size_request(self.banner_small,self.banner_small)
395                        b.set_margin_top(10)
396                        b.connect("clicked",self.related_app_clicked,p)
397                        b.set_name("RELATED_BUTTON")
398                        b.set_valign(Gtk.Align.CENTER)
399                        b.set_tooltip_text(p["name"])
400                        self.related_box.pack_start(b,False,False,3)
401               
402                self.related_sw.get_hadjustment().set_value(0)
403                self.related_box.show_all()
404               
405                for x in self.screenshots_box.get_children():
406                        x.connect("clicked",self.core.main_window.screenshot_clicked)
407               
408               
409        #def set_values
410       
411       
412        def set_css_info(self):
413               
414                self.style_provider=Gtk.CssProvider()
415                f=Gio.File.new_for_path(self.core.rsrc_dir+"lliurex-store.css")
416                self.style_provider.load_from_file(f)
417                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
418               
419                self.set_name("DETAILS_BOX")
420               
421                self.details_divider.set_name("DIVIDER")
422                self.description_divider.set_name("DIVIDER")
423                self.related_divider.set_name("DIVIDER")
424               
425                self.details_label.set_name("DETAILS_LABEL")
426                self.version_label.set_name("DETAILS_OPTIONS")
427                self.category_label.set_name("DETAILS_OPTIONS")
428                self.license_label.set_name("DETAILS_OPTIONS")
429                self.size_label.set_name("DETAILS_OPTIONS")
430                self.website_label.set_name("DETAILS_OPTIONS")
431               
432                self.version_value_label.set_name("DETAILS_VALUES")
433                self.category_value_label.set_name("DETAILS_VALUES")
434                self.license_value_label.set_name("DETAILS_VALUES")
435                self.size_value_label.set_name("DETAILS_VALUES")
436                self.website_value_label.set_name("DETAILS_VALUES")
437               
438                self.app_name_label.set_name("TITLE")
439                self.short_description_label.set_name("SHORT_DESCRIPTION")
440                self.full_description_label.set_name("FULL_DESCRIPTION")
441               
442                self.related_label.set_name("RELATED_LABEL")
443               
444                self.install_button.set_name("INSTALL_BUTTON")
445                self.install_label.set_name("DETAILS_LABEL")
446                self.uninstall_button.set_name("UNINSTALL_BUTTON")
447                self.open_button.set_name("INSTALL_BUTTON")
448               
449        #def set-css_info
450       
451       
452        def related_app_clicked(self,widget,app):
453               
454                self.core.main_window.load_pkg_data(app["package"])
455               
456        #def related_app_clicked
457       
458       
459        def install_clicked(self,widget):
460               
461                self.install_label.set_text("Installing...")
462                self.install_stack.set_visible_child_name("progress")
463               
464                t=threading.Thread(target=self.install_pkg)
465                t.daemon=True
466                t.start()
467                GLib.timeout_add(100,self.pulse_pbar,t,"installed","install")
468               
469        #def install_clicked
470       
471       
472        def uninstall_clicked(self,widget):
473               
474                self.install_label.set_text("Uninstalling...")
475                self.install_stack.set_visible_child_name("progress")
476               
477                t=threading.Thread(target=self.uninstall_pkg)
478                t.daemon=True
479                t.start()
480                GLib.timeout_add(100,self.pulse_pbar,t,"install","installed")
481               
482        #def install_clicked
483       
484               
485        def pulse_pbar(self,t,target,fallback):
486               
487                if t.is_alive():
488                        self.install_pbar.pulse()
489                        return True
490               
491               
492                if self.thread_ret:
493                        self.install_stack.set_visible_child_name(target)
494                else:
495                        self.install_stack.set_visible_child_name(fallback)
496               
497                return False
498               
499        #def pulse_pbar
500       
501       
502        def install_pkg(self):
503               
504                pkg=self.core.main_window.current_pkg["package"]
505                self.thread_ret=self.core.store.install_package(pkg)
506               
507        #def install_pkg
508       
509       
510        def uninstall_pkg(self):
511               
512                pkg=self.core.main_window.current_pkg["package"]
513                self.thread_ret=self.core.store.uninstall_package(pkg)
514               
515        #def uninstall_pkg
516       
517       
518        def open_clicked(self,widget):
519                if self.core.main_window.current_pkg["name"].endswith('.snap'):
520                        snap=self.core.main_window.current_pkg["name"].replace('.snap','')
521                        if os.path.exists("/snap/bin/%s"%snap):
522                                Popen(["/snap/bin/%s"%snap])
523                elif self.core.main_window.current_pkg["package"].endswith('.appimage'):
524                        appimg=self.core.main_window.current_pkg["package"].lower()
525                        if os.path.exists(os.getenv("HOME")+"/.local/bin/%s"%appimg):
526                                Popen([os.getenv("HOME")+"/.local/bin/%s"%appimg])
527#                               os.system(os.getenv("HOME")+"/.local/bin/%s"%appimg)
528                elif 'Zomando' in self.core.main_window.current_pkg["categories"]:
529                        zmd=self.core.main_window.current_pkg["id"]+".zmd"
530                        if os.path.exists("/usr/share/zero-center/zmds/%s"%zmd):
531                                Popen(["pe", "/usr/share/zero-center/zmds/%s"%zmd])
532                else:
533                        desktop=self.core.main_window.current_pkg["id"]
534                        if os.path.exists("/usr/share/applications/%s"%desktop):
535                                os.system("gtk-launch %s"%desktop)
536               
537        #def open_clicked
538       
Note: See TracBrowser for help on using the repository browser.