From 2a5273bfcc0a5eb62d54247bcc634365f31ecf74 Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 4 Aug 2025 02:35:20 +0530 Subject: [PATCH 01/29] Cleaning Up --- plugin_manager.py | 838 ++++++++++++++++++++++++++-------------------- 1 file changed, 473 insertions(+), 365 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index f251c45..69c8931 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -858,11 +858,17 @@ class ChangelogWindow(popup.PopupWindow): scale_origin_stack_offset=self.scale_origin ) - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, height * 0.87), size=(0, 0), - h_align='center', v_align='center', text='ChangeLog', - scale=text_scale * 1.25, color=bui.app.ui_v1.title_color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, height * 0.87), + size=(0, 0), + h_align='center', + v_align='center', + text='ChangeLog', + scale=text_scale * 1.25, + color=bui.app.ui_v1.title_color, + maxwidth=width * 0.9 + ) back_button = bui.buttonwidget( parent=self._root_widget, @@ -871,7 +877,8 @@ class ChangelogWindow(popup.PopupWindow): scale=0.8, label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', - on_activate_call=self._back) + on_activate_call=self._back + ) bui.containerwidget(edit=self._root_widget, cancel_button=back_button) @@ -886,12 +893,17 @@ class ChangelogWindow(popup.PopupWindow): h_align = 'center' extra = 1 - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, height * 0.72), size=(0, 0), - h_align='center', v_align='center', - text=PLUGIN_MANAGER_VERSION + released_on, - scale=text_scale * 0.9, color=color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, height * 0.72), + size=(0, 0), + h_align='center', + v_align='center', + text=PLUGIN_MANAGER_VERSION + released_on, + scale=text_scale * 0.9, + color=color, + maxwidth=width * 0.9 + ) bui.buttonwidget( parent=self._root_widget, @@ -900,15 +912,22 @@ class ChangelogWindow(popup.PopupWindow): scale=0.8, label='Full ChangeLog', button_type='square', - on_activate_call=lambda: bui.open_url(REPOSITORY_URL + '/blob/main/CHANGELOG.md')) + on_activate_call=lambda: bui.open_url(REPOSITORY_URL + '/blob/main/CHANGELOG.md') + ) loop_height = height * 0.62 for log in logs: - bui.textwidget(parent=self._root_widget, - position=(width * 0.5 * extra, loop_height), size=(0, 0), - h_align=h_align, v_align='top', text=log, - scale=text_scale, color=color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.5 * extra, loop_height), + size=(0, 0), + h_align=h_align, + v_align='top', + text=log, + scale=text_scale, + color=color, + maxwidth=width * 0.9 + ) loop_height -= 35 def _back(self) -> None: @@ -939,11 +958,17 @@ class AuthorsWindow(popup.PopupWindow): ) pos = height * 0.9 - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos), size=(0, 0), - h_align='center', v_align='center', text='Authors', - scale=text_scale * 1.25, color=color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos), + size=(0, 0), + h_align='center', + v_align='center', + text='Authors', + scale=text_scale * 1.25, + color=color, + maxwidth=width * 0.9 + ) back_button = bui.buttonwidget( parent=self._root_widget, @@ -952,39 +977,48 @@ class AuthorsWindow(popup.PopupWindow): scale=0.8, label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', - on_activate_call=self._back) + on_activate_call=self._back + ) bui.containerwidget(edit=self._root_widget, cancel_button=back_button) - self._scrollwidget = bui.scrollwidget(parent=self._root_widget, - size=(width * 0.8, height * 0.75), - position=(width * 0.1, height * 0.1)) - self._columnwidget = bui.columnwidget(parent=self._scrollwidget, - border=1, - left_border=-15, - margin=0) + self._scrollwidget = bui.scrollwidget( + parent=self._root_widget, + size=(width * 0.8, height * 0.75), + position=(width * 0.1, height * 0.1) + ) + self._columnwidget = bui.columnwidget( + parent=self._scrollwidget, + border=1, + left_border=-15, + margin=0 + ) for author in self.authors_info: for key, value in author.items(): text = f"{key.title()}: {value if value != '' else 'Not Provided'}" if key == 'name': text = value - bui.textwidget(parent=self._columnwidget, - size=(width * 0.8, 35 if key == 'name' else 30), - color=color if key == 'name' else (0.75, 0.7, 0.8), - scale=( - (1.1 if key == 'name' else 0.9) if _uiscale is babase.UIScale.SMALL else - (1.2 if key == 'name' else 1.0) - ), - text=text, - h_align='center', - v_align='center', - maxwidth=420) - bui.textwidget(parent=self._columnwidget, - size=(width * 0.8, 30), - always_highlight=True, - h_align='center', - v_align='center') + bui.textwidget( + parent=self._columnwidget, + size=(width * 0.8, 35 if key == 'name' else 30), + color=color if key == 'name' else (0.75, 0.7, 0.8), + scale=( + (1.1 if key == 'name' else 0.9) if _uiscale is babase.UIScale.SMALL else + (1.2 if key == 'name' else 1.0) + ), + text=text, + h_align='center', + v_align='center', + maxwidth=420 + ) + bui.textwidget( + parent=self._columnwidget, + size=(width * 0.8, 30), + always_highlight=True, + h_align='center', + v_align='center' + ) def _back(self) -> None: bui.getsound('swish').play() @@ -1045,41 +1079,53 @@ class PluginWindow(popup.PopupWindow): pos = height * 0.8 plug_name = self.plugin.name.replace('_', ' ').title() plugin_title = f"{plug_name} (v{self.plugin.latest_compatible_version.number})" - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos), size=(0, 0), - h_align='center', v_align='center', text=plugin_title, - scale=text_scale * 1.25, color=color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos), + size=(0, 0), + h_align='center', + v_align='center', + text=plugin_title, + scale=text_scale * 1.25, + color=color, + maxwidth=width * 0.9 + ) pos -= 25 # Author text = 'by ' + ', '.join([author["name"] for author in self.plugin.info["authors"]]) - author_text_control_btn = bui.buttonwidget(parent=self._root_widget, - position=(width * 0.49 - - (len(text)*14/2), pos - 10), - size=(len(text)*14, 20), - label='', - texture=bui.gettexture("empty"), - on_activate_call=lambda: - AuthorsWindow(self.plugin.info["authors"], self._root_widget)) - bui.textwidget(parent=self._root_widget, - position=(width * 0.49 - (len(text)*14/2), pos - 10), - size=(len(text)*14, 20), - h_align='center', - v_align='center', - text=text, - scale=text_scale * 0.8, - color=(0.75, 0.7, 0.8), - maxwidth=width * 0.9, - draw_controller=author_text_control_btn, - ) + author_text_control_btn = bui.buttonwidget( + parent=self._root_widget, + position=(width * 0.49 - (len(text)*14/2), pos - 10), + size=(len(text)*14, 20), + label='', + texture=bui.gettexture("empty"), + on_activate_call=lambda: AuthorsWindow(self.plugin.info["authors"], self._root_widget) + ) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49 - (len(text)*14/2), pos - 10), + size=(len(text)*14, 20), + h_align='center', + v_align='center', + text=text, + scale=text_scale * 0.8, + color=(0.75, 0.7, 0.8), + maxwidth=width * 0.9, + draw_controller=author_text_control_btn, + ) pos -= 60 # Info - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos), size=(0, 0), - h_align='center', v_align='center', - text=self.get_description(), - scale=text_scale * 0.6, color=color, - maxwidth=width * 0.95) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos), + size=(0, 0), + h_align='center', + v_align='center', + text=self.get_description(), + scale=text_scale * 0.6, + color=color, + maxwidth=width * 0.95 + ) b1_color = None b2_color = (0.8, 0.15, 0.35) b3_color = (0.2, 0.8, 0.3) @@ -1113,43 +1159,48 @@ class PluginWindow(popup.PopupWindow): button1_action = self.install if to_draw_button1: - selected_btn = bui.buttonwidget(parent=self._root_widget, - position=( - width * ( - 0.1 if self.plugin.is_installed and has_update else - 0.25 if self.plugin.is_installed else - 0.4), pos), - size=button_size, - on_activate_call=button1_action, - color=b1_color, - textcolor=b_text_color, - button_type='square', - text_scale=1, - label=button1_label) + selected_btn = bui.buttonwidget( + parent=self._root_widget, + position=( + width * (0.1 if self.plugin.is_installed and has_update else + 0.25 if self.plugin.is_installed else 0.4), pos + ), + size=button_size, + on_activate_call=button1_action, + color=b1_color, + textcolor=b_text_color, + button_type='square', + text_scale=1, + label=button1_label + ) if self.plugin.is_installed: - selected_btn = bui.buttonwidget(parent=self._root_widget, - position=( - width * (0.4 if has_update or not to_draw_button1 else 0.55), pos), - size=button_size, - on_activate_call=button2_action, - color=b2_color, - textcolor=b_text_color, - button_type='square', - text_scale=1, - label=button2_label) + selected_btn = bui.buttonwidget( + parent=self._root_widget, + position=( + width * (0.4 if has_update or not to_draw_button1 else 0.55), pos), + size=button_size, + on_activate_call=button2_action, + color=b2_color, + textcolor=b_text_color, + button_type='square', + text_scale=1, + label=button2_label + ) if has_update: - selected_btn = bui.buttonwidget(parent=self._root_widget, - position=(width * 0.7, pos), - size=button_size, - on_activate_call=button3_action, - color=b3_color, - textcolor=b_text_color, - autoselect=True, - button_type='square', - text_scale=1, - label=button3_label) + selected_btn = bui.buttonwidget( + parent=self._root_widget, + position=(width * 0.7, pos), + size=button_size, + on_activate_call=button3_action, + color=b3_color, + textcolor=b_text_color, + autoselect=True, + button_type='square', + text_scale=1, + label=button3_label + ) bui.containerwidget( edit=self._root_widget, @@ -1161,28 +1212,34 @@ class PluginWindow(popup.PopupWindow): 450 if _uiscale is babase.UIScale.MEDIUM else 440) open_pos_y = (100 if _uiscale is babase.UIScale.SMALL else 110 if _uiscale is babase.UIScale.MEDIUM else 120) - open_button = bui.buttonwidget(parent=self._root_widget, - autoselect=True, - position=(open_pos_x, open_pos_y), - size=(40, 40), - button_type="square", - label="", - color=(0.6, 0.53, 0.63), - on_activate_call=lambda: bui.open_url(self.plugin.view_url)) - bui.imagewidget(parent=self._root_widget, - position=(open_pos_x, open_pos_y), - size=(40, 40), - color=(0.8, 0.95, 1), - texture=bui.gettexture("file"), - draw_controller=open_button) - bui.textwidget(parent=self._root_widget, - position=(open_pos_x-3, open_pos_y+12), - text="Source", - size=(10, 10), - draw_controller=open_button, - color=(1, 1, 1, 1), - rotate=25, - scale=0.45) + open_button = bui.buttonwidget( + parent=self._root_widget, + autoselect=True, + position=(open_pos_x, open_pos_y), + size=(40, 40), + button_type="square", + label="", + color=(0.6, 0.53, 0.63), + on_activate_call=lambda: bui.open_url(self.plugin.view_url) + ) + bui.imagewidget( + parent=self._root_widget, + position=(open_pos_x, open_pos_y), + size=(40, 40), + color=(0.8, 0.95, 1), + texture=bui.gettexture("file"), + draw_controller=open_button + ) + bui.textwidget( + parent=self._root_widget, + position=(open_pos_x-3, open_pos_y+12), + text="Source", + size=(10, 10), + draw_controller=open_button, + color=(1, 1, 1, 1), + rotate=25, + scale=0.45 + ) # Below snippet handles the tutorial button in the plugin window tutorial_url = self.plugin.info["external_url"] @@ -1197,52 +1254,62 @@ class PluginWindow(popup.PopupWindow): 500 if _uiscale is babase.UIScale.MEDIUM else 490) open_pos_y = (100 if _uiscale is babase.UIScale.SMALL else 110 if _uiscale is babase.UIScale.MEDIUM else 120) - open_button = bui.buttonwidget(parent=self._root_widget, - autoselect=True, - position=(open_pos_x, open_pos_y), - size=(40, 40), - button_type="square", - label="", - color=(0.6, 0.53, 0.63), + open_button = bui.buttonwidget( + parent=self._root_widget, + autoselect=True, + position=(open_pos_x, open_pos_y), + size=(40, 40), + button_type="square", + label="", + color=(0.6, 0.53, 0.63), + on_activate_call=tutorial_confirm_window + ) - on_activate_call=tutorial_confirm_window) - - bui.imagewidget(parent=self._root_widget, - position=(open_pos_x, open_pos_y), - size=(40, 40), - color=(0.8, 0.95, 1), - texture=bui.gettexture("frameInset"), - draw_controller=open_button) - bui.textwidget(parent=self._root_widget, - position=(open_pos_x - 3, open_pos_y + 12), - text="Tutorial", - size=(10, 10), - draw_controller=open_button, - color=(1, 1, 1, 1), - rotate=25, - scale=0.45) + bui.imagewidget( + parent=self._root_widget, + position=(open_pos_x, open_pos_y), + size=(40, 40), + color=(0.8, 0.95, 1), + texture=bui.gettexture("frameInset"), + draw_controller=open_button + ) + bui.textwidget( + parent=self._root_widget, + position=(open_pos_x - 3, open_pos_y + 12), + text="Tutorial", + size=(10, 10), + draw_controller=open_button, + color=(1, 1, 1, 1), + rotate=25, + scale=0.45 + ) if to_draw_button4: settings_pos_x = (60 if _uiscale is babase.UIScale.SMALL else 60 if _uiscale is babase.UIScale.MEDIUM else 60) settings_pos_y = (100 if _uiscale is babase.UIScale.SMALL else 110 if _uiscale is babase.UIScale.MEDIUM else 120) - settings_button = bui.buttonwidget(parent=self._root_widget, - autoselect=True, - position=(settings_pos_x, settings_pos_y), - size=(40, 40), - button_type="square", - label="", - color=(0, 0.75, 0.75),) + settings_button = bui.buttonwidget( + parent=self._root_widget, + autoselect=True, + position=(settings_pos_x, settings_pos_y), + size=(40, 40), + button_type="square", + label="", + color=(0, 0.75, 0.75) + ) bui.buttonwidget( edit=settings_button, - on_activate_call=babase.Call(self.settings, settings_button),) - bui.imagewidget(parent=self._root_widget, - position=(settings_pos_x, settings_pos_y), - size=(40, 40), - color=(0.8, 0.95, 1), - texture=bui.gettexture("settingsIcon"), - draw_controller=settings_button) + on_activate_call=babase.Call(self.settings, settings_button) + ) + bui.imagewidget( + parent=self._root_widget, + position=(settings_pos_x, settings_pos_y), + size=(40, 40), + color=(0.8, 0.95, 1), + texture=bui.gettexture("settingsIcon"), + draw_controller=settings_button + ) def _ok(self) -> None: bui.containerwidget(edit=self._root_widget, transition='out_scale') @@ -1511,29 +1578,40 @@ class PluginSourcesWindow(popup.PopupWindow): 40 if _uiscale is babase.UIScale.MEDIUM else 60) scroll_pos_y = 105 - self._scrollwidget = bui.scrollwidget(parent=self._root_widget, - size=(scroll_size_x, scroll_size_y), - position=(scroll_pos_x, scroll_pos_y)) - self._columnwidget = bui.columnwidget(parent=self._scrollwidget, - border=1, - margin=0) + self._scrollwidget = bui.scrollwidget( + parent=self._root_widget, + size=(scroll_size_x, scroll_size_y), + position=(scroll_pos_x, scroll_pos_y) + ) + self._columnwidget = bui.columnwidget( + parent=self._scrollwidget, + border=1, margin=0 + ) delete_source_button_position_pos_x = 360 delete_source_button_position_pos_y = 110 - delete_source_button = bui.buttonwidget(parent=self._root_widget, - position=(delete_source_button_position_pos_x, - delete_source_button_position_pos_y), - size=(25, 25), label="", - on_activate_call=self.delete_selected_source, - button_type="square", - color=(0.6, 0, 0)) + delete_source_button = bui.buttonwidget( + parent=self._root_widget, + position=( + delete_source_button_position_pos_x, delete_source_button_position_pos_y + ), + size=(25, 25), + label="", + on_activate_call=self.delete_selected_source, + button_type="square", + color=(0.6, 0, 0) + ) - bui.imagewidget(parent=self._root_widget, - position=(delete_source_button_position_pos_x + 2, - delete_source_button_position_pos_y), - size=(25, 25), color=(5, 2, 2), - texture=bui.gettexture("crossOut"), - draw_controller=delete_source_button) + bui.imagewidget( + parent=self._root_widget, + position=( + delete_source_button_position_pos_x + 2, delete_source_button_position_pos_y + ), + size=(25, 25), + color=(5, 2, 2), + texture=bui.gettexture("crossOut"), + draw_controller=delete_source_button + ) warning_pos_x = (43 if _uiscale is babase.UIScale.SMALL else 35 if _uiscale is babase.UIScale.MEDIUM else @@ -1551,26 +1629,30 @@ class PluginSourcesWindow(popup.PopupWindow): maxwidth=400, ) - self._add_source_widget = bui.textwidget(parent=self._root_widget, - size=(335, 50), - position=(21, 22), - h_align='left', - v_align='center', - editable=True, - scale=0.75, - maxwidth=215, - description="Add Source") + self._add_source_widget = bui.textwidget( + parent=self._root_widget, + size=(335, 50), + position=(21, 22), + h_align='left', + v_align='center', + editable=True, + scale=0.75, + maxwidth=215, + description="Add Source" + ) - bui.buttonwidget(parent=self._root_widget, - position=(330, 28), - size=(37, 37), - on_activate_call=lambda: loop.create_task(self.add_source()), - label="", - texture=bui.gettexture("startButton"), - button_type="square", - color=(0, 0.9, 0), - textcolor=b_textcolor, - text_scale=1) + bui.buttonwidget( + parent=self._root_widget, + position=(330, 28), + size=(37, 37), + on_activate_call=lambda: loop.create_task(self.add_source()), + label="", + texture=bui.gettexture("startButton"), + button_type="square", + color=(0, 0.9, 0), + textcolor=b_textcolor, + text_scale=1 + ) self.draw_sources() @@ -1580,15 +1662,17 @@ class PluginSourcesWindow(popup.PopupWindow): color = (1, 1, 1) for custom_source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: - bui.textwidget(parent=self._columnwidget, - selectable=True, - color=color, - text=custom_source, - on_select_call=lambda: self.select_source(custom_source), - h_align='left', - v_align='center', - scale=0.75, - maxwidth=260) + bui.textwidget( + parent=self._columnwidget, + selectable=True, + color=color, + text=custom_source, + on_select_call=lambda: self.select_source(custom_source), + h_align='left', + v_align='center', + scale=0.75, + maxwidth=260 + ) def select_source(self, source): self.selected_source = source @@ -1651,13 +1735,16 @@ class PluginCategoryWindow(popup.PopupMenuWindow): 1.65 if _uiscale is babase.UIScale.MEDIUM else 1.23), choices=choices, current_choice=current_choice, - delegate=self) + delegate=self + ) self._update_custom_sources_widget() def _update_custom_sources_widget(self): - bui.textwidget(edit=self._columnwidget.get_children()[-1], - color=(0.5, 0.5, 0.5), - on_activate_call=self.show_sources_window) + bui.textwidget( + edit=self._columnwidget.get_children()[-1], + color=(0.5, 0.5, 0.5), + on_activate_call=self.show_sources_window + ) def popup_menu_selected_choice(self, window, choice): @@ -1730,7 +1817,8 @@ class PluginManagerWindow(bui.MainWindow): scale=0.8, label=babase.charstr(babase.SpecialChar.BACK), button_type='backSmall', - on_activate_call=self.main_window_back) + on_activate_call=self.main_window_back + ) bui.containerwidget(edit=self._root_widget, cancel_button=back_button) @@ -1841,19 +1929,16 @@ class PluginManagerWindow(bui.MainWindow): b_textcolor = (0.8, 0.8, 0.85) if self.alphabet_order_selection_button is None: - self.alphabet_order_selection_button = bui.buttonwidget(parent=self._root_widget, - size=(40, 30), - position=( - category_pos_x - 47, - category_pos_y), - label=( - 'Z - A' if self.selected_alphabet_order == 'z_a' - else 'A - Z'), - on_activate_call=( - lambda: loop.create_task(self._on_order_button_press())), - button_type="square", - textcolor=b_textcolor, - text_scale=0.6) + self.alphabet_order_selection_button = bui.buttonwidget( + parent=self._root_widget, + size=(40, 30), + position=(category_pos_x - 47, category_pos_y), + label='Z - A' if self.selected_alphabet_order == 'z_a' else 'A - Z', + on_activate_call=lambda: loop.create_task(self._on_order_button_press()), + button_type="square", + textcolor=b_textcolor, + text_scale=0.6 + ) else: b = self.alphabet_order_selection_button bui.buttonwidget( @@ -1864,15 +1949,16 @@ class PluginManagerWindow(bui.MainWindow): label = f"Category: {post_label}" if self.category_selection_button is None: - self.category_selection_button = b = bui.buttonwidget(parent=self._root_widget, - position=(category_pos_x, - category_pos_y), - size=b_size, - label=label, - button_type="square", - textcolor=b_textcolor, - text_scale=0.6) - bui.buttonwidget(b, on_activate_call=lambda: self.show_categories_window(source=b)), + self.category_selection_button = b = bui.buttonwidget( + parent=self._root_widget, + position=(category_pos_x, category_pos_y), + size=b_size, + label=label, + button_type="square", + textcolor=b_textcolor, + text_scale=0.6 + ) + bui.buttonwidget(edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), else: b = self.category_selection_button bui.buttonwidget( @@ -2214,58 +2300,66 @@ class PluginManagerSettingsWindow(popup.PopupWindow): ) pos -= 20 - self._changelog_button = b = bui.buttonwidget(parent=self._root_widget, - position=((width * 0.2) - button_size[0] / 2 - 5, - pos), - size=(80, 30), - textcolor=b_text_color, - button_type='square', - label='') + self._changelog_button = b = bui.buttonwidget( + parent=self._root_widget, + position=((width * 0.2) - button_size[0] / 2 - 5, pos), + size=(80, 30), + textcolor=b_text_color, + button_type='square', + label='' + ) bui.buttonwidget(b, on_activate_call=lambda: ChangelogWindow(b)) - bui.textwidget(parent=self._root_widget, - position=((width * 0.2) - button_size[0] / 2, pos), - size=(70, 30), - scale=0.6, - h_align='center', - v_align='center', - text='ChangeLog', - color=b_text_color, - draw_controller=self._changelog_button, - ) - self._save_button = bui.buttonwidget(parent=self._root_widget, - position=((width * 0.82) - button_size[0] / 2, pos), - size=(73, 35), - on_activate_call=self.save_settings_button, - textcolor=b_text_color, - button_type='square', - text_scale=1, - scale=0, - selectable=False, - label="Save") + bui.textwidget( + parent=self._root_widget, + position=((width * 0.2) - button_size[0] / 2, pos), + size=(70, 30), + scale=0.6, + h_align='center', + v_align='center', + text='ChangeLog', + color=b_text_color, + draw_controller=self._changelog_button, + ) + self._save_button = bui.buttonwidget( + parent=self._root_widget, + position=((width * 0.82) - button_size[0] / 2, pos), + size=(73, 35), + on_activate_call=self.save_settings_button, + textcolor=b_text_color, + button_type='square', + text_scale=1, + scale=0, + selectable=False, + label="Save" + ) pos -= 40 for setting, value in self.settings.items(): - bui.checkboxwidget(parent=self._root_widget, - position=(width * 0.1, pos), - size=(170, 30), - text=setting, - value=value, - on_value_change_call=babase.Call(self.toggle_setting, setting), - maxwidth=500, - textcolor=(0.9, 0.9, 0.9), - scale=text_scale * 0.8) + bui.checkboxwidget( + parent=self._root_widget, + position=(width * 0.1, pos), + size=(170, 30), + text=setting, + value=value, + on_value_change_call=babase.Call(self.toggle_setting, setting), + maxwidth=500, + textcolor=(0.9, 0.9, 0.9), + scale=text_scale * 0.8 + ) pos -= 34 * text_scale pos = height - 200 - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos-5), - size=(0, 0), - h_align='center', - v_align='center', - text='Contribute to plugins or to this community plugin manager!', - scale=text_scale * 0.65, - color=color, - maxwidth=width * 0.95) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos-5), + size=(0, 0), + h_align='center', + v_align='center', + text='Contribute to plugins or to this community plugin manager!', + scale=text_scale * 0.65, + color=color, + maxwidth=width * 0.95 + ) pos -= 75 try: @@ -2273,40 +2367,48 @@ class PluginManagerSettingsWindow(popup.PopupWindow): except urllib.error.URLError: plugin_manager_update_available = False discord_width = (width * 0.20) if plugin_manager_update_available else (width * 0.31) - self.discord_button = bui.buttonwidget(parent=self._root_widget, - position=(discord_width - button_size[0] / 2, pos), - size=button_size, - on_activate_call=lambda: bui.open_url(DISCORD_URL), - textcolor=b_text_color, - color=discord_bg_color, - button_type='square', - text_scale=1, - label="") + self.discord_button = bui.buttonwidget( + parent=self._root_widget, + position=(discord_width - button_size[0] / 2, pos), + size=button_size, + on_activate_call=lambda: bui.open_url(DISCORD_URL), + textcolor=b_text_color, + color=discord_bg_color, + button_type='square', + text_scale=1, + label="" + ) - bui.imagewidget(parent=self._root_widget, - position=(discord_width+0.5 - button_size[0] / 2, pos), - size=button_size, - texture=bui.gettexture("discordLogo"), - color=discord_fg_color, - draw_controller=self.discord_button) + bui.imagewidget( + parent=self._root_widget, + position=(discord_width+0.5 - button_size[0] / 2, pos), + size=button_size, + texture=bui.gettexture("discordLogo"), + color=discord_fg_color, + draw_controller=self.discord_button + ) github_width = (width * 0.49) if plugin_manager_update_available else (width * 0.65) - self.github_button = bui.buttonwidget(parent=self._root_widget, - position=(github_width - button_size[0] / 2, pos), - size=button_size, - on_activate_call=lambda: bui.open_url(REPOSITORY_URL), - textcolor=b_text_color, - color=github_bg_color, - button_type='square', - text_scale=1, - label='') + self.github_button = bui.buttonwidget( + parent=self._root_widget, + position=(github_width - button_size[0] / 2, pos), + size=button_size, + on_activate_call=lambda: bui.open_url(REPOSITORY_URL), + textcolor=b_text_color, + color=github_bg_color, + button_type='square', + text_scale=1, + label='' + ) - bui.imagewidget(parent=self._root_widget, - position=(github_width + 0.5 - button_size[0] / 2, pos), - size=button_size, - texture=bui.gettexture("githubLogo"), - color=(1, 1, 1), - draw_controller=self.github_button) + bui.imagewidget( + parent=self._root_widget, + position=(github_width + 0.5 - button_size[0] / 2, pos), + size=button_size, + texture=bui.gettexture("githubLogo"), + color=(1, 1, 1), + draw_controller=self.github_button + ) bui.containerwidget(edit=self._root_widget, on_cancel_call=self._ok) @@ -2318,61 +2420,65 @@ class PluginManagerSettingsWindow(popup.PopupWindow): text_color = (0.75, 0.2, 0.2) button_size = (95 * s, 32 * s) update_button_label = f'Update to v{plugin_manager_update_available[0]}' - self._update_button = bui.buttonwidget(parent=self._root_widget, - position=((width * 0.77) - button_size[0] / 2, - pos), - size=button_size, - on_activate_call=lambda: - loop.create_task( - self.update( - *plugin_manager_update_available - ) - ), - textcolor=b_text_color, - button_type='square', - text_scale=1, - color=(0, 0.7, 0), - label=update_button_label) - self._restart_to_reload_changes_text = bui.textwidget(parent=self._root_widget, - position=(width * 0.79, pos + 20), - size=(0, 0), - h_align='center', - v_align='center', - text='', - scale=text_scale * 0.65, - color=(0, 0.8, 0), - maxwidth=width * 0.9) + self._update_button = bui.buttonwidget( + parent=self._root_widget, + position=((width * 0.77) - button_size[0] / 2, pos), + size=button_size, + on_activate_call=lambda: loop.create_task(self.update(*plugin_manager_update_available)), + textcolor=b_text_color, + button_type='square', + text_scale=1, + color=(0, 0.7, 0), + label=update_button_label + ) + self._restart_to_reload_changes_text = bui.textwidget( + parent=self._root_widget, + position=(width * 0.79, pos + 20), + size=(0, 0), + h_align='center', + v_align='center', + text='', + scale=text_scale * 0.65, + color=(0, 0.8, 0), + maxwidth=width * 0.9 + ) else: text_color = (0, 0.8, 0) pos -= 25 - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos), - size=(0, 0), - h_align='center', - v_align='center', - text=f'Plugin Manager v{PLUGIN_MANAGER_VERSION}', - scale=text_scale * 0.8, - color=text_color, - maxwidth=width * 0.9) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos), + size=(0, 0), + h_align='center', + v_align='center', + text=f'Plugin Manager v{PLUGIN_MANAGER_VERSION}', + scale=text_scale * 0.8, + color=text_color, + maxwidth=width * 0.9 + ) pos -= 25 - bui.textwidget(parent=self._root_widget, - position=(width * 0.49, pos), - size=(0, 0), - h_align='center', - v_align='center', - text=f'API Version: {_app_api_version}', - scale=text_scale * 0.7, - color=(0.4, 0.8, 1), - maxwidth=width * 0.95) + bui.textwidget( + parent=self._root_widget, + position=(width * 0.49, pos), + size=(0, 0), + h_align='center', + v_align='center', + text=f'API Version: {_app_api_version}', + scale=text_scale * 0.7, + color=(0.4, 0.8, 1), + maxwidth=width * 0.95 + ) pos = height * 0.1 def toggle_setting(self, setting, set_value): self.settings[setting] = set_value check = self.settings == babase.app.config["Community Plugin Manager"]["Settings"] - bui.buttonwidget(edit=self._save_button, - scale=0 if check else 1, - selectable=(not check)) + bui.buttonwidget( + edit=self._save_button, + scale=0 if check else 1, + selectable=(not check) + ) def save_settings_button(self): babase.app.config["Community Plugin Manager"]["Settings"] = self.settings.copy() @@ -2390,8 +2496,10 @@ class PluginManagerSettingsWindow(popup.PopupWindow): else: bui.screenmessage("Plugin manager update successful", color=(0, 1, 0)) bui.getsound('shieldUp').play() - bui.textwidget(edit=self._restart_to_reload_changes_text, - text='Update Applied!\nRestart game to reload changes.') + bui.textwidget( + edit=self._restart_to_reload_changes_text, + text='Update Applied!\nRestart game to reload changes.' + ) self._update_button.delete() def _ok(self) -> None: From 8155b3a317bda25e3440c3082ebaf8fcf77a7f00 Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 4 Aug 2025 02:51:27 +0530 Subject: [PATCH 02/29] Fixing Up --- plugin_manager.py | 176 +++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 69c8931..b949ec3 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -36,7 +36,6 @@ REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" CURRENT_TAG = "main" _env = _babase.env() -_uiscale = bui.app.ui_v1.uiscale _app_api_version = babase.app.env.api_version INDEX_META = "{repository_url}/{content_type}/{tag}/index.json" @@ -48,6 +47,7 @@ PLUGIN_DIRECTORY = _env["python_directory_user"] loop = babase._asyncio._asyncio_event_loop +def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") @@ -842,7 +842,7 @@ class ChangelogWindow(popup.PopupWindow): def __init__(self, origin_widget): self.scale_origin = origin_widget.get_screen_space_center() bui.getsound('swish').play() - s = 1.65 if _uiscale is babase.UIScale.SMALL else 1.39 if _uiscale is babase.UIScale.MEDIUM else 1.67 + s = 1.65 if _uiscale() is babase.UIScale.SMALL else 1.39 if _uiscale() is babase.UIScale.MEDIUM else 1.67 width = 400 * s height = width * 0.5 color = (1, 1, 1) @@ -854,7 +854,7 @@ class ChangelogWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._back, transition=transition, - scale=(1.5 if _uiscale is babase.UIScale.SMALL else 1.5 if _uiscale is babase.UIScale.MEDIUM else 1.0), + scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -940,7 +940,7 @@ class AuthorsWindow(popup.PopupWindow): self.authors_info = authors_info self.scale_origin = origin_widget.get_screen_space_center() bui.getsound('swish').play() - s = 1.25 if _uiscale is babase.UIScale.SMALL else 1.39 if _uiscale is babase.UIScale.MEDIUM else 1.67 + s = 1.25 if _uiscale() is babase.UIScale.SMALL else 1.39 if _uiscale() is babase.UIScale.MEDIUM else 1.67 width = 400 * s height = width * 0.8 color = (1, 1, 1) @@ -952,8 +952,8 @@ class AuthorsWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._back, transition=transition, - scale=(1.5 if _uiscale is babase.UIScale.SMALL else 1.5 - if _uiscale is babase.UIScale.MEDIUM else 1.0), + scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 + if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -1004,7 +1004,7 @@ class AuthorsWindow(popup.PopupWindow): size=(width * 0.8, 35 if key == 'name' else 30), color=color if key == 'name' else (0.75, 0.7, 0.8), scale=( - (1.1 if key == 'name' else 0.9) if _uiscale is babase.UIScale.SMALL else + (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else (1.2 if key == 'name' else 1.0) ), text=text, @@ -1059,7 +1059,7 @@ class PluginWindow(popup.PopupWindow): async def draw_ui(self): bui.getsound('swish').play() b_text_color = (0.75, 0.7, 0.8) - s = 1.25 if _uiscale is babase.UIScale.SMALL else 1.39 if babase.UIScale.MEDIUM else 1.67 + s = 1.25 if _uiscale() is babase.UIScale.SMALL else 1.39 if babase.UIScale.MEDIUM else 1.67 width = 400 * s height = 120 + 100 * s color = (1, 1, 1) @@ -1071,8 +1071,8 @@ class PluginWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._cancel, transition=transition, - scale=(2.1 if _uiscale is babase.UIScale.SMALL else 1.5 - if _uiscale is babase.UIScale.MEDIUM else 1.0), + scale=(2.1 if _uiscale() is babase.UIScale.SMALL else 1.5 + if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -1208,10 +1208,10 @@ class PluginWindow(popup.PopupWindow): selected_child=selected_btn ) - open_pos_x = (390 if _uiscale is babase.UIScale.SMALL else - 450 if _uiscale is babase.UIScale.MEDIUM else 440) - open_pos_y = (100 if _uiscale is babase.UIScale.SMALL else - 110 if _uiscale is babase.UIScale.MEDIUM else 120) + open_pos_x = (390 if _uiscale() is babase.UIScale.SMALL else + 450 if _uiscale() is babase.UIScale.MEDIUM else 440) + open_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else + 110 if _uiscale() is babase.UIScale.MEDIUM else 120) open_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1250,10 +1250,10 @@ class PluginWindow(popup.PopupWindow): text=text, action=lambda: bui.open_url(self.plugin.info["external_url"]), ) - open_pos_x = (440 if _uiscale is babase.UIScale.SMALL else - 500 if _uiscale is babase.UIScale.MEDIUM else 490) - open_pos_y = (100 if _uiscale is babase.UIScale.SMALL else - 110 if _uiscale is babase.UIScale.MEDIUM else 120) + open_pos_x = (440 if _uiscale() is babase.UIScale.SMALL else + 500 if _uiscale() is babase.UIScale.MEDIUM else 490) + open_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else + 110 if _uiscale() is babase.UIScale.MEDIUM else 120) open_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1285,10 +1285,10 @@ class PluginWindow(popup.PopupWindow): ) if to_draw_button4: - settings_pos_x = (60 if _uiscale is babase.UIScale.SMALL else - 60 if _uiscale is babase.UIScale.MEDIUM else 60) - settings_pos_y = (100 if _uiscale is babase.UIScale.SMALL else - 110 if _uiscale is babase.UIScale.MEDIUM else 120) + settings_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else + 60 if _uiscale() is babase.UIScale.MEDIUM else 60) + settings_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else + 110 if _uiscale() is babase.UIScale.MEDIUM else 120) settings_button = bui.buttonwidget( parent=self._root_widget, autoselect=True, @@ -1552,8 +1552,8 @@ class PluginSourcesWindow(popup.PopupWindow): size=(400, 340), on_outside_click_call=self._ok, transition=transition, - scale=(2.1 if _uiscale is babase.UIScale.SMALL else 1.5 - if _uiscale is babase.UIScale.MEDIUM else 1.0), + scale=(2.1 if _uiscale() is babase.UIScale.SMALL else 1.5 + if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin, on_cancel_call=self._ok ) @@ -1570,12 +1570,12 @@ class PluginSourcesWindow(popup.PopupWindow): maxwidth=270, ) - scroll_size_x = (290 if _uiscale is babase.UIScale.SMALL else - 300 if _uiscale is babase.UIScale.MEDIUM else 290) - scroll_size_y = (170 if _uiscale is babase.UIScale.SMALL else - 185 if _uiscale is babase.UIScale.MEDIUM else 180) - scroll_pos_x = (55 if _uiscale is babase.UIScale.SMALL else - 40 if _uiscale is babase.UIScale.MEDIUM else 60) + scroll_size_x = (290 if _uiscale() is babase.UIScale.SMALL else + 300 if _uiscale() is babase.UIScale.MEDIUM else 290) + scroll_size_y = (170 if _uiscale() is babase.UIScale.SMALL else + 185 if _uiscale() is babase.UIScale.MEDIUM else 180) + scroll_pos_x = (55 if _uiscale() is babase.UIScale.SMALL else + 40 if _uiscale() is babase.UIScale.MEDIUM else 60) scroll_pos_y = 105 self._scrollwidget = bui.scrollwidget( @@ -1613,8 +1613,8 @@ class PluginSourcesWindow(popup.PopupWindow): draw_controller=delete_source_button ) - warning_pos_x = (43 if _uiscale is babase.UIScale.SMALL else - 35 if _uiscale is babase.UIScale.MEDIUM else + warning_pos_x = (43 if _uiscale() is babase.UIScale.SMALL else + 35 if _uiscale() is babase.UIScale.MEDIUM else 48) bui.textwidget( parent=self._root_widget, @@ -1731,8 +1731,8 @@ class PluginCategoryWindow(popup.PopupMenuWindow): self.scale_origin = origin_widget.get_screen_space_center() super().__init__( position=self.scale_origin, - scale=(2.3 if _uiscale is babase.UIScale.SMALL else - 1.65 if _uiscale is babase.UIScale.MEDIUM else 1.23), + scale=(2.3 if _uiscale() is babase.UIScale.SMALL else + 1.65 if _uiscale() is babase.UIScale.MEDIUM else 1.23), choices=choices, current_choice=current_choice, delegate=self @@ -1773,13 +1773,13 @@ class PluginManagerWindow(bui.MainWindow): loop.create_task(self.draw_index()) - self._width = (700 if _uiscale is babase.UIScale.SMALL - else 550 if _uiscale is babase.UIScale.MEDIUM + self._width = (700 if _uiscale() is babase.UIScale.SMALL + else 550 if _uiscale() is babase.UIScale.MEDIUM else 570) - self._height = (500 if _uiscale is babase.UIScale.SMALL - else 422 if _uiscale is babase.UIScale.MEDIUM + self._height = (500 if _uiscale() is babase.UIScale.SMALL + else 422 if _uiscale() is babase.UIScale.MEDIUM else 500) - top_extra = 20 if _uiscale is babase.UIScale.SMALL else 0 + top_extra = 20 if _uiscale() is babase.UIScale.SMALL else 0 if origin_widget: self._transition_out = "out_scale" @@ -1790,21 +1790,21 @@ class PluginManagerWindow(bui.MainWindow): root_widget=bui.containerwidget( size=(self._width, self._height + top_extra), toolbar_visibility="menu_minimal", - scale=(1.9 if _uiscale is babase.UIScale.SMALL - else 1.5 if _uiscale is babase.UIScale.MEDIUM + scale=(1.9 if _uiscale() is babase.UIScale.SMALL + else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), - stack_offset=(0, -25) if _uiscale is babase.UIScale.SMALL else (0, 0) + stack_offset=(0, -25) if _uiscale() is babase.UIScale.SMALL else (0, 0) ), transition=transition, origin_widget=origin_widget, ) - back_pos_x = 5 + (37 if _uiscale is babase.UIScale.SMALL else - 27 if _uiscale is babase.UIScale.MEDIUM else 68) - back_pos_y = self._height - (95 if _uiscale is babase.UIScale.SMALL else - 65 if _uiscale is babase.UIScale.MEDIUM else 50) + back_pos_x = 5 + (37 if _uiscale() is babase.UIScale.SMALL else + 27 if _uiscale() is babase.UIScale.MEDIUM else 68) + back_pos_y = self._height - (95 if _uiscale() is babase.UIScale.SMALL else + 65 if _uiscale() is babase.UIScale.MEDIUM else 50) - if _uiscale is bui.UIScale.SMALL: + if _uiscale() is bui.UIScale.SMALL: self._back_button = None bui.containerwidget( edit=self._root_widget, on_cancel_call=self.main_window_back @@ -1822,8 +1822,8 @@ class PluginManagerWindow(bui.MainWindow): bui.containerwidget(edit=self._root_widget, cancel_button=back_button) - title_pos = self._height - (83 if _uiscale is babase.UIScale.SMALL else - 50 if _uiscale is babase.UIScale.MEDIUM else 50) + title_pos = self._height - (83 if _uiscale() is babase.UIScale.SMALL else + 50 if _uiscale() is babase.UIScale.MEDIUM else 50) bui.textwidget( parent=self._root_widget, position=(-10, title_pos), @@ -1836,8 +1836,8 @@ class PluginManagerWindow(bui.MainWindow): maxwidth=270, ) - loading_pos_y = self._height - (275 if _uiscale is babase.UIScale.SMALL else - 235 if _uiscale is babase.UIScale.MEDIUM else 270) + loading_pos_y = self._height - (275 if _uiscale() is babase.UIScale.SMALL else + 235 if _uiscale() is babase.UIScale.MEDIUM else 270) self._plugin_manager_status_text = bui.textwidget( parent=self._root_widget, @@ -1905,14 +1905,14 @@ class PluginManagerWindow(bui.MainWindow): await self.select_category("All") def draw_plugins_scroll_bar(self): - scroll_size_x = (515 if _uiscale is babase.UIScale.SMALL else - 430 if _uiscale is babase.UIScale.MEDIUM else 420) - scroll_size_y = (245 if _uiscale is babase.UIScale.SMALL else - 265 if _uiscale is babase.UIScale.MEDIUM else 335) - scroll_pos_x = (70 if _uiscale is babase.UIScale.SMALL else - 50 if _uiscale is babase.UIScale.MEDIUM else 70) - scroll_pos_y = (100 if _uiscale is babase.UIScale.SMALL else - 35 if _uiscale is babase.UIScale.MEDIUM else 40) + scroll_size_x = (515 if _uiscale() is babase.UIScale.SMALL else + 430 if _uiscale() is babase.UIScale.MEDIUM else 420) + scroll_size_y = (245 if _uiscale() is babase.UIScale.SMALL else + 265 if _uiscale() is babase.UIScale.MEDIUM else 335) + scroll_pos_x = (70 if _uiscale() is babase.UIScale.SMALL else + 50 if _uiscale() is babase.UIScale.MEDIUM else 70) + scroll_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else + 35 if _uiscale() is babase.UIScale.MEDIUM else 40) self._scrollwidget = bui.scrollwidget(parent=self._root_widget, size=(scroll_size_x, scroll_size_y), position=(scroll_pos_x, scroll_pos_y)) @@ -1921,10 +1921,10 @@ class PluginManagerWindow(bui.MainWindow): margin=0) def draw_category_selection_button(self, post_label): - category_pos_x = (440 if _uiscale is babase.UIScale.SMALL else - 340 if _uiscale is babase.UIScale.MEDIUM else 370) - category_pos_y = self._height - (141 if _uiscale is babase.UIScale.SMALL else - 110 if _uiscale is babase.UIScale.MEDIUM else 110) + category_pos_x = (440 if _uiscale() is babase.UIScale.SMALL else + 340 if _uiscale() is babase.UIScale.MEDIUM else 370) + category_pos_y = self._height - (141 if _uiscale() is babase.UIScale.SMALL else + 110 if _uiscale() is babase.UIScale.MEDIUM else 110) b_size = (140, 30) b_textcolor = (0.8, 0.8, 0.85) @@ -1979,22 +1979,22 @@ class PluginManagerWindow(bui.MainWindow): ) def draw_search_bar(self): - search_bar_pos_x = (85 if _uiscale is babase.UIScale.SMALL else - 68 if _uiscale is babase.UIScale.MEDIUM else 75) + search_bar_pos_x = (85 if _uiscale() is babase.UIScale.SMALL else + 68 if _uiscale() is babase.UIScale.MEDIUM else 75) search_bar_pos_y = self._height - ( - 145 if _uiscale is babase.UIScale.SMALL else - 110 if _uiscale is babase.UIScale.MEDIUM else 116) + 145 if _uiscale() is babase.UIScale.SMALL else + 110 if _uiscale() is babase.UIScale.MEDIUM else 116) - search_bar_size_x = (320 if _uiscale is babase.UIScale.SMALL else - 230 if _uiscale is babase.UIScale.MEDIUM else 260) + search_bar_size_x = (320 if _uiscale() is babase.UIScale.SMALL else + 230 if _uiscale() is babase.UIScale.MEDIUM else 260) search_bar_size_y = ( - 35 if _uiscale is babase.UIScale.SMALL else - 35 if _uiscale is babase.UIScale.MEDIUM else 45) + 35 if _uiscale() is babase.UIScale.SMALL else + 35 if _uiscale() is babase.UIScale.MEDIUM else 45) - filter_txt_pos_x = (60 if _uiscale is babase.UIScale.SMALL else - 40 if _uiscale is babase.UIScale.MEDIUM else 50) - filter_txt_pos_y = search_bar_pos_y + (3 if _uiscale is babase.UIScale.SMALL else - 4 if _uiscale is babase.UIScale.MEDIUM else 8) + filter_txt_pos_x = (60 if _uiscale() is babase.UIScale.SMALL else + 40 if _uiscale() is babase.UIScale.MEDIUM else 50) + filter_txt_pos_y = search_bar_pos_y + (3 if _uiscale() is babase.UIScale.SMALL else + 4 if _uiscale() is babase.UIScale.MEDIUM else 8) bui.textwidget(parent=self._root_widget, text="Filter", @@ -2006,8 +2006,8 @@ class PluginManagerWindow(bui.MainWindow): scale=0.5) filter_txt = babase.Lstr(resource='filterText') - search_bar_maxwidth = search_bar_size_x - (95 if _uiscale is babase.UIScale.SMALL else - 77 if _uiscale is babase.UIScale.MEDIUM else + search_bar_maxwidth = search_bar_size_x - (95 if _uiscale() is babase.UIScale.SMALL else + 77 if _uiscale() is babase.UIScale.MEDIUM else 85) self._filter_widget = bui.textwidget(parent=self._root_widget, text="", @@ -2041,10 +2041,10 @@ class PluginManagerWindow(bui.MainWindow): pass def draw_settings_icon(self): - settings_pos_x = (610 if _uiscale is babase.UIScale.SMALL else - 500 if _uiscale is babase.UIScale.MEDIUM else 510) - settings_pos_y = (130 if _uiscale is babase.UIScale.SMALL else - 60 if _uiscale is babase.UIScale.MEDIUM else 70) + settings_pos_x = (610 if _uiscale() is babase.UIScale.SMALL else + 500 if _uiscale() is babase.UIScale.MEDIUM else 510) + settings_pos_y = (130 if _uiscale() is babase.UIScale.SMALL else + 60 if _uiscale() is babase.UIScale.MEDIUM else 70) controller_button = bui.buttonwidget(parent=self._root_widget, position=(settings_pos_x, settings_pos_y), size=(30, 30), @@ -2066,10 +2066,10 @@ class PluginManagerWindow(bui.MainWindow): draw_controller=controller_button) def draw_refresh_icon(self): - refresh_pos_x = (610 if _uiscale is babase.UIScale.SMALL else - 500 if _uiscale is babase.UIScale.MEDIUM else 510) - refresh_pos_y = (180 if _uiscale is babase.UIScale.SMALL else - 108 if _uiscale is babase.UIScale.MEDIUM else 120) + refresh_pos_x = (610 if _uiscale() is babase.UIScale.SMALL else + 500 if _uiscale() is babase.UIScale.MEDIUM else 510) + refresh_pos_y = (180 if _uiscale() is babase.UIScale.SMALL else + 108 if _uiscale() is babase.UIScale.MEDIUM else 120) controller_button = bui.buttonwidget( parent=self._root_widget, @@ -2262,7 +2262,7 @@ class PluginManagerSettingsWindow(popup.PopupWindow): async def draw_ui(self): b_text_color = (0.8, 0.8, 0.85) - s = 1.25 if _uiscale is babase.UIScale.SMALL else 1.27 if _uiscale is babase.UIScale.MEDIUM else 1.3 + s = 1.25 if _uiscale() is babase.UIScale.SMALL else 1.27 if _uiscale() is babase.UIScale.MEDIUM else 1.3 width = 380 * s height = 150 + 150 * s color = (0.9, 0.9, 0.9) @@ -2281,8 +2281,8 @@ class PluginManagerSettingsWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._ok, transition=transition, - scale=(2.1 if _uiscale is babase.UIScale.SMALL else 1.5 - if _uiscale is babase.UIScale.MEDIUM else 1.0), + scale=(2.1 if _uiscale() is babase.UIScale.SMALL else 1.5 + if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) pos = height * 0.9 From 81db33cccebdb0a78af06b61c8b78346147f0c97 Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 4 Aug 2025 21:07:55 +0530 Subject: [PATCH 03/29] More Cleaning Up --- plugin_manager.py | 66 +++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index b949ec3..69854ca 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1913,12 +1913,16 @@ class PluginManagerWindow(bui.MainWindow): 50 if _uiscale() is babase.UIScale.MEDIUM else 70) scroll_pos_y = (100 if _uiscale() is babase.UIScale.SMALL else 35 if _uiscale() is babase.UIScale.MEDIUM else 40) - self._scrollwidget = bui.scrollwidget(parent=self._root_widget, - size=(scroll_size_x, scroll_size_y), - position=(scroll_pos_x, scroll_pos_y)) - self._columnwidget = bui.columnwidget(parent=self._scrollwidget, - border=2, - margin=0) + self._scrollwidget = bui.scrollwidget( + parent=self._root_widget, + size=(scroll_size_x, scroll_size_y), + position=(scroll_pos_x, scroll_pos_y) + ) + self._columnwidget = bui.columnwidget( + parent=self._scrollwidget, + border=2, + margin=0 + ) def draw_category_selection_button(self, post_label): category_pos_x = (440 if _uiscale() is babase.UIScale.SMALL else @@ -2009,17 +2013,19 @@ class PluginManagerWindow(bui.MainWindow): search_bar_maxwidth = search_bar_size_x - (95 if _uiscale() is babase.UIScale.SMALL else 77 if _uiscale() is babase.UIScale.MEDIUM else 85) - self._filter_widget = bui.textwidget(parent=self._root_widget, - text="", - size=(search_bar_size_x, search_bar_size_y), - position=(search_bar_pos_x, search_bar_pos_y), - h_align='left', - v_align='center', - editable=True, - scale=0.8, - autoselect=True, - maxwidth=search_bar_maxwidth, - description=filter_txt) + self._filter_widget = bui.textwidget( + parent=self._root_widget, + text="", + size=(search_bar_size_x, search_bar_size_y), + position=(search_bar_pos_x, search_bar_pos_y), + h_align='left', + v_align='center', + editable=True, + scale=0.8, + autoselect=True, + maxwidth=search_bar_maxwidth, + description=filter_txt + ) self._last_filter_text = "" self._last_filter_plugins = [] @@ -2045,11 +2051,13 @@ class PluginManagerWindow(bui.MainWindow): 500 if _uiscale() is babase.UIScale.MEDIUM else 510) settings_pos_y = (130 if _uiscale() is babase.UIScale.SMALL else 60 if _uiscale() is babase.UIScale.MEDIUM else 70) - controller_button = bui.buttonwidget(parent=self._root_widget, - position=(settings_pos_x, settings_pos_y), - size=(30, 30), - button_type="square", - label="") + controller_button = bui.buttonwidget( + parent=self._root_widget, + position=(settings_pos_x, settings_pos_y), + size=(30, 30), + button_type="square", + label="" + ) bui.buttonwidget( controller_button, on_activate_call=babase.Call( @@ -2058,12 +2066,14 @@ class PluginManagerWindow(bui.MainWindow): controller_button ) ) - bui.imagewidget(parent=self._root_widget, - position=(settings_pos_x, settings_pos_y), - size=(30, 30), - color=(0.8, 0.95, 1), - texture=bui.gettexture("settingsIcon"), - draw_controller=controller_button) + bui.imagewidget( + parent=self._root_widget, + position=(settings_pos_x, settings_pos_y), + size=(30, 30), + color=(0.8, 0.95, 1), + texture=bui.gettexture("settingsIcon"), + draw_controller=controller_button + ) def draw_refresh_icon(self): refresh_pos_x = (610 if _uiscale() is babase.UIScale.SMALL else From 1e47a0dd6bac8e284c6e5af21b65c6fa55dd2a9a Mon Sep 17 00:00:00 2001 From: Vishal Date: Tue, 5 Aug 2025 06:27:53 +0530 Subject: [PATCH 04/29] More CLeaning Up --- plugin_manager.py | 369 ++++++++++++++++++++++++---------------------- 1 file changed, 193 insertions(+), 176 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 69854ca..977ad75 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -23,7 +23,7 @@ import pathlib import hashlib import contextlib -from typing import cast +from typing import cast, override from datetime import datetime # Modules used for overriding AllSettingsWindow @@ -838,6 +838,183 @@ class Plugin: bui.getsound('error').play() +class PluginManager: + def __init__(self): + self.request_headers = HEADERS + self._index = _CACHE.get("index", {}) + self._changelog = _CACHE.get("changelog", {}) + self.categories = {} + self.module_path = sys.modules[__name__].__file__ + self._index_setup_in_progress = False + self._changelog_setup_in_progress = False + + async def get_index(self): + if not self._index: + request = urllib.request.Request( + INDEX_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers, + ) + response = await async_send_network_request(request) + index = json.loads(response.read()) + self.set_index_global_cache(index) + self._index = index + return self._index + + async def setup_index(self): + while self._index_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._index_setup_in_progress = not bool(self._index) + index = await self.get_index() + await self.setup_plugin_categories(index) + self._index_setup_in_progress = False + + async def get_changelog(self) -> str: + requested = False + if not self._changelog: + request = urllib.request.Request(CHANGELOG_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers) + response = await async_send_network_request(request) + self._changelog = response.read().decode() + requested = True + return [self._changelog, requested] + + async def setup_changelog(self, version=None) -> None: + if version is None: + version = PLUGIN_MANAGER_VERSION + while self._changelog_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._changelog_setup_in_progress = not bool(self._changelog) + try: + full_changelog = await self.get_changelog() + if full_changelog[1]: + pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" + released_on = full_changelog[0].split(version)[1].split('\n')[0] + matches = re.findall(pattern, full_changelog[0], re.DOTALL) + if matches: + changelog = { + 'released_on': released_on, + 'info': matches[0].strip() + } + else: + changelog = {'released_on': ' (Not Provided)', + 'info': f"Changelog entry for version {version} not found."} + else: + changelog = full_changelog[0] + except urllib.error.URLError: + changelog = {'released_on': ' (Not Provided)', + 'info': 'Could not get ChangeLog due to Internet Issues.'} + self.set_changelog_global_cache(changelog) + self._changelog_setup_in_progress = False + + async def setup_plugin_categories(self, plugin_index): + # A hack to have the "All" category show at the top. + self.categories["All"] = None + + requests = [] + for meta_url in plugin_index["categories"]: + category = Category(meta_url) + request = category.fetch_metadata() + requests.append(request) + for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: + source_splits = source.split("@", maxsplit=1) + if len(source_splits) == 1: + # Fallack to `main` if `@branchname` isn't specified in an external source URI. + source_repo, source_tag = source_splits[0], "main" + else: + source_repo, source_tag = source_splits + meta_url = partial_format( + plugin_index["external_source_url"], + repository=source_repo, + ) + category = Category(meta_url, tag=source_tag) + request = category.fetch_metadata() + requests.append(request) + categories = await asyncio.gather(*requests) + + all_plugins = [] + for category in categories: + self.categories[await category.get_name()] = category + all_plugins.extend(await category.get_plugins()) + self.categories["All"] = CategoryAll(plugins=all_plugins) + + def cleanup(self): + for category in self.categories.values(): + if category is not None: + category.cleanup() + self.categories.clear() + self._index.clear() + self._changelog = None + self.unset_index_global_cache() + + async def refresh(self): + self.cleanup() + await self.setup_index() + + def set_index_global_cache(self, index): + _CACHE["index"] = index + + def set_changelog_global_cache(self, changelog): + _CACHE["changelog"] = changelog + + def unset_index_global_cache(self): + try: + del _CACHE["index"] + del _CACHE["changelog"] + except KeyError: + pass + + async def get_update_details(self): + index = await self.get_index() + for version, info in index["versions"].items(): + if info["api_version"] != _app_api_version: + # No point checking a version of the API game doesn't support. + continue + if version == PLUGIN_MANAGER_VERSION: + # We're already on the latest version for the current API. + return + else: + if next(iter(index["versions"])) == version: + # Version on the top is the latest, so no need to specify + # the commit SHA explicitly to GitHub to access the latest file. + commit_sha = None + else: + commit_sha = info["commit_sha"] + return version, commit_sha + + async def update(self, to_version=None, commit_sha=None): + index = await self.get_index() + if to_version is None: + to_version, commit_sha = await self.get_update_details() + to_version_info = index["versions"][to_version] + tag = commit_sha or CURRENT_TAG + download_url = index["plugin_manager_url"].format( + content_type="raw", + tag=tag, + ) + response = await async_send_network_request(download_url) + content = response.read() + if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: + raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") + with open(self.module_path, "wb") as fout: + fout.write(content) + return to_version_info + + async def soft_refresh(self): + pass + + class ChangelogWindow(popup.PopupWindow): def __init__(self, origin_widget): self.scale_origin = origin_widget.get_screen_space_center() @@ -1362,181 +1539,7 @@ class PluginWindow(popup.PopupWindow): bui.getsound('shieldUp').play() -class PluginManager: - def __init__(self): - self.request_headers = HEADERS - self._index = _CACHE.get("index", {}) - self._changelog = _CACHE.get("changelog", {}) - self.categories = {} - self.module_path = sys.modules[__name__].__file__ - self._index_setup_in_progress = False - self._changelog_setup_in_progress = False - async def get_index(self): - if not self._index: - request = urllib.request.Request( - INDEX_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers, - ) - response = await async_send_network_request(request) - index = json.loads(response.read()) - self.set_index_global_cache(index) - self._index = index - return self._index - - async def setup_index(self): - while self._index_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._index_setup_in_progress = not bool(self._index) - index = await self.get_index() - await self.setup_plugin_categories(index) - self._index_setup_in_progress = False - - async def get_changelog(self) -> str: - requested = False - if not self._changelog: - request = urllib.request.Request(CHANGELOG_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers) - response = await async_send_network_request(request) - self._changelog = response.read().decode() - requested = True - return [self._changelog, requested] - - async def setup_changelog(self, version=None) -> None: - if version is None: - version = PLUGIN_MANAGER_VERSION - while self._changelog_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._changelog_setup_in_progress = not bool(self._changelog) - try: - full_changelog = await self.get_changelog() - if full_changelog[1]: - pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" - released_on = full_changelog[0].split(version)[1].split('\n')[0] - matches = re.findall(pattern, full_changelog[0], re.DOTALL) - if matches: - changelog = { - 'released_on': released_on, - 'info': matches[0].strip() - } - else: - changelog = {'released_on': ' (Not Provided)', - 'info': f"Changelog entry for version {version} not found."} - else: - changelog = full_changelog[0] - except urllib.error.URLError: - changelog = {'released_on': ' (Not Provided)', - 'info': 'Could not get ChangeLog due to Internet Issues.'} - self.set_changelog_global_cache(changelog) - self._changelog_setup_in_progress = False - - async def setup_plugin_categories(self, plugin_index): - # A hack to have the "All" category show at the top. - self.categories["All"] = None - - requests = [] - for meta_url in plugin_index["categories"]: - category = Category(meta_url) - request = category.fetch_metadata() - requests.append(request) - for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: - source_splits = source.split("@", maxsplit=1) - if len(source_splits) == 1: - # Fallack to `main` if `@branchname` isn't specified in an external source URI. - source_repo, source_tag = source_splits[0], "main" - else: - source_repo, source_tag = source_splits - meta_url = partial_format( - plugin_index["external_source_url"], - repository=source_repo, - ) - category = Category(meta_url, tag=source_tag) - request = category.fetch_metadata() - requests.append(request) - categories = await asyncio.gather(*requests) - - all_plugins = [] - for category in categories: - self.categories[await category.get_name()] = category - all_plugins.extend(await category.get_plugins()) - self.categories["All"] = CategoryAll(plugins=all_plugins) - - def cleanup(self): - for category in self.categories.values(): - if category is not None: - category.cleanup() - self.categories.clear() - self._index.clear() - self._changelog = None - self.unset_index_global_cache() - - async def refresh(self): - self.cleanup() - await self.setup_index() - - def set_index_global_cache(self, index): - _CACHE["index"] = index - - def set_changelog_global_cache(self, changelog): - _CACHE["changelog"] = changelog - - def unset_index_global_cache(self): - try: - del _CACHE["index"] - del _CACHE["changelog"] - except KeyError: - pass - - async def get_update_details(self): - index = await self.get_index() - for version, info in index["versions"].items(): - if info["api_version"] != _app_api_version: - # No point checking a version of the API game doesn't support. - continue - if version == PLUGIN_MANAGER_VERSION: - # We're already on the latest version for the current API. - return - else: - if next(iter(index["versions"])) == version: - # Version on the top is the latest, so no need to specify - # the commit SHA explicitly to GitHub to access the latest file. - commit_sha = None - else: - commit_sha = info["commit_sha"] - return version, commit_sha - - async def update(self, to_version=None, commit_sha=None): - index = await self.get_index() - if to_version is None: - to_version, commit_sha = await self.get_update_details() - to_version_info = index["versions"][to_version] - tag = commit_sha or CURRENT_TAG - download_url = index["plugin_manager_url"].format( - content_type="raw", - tag=tag, - ) - response = await async_send_network_request(download_url) - content = response.read() - if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: - raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") - with open(self.module_path, "wb") as fout: - fout.write(content) - return to_version_info - - async def soft_refresh(self): - pass class PluginSourcesWindow(popup.PopupWindow): @@ -1763,7 +1766,11 @@ class PluginCategoryWindow(popup.PopupMenuWindow): class PluginManagerWindow(bui.MainWindow): - def __init__(self, transition: str = "in_right", origin_widget: bui.Widget = None): + def __init__( + self, + transition: str = "in_right", + origin_widget: bui.Widget = None + ): self.plugin_manager = PluginManager() self.category_selection_button = None self.selected_category = 'All' @@ -1857,6 +1864,16 @@ class PluginManagerWindow(bui.MainWindow): size=48, ) + @override + def get_main_window_state(self) -> bui.MainWindowState: + # Support recreating our window for back/refresh purposes. + cls = type(self) + return bui.BasicMainWindowState( + create_call=lambda transition, origin_widget: cls( + transition=transition, origin_widget=origin_widget + ) + ) + def spin(self, show=False): w = self._loading_spinner p = self._root_widget From d52b10fb069f2a6b02810ca78dc30bfd0bed424f Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 6 Aug 2025 00:50:09 +0530 Subject: [PATCH 05/29] Can move through Plugins --- plugin_manager.py | 108 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 977ad75..e897f0b 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1203,8 +1203,17 @@ class AuthorsWindow(popup.PopupWindow): class PluginWindow(popup.PopupWindow): - def __init__(self, plugin, origin_widget, button_callback=lambda: None): - self.plugin = plugin + def __init__( + self, + plugin: Plugin, + origin_widget, + plugins_list, + transition = 'in_scale', + button_callback=lambda: None, + ): + self.plugin: Plugin = plugin + self.transition = transition + self.plugins_list = plugins_list self.button_callback = button_callback self.scale_origin = origin_widget.get_screen_space_center() @@ -1212,7 +1221,7 @@ class PluginWindow(popup.PopupWindow): def get_description(self, minimum_character_offset=40): """ - Splits the loong plugin description into multiple lines. + Splits the long plugin description into multiple lines. """ string = self.plugin.info["description"] string_length = len(string) @@ -1237,22 +1246,49 @@ class PluginWindow(popup.PopupWindow): bui.getsound('swish').play() b_text_color = (0.75, 0.7, 0.8) s = 1.25 if _uiscale() is babase.UIScale.SMALL else 1.39 if babase.UIScale.MEDIUM else 1.67 - width = 400 * s + width = 450 * s height = 120 + 100 * s color = (1, 1, 1) text_scale = 0.7 * s - self._transition_out = 'out_scale' - transition = 'in_scale' self._root_widget = bui.containerwidget( size=(width, height), on_outside_click_call=self._cancel, - transition=transition, + transition=self.transition, scale=(2.1 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) + i = self.plugins_list.index(self.plugin) + self.p_n_plugins = [ + self.plugins_list[i-1] if (i-1 > -1) else None, + self.plugins_list[i+1] if (i+1 < len(self.plugins_list)) else None + ] + + if self.p_n_plugins is not None: + if self.p_n_plugins[0] is not None: + previous_plugin_button = bui.buttonwidget( + parent=self._root_widget, + position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), height/2 - 20*s), + label='<', + size=(25, 40), + color=(1, 0.5, 0.5), + scale=s, + on_activate_call=self.show_previous_plugin + ) + + if self.p_n_plugins[1] is not None: + next_plugin_button = bui.buttonwidget( + parent=self._root_widget, + position=(width - 12.5*s - (8 if _uiscale() is babase.UIScale.SMALL else 0), height/2 - 20*s), + label='>', + size=(25, 40), + color=(1, 0.5, 0.5), + scale=s, + on_activate_call=self.show_next_plugin + ) + pos = height * 0.8 plug_name = self.plugin.name.replace('_', ' ').title() plugin_title = f"{plug_name} (v{self.plugin.latest_compatible_version.number})" @@ -1514,6 +1550,26 @@ class PluginWindow(popup.PopupWindow): def settings(self, source_widget): self.local_plugin.launch_settings(source_widget) + def show_previous_plugin(self): + bui.containerwidget(edit=self._root_widget, transition='out_right') + PluginWindow( + self.p_n_plugins[0], + self._root_widget, + transition='in_left', + plugins_list=self.plugins_list, + button_callback=lambda: None + ) + + def show_next_plugin(self): + bui.containerwidget(edit=self._root_widget, transition='out_left') + PluginWindow( + self.p_n_plugins[1], + self._root_widget, + transition='in_right', + plugins_list=self.plugins_list, + button_callback=lambda: None + ) + @button def disable(self) -> None: self.local_plugin.disable() @@ -1539,9 +1595,6 @@ class PluginWindow(popup.PopupWindow): bui.getsound('shieldUp').play() - - - class PluginSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): self.selected_source = None @@ -2174,29 +2227,33 @@ class PluginManagerWindow(bui.MainWindow): if category == 'Installed': plugin_names_to_draw = tuple( - self.draw_plugin_name(plugin) for plugin in plugins if plugin.is_installed + plugin for plugin in plugins if plugin.is_installed ) else: - plugin_names_to_draw = tuple(self.draw_plugin_name(plugin) for plugin in plugins) + plugin_names_to_draw = plugins [plugin.delete() for plugin in self._columnwidget.get_children()] text_widget = bui.textwidget(parent=self._columnwidget) text_widget.delete() - await asyncio.gather(*plugin_names_to_draw) + # await asyncio.gather(*plugin_names_to_draw) - async def draw_plugin_name(self, plugin): - try: - latest_compatible_version = plugin.latest_compatible_version - except NoCompatibleVersion: - # We currently don't show plugins that have no compatible versions. - return + plugin_names_ready_to_draw = [] + for plugin in plugin_names_to_draw: + try: lcv = plugin.latest_compatible_version + except NoCompatibleVersion: continue + plugin_names_ready_to_draw += [plugin] + + for i, plugin in enumerate(plugin_names_ready_to_draw): + await self.draw_plugin_name(plugin, plugin_names_ready_to_draw) + + async def draw_plugin_name(self, plugin, plugins_list): if plugin.is_installed: local_plugin = plugin.get_local() if await local_plugin.is_enabled(): if not local_plugin.is_installed_via_plugin_manager: color = (0.8, 0.2, 0.2) - elif local_plugin.version == latest_compatible_version.number: + elif local_plugin.version == plugin.latest_compatible_version.number: color = (0, 0.95, 0.2) else: color = (1, 0.6, 0) @@ -2220,7 +2277,7 @@ class PluginManagerWindow(bui.MainWindow): color=color, text=plugin.name.replace('_', ' ').title(), click_activate=True, - on_activate_call=lambda: self.show_plugin_window(plugin), + on_activate_call=lambda: self.show_plugin_window(plugin, plugins_list), h_align='left', v_align='center', maxwidth=420 @@ -2229,8 +2286,13 @@ class PluginManagerWindow(bui.MainWindow): # XXX: This seems nicer. Might wanna use this in future. # text_widget.add_delete_callback(lambda: self.plugins_in_current_view.pop(plugin.name)) - def show_plugin_window(self, plugin): - PluginWindow(plugin, self._root_widget, lambda: self.draw_plugin_name(plugin)) + def show_plugin_window(self, plugin, plugins_list): + PluginWindow( + plugin, + self._root_widget, + plugins_list=plugins_list, + button_callback=lambda: self.draw_plugin_name(plugin, plugins_list) + ) def show_categories_window(self, source): PluginCategoryWindow( From eb7947b2dce87601312a1c55b26bc1328e71beb5 Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 6 Aug 2025 00:53:13 +0530 Subject: [PATCH 06/29] V-1.2.1 --- index.json | 1 + plugin_manager.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index 9fabd13..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,6 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", diff --git a/plugin_manager.py b/plugin_manager.py index e897f0b..e5c311c 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,7 @@ from datetime import datetime # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.1.3" +PLUGIN_MANAGER_VERSION = "1.2.1" REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. From 65c7bdc7e00aea9ae75daded79e55fe05d46e831 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:24:53 +0000 Subject: [PATCH 07/29] [ci] auto-format --- plugin_manager.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index e5c311c..7226677 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1031,7 +1031,8 @@ class ChangelogWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._back, transition=transition, - scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), + scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() + is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -1163,7 +1164,7 @@ class AuthorsWindow(popup.PopupWindow): parent=self._root_widget, size=(width * 0.8, height * 0.75), position=(width * 0.1, height * 0.1) - ) + ) self._columnwidget = bui.columnwidget( parent=self._scrollwidget, border=1, @@ -1181,9 +1182,9 @@ class AuthorsWindow(popup.PopupWindow): size=(width * 0.8, 35 if key == 'name' else 30), color=color if key == 'name' else (0.75, 0.7, 0.8), scale=( - (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else - (1.2 if key == 'name' else 1.0) - ), + (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else + (1.2 if key == 'name' else 1.0) + ), text=text, h_align='center', v_align='center', @@ -1208,7 +1209,7 @@ class PluginWindow(popup.PopupWindow): plugin: Plugin, origin_widget, plugins_list, - transition = 'in_scale', + transition='in_scale', button_callback=lambda: None, ): self.plugin: Plugin = plugin @@ -1270,7 +1271,8 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[0] is not None: previous_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), height/2 - 20*s), + position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), + height/2 - 20*s), label='<', size=(25, 40), color=(1, 0.5, 0.5), @@ -1281,7 +1283,8 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[1] is not None: next_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(width - 12.5*s - (8 if _uiscale() is babase.UIScale.SMALL else 0), height/2 - 20*s), + position=(width - 12.5*s - (8 if _uiscale() + is babase.UIScale.SMALL else 0), height/2 - 20*s), label='>', size=(25, 40), color=(1, 0.5, 0.5), @@ -1376,7 +1379,7 @@ class PluginWindow(popup.PopupWindow): parent=self._root_widget, position=( width * (0.1 if self.plugin.is_installed and has_update else - 0.25 if self.plugin.is_installed else 0.4), pos + 0.25 if self.plugin.is_installed else 0.4), pos ), size=button_size, on_activate_call=button1_action, @@ -2032,7 +2035,8 @@ class PluginManagerWindow(bui.MainWindow): textcolor=b_textcolor, text_scale=0.6 ) - bui.buttonwidget(edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), + bui.buttonwidget( + edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), else: b = self.category_selection_button bui.buttonwidget( @@ -2239,8 +2243,10 @@ class PluginManagerWindow(bui.MainWindow): plugin_names_ready_to_draw = [] for plugin in plugin_names_to_draw: - try: lcv = plugin.latest_compatible_version - except NoCompatibleVersion: continue + try: + lcv = plugin.latest_compatible_version + except NoCompatibleVersion: + continue plugin_names_ready_to_draw += [plugin] for i, plugin in enumerate(plugin_names_ready_to_draw): @@ -2513,7 +2519,8 @@ class PluginManagerSettingsWindow(popup.PopupWindow): parent=self._root_widget, position=((width * 0.77) - button_size[0] / 2, pos), size=button_size, - on_activate_call=lambda: loop.create_task(self.update(*plugin_manager_update_available)), + on_activate_call=lambda: loop.create_task( + self.update(*plugin_manager_update_available)), textcolor=b_text_color, button_type='square', text_scale=1, From 7611d3fad135bdf5df868d8f99cd00b53e06a8d3 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Tue, 5 Aug 2025 19:24:54 +0000 Subject: [PATCH 08/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..2293932 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "65c7bdc", + "released_on": "05-08-2025", + "md5sum": "b7de1dac07c94cea75195cffead5bd1b" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 51cccdd22847662cceefe3bf32930707572a2f01 Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 6 Aug 2025 00:56:30 +0530 Subject: [PATCH 09/29] Updating Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b9db28..393a492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ## Plugin Manager (dd-mm-yyyy) +### 1.2.1 (05-08-2025) + +- Cleaning up the code. +- UI now works again for small screens. +- Added a new feature to move through plugins. + ### 1.1.3 (06-04-2025) - Hot Fix From 6242ba4f5901babfb87269da392bd9d2568e6355 Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 6 Aug 2025 17:55:51 +0530 Subject: [PATCH 10/29] A Fix which doesn't let popups be in background when UI scale is changed --- plugin_manager.py | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 7226677..d51bb65 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -46,6 +46,13 @@ HEADERS = { PLUGIN_DIRECTORY = _env["python_directory_user"] loop = babase._asyncio._asyncio_event_loop +open_popups = [] + +def _add_popup(popup): open_popups.append(popup) + +def _remove_popup(popup): + try: open_popups.remove(popup) + except ValueError: pass def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") @@ -1036,6 +1043,8 @@ class ChangelogWindow(popup.PopupWindow): scale_origin_stack_offset=self.scale_origin ) + _add_popup(self) + bui.textwidget( parent=self._root_widget, position=(width * 0.49, height * 0.87), @@ -1110,6 +1119,7 @@ class ChangelogWindow(popup.PopupWindow): def _back(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') @@ -1135,6 +1145,8 @@ class AuthorsWindow(popup.PopupWindow): scale_origin_stack_offset=self.scale_origin ) + _add_popup(self) + pos = height * 0.9 bui.textwidget( parent=self._root_widget, @@ -1164,7 +1176,7 @@ class AuthorsWindow(popup.PopupWindow): parent=self._root_widget, size=(width * 0.8, height * 0.75), position=(width * 0.1, height * 0.1) - ) + ) self._columnwidget = bui.columnwidget( parent=self._scrollwidget, border=1, @@ -1200,6 +1212,7 @@ class AuthorsWindow(popup.PopupWindow): def _back(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') @@ -1261,6 +1274,8 @@ class PluginWindow(popup.PopupWindow): scale_origin_stack_offset=self.scale_origin ) + _add_popup(self) + i = self.plugins_list.index(self.plugin) self.p_n_plugins = [ self.plugins_list[i-1] if (i-1 > -1) else None, @@ -1528,10 +1543,12 @@ class PluginWindow(popup.PopupWindow): ) def _ok(self) -> None: + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') def _cancel(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') def button(fn): @@ -1555,6 +1572,7 @@ class PluginWindow(popup.PopupWindow): def show_previous_plugin(self): bui.containerwidget(edit=self._root_widget, transition='out_right') + _remove_popup(self) PluginWindow( self.p_n_plugins[0], self._root_widget, @@ -1565,6 +1583,7 @@ class PluginWindow(popup.PopupWindow): def show_next_plugin(self): bui.containerwidget(edit=self._root_widget, transition='out_left') + _remove_popup(self) PluginWindow( self.p_n_plugins[1], self._root_widget, @@ -1598,7 +1617,7 @@ class PluginWindow(popup.PopupWindow): bui.getsound('shieldUp').play() -class PluginSourcesWindow(popup.PopupWindow): +class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): self.selected_source = None @@ -1617,6 +1636,8 @@ class PluginSourcesWindow(popup.PopupWindow): on_cancel_call=self._ok ) + _add_popup(self) + bui.textwidget( parent=self._root_widget, position=(155, 300), @@ -1780,6 +1801,7 @@ class PluginSourcesWindow(popup.PopupWindow): def _ok(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') @@ -1814,10 +1836,11 @@ class PluginCategoryWindow(popup.PopupMenuWindow): def show_sources_window(self): self._ok() - PluginSourcesWindow(origin_widget=self.root_widget) + PluginCustomSourcesWindow(origin_widget=self.root_widget) def _ok(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self.root_widget, transition='out_scale') @@ -1833,6 +1856,8 @@ class PluginManagerWindow(bui.MainWindow): self.plugins_in_current_view = {} self.selected_alphabet_order = 'a_z' self.alphabet_order_selection_button = None + global open_popups + open_popups = [] loop.create_task(self.draw_index()) @@ -1923,6 +1948,12 @@ class PluginManagerWindow(bui.MainWindow): @override def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. + global open_popups + print(open_popups) + for popup in open_popups: + try: + bui.containerwidget(edit=popup._root_widget, transition='out_scale') + except: pass cls = type(self) return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( @@ -2036,7 +2067,9 @@ class PluginManagerWindow(bui.MainWindow): text_scale=0.6 ) bui.buttonwidget( - edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), + edit=b, + on_activate_call=lambda: self.show_categories_window(source=b) + ) else: b = self.category_selection_button bui.buttonwidget( @@ -2380,6 +2413,7 @@ class PluginManagerSettingsWindow(popup.PopupWindow): if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) + _add_popup(self) pos = height * 0.9 setting_title = "Settings" bui.textwidget( @@ -2600,6 +2634,7 @@ class PluginManagerSettingsWindow(popup.PopupWindow): def _ok(self) -> None: bui.getsound('swish').play() + _remove_popup(self) bui.containerwidget(edit=self._root_widget, transition='out_scale') From 6569a037b7709dbb215798eec37541b671074141 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Wed, 6 Aug 2025 12:26:16 +0000 Subject: [PATCH 11/29] [ci] auto-format --- plugin_manager.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index d51bb65..8b28676 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -48,11 +48,16 @@ loop = babase._asyncio._asyncio_event_loop open_popups = [] + def _add_popup(popup): open_popups.append(popup) -def _remove_popup(popup): - try: open_popups.remove(popup) - except ValueError: pass + +def _remove_popup(popup): + try: + open_popups.remove(popup) + except ValueError: + pass + def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") @@ -1176,7 +1181,7 @@ class AuthorsWindow(popup.PopupWindow): parent=self._root_widget, size=(width * 0.8, height * 0.75), position=(width * 0.1, height * 0.1) - ) + ) self._columnwidget = bui.columnwidget( parent=self._scrollwidget, border=1, @@ -1953,7 +1958,8 @@ class PluginManagerWindow(bui.MainWindow): for popup in open_popups: try: bui.containerwidget(edit=popup._root_widget, transition='out_scale') - except: pass + except: + pass cls = type(self) return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( From bc0abfe7aeb0e3fbb16625efa5c509e7b48e0d43 Mon Sep 17 00:00:00 2001 From: Vishal Date: Thu, 7 Aug 2025 01:25:43 +0530 Subject: [PATCH 12/29] Fixing same previous bug for Category window --- plugin_manager.py | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 8b28676..2b5f3be 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,7 @@ from datetime import datetime # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.2.1" +PLUGIN_MANAGER_VERSION = "1.2.0" REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. @@ -48,17 +48,14 @@ loop = babase._asyncio._asyncio_event_loop open_popups = [] - def _add_popup(popup): open_popups.append(popup) - def _remove_popup(popup): try: open_popups.remove(popup) except ValueError: pass - def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") @@ -1043,8 +1040,7 @@ class ChangelogWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._back, transition=transition, - scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() - is babase.UIScale.MEDIUM else 1.0), + scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -1181,7 +1177,7 @@ class AuthorsWindow(popup.PopupWindow): parent=self._root_widget, size=(width * 0.8, height * 0.75), position=(width * 0.1, height * 0.1) - ) + ) self._columnwidget = bui.columnwidget( parent=self._scrollwidget, border=1, @@ -1199,9 +1195,9 @@ class AuthorsWindow(popup.PopupWindow): size=(width * 0.8, 35 if key == 'name' else 30), color=color if key == 'name' else (0.75, 0.7, 0.8), scale=( - (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else - (1.2 if key == 'name' else 1.0) - ), + (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else + (1.2 if key == 'name' else 1.0) + ), text=text, h_align='center', v_align='center', @@ -1227,7 +1223,7 @@ class PluginWindow(popup.PopupWindow): plugin: Plugin, origin_widget, plugins_list, - transition='in_scale', + transition = 'in_scale', button_callback=lambda: None, ): self.plugin: Plugin = plugin @@ -1291,8 +1287,7 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[0] is not None: previous_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), - height/2 - 20*s), + position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), height/2 - 20*s), label='<', size=(25, 40), color=(1, 0.5, 0.5), @@ -1303,8 +1298,7 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[1] is not None: next_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(width - 12.5*s - (8 if _uiscale() - is babase.UIScale.SMALL else 0), height/2 - 20*s), + position=(width - 12.5*s - (8 if _uiscale() is babase.UIScale.SMALL else 0), height/2 - 20*s), label='>', size=(25, 40), color=(1, 0.5, 0.5), @@ -1399,7 +1393,7 @@ class PluginWindow(popup.PopupWindow): parent=self._root_widget, position=( width * (0.1 if self.plugin.is_installed and has_update else - 0.25 if self.plugin.is_installed else 0.4), pos + 0.25 if self.plugin.is_installed else 0.4), pos ), size=button_size, on_activate_call=button1_action, @@ -1823,6 +1817,8 @@ class PluginCategoryWindow(popup.PopupMenuWindow): current_choice=current_choice, delegate=self ) + self._root_widget = self.root_widget + _add_popup(self) self._update_custom_sources_widget() def _update_custom_sources_widget(self): @@ -1958,8 +1954,7 @@ class PluginManagerWindow(bui.MainWindow): for popup in open_popups: try: bui.containerwidget(edit=popup._root_widget, transition='out_scale') - except: - pass + except: pass cls = type(self) return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( @@ -2072,10 +2067,7 @@ class PluginManagerWindow(bui.MainWindow): textcolor=b_textcolor, text_scale=0.6 ) - bui.buttonwidget( - edit=b, - on_activate_call=lambda: self.show_categories_window(source=b) - ) + bui.buttonwidget(edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), else: b = self.category_selection_button bui.buttonwidget( @@ -2282,10 +2274,8 @@ class PluginManagerWindow(bui.MainWindow): plugin_names_ready_to_draw = [] for plugin in plugin_names_to_draw: - try: - lcv = plugin.latest_compatible_version - except NoCompatibleVersion: - continue + try: lcv = plugin.latest_compatible_version + except NoCompatibleVersion: continue plugin_names_ready_to_draw += [plugin] for i, plugin in enumerate(plugin_names_ready_to_draw): @@ -2559,8 +2549,7 @@ class PluginManagerSettingsWindow(popup.PopupWindow): parent=self._root_widget, position=((width * 0.77) - button_size[0] / 2, pos), size=button_size, - on_activate_call=lambda: loop.create_task( - self.update(*plugin_manager_update_available)), + on_activate_call=lambda: loop.create_task(self.update(*plugin_manager_update_available)), textcolor=b_text_color, button_type='square', text_scale=1, From 2e892816ee0e91d7ff822db07aaa5350d93b39f4 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Wed, 6 Aug 2025 19:56:08 +0000 Subject: [PATCH 13/29] [ci] auto-format --- plugin_manager.py | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 2b5f3be..78215c4 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -48,14 +48,17 @@ loop = babase._asyncio._asyncio_event_loop open_popups = [] + def _add_popup(popup): open_popups.append(popup) + def _remove_popup(popup): try: open_popups.remove(popup) except ValueError: pass + def _uiscale(): return bui.app.ui_v1.uiscale def _regexp_friendly_class_name_shortcut(string): return string.replace(".", "\\.") @@ -1040,7 +1043,8 @@ class ChangelogWindow(popup.PopupWindow): size=(width, height), on_outside_click_call=self._back, transition=transition, - scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() is babase.UIScale.MEDIUM else 1.0), + scale=(1.5 if _uiscale() is babase.UIScale.SMALL else 1.5 if _uiscale() + is babase.UIScale.MEDIUM else 1.0), scale_origin_stack_offset=self.scale_origin ) @@ -1177,7 +1181,7 @@ class AuthorsWindow(popup.PopupWindow): parent=self._root_widget, size=(width * 0.8, height * 0.75), position=(width * 0.1, height * 0.1) - ) + ) self._columnwidget = bui.columnwidget( parent=self._scrollwidget, border=1, @@ -1195,9 +1199,9 @@ class AuthorsWindow(popup.PopupWindow): size=(width * 0.8, 35 if key == 'name' else 30), color=color if key == 'name' else (0.75, 0.7, 0.8), scale=( - (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else - (1.2 if key == 'name' else 1.0) - ), + (1.1 if key == 'name' else 0.9) if _uiscale() is babase.UIScale.SMALL else + (1.2 if key == 'name' else 1.0) + ), text=text, h_align='center', v_align='center', @@ -1223,7 +1227,7 @@ class PluginWindow(popup.PopupWindow): plugin: Plugin, origin_widget, plugins_list, - transition = 'in_scale', + transition='in_scale', button_callback=lambda: None, ): self.plugin: Plugin = plugin @@ -1287,7 +1291,8 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[0] is not None: previous_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), height/2 - 20*s), + position=(-12.5*s + (4 if _uiscale() is babase.UIScale.SMALL else -5), + height/2 - 20*s), label='<', size=(25, 40), color=(1, 0.5, 0.5), @@ -1298,7 +1303,8 @@ class PluginWindow(popup.PopupWindow): if self.p_n_plugins[1] is not None: next_plugin_button = bui.buttonwidget( parent=self._root_widget, - position=(width - 12.5*s - (8 if _uiscale() is babase.UIScale.SMALL else 0), height/2 - 20*s), + position=(width - 12.5*s - (8 if _uiscale() + is babase.UIScale.SMALL else 0), height/2 - 20*s), label='>', size=(25, 40), color=(1, 0.5, 0.5), @@ -1393,7 +1399,7 @@ class PluginWindow(popup.PopupWindow): parent=self._root_widget, position=( width * (0.1 if self.plugin.is_installed and has_update else - 0.25 if self.plugin.is_installed else 0.4), pos + 0.25 if self.plugin.is_installed else 0.4), pos ), size=button_size, on_activate_call=button1_action, @@ -1954,7 +1960,8 @@ class PluginManagerWindow(bui.MainWindow): for popup in open_popups: try: bui.containerwidget(edit=popup._root_widget, transition='out_scale') - except: pass + except: + pass cls = type(self) return bui.BasicMainWindowState( create_call=lambda transition, origin_widget: cls( @@ -2067,7 +2074,8 @@ class PluginManagerWindow(bui.MainWindow): textcolor=b_textcolor, text_scale=0.6 ) - bui.buttonwidget(edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), + bui.buttonwidget( + edit=b, on_activate_call=lambda: self.show_categories_window(source=b)), else: b = self.category_selection_button bui.buttonwidget( @@ -2274,8 +2282,10 @@ class PluginManagerWindow(bui.MainWindow): plugin_names_ready_to_draw = [] for plugin in plugin_names_to_draw: - try: lcv = plugin.latest_compatible_version - except NoCompatibleVersion: continue + try: + lcv = plugin.latest_compatible_version + except NoCompatibleVersion: + continue plugin_names_ready_to_draw += [plugin] for i, plugin in enumerate(plugin_names_ready_to_draw): @@ -2549,7 +2559,8 @@ class PluginManagerSettingsWindow(popup.PopupWindow): parent=self._root_widget, position=((width * 0.77) - button_size[0] / 2, pos), size=button_size, - on_activate_call=lambda: loop.create_task(self.update(*plugin_manager_update_available)), + on_activate_call=lambda: loop.create_task( + self.update(*plugin_manager_update_available)), textcolor=b_text_color, button_type='square', text_scale=1, From 749fe45e679d28b1fbf77e03600e496233bf744e Mon Sep 17 00:00:00 2001 From: Vishal Date: Thu, 7 Aug 2025 01:27:19 +0530 Subject: [PATCH 14/29] v1.2.1 - 2nd update --- index.json | 7 +------ plugin_manager.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/index.json b/index.json index 2293932..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "65c7bdc", - "released_on": "05-08-2025", - "md5sum": "b7de1dac07c94cea75195cffead5bd1b" - }, + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", diff --git a/plugin_manager.py b/plugin_manager.py index 78215c4..8bbbc36 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,7 @@ from datetime import datetime # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.2.0" +PLUGIN_MANAGER_VERSION = "1.2.1" REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. From 45c1f6343c722328a14f398f29a59d6fee1ee8c5 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Wed, 6 Aug 2025 19:57:38 +0000 Subject: [PATCH 15/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..1de9dd2 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "749fe45", + "released_on": "06-08-2025", + "md5sum": "5320dbe276f592a2348f41a22e962989" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 2cc8d68a8267628edaf0f7776807083c792ef384 Mon Sep 17 00:00:00 2001 From: Vishal Date: Thu, 7 Aug 2025 01:30:15 +0530 Subject: [PATCH 16/29] Updating Changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 393a492..2fc91e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,9 @@ ### 1.2.1 (05-08-2025) - Cleaning up the code. -- UI now works again for small screens. +- UI now works again for other scales if used from dev console. - Added a new feature to move through plugins. +- Fixed popups getting stuck in background. ### 1.1.3 (06-04-2025) From c602f963b1d26e87ffea520441734643c1290cde Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 20:54:40 +0530 Subject: [PATCH 17/29] closes #317 and cleanup diff --- index.json | 7 +- plugin_manager.py | 358 +++++++++++++++++++++++----------------------- 2 files changed, 182 insertions(+), 183 deletions(-) diff --git a/index.json b/index.json index 1de9dd2..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "749fe45", - "released_on": "06-08-2025", - "md5sum": "5320dbe276f592a2348f41a22e962989" - }, + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", diff --git a/plugin_manager.py b/plugin_manager.py index 8bbbc36..581d214 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -850,183 +850,6 @@ class Plugin: bui.getsound('error').play() -class PluginManager: - def __init__(self): - self.request_headers = HEADERS - self._index = _CACHE.get("index", {}) - self._changelog = _CACHE.get("changelog", {}) - self.categories = {} - self.module_path = sys.modules[__name__].__file__ - self._index_setup_in_progress = False - self._changelog_setup_in_progress = False - - async def get_index(self): - if not self._index: - request = urllib.request.Request( - INDEX_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers, - ) - response = await async_send_network_request(request) - index = json.loads(response.read()) - self.set_index_global_cache(index) - self._index = index - return self._index - - async def setup_index(self): - while self._index_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._index_setup_in_progress = not bool(self._index) - index = await self.get_index() - await self.setup_plugin_categories(index) - self._index_setup_in_progress = False - - async def get_changelog(self) -> str: - requested = False - if not self._changelog: - request = urllib.request.Request(CHANGELOG_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers) - response = await async_send_network_request(request) - self._changelog = response.read().decode() - requested = True - return [self._changelog, requested] - - async def setup_changelog(self, version=None) -> None: - if version is None: - version = PLUGIN_MANAGER_VERSION - while self._changelog_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._changelog_setup_in_progress = not bool(self._changelog) - try: - full_changelog = await self.get_changelog() - if full_changelog[1]: - pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" - released_on = full_changelog[0].split(version)[1].split('\n')[0] - matches = re.findall(pattern, full_changelog[0], re.DOTALL) - if matches: - changelog = { - 'released_on': released_on, - 'info': matches[0].strip() - } - else: - changelog = {'released_on': ' (Not Provided)', - 'info': f"Changelog entry for version {version} not found."} - else: - changelog = full_changelog[0] - except urllib.error.URLError: - changelog = {'released_on': ' (Not Provided)', - 'info': 'Could not get ChangeLog due to Internet Issues.'} - self.set_changelog_global_cache(changelog) - self._changelog_setup_in_progress = False - - async def setup_plugin_categories(self, plugin_index): - # A hack to have the "All" category show at the top. - self.categories["All"] = None - - requests = [] - for meta_url in plugin_index["categories"]: - category = Category(meta_url) - request = category.fetch_metadata() - requests.append(request) - for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: - source_splits = source.split("@", maxsplit=1) - if len(source_splits) == 1: - # Fallack to `main` if `@branchname` isn't specified in an external source URI. - source_repo, source_tag = source_splits[0], "main" - else: - source_repo, source_tag = source_splits - meta_url = partial_format( - plugin_index["external_source_url"], - repository=source_repo, - ) - category = Category(meta_url, tag=source_tag) - request = category.fetch_metadata() - requests.append(request) - categories = await asyncio.gather(*requests) - - all_plugins = [] - for category in categories: - self.categories[await category.get_name()] = category - all_plugins.extend(await category.get_plugins()) - self.categories["All"] = CategoryAll(plugins=all_plugins) - - def cleanup(self): - for category in self.categories.values(): - if category is not None: - category.cleanup() - self.categories.clear() - self._index.clear() - self._changelog = None - self.unset_index_global_cache() - - async def refresh(self): - self.cleanup() - await self.setup_index() - - def set_index_global_cache(self, index): - _CACHE["index"] = index - - def set_changelog_global_cache(self, changelog): - _CACHE["changelog"] = changelog - - def unset_index_global_cache(self): - try: - del _CACHE["index"] - del _CACHE["changelog"] - except KeyError: - pass - - async def get_update_details(self): - index = await self.get_index() - for version, info in index["versions"].items(): - if info["api_version"] != _app_api_version: - # No point checking a version of the API game doesn't support. - continue - if version == PLUGIN_MANAGER_VERSION: - # We're already on the latest version for the current API. - return - else: - if next(iter(index["versions"])) == version: - # Version on the top is the latest, so no need to specify - # the commit SHA explicitly to GitHub to access the latest file. - commit_sha = None - else: - commit_sha = info["commit_sha"] - return version, commit_sha - - async def update(self, to_version=None, commit_sha=None): - index = await self.get_index() - if to_version is None: - to_version, commit_sha = await self.get_update_details() - to_version_info = index["versions"][to_version] - tag = commit_sha or CURRENT_TAG - download_url = index["plugin_manager_url"].format( - content_type="raw", - tag=tag, - ) - response = await async_send_network_request(download_url) - content = response.read() - if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: - raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") - with open(self.module_path, "wb") as fout: - fout.write(content) - return to_version_info - - async def soft_refresh(self): - pass - - class ChangelogWindow(popup.PopupWindow): def __init__(self, origin_widget): self.scale_origin = origin_widget.get_screen_space_center() @@ -1621,6 +1444,187 @@ class PluginWindow(popup.PopupWindow): await self.plugin.update() bui.getsound('shieldUp').play() +class PluginManager: + def __init__(self): + self.request_headers = HEADERS + self._index = _CACHE.get("index", {}) + self._changelog = _CACHE.get("changelog", {}) + self.categories = {} + self.module_path = sys.modules[__name__].__file__ + self._index_setup_in_progress = False + self._changelog_setup_in_progress = False + + async def get_index(self): + if not self._index: + request = urllib.request.Request( + INDEX_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers, + ) + response = await async_send_network_request(request) + index = json.loads(response.read()) + self.set_index_global_cache(index) + self._index = index + return self._index + + async def setup_index(self): + while self._index_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._index_setup_in_progress = not bool(self._index) + index = await self.get_index() + await self.setup_plugin_categories(index) + self._index_setup_in_progress = False + + async def get_changelog(self) -> list[str, bool]: + requested = False + if not self._changelog: + request = urllib.request.Request(CHANGELOG_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers) + response = await async_send_network_request(request) + self._changelog = response.read().decode() + requested = True + return [self._changelog, requested] + + async def setup_changelog(self, version=None) -> None: + if version is None: + version = PLUGIN_MANAGER_VERSION + while self._changelog_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._changelog_setup_in_progress = not bool(self._changelog) + try: + full_changelog = await self.get_changelog() + # check if the changelog was requested + if full_changelog[1]: + pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" + if (len(full_changelog[0].split(version))>1): + print(len(full_changelog[0].split(version))) + released_on = full_changelog[0].split(version)[1].split('\n')[0] + matches = re.findall(pattern, full_changelog[0], re.DOTALL) + else: + matches = None + + if matches: + changelog = { + 'released_on': released_on, + 'info': matches[0].strip() + } + else: + changelog = {'released_on': ' (Not Provided)', + 'info': f"Changelog entry for version {version} not found."} + else: + changelog = full_changelog[0] + except urllib.error.URLError: + changelog = {'released_on': ' (Not Provided)', + 'info': 'Could not get ChangeLog due to Internet Issues.'} + self.set_changelog_global_cache(changelog) + self._changelog_setup_in_progress = False + + async def setup_plugin_categories(self, plugin_index): + # A hack to have the "All" category show at the top. + self.categories["All"] = None + + requests = [] + for meta_url in plugin_index["categories"]: + category = Category(meta_url) + request = category.fetch_metadata() + requests.append(request) + for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: + source_splits = source.split("@", maxsplit=1) + if len(source_splits) == 1: + # Fallack to `main` if `@branchname` isn't specified in an external source URI. + source_repo, source_tag = source_splits[0], "main" + else: + source_repo, source_tag = source_splits + meta_url = partial_format( + plugin_index["external_source_url"], + repository=source_repo, + ) + category = Category(meta_url, tag=source_tag) + request = category.fetch_metadata() + requests.append(request) + categories = await asyncio.gather(*requests) + + all_plugins = [] + for category in categories: + self.categories[await category.get_name()] = category + all_plugins.extend(await category.get_plugins()) + self.categories["All"] = CategoryAll(plugins=all_plugins) + + def cleanup(self): + for category in self.categories.values(): + if category is not None: + category.cleanup() + self.categories.clear() + self._index.clear() + self._changelog = None + self.unset_index_global_cache() + + async def refresh(self): + self.cleanup() + await self.setup_index() + + def set_index_global_cache(self, index): + _CACHE["index"] = index + + def set_changelog_global_cache(self, changelog): + _CACHE["changelog"] = changelog + + def unset_index_global_cache(self): + try: + del _CACHE["index"] + del _CACHE["changelog"] + except KeyError: + pass + + async def get_update_details(self): + index = await self.get_index() + for version, info in index["versions"].items(): + if info["api_version"] != _app_api_version: + # No point checking a version of the API game doesn't support. + continue + if version == PLUGIN_MANAGER_VERSION: + # We're already on the latest version for the current API. + return + else: + if next(iter(index["versions"])) == version: + # Version on the top is the latest, so no need to specify + # the commit SHA explicitly to GitHub to access the latest file. + commit_sha = None + else: + commit_sha = info["commit_sha"] + return version, commit_sha + + async def update(self, to_version=None, commit_sha=None): + index = await self.get_index() + if to_version is None: + to_version, commit_sha = await self.get_update_details() + to_version_info = index["versions"][to_version] + tag = commit_sha or CURRENT_TAG + download_url = index["plugin_manager_url"].format( + content_type="raw", + tag=tag, + ) + response = await async_send_network_request(download_url) + content = response.read() + if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: + raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") + with open(self.module_path, "wb") as fout: + fout.write(content) + return to_version_info + + async def soft_refresh(self): + pass class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): From 051d54bdc7f2924d2e3973978d3256f79964eb89 Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:25:49 +0000 Subject: [PATCH 18/29] [ci] auto-format --- plugin_manager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 581d214..63eceec 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1444,6 +1444,7 @@ class PluginWindow(popup.PopupWindow): await self.plugin.update() bui.getsound('shieldUp').play() + class PluginManager: def __init__(self): self.request_headers = HEADERS @@ -1507,13 +1508,13 @@ class PluginManager: # check if the changelog was requested if full_changelog[1]: pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" - if (len(full_changelog[0].split(version))>1): + if (len(full_changelog[0].split(version)) > 1): print(len(full_changelog[0].split(version))) released_on = full_changelog[0].split(version)[1].split('\n')[0] matches = re.findall(pattern, full_changelog[0], re.DOTALL) else: matches = None - + if matches: changelog = { 'released_on': released_on, @@ -1626,6 +1627,7 @@ class PluginManager: async def soft_refresh(self): pass + class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): self.selected_source = None From 6b17ba080f2243824c84b8350efbe6f7d7583497 Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:25:50 +0000 Subject: [PATCH 19/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..6192cc9 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "051d54b", + "released_on": "09-08-2025", + "md5sum": "226769d21709895157524dcf0ea18359" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 9228ed92e940fc9b72748d4043c434bedda693e3 Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 9 Aug 2025 21:01:42 +0530 Subject: [PATCH 20/29] Seperating Main Plugin Manager class from UI classes --- plugin_manager.py | 366 +++++++++++++++++++++++----------------------- 1 file changed, 183 insertions(+), 183 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index 63eceec..abfdc64 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -850,6 +850,189 @@ class Plugin: bui.getsound('error').play() +class PluginManager: + def __init__(self): + self.request_headers = HEADERS + self._index = _CACHE.get("index", {}) + self._changelog = _CACHE.get("changelog", {}) + self.categories = {} + self.module_path = sys.modules[__name__].__file__ + self._index_setup_in_progress = False + self._changelog_setup_in_progress = False + + async def get_index(self): + if not self._index: + request = urllib.request.Request( + INDEX_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers, + ) + response = await async_send_network_request(request) + index = json.loads(response.read()) + self.set_index_global_cache(index) + self._index = index + return self._index + + async def setup_index(self): + while self._index_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._index_setup_in_progress = not bool(self._index) + index = await self.get_index() + await self.setup_plugin_categories(index) + self._index_setup_in_progress = False + + async def get_changelog(self) -> list[str, bool]: + requested = False + if not self._changelog: + request = urllib.request.Request(CHANGELOG_META.format( + repository_url=REPOSITORY_URL, + content_type="raw", + tag=CURRENT_TAG + ), + headers=self.request_headers) + response = await async_send_network_request(request) + self._changelog = response.read().decode() + requested = True + return [self._changelog, requested] + + async def setup_changelog(self, version=None) -> None: + if version is None: + version = PLUGIN_MANAGER_VERSION + while self._changelog_setup_in_progress: + # Avoid making multiple network calls to the same resource in parallel. + # Rather wait for the previous network call to complete. + await asyncio.sleep(0.1) + self._changelog_setup_in_progress = not bool(self._changelog) + try: + full_changelog = await self.get_changelog() + # check if the changelog was requested + if full_changelog[1]: + pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" + if (len(full_changelog[0].split(version)) > 1): + print(len(full_changelog[0].split(version))) + released_on = full_changelog[0].split(version)[1].split('\n')[0] + matches = re.findall(pattern, full_changelog[0], re.DOTALL) + else: + matches = None + + if matches: + changelog = { + 'released_on': released_on, + 'info': matches[0].strip() + } + else: + changelog = {'released_on': ' (Not Provided)', + 'info': f"Changelog entry for version {version} not found."} + else: + changelog = full_changelog[0] + except urllib.error.URLError: + changelog = {'released_on': ' (Not Provided)', + 'info': 'Could not get ChangeLog due to Internet Issues.'} + self.set_changelog_global_cache(changelog) + self._changelog_setup_in_progress = False + + async def setup_plugin_categories(self, plugin_index): + # A hack to have the "All" category show at the top. + self.categories["All"] = None + + requests = [] + for meta_url in plugin_index["categories"]: + category = Category(meta_url) + request = category.fetch_metadata() + requests.append(request) + for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: + source_splits = source.split("@", maxsplit=1) + if len(source_splits) == 1: + # Fallack to `main` if `@branchname` isn't specified in an external source URI. + source_repo, source_tag = source_splits[0], "main" + else: + source_repo, source_tag = source_splits + meta_url = partial_format( + plugin_index["external_source_url"], + repository=source_repo, + ) + category = Category(meta_url, tag=source_tag) + request = category.fetch_metadata() + requests.append(request) + categories = await asyncio.gather(*requests) + + all_plugins = [] + for category in categories: + self.categories[await category.get_name()] = category + all_plugins.extend(await category.get_plugins()) + self.categories["All"] = CategoryAll(plugins=all_plugins) + + def cleanup(self): + for category in self.categories.values(): + if category is not None: + category.cleanup() + self.categories.clear() + self._index.clear() + self._changelog = None + self.unset_index_global_cache() + + async def refresh(self): + self.cleanup() + await self.setup_index() + + def set_index_global_cache(self, index): + _CACHE["index"] = index + + def set_changelog_global_cache(self, changelog): + _CACHE["changelog"] = changelog + + def unset_index_global_cache(self): + try: + del _CACHE["index"] + del _CACHE["changelog"] + except KeyError: + pass + + async def get_update_details(self): + index = await self.get_index() + for version, info in index["versions"].items(): + if info["api_version"] != _app_api_version: + # No point checking a version of the API game doesn't support. + continue + if version == PLUGIN_MANAGER_VERSION: + # We're already on the latest version for the current API. + return + else: + if next(iter(index["versions"])) == version: + # Version on the top is the latest, so no need to specify + # the commit SHA explicitly to GitHub to access the latest file. + commit_sha = None + else: + commit_sha = info["commit_sha"] + return version, commit_sha + + async def update(self, to_version=None, commit_sha=None): + index = await self.get_index() + if to_version is None: + to_version, commit_sha = await self.get_update_details() + to_version_info = index["versions"][to_version] + tag = commit_sha or CURRENT_TAG + download_url = index["plugin_manager_url"].format( + content_type="raw", + tag=tag, + ) + response = await async_send_network_request(download_url) + content = response.read() + if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: + raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") + with open(self.module_path, "wb") as fout: + fout.write(content) + return to_version_info + + async def soft_refresh(self): + pass + + class ChangelogWindow(popup.PopupWindow): def __init__(self, origin_widget): self.scale_origin = origin_widget.get_screen_space_center() @@ -1445,189 +1628,6 @@ class PluginWindow(popup.PopupWindow): bui.getsound('shieldUp').play() -class PluginManager: - def __init__(self): - self.request_headers = HEADERS - self._index = _CACHE.get("index", {}) - self._changelog = _CACHE.get("changelog", {}) - self.categories = {} - self.module_path = sys.modules[__name__].__file__ - self._index_setup_in_progress = False - self._changelog_setup_in_progress = False - - async def get_index(self): - if not self._index: - request = urllib.request.Request( - INDEX_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers, - ) - response = await async_send_network_request(request) - index = json.loads(response.read()) - self.set_index_global_cache(index) - self._index = index - return self._index - - async def setup_index(self): - while self._index_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._index_setup_in_progress = not bool(self._index) - index = await self.get_index() - await self.setup_plugin_categories(index) - self._index_setup_in_progress = False - - async def get_changelog(self) -> list[str, bool]: - requested = False - if not self._changelog: - request = urllib.request.Request(CHANGELOG_META.format( - repository_url=REPOSITORY_URL, - content_type="raw", - tag=CURRENT_TAG - ), - headers=self.request_headers) - response = await async_send_network_request(request) - self._changelog = response.read().decode() - requested = True - return [self._changelog, requested] - - async def setup_changelog(self, version=None) -> None: - if version is None: - version = PLUGIN_MANAGER_VERSION - while self._changelog_setup_in_progress: - # Avoid making multiple network calls to the same resource in parallel. - # Rather wait for the previous network call to complete. - await asyncio.sleep(0.1) - self._changelog_setup_in_progress = not bool(self._changelog) - try: - full_changelog = await self.get_changelog() - # check if the changelog was requested - if full_changelog[1]: - pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" - if (len(full_changelog[0].split(version)) > 1): - print(len(full_changelog[0].split(version))) - released_on = full_changelog[0].split(version)[1].split('\n')[0] - matches = re.findall(pattern, full_changelog[0], re.DOTALL) - else: - matches = None - - if matches: - changelog = { - 'released_on': released_on, - 'info': matches[0].strip() - } - else: - changelog = {'released_on': ' (Not Provided)', - 'info': f"Changelog entry for version {version} not found."} - else: - changelog = full_changelog[0] - except urllib.error.URLError: - changelog = {'released_on': ' (Not Provided)', - 'info': 'Could not get ChangeLog due to Internet Issues.'} - self.set_changelog_global_cache(changelog) - self._changelog_setup_in_progress = False - - async def setup_plugin_categories(self, plugin_index): - # A hack to have the "All" category show at the top. - self.categories["All"] = None - - requests = [] - for meta_url in plugin_index["categories"]: - category = Category(meta_url) - request = category.fetch_metadata() - requests.append(request) - for source in babase.app.config["Community Plugin Manager"]["Custom Sources"]: - source_splits = source.split("@", maxsplit=1) - if len(source_splits) == 1: - # Fallack to `main` if `@branchname` isn't specified in an external source URI. - source_repo, source_tag = source_splits[0], "main" - else: - source_repo, source_tag = source_splits - meta_url = partial_format( - plugin_index["external_source_url"], - repository=source_repo, - ) - category = Category(meta_url, tag=source_tag) - request = category.fetch_metadata() - requests.append(request) - categories = await asyncio.gather(*requests) - - all_plugins = [] - for category in categories: - self.categories[await category.get_name()] = category - all_plugins.extend(await category.get_plugins()) - self.categories["All"] = CategoryAll(plugins=all_plugins) - - def cleanup(self): - for category in self.categories.values(): - if category is not None: - category.cleanup() - self.categories.clear() - self._index.clear() - self._changelog = None - self.unset_index_global_cache() - - async def refresh(self): - self.cleanup() - await self.setup_index() - - def set_index_global_cache(self, index): - _CACHE["index"] = index - - def set_changelog_global_cache(self, changelog): - _CACHE["changelog"] = changelog - - def unset_index_global_cache(self): - try: - del _CACHE["index"] - del _CACHE["changelog"] - except KeyError: - pass - - async def get_update_details(self): - index = await self.get_index() - for version, info in index["versions"].items(): - if info["api_version"] != _app_api_version: - # No point checking a version of the API game doesn't support. - continue - if version == PLUGIN_MANAGER_VERSION: - # We're already on the latest version for the current API. - return - else: - if next(iter(index["versions"])) == version: - # Version on the top is the latest, so no need to specify - # the commit SHA explicitly to GitHub to access the latest file. - commit_sha = None - else: - commit_sha = info["commit_sha"] - return version, commit_sha - - async def update(self, to_version=None, commit_sha=None): - index = await self.get_index() - if to_version is None: - to_version, commit_sha = await self.get_update_details() - to_version_info = index["versions"][to_version] - tag = commit_sha or CURRENT_TAG - download_url = index["plugin_manager_url"].format( - content_type="raw", - tag=tag, - ) - response = await async_send_network_request(download_url) - content = response.read() - if hashlib.md5(content).hexdigest() != to_version_info["md5sum"]: - raise MD5CheckSumFailed("MD5 checksum failed during plugin manager update.") - with open(self.module_path, "wb") as fout: - fout.write(content) - return to_version_info - - async def soft_refresh(self): - pass - - class PluginCustomSourcesWindow(popup.PopupWindow): def __init__(self, origin_widget): self.selected_source = None From 6f2afc8a048c6398df007630643211c82d1bf276 Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 9 Aug 2025 21:02:43 +0530 Subject: [PATCH 21/29] V-1.2.1 --- index.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/index.json b/index.json index 6192cc9..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "051d54b", - "released_on": "09-08-2025", - "md5sum": "226769d21709895157524dcf0ea18359" - }, + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 7e02b45698a189eb749b6315ea436df8dfbe9302 Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Sat, 9 Aug 2025 15:33:03 +0000 Subject: [PATCH 22/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..874eceb 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "6f2afc8", + "released_on": "09-08-2025", + "md5sum": "09b95fd2220408645ecffeb171d73365" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 836f980ac2b751b36d594a289ff89d4b0342fe7b Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 9 Aug 2025 21:37:37 +0530 Subject: [PATCH 23/29] Removing print lines --- plugin_manager.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugin_manager.py b/plugin_manager.py index abfdc64..d1c8458 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -914,7 +914,6 @@ class PluginManager: if full_changelog[1]: pattern = rf"### {version} \(\d\d-\d\d-\d{{4}}\)\n(.*?)(?=### \d+\.\d+\.\d+|\Z)" if (len(full_changelog[0].split(version)) > 1): - print(len(full_changelog[0].split(version))) released_on = full_changelog[0].split(version)[1].split('\n')[0] matches = re.findall(pattern, full_changelog[0], re.DOTALL) else: @@ -1962,7 +1961,6 @@ class PluginManagerWindow(bui.MainWindow): def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. global open_popups - print(open_popups) for popup in open_popups: try: bui.containerwidget(edit=popup._root_widget, transition='out_scale') From ed6d9466b342f500524a46045377aed8f95f5a5f Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 9 Aug 2025 21:38:28 +0530 Subject: [PATCH 24/29] V-1.2.1 finally --- CHANGELOG.md | 2 +- index.json | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc91e5..6fb758b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Plugin Manager (dd-mm-yyyy) -### 1.2.1 (05-08-2025) +### 1.2.1 (09-08-2025) - Cleaning up the code. - UI now works again for other scales if used from dev console. diff --git a/index.json b/index.json index 874eceb..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "6f2afc8", - "released_on": "09-08-2025", - "md5sum": "09b95fd2220408645ecffeb171d73365" - }, + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From ce91e940ec7a2af953d06db09e846ca156686edd Mon Sep 17 00:00:00 2001 From: vishal332008 <76160371+vishal332008@users.noreply.github.com> Date: Sat, 9 Aug 2025 16:08:51 +0000 Subject: [PATCH 25/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..ea8c9bb 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "ed6d946", + "released_on": "09-08-2025", + "md5sum": "9341a0a0ec2ecc41f14a6570ccb7882a" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 5afbadd1d890c3b33f21de495978a6605b10a263 Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 22:05:42 +0530 Subject: [PATCH 26/29] Update changelog --- CHANGELOG.md | 1 + index.json | 7 +------ plugin_manager.py | 2 ++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb758b..9a141d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - UI now works again for other scales if used from dev console. - Added a new feature to move through plugins. - Fixed popups getting stuck in background. +- Missing version CHANGELOG no longer causes error ### 1.1.3 (06-04-2025) diff --git a/index.json b/index.json index ea8c9bb..eb04d3d 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "ed6d946", - "released_on": "09-08-2025", - "md5sum": "9341a0a0ec2ecc41f14a6570ccb7882a" - }, + "1.2.1": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", diff --git a/plugin_manager.py b/plugin_manager.py index d1c8458..667d992 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -1961,6 +1961,8 @@ class PluginManagerWindow(bui.MainWindow): def get_main_window_state(self) -> bui.MainWindowState: # Support recreating our window for back/refresh purposes. global open_popups + # Close all open popups if ui changes. + # check pr #390 for more info. for popup in open_popups: try: bui.containerwidget(edit=popup._root_widget, transition='out_scale') From c402474f81364662bedf1f0ad466a302a1efe88b Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 16:36:37 +0000 Subject: [PATCH 27/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index eb04d3d..302b32f 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": null, + "1.2.1": { + "api_version": 9, + "commit_sha": "5afbadd", + "released_on": "09-08-2025", + "md5sum": "6034f81bae2cdab4f5fba511d30075d4" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", From 1a9468daa3312b8c8d996ed87f81d041a1f08664 Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 22:14:31 +0530 Subject: [PATCH 28/29] change version to 1.1.4 --- CHANGELOG.md | 2 +- index.json | 7 +------ plugin_manager.py | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a141d3..72983d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## Plugin Manager (dd-mm-yyyy) -### 1.2.1 (09-08-2025) +### 1.1.4 (09-08-2025) - Cleaning up the code. - UI now works again for other scales if used from dev console. diff --git a/index.json b/index.json index 302b32f..28cbfc0 100644 --- a/index.json +++ b/index.json @@ -1,12 +1,7 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.2.1": { - "api_version": 9, - "commit_sha": "5afbadd", - "released_on": "09-08-2025", - "md5sum": "6034f81bae2cdab4f5fba511d30075d4" - }, + "1.1.4": null, "1.1.3": { "api_version": 9, "commit_sha": "728b01b", diff --git a/plugin_manager.py b/plugin_manager.py index 667d992..d255877 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -29,7 +29,7 @@ from datetime import datetime # Modules used for overriding AllSettingsWindow import logging -PLUGIN_MANAGER_VERSION = "1.2.1" +PLUGIN_MANAGER_VERSION = "1.1.4" REPOSITORY_URL = "https://github.com/bombsquad-community/plugin-manager" # Current tag can be changed to "staging" or any other branch in # plugin manager repo for testing purpose. From b0288283bbd9497bad281aa672f05b295ada4ea9 Mon Sep 17 00:00:00 2001 From: Loup-Garou911XD <90267658+Loup-Garou911XD@users.noreply.github.com> Date: Sat, 9 Aug 2025 16:45:32 +0000 Subject: [PATCH 29/29] [ci] apply-version-metadata --- index.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/index.json b/index.json index 28cbfc0..54310e9 100644 --- a/index.json +++ b/index.json @@ -1,7 +1,12 @@ { "plugin_manager_url": "https://github.com/bombsquad-community/plugin-manager/{content_type}/{tag}/plugin_manager.py", "versions": { - "1.1.4": null, + "1.1.4": { + "api_version": 9, + "commit_sha": "1a9468d", + "released_on": "09-08-2025", + "md5sum": "638c30b15027156cc6a1803d0ee07399" + }, "1.1.3": { "api_version": 9, "commit_sha": "728b01b",