diff --git a/res/template/fragments/page_wrap.html b/res/template/fragments/page_wrap.html index c99e4a9..ef6256d 100644 --- a/res/template/fragments/page_wrap.html +++ b/res/template/fragments/page_wrap.html @@ -23,7 +23,7 @@ API Acknowledgements Server Status - {{if eq .User.Subscription.DisableAdDisplay false}} + {{if eq .User.Subscription.ID ""}} Shopping discounts {{end}} diff --git a/svelte/src/admin_panel/Home.svelte b/svelte/src/admin_panel/Home.svelte index 0138e4d..1a6d710 100644 --- a/svelte/src/admin_panel/Home.svelte +++ b/svelte/src/admin_panel/Home.svelte @@ -5,14 +5,14 @@ import Chart from "../util/Chart.svelte"; let graphViews let graphBandwidth -let graphHotlink +let graphBandwidthPaid let graphTimeout = null let start_time = "" let end_time = "" let total_bandwidth = 0 let total_views = 0 -let total_hotlink = 0 +let total_bandwidth_paid = 0 const loadGraph = (minutes, interval, live) => { if (graphTimeout !== null) { clearTimeout(graphTimeout) } if (live) { @@ -44,17 +44,17 @@ const loadGraph = (minutes, interval, live) => { graphViews.chart().data.datasets[0].data = resp.views.amounts; graphBandwidth.chart().data.labels = resp.views.timestamps; graphBandwidth.chart().data.datasets[0].data = resp.bandwidth.amounts; - graphHotlink.chart().data.labels = resp.views.timestamps; - graphHotlink.chart().data.datasets[0].data = resp.direct_link_bandwidth.amounts; + graphBandwidthPaid.chart().data.labels = resp.views.timestamps; + graphBandwidthPaid.chart().data.datasets[0].data = resp.bandwidth_paid.amounts; graphViews.update() graphBandwidth.update() - graphHotlink.update() + graphBandwidthPaid.update() start_time = resp.views.timestamps[0] end_time = resp.views.timestamps.slice(-1)[0]; total_bandwidth = resp.bandwidth.amounts.reduce((acc, val) => acc + val) total_views = resp.views.amounts.reduce((acc, val) => acc + val) - total_hotlink = resp.direct_link_bandwidth.amounts.reduce((acc, val) => acc + val) + total_bandwidth_paid = resp.bandwidth_paid.amounts.reduce((acc, val) => acc + val) }) } @@ -141,13 +141,13 @@ onDestroy(() => {
- +
Total usage from {start_time} to {end_time}
{formatDataVolume(total_bandwidth, 3)} bandwidth, - {formatDataVolume(total_hotlink, 3)} hotlink bandwidth and + {formatDataVolume(total_bandwidth_paid, 3)} paid bandwidth and {formatThousands(total_views, 3)} views
diff --git a/svelte/src/file_viewer/DetailsWindow.svelte b/svelte/src/file_viewer/DetailsWindow.svelte index 52fe3d1..d739c62 100644 --- a/svelte/src/file_viewer/DetailsWindow.svelte +++ b/svelte/src/file_viewer/DetailsWindow.svelte @@ -45,6 +45,9 @@ let update_charts = () => { resp.bandwidth.amounts.forEach((val, idx) => { resp.bandwidth.amounts[idx] = Math.round(val / file.size); }); + resp.bandwidth_paid.amounts.forEach((val, idx) => { + resp.bandwidth.amounts[idx] += Math.round(val / file.size); + }); download_chart.chart().data.labels = resp.views.timestamps view_chart.chart().data.labels = resp.views.timestamps download_chart.chart().data.datasets[0].data = resp.bandwidth.amounts @@ -78,8 +81,20 @@ let update_charts = () => { {formatDataVolume(file.size, 4)} ( {formatThousands(file.size)} B ) - Bandwidth - {formatDataVolume(file.bandwidth_used, 4)} ( {formatThousands(file.bandwidth_used)} B ) + Free bandwidth used + + {formatDataVolume(file.bandwidth_used, 4)} + ( {formatThousands(file.bandwidth_used)} B ), + {(file.bandwidth_used/file.size).toFixed(1)}x file size + + + + Premium bandwidth used + + {formatDataVolume(file.bandwidth_used_paid, 4)} + ( {formatThousands(file.bandwidth_used_paid)} B ), + {(file.bandwidth_used_paid/file.size).toFixed(1)}x file size + Unique downloads diff --git a/svelte/src/file_viewer/FileStats.svelte b/svelte/src/file_viewer/FileStats.svelte index 76fc493..ca38b24 100644 --- a/svelte/src/file_viewer/FileStats.svelte +++ b/svelte/src/file_viewer/FileStats.svelte @@ -50,7 +50,7 @@ let update_stats = (id) => { if (file.size === 0) { downloads = j.downloads } else { - downloads = Math.round(j.bandwidth / file.size) + downloads = Math.round((j.bandwidth + j.bandwidth_paid) / file.size) } } socket.onerror = err => { diff --git a/svelte/src/file_viewer/FileViewer.svelte b/svelte/src/file_viewer/FileViewer.svelte index 7b540a5..e0d7c5d 100644 --- a/svelte/src/file_viewer/FileViewer.svelte +++ b/svelte/src/file_viewer/FileViewer.svelte @@ -437,7 +437,7 @@ const keyboard_event = evt => { - {#if current_file.show_ads && window.viewer_data.user_ads_enabled} + {#if current_file.show_ads} {skyscraper_visible = e.detail}}> {/if} diff --git a/svelte/src/user_home/Home.svelte b/svelte/src/user_home/Home.svelte index 3228369..c70a3ac 100644 --- a/svelte/src/user_home/Home.svelte +++ b/svelte/src/user_home/Home.svelte @@ -9,13 +9,13 @@ import Euro from "../util/Euro.svelte" let graph_view = null let graph_download = null let graph_bandwidth = null -let graph_direct_link = null +let graph_transfer_paid = null let time_start = "" let time_end = "" let total_views = 0 let total_downloads = 0 let total_bandwidth = 0 -let total_direct_link = 0 +let total_transfer_paid = 0 let load_graph = (graph, stat, minutes, interval) => { let today = new Date() @@ -54,8 +54,8 @@ let load_graph = (graph, stat, minutes, interval) => { total_downloads = total; } else if (stat == "bandwidth") { total_bandwidth = total; - } else if (stat == "direct_bandwidth") { - total_direct_link = total; + } else if (stat == "transfer_paid") { + total_transfer_paid = total; } }).catch(e => { console.error("Error requesting time series: " + e); @@ -75,11 +75,12 @@ let update_graphs = (minutes, interval, live) => { load_graph(graph_view, "views", minutes, interval) load_graph(graph_download, "downloads", minutes, interval) load_graph(graph_bandwidth, "bandwidth", minutes, interval) - load_graph(graph_direct_link, "direct_bandwidth", minutes, interval) + load_graph(graph_transfer_paid, "transfer_paid", minutes, interval) load_direct_bw() } -let direct_link_bandwidth_used = 0 +let transfer_cap = 0 +let transfer_used = 0 let storage_space_used = 0 let load_direct_bw = () => { let today = new Date() @@ -87,7 +88,7 @@ let load_direct_bw = () => { start.setDate(start.getDate() - 30) fetch( - window.api_endpoint + "/user/time_series/direct_bandwidth" + + window.api_endpoint + "/user/time_series/transfer_paid" + "?start=" + start.toISOString() + "&end=" + today.toISOString() + "&interval=60" @@ -96,7 +97,7 @@ let load_direct_bw = () => { return resp.json(); }).then(resp => { let total = resp.amounts.reduce((accum, val) => accum += val, 0); - direct_link_bandwidth_used = total + transfer_used = total storage_space_used = window.user.storage_space_used }).catch(e => { console.error("Error requesting time series: " + e); @@ -104,6 +105,14 @@ let load_direct_bw = () => { } onMount(() => { + if (window.user.subscription.monthly_transfer_cap > 0) { + transfer_cap = window.user.subscription.monthly_transfer_cap + } else if (window.user.monthly_transfer_cap > 0) { + transfer_cap = window.user.monthly_transfer_cap + } else { + transfer_cap = -1 + } + update_graphs(1440, 1, true); }) onDestroy(() => { @@ -128,14 +137,6 @@ onDestroy(() => {
  • Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
  • -
  • - Advertisements when you view files: - {#if window.user.subscription.disable_ad_display}No{:else}Yes{/if} -
  • -
  • - Advertisements when others view your files: - {#if window.user.subscription.disable_ads_on_files}No{:else}Yes{/if} -
  • {#if window.user.subscription.file_expiry_days > 0}
  • Files expire after {window.user.subscription.file_expiry_days} days
  • {:else} @@ -156,10 +157,10 @@ onDestroy(() => { {/if} - {#if window.user.subscription.direct_linking_bandwidth === -1} - Hotlink bandwidth used in the last 30 days: {formatDataVolume(direct_link_bandwidth_used, 3)}
    + {#if transfer_cap === -1} + Paid transfers in the last 30 days: {formatDataVolume(transfer_used, 3)}
    {:else} - + {/if}

    Exports

    @@ -224,8 +225,18 @@ onDestroy(() => { {formatThousands(total_views)} views, {formatThousands(total_downloads)} downloads, {formatDataVolume(total_bandwidth, 3)} bandwidth and - {formatDataVolume(total_direct_link, 3)} direct link bandwidth + {formatDataVolume(total_transfer_paid, 3)} paid transfers +
    +

    Paid transfers

    +

    + A paid transfer is when a file is downloaded using the data cap on + your subscription plan. These can be files you downloaded from other + people, or other people downloading your files if you have bandwidth + sharing enabled. +

    +
    +

    Views

    @@ -255,17 +266,4 @@ onDestroy(() => {

    -
    -

    Hotlink bandwidth

    -

    - When a file is downloaded without going through pixeldrain's - download page it counts as a hotlink. Because hotlinking costs us - bandwidth and doesn't generate any ad revenue we have to limit it. - When your hotlink bandwidth runs out people will be asked to do a - test before they can download your files. See our - subscription options to get more hotlink - bandwidth. -

    -
    - diff --git a/svelte/src/user_home/HotlinkProgressBar.svelte b/svelte/src/user_home/HotlinkProgressBar.svelte index c393c97..46864f6 100644 --- a/svelte/src/user_home/HotlinkProgressBar.svelte +++ b/svelte/src/user_home/HotlinkProgressBar.svelte @@ -8,7 +8,7 @@ $: frac = used / total
    - Hotlink bandwidth: + Paid transfers: {formatDataVolume(used, 3)} out of {formatDataVolume(total, 3)} @@ -20,10 +20,9 @@ $: frac = used / total {#if frac > 0.99}
    - You have used all of your hotlink bandwidth. Other people won't - be able to download your files directly from the API anymore. - Downloads will have to go through the file viewer page. Please - upgrade to a higher support tier to continue hotlinking files: + You have used all of your data cap. People can still download your + files, but not directly from the API anymore. The file viewer shows + ads on your files and download speeds are limited.
    Upgrade options @@ -31,12 +30,10 @@ $: frac = used / total
    {:else if frac > 0.8} diff --git a/svelte/src/user_home/Subscription.svelte b/svelte/src/user_home/Subscription.svelte index 9b867dd..b9b8e4a 100644 --- a/svelte/src/user_home/Subscription.svelte +++ b/svelte/src/user_home/Subscription.svelte @@ -3,15 +3,20 @@ import Spinner from "../util/Spinner.svelte"; import Euro from "../util/Euro.svelte" let loading = false +let subscription = window.user.subscription.id +let hotlinking = window.user.hotlinking_enabled +let transfer_cap = window.user.monthly_transfer_cap / 1e12 let result = "" let result_success = false -const update_subscription = async name => { +const update_subscription = async () => { loading = true const form = new FormData() - form.append("subscription", name) + form.append("subscription", subscription) + form.append("hotlinking_enabled", hotlinking) + form.append("transfer_cap", transfer_cap*1e12) try { const resp = await fetch( window.api_endpoint+"/user/subscription", @@ -62,97 +67,135 @@ const update_subscription = async name => { balance to activate the subscription again.

    - {#if result !== ""} -
    - {result} +

    Prepaid plans

    + {#if window.user.subscription.type === "patreon"} +

    Prepaid subscriptions are not available for Patreon supporters.

    + {:else} + {#if result !== ""} +
    + {result} +
    + {/if} + +
    +
    +
    + Prepaid
    + {#if subscription === "prepaid"} + Currently active + {:else} + + {/if} +
    +
    +
      +
    • Base price of €1 per month
    • +
    • €4 per TB per month for storage
    • +
    • €2 per TB for data transfer
    • +
    • Files never expire as long as subscription is active
    • +
    +
    +
    +
    +
    + 120 days storage
    + {#if subscription === "prepaid_temp_storage_120d"} + Currently active + {:else} + + {/if} +
    +
    +
      +
    • Base price of €1 per month
    • +
    • €2 per TB per month for storage
    • +
    • €2 per TB for data transfer
    • +
    • Files expire 120 days after the last time they're viewed
    • +
    +
    +
    +
    +
    + 60 days storage
    + {#if subscription === "prepaid_temp_storage_60d"} + Currently active + {:else} + + {/if} +
    +
    +
      +
    • Base price of €1 per month
    • +
    • €1 per TB per month for storage
    • +
    • €2 per TB for data transfer
    • +
    • Files expire 60 days after the last time they're viewed
    • +
    +
    +
    +
    +
    + Free
    + {#if subscription === ""} + Currently active + {:else} + + {/if} +
    +
    +
      +
    • Standard free plan, files expire after 30 days.
    • +
    +
    +
    {/if} -
    -
    -
    - Prepaid
    - {#if window.user.subscription.id === "prepaid"} - Currently active - {:else} - - {/if} -
    -
    -
      -
    • Base price of €2 per month (includes all the benefits of the Pro plan)
    • -
    • €4 per TB per month for storage
    • -
    • €2 per TB for hotlink bandwidth
    • -
    • All advertisements disabled
    • -
    • No rate limit, your files will download at the highest speed possible
    • -
    -
    -
    -
    -
    - Just storage
    - {#if window.user.subscription.id === "prepaid_storage"} - Currently active - {:else} - - {/if} -
    -
    -
      -
    • Base price of €1 per month
    • -
    • €4 per TB per month for storage
    • -
    • 100 GB of hotlink bandwidth per month
    • -
    • You don't see ads, but people downloading your files do see ads
    • -
    -
    -
    -
    -
    - Temporary storage
    - {#if window.user.subscription.id === "prepaid_storage_temp"} - Currently active - {:else} - - {/if} -
    -
    -
      -
    • Base price of €1 per month
    • -
    • €2 per TB per month for storage
    • -
    • 100 GB of hotlink bandwidth per month
    • -
    • You don't see ads, but people downloading your files do see ads
    • -
    • Files expire 90 days after the last time they're viewed
    • -
    -
    -
    -
    -
    - Free
    - {#if window.user.subscription.id === ""} - Currently active - {:else} - - {/if} -
    -
    -
      -
    • Standard free plan, files expire after 30 days.
    • -
    -
    -
    -
    +

    Bandwidth sharing

    + + {#if hotlinking} + + {:else} + + {/if} +

    + When bandwidth sharing is enabled all the bandwidth that your files + use will be subtracted from your data cap. Advertisements will be + disabled on the download pages for your files and download speed + will be unlimited. The rate limiting captcha for files is also + disabled when bandwidth sharing is on. You can directly embed your + file's download link anywhere, you don't need to use the file viewer + page. +

    + +

    Bill shock limit

    + Billshock limit in terabytes per month. Set to 0 to disable
    + TB + +

    + The billshock limit limits how much bandwidth your account can use + in a 30 day window. When this limit is reached files will show ads + again and can only be downloaded from the file viewer page. This is + mostly useful for prepaid plans, but it works for patreon plans too. + Set to 0 to disable the limit. +

    @@ -204,4 +247,11 @@ const update_subscription = async name => { .feat_table > div > div.round_tr { border-top-right-radius: 0.5em; } .feat_table > div > div.round_br { border-bottom-right-radius: 0.5em; } +.green { + color: var(--highlight_color); +} +.red { + color: var(--danger_color); +} + diff --git a/webcontroller/file_viewer.go b/webcontroller/file_viewer.go index fb39c49..d3f9ebf 100644 --- a/webcontroller/file_viewer.go +++ b/webcontroller/file_viewer.go @@ -74,7 +74,7 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, var vd = fileViewerData{ CaptchaKey: wc.captchaKey(), ViewToken: wc.viewTokenOrBust(), - UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), + UserAdsEnabled: templateData.User.Subscription.ID == "", } if len(ids) > 1 { @@ -149,7 +149,7 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, Type: "list", CaptchaKey: wc.captchaSiteKey, ViewToken: wc.viewTokenOrBust(), - UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), + UserAdsEnabled: templateData.User.Subscription.ID == "", APIResponse: list, }