Переглянути джерело

dev: automated commit - 2025-10-19 12:15:20

Mariano Z. 3 місяців тому
батько
коміт
b40e30baef

+ 198 - 0
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()

+ 178 - 0
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()

+ 23 - 30
mise/.config/mise/config.toml

@@ -2,38 +2,31 @@
 mkcert = "latest"
 usage = "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
+"ubi:a-h/templ" = "latest"
+"ubi:stern/stern" = "latest"
 
-# 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
+#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"
 
-# config files with these prefixes will be trusted by default
+[settings]
+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"]

+ 1 - 0
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

+ 1 - 1
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

+ 2 - 2
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