first commit
This commit is contained in:
commit
2863fc8284
|
|
@ -0,0 +1,56 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "❌ Błąd: Musisz podać plik!"
|
||||||
|
echo "👉 Użycie: cad nazwa_pliku.py"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE=$1
|
||||||
|
FULL_PATH=$(realpath $FILE)
|
||||||
|
SESSION="cad_session"
|
||||||
|
LIVE_SCRIPT="/home/pali112/Build123d/live.py"
|
||||||
|
|
||||||
|
# 1. Zabijamy starą sesję
|
||||||
|
tmux kill-session -t $SESSION 2>/dev/null
|
||||||
|
|
||||||
|
echo "🚀 Tworzę sesję..."
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# OKNO 1: CODE
|
||||||
|
# ==========================================
|
||||||
|
tmux new-session -d -s $SESSION -n 'Code' "vim $FILE"
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# OKNO 2: SERVER
|
||||||
|
# ==========================================
|
||||||
|
echo "🖥️ Przygotowuję maszynownię..."
|
||||||
|
|
||||||
|
# 1. Tworzymy drugie okno
|
||||||
|
tmux new-window -t $SESSION -n 'Server'
|
||||||
|
sleep 0.5 # Daj mu chwilę na wstanie
|
||||||
|
|
||||||
|
# 2. URUCHAMIAMY SERWER (Góra)
|
||||||
|
# W tym momencie mamy tylko jeden panel, więc ślemy do niego.
|
||||||
|
tmux send-keys -t "${SESSION}:Server" "python3 -m ocp_vscode --host 0.0.0.0 --port 3939" C-m
|
||||||
|
|
||||||
|
# 3. DZIELIMY OKNO
|
||||||
|
echo "✂️ Dzielę ekran..."
|
||||||
|
# Dzielimy aktywne okno (Server).
|
||||||
|
# Flaga -d nie jest użyta, więc focus przenosi się do NOWEGO (dolnego) panelu.
|
||||||
|
# Używamy -l 15 zamiast %, żeby wymusić stałą wysokość (15 linii tekstu na dole) - to pewniejsze.
|
||||||
|
tmux split-window -t "${SESSION}:Server" -v -l 15
|
||||||
|
sleep 0.5 # Ważna pauza!
|
||||||
|
|
||||||
|
# 4. URUCHAMIAMY RUNNERA (Dół)
|
||||||
|
# Skoro po splicie kursor jest na dole, ślemy po prostu do okna Server.
|
||||||
|
tmux send-keys -t "${SESSION}:Server" "python3 $LIVE_SCRIPT $FULL_PATH" C-m
|
||||||
|
|
||||||
|
# ==========================================
|
||||||
|
# FINISH
|
||||||
|
# ==========================================
|
||||||
|
# Wracamy do kodu
|
||||||
|
tmux select-window -t "${SESSION}:Code"
|
||||||
|
|
||||||
|
echo "✅ Gotowe! Podłączam..."
|
||||||
|
tmux attach-session -t $SESSION
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
from threading import Timer
|
||||||
|
|
||||||
|
# --- KONFIGURACJA ---
|
||||||
|
VIEWER_PORT = 3939
|
||||||
|
DELAY_SECONDS = 0.1 # Czeka na ciszę przez 0.5s zanim przeładuje
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("❌ Błąd: Nie podałeś nazwy pliku!")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
RAW_PATH = sys.argv[1]
|
||||||
|
ABS_PATH = os.path.abspath(RAW_PATH)
|
||||||
|
DIR_NAME = os.path.dirname(ABS_PATH)
|
||||||
|
FILE_NAME = os.path.basename(ABS_PATH)
|
||||||
|
MODULE_NAME = os.path.splitext(FILE_NAME)[0]
|
||||||
|
|
||||||
|
print(f"📂 Katalog roboczy: {DIR_NAME}")
|
||||||
|
os.chdir(DIR_NAME)
|
||||||
|
if "." not in sys.path:
|
||||||
|
sys.path.insert(0, ".")
|
||||||
|
|
||||||
|
# --- IMPORTY CAD ---
|
||||||
|
print(f"🔥 Ładuję biblioteki CAD...")
|
||||||
|
import build123d
|
||||||
|
from ocp_vscode import show, set_port
|
||||||
|
|
||||||
|
# Konfigurujemy klienta, żeby gadał z portem 3939
|
||||||
|
set_port(VIEWER_PORT)
|
||||||
|
|
||||||
|
print(f"🚀 GOTOWE! Nasłuchuję zmian w: {FILE_NAME}")
|
||||||
|
|
||||||
|
# --- OBSŁUGA ZMIAN PLIKU ---
|
||||||
|
class RebuildHandler(FileSystemEventHandler):
|
||||||
|
def __init__(self):
|
||||||
|
self.timer = None
|
||||||
|
|
||||||
|
def on_modified(self, event):
|
||||||
|
# Reagujemy tylko na zmianę TEGO konkretnego pliku
|
||||||
|
if os.path.abspath(event.src_path) == ABS_PATH:
|
||||||
|
# Jeśli zegar już tyka, anulujemy go (bo przyszło nowe zdarzenie = Vim jeszcze pisze)
|
||||||
|
if self.timer:
|
||||||
|
self.timer.cancel()
|
||||||
|
|
||||||
|
# Ustawiamy nowy timer. Odpali się tylko jeśli przez 0.5s nic nowego nie przyjdzie.
|
||||||
|
self.timer = Timer(DELAY_SECONDS, self.process_reload)
|
||||||
|
self.timer.start()
|
||||||
|
|
||||||
|
def process_reload(self):
|
||||||
|
print(f"♻️ Przeliczam {MODULE_NAME}... ", end="", flush=True)
|
||||||
|
start_time = time.time()
|
||||||
|
try:
|
||||||
|
# Magia przeładowania modułu bez restartu procesu
|
||||||
|
if MODULE_NAME in sys.modules:
|
||||||
|
importlib.reload(sys.modules[MODULE_NAME])
|
||||||
|
else:
|
||||||
|
importlib.import_module(MODULE_NAME)
|
||||||
|
|
||||||
|
print(f"Gotowe ({time.time() - start_time:.2f}s)")
|
||||||
|
except Exception as e:
|
||||||
|
# Łapiemy błędy składni/CAD, żeby runner się nie wywalił
|
||||||
|
print(f"\n❌ BŁĄD KODU:\n{e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 1. Pierwsze uruchomienie przy starcie
|
||||||
|
try:
|
||||||
|
importlib.import_module(MODULE_NAME)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Startowy błąd w kodzie: {e}")
|
||||||
|
|
||||||
|
# 2. Uruchomienie obserwatora (Watchdog)
|
||||||
|
event_handler = RebuildHandler()
|
||||||
|
observer = Observer()
|
||||||
|
# Obserwujemy katalog, ale w handlerze filtrujemy tylko nasz plik
|
||||||
|
observer.schedule(event_handler, path='.', recursive=False)
|
||||||
|
observer.start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
observer.stop()
|
||||||
|
print("\n🛑 Koniec pracy.")
|
||||||
|
observer.join()
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
" Dodaj globalne tagi dla biblioteki BOSL2
|
||||||
|
set tags+=~/.build123_tags
|
||||||
|
|
||||||
|
" Skrót do następnego bufora: \ + Tab
|
||||||
|
nnoremap <silent> <leader><Tab> :bnext<CR>
|
||||||
|
nnoremap <leader>w :w <bar> !python %<CR>
|
||||||
|
|
||||||
|
" Używaj ruff jako lintera (sprawdzanie błędów)
|
||||||
|
let g:ale_linters = {
|
||||||
|
\ 'python': ['flake8']
|
||||||
|
\}
|
||||||
|
|
||||||
|
" Używaj ruff jako fixera (do :ALEFix)
|
||||||
|
let g:ale_fixers = {
|
||||||
|
\ 'python': ['ruff_format']
|
||||||
|
\}
|
||||||
|
|
||||||
|
" <Leader>[ działa jak przełącznik: raz włącza, raz wyłącza tryb PASTE
|
||||||
|
nnoremap <leader>[ :set invpaste paste?<CR>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
/home/pali112/Nextcloud/start/my_others
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
snippet build123d
|
||||||
|
from build123d import *
|
||||||
|
snippet ocp
|
||||||
|
from ocp_vscode import *
|
||||||
|
snippet box
|
||||||
|
Box(${1:length}, ${2:width}, ${3:height})
|
||||||
|
|
||||||
|
snippet text
|
||||||
|
Text("${1:what?}", font_size=${2:ile?})
|
||||||
|
|
||||||
|
|
||||||
|
snippet otwieramy
|
||||||
|
offset(amount=-${1:grubosc_scianki}, openings=${2:what}.faces().sort_by(Axis.Z)[-1])
|
||||||
|
|
||||||
|
snippet loc
|
||||||
|
with Locations((${1:x}, ${2:y}, ${3:z})):
|
||||||
|
|
||||||
|
snippet rec
|
||||||
|
Rectangle(${1:dlugosc}, ${2:szerokosc})
|
||||||
|
|
||||||
|
|
||||||
|
snippet filletpolyline
|
||||||
|
FilletPolyline((${1:pts1}, ${2:pts2}), (${3:pts3}, ${4:pts4}), (${5:pts5}, ${6:pts5}), radius=${7:fillet radius})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
snippet part
|
||||||
|
with BuildPart() as ${1:what?}:
|
||||||
|
snippet sketch
|
||||||
|
with BuildSketch() as ${1:what?}:
|
||||||
|
|
||||||
|
snippet line
|
||||||
|
with BuildLine() as ${1:what?}:
|
||||||
|
|
||||||
|
snippet debug
|
||||||
|
debug(${1:what?})
|
||||||
|
snippet move
|
||||||
|
move(Location((${1:0}, ${2:0}, ${3:0})))
|
||||||
|
|
||||||
|
snippet extrude
|
||||||
|
extrude(amount=${1:ile?})
|
||||||
|
|
||||||
|
snippet align
|
||||||
|
align=Align.${1:what?}
|
||||||
|
|
||||||
|
snippet alignl
|
||||||
|
align=(Align.${1:what?}, Align.${2:what?}, Align.${3:what?})
|
||||||
|
|
||||||
|
snippet fs
|
||||||
|
${1:what?}.faces().sort_by(Axis.${2:what?})
|
||||||
|
|
||||||
|
|
||||||
|
snippet grid
|
||||||
|
with GridLocations(${1:x_spacing,}, ${2:y_spacing}, ${3:x_count}, ${4:y_count})
|
||||||
|
|
||||||
|
snippet mode
|
||||||
|
mode=Mode.${1:what?}
|
||||||
|
|
||||||
|
snippet fillet
|
||||||
|
fillet(${1:objects}, ${2:radius})
|
||||||
|
|
||||||
|
snippet circle
|
||||||
|
Circle(${1:radius})
|
||||||
|
|
||||||
|
snippet mirror
|
||||||
|
mirror(about=Plane.${1:XY})
|
||||||
|
|
||||||
|
snippet triangle
|
||||||
|
Triangle(a=${1:a}, ${2:b}, ${3:c}, ${4:opcional_Angle1}, ${5:optional_Angle2}, ${6:opcional_Angle3})
|
||||||
|
|
||||||
|
snippet cone
|
||||||
|
Cone(bottom_radius=${1:ile?}, top_radius=${2:ile?}, height=${3:ile?})
|
||||||
|
|
||||||
|
snippet scale
|
||||||
|
scale(${1:what?}, by=${2:scale_factor})
|
||||||
|
|
||||||
|
snippet show
|
||||||
|
show(${1:what?})
|
||||||
|
snippet showc
|
||||||
|
show(${1:what?}, colors=["${2:grey}"])
|
||||||
|
snippet joint_location
|
||||||
|
joint_location((${1:x}, ${2:y}, ${3:z}))
|
||||||
|
|
||||||
|
snippet recr
|
||||||
|
RectangleRounded(${1:dlugosc}, ${2:szerokosc}, ${3:radius})
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import filedialog, messagebox
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def browse_exec():
|
||||||
|
path = filedialog.askopenfilename(title="Wybierz plik wykonywalny (AppImage/skrypt)")
|
||||||
|
if path:
|
||||||
|
entry_exec.delete(0, tk.END)
|
||||||
|
entry_exec.insert(0, path)
|
||||||
|
|
||||||
|
def browse_icon():
|
||||||
|
path = filedialog.askopenfilename(title="Wybierz ikonę", filetypes=[("Pliki graficzne", "*.png *.svg *.ico *.jpg *.jpeg")])
|
||||||
|
if path:
|
||||||
|
entry_icon.delete(0, tk.END)
|
||||||
|
entry_icon.insert(0, path)
|
||||||
|
|
||||||
|
def choose_location():
|
||||||
|
location = var_location.get()
|
||||||
|
if location == "local":
|
||||||
|
return os.path.expanduser("~/.local/share/applications")
|
||||||
|
elif location == "system":
|
||||||
|
return "/usr/share/applications"
|
||||||
|
elif location == "desktop":
|
||||||
|
return os.path.join(os.path.expanduser("~"), "Pulpit")
|
||||||
|
else:
|
||||||
|
return os.path.expanduser("~")
|
||||||
|
|
||||||
|
def create_desktop_entry():
|
||||||
|
name = entry_name.get().strip()
|
||||||
|
exec_path = entry_exec.get().strip()
|
||||||
|
icon_path = entry_icon.get().strip()
|
||||||
|
terminal = var_terminal.get()
|
||||||
|
|
||||||
|
if not name or not exec_path:
|
||||||
|
messagebox.showerror("Błąd", "Nazwa aplikacji i ścieżka do pliku wykonywalnego są wymagane.")
|
||||||
|
return
|
||||||
|
|
||||||
|
terminal_value = "true" if terminal else "false"
|
||||||
|
|
||||||
|
desktop_content = f"""[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name={name}
|
||||||
|
Exec="{exec_path}"
|
||||||
|
{"Icon=" + icon_path if icon_path else ""}
|
||||||
|
Terminal={terminal_value}
|
||||||
|
"""
|
||||||
|
|
||||||
|
filename = name.lower().replace(" ", "_") + ".desktop"
|
||||||
|
folder = choose_location()
|
||||||
|
desktop_path = os.path.join(folder, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if folder.startswith("/usr"):
|
||||||
|
# Zapis przez pkexec do katalogu systemowego
|
||||||
|
tmpfile = f"/tmp/{filename}"
|
||||||
|
with open(tmpfile, "w") as f:
|
||||||
|
f.write(desktop_content)
|
||||||
|
subprocess.run(["pkexec", "cp", tmpfile, desktop_path], check=True)
|
||||||
|
subprocess.run(["pkexec", "chmod", "755", desktop_path], check=True)
|
||||||
|
os.remove(tmpfile)
|
||||||
|
else:
|
||||||
|
os.makedirs(folder, exist_ok=True)
|
||||||
|
with open(desktop_path, 'w') as f:
|
||||||
|
f.write(desktop_content)
|
||||||
|
os.chmod(desktop_path, 0o755)
|
||||||
|
|
||||||
|
messagebox.showinfo("Sukces", f"Skrót utworzony: {desktop_path}")
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror("Błąd", f"Nie udało się zapisać skrótu:\n{e}")
|
||||||
|
|
||||||
|
# GUI
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Tworzenie skrótu .desktop")
|
||||||
|
|
||||||
|
tk.Label(root, text="Nazwa aplikacji:").grid(row=0, column=0, sticky="e")
|
||||||
|
entry_name = tk.Entry(root, width=40)
|
||||||
|
entry_name.grid(row=0, column=1, pady=2)
|
||||||
|
|
||||||
|
tk.Label(root, text="Ścieżka do pliku:").grid(row=1, column=0, sticky="e")
|
||||||
|
entry_exec = tk.Entry(root, width=40)
|
||||||
|
entry_exec.grid(row=1, column=1, pady=2)
|
||||||
|
tk.Button(root, text="Przeglądaj", command=browse_exec).grid(row=1, column=2)
|
||||||
|
|
||||||
|
tk.Label(root, text="Ikona (opcjonalnie):").grid(row=2, column=0, sticky="e")
|
||||||
|
entry_icon = tk.Entry(root, width=40)
|
||||||
|
entry_icon.grid(row=2, column=1, pady=2)
|
||||||
|
tk.Button(root, text="Przeglądaj", command=browse_icon).grid(row=2, column=2)
|
||||||
|
|
||||||
|
var_terminal = tk.BooleanVar()
|
||||||
|
tk.Checkbutton(root, text="Uruchamiane w terminalu", variable=var_terminal).grid(row=3, column=1, pady=4)
|
||||||
|
|
||||||
|
tk.Label(root, text="Miejsce zapisu:").grid(row=4, column=0, sticky="e")
|
||||||
|
var_location = tk.StringVar(value="local")
|
||||||
|
tk.Radiobutton(root, text="Lokalnie (~/.local/share/applications)", variable=var_location, value="local").grid(row=4, column=1, sticky="w")
|
||||||
|
tk.Radiobutton(root, text="Systemowo (/usr/share/applications)", variable=var_location, value="system").grid(row=5, column=1, sticky="w")
|
||||||
|
tk.Radiobutton(root, text="Pulpit", variable=var_location, value="desktop").grid(row=6, column=1, sticky="w")
|
||||||
|
|
||||||
|
tk.Button(root, text="Utwórz skrót", command=create_desktop_entry, bg="#4CAF50", fg="white").grid(row=7, column=1, pady=10)
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Utworzenie linków"
|
||||||
|
ln -s /home/pali112/Nextcloud/start/my_configs.vim /home/pali112/.vim_runtime/my_configs.vim
|
||||||
|
ln -s /home/pali112/Nextcloud/start/my_others /home/pali112/.vim_runtime/my_others
|
||||||
|
ln -s /home/pali112/Nextcloud/start/.zshrc /home/pali112/.zshrc
|
||||||
|
ln -s /home/pali112/Nextcloud/start/.build123_tags /home/pali112/.build123_tags
|
||||||
|
ln -s /home/pali112/Nextcloud/start/.flake8 /home/pali112/.flake8
|
||||||
|
ln -s /home/pali112/Nextcloud/start/.tmux.conf /home/pali112/.tmux.conf
|
||||||
|
ln -s /home/pali112/Nextcloud/start/live.py /home/pali112/Build123d/live.py
|
||||||
|
|
||||||
|
KATALOG="/home/pali112/.local/bin"
|
||||||
|
|
||||||
|
# 1. Sprawdzenie, czy katalog istnieje
|
||||||
|
if [ ! -d "$KATALOG" ]; then
|
||||||
|
|
||||||
|
# 2. Jeśli NIE istnieje (-d sprawdza katalog, ! odwraca wynik)
|
||||||
|
echo "Katalog $KATALOG nie istnieje. Tworzę go..."
|
||||||
|
|
||||||
|
# 3. Utworzenie katalogu
|
||||||
|
# Flaga -p zapewnia, że wszystkie potrzebne katalogi nadrzędne (.local) też zostaną utworzone, jeśli ich nie ma.
|
||||||
|
mkdir -p "$KATALOG"
|
||||||
|
|
||||||
|
# 4. Sprawdzenie, czy operacja się powiodła
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Katalog $KATALOG został pomyślnie utworzony."
|
||||||
|
else
|
||||||
|
echo "Błąd: Nie udało się utworzyć katalogu $KATALOG."
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
# 5. Jeśli katalog już istnieje
|
||||||
|
echo "Katalog $KATALOG już istnieje wykonuję kolejne rzeczy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Tworzenie linku cad"
|
||||||
|
ln -s /home/pali112/Nextcloud/start/cad /home/pali112/.local/bin/cad
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue