Support downloading files from zip files in filesystem

This commit is contained in:
2024-02-16 18:02:51 +01:00
parent a4c5b97cdf
commit 68ef84b1e7
5 changed files with 131 additions and 59 deletions

View File

@@ -46,14 +46,11 @@ const update_base = async base => {
transfer_used = j.transfer_free + j.transfer_paid
}
socket.onerror = err => {
if (socket === null) {
return
}
console.error("WS error", err)
socket.close()
socket = null
error_msg = "failed to get stats, retrying..."
close_socket()
window.setTimeout(() => {
if (socket === null) {
update_base(base)

View File

@@ -37,30 +37,35 @@ const add_styles = (style, properties) => {
if (properties.brand_input_color) {
style.input_background = properties.brand_input_color
style.input_hover_background = properties.brand_input_color
style.input_text = add_light(properties.brand_input_color, 70)
style.input_text = add_contrast(properties.brand_input_color, 70)
}
if (properties.brand_highlight_color) {
style.highlight_color = properties.brand_highlight_color
style.highlight_background = properties.brand_highlight_color
style.highlight_text_color = add_light(properties.brand_highlight_color, 70)
style.link_color = properties.brand_highlight_color
style.highlight_text_color = add_contrast(properties.brand_highlight_color, 70)
// If we have a body colour to compare it to we use the highlight colour
// to generate the link colour
if (properties.brand_body_color) {
style.link_color = generate_link_color(properties.brand_highlight_color, properties.brand_body_color)
}
}
if (properties.brand_danger_color) {
style.danger_color = properties.brand_danger_color
style.danger_text_color = add_light(properties.brand_danger_color, 70)
style.danger_text_color = add_contrast(properties.brand_danger_color, 70)
}
if (properties.brand_background_color) {
style.background_color = properties.brand_background_color
style.background = properties.brand_background_color
style.background_text_color = add_light(properties.brand_background_color, 70)
style.background_text_color = add_contrast(properties.brand_background_color, 70)
style.background_pattern_color = properties.brand_background_color
}
if (properties.brand_body_color) {
style.body_color = properties.brand_body_color
style.body_background = properties.brand_body_color
style.body_text_color = add_light(properties.brand_body_color, 70)
style.body_text_color = add_contrast(properties.brand_body_color, 70)
style.shaded_background = set_alpha(properties.brand_body_color, 0.8)
style.separator = add_light(properties.brand_body_color, 5)
style.separator = add_contrast(properties.brand_body_color, 6)
style.shadow_color = darken(properties.brand_body_color, 0.8)
}
if (properties.brand_card_color) {
@@ -74,7 +79,7 @@ const add_styles = (style, properties) => {
}
}
const add_light = (color, amt) => {
const add_contrast = (color, amt) => {
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
// If the lightness is less than 40 it is considered a dark colour. This
// threshold is 40 instead of 50 because overall dark text is more legible
@@ -99,3 +104,17 @@ const set_alpha = (color, amt) => {
rgb.push(amt)
return "rgba(" + rgb.join(", ") + ")"
}
const generate_link_color = (link_color, body_color) => {
let link = rgb2hsl(parse(link_color))
let body = rgb2hsl(parse(body_color))
// If the body and link colours are both dark we lighten the link, and the
// other way around too
if (body[2] < 50 && link[2] < 50) {
link[2] = link[2] + 40 // Dark color, add lightness
} else if (body[2] > 50 && link[2] > 50) {
link[2] = link[2] - 40 // Light color, remove lightness
}
return rgb2hex(hsl2rgb(link)) // Convert back to hex
}

View File

@@ -119,6 +119,76 @@ const copy_magnet = () => {
</button>
</IconBlock>
<TextBlock>
<details>
<summary>How do I download this? (expand for more information)</summary>
<p>
This is a torrent file, which means you will need a torrent client to
download it. Here are some good torrent clients for various platforms:
</p>
<ul>
<li><a href="https://transmissionbt.com/download">Transmission</a> (Linux, Mac, Windows)</li>
<li><a href="https://www.qbittorrent.org/download">qBittorrent</a> (Linux, Mac, Windows)</li>
<li><a href="https://play.google.com/store/apps/details?id=org.proninyaroslav.libretorrent">LibreTorrent</a> (Android)</li>
</ul>
<p>
After installing your torrent client you will be able to use the
<a href={magnet}><Magnet/> Open magnet link</a>
button to download the files in your torrent client.
</p>
<h3>What is a torrent?</h3>
<p>
<a href="https://wikipedia.org/wiki/BitTorrent">BitTorrent</a> is a
peer-to-peer network for sharing files. This torrent file does not
actually contain the files listed below, instead it contains
instructions for your torrent client to download the files from
other people who happen to be downloading the same files currently.
This means that instead of connecting to a single server (like
pixeldrain), you will be connecting to other people on the internet
to download these files.
</p>
<p>
Torrents are a highly efficient and free method of transferring
files over the internet. Since the bandwidth is shared directly
between users there is no need for expensive servers to host the
files for you.
</p>
<h3>Is this safe?</h3>
<p>
Your torrent client will make sure that the files you receive from
your peers are actually what they say it is. This makes it just as
safe as any other form of downloading. Like always when downloading
files you still need to be aware of what you are downloading. Don't
just blindly trust any file anyone sends you.
</p>
<h3>Is it private?</h3>
<p>
When downloading a torrent file you will be part of the so-called
'torrent swarm'. Anyone in the swarm can see each other's IP
addresses. This is not a bad thing on its own, but there a few cases
in which this can be abused.
</p>
<p>
Anyone in the swarm will be able to see what you are downloading,
even across different torrents. This is something to keep in mind
when downloading torrents. If someone can link your IP address to
your identity then there are ways to find out which files you have
downloaded in the past (provided that your IP address has not
changed since then).
</p>
<p>
If you are downloading copyrighted material (which I do not condone)
then rightsholders will be able to see your IP address. In most
cases this is not a problem because your ISP will still protect your
identity. But there are some countries (notably the USA) where your
ISP will not respect your right to privacy and the rightsholder will
be able to contact you. If this worries you then you should look
into VPN services to protect your privacy, like <a
href="https://mullvad.net">Mullvad</a>.
</p>
</details>
</TextBlock>
{#if status === "finished"}
<TextBlock>
<h2>Files in this torrent</h2>

View File

@@ -1,7 +1,7 @@
<script>
import { createEventDispatcher } from "svelte";
import { formatDataVolume, formatDate } from "../../util/Formatting.svelte"
import ZipItem from "./ZipItem.svelte";
import ZipItem from "../../file_viewer/viewers/ZipItem.svelte";
import IconBlock from "../../file_viewer/viewers/IconBlock.svelte";
import TextBlock from "../../file_viewer/viewers/TextBlock.svelte";
import { fs_node_icon, fs_path_url } from "../FilesystemUtil";
@@ -18,10 +18,17 @@ let zip = {
}
let uncomp_size = 0
let comp_ratio = 0
let archive_type = ""
export const update = async () => {
dispatch("loading", true)
if (state.base.file_type === "application/zip") {
archive_type = "zip"
} else if (state.base.file_type === "application/x-7z-compressed") {
archive_type = "7z"
}
try {
let resp = await fetch(fs_path_url(state.base.path)+"?zip_info")
@@ -32,6 +39,13 @@ export const update = async () => {
zip = await resp.json()
// Check if the zip has the property which allows separate files to be
// downloaded. If so then we set the download URL for each file
if (zip.properties && zip.properties.includes("read_individual_files")) {
// Set the download URL for each file in the zip
recursive_set_url(fs_path_url(state.base.path)+"?zip_file=", zip)
}
uncomp_size = recursive_size(zip)
comp_ratio = (uncomp_size / state.base.file_size)
} catch (err) {
@@ -43,6 +57,16 @@ export const update = async () => {
status = "finished"
}
const recursive_set_url = (parent_path, file) => {
file.download_url = parent_path
if (file.children) {
Object.entries(file.children).forEach(child => {
recursive_set_url(file.download_url + "/" + child[0], child[1])
});
}
}
const recursive_size = (file) => {
let size = file.size
@@ -64,8 +88,14 @@ const recursive_size = (file) => {
<h1>{state.base.name}</h1>
<IconBlock icon_href={fs_node_icon(state.base, 256, 256)}>
{#if archive_type === "7z"}
This is a 7-zip archive. You will need
<a href="https://www.7-zip.org/">7-zip</a> or compatible software to
extract it<br/>
{/if}
Compressed size: {formatDataVolume(state.base.file_size, 3)}<br/>
Uncompressed size: {formatDataVolume(uncomp_size, 3)} (Ratio: {comp_ratio.toFixed(2)}x)<br/>
Uncompressed size: {formatDataVolume(zip.size, 3)} (Ratio: {comp_ratio.toFixed(2)}x)<br/>
Uploaded on: {formatDate(state.base.created, true, true, true)}
<br/>
<button class="button_highlight" on:click={() => {dispatch("download")}}>

View File

@@ -1,44 +0,0 @@
<script>
import { formatDataVolume } from "../../util/Formatting.svelte";
export let item = {
size: 0,
children: null,
}
</script>
<!-- First get directories and render them as details collapsibles -->
{#each Object.entries(item.children) as [name, child]}
{#if child.children}
<details>
<summary>
{name} ({formatDataVolume(child.size, 3)})
</summary>
<svelte:self item={child}></svelte:self>
</details>
{/if}
{/each}
<!-- Then get files and render them as list items -->
<ul>
{#each Object.entries(item.children) as [name, child]}
{#if !child.children}
<li>
{name} ({formatDataVolume(child.size, 3)})<br/>
</li>
{/if}
{/each}
</ul>
<style>
details {
padding-left: 12px;
border: none;
border-left: 2px solid var(--separator);
}
ul {
margin: 0;
padding-left: 30px;
border-left: 2px solid var(--separator);
}
</style>