stuff
This commit is contained in:
21
.bash_env
21
.bash_env
@@ -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"
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
|
|||||||
3
.bashrc
3
.bashrc
@@ -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)"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
[env]
|
[env]
|
||||||
TERM = "xterm-256color"
|
TERM = "xterm-256color"
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
8
.config/environment.d/10-session.conf
Normal file
8
.config/environment.d/10-session.conf
Normal 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
|
||||||
2
.config/environment.d/10-ssh-agent.conf
Normal file
2
.config/environment.d/10-ssh-agent.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
SSH_AUTH_SOCK=%t/keyring/ssh
|
||||||
|
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
12
.config/systemd/user/gnome-keyring.service
Normal file
12
.config/systemd/user/gnome-keyring.service
Normal 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
1
.gitignore
vendored
@@ -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*
|
||||||
|
|||||||
@@ -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
28
.local/bin/brl_to_usd.py
Executable 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
10
.local/bin/duck.sh
Executable 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"
|
||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user