Appstore Workbench began as an attempt to provide a desktop alternative to 4TU's Homebrew Appstore, but moved to using a plugin system to provide more tools than just homebrew management, serving as a basis to many projects that would otherwise not warrant a gui. Appstore Workbench is welcome to community plugin submissions for any console. Appstore Workbench is a Mac/Windows/Linux compatible python app.
- Homebrew plugins for Wii, WiiU, and Nintendo Switch. Over 500 packages
- Homebrew management tool that doesn't require target platforms to have access to the internet
- Dynamic Search
- Categories
- Compatible with the Homebrew Appstore package manager
- Easily open project pages in browser
- Threaded operations mean the app stays responsive with big downloads
- Plugin Support
- Scalable Window
- Nintendo Switch, WiiU, and Wii homebrew
- Switch Serial Number Checker
- Switch Payload Injector
- WiiU Web Exploit Hoster
Works on: macOS, Windows, Linux
Python 3.6 or greater
Dependencies vary by OS, see below.
- Extract appstore-workbench.zip
- Install python
- You must restart your pc after installing python for the first time.
- If you do a custom installation remember to install tcl/tk, add python to the path, and include pip
- In a command prompt navigate to the dir you extracted the app to and type
pip install -r requirements.txt
to install dependencies - Type
python appstore-workbench
- Extract appstore-workbench.zip
- Mac users may already have a compatible version of python installed, try double-clicking appstoreworkbench.py
- In a command prompt navigate to the dir you extracted the app to and type
pip3 install -r requirements.txt
to install dependencies- If the file opens in a text reader, close the reader and right-click the file and open it with pylauncher
- If this still doesn't work, install python
- To run the app: double-click
appstore-workbench.py
- Extract appstore-workbench.zip
- Navigate to the directory in a terminal
- Type
pip3 install -r requirements.txt
to install dependencies - Type
python appstore-workbench.py
- If you are missing dependencies do the following:
- Ubuntu/Debian:
sudo apt install python3 python3-pip python3-tk python3-pil.imagetk
- Manjaro/Arch:
sudo pacman -S python3 python-pip tk python-pillow
- Ubuntu/Debian:
- If you are missing dependencies do the following:
- If you don't know how to do this you should probably be using Windows.
- Finally type
python3 appstore-workbench.py
- Error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)
- Solution: Macintosh HD > Applications > Python3.6 folder (or whatever version of python you're using) > double click on "Install Certificates.command" file
Plugins form the basis of appstore-workbench. On it's own appstore-workbench serves only to download plugins. This allows appstore-workbench to serve a variety of consoles without becoming bloated - being able to be tailored to the user's needs. Plugins can either run in the background, add pages, or both. Pages are derived from tkinter tk.Frame objects so you can use them to build anything you could build in a normal tkinter Frame.
Plugins can also added manually by placing them in the plugins
folder of appstore-workbench.
Single-file plugins can be named anything.py
, plugins with assets must be in folders, and must be called plugin.py
The plugin system is non-recursive, meaning a plugin in ./plugins/plugin_folder/plugin_subfolder/plugin.py
would not be seen.
_appstore-workbench
|_plugins
|_pluginA.py
|_pluginB.py
|_pluginC
| |_plugin.py
|_pluginD
|_plugin.py
from gui.widgets import basePlugin
import os
class Plugin(basePlugin.BasePlugin):
def __init__(self, app, container):
super().__init__(self, app, "PLUGIN_NAME", container)
self.app = app #gui object
self.container = container #Parent frame for pages, classed from tk.Frame()
#Declare any values you want available throughout your pages here
def get_pages(self):
#If your plugin does more than run in the background,
#this function will need to return a list of pages
#derived from basePage.BasePage
return []
def exit(self):
#If your widgets needs to do things to exit gracefully
#you need to do them here.
pass
#Setup function called on each plugin, must return object
#derived from basePlugin.BasePlugin
def setup(app, container):
#Do stuff you need done before the plugin loads here
return Plugin(app, container)
from gui.widgets import basePage
import tkinter as tk #Basepage is derived from tk.Frame so tk widgets work
import style #style.py is used to keep app colors and sizes consistent
class Page(basePage.BasePage):
def __init__(self, app, container, plugin):
super().__init__(self, app, container, "NAME")
about_label = tk.Label(self,
text = "Hello!",
background = style.primary_color,
foreground = style.primary_text_color,
font = style.smalltext
).place(
relx = 0.5,
x = - 50,
width = 100,
rely = 0.5,
y = - 20
height = - 50
)
Also included in this project is a worker thread tool I made that works with tkinter (calling threads from within the gui normally doesn't work). Threads must be procedural (they can't return something), but they are incredibly useful for updating elements of the gui without blocking everything else.
from gui.widgets import basePage
from asyncthreader import threader #Import thread
def load_big_file():
#When called above by the threader anything here will run without blocking
pass
class Page(basePage.BasePage):
def __init__(self, app, container, plugin):
super().__init__(self, app, container, "NAME")
#Let's say this gets called when a button on the page is pushed
def on_button_push(self):
#Calling something blocking here would freeze everything
#Instead call it as a thread
threader.do_async(load_big_file)
Additionally threads can be called with args:
from asyncthreader import threader
def callback(arg1, arg2, ...):
pass
threader.do_async(callback, [arg1, ar2, ...])
Appstore Workbench contains a python module for interacting with libget-style repos. It was written to be objective so multiple instances of it could be used at once, allowing the management of multiple consoles on the same sd card. This is useful in some cases, for example people using both WiiU and Wii (through vwii) homebrew. It also means the libget standard can be used locally for package management within the app, examples being payload injectors, and its the apps own plugin system.
Appstore Workbench is mostly compatible with 4TU's Homebrew Appstore there are still a few small things to tweak like checking asset modes when updating.
- pwscind
- Answered all sorts of questions about the appstore repos
- vgmoose
- <3
- The rest of the 4TU team for being gorgeous
- CrafterPika
- Helped me get the app working with the WiiU since I don't have a one.
- Helped with WiiUExploit plugin
- Archbox
- Fellow Turtle
- Wii Testing
- Circuit10
- HTML friend