class detailPage(activeFrame): def __init__(self, parent, controller): activeFrame.__init__(self, parent, controller) self.controller = controller self.appstore_handler = Store_handler self.package_parser = Parser self.selected_version = None self.version_index = None self.package = None self.bind("<Configure>", self.on_configure) self.column = ThemedFrame(self, background=style.color_1) self.column.place(relx=1, rely=0, width=style.sidecolumnwidth, relheight=1, x=-style.sidecolumnwidth) self.column_body = ThemedFrame(self.column, background=style.color_1) self.column_body.place(relwidth=1, relheight=1) self.column_title = ThemedLabel(self.column_body, "", anchor="w", font=style.mediumboldtext, foreground=style.w, background=style.color_1) self.column_title.place(x=style.offset, width=-style.offset, rely=0, relwidth=1, height=style.detailspagemultiplier) self.column_author = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_author.place(x=style.offset, width=-style.offset, y=style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_version = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_version.place(x=style.offset, width=-style.offset, y=1.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_license = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_license.place(x=style.offset, width=-style.offset, y=1.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_package = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_package.place(x=style.offset, width=-style.offset, y=2.000 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_downloads = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_downloads.place(x=style.offset, width=-style.offset, y=2.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_updated = ThemedLabel(self.column_body, "", anchor="w", font=style.smalltext, foreground=style.w, background=style.color_1) self.column_updated.place(x=style.offset, width=-style.offset, y=2.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) # self.column_separator_top = ThemedLabel(self.column_body, "", background=style.lg) # self.column_separator_top.place(rely=1,relwidth = 1, x = + style.offset, y = - 3 * (style.buttonsize + style.offset) - 3 * style.offset - style.buttonsize - 1 - 0.5 * style.buttonsize, width = - 2 * style.offset, height = 1) # self.column_separator_bot = ThemedLabel(self.column_body, "", background=style.lg) # self.column_separator_bot.place(rely=1,relwidth = 1, x = + style.offset, y = - 3 * (style.buttonsize + style.offset) - style.offset - 1, width = - 2 * style.offset, height = 1) self.column_open_url_button = button( self.column_body, callback=self.trigger_open_tab, text_string="VISIT PAGE", font=style.mediumboldtext, background=style.color_2, ).place(rely=1, relwidth=1, x=+style.offset, y=-3 * (style.buttonsize + style.offset), width=-2 * style.offset, height=style.buttonsize) self.column_install_button = button(self.column_body, callback=self.trigger_install, text_string="INSTALL", font=style.mediumboldtext, background=style.color_2) self.column_install_button.place(rely=1, relwidth=1, x=+style.offset, y=-2 * (style.buttonsize + style.offset), width=-2 * style.offset, height=style.buttonsize) self.column_uninstall_button = button(self.column_body, callback=self.trigger_uninstall, text_string="UNINSTALL", font=style.mediumboldtext, background=style.color_2) self.back_image = ImageTk.PhotoImage( Image.open("assets/return.png").resize( (style.buttonsize, style.buttonsize), Image.ANTIALIAS)) self.column_backbutton = button(self.column_body, image_object=self.back_image, callback=self.leave, background=style.color_1) self.column_backbutton.place(rely=1, relx=1, x=-(style.buttonsize + style.offset), y=-(style.buttonsize + style.offset)) # self.column_backbutton_ttp = tooltip(self.column_backbutton,"Back to list") self.content_frame = ThemedFrame(self, background=style.color_2) self.content_frame.place(x=0, width=-style.sidecolumnwidth, rely=0, relheight=1, relwidth=1) self.content_frame_header = ThemedFrame(self.content_frame, background=style.color_2) self.content_frame_header.place(x=style.offset, width=-2 * style.offset, rely=0, relwidth=1, height=style.detailspagemultiplier) self.content_frame_body = ThemedFrame(self.content_frame, background=style.color_2) self.content_frame_body.place(x=style.offset, width=-2 * style.offset, y=style.detailspagemultiplier, relwidth=1, height=-style.detailspagemultiplier, relheight=1) self.content_banner_image_frame = ThemedFrame(self.content_frame, background=style.color_2) self.content_banner_image_frame.place( x=0, y=+style.detailspagemultiplier, relwidth=1, height=-style.detailspagemultiplier, relheight=0.4) self.content_banner_image = ThemedLabel( self.content_banner_image_frame, "", background=style.color_2, foreground=style.w, anchor="center", wraplength=None) self.content_banner_image.place(x=0, y=0, relwidth=1, relheight=1) self.content_frame_details = scrolledText(self.content_frame_body, wrap='word', font=style.smalltext, background=style.lg) self.content_frame_details.place(rely=0.4, relx=0, relwidth=1, relheight=0.6, x=+style.offset, width=-2 * (style.offset), height=-style.offset) #Displays app name self.header_label = ThemedLabel(self.content_frame_header, "", anchor="w", font=style.giantboldtext, background=style.color_2, foreground=style.b) self.header_label.place(rely=0, y=0, relheight=0.65) #Displays app name self.header_author = ThemedLabel(self.content_frame_header, "", anchor="w", font=style.smalltext, background=style.color_2, foreground=style.color_1) self.header_author.place(rely=0.65, y=0, relheight=0.35) self.progress_bar = progressFrame(self) self.yesnoPage = yesnoPage(self) def on_menu_update(self, option): self.selected_tag_name.set(option) self.select_version(option) def update_page(self, package): self.selected_version = None self.package = package threader.do_async(self.update_banner) version = package["version"] self.column_title.set("Title: {}".format(package["title"])) self.column_author.set("Author: {}".format(package["author"])) self.column_version.set("Latest Version: {}".format( package["version"])) try: self.column_license.set("License: {}".format(package["license"])) except: self.column_license.set("License: N/A") self.column_package.set("Package: {}".format(package["name"])) ttl_dl = 0 try: ttl_dl += package["web_dls"] except: pass try: ttl_dl += package["app_dls"] except: pass self.column_downloads.set("Downloads: {}".format(ttl_dl)) self.column_updated.set("Updated: {}".format(package["updated"])) self.content_frame_details.configure(state="normal") self.content_frame_details.delete('1.0', "end") #Makes newlines in details print correctly. Hacky but :shrug: details = package["description"].replace("\\n", """ """) self.content_frame_details.insert("1.0", details) self.content_frame_details.configure(state="disabled") self.header_label.set(package["title"]) self.header_author.set(package["author"]) #Hides or places the uninstalll button if not installed or installed respectively #get_package_entry returns none if no package is found or if the sd path is not set if self.appstore_handler.get_package_entry(package["name"]): self.column_uninstall_button.place( rely=1, relwidth=1, x=+style.offset, y=-1 * (style.buttonsize + style.offset), width=-(3 * style.offset + style.buttonsize), height=style.buttonsize) if self.column_install_button: if self.appstore_handler.clean_version( self.appstore_handler.get_package_version( package["name"]), package["title"] ) > self.appstore_handler.clean_version( package["version"], package["title"]): self.column_install_button.settext("UPDATE") else: self.column_install_button.settext("REINSTALL") else: self.column_uninstall_button.place_forget() if self.column_install_button: self.column_install_button.settext("INSTALL") tags = [] def select_version(self, option): try: self.selected_version = option self.version_index = self.controller.appstore_handler.get_tag_index( self.package["github_content"], self.selected_version) self.update_release_notes() except Exception as e: # print(e) pass def on_configure(self, event=None): if self.package: self.after(100, self.update_banner()) def update_banner(self): self.bannerimage = getScreenImage(self.package["name"]) if self.bannerimage: self.do_update_banner(self.bannerimage) else: self.do_update_banner("assets/notfound.png") def do_update_banner(self, image_path): maxheight = self.content_banner_image_frame.winfo_height() maxwidth = self.content_banner_image_frame.winfo_width() if maxwidth > 0 and maxheight > 0: art_image = Image.open(image_path) wpercent = (maxwidth / float(art_image.size[0])) hsize = int((float(art_image.size[1]) * float(wpercent))) w_img = art_image.resize((maxwidth, hsize), Image.ANTIALIAS) if w_img.size[0] > maxheight: hpercent = (maxheight / float(art_image.size[1])) wsize = int((float(art_image.size[0]) * float(hpercent))) art_image = art_image.resize((maxwidth, hsize), Image.ANTIALIAS) else: art_image = w_img art_image = ImageTk.PhotoImage(art_image) self.content_banner_image.configure(image=art_image) self.content_banner_image.image = art_image def show(self, repo): self.do_update_banner("assets/notfound.png") threader.do_async(self.update_page, [repo], priority="medium") self.tkraise() for child in self.winfo_children(): child.bind("<Escape>", self.leave) def leave(self): self.controller.show_frame("appstorePage") for child in self.winfo_children(): child.unbind("<Escape>") def reload_function(self): self.controller.frames["appstorePage"].reload_category_frames() self.reload() def trigger_install(self): index = self.version_index or 0 if not self.appstore_handler.check_path(): self.set_sd() if self.appstore_handler.check_path(): if self.appstore_handler.check_if_get_init(): if self.package: threader.do_async( self.appstore_handler.handler_install_package, [ self.package, self.progress_bar.update, self.reload_function, self.progress_bar.set_title ], priority="high") else: self.yesnoPage.getanswer( "The homebrew appstore has not been initiated here yet, would you like to initiate it?", self.init_get_then_continue) def init_get_then_continue(self): self.appstore_handler.init_get() self.trigger_install() def trigger_uninstall(self): if self.package: threader.do_async(self.appstore_handler.uninstall_package, [self.package], priority="high") self.controller.frames["appstorePage"].reload_category_frames() self.schedule_callback(self.reload(), 100) def reload(self): threader.do_async(self.update_page, [self.package]) def trigger_open_tab(self): if self.package: try: url = self.package["url"] opentab(url) except Exception as e: print("Failed to open tab - {}".format(e)) def set_sd(self): chosensdpath = tkinter.filedialog.askdirectory( initialdir="/", title='Please select your SD card') self.appstore_handler.set_path(chosensdpath) self.reload()
class storeAppSquare(ThemedFrame): def __init__(self, parent, controller, framework, category_frame, repo, callback, status_handler): self.controller = controller self.parent = parent self.framework = framework self.category_frame = category_frame self.repo = repo self.name = repo["name"] self.callback = callback self.status_handler = status_handler self.active = True self.image_sharer = image_sharer self.imageset = False self.base_x = None #Stores the base x location to build the button from for dynamic building self.base_y = None #Stores the base y location to build the button from for dynamic building self.canvas = None self.placed = False self.thumbnailheight = None self.thumbnailwidth = None ThemedFrame.__init__(self, parent, background=style.w) self.buttonobj = button(self, image_object=None, callback=lambda: self.callback(repo), background=style.color_2) self.buttonobj.place(relheight=1, relwidth=1) #Placeholders used by the category frame when building the button, fixes the disappearing text issue self.buttontitlelabel = None #Placeholder used for the button title self.buttonauthorlabel = None #Placeholder for the button author self.buttonversionlabel = None #Placeholder for the current cersion self.buttonseparator = None #Placeholder for underline in each button self.buttonstatuslabel = None #Placeholder for download / version status self.update_button_sizes() def update_button_sizes(self): thumbnail_size_map = { "tiny": (style.tiny_thumbnail_height, style.tiny_thumbnail_width), "small": (style.small_thumbnail_height, style.small_thumbnail_width), "medium": (style.medium_thumbnail_height, style.medium_thumbnail_width), "large": (style.large_thumbnail_height, style.large_thumbnail_width), "huge": (style.huge_thumbnail_height, style.huge_thumbnail_width) } thumbnail_size = settings.get_setting("thumbnail_size") thumbnail_size = thumbnail_size_map.get(thumbnail_size) if thumbnail_size: if not self.thumbnailwidth == thumbnail_size[1]: self.thumbnailheight = thumbnail_size[0] self.thumbnailwidth = thumbnail_size[1] return True def set_image(self): repo = self.repo try: package = repo["package"] except: package = None try: image_file = getPackageIcon(package) or notfoundimage button_image = Image.open(image_file) #Resizes and saves image if it's the wrong size for faster loads in the future if not button_image.size[0] == [ self.thumbnailwidth, self.thumbnailheight ]: button_image = button_image.resize( (self.thumbnailwidth, self.thumbnailheight), Image.ANTIALIAS) self.button_image = ImageTk.PhotoImage(button_image) except Exception as e: print(e) self.button_image = self.category_frame.notfoundimage self.buttonobj.setimage(self.button_image) self.imageset = True def set_xy_canvas(self, base_x, base_y, canvas): self.base_x = base_x self.base_y = base_y self.canvas = canvas def get_xy(self): return ((self.base_x, self.base_y)) def build_button(self): update_button_sizes = self.update_button_sizes() if not self.placed: if self.base_y and self.base_x and self.canvas: self.placed = True repo = self.repo label_y = self.base_y + self.thumbnailheight - style.buttontextheight + 40 def place_button(): self.place(x=self.base_x, y=self.base_y, height=self.thumbnailheight + 2 * style.offset, width=self.thumbnailwidth) # ttp = "{}\nAuthor: {}\nDownloads: {}".format(repo["description"], repo["author"], repo["downloads"]) # self.button_ttp = tooltip(self.buttonobj,ttp) def place_buttontitlelabel(): if not self.buttontitlelabel: self.buttontitlelabel = ThemedLabel( self.canvas, self.repo["name"], anchor="e", label_font=style.mediumboldtext, foreground=style.w, background=style.color_2) self.buttontitlelabel.place(x=self.base_x, y=label_y - 1.5 * style.buttontextheight, width=self.thumbnailwidth) def place_buttonauthorlabel(): if not self.buttonauthorlabel: self.buttonauthorlabel = ThemedLabel( self.canvas, self.repo["author"], anchor="e", label_font=style.smallboldtext, foreground=style.lg, background=style.color_2) self.buttonauthorlabel.place(x=self.base_x, y=label_y, width=self.thumbnailwidth) def place_buttonstatuslabel(): if not self.buttonstatuslabel: self.buttonstatuslabel = ThemedLabel( self.canvas, "", anchor="w", label_font=style.smallboldtext, foreground=style.lg, background=style.color_2) self.buttonstatuslabel.place( x=self.base_x, y=label_y - 1.5 * style.buttontextheight + 4) status = None package = self.repo["package"] if self.status_handler.packages: if package in self.status_handler.packages: installed_version = self.status_handler.get_package_version( package) current_version = repo_parser.package_dict[ package]["github_content"][0]["tag_name"] if self.status_handler.clean_version( installed_version, package ) == self.status_handler.clean_version( current_version, package): status = "UPTODATE" elif self.status_handler.clean_version( installed_version, package ) < self.status_handler.clean_version( current_version, package): status = "NEEDSUPDATE" else: status = "UPTODATE" else: status = "NOTINSTALLED" else: status = "NOTINSTALLED" self.buttonstatuslabel.configure( image=self.category_frame.status_map[status]) def place_buttonversionlabel(): if not self.buttonversionlabel: self.buttonversionlabel = ThemedLabel( self.canvas, self.repo["github_content"][0]["tag_name"], anchor="w", label_font=style.smallboldtext, foreground=style.lg, background=style.color_2) self.buttonversionlabel.place(x=self.base_x, y=label_y) def place_buttonseparator(): if not self.buttonseparator: self.buttonseparator = tk.Label(self.canvas, background=style.lg, borderwidth=0) self.buttonseparator.place(x=self.base_x, y=label_y + 2 * style.offset + style.buttontextheight, height=1, width=self.thumbnailwidth) place_button() place_buttonauthorlabel() place_buttontitlelabel() place_buttonstatuslabel() place_buttonversionlabel() place_buttonseparator() if not self.imageset or update_button_sizes: self.set_image() self.items = [ self, self.buttonobj, self.buttontitlelabel, self.buttonauthorlabel, self.buttonversionlabel, self.buttonseparator, self.buttonstatuslabel ] for item in self.items: try: if platform.system() == 'Windows' or platform.system( ) == "Darwin": item.bind("<MouseWheel>", self.canvas.on_mouse_wheel) elif platform.system() == "Linux": item.bind("<Button-4>", self.canvas.on_mouse_wheel) item.bind("<Button-5>", self.canvas.on_mouse_wheel) except Exception as e: print(e)
class detailPage(activeFrame): def __init__(self, parent, controller): activeFrame.__init__(self, parent, controller) self.controller = controller self.appstore_handler = controller.appstore_handler self.repo_parser = controller.repo_parser self.repo = None #------------------------------ self.column = ThemedFrame(self, background=style.light_color) self.column.place(relx=1, rely=0, width=style.sidecolumnwidth, relheight=1, x=-style.sidecolumnwidth) self.column_body = ThemedFrame(self.column, background=style.light_color) self.column_body.place(relwidth=1, relheight=1) self.column_title = ThemedLabel(self.column_body, "", anchor="w", label_font=style.mediumboldtext, foreground=style.w, background=style.light_color) self.column_title.place(x=5, width=-5, rely=0, relwidth=1, height=style.headerheight) #------------------------------ self.column_author = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_author.place(x=5, width=-5, y=style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_version = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_version.place(x=5, width=-5, y=1.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_license = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_license.place(x=5, width=-5, y=1.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) #------------------------------ #------------------------------ self.column_package = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_package.place(x=5, width=-5, y=2.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_downloads = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_downloads.place(x=5, width=-5, y=2.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_updated = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_updated.place(x=5, width=-5, y=3.00 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) #------------------------------ #------------------------------ self.column_downloaded = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_downloaded.place(x=5, width=-5, y=3.66 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) #------------------------------ self.column_extracted = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.light_color) self.column_extracted.place(x=5, width=-5, y=4 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_open_url_button = button( self.column_body, callback=self.trigger_open_tab, text_string="VISIT PAGE", font=style.mediumboldtext, background=style.dark_color).place( rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-4 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) self.column_install_button = button(self.column_body, callback=self.trigger_install, text_string="INSTALL", font=style.mediumboldtext, background=style.dark_color) self.column_install_button.place(rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-3 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) self.column_uninstall_button = button(self.column_body, callback=self.trigger_uninstall, text_string="UNINSTALL", font=style.mediumboldtext, background=style.dark_color) self.back_image = ImageTk.PhotoImage( Image.open(locations.backimage).resize( (style.buttonsize, style.buttonsize), Image.ANTIALIAS)) self.column_backbutton = button(self.column_body, image_object=self.back_image, callback=self.leave, background=style.light_color) self.column_backbutton.place(rely=1, relx=1, x=-(style.buttonsize + style.offset), y=-(style.buttonsize + style.offset)) self.column_backbutton_ttp = tooltip(self.column_backbutton, "Back to list") self.content_frame = ThemedFrame(self, background=style.w) self.content_frame.place(x=0, width=-style.sidecolumnwidth, rely=0, relheight=1, relwidth=1) self.content_frame_header = ThemedFrame(self.content_frame, background=style.w) self.content_frame_header.place(x=style.offset, width=-2 * style.offset, rely=0, relwidth=1, height=style.detailspagemultiplier) self.content_frame_body = ThemedFrame(self.content_frame, background=style.w) self.content_frame_body.place(x=style.offset, width=-2 * style.offset, y=style.detailspagemultiplier, relwidth=1, height=-style.detailspagemultiplier, relheight=1) self.content_banner_image = ThemedLabel(self.content_frame_body, "", background=style.w, foreground=style.w, anchor="center", wraplength=None) self.content_banner_image.place(x=0, y=0, relwidth=1, relheight=0.5) self.content_frame_details = scrolledText(self.content_frame_body, wrap='word', font=style.smalltext) self.content_frame_details.place(rely=0.5, relx=0, relwidth=1, relheight=0.5, x=+style.offset, width=-2 * (style.offset), height=-style.offset) #Displays app name self.header_label = ThemedLabel(self.content_frame_header, "", anchor="w", label_font=style.giantboldtext, background=style.w, foreground=style.b) self.header_label.place(rely=0, y=0, relheight=0.65) #Displays app name self.header_author = ThemedLabel(self.content_frame_header, "", anchor="w", label_font=style.smalltext, background=style.w, foreground=style.light_color) self.header_author.place(rely=0.65, y=0, relheight=0.35) self.progress_bar = progressFrame(self) self.yesnoPage = yesnoPage(self) def update_page(self, repo): self.repo = repo package = repo["name"] try: web_dls = repo["web_dls"] except: web_dls = 0 try: app_dls = repo["app_dls"] except: app_dls = 0 ttl_dls = web_dls + app_dls self.column_title.set("Title: {}".format(repo["title"])) self.column_author.set("Author: {}".format(repo["author"])) self.column_version.set("Version: {}".format(repo["version"])) self.column_license.set("License: {}".format(repo["license"])) self.column_package.set("Package: {}".format(package)) self.column_downloads.set("Downloads: {}".format(ttl_dls)) self.column_updated.set("Updated: {}".format(repo["updated"])) self.column_downloaded.set("Dowloaded size: {} KB".format( repo["filesize"])) self.column_extracted.set("Install size: {} KB".format( repo["extracted"])) self.content_frame_details.configure(state="normal") self.content_frame_details.delete('1.0', "end") #Makes newlines in details print correctly. Hacky but :shrug: details = repo["details"].replace("\\n", """ """) self.content_frame_details.insert("1.0", details) self.content_frame_details.configure(state="disabled") self.header_label.set(repo["title"]) self.header_author.set(repo["author"]) #Hides or places the uninstalll button if not installed or installed respectively #get_package_entry returns none if no package is found or if the sd path is not set if self.appstore_handler.get_package_entry(package): self.column_uninstall_button.place( rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-2 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) if self.column_install_button: if self.appstore_handler.clean_version( self.appstore_handler.get_package_version(package), package) > self.appstore_handler.clean_version( self.appstore_handler.get_package_version( self.repo["version"]), package): self.column_install_button.settext("UPDATE") else: self.column_install_button.settext("REINSTALL") else: self.column_uninstall_button.place_forget() if self.column_install_button: self.column_install_button.settext("INSTALL") def do_update_banner(): self.bannerimage = getScreenImage(package) if self.bannerimage: self.update_banner(self.bannerimage) else: self.update_banner(locations.notfoundimage) print("failed to download screenshot for {}".format(package)) self.controller.async_threader.do_async(do_update_banner, []) def update_banner(self, image_path): art_image = Image.open(image_path) art_image = ImageTk.PhotoImage(art_image) self.content_banner_image.configure(image=art_image) self.content_banner_image.image = art_image def show(self, repo): self.update_banner(locations.notfoundimage) self.controller.async_threader.do_async(self.update_page, [repo], priority="medium") self.tkraise() for child in self.winfo_children(): child.bind("<Escape>", self.leave) def leave(self): self.controller.show_frame("appstorePage") for child in self.winfo_children(): child.unbind("<Escape>") def reload_function(self): self.controller.frames["appstorePage"].reload_category_frames() self.reload() def trigger_install(self): if not self.appstore_handler.check_path(): self.set_sd() if self.appstore_handler.check_path(): if self.appstore_handler.check_if_get_init(): if self.repo: self.controller.async_threader.do_async( self.appstore_handler.install_package, [ self.repo, self.progress_bar.update, self.reload_function, self.progress_bar.set_title ], priority="high") else: self.yesnoPage.getanswer( "The homebrew appstore has not been initiated here yet, would you like to initiate it?", self.init_get_then_continue) def init_get_then_continue(self): self.appstore_handler.init_get() self.trigger_install() def trigger_uninstall(self): if self.repo: self.controller.async_threader.do_async( self.appstore_handler.uninstall_package, [self.repo], priority="high") self.controller.frames["appstorePage"].reload_category_frames() self.schedule_callback(self.reload(), 100) def reload(self): self.controller.async_threader.do_async(self.update_page, [self.repo]) def trigger_open_tab(self): if self.repo: try: url = self.repo["url"] opentab(url) except: print("Failed to open tab for url {}".format(url)) def set_sd(self): chosensdpath = tkinter.filedialog.askdirectory( initialdir="/", title='Please select your SD card') self.appstore_handler.set_path(chosensdpath) self.reload()
class storeAppSquare(ThemedFrame): def __init__(self, parent, controller, framework, category_frame, repo): self.controller = controller self.parent = parent self.framework = framework self.category_frame = category_frame self.repo = repo self.name = repo["name"] self.active = True self.image_sharer = self.controller.image_sharer self.imageset = False self.base_x = None #Stores the base x location to build the button from for dynamic building self.base_y = None #Stores the base y location to build the button from for dynamic building self.canvas = None self.placed = False ThemedFrame.__init__(self, parent, background = style.w) self.buttonobj = button(self,image_object=None,callback=lambda: self.open_details(repo),background = style.w) self.buttonobj.place(relheight=1,relwidth=1) #Placeholders used by the category frame when building the button, fixes the disappearing text issue self.buttontitlelabel = None #Placeholder used for the button title self.buttonauthorlabel = None #Placeholder for the button author self.buttonversionlabel = None #Placeholder for the current cersion self.buttonseparator = None #Placeholder for underline in each button self.buttonstatuslabel = None #Placeholder for download / version status self.items = [ self, self.buttonobj, self.buttontitlelabel, self.buttonauthorlabel, self.buttonversionlabel, self.buttonseparator, self.buttonstatuslabel ] def open_details(self, repo): self.controller.frames["detailPage"].show(repo) def set_image(self): repo = self.repo package = repo["name"] #Checks a shared dict to see if this package already has an image loaded, returns none if not self.button_image = self.image_sharer.get_image(package) if not self.button_image: try: image_file = getPackageIcon(package) or notfoundimage button_image = Image.open(image_file) #Resizes and saves image if it's the wrong size for faster loads in the future if not button_image.size[0] == [style.thumbnailwidth, style.thumbnailheight]: button_image = button_image.resize((style.thumbnailwidth, style.thumbnailheight), Image.ANTIALIAS) self.button_image = ImageTk.PhotoImage(button_image) if not image_file == notfoundimage: self.image_sharer.set_image(package, self.button_image) except Exception as e: self.button_image = self.category_frame.notfoundimage self.image_sharer.set_image(package, self.button_image) self.buttonobj.setimage(self.button_image) self.imageset = True def set_xy_canvas(self, base_x, base_y, canvas): self.base_x = base_x self.base_y = base_y self.canvas = canvas def get_xy(self): return((self.base_x, self.base_y)) def build_button(self): if not self.placed: if self.base_y and self.base_x and self.canvas: self.placed = True repo = self.repo label_y = self.base_y + style.thumbnailheight - style.buttontextheight + 40 def place_button(): self.place(x=self.base_x, y = self.base_y, height = style.thumbnailheight + 2 * style.offset, width = style.thumbnailwidth) self.buttonobj.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.bind("<MouseWheel>", self.canvas.on_mouse_wheel) try: web_dls = repo["web_dls"] except: web_dls = 0 try: app_dls = repo["app_dls"] except: app_dls = 0 ttl_dls = web_dls + app_dls # ttp = "{}\nAuthor: {}\nDownloads: {}".format(repo["description"], repo["author"], ttl_dls) # self.button_ttp = tooltip(self.buttonobj,ttp) def place_buttontitlelabel(): if not self.buttontitlelabel: self.buttontitlelabel = ThemedLabel(self.canvas,self.repo["title"],anchor="e",label_font=style.mediumboldtext,foreground=style.b,background=style.w) self.buttontitlelabel.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.buttontitlelabel.place(x = self.base_x, y = label_y - 1.5 * style.buttontextheight, width = style.thumbnailwidth) def place_buttonauthorlabel(): if not self.buttonauthorlabel: self.buttonauthorlabel = ThemedLabel(self.canvas,self.repo["author"],anchor="e",label_font=style.smallboldtext,foreground=style.lg,background=style.w) self.buttonauthorlabel.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.buttonauthorlabel.place(x = self.base_x, y = label_y, width = style.thumbnailwidth) def place_buttonstatuslabel(): if not self.buttonstatuslabel: self.buttonstatuslabel = ThemedLabel(self.canvas,"",anchor="w",label_font=style.smallboldtext,foreground=style.lg,background=style.w) self.buttonstatuslabel.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.buttonstatuslabel.place(x = self.base_x, y = label_y - 1.5 * style.buttontextheight + 4) status = None package = self.repo["name"] if self.controller.appstore_handler.packages: if package in self.controller.appstore_handler.packages: installed_version = self.controller.appstore_handler.get_package_version(package) if self.controller.appstore_handler.clean_version(installed_version, package) == self.controller.appstore_handler.clean_version(installed_version, package): status = "UPTODATE" elif self.controller.appstore_handler.clean_version(installed_version, package) < self.controller.appstore_handler.clean_version(installed_version, package): status = "NEEDSUPDATE" else: status = "NOTINSTALLED" else: status = "NOTINSTALLED" self.buttonstatuslabel.configure(image=self.category_frame.status_map[status]) def place_buttonversionlabel(): if not self.buttonversionlabel: self.buttonversionlabel = ThemedLabel(self.canvas,self.repo["version"],anchor="w",label_font=style.smallboldtext,foreground=style.lg,background=style.w) self.buttonversionlabel.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.buttonversionlabel.place(x = self.base_x, y = label_y) def place_buttonseparator(): if not self.buttonseparator: self.buttonseparator = tk.Label(self.canvas, background=style.lg, borderwidth= 0) self.buttonseparator.bind("<MouseWheel>", self.canvas.on_mouse_wheel) self.buttonseparator.place(x = self.base_x, y = label_y + 2 * style.offset + style.buttontextheight, height = 1, width = style.thumbnailwidth) place_button() place_buttonauthorlabel() place_buttontitlelabel() place_buttonstatuslabel() place_buttonversionlabel() place_buttonseparator() if not self.imageset: self.set_image()
class detailPage(activeFrame): def __init__(self, parent, controller): activeFrame.__init__(self, parent, controller) self.controller = controller self.appstore_handler = controller.appstore_handler self.repo_parser = controller.repo_parser self.selected_version = None self.version_index = None self.repo = None self.bind("<Configure>", self.on_configure) #------------------------------ self.column = ThemedFrame(self, background=style.color_1) self.column.place(relx=1, rely=0, width=style.sidecolumnwidth, relheight=1, x=-style.sidecolumnwidth) self.column_body = ThemedFrame(self.column, background=style.color_1) self.column_body.place(relwidth=1, relheight=1) self.column_title = ThemedLabel(self.column_body, "", anchor="w", label_font=style.mediumboldtext, foreground=style.w, background=style.color_1) self.column_title.place(x=5, width=-5, rely=0, relwidth=1, height=style.detailspagemultiplier) #------------------------------ self.column_author = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_author.place(x=5, width=-5, y=style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_version = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_version.place(x=5, width=-5, y=1.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_license = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_license.place(x=5, width=-5, y=1.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) #------------------------------ #------------------------------ self.column_package = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_package.place(x=5, width=-5, y=2.333 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_downloads = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_downloads.place(x=5, width=-5, y=2.666 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) self.column_updated = ThemedLabel(self.column_body, "", anchor="w", label_font=style.smalltext, foreground=style.w, background=style.color_1) self.column_updated.place(x=5, width=-5, y=3.00 * style.detailspagemultiplier, relwidth=1, height=0.333 * style.detailspagemultiplier) #------------------------------ self.releases_listbox = ScrolledThemedListBox(self.column_body) self.releases_listbox.configure(activestyle="none") self.releases_listbox.place( relwidth=1, y=3.66 * style.detailspagemultiplier, relheight=1, height=-(3.66 * style.detailspagemultiplier + 3 * (style.buttonsize + style.offset) + style.offset)) self.releases_listbox.bind('<<ListboxSelect>>', self.select_version) self.column_open_url_button = button( self.column_body, callback=self.trigger_open_tab, text_string="VISIT PAGE", font=style.mediumboldtext, background=style.color_2, ).place(rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-3 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) self.column_install_button = button(self.column_body, callback=self.trigger_install, text_string="INSTALL", font=style.mediumboldtext, background=style.color_2) self.column_install_button.place(rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-2 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) self.column_uninstall_button = button(self.column_body, callback=self.trigger_uninstall, text_string="UNINSTALL", font=style.mediumboldtext, background=style.color_2) self.back_image = ImageTk.PhotoImage( Image.open(locations.backimage).resize( (style.buttonsize, style.buttonsize), Image.ANTIALIAS)) self.column_backbutton = button(self.column_body, image_object=self.back_image, callback=self.leave, background=style.color_1) self.column_backbutton.place(rely=1, relx=1, x=-(style.buttonsize + style.offset), y=-(style.buttonsize + style.offset)) # self.column_backbutton_ttp = tooltip(self.column_backbutton,"Back to list") self.content_frame = ThemedFrame(self, background=style.color_2) self.content_frame.place(x=0, width=-style.sidecolumnwidth, rely=0, relheight=1, relwidth=1) self.content_frame_header = ThemedFrame(self.content_frame, background=style.color_2) self.content_frame_header.place(x=style.offset, width=-2 * style.offset, rely=0, relwidth=1, height=style.detailspagemultiplier) self.content_frame_body = ThemedFrame(self.content_frame, background=style.color_2) self.content_frame_body.place(x=style.offset, width=-2 * style.offset, y=style.detailspagemultiplier, relwidth=1, height=-style.detailspagemultiplier, relheight=1) self.content_banner_image_frame = ThemedFrame(self.content_frame, background=style.color_2) self.content_banner_image_frame.place( x=0, y=+style.detailspagemultiplier, relwidth=1, height=-style.detailspagemultiplier, relheight=0.4) self.content_banner_image = ThemedLabel( self.content_banner_image_frame, "", background=style.color_2, foreground=style.w, anchor="center", wraplength=None) self.content_banner_image.place(x=0, y=0, relwidth=1, relheight=1) self.content_frame_details = scrolledText(self.content_frame_body, wrap='word', font=style.smalltext, background=style.lg) self.content_frame_details.place(rely=0.4, relx=0, relwidth=1, relheight=0.25, x=+style.offset, width=-2 * (style.offset), height=-style.offset) self.content_frame_patch_notes_label = ThemedLabel( self.content_frame_body, "Release notes:", anchor="w", label_font=style.mediumboldtext, foreground=style.b, background=style.color_2) self.content_frame_patch_notes_label.place( relx=0.5, width=self.content_frame_patch_notes_label.winfo_reqwidth(), rely=0.65, y=+style.offset, x=-0.5 * self.content_frame_patch_notes_label.winfo_reqwidth(), height=0.33 * style.detailspagemultiplier) self.content_frame_version_details = scrolledText( self.content_frame_body, wrap='word', font=style.smalltext, background=style.lg) self.content_frame_version_details.place( rely=0.65, y=+style.offset + 0.33 * style.detailspagemultiplier, relx=0, relwidth=1, relheight=0.35, height=-(2 * style.offset + 0.33 * style.detailspagemultiplier), x=+style.offset, width=-2 * (style.offset)) #Displays app name self.header_label = ThemedLabel(self.content_frame_header, "", anchor="w", label_font=style.giantboldtext, background=style.color_2, foreground=style.b) self.header_label.place(rely=0, y=0, relheight=0.65) #Displays app name self.header_author = ThemedLabel(self.content_frame_header, "", anchor="w", label_font=style.smalltext, background=style.color_2, foreground=style.color_1) self.header_author.place(rely=0.65, y=0, relheight=0.35) self.progress_bar = progressFrame(self) self.yesnoPage = yesnoPage(self) def update_page(self, repo): self.selected_version = None self.repo = repo try: package = repo["store_equivalent"] except: package = repo["software"] github_content = repo["github_content"] version = github_content[0]["tag_name"] self.column_title.set("Title: {}".format(repo["name"])) self.column_author.set("Author: {}".format(repo["author"])) self.column_version.set("Latest Version: {}".format( github_content[0]["tag_name"])) try: self.column_license.set("License: {}".format(repo["license"])) except: self.column_license.set("License: N/A") self.column_package.set("Package: {}".format(package)) self.column_downloads.set("Downloads: {}".format(repo["downloads"])) self.column_updated.set("Updated: {}".format( github_content[0]["created_at"])) self.content_frame_details.configure(state="normal") self.content_frame_details.delete('1.0', "end") #Makes newlines in details print correctly. Hacky but :shrug: details = repo["description"].replace("\\n", """ """) self.content_frame_details.insert("1.0", details) self.content_frame_details.configure(state="disabled") self.header_label.set(repo["name"]) self.header_author.set(repo["author"]) #Hides or places the uninstalll button if not installed or installed respectively #get_package_entry returns none if no package is found or if the sd path is not set if self.appstore_handler.get_package_entry(package): self.column_uninstall_button.place( rely=1, relx=0.5, x=-1.5 * (style.buttonsize), y=-1 * (style.buttonsize + style.offset), width=3 * style.buttonsize, height=style.buttonsize) if self.column_install_button: if self.appstore_handler.clean_version( self.appstore_handler.get_package_version(package), package) > self.appstore_handler.clean_version( self.appstore_handler.get_package_version(version), package): self.column_install_button.settext("UPDATE") else: self.column_install_button.settext("REINSTALL") else: self.column_uninstall_button.place_forget() if self.column_install_button: self.column_install_button.settext("INSTALL") def do_update_banner(): self.bannerimage = getScreenImage(package) if self.bannerimage: self.update_banner(self.bannerimage) else: self.update_banner(locations.notfoundimage) print("failed to download screenshot for {}".format(package)) self.update_releases_listbox() self.controller.async_threader.do_async(do_update_banner, []) def select_version(self, event): try: widget = event.widget selection = widget.curselection() picked = widget.get(selection[0]) self.selected_version = picked self.version_index = self.controller.appstore_handler.get_tag_index( self.repo["github_content"], self.selected_version) self.update_release_notes() except Exception as e: print(e) def on_configure(self, event=None): if self.repo: repo = self.repo try: package = repo["store_equivalent"] except: package = repo["software"] self.bannerimage = getScreenImage(package) if self.bannerimage: self.update_banner(self.bannerimage) else: self.update_banner(locations.notfoundimage) def update_banner(self, image_path): maxheight = self.content_banner_image_frame.winfo_height() maxwidth = self.content_banner_image_frame.winfo_width() if maxwidth > 0 and maxheight > 0: art_image = Image.open(image_path) wpercent = (maxwidth / float(art_image.size[0])) hsize = int((float(art_image.size[1]) * float(wpercent))) w_img = art_image.resize((maxwidth, hsize), Image.ANTIALIAS) if w_img.size[0] > maxheight: hpercent = (maxheight / float(art_image.size[1])) wsize = int((float(art_image.size[0]) * float(hpercent))) art_image = art_image.resize((maxwidth, hsize), Image.ANTIALIAS) else: art_image = w_img art_image = ImageTk.PhotoImage(art_image) self.content_banner_image.configure(image=art_image) self.content_banner_image.image = art_image def update_releases_listbox(self): self.releases_listbox.delete(0, "end") for release in self.repo["github_content"]: tag = release["tag_name"] self.releases_listbox.insert("end", tag) self.releases_listbox.select_set( 0) #sets focus on the first item in listbox self.releases_listbox.event_generate("<<ListboxSelect>>") self.update_release_notes() def update_release_notes(self): notes = self.repo["github_content"][self.version_index]["body"] self.content_frame_version_details.configure(state="normal") self.content_frame_version_details.delete('1.0', "end") #Makes newlines in details print correctly. Hacky but :shrug: notes = notes.replace("\\n", """ """) self.content_frame_version_details.insert("1.0", notes) self.content_frame_version_details.configure(state="disabled") def show(self, repo): self.update_banner(locations.notfoundimage) self.controller.async_threader.do_async(self.update_page, [repo], priority="medium") self.tkraise() for child in self.winfo_children(): child.bind("<Escape>", self.leave) def leave(self): self.controller.show_frame("appstorePage") for child in self.winfo_children(): child.unbind("<Escape>") def reload_function(self): self.controller.frames["appstorePage"].reload_category_frames() self.reload() def trigger_install(self): index = 0 if not self.appstore_handler.check_path(): self.set_sd() if self.appstore_handler.check_path(): if self.appstore_handler.check_if_get_init(): if self.repo: self.controller.async_threader.do_async( self.appstore_handler.install_package, [ self.repo, self.version_index, self.progress_bar.update, self.reload_function, self.progress_bar.set_title ], priority="high") else: self.yesnoPage.getanswer( "The homebrew appstore has not been initiated here yet, would you like to initiate it?", self.init_get_then_continue) def init_get_then_continue(self): self.appstore_handler.init_get() self.trigger_install() def trigger_uninstall(self): if self.repo: self.controller.async_threader.do_async( self.appstore_handler.uninstall_package, [self.repo], priority="high") self.controller.frames["appstorePage"].reload_category_frames() self.schedule_callback(self.reload(), 100) def reload(self): self.controller.async_threader.do_async(self.update_page, [self.repo]) def trigger_open_tab(self): if self.repo: try: url = self.repo["projectpage"] opentab(url) except: print("Failed to open tab for url {}".format(url)) def set_sd(self): chosensdpath = tkinter.filedialog.askdirectory( initialdir="/", title='Please select your SD card') self.appstore_handler.set_path(chosensdpath) self.reload()