This commit is contained in:
2025-08-15 10:25:28 -07:00
parent 7622859ccd
commit a3c3f911b0
16 changed files with 229 additions and 100 deletions

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# Environment exports
export MOZ_ENABLE_WAYLAND=1
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_STATE_HOME="$HOME/.local/state"
export BROWSER=/usr/bin/librewolf
export VISUAL=nvim
export EDITOR=nvim
export QT_QPA_PLATFORMTHEME=qt5ct
export SCREENRC="$XDG_CONFIG_HOME"/screen/screenrc
export SCREENDIR="${XDG_RUNTIME_DIR}/screen"
export XDG_DATA_DIRS="/var/lib/flatpak/exports/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
# Paths
export PATH="$PATH:$HOME/.local/bin"
export PATH="$PATH:$HOME/.config/emacs/bin"
export PATH="$PATH:/var/lib/flatpak/exports/bin"

View File

@@ -1,7 +1,8 @@
#!/usr/bin/env bash # ~/.bash_profile
if [ -f ~/.bash_env ]; then # If interactive, load .bashrc for aliases, functions, prompt, etc.
. "$HOME"/.bash_env if [ -n "$BASH_VERSION" ]; then
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi fi
# [ "$(tty)" = "/dev/tty1" ] && exec sway

View File

@@ -51,6 +51,7 @@ export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;32m' export LESS_TERMCAP_us=$'\E[01;32m'
export PATH="$HOME/scripts:$PATH" export PATH="$HOME/scripts:$PATH"
export PATH="/var/lib/flatpak/exports/bin/:$PATH"
####################################################### #######################################################
# GOPASS # GOPASS
@@ -206,3 +207,5 @@ keys()
} }
keys keys
#eval "$(starship init bash)"

View File

@@ -1,4 +1,3 @@
[env] [env]
TERM = "xterm-256color" TERM = "xterm-256color"

View File

@@ -1,4 +1,4 @@
directory: ~/media/music/slsk/to-sort directory: /mnt/media/music/slsk/to-sort
library: ~/.config/beets/beets-library.db library: ~/.config/beets/beets-library.db
import: import:

View File

@@ -0,0 +1,8 @@
MOZ_ENABLE_WAYLAND=1
BROWSER=/usr/bin/librewolf
VISUAL=nvim
EDITOR=nvim
SCREENRC=%h/.config/screen/screenrc
SCREENDIR=%t/screen
XDG_DATA_DIRS=/var/lib/flatpak/exports/share:%h/.local/share/flatpak/exports/share:/usr/local/share:/usr/share
PATH=%h/.local/bin:%h/.config/emacs/bin:/var/lib/flatpak/exports/bin:%P

View File

@@ -0,0 +1,2 @@
SSH_AUTH_SOCK=%t/keyring/ssh

View File

@@ -1,4 +1,4 @@
music_directory "~/music" music_directory "/mnt/media/music"
playlist_directory "~/.local/share/mpd/playlists" playlist_directory "~/.local/share/mpd/playlists"
db_file "~/.local/share/mpd/db" db_file "~/.local/share/mpd/db"
log_file "~/.local/share/mpd/log" log_file "~/.local/share/mpd/log"

View File

@@ -1,7 +1,7 @@
mpd_host = "127.0.0.1" mpd_host = "127.0.0.1"
mpd_port = "6660" mpd_port = "6660"
mpd_music_dir = "/home/opal/music" mpd_music_dir = "/mnt/media/music"
ncmpcpp_directory = "~/.config/ncmpcpp" ncmpcpp_directory = "~/.config/ncmpcpp"
lyrics_directory = "~/.config/ncmpcpp/lyrics" lyrics_directory = "~/.config/ncmpcpp/lyrics"

View File

@@ -268,29 +268,22 @@ exec /usr/bin/udiskie &
# Network Manager tray applet # Network Manager tray applet
exec /usr/bin/nm-applet exec /usr/bin/nm-applet
# SSH Agent
exec eval $(ssh-agent -s)
# Bluetooth manager tray applet # Bluetooth manager tray applet
exec /usr/bin/blueman-applet exec /usr/bin/blueman-applet
# KDE polkit # KDE polkit
exec /usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1 exec /usr/lib/x86_64-linux-gnu/libexec/polkit-kde-authentication-agent-1
# Gtk
exec systemctl --user import-environment DISPLAY WAYLAND_DISPLAY SWAYSOCK
exec hash dbus-update-activation-environment 2>/dev/null && dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK
# No idle on audio # No idle on audio
exec sway-audio-idle-inhibit exec_always sway-audio-idle-inhibit
# Idle configuration # Idle configuration
exec swayidle -w \ # exec swayidle -w \
timeout 300 'swaylock -f' \ # timeout 300 'swaylock -f' \
timeout 600 'swaymsg "output * dpms off"' \ # timeout 600 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \ # resume 'swaymsg "output * dpms on"' \
before-sleep 'swaylock -f' \ # before-sleep 'swaylock -f' \
timeout 1800 'systemctl suspend' # timeout 1800 'systemctl suspend'
####################### #######################
# DECORATIONS # DECORATIONS

View File

@@ -0,0 +1,12 @@
[Unit]
Description=GNOME Keyring
After=graphical-session.target
[Service]
Type=simple
ExecStart=/usr/bin/gnome-keyring-daemon --foreground --components=ssh,secrets,pkcs11
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
[Install]
WantedBy=default.target

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@
.config/beets/beets-library.db .config/beets/beets-library.db
.config/beets/state.pickle .config/beets/state.pickle
.local/share/mpd .local/share/mpd
.config/ncmpcpp/lyrics/
*.swp *.swp
lazy-lock.json lazy-lock.json
*.sync-conflict* *.sync-conflict*

View File

@@ -25,7 +25,7 @@ if [ -n "$(git status --porcelain "$bookmarks_file")" ]; then
git commit -m "Update bookmarks file" git commit -m "Update bookmarks file"
# Push the changes and log output # Push the changes and log output
GIT_SSH_COMMAND="ssh -i ~/.ssh/ry_ecdsa" git push origin master 2>&1 | tee -a /tmp/bookmark_git_push.log git push origin master 2>&1 | tee -a /tmp/bookmark_git_push.log
notify-send "Bookmarks updated" "Changes pushed." notify-send "Bookmarks updated" "Changes pushed."
else else

28
.local/bin/brl_to_usd.py Executable file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python3
import requests
import sys
def brl_to_usd(amount_brl):
url = f"https://api.exchangerate.host/convert?from=BRL&to=USD&amount={amount_brl}"
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
usd = data["result"]
print(f"R${amount_brl:.2f} BRL = ${usd:.2f} USD")
except Exception as e:
print(f"Error converting currency: {e}")
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: ./brl_to_usd.py <amount_in_brl>")
sys.exit(1)
try:
amount = float(sys.argv[1])
brl_to_usd(amount)
except ValueError:
print("Please provide a valid number.")
sys.exit(1)

10
.local/bin/duck.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
duckdnsdir="$HOME/.local/share/duckdns"
logfile="$duckdnsdir/duck.log"
mkdir -p "$duckdnsdir"
echo "[$(date)] Updating DuckDNS..." >> "$logfile"
curl -k -s "https://www.duckdns.org/update?domains=lasthomelyhouse&token=c4b7e773-b049-4207-a6c3-e7a153d78ad0&ip=" >> "$logfile"
echo "" >> "$logfile"

View File

@@ -1,38 +1,62 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
JIRA to Org-mode Sync Script
Fetches open tickets from JIRA and adds them to an Org-mode file.
"""
import requests import requests
import urllib.parse import urllib.parse
import os import os
import re import re
import sys
from typing import List, Dict, Any
# Config stuff
# Configuration
TOKEN = "NDQ0ODE5ODQ5NDU0OkwyY36wdY9DAvXsBr1M4bMjFmp6" TOKEN = "NDQ0ODE5ODQ5NDU0OkwyY36wdY9DAvXsBr1M4bMjFmp6"
JIRA_URL = "https://jira.atg-corp.com" JIRA_URL = "https://jira.atg-corp.com"
TICKET_FILTER = 'project = "IS" AND status in (Open, "In Progress", Blocked, "Waiting for Customer", Stalled) AND assignee in (currentUser())' PROJECTS = ["IS", "ISP"] # Projects to include
STATUSES = ["Open", "In Progress", "Blocked", "Waiting for Customer", "Stalled"]
TODO_FILE = os.path.expanduser("~/sync/org/agenda/work.org") TODO_FILE = os.path.expanduser("~/sync/org/agenda/work.org")
encoded_jql = urllib.parse.quote(TICKET_FILTER) # Build JQL filter for multiple projects
headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"} PROJECT_FILTER = "project in ({})".format(", ".join(f'"{p}"' for p in PROJECTS))
STATUS_FILTER = "status in ({})".format(", ".join(f'"{s}"' for s in STATUSES))
TICKET_FILTER = f"{PROJECT_FILTER} AND {STATUS_FILTER} AND assignee in (currentUser())"
# Request stuff
response = requests.get(
f"{JIRA_URL}/rest/api/2/search?jql={encoded_jql}", headers=headers
)
response.raise_for_status()
issues = response.json().get("issues", [])
with open(TODO_FILE, "r", encoding="utf-8") as f: def fetch_jira_issues() -> List[Dict[str, Any]]:
lines = f.readlines() """Fetch issues from JIRA based on the configured filter."""
file_content = "".join(lines) encoded_jql = urllib.parse.quote(TICKET_FILTER)
headers = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
# Aggregate issues try:
new_entries = [] response = requests.get(
for issue in issues: f"{JIRA_URL}/rest/api/2/search?jql={encoded_jql}", headers=headers
)
response.raise_for_status()
return response.json().get("issues", [])
except requests.RequestException as e:
print(f"Error fetching JIRA issues: {e}")
sys.exit(1)
def read_file_content(filepath: str) -> List[str]:
"""Read the content of the org file."""
try:
with open(filepath, "r", encoding="utf-8") as f:
return f.readlines()
except FileNotFoundError:
print(f"File not found: {filepath}")
sys.exit(1)
except IOError as e:
print(f"Error reading file: {e}")
sys.exit(1)
def create_org_entry(issue: Dict[str, Any]) -> str:
"""Create an Org-mode entry from a JIRA issue."""
key = issue["key"] key = issue["key"]
# Check if this issue already exists in the file
if f"[{key}]" in file_content:
continue
summary = issue["fields"]["summary"] summary = issue["fields"]["summary"]
url = f"{JIRA_URL}/browse/{key}" url = f"{JIRA_URL}/browse/{key}"
description = issue["fields"].get("description", "") description = issue["fields"].get("description", "")
@@ -43,45 +67,114 @@ for issue in issues:
entry += " :END:\n" entry += " :END:\n"
if description: if description:
# Indent each line of the description to maintain Org-mode structure. # Clean and indent description for Org-mode structure
desc_lines = description.splitlines() desc_lines = description.splitlines()
indented_desc = "\n".join(" " + line for line in desc_lines) indented_desc = "\n".join(" " + line for line in desc_lines if line.strip())
entry += indented_desc + "\n" if indented_desc:
entry += indented_desc + "\n"
new_entries.append(entry) return entry
if not new_entries:
print("No new issues to add.")
exit(0)
new_file_lines = [] def filter_new_issues(issues: List[Dict[str, Any]], file_content: str) -> List[str]:
inbox_found = False """Filter out issues that already exist in the file."""
i = 0 new_entries = []
while i < len(lines): for issue in issues:
line = lines[i] key = issue["key"]
new_file_lines.append(line) # Check if this issue already exists in the file (same logic as original)
# Look for the "* Inbox" heading exactly. if f"[{key}]" in file_content:
if re.match(r"^\*+\s+Inbox\b", line.strip(), re.IGNORECASE): print(f"Skipping {key} - already exists in file")
inbox_found = True continue
i += 1
# Copy over any existing child lines under Inbox. print(f"Adding new issue: {key}")
while i < len(lines) and ( new_entries.append(create_org_entry(issue))
lines[i].startswith("**")
or (lines[i].strip() and not lines[i].startswith("* ")) return new_entries
):
new_file_lines.append(lines[i])
def insert_entries_under_inbox(lines: List[str], new_entries: List[str]) -> List[str]:
"""Insert new entries under the Inbox heading."""
new_file_lines = []
inbox_found = False
i = 0
while i < len(lines):
line = lines[i]
new_file_lines.append(line)
# Look for the "* Inbox" heading
if re.match(r"^\*+\s+Inbox\b", line.strip(), re.IGNORECASE):
inbox_found = True
i += 1 i += 1
# Insert our new JIRA entries here.
new_file_lines.extend(new_entries)
# Append the rest of the file.
new_file_lines.extend(lines[i:])
break
i += 1
if not inbox_found: # Copy existing child lines under Inbox
print("Couldn't find '* Inbox' heading in the file.") while i < len(lines) and (
else: lines[i].startswith("**")
with open(TODO_FILE, "w", encoding="utf-8") as f: or (lines[i].strip() and not lines[i].startswith("* "))
f.writelines(new_file_lines) ):
print(f"Appended {len(new_entries)} new JIRA issues under '* Inbox' in {TODO_FILE}") new_file_lines.append(lines[i])
i += 1
# Insert new JIRA entries
new_file_lines.extend(new_entries)
# Append the rest of the file
new_file_lines.extend(lines[i:])
break
i += 1
if not inbox_found:
raise ValueError("Couldn't find '* Inbox' heading in the file.")
return new_file_lines
def write_file_content(filepath: str, content: List[str]) -> None:
"""Write content to the org file."""
try:
with open(filepath, "w", encoding="utf-8") as f:
f.writelines(content)
except IOError as e:
print(f"Error writing file: {e}")
sys.exit(1)
def main():
"""Main function to orchestrate the sync process."""
print(f"Fetching issues from projects: {', '.join(PROJECTS)}")
# Fetch issues from JIRA
issues = fetch_jira_issues()
print(f"Found {len(issues)} total issues")
# Read existing file content
lines = read_file_content(TODO_FILE)
file_content = "".join(lines)
# Filter for new issues
new_entries = filter_new_issues(issues, file_content)
if not new_entries:
print("No new issues to add.")
return
try:
# Insert new entries under Inbox
new_file_lines = insert_entries_under_inbox(lines, new_entries)
# Write updated content back to file
write_file_content(TODO_FILE, new_file_lines)
print(
f"Successfully added {len(new_entries)} new JIRA issues under '* Inbox' in {TODO_FILE}"
)
except ValueError as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()