From b40e30baef8cc6fba1617277226151a47a64655e Mon Sep 17 00:00:00 2001 From: "Mariano Z." Date: Sun, 19 Oct 2025 12:15:20 -0300 Subject: [PATCH] dev: automated commit - 2025-10-19 12:15:20 --- .../bin/generate_dbeaver_connections.py | 198 ++++++++++++++++++ .../bin/generate_tinyrdm_connections.py | 178 ++++++++++++++++ mise/.config/mise/config.toml | 55 +++-- sway/.config/sway/config.d/keybindings | 1 + tmux/.config/tmux/tmux.conf | 2 +- zsh/.config/zsh/path.zsh | 4 +- 6 files changed, 404 insertions(+), 34 deletions(-) create mode 100755 local-bin/.local/bin/generate_dbeaver_connections.py create mode 100755 local-bin/.local/bin/generate_tinyrdm_connections.py diff --git a/local-bin/.local/bin/generate_dbeaver_connections.py b/local-bin/.local/bin/generate_dbeaver_connections.py new file mode 100755 index 0000000..be81585 --- /dev/null +++ b/local-bin/.local/bin/generate_dbeaver_connections.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +""" +Generate DBeaver data-sources.json from sdm status --json output +Organizes PostgreSQL connections by customer folders +Excludes readonly connections, includes activate connections +""" + +import subprocess +import json +import re +import uuid +import os +from collections import defaultdict + +def run_sdm_status(): + try: + result = subprocess.run(['sdm', 'status', '--json'], capture_output=True, text=True) + if result.returncode != 0: + print(f"Error running sdm status: {result.stderr}") + return None + return json.loads(result.stdout) + except FileNotFoundError: + print("Error: sdm command not found") + return None + except json.JSONDecodeError as e: + print(f"Error parsing JSON: {e}") + return None + +def parse_postgres_connections(sdm_data): + connections = [] + + for item in sdm_data: + if item.get('type') == 'postgres': + name = item.get('name', '') + address = item.get('address', '') + + if 'readonly' in name: + continue + + if ':' in address: + addr, port = address.split(':') + port = int(port) + else: + continue + + env_info = parse_connection_name(name) + if env_info: + connections.append({ + 'name': name, + 'addr': addr, + 'port': port, + 'environment': env_info['environment'], + 'customer': env_info['customer'], + 'stage': env_info['stage'] + }) + + return connections + +def parse_connection_name(name): + pattern = r'oc-([^-]+)-([^-]+)-.*' + match = re.match(pattern, name) + + if not match: + return None + + environment = match.group(1) + customer = match.group(2) + + if environment in ['dev', 'nextrc', 'nextrc2']: + stage = 'internal' + elif environment in ['stage', 'stage2', 'uat']: + stage = 'stage' + elif environment in ['prod', 'prod2']: + stage = 'production' + else: + stage = 'unknown' + + return { + 'environment': environment, + 'customer': customer, + 'stage': stage + } + +def create_dbeaver_connection(conn, connection_id): + if conn['customer'] == 'internal' or conn['customer'].startswith('feature'): + folder = 'internal' + elif conn['stage'] == 'stage': + folder = conn['customer'] + elif conn['stage'] == 'production': + folder = conn['customer'] + else: + folder = 'other' + + display_name = conn['name'].replace('oc-', '').replace('-rds', '').replace('-activate', '') + + if 'activate' in conn['name']: + display_name = f"activate-{display_name}" + + if 'activate' in conn['name']: + default_db = "postgres" + db_url = f"jdbc:postgresql://{conn['addr']}:{conn['port']}/postgres" + else: + default_db = "member_dossier" + db_url = f"jdbc:postgresql://{conn['addr']}:{conn['port']}/member_dossier" + + return { + "provider": "postgresql", + "driver": "postgres-jdbc", + "name": display_name, + "save-password": True, + "folder": folder, + "configuration": { + "host": conn['addr'], + "port": str(conn['port']), + "database": default_db, + "url": db_url, + "configurationType": "MANUAL", + "home": "/bin", + "type": conn['environment'], + "closeIdleConnection": False, + "provider-properties": { + "@dbeaver-show-non-default-db@": "true", + "@dbeaver-show-template-db@": "true", + "@dbeaver-show-unavailable-db@": "true", + "show-database-statistics": "false", + "@dbeaver-read-all-data-types-db@": "false", + "@dbeaver-use-prepared-statements-db@": "false", + "postgresql.dd.plain.string": "false", + "postgresql.dd.tag.string": "false" + }, + "auth-model": "native" + } + } + +def group_connections(connections): + folders = defaultdict(list) + + for conn in connections: + if conn['customer'] == 'internal' or conn['customer'].startswith('feature'): + folder = 'internal' + elif conn['stage'] == 'stage': + folder = conn['customer'] + elif conn['stage'] == 'production': + folder = conn['customer'] + else: + folder = 'other' + + folders[folder].append(conn) + + return folders + +def generate_dbeaver_config(connections): + folders = group_connections(connections) + + folders_config = {} + for folder_name in folders.keys(): + folders_config[folder_name] = {} + + connections_config = {} + + for conn in connections: + connection_id = f"postgres-jdbc-{uuid.uuid4().hex[:8]}-{uuid.uuid4().hex[:8]}" + conn_config = create_dbeaver_connection(conn, connection_id) + connections_config[connection_id] = conn_config + + return { + "folders": folders_config, + "connections": connections_config + } + +def main(): + print("Generating DBeaver data-sources.json from sdm status --json...") + + sdm_data = run_sdm_status() + if not sdm_data: + return + + connections = parse_postgres_connections(sdm_data) + print(f"Found {len(connections)} PostgreSQL connections") + + folders = group_connections(connections) + + for folder_name, conns in folders.items(): + print(f" {folder_name}: {len(conns)} connections") + + dbeaver_config = generate_dbeaver_config(connections) + + output_file = os.path.expanduser('~/.local/share/DBeaverData/workspace6/Stuzo/.dbeaver/data-sources.json') + try: + with open(output_file, 'w') as f: + json.dump(dbeaver_config, f, indent='\t') + print(f"✅ Successfully generated {output_file}") + print("📝 Note: You may need to restart DBeaver to see the new connections") + except Exception as e: + print(f"❌ Error writing file: {e}") + +if __name__ == '__main__': + main() diff --git a/local-bin/.local/bin/generate_tinyrdm_connections.py b/local-bin/.local/bin/generate_tinyrdm_connections.py new file mode 100755 index 0000000..d785008 --- /dev/null +++ b/local-bin/.local/bin/generate_tinyrdm_connections.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +""" +Generate TinyRDM connections.yaml from sdm status --json output +Organizes Redis connections into Internal, Stage, and Production groups +Excludes activate and readonly connections +""" + +import subprocess +import json +import re +import os +from collections import defaultdict + +def run_sdm_status(): + try: + result = subprocess.run(['sdm', 'status', '--json'], capture_output=True, text=True) + if result.returncode != 0: + print(f"Error running sdm status: {result.stderr}") + return None + return json.loads(result.stdout) + except FileNotFoundError: + print("Error: sdm command not found") + return None + except json.JSONDecodeError as e: + print(f"Error parsing JSON: {e}") + return None + +def parse_redis_connections(sdm_data): + connections = [] + + for item in sdm_data: + if item.get('type') == 'redis': + name = item.get('name', '') + address = item.get('address', '') + + if ('activate-cache' in name or 'activate-readonly' in name or + 'readonly-redis' in name): + continue + + if ':' in address: + addr, port = address.split(':') + port = int(port) + else: + continue + + env_info = parse_connection_name(name) + if env_info: + connections.append({ + 'name': name, + 'addr': addr, + 'port': port, + 'environment': env_info['environment'], + 'customer': env_info['customer'], + 'stage': env_info['stage'] + }) + + return connections + +def parse_connection_name(name): + pattern = r'oc-([^-]+)-([^-]+)-.*' + match = re.match(pattern, name) + + if not match: + return None + + environment = match.group(1) + customer = match.group(2) + + if environment in ['dev', 'nextrc', 'nextrc2']: + stage = 'internal' + elif environment in ['stage', 'stage2', 'uat']: + stage = 'stage' + elif environment in ['prod', 'prod2']: + stage = 'production' + else: + stage = 'unknown' + + return { + 'environment': environment, + 'customer': customer, + 'stage': stage + } + +def create_connection_yaml(name, addr, port, stage): + colors = { + 'internal': '#4ECF60', + 'stage': '#FFA500', + 'production': '#FF0000' + } + + color = colors.get(stage, '#808080') + + return f""" - name: {name} + last_db: 0 + network: tcp + addr: {addr} + port: {port} + default_filter: '*' + key_separator: ':' + conn_timeout: 60 + exec_timeout: 60 + db_filter_type: none + load_size: 10000 + mark_color: '{color}' + refresh_interval: 5""" + +def group_connections(connections): + groups = defaultdict(list) + + for conn in connections: + if conn['customer'] == 'internal': + group_name = 'Internal' + conn_stage = 'internal' + elif conn['stage'] in ['stage']: + group_name = 'Stage' + conn_stage = 'stage' + elif conn['stage'] in ['production']: + group_name = 'Production' + conn_stage = 'production' + else: + continue + + conn_yaml = create_connection_yaml( + conn['name'], + conn['addr'], + conn['port'], + conn_stage + ) + + groups[group_name].append(conn_yaml) + + return groups + +def generate_yaml_content(groups): + yaml_lines = [] + group_order = ['Internal', 'Stage', 'Production'] + + for group_name in group_order: + if group_name in groups: + yaml_lines.append(f"- name: {group_name}") + yaml_lines.append(" last_db: 0") + yaml_lines.append(" type: group") + yaml_lines.append(" connections:") + + for conn_yaml in groups[group_name]: + yaml_lines.append(conn_yaml) + + yaml_lines.append("") + + return '\n'.join(yaml_lines) + +def main(): + print("Generating TinyRDM connections.yaml from sdm status --json...") + + sdm_data = run_sdm_status() + if not sdm_data: + return + + connections = parse_redis_connections(sdm_data) + print(f"Found {len(connections)} Redis connections") + + groups = group_connections(connections) + + for group_name, conns in groups.items(): + print(f" {group_name}: {len(conns)} connections") + + yaml_content = generate_yaml_content(groups) + + output_file = os.path.expanduser('~/.config/TinyRDM/connections.yaml') + try: + with open(output_file, 'w') as f: + f.write(yaml_content) + print(f"✅ Successfully generated {output_file}") + except Exception as e: + print(f"❌ Error writing file: {e}") + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/mise/.config/mise/config.toml b/mise/.config/mise/config.toml index 48d1909..fa4c123 100644 --- a/mise/.config/mise/config.toml +++ b/mise/.config/mise/config.toml @@ -2,38 +2,31 @@ mkcert = "latest" usage = "latest" +"ubi:a-h/templ" = "latest" +"ubi:stern/stern" = "latest" + +#Some optional utilities +"ubi:BurntSushi/ripgrep" = { version = "latest", exe = "rg" } +"ubi:sharkdp/fd" = "latest" +"ubi:sharkdp/bat" = "latest" +"ubi:cli/cli" = { version = "latest", exe = "gh" } +"ubi:jdx/mise" = "latest" + [settings] -# plugins can read the versions files used by other version managers (if enabled by the plugin) -# for example, .nvmrc in the case of node's nvm -legacy_version_file = true # enabled by default (unlike asdf) - -# configure `mise install` to always keep the downloaded archive -always_keep_download = false # deleted after install by default -always_keep_install = false # deleted on failure by default - -# configure how frequently (in minutes) to fetch updated plugin repository changes -# this is updated whenever a new runtime is installed -# (note: this isn't currently implemented but there are plans to add it: https://github.com/jdx/mise/issues/128) -plugin_autoupdate_last_check_duration = '1 week' # set to 0 to disable updates - -# config files with these prefixes will be trusted by default +legacy_version_file = true +always_keep_download = false +always_keep_install = false +plugin_autoupdate_last_check_duration = '1 week' trusted_config_paths = [] - -verbose = false # set to true to see full installation output, see `MISE_VERBOSE` -asdf_compat = false # set to true to ensure .tool-versions will be compatible with asdf, see `MISE_ASDF_COMPAT` -#http_timeout = 30 # set the timeout for http requests in seconds, see `MISE_HTTP_TIMEOUT` -jobs = 4 # number of plugins or runtimes to install in parallel. The default is `4`. -raw = false # set to true to directly pipe plugins to stdin/stdout/stderr -yes = false # set to true to automatically answer yes to all prompts - -not_found_auto_install = true # see MISE_NOT_FOUND_AUTO_INSTALL -task_output = "prefix" # see Tasks Runner for more information -paranoid = false # see MISE_PARANOID - -env_file = '.env' # load env vars from a dotenv file, see `MISE_ENV_FILE` - -experimental = true # enable experimental features - -# configure messages displayed when entering directories with config files +verbose = false +asdf_compat = false +jobs = 4 +raw = false +yes = false +not_found_auto_install = true +task_output = "prefix" +paranoid = false +env_file = ".env" +experimental = true status = { missing_tools = "if_other_versions_installed", show_env = false, show_tools = false } idiomatic_version_file_enable_tools = ["node"] diff --git a/sway/.config/sway/config.d/keybindings b/sway/.config/sway/config.d/keybindings index d33e2d9..50793ab 100644 --- a/sway/.config/sway/config.d/keybindings +++ b/sway/.config/sway/config.d/keybindings @@ -22,6 +22,7 @@ bindsym { $mod+o exec ~/.local/bin/launch-or-focus obsidian "cd /home/forbi/Documents/Vault && $term --class obsidian nvim" $mod+e exec pcmanfm $mod+y exec clapboard + $mod+b exec rofi-rbw --action copy } # Window Management diff --git a/tmux/.config/tmux/tmux.conf b/tmux/.config/tmux/tmux.conf index f384825..e0d320e 100644 --- a/tmux/.config/tmux/tmux.conf +++ b/tmux/.config/tmux/tmux.conf @@ -84,7 +84,7 @@ set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-sensible' set -g @plugin 'tmux-plugins/tmux-yank' set -g @plugin 'catppuccin/tmux#v0.2.0' -set -g @plugin 'tmux-plugins/tmux-battery' +set -g @plugin 'tmux-plugins/tmux-battery' # Re-enabled with our fixes set -g @plugin 'MaximilianGaedig/tmux-filter' # Plugin Settings diff --git a/zsh/.config/zsh/path.zsh b/zsh/.config/zsh/path.zsh index e893c07..05b33f1 100644 --- a/zsh/.config/zsh/path.zsh +++ b/zsh/.config/zsh/path.zsh @@ -1,5 +1,3 @@ -# Efficient PATH management - function update_path() { # Define directories to add to PATH local dirs=( @@ -10,6 +8,8 @@ function update_path() { "$HOME/.local/share/npm/bin" "$HOME/.local/share/cargo/bin" "$HOME/.local/share/go/bin" + "$HOME/.local/share/flatpak/exports/share" + "/var/lib/flatpak/exports/share" ) # Prepare new PATH variable