Files
kniip/.cursor/plans/zipline_upload_df938514.plan.md
T
2026-11-07 12:19:45 +01:00

6.8 KiB

name, overview, todos, isProject
name overview todos isProject
Zipline upload Een Zipline 4-uploadbestemming toevoegen die je configureert door het ShareX-bestand (.sxcu) of het Shell Script-bestand (.sh) uit Zipline te importeren. Kniip uploadt daarna zelf via HttpClient, met een aparte knop Uploaden in de editor en in het screencastvenster. De link komt op het klembord.
id content status
config UploaderConfig + UploaderImporter (sxcu- en curl/sh-parser) in src/Kniip/Upload completed
id content status
client ZiplineUploader met HttpClient multipart, foutafhandeling en JSON-padlezer completed
id content status
settings AppSettings.Uploader, DPAPI-versleuteling token in SettingsStore, tabblad Uploaden (importeren/testen/verwijderen) completed
id content status
clipboard ClipboardWriter.SetText toevoegen completed
id content status
editor Uploadknop + Ctrl+U in EditorWindow, zichtbaar alleen met config; ToolbarPanel-volgorde controleren completed
id content status
screencast Uploadknop in ScreencastWindow: export naar temp, upload met voortgang/annuleren, link naar klembord completed
id content status
build Bouwen en testen met een echte .sxcu en .sh uit Zipline 4 completed
false

Upload naar Zipline 4

Hoe het werkt

flowchart LR
    sxcu["ShareX .sxcu"] --> importer[UploaderImporter]
    sh["Shell script .sh"] --> importer
    importer --> config["UploaderConfig in AppSettings"]
    editorBtn["Editor: Uploaden"] --> client[ZiplineUploader]
    castBtn["Screencast: Uploaden"] --> client
    config --> client
    client -->|"POST multipart"| server["Zipline /api/upload"]
    server -->|"JSON files[0].url"| client
    client --> clip["URL naar klembord + melding"]

Zipline 4 gebruikt een vast patroon: POST https://host/api/upload met de header authorization: <token>, extra headers zoals x-zipline-format, een multipart-veld file, en als antwoord {"files":[{"url": ...}]}. Beide exportbestanden bevatten precies die gegevens. Kniip leest ze daarom alleen in en voert niets uit.

Nieuwe bestanden in src/Kniip/Upload/

  • UploaderConfig.cs bevat de velden Name, RequestUrl, Headers (een dictionary), FileFormName (standaard "file") en UrlPath (standaard "files[0].url"). Daarnaast staat er een eigenschap IsConfigured.
  • UploaderImporter.cs:
    • FromSxcu(string json): leest met System.Text.Json de velden RequestURL, Headers, FileFormName en URL uit. Van URL wordt {json:files[0].url} omgezet naar het pad files[0].url. Een .sxcu met Body anders dan MultipartFormData wordt geweigerd.
    • FromShellScript(string text): zoekt de curl-regel. Daaruit haalt hij de http(s)://-URL, elke -H "naam: waarde" als header (behalve content-type), en de veldnaam uit -F naam=@.... Het antwoordpad komt uit jq -r <pad> als dat er staat, anders de standaardwaarde. Regelvervolgingen (\ aan het einde van een regel) en aanhalingstekens worden gewoon afgehandeld.
    • Kan het bestand niet worden gelezen, dan geeft de importer een duidelijke Nederlandse foutmelding.
  • ZiplineUploader.cs: één statische HttpClient en de methode Task<string> UploadAsync(UploaderConfig, Stream, string fileName, string contentType, IProgress<double>?, CancellationToken). Die bouwt de MultipartFormDataContent, voegt de headers toe en geeft bij een HTTP-fout de statuscode en de error-tekst van Zipline terug. Daarna leest hij de URL via een eenvoudige padlezer (a.b[0].c) uit het JSON-antwoord.

Instellingen

  • In src/Kniip/Settings/AppSettings.cs komt public UploaderConfig? Uploader { get; set; } bij.
  • De authorization-header is een geheime token. Die wordt in de settings-JSON met DPAPI versleuteld voor de huidige gebruiker, via ProtectedData.Protect en het NuGet-pakket System.Security.Cryptography.ProtectedData. Dat gebeurt in src/Kniip/Settings/SettingsStore.cs bij het opslaan en laden.
  • In src/Kniip/Settings/SettingsWindow.xaml komt een nieuw tabblad Uploaden met:
    • Een knop "Importeren..." met een OpenFileDialog en het filter ShareX-uploader (*.sxcu)|*.sxcu|Shell script (*.sh)|*.sh.
    • Een regel die de huidige bestemming toont: de servernaam uit de URL, zonder token.
    • De knoppen "Testen" (uploadt een klein PNG'tje en toont de link) en "Verwijderen".
    • Een hinttekst: "Maak het bestand in Zipline via Instellingen > Generate Uploaders (ShareX of Shell Script)."
  • De afhandeling komt in src/Kniip/Settings/SettingsWindow.xaml.cs. De nieuwe configuratie wordt pas bij Opslaan vastgelegd, net als bij de andere instellingen.

Editor

  • In src/Kniip/Editor/EditorWindow.xaml komt een nieuwe toolbarknop ItemId="Upload" (icoon &#xE898;, titel "Uploaden"), tussen Opslaan en Kopiëren.
  • In src/Kniip/Editor/EditorWindow.xaml.cs komt Upload_Click plus de sneltoets Ctrl+U:
    • CommitTextEdit(), daarna DocumentRenderer.Export(_doc) en vervolgens ImageExporter.EncodePng.
    • UploadAsync met de bestandsnaam Knipsel yyyy-MM-dd HHmmss.png.
    • Het resultaat gaat naar ClipboardWriter.SetText(url) en ShowTemporaryHint("Geüpload, link gekopieerd: ...").
    • Tijdens het uploaden is de knop uitgeschakeld.
  • De knop is ingeklapt zolang Uploader niet is ingesteld. Dat wordt opnieuw gecontroleerd in OnActivated, net zoals ApplySaveButton dat doet.
  • Ik controleer in ToolbarPanel dat een nieuw ItemId ook verschijnt als er al een ToolbarOrder is opgeslagen. Zo niet, dan komen onbekende items achteraan.

Screencast

  • In src/Kniip/Recording/ScreencastWindow.xaml komt een knop UploadButton naast Kopiëren.
  • In src/Kniip/Recording/ScreencastWindow.xaml.cs komt Upload_Click. Dat volgt hetzelfde patroon als Copy_Click:
    • Eerst ExportAsync naar een tijdelijke map.
    • Daarna UploadAsync met video/mp4 of image/gif. De voortgang loopt via dezelfde Progress-balk en annuleren gaat via _export.
    • Daarna gaat de URL naar het klembord en toont SavedText de link.
    • SetBusy schakelt ook UploadButton uit.

Hulpfunctie

Buiten de scope

  • Automatisch uploaden bij een nieuw knipsel.
  • Een "opslaan en uploaden"-keuze voor de knop Opslaan.
  • Het echt uitvoeren van het shellscript.
  • Andere uploaders dan Zipline. De importer werkt in principe ook voor andere ShareX-configuraties met multipart, maar dat wordt niet getest.