Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/cli/app/commands/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Annotated
from urllib.parse import urlparse
import tempfile

import os
import typer
from async_typer import AsyncTyper

Expand Down Expand Up @@ -50,7 +50,7 @@ async def download(
key_secret: str
inferred_url: str | None = None

# Case 1: Full URL -> https://instance.com/download/SLUG#KEY
# Full URL -> https://instance.com/download/SLUG#KEY
if "://" in link:
parsed = urlparse(link)
fragment = parsed.fragment
Expand All @@ -68,7 +68,7 @@ async def download(
inferred_url = f"{parsed.scheme}://{parsed.netloc}"
key_secret = fragment

# Case 2: SLUG#KEY
# SLUG#KEY
elif "#" in link:
slug, key_secret = link.split("#", 1)

Expand All @@ -83,7 +83,9 @@ async def download(
urls = UrlBuilder.resolve(base_url)

# Process
tmp_run = tempfile.mktemp(prefix="chithi_")
fd, tmp_run = tempfile.mkstemp(prefix="chithi_")
os.close(fd)

tmp_dl = Path(f"{tmp_run}.dl")
tmp_zip = Path(f"{tmp_run}.zip")

Expand Down
12 changes: 8 additions & 4 deletions src/cli/app/commands/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
from typing import Annotated
import tempfile
import os
from rich.console import Console

import segno
import typer
from async_typer import AsyncTyper

from app import archive, client, crypto
from app.builder.urls import UrlBuilder
from app.helpers.file import cleanup
from rich_pixels import Pixels

app = AsyncTyper(help="Upload & download encrypted files via Chithi.")
console = Console()


@app.async_command()
Expand Down Expand Up @@ -127,10 +129,12 @@ async def upload(
finally:
cleanup(tmp_zip, tmp_enc)

qr = segno.make(download_url)
qr = segno.make(download_url, error="L")
qr.save("test.png")
pixels = Pixels.from_image_path("test.png")

typer.echo("\n✓ Upload complete!")
typer.echo(qr.terminal(compact=True))
typer.echo("✓ Upload complete!")
console.print(pixels)
typer.echo(f" Download URL : {download_url}")

if password:
Expand Down
4 changes: 4 additions & 0 deletions src/cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ dependencies = [
# Terminal QR-code rendering
"segno>=1.5.1",
"pydantic-settings>=2.12.0",
"resvg-py>=0.2.6",
"pillow>=12.1.1",
"rich>=14.3.2",
"rich-pixels>=3.0.1",
]


Expand Down
Binary file added src/cli/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added src/cli/test.txt
Empty file.
195 changes: 195 additions & 0 deletions src/cli/uv.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
{@render children?.()}
{#if showCloseButton}
<DialogPrimitive.Close
class="absolute end-4 top-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
class="absolute inset-e-4 top-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
>
<XIcon />
<span class="sr-only">Close</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
import favicon from '$lib/assets/logo.svg';
import { PUBLIC_INSTANCE_URL } from '#consts/urls';
import { SiGithub } from "@icons-pack/svelte-simple-icons";
import { SiGithub,SiBuymeacoffee,SiLiberapay,SiKofi, SiPatreon } from "@icons-pack/svelte-simple-icons";
import { env } from '$env/dynamic/public';

const { isAuthenticated, user: userData } = useAuth();

let { children } = $props();
Expand Down Expand Up @@ -61,7 +63,8 @@
icon: Link
}
];
const footerLinks = [
let footerLinks = $state(
[
{
href:'/speedtest',
name:"Speedtest",
Expand All @@ -82,7 +85,33 @@
name: 'Source',
icon: SiGithub
}
];
]
);

$effect(()=>{
type DonationKey = 'PUBLIC_BUY_ME_A_COFFEE' | 'PUBLIC_LIBERAPAY' | 'PUBLIC_KO_FI' | 'PUBLIC_PATREON';

interface DonationPlatform {
key: DonationKey;
name: string;
icon: any;
}

const donationPlatforms: DonationPlatform[] = [
{ key: 'PUBLIC_BUY_ME_A_COFFEE', name: "Support by buying a coffee", icon: SiBuymeacoffee },
{ key: 'PUBLIC_LIBERAPAY', name: "Support by Liberapay", icon: SiLiberapay },
{ key: 'PUBLIC_KO_FI', name: "Support by Ko-Fi", icon: SiKofi },
{ key: 'PUBLIC_PATREON', name: "Support by Patreon", icon: SiPatreon }
];
donationPlatforms.forEach(({ key, name, icon }) => {
// Cast key to ensure TS knows it exists on the env object
const href = (env as Record<string, string | undefined>)[key];

if (href) {
footerLinks.push({ href, name, icon });
}
});
})
</script>

<div class="relative flex min-h-svh min-w-screen flex-col overflow-hidden bg-background text-foreground">
Expand Down