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