Skip to content

Commit

Permalink
Merge pull request #2 from Gabisonfire/0.3
Browse files Browse the repository at this point in the history
0.3
  • Loading branch information
Gabisonfire committed Dec 22, 2021
2 parents 44024e3 + 1a25aa7 commit c79990f
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 66 deletions.
40 changes: 26 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
# Deckster
### A service to manage your Streamdeck easily on Linux
### A service to manage your Stream Deck easily on Linux
---

## Documentation

[Online](https://deckster-sd.readthedocs.io/en/latest/)

Offline:
```bash
pip install mkdocs
mkdocs serve
```
Then navigate to http://localhost:8000
[Online Documentation](https://deckster-sd.readthedocs.io/en/latest/)

## Quickstart
```
pip install deckster-sd
```
The install process will create a default `config.json` to your /`home`/`.config`/`deckster` folder. Then just run `deckster`.
The install process will create a default `config.json` to your /`~/`/`.config`/`deckster` folder. Then just run `deckster`.

Install dependencies and add permissions:
```bash
# Install system packages needed for the default LibUSB HIDAPI backend
sudo apt install -y libudev-dev libusb-1.0-0-dev libhidapi-libusb0

# Install system packages needed for the Python Pillow package installation
sudo apt install -y libjpeg-dev zlib1g-dev libopenjp2-7 libtiff5

# Add udev rule to allow all users non-root access to Elgato StreamDeck devices:
sudo tee /etc/udev/rules.d/10-streamdeck.rules << EOF
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fd9", GROUP="users", TAG+="uaccess"
EOF
# Reload udev rules to ensure the new permissions take effect
sudo udevadm control --reload-rules
```
# Service
You can have deckster run as a service by using the service file template in the repository. Replace "myusername" with your linux user and then run:
You can have deckster run as a service by using the service file template in the repository.
```bash
sudo cp deckster.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start deckster
mkdir -p $HOME/.local/share/systemd/user
cp deckster.service $HOME/.local/share/systemd/user
systemctl --user daemon-reload
systemctl --user enable
systemctl --user start deckster
```
2 changes: 1 addition & 1 deletion deckster/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.0"
__version__ = "0.3.0"
2 changes: 1 addition & 1 deletion deckster/common/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path

global __version__
__version__ = "0.2.0"
__version__ = "0.3.0"

logger = logging.getLogger("deckster")

Expand Down
4 changes: 1 addition & 3 deletions deckster/deckster.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
logger.debug(f"Plugins path: {PLUGINS_DIR}")
logger.debug(f"Current page: {PAGE}")


def render_key_image(deck, icon_filename, key):
logger.debug(f"Rendering image for key:{key.key} with {icon_filename}")
bottom_margin = 0 if key.label == "@hide" else 20
Expand Down Expand Up @@ -186,7 +185,6 @@ def update_key_state(key):
cfg.write_key_config(key.key , key.page, "toggle_state", key.toggle_state)

def main():

logger.info(f"Deckster v{__version__}")
logger.info(f"Initializing...")
streamdecks = DeviceManager().enumerate()
Expand All @@ -209,7 +207,7 @@ def graceful_shutdown(sig, frame):
#for index, deck in enumerate(streamdecks):
deck.open()
deck.reset()
signal.signal(signal.SIGINT, graceful_shutdown)
signal.signal(signal.SIGTERM, graceful_shutdown)
logger.debug(f"Opened '{deck.deck_type()}' device (serial number: '{deck.get_serial_number()}')")
deck.set_brightness(cfg.read_config("brightness"))
draw_deck(deck, init_draw=True)
Expand Down
69 changes: 34 additions & 35 deletions deckster/generators/builtins/steam.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ def __repr__(self):
def __lt__(self, other):
return self.title < other.title

class NavKey:
def __init__(self, args, is_next, page, hide_label, font, padding, label_truncate):
self.key = args["next_key"] if is_next else args["previous_key"]
self.page = page
self.plugin = "builtins.page.next" if is_next else "builtins.page.previous"
self.icon_default = args["next_icon"] if is_next else args["previous_icon"]
self.label = f"{'@hide' if hide_label else 'Next'}" if is_next else f"{'@hide' if hide_label else 'Previous'}"
self.font = font
self.button_type = "push"
self.padding = padding
self.label_truncate = label_truncate

def read_installed_apps(path):
apps = []
path = os.path.expanduser(path)
Expand Down Expand Up @@ -81,13 +93,13 @@ def write_keyfile(args, final_apps):
keyfile = []
start = 0
limit = 100
next = None
previous = None
add_navigation = False
font = "Roboto-Regular.ttf"
padding = [0,0,0,0]
hide_label = False
label_truncate = -1
allow_more_pages = False
page = args["page"]
if "start" in args:
start = args["start"]
if "limit" in args:
Expand All @@ -102,48 +114,33 @@ def write_keyfile(args, final_apps):
padding = args["padding"]
if "label_truncate" in args:
label_truncate = args["label_truncate"]

if add_navigation:
next = {
"key": args["next_key"],
"page": args["page"],
"plugin": "builtins.page.next",
"icon_default":args["next_icon"],
"label" : f"{'@hide' if hide_label else 'Next'}",
"font": font,
"button_type": "push",
"padding": padding,
"label_truncate": label_truncate
}
previous = {
"key": args["previous_key"],
"page": args["page"],
"plugin": "builtins.page.previous",
"icon_default":args["previous_icon"],
"label" : f"{'@hide' if hide_label else 'Previous'}",
"font": font,
"button_type": "push",
"padding": padding,
"label_truncate": label_truncate
}
if "allow_more_pages" in args:
allow_more_pages = args["allow_more_pages"]

app_index = 0
while start < limit:
if start+1 > MAX_KEYS:
logger.warning(f"The limit set of '{limit}' is higher than the number of keys: {MAX_KEYS}. Stopping. ({len(final_apps) - MAX_KEYS + 2 if add_navigation else 0} hidden)")
break
if allow_more_pages:
logger.info(f"Maximum Keys reached for page {page}, continuing on page {page + 1}")
page += 1
start = 0
else:
logger.warning(f"The limit set of '{limit}' is higher than the number of keys: {MAX_KEYS}. Stopping. ({len(final_apps) - MAX_KEYS + 2 if add_navigation else 0} hidden)")
break
if add_navigation:
if start == args["next_key"]:
keyfile.append(next)
logger.debug(f"Adding navigation key 'next' at page {page}, position {start}.")
keyfile.append(NavKey(args, True, page, hide_label, font, padding, label_truncate).__dict__)
start+=1
continue
elif start == args["previous_key"]:
keyfile.append(previous)
logger.debug(f"Adding navigation key 'previous' at page {page}, position {start}.")
keyfile.append(NavKey(args, False, page, hide_label, font, padding, label_truncate).__dict__)
start+=1
continue
k = {
"key": start,
"page": args["page"],
"page": page,
"plugin": "builtins.shell",
"args": {
"command": [
Expand All @@ -164,10 +161,12 @@ def write_keyfile(args, final_apps):
if app_index == -1:
logger.warning(f"The limit set of '{limit}' is higher than the number of applications found: {len(final_apps)}. Stopping.")
# If we were not up to the navigation position, insert them here before breaking.
if add_navigation and start < next["key"]:
keyfile.append(next)
if add_navigation and start < previous["key"]:
keyfile.append(previous)
if add_navigation and start <= args["next_key"]:
logger.debug(f"Adding navigation key 'next' at page {page}, position {start} before ending loop.")
keyfile.append(NavKey(args, True, page, hide_label, font, padding, label_truncate).__dict__)
if add_navigation and start <= args["previous_key"]:
logger.debug(f"Adding navigation key 'previous' at page {page}, position {start} before ending loop.")
keyfile.append(NavKey(args, False, page, hide_label, font, padding, label_truncate).__dict__)
break
with open(os.path.join(KEY_DIR, KEY_FILENAME), 'w', encoding='utf-8') as f:
json.dump(keyfile, f, ensure_ascii=False, indent=4)
Expand Down
3 changes: 2 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# 0.3
- Updated service file for proper user install.
- Proper SIGTERM handling
- Steam generator: Automatically add pages as needed.

# 0.2
- Proper shutdown on CTRL+C
- Added generators
- Added Steam as builtin generator
- Various code optimization
Expand Down
24 changes: 14 additions & 10 deletions docs/generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,28 @@ Ex:
Reads installed games and applications, retreive their title and icons and tiles them.

- reference: `builtins.steam`
- requires: (`pip install`)
- beautifulsoup4
- vdf
- args:
- page (int): The page to add the keys to
- page (int): The page to add the keys to. Required.
- allow_more_pages (bool): Will keep adding pages starting from `page` as needed. Default: false
- steam_lib (string): The path to your `libraryfolders.vdf`, usually in `~/.steam/steam/steamapps/`
- start (int): At what key to start. Remember the key count starts at 0.
- limit (int): Limit of key to use. The generator will use either this or you deck's max keys.
- start (int): At what key to start. Remember the key count starts at 0. Default: 0
- limit (int): Limit of key to use. The generator will use either this or you deck's max keys. Default: 100
- filters (string/int)[]: Games or apps to filter out, either by title or id. Exact match only at the moment.
- download_icons (bool): Download or not the icons.
- overwrite (bool): Will overwrite the file on launch, essentially refreshing the games.
- hide_label (bool): Setting to true will show icons only.
- font (string): Changes the labels font.
- add_navigation (bool): Will add page navigation buttons at the provided positions.
- overwrite (bool): Will overwrite the file on launch, essentially refreshing the games. Default: false
- hide_label (bool): Setting to true will show icons only. Default: False
- font (string): Changes the labels font. Default: Roboto-Regular.ttf
- add_navigation (bool): Will add page navigation buttons at the provided positions. Default: false
- previous_key (int): Where to put the `previous` button.
- previous_icon (string): The icon to use for the `previous` button, relative to `icons_dir`.
- next_key (int): Where to put the `next` button.
- next_icon (string): The icon to use for the `next` button, relative to `icons_dir`.
- sort_titles (bool): Sort titles alphabetically.
- padding ([int,int,int,int]): Add padding around the icons. Left, Right, Bottom, Top.
- label_truncate (int): Will truncate the labels after this amount of characters.
- sort_titles (bool): Sort titles alphabetically. Default: false
- padding ([int,int,int,int]): Add padding around the icons. Left, Right, Bottom, Top. Default: [0,0,0,0]
- label_truncate (int): Will truncate the labels after this amount of characters. Default: No truncating (-1)


Example:
Expand Down
1 change: 0 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,4 @@ Built with [Dean Camera](https://github.com/abcminiuser/)'s awesome [Streamdeck]
- 2nd function for keys (like double-tap), to save space for navigation
- Regex filtering
- Steam Generator:
- Overflow games to next page
- Refresh games without restarting deck
17 changes: 17 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ pip install deckster-sd
```
The install process will create a default `config.json` to your /`home`/`.config`/`deckster` folder.

Install dependencies and add permissions:
```bash
# Install system packages needed for the default LibUSB HIDAPI backend
sudo apt install -y libudev-dev libusb-1.0-0-dev libhidapi-libusb0

# Install system packages needed for the Python Pillow package installation
sudo apt install -y libjpeg-dev zlib1g-dev libopenjp2-7 libtiff5

# Add udev rule to allow all users non-root access to Elgato StreamDeck devices:
sudo tee /etc/udev/rules.d/10-streamdeck.rules << EOF
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fd9", GROUP="users", TAG+="uaccess"
EOF
# Reload udev rules to ensure the new permissions take effect
sudo udevadm control --reload-rules
```
```json
{
"icons_dir": "~/deckster/icons",
Expand Down

0 comments on commit c79990f

Please sign in to comment.