Compare commits

..

14 Commits

Author SHA1 Message Date
d9c5e4c9b1 image detection not working 2026-01-08 18:02:20 +01:00
61c58e632d image detection not working 2026-01-08 18:00:24 +01:00
a7fd2af552 removed recursion 2026-01-08 13:19:02 +01:00
cb01ee6273 ganz gut so 2026-01-07 14:02:20 +01:00
97b6f2d41d initial script 2026-01-07 12:54:33 +01:00
1863c264f8 Move creation time to newly encoded files 2025-08-18 11:39:42 +02:00
4bbdd7cb3d server status for nomad 2024-02-29 13:00:07 +01:00
a4af7c430a loads of stuff changed 2024-02-29 11:45:54 +01:00
df1d3a83ac Merge branch 'master' of git.lan:chaos/spielplatz 2022-09-19 16:55:33 +02:00
94382ef7c7 domain and powercycle script 2022-09-14 19:57:15 +02:00
31274f3825 adding nummer5 tools 2022-09-14 19:41:27 +02:00
Udo
27d8ad95aa RAV207 commands 2021-02-18 15:23:20 +01:00
Udo
05fb5bfa77 RAV207 commands 2021-02-18 15:07:34 +01:00
8cc8efd81b ESPHome Truhe 2021-01-25 17:59:23 +01:00
24 changed files with 355 additions and 34 deletions

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hacking_spielplatz</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
</pydev_project>

View File

@@ -1,3 +0,0 @@
eclipse.preferences.version=1
encoding//kodi/context.kino.control/main.py=utf-8
encoding//kodi/context.kino.control/resources/lib/context.py=utf-8

18
GoPro/TransferCreationTime.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/bash
#find -type f -not -iname '*\ \(*' -name \*MP4 -exec stat -c '%y %Y %n' {} \;
#touch -m -a -t $(date -d @1754466694 +'%Y%m%d%H%M.%S') './GX010042 (1).mp4'
for F in $(find -type f -not -iname '*\ \(*' -name \*MP4); do
FStrip=$(basename -s ".MP4" -- ${F})
FEncoded="${FStrip} (1).mp4"
if [ -e "${FEncoded}" ]; then
MTIME=$(stat -c '%Y' ${F})
MDate=$(date -d @${MTIME} +'%Y%m%d%H%M.%S')
echo "$F $MTIME $MDate '${FEncoded}' "
touch -m -a -t ${MDate} "${FEncoded}"
else
echo "Not Encoded: ${F}"
fi
done

12
duply-backup-lenny.sh Executable file → Normal file
View File

@@ -13,12 +13,12 @@ NOTIFYCMD="su - ${XUSER} DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user
for I in ${DIR}/lenny*; do
BCKP=$(basename $I)
${NOTIFYCMD} ${BCKP} "Starting Backup..."
#${NOTIFYCMD} ${BCKP} "Starting Backup..."
/usr/bin/duply $BCKP ${CMD} 2&>1 >${LOGDIR}/${BCKP}.log;
FIN=$?
if [ $FIN -eq 0 ]; then
${NOTIFYCMD} --icon=sync-synchronizing ${BCKP} "Backup success."
else
${NOTIFYCMD} -u critical --icon=sync-error ${BCKP} "Done Backup Error: ${FIN}"
fi
#if [ $FIN -eq 0 ]; then
# ${NOTIFYCMD} --icon=sync-synchronizing ${BCKP} "Backup success."
#else
# ${NOTIFYCMD} -u critical --icon=sync-error ${BCKP} "Done Backup Error: ${FIN}"
#fi
done

View File

@@ -3,4 +3,4 @@ PWR_LEINI=2
PWR_TRUHE=3
LIRC_BEAMER_AN="Beamer KEY_POWER"
LIRC_BEAMER_AUS="Beamer KEY_POWER2"
MQTT=mqtt.chaos
MQTT=mqtt

0
kino/kino_an.sh Executable file → Normal file
View File

0
kino/kino_aus.sh Executable file → Normal file
View File

2
kino/truhe_an.sh Executable file → Normal file
View File

@@ -5,4 +5,4 @@ MP=$(dirname "$ME")
. ${MP}/kino.conf
#sispmctl -o ${PWR_TRUHE} #Truhe
mosquitto_pub -h ${MQTT} -t homie/Truhe-switch/SYSTEM/gpio12/set -m 1
mosquitto_pub -h ${MQTT} -t truhe_switch/switch/truhe_switch_power/command -m ON

2
kino/truhe_aus.sh Executable file → Normal file
View File

@@ -6,4 +6,4 @@ MP=$(dirname "$ME")
#sispmctl -f ${PWR_TRUHE} #Truhe
mosquitto_pub -h ${MQTT} -t homie/Truhe-switch/SYSTEM/gpio12/set -m 0
mosquitto_pub -h ${MQTT} -t truhe_switch/switch/truhe_switch_power/command -m OFF

0
mqtt/remove_retained_topic.sh Executable file → Normal file
View File

2
nummer5/hosts.conf Normal file
View File

@@ -0,0 +1,2 @@
hosts="pine01.wks pine02.wks pine03.wks pine04.wks pine05.wks adm01.wks ebin01.wks ebin02.wks"
domain="wks"

View File

@@ -0,0 +1,12 @@
#!/bin/bash
. hosts.conf
host=$1
hostname=$(echo ${host} | sed s/\.${domain}//)
MOSQ="mosquitto_pub -h mqtt.wks -t switch_cloud/switch/${hostname}/command -m"
echo "${host} turning it off"
${MOSQ} OFF
sleep 2
echo "${host} turning it on"
${MOSQ} ON
ping -W 1 ${host}

13
nummer5/nummer5-hosts-alive.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
. hosts.conf
for host in $hosts; do
if ping -c 1 -W 1 "$host" >/dev/null; then
echo "$host is alive"
else
echo "$host is pining for the fjords"
fi
done
echo ''
nomad server members
echo ''
nomad node status

4
osmc.wks/amp_aux.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_ONCE Yamaha_RAV207 AMP/AUX

3
osmc.wks/amp_power.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_ONCE RAV207 KEY_POWER

4
osmc.wks/amp_tuner.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_ONCE Yamaha_RAV207 AMP/TUNER_INPUT

4
osmc.wks/amp_vaux.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_ONCE Yamaha_RAV207 AMP/V_AUX

6
osmc.wks/amp_vol_down.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_START Yamaha_RAV207 AMP/VOL_DOWN
sleep 1
irsend -d /var/run/lirc/lircd-lirc0 SEND_STOP Yamaha_RAV207 AMP/VOL_DOWN

6
osmc.wks/amp_vol_up.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
irsend -d /var/run/lirc/lircd-lirc0 SEND_START Yamaha_RAV207 AMP/VOL_UP
sleep 1
irsend -d /var/run/lirc/lircd-lirc0 SEND_STOP Yamaha_RAV207 AMP/VOL_UP

0
raspbmc-backup-fresh.sh Executable file → Normal file
View File

0
raspbmc-backup.sh Executable file → Normal file
View File

0
raspbmc-restore.sh Executable file → Normal file
View File

View File

@@ -0,0 +1,274 @@
import os
import requests
import re
from bs4 import BeautifulSoup
import subprocess
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# === Configuration ===
REDMINE_URL = "https://redmine.maketank.net" # e.g., https://redmine.example.com
REDMINE_API_KEY = "62120b7ed6bf84023b2a1d7d5a265cf172f8d607"
PROJECT_ID = "bastelstube" # e.g., "my-project"
#GITEA_WIKI_URL = "https://git.maketank.net/chaos/spielplatz.wiki.git" # Gitea wiki Git URL
GITEA_WIKI_URL = "ssh://git@git.maketank.net:2222/chaos/spielplatz.wiki.git"
#GITEA_USERNAME = "do"
#GITEA_TOKEN = "2d2be00637182c6d5411512f456218ee59fa1f81" # Use a personal access token
# Optional: Gitea API for creating pages (if you want to use it instead of Git)
# GITEA_API_URL = "https://gitea.example.com/api/v1"
# === Functions ===
def redmine_get_wiki_pages():
"""Get all wiki pages from Redmine project"""
# First get the list of pages and their parent information
index_url = f"{REDMINE_URL}/projects/{PROJECT_ID}/wiki/index.xml"
headers = {"X-Redmine-API-Key": REDMINE_API_KEY}
response = requests.get(index_url, headers=headers)
response.raise_for_status()
soup = BeautifulSoup(response.content, "xml")
pages = []
for page in soup.find_all("wiki_page"):
title = page.find("title").text
parent = page.find('parent')
if parent:
parent = parent['title']
else:
parent = None # Root level pages have no parent
logger.info(f"Found page: {title} (Parent: {parent})")
# Fetch individual page content
page_url = f"{REDMINE_URL}/projects/{PROJECT_ID}/wiki/{title}.xml"
try:
page_response = requests.get(page_url, headers=headers)
page_response.raise_for_status()
page_soup = BeautifulSoup(page_response.content, "xml")
content = page_soup.find("text").text if page_soup.find("text") else ""
pages.append({"title": title, "parent": parent, "content": content})
logger.info(f"Fetched content for: {title}")
except Exception as e:
logger.warning(f"Failed to fetch content for page '{title}': {e}")
# Add empty content if fetch fails
pages.append({"title": title, "parent": parent, "content": ""})
return pages
def redmine_markup_to_markdown(content, pages):
"""Convert Redmine wiki markup to Markdown"""
# Convert links - handle both [[page]] and [page] syntax
def replace_link(match):
link = match.group(1)
if link in pages: # Ensure the linked page exists
# Create a relative path based on parent-child hierarchy
href = f"{pages[link]['title'].replace(' ', '_')}.md"
return f"[{link}]({href})"
else:
logger.warning(f"Linked page not found: {link}")
# Return original link if linked page not found
return match.group()
# Replace [[page]] with [page](page_url)
content = re.sub(r'\[\[(.*?)\]\]', replace_link, content)
# Convert bold (strong in textile)
content = re.sub(r'\*\*(.*?)\*\*', r'**\1**', content)
content = re.sub(r'\*(.*?)\*', r'*\1*', content)
# Convert headings
content = re.sub(r'^h1\.(.*?)$', r'# \1', content, flags=re.MULTILINE)
content = re.sub(r'^h2\.(.*?)$', r'## \1', content, flags=re.MULTILINE)
content = re.sub(r'^h3\.(.*?)$', r'### \1', content, flags=re.MULTILINE)
content = re.sub(r'^h4\.(.*?)$', r'#### \1', content, flags=re.MULTILINE)
content = re.sub(r'^h5\.(.*?)$', r'##### \1', content, flags=re.MULTILINE)
content = re.sub(r'^h6\.(.*?)$', r'###### \1', content, flags=re.MULTILINE)
# Convert lists
content = re.sub(r'^\s*\* (.*?)$', r'- \1', content, flags=re.MULTILINE)
content = re.sub(r'^\s*\# (.*?)$', r'1. \1', content, flags=re.MULTILINE)
# Convert images - handle !image! and ![alt](image)
content = re.sub(r'!\[(.*?)\]\((.*?)\)', r'![](\2)', content)
content = re.sub(r'!(.*?)!', r'![](\\1)', content)
# Convert code blocks
content = re.sub(r'<pre>(.*?)</pre>', r'```python\n\1\n```', content, flags=re.DOTALL)
# Convert inline code
content = re.sub(r'\{\{(.*?)\}\}', r'`\1`', content)
# Remove HTML tags (if any)
content = re.sub(r'<[^>]+>', '', content)
# Handle textile-specific elements like blockquotes
content = re.sub(r'^bq\.(.*?)$', r'> \1', content, flags=re.MULTILINE)
return content
def download_image(image_url, local_dir):
"""Download an image from Redmine and save it locally"""
try:
headers = {"X-Redmine-API-Key": REDMINE_API_KEY}
response = requests.get(f"{REDMINE_URL}{image_url}", headers=headers)
response.raise_for_status()
# Extract filename from URL
filename = os.path.basename(image_url)
filepath = os.path.join(local_dir, "images", filename)
# Create images directory if it doesn't exist
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'wb') as f:
f.write(response.content)
logger.info(f"Downloaded image: {filename}")
return f"./images/{filename}"
except Exception as e:
logger.warning(f"Failed to download image from {image_url}: {e}")
return None
def clone_or_init_wiki_repo(repo_url, local_dir):
"""Clone or initialize the Gitea wiki repo"""
if not os.path.exists(local_dir):
logger.info(f"Cloning Gitea wiki repository: {repo_url}")
subprocess.run(["git", "clone", repo_url, local_dir], check=True)
else:
logger.info(f"Using existing local wiki repo: {local_dir}")
os.chdir(local_dir)
subprocess.run(["git", "pull"], check=True)
os.chdir('..')
return local_dir
def push_to_gitea_wiki(local_dir, pages):
"""Add pages as Markdown files and push to Gitea"""
page_map = {page['title']: page for page in pages} # Map titles to their data
curr_dir = os.getcwd()
logger.info(f"We are in: {curr_dir}")
# Remove all existing files in the repo (except .git folder)
for item in os.listdir(local_dir):
if item != '.git':
item_path = os.path.join(local_dir, item)
if os.path.isfile(item_path):
os.remove(item_path)
elif os.path.isdir(item_path):
import shutil
shutil.rmtree(item_path)
# Create pages as .md files
for page in pages:
title = page['title']
parent = page.get('parent')
if title == 'Wiki':
filename = "Home.md"
else:
filename = f"{title.replace(' ', '_')}.md"
filepath = os.path.join(local_dir, filename)
if parent and parent in page_map:
# If this page has a parent, create relative path from the parent's directory
parent_filename = f"{parent.replace(' ', '_')}.md"
parent_filepath = os.path.join(local_dir, parent_filename)
if os.path.exists(parent_filepath):
# Parent directory exists, create subdirectory for this page
page_subdir = os.path.dirname(filepath)
os.makedirs(page_subdir, exist_ok=True)
else:
# This is a root level page, no need to create subdirectories
pass
# Convert content to Markdown and handle links
markdown_content = redmine_markup_to_markdown(page['content'], page_map)
# Find all images in the content to log them
image_pattern = r'!(.*?)!'
found_images = re.findall(image_pattern, markdown_content)
if found_images:
logger.info(f"Found images on page '{title}': {found_images}")
# Process all !image! patterns in the content
original_content = markdown_content
# Find all image tags in the format !image_name!
image_tags = re.findall(r'!(.*?)!', original_content)
# For each image tag, attempt to download it and replace it with Markdown syntax
for image_tag in image_tags:
if image_tag and not image_tag.startswith('\\'):
logger.info(f"Found image tag: {image_tag}")
# Replace the specific tag with our download logic
markdown_content = markdown_content.replace(
f"!{image_tag}!",
handle_image_tag(image_tag, local_dir)
)
# Write to file
with open(filepath, 'w', encoding='utf-8') as f:
f.write(f"# {title}\n\n")
f.write(markdown_content)
logger.info(f"Saved page: {filename}")
# Add, commit, and push
os.chdir(local_dir)
subprocess.run(["git", "add", "."], check=True)
subprocess.run(["git", "commit", "-m", "'Import Redmine wiki pages'"], check=False)
subprocess.run(["git", "push", "origin", "main"], check=True)
logger.info("✅ Wiki pages pushed to Gitea!")
def handle_image_tag(image_name, local_dir):
"""Handle replacement of image tags with downloaded images"""
# Check if the image has a valid extension (.png, .jpg, or .jpeg)
valid_extensions = ('.png', '.jpg', '.jpeg')
if not any(image_name.lower().endswith(ext) for ext in valid_extensions):
logger.warning(f"Invalid image extension in tag: {image_name}")
return f"!{image_name}!" # Return original format for invalid extensions
if image_name and not image_name.startswith('\\'):
# In Redmine, images are usually at /attachments/... path
image_url = f"/attachments/download/{image_name}"
logger.info(f"Attempting to download image: {image_name}")
# Try to download the image
downloaded_path = download_image(image_url, local_dir)
if downloaded_path:
return f"![]({downloaded_path})"
else:
# If download fails, keep the original format
return f"!{image_name}!"
else:
# This is likely a regex capture group that wasn't meant to be an image
return f"!{image_name}!"
def main():
# Step 1: Get wiki pages from Redmine
logger.info("Fetching Redmine wiki pages...")
pages = redmine_get_wiki_pages()
# Step 2: Prepare local directory for Gitea wiki
local_wiki_dir = "gitea_wiki_clone"
clone_or_init_wiki_repo(GITEA_WIKI_URL, local_wiki_dir)
# Step 3: Push pages to Gitea
push_to_gitea_wiki(local_wiki_dir, pages)
if __name__ == "__main__":
main()