2024-11-22 09:13:31 -05:00
#! /usr/bin/env nix-shell
2024-11-22 09:50:05 -05:00
#! nix-shell -i python -p python312 python312Packages.tkinter python312Packages.requests libnotify
2024-11-22 09:13:31 -05:00
import argparse
import mimetypes
import os
import subprocess
from pathlib import Path
from shutil import which
from tkinter import Tk
from typing import Any
import requests # type: ignore
2024-11-22 09:50:05 -05:00
from common . common import does_desktop_entry_exist , notify , read_secret_file
2024-11-22 09:13:31 -05:00
2024-11-22 09:50:05 -05:00
def copy_to_clipboard ( text : str ) - > None :
if which ( " xclip " ) :
subprocess . run (
[ " xclip " , " -selection " , " clipboard " , " -t " , " text/plain " , " -i " ] ,
input = text . encode ( ) ,
2024-11-22 09:13:31 -05:00
)
2024-11-22 09:50:05 -05:00
elif which ( " wl-copy " ) :
subprocess . run ( [ " wl-copy " , " --type " , " text/plain " ] , input = text . encode ( ) )
2024-11-22 09:13:31 -05:00
else :
2024-11-22 09:50:05 -05:00
root = Tk ( )
root . withdraw ( )
root . clipboard_clear ( )
root . clipboard_append ( text )
root . update ( )
root . destroy ( )
2024-11-22 09:13:31 -05:00
def zipline (
file_path : Path ,
instance_url : str ,
application_name : str = None ,
desktop_entry : str = None ,
) - > Any :
token = read_secret_file ( " zipline " )
if not token :
raise FileNotFoundError (
" Secret file at /run/secrets/zipline either does not exist or is empty. "
)
if not os . path . isfile ( file_path ) :
raise FileNotFoundError ( f " File at { file_path } does not exist. " )
use_send_notify = False
if application_name and desktop_entry :
if not does_desktop_entry_exist ( desktop_entry = desktop_entry ) :
raise FileNotFoundError ( " Desktop entry does not exist. " )
if not which ( " notify-send " ) :
raise FileNotFoundError ( " notify-send is not installed. " )
use_send_notify = True
content_type = mimetypes . guess_type ( file_path ) [ 0 ] or " application/octet-stream "
try :
headers = { " authorization " : token }
files = {
" file " : ( os . path . basename ( file_path ) , open ( file_path , " rb " ) , content_type )
}
response = requests . post (
f " { instance_url . rstrip ( ' / ' ) } /api/upload " , headers = headers , files = files
)
if response . status_code == 200 :
response_data = response . json ( )
link = response_data . get ( " files " , [ None ] ) [ 0 ]
if link :
copy_to_clipboard ( text = link )
2024-11-22 09:50:05 -05:00
print ( f " Link copied to clipboard: { link } " )
2024-11-22 09:13:31 -05:00
if use_send_notify :
notify (
application_name = application_name ,
title = " Upload Successful " ,
message = f " Link copied to clipboard: { link } " ,
urgency = " low " ,
category = " transfer.complete " ,
icon = file_path ,
)
else :
raise ValueError ( " Invalid response format. " )
else :
error_message = response . text
raise Exception ( error_message )
except Exception as e :
if use_send_notify :
notify (
application_name = application_name ,
title = " Upload Failed " ,
message = f " An error occurred: { e } " ,
urgency = " critical " ,
category = " transfer.error " ,
icon = file_path ,
)
raise e
if __name__ == " __main__ " :
parser = argparse . ArgumentParser (
2024-11-22 09:52:38 -05:00
prog = " zipline.py " ,
2024-11-22 09:13:31 -05:00
description = " Upload a file to a Zipline instance. " ,
2024-11-22 09:52:38 -05:00
epilog = " Example usage: zipline.py /path/to/file.txt " ,
2024-11-22 09:13:31 -05:00
)
parser . add_argument ( " file " , help = " The file to upload. " )
parser . add_argument (
" --url " ,
help = " The URL of the Zipline instance. Defaults to ' https://csw.im ' . " ,
default = " https://csw.im " ,
)
parser . add_argument (
" --application-name " ,
help = " The name of the application that is uploading the file. Defaults to ' Zipline ' . " ,
default = " Zipline " ,
)
parser . add_argument (
" --desktop-entry " ,
help = " The desktop entry file for the application that is uploading the file. If this is provided, send-notify will be invoked to display a notification if the upload succeeds or fails. " ,
default = None ,
)
args = parser . parse_args ( )
zipline (
file_path = args . file ,
instance_url = args . url ,
application_name = args . application_name ,
desktop_entry = args . desktop_entry ,
)