commit bfd200f1ec11fc496ca702f0b0a791956954d7a9 Author: elpatron Date: Mon Mar 31 14:50:58 2025 +0200 Initiales Commit: Multi-Plattform Clipboard zu snips.sh Integration diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0a9abae --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dist/ +*.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..84ba8a9 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Clip2Snips + +Eine Go-Anwendung, die Text aus der Zwischenablage an [snips.sh](https://snips.sh/) sendet und die resultierende URL zurück in die Zwischenablage kopiert. + +## Voraussetzungen + +- Go 1.21 oder höher (für Build) +- SSH-Zugang zu snips.sh +- SSH Schlüsselpaar - ggf. `ssh-keygen` (alle OS) ausführen +- Betriebssystemspezifische Anforderungen: + - Windows: PowerShell + - Linux: xclip oder xsel (`sudo apt install xclip` oder `sudo apt install xsel`) + - macOS: keine zusätzlichen Anforderungen (pbcopy/pbpaste sind vorinstalliert) + +## Installation + +1. Klonen Sie das Repository +2. Führen Sie den Build für Ihr Betriebssystem aus: + ```powershell + # Windows (PowerShell) + .\build.ps1 + ``` + Die Binärdateien werden im `dist`-Verzeichnis erstellt: + - Windows: `clip2snips.exe` + - Linux: `clip2snips-linux` + - macOS: `clip2snips-darwin` + +3. Stellen Sie sicher, dass Sie SSH-Zugang zu snips.sh haben (ggf. `ssh snips.sh` ausführen und den SSH-Key akzeptieren) + +## Verwendung + +1. Kopieren Sie Text in die Zwischenablage +2. Führen Sie die Anwendung aus +3. Die Snips-URL wird automatisch in die Zwischenablage kopiert und in der Konsole angezeigt + +## Fehlerbehebung + +- Stellen Sie sicher, dass Sie eine aktive Internetverbindung haben +- Überprüfen Sie Ihre SSH-Konfiguration für snips.sh +- Betriebssystemspezifische Probleme: + - Windows: Stellen Sie sicher, dass PowerShell verfügbar ist + - Linux: Installieren Sie xclip oder xsel + - macOS: Keine speziellen Anforderungen \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..1327fb7 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,32 @@ +# build.ps1 + +# Erstelle Ausgabeverzeichnis +$outDir = "dist" +if (-not (Test-Path $outDir)) { + New-Item -ItemType Directory -Path $outDir +} + +# Build-Konfigurationen +$targets = @( + @{OS="windows"; ARCH="amd64"; EXT=".exe"}, + @{OS="linux"; ARCH="amd64"; EXT=""}, + @{OS="darwin"; ARCH="amd64"; EXT=""} +) + +# Führe Builds aus +foreach ($target in $targets) { + $outFile = "clip2snips$($target.EXT)" + if ($target.OS -ne "windows") { + $outFile = "clip2snips-$($target.OS)$($target.EXT)" + } + $outPath = Join-Path $outDir $outFile + + Write-Host "Building for $($target.OS)/$($target.ARCH)..." + $env:GOOS = $target.OS + $env:GOARCH = $target.ARCH + + go build -o $outPath +} + +Write-Host "`nBuild completed. Binaries in ./$outDir/:" +Get-ChildItem $outDir diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d3704b2 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module clip2snips + +go 1.21 \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..2ded01d --- /dev/null +++ b/main.go @@ -0,0 +1,118 @@ +package main + +import ( + "fmt" + "os/exec" + "regexp" + "runtime" + "strings" +) + +func main() { + // Text aus der Zwischenablage lesen + clipText, err := getClipboard() + if err != nil { + fmt.Printf("fehler beim lesen der zwischenablage: %v\n", err) + return + } + + // Entferne Zeilenumbrüche am ende + clipText = strings.TrimSpace(clipText) + if clipText == "" { + fmt.Println("die zwischenablage ist leer") + return + } + + // Text an snips.sh senden + output, err := sendToSnips(clipText) + if err != nil { + fmt.Printf("fehler beim senden an snips.sh: %v\n", err) + return + } + + // URL aus der antwort extrahieren + url := extractURL(output) + if url == "" { + fmt.Println("keine url in der antwort gefunden") + return + } + + // URL in die zwischenablage kopieren + err = setClipboard(url) + if err != nil { + fmt.Printf("fehler beim kopieren der url: %v\n", err) + return + } + + fmt.Println(url) +} + +func getClipboard() (string, error) { + var cmd *exec.Cmd + switch runtime.GOOS { + case "windows": + cmd = exec.Command("powershell", "-command", "Get-Clipboard") + case "linux": + // Prüfe, ob xclip installiert ist + if _, err := exec.LookPath("xclip"); err == nil { + cmd = exec.Command("xclip", "-selection", "clipboard", "-o") + } else if _, err := exec.LookPath("xsel"); err == nil { + cmd = exec.Command("xsel", "--clipboard", "--output") + } else { + return "", fmt.Errorf("weder xclip noch xsel sind installiert") + } + case "darwin": // macOS + cmd = exec.Command("pbpaste") + default: + return "", fmt.Errorf("betriebssystem %s wird nicht unterstützt", runtime.GOOS) + } + + output, err := cmd.Output() + if err != nil { + return "", err + } + return string(output), nil +} + +func setClipboard(text string) error { + var cmd *exec.Cmd + switch runtime.GOOS { + case "windows": + cmd = exec.Command("powershell", "-command", fmt.Sprintf("Set-Clipboard -Value '%s'", text)) + case "linux": + // Prüfe, ob xclip installiert ist + if _, err := exec.LookPath("xclip"); err == nil { + cmd = exec.Command("xclip", "-selection", "clipboard") + } else if _, err := exec.LookPath("xsel"); err == nil { + cmd = exec.Command("xsel", "--clipboard", "--input") + } else { + return fmt.Errorf("weder xclip noch xsel sind installiert") + } + case "darwin": // macOS + cmd = exec.Command("pbcopy") + default: + return fmt.Errorf("betriebssystem %s wird nicht unterstützt", runtime.GOOS) + } + + cmd.Stdin = strings.NewReader(text) + return cmd.Run() +} + +func sendToSnips(text string) (string, error) { + cmd := exec.Command("ssh", "-T", "snips.sh") + cmd.Stdin = strings.NewReader(text) + output, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("SSH-Fehler: %v\nOutput: %s", err, string(output)) + } + return string(output), nil +} + +func extractURL(output string) string { + re := regexp.MustCompile(`f:([a-zA-Z0-9]+)@snips\.sh`) + matches := re.FindStringSubmatch(output) + if len(matches) > 1 { + return fmt.Sprintf("https://snips.sh/f/%s", matches[1]) + } + return "" +}