diff --git a/.gitignore b/.gitignore index e6deb28..0fcd276 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .vscode main pdwebconf.toml -go.sum svelte/node_modules res/static/svelte/* diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ede3de1 --- /dev/null +++ b/go.sum @@ -0,0 +1,69 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70 h1:yRkXab8h+BAWEphLE0qexJVxIOdPgw+3T9VSLuyPXus= +github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70/go.mod h1:Ig5am30IOP/eqsjogI1TuSlOTIeTPHoMOpYYM1bisww= +github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3 h1:PfKr7anK3z4kLG9V6BbbKOVFhVaGEAJi4HxXCAa+QeU= +github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3/go.mod h1:jdnyerqAlXJJpQmpyrdmSYMitRaRZ8RejEXuXz6n5QY= +github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145 h1:2a8cFtVwEvK7NeimwAEoSUdf4hC80cXpnj3s4pHga+c= +github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145/go.mod h1:Ew6h8nlacK6H8aABMDUYN3uaO4Rpw2HLKQZ2ntEybqM= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= +github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8= +github.com/chris-ramon/douceur v0.2.0 h1:IDMEdxlEUUBYBKE4z/mJnFyVXox+MjuEVDJNN27glkU= +github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= +github.com/jhillyerd/enmime v0.8.4/go.mod h1:SWWlqKsXJMl00Nnuh04RSu6XoEo83B/VaujD/xzoBP0= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg= +github.com/microcosm-cc/bluemonday v1.0.4/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= +github.com/scylladb/gocql v1.5.0 h1:tWaA08A8IprjgtBNPTVn8RkdiwEFUc85VcLA0E8JjH0= +github.com/scylladb/gocql v1.5.0/go.mod h1:S154F0u6zQlF3JjuHAidQIExQf9H45yT8z68h0FQYdU= +github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 h1:3wPMTskHO3+O6jqTEXyFcsnuxMQOqYSaHsDxcbUXpqA= +golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= diff --git a/res/include/script/dependencies/drawGraph.js b/res/include/script/dependencies/drawGraph.js deleted file mode 100644 index 4252869..0000000 --- a/res/include/script/dependencies/drawGraph.js +++ /dev/null @@ -1,65 +0,0 @@ -Chart.defaults.global.defaultFontColor = "#b3b3b3"; -Chart.defaults.global.defaultFontSize = 15; -Chart.defaults.global.defaultFontFamily = "system-ui, sans-serif"; -Chart.defaults.global.maintainAspectRatio = false; -Chart.defaults.global.elements.point.radius = 0; -Chart.defaults.global.tooltips.mode = "index"; -Chart.defaults.global.tooltips.axis = "x"; -Chart.defaults.global.tooltips.intersect = false; -Chart.defaults.global.animation.duration = 500; -Chart.defaults.global.animation.easing = "linear"; - -function drawGraph(element, label, dataType) { - return new Chart( - element, - { - type: 'line', - data: { - datasets: [ - { - label: label, - backgroundColor: "#" + window.style.highlightColor, - borderWidth: 0, - lineTension: 0, - fill: true, - yAxisID: "ax_1" - } - ] - }, - options: { - legend: { display: false }, - scales: { - yAxes: [ - { - type: "linear", - display: true, - position: "left", - id: "ax_1", - ticks: { - callback: function (value, index, values) { - if (dataType == "bytes") { - return formatDataVolume(value, 3); - } - return formatNumber(value, 3); - }, - beginAtZero: true - }, - gridLines: { display: true }, - } - ], - xAxes: [ - { - ticks: { - sampleSize: 1, - padding: 4, - minRotation: 0, - maxRotation: 0 - }, - gridLines: { display: false } - } - ] - } - } - } - ); -} diff --git a/res/include/script/file_viewer/AbuseReportWindow.js b/res/include/script/file_viewer/AbuseReportWindow.js deleted file mode 100644 index 4eb00bb..0000000 --- a/res/include/script/file_viewer/AbuseReportWindow.js +++ /dev/null @@ -1,80 +0,0 @@ -function AbuseReportWindow(viewer) { - this.viewer = viewer - this.visible = false - this.modal = new Modal( - document.getElementById("file_viewer"), - () => { this.toggle() }, - "Report abuse", "650px", "auto", - ) - - this.btnReportAbuse = document.getElementById("btn_report_abuse") - this.btnReportAbuse.addEventListener("click", () => { this.toggle() }) - - let clone = document.getElementById("tpl_report_abuse_popup").content.cloneNode(true) - this.form = clone.querySelector(".abuse_type_form") - // this.emailField = clone.querySelector(".abuse_email_field") - this.notification = clone.querySelector(".abuse_report_notification") - this.modal.setBody(clone) - - this.form.addEventListener("submit", e => { this.submit(e) }) -} - -AbuseReportWindow.prototype.toggle = function () { - if (this.visible) { - this.modal.close() - this.btnReportAbuse.classList.remove("button_highlight") - this.visible = false - } else { - this.modal.open() - this.btnReportAbuse.classList.add("button_highlight") - this.visible = true - } -} - -AbuseReportWindow.prototype.notify = function (success, content) { - this.notification.style.display = "" - this.notification.classList = "abuse_report_notification " + (success ? "highlight_green" : "highlight_red") - this.notification.innerHTML = content -} - -AbuseReportWindow.prototype.submit = async function (e) { - e.preventDefault() - - let abuseType = "" - this.form.querySelectorAll('[name="abuse_type"]').forEach(elem => { - if (elem.checked) { - abuseType = elem.value - } - }) - - if (abuseType === "") { - this.notify(false, "Please select an abuse type") - return - } - - const form = new FormData() - form.append("type", abuseType) - // form.append("email", this.emailField.value) - - try { - const resp = await fetch( - this.viewer.file.get_href + "/report_abuse", - { method: "POST", body: form } - ); - if (resp.status >= 400) { - let json = await resp.json() - if (json.value === "resource_already_exists") { - throw "You have already reported this file" - } else if (json.value === "file_already_blocked") { - throw "This file has already been blocked" - } else if (json.value === "multiple_errors") { - throw json.errors[0].message - } - throw json.message - } - - this.notify(true, "Report has been sent") - } catch (err) { - this.notify(false, "Failed to send report: " + err) - } -} diff --git a/res/include/script/file_viewer/DetailsWindow.js b/res/include/script/file_viewer/DetailsWindow.js deleted file mode 100644 index 18d7b6b..0000000 --- a/res/include/script/file_viewer/DetailsWindow.js +++ /dev/null @@ -1,103 +0,0 @@ -function DetailsWindow(viewer) { - this.viewer = viewer - this.visible = false - this.file = null - this.graphsInitialized = false - this.graphViews = 0 - this.graphDownloads = 0 - this.modal = new Modal( - document.getElementById("file_viewer"), - () => { this.toggle() }, - "File Details", "1200px", "1000px", - ) - - let clone = document.getElementById("tpl_details_popup").content.cloneNode(true) - this.divFileDetails = clone.querySelector(".info_file_details") - this.modal.setBody(clone) - - this.btnDetails = document.getElementById("btn_details") - this.btnDetails.addEventListener("click", () => { this.toggle() }) -} - -DetailsWindow.prototype.toggle = function () { - if (this.visible) { - this.modal.close() - this.btnDetails.classList.remove("button_highlight") - this.visible = false - } else { - this.modal.open() - this.btnDetails.classList.add("button_highlight") - this.visible = true - - if (!this.graphsInitialized) { - this.renderGraphs() - this.graphsInitialized = true - } - this.updateGraph(this.file) - } -} - -DetailsWindow.prototype.setFile = function (file) { - this.file = file - let desc = "" - if (this.viewer.isList) { - desc = file.description - } - this.divFileDetails.innerHTML = `
- Charts rendered by the amazing Chart.js. -
- -File Shortcuts | |
c | = Copy URL of this page |
i | = Toggle details window (this window) (info) |
s | = Download the file you are currently viewing (save) |
q | = Close the window (quit) |
List Shortcuts | |
a or ← | = View previous item in list |
d or → | = View next item in list |
r | = Toggle shuffle (random) |
SHIFT + s | = Download all the files in the list as a zip archive |
- When you delete a file it cannot be recovered. - Nobody will be able to download it and the link will - stop working. The file will also disappear from any - lists it's contained in. -
-- You can embed pixeldrain's file viewer in your own web pages. We - have created a special HTML code which renders a minimalistic - version of the file viewer where the title bar is a bit thinner and - the toolbar is collapsed by default. -
-- Unless it was uploaded using a pixeldrain Pro account the embedded - file will also show advertisements. -
-- If you think this file violates pixeldrain's - content policy you can - report it for moderation with this form. You cannot report - copyright abuse with this form, send a formal DMCA notification - to the - abuse e-mail address - instead. -
- - - - -- On pixeldrain you can share your files with large or small - groups of people. The sky is the limit! -
- - - - - - - {{ if and .Other.FileAdsEnabled .Other.UserAdsEnabled }} - {{ template "analytics" }} - {{ template "floating_ads" . }} - {{ end }} - - -{{end}} diff --git a/webcontroller/file_viewer.go b/webcontroller/file_viewer.go index 9851d74..38d309d 100644 --- a/webcontroller/file_viewer.go +++ b/webcontroller/file_viewer.go @@ -2,7 +2,6 @@ package webcontroller import ( "fmt" - "math/rand" "net/http" "strings" "time" @@ -24,113 +23,19 @@ func browserCompat(ua string) bool { return strings.Contains(ua, "MSIE") || strings.Contains(ua, "Trident/7.0") } -type viewerData struct { - Type string // file or list - CaptchaKey string - ViewToken string - AdBannerType int - AdSkyscraperType string - AdFloaterType int - AdPopupType int - FileAdsEnabled bool - UserAdsEnabled bool - Embedded bool - APIResponse interface{} -} - -func (vd *viewerData) adType(files []pixelapi.ListFile) { - if len(files) == 0 { - return - } else if !vd.FileAdsEnabled || !vd.UserAdsEnabled { - return - } - - var avgSize int64 - for _, v := range files { - avgSize += v.Size - } - avgSize /= int64(len(files)) - - const ( - // Banners - none = 0 - aAds = 1 - patreon = 2 - adshares = 3 - amarulaSolutions = 4 - adMaven = 5 - adSterra = 6 - brave = 7 - pdpro1 = 8 - pdpro2 = 9 - pdpro3 = 10 - pdpro4 = 11 - clickAduBanner = 12 - amarulaElectronics = 13 - adsPlus = 14 - pixFuture = 15 - publisherrest1 = 16 - publisherrest2 = 17 - publisherrest3 = 18 - - // Skyscrapers - aAdsSkyscraper = "a-ads" - pixfutureSkyscraper = "pixfuture" - adsPlusSkyscraper = "adsplus" - adsharesSkyscraper = "adshares" - - // Floaters - // propellerFloat = 1 - // adSterraFloat = 2 - // adMavenFloat = 3 - - // Popunders - // clickAduPopup = 1 - // propellerPopup = 2 - ) - - // Intn returns a number up to n, but never n itself. So to get a random 0 - // or 1 we need to give it n=2. We can use this function to make other - // splits like 1/3 1/4, etc - - switch i := rand.Intn(20); i { - case 0: - vd.AdBannerType = publisherrest1 // 5%, total 5% - case 1: - vd.AdBannerType = publisherrest2 // 5%, total 10% - case 2: - vd.AdBannerType = publisherrest3 // 5%, total 15% - case 3, 4, 5: - vd.AdBannerType = brave // 15%, total 30% - case 6, 7, 8, 9, 10, 11, 12: - vd.AdBannerType = adsPlus // 35%, total 65% - case 13, 14, 15, 16, 17, 18, 19: - vd.AdBannerType = pixFuture // 35%, total 100% - default: - panic(fmt.Errorf("random number generator returned unrecognised number: %d", i)) - } - - switch i := rand.Intn(2); i { - case 0: - vd.AdSkyscraperType = aAdsSkyscraper - case 1: - vd.AdSkyscraperType = pixfutureSkyscraper - default: - panic(fmt.Errorf("random number generator returned unrecognised number: %d", i)) - } +type fileViewerData struct { + Type string `json:"type"` // file or list + APIResponse interface{} `json:"api_response"` + CaptchaKey string `json:"captcha_key"` + ViewToken string `json:"view_token"` + Embedded bool `json:"embedded"` + UserAdsEnabled bool `json:"user_ads_enabled"` } // ServeFileViewer controller for GET /u/:id func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - var err error if p.ByName("id") == "demo" { - wc.serveFileViewerDemo(w, r, 1, "a-ads") // Required for a-ads.com quality check - return - } else if p.ByName("id") == "adsplus" { - wc.serveFileViewerDemo(w, r, 14, "") - return - } else if p.ByName("id") == "pixfuture" { - wc.serveFileViewerDemo(w, r, 15, "") + wc.serveViewerDemo(w, r) // Required for a-ads.com quality check return } @@ -141,9 +46,9 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, return } + var err error var ids = strings.Split(p.ByName("id"), ",") - - templateData := wc.newTemplateData(w, r) + var templateData = wc.newTemplateData(w, r) var files []pixelapi.ListFile for _, id := range ids { @@ -166,13 +71,11 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, templateData.OGData = wc.metadataFromFile(files[0].FileInfo) - var vd = viewerData{ + var vd = fileViewerData{ CaptchaKey: wc.captchaKey(), ViewToken: wc.viewTokenOrBust(), - FileAdsEnabled: files[0].ShowAds, UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), } - vd.adType(files) if len(ids) > 1 { templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(files)) @@ -195,11 +98,6 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, templateData.Other = vd - var templateName = "file_viewer" - if browserCompat(r.UserAgent()) { - templateName = "file_viewer_compat" - } - for _, file := range files { if file.AbuseType != "" { w.WriteHeader(http.StatusUnavailableForLegalReasons) @@ -207,47 +105,25 @@ func (wc *WebController) serveFileViewer(w http.ResponseWriter, r *http.Request, } } + var templateName = "file_viewer_svelte" + if browserCompat(r.UserAgent()) { + templateName = "file_viewer_compat" + } + err = wc.templates.Get().ExecuteTemplate(w, templateName, templateData) if err != nil && !strings.Contains(err.Error(), "broken pipe") { log.Error("Error executing template file_viewer: %s", err) } } -// ServeFileViewerDemo is a dummy API response that responds with info about a -// non-existent demo file. This is required by the a-ads ad network to allow for -// automatic checking of the presence of the ad unit on this page. -func (wc *WebController) serveFileViewerDemo(w http.ResponseWriter, r *http.Request, banner int, scraper string) { - templateData := wc.newTemplateData(w, r) - templateData.Other = viewerData{ - Type: "file", - CaptchaKey: wc.captchaSiteKey, - AdBannerType: banner, // Always show a-ads on the demo page - AdSkyscraperType: scraper, - FileAdsEnabled: true, - UserAdsEnabled: true, - APIResponse: map[string]interface{}{ - "id": "demo", - "name": "Demo file", - "date_upload": "2017-01-01 12:34:56", - "date_lastview": "2017-01-01 12:34:56", - "size": 123456789, - "views": 1, - "bandwidth_used": 123456789, - "mime_type": "text/demo", - "description": "A file to demonstrate the viewer page", - "mime_image": "/res/img/mime/text.png", - "thumbnail": "/res/img/mime/text.png", - "abuse_type": "", - }, - } - err := wc.templates.Get().ExecuteTemplate(w, "file_viewer", templateData) - if err != nil && !strings.Contains(err.Error(), "broken pipe") { - log.Error("Error rendering demo file: %s", err) - } -} - -// ServeListViewer controller for GET /l/:id func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + // If the user agent is Wget we redirect it to the API so that the file can + // be downloaded directly + if strings.HasPrefix(r.UserAgent(), "Wget/") { + http.Redirect(w, r, "/api/list/"+p.ByName("id")+"/zip", http.StatusSeeOther) + return + } + var templateData = wc.newTemplateData(w, r) var list, err = templateData.PixelAPI.GetListID(p.ByName("id")) if err != nil { @@ -269,26 +145,19 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title) templateData.OGData = wc.metadataFromList(list) - var vd = viewerData{ + var vd = fileViewerData{ Type: "list", CaptchaKey: wc.captchaSiteKey, ViewToken: wc.viewTokenOrBust(), - FileAdsEnabled: list.Files[0].ShowAds, UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), APIResponse: list, } - vd.adType(list.Files) if _, ok := r.URL.Query()["embed"]; ok { vd.Embedded = true } templateData.Other = vd - var templateName = "file_viewer" - if browserCompat(r.UserAgent()) { - templateName = "file_viewer_compat" - } - for _, file := range list.Files { if file.AbuseType != "" { w.WriteHeader(http.StatusUnavailableForLegalReasons) @@ -296,8 +165,44 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request, } } + var templateName = "file_viewer_svelte" + if browserCompat(r.UserAgent()) { + templateName = "file_viewer_compat" + } + err = wc.templates.Get().ExecuteTemplate(w, templateName, templateData) if err != nil && !strings.Contains(err.Error(), "broken pipe") { log.Error("Error executing template file_viewer: %s", err) } } + +// ServeFileViewerDemo is a dummy API response that responds with info about a +// non-existent demo file. This is required by the a-ads ad network to allow for +// automatic checking of the presence of the ad unit on this page. +func (wc *WebController) serveViewerDemo(w http.ResponseWriter, r *http.Request) { + templateData := wc.newTemplateData(w, r) + templateData.Other = fileViewerData{ + Type: "file", + CaptchaKey: wc.captchaSiteKey, + UserAdsEnabled: true, + APIResponse: map[string]interface{}{ + "id": "demo", + "name": "Demo file", + "date_upload": "2017-01-01 12:34:56", + "date_lastview": "2017-01-01 12:34:56", + "size": 123456789, + "views": 1, + "bandwidth_used": 123456789, + "mime_type": "text/demo", + "description": "A file to demonstrate the viewer page", + "mime_image": "/res/img/mime/text.png", + "thumbnail": "/res/img/mime/text.png", + "abuse_type": "", + "show_ads": true, + }, + } + err := wc.templates.Get().ExecuteTemplate(w, "file_viewer_svelte", templateData) + if err != nil && !strings.Contains(err.Error(), "broken pipe") { + log.Error("Error rendering demo file: %s", err) + } +} diff --git a/webcontroller/file_viewer_svelte.go b/webcontroller/file_viewer_svelte.go deleted file mode 100644 index 621ff48..0000000 --- a/webcontroller/file_viewer_svelte.go +++ /dev/null @@ -1,196 +0,0 @@ -package webcontroller - -import ( - "fmt" - "net/http" - "strings" - "time" - - "fornaxian.tech/pixeldrain_api_client/pixelapi" - "github.com/Fornaxian/log" - "github.com/julienschmidt/httprouter" -) - -type fileViewerData struct { - Type string `json:"type"` // file or list - APIResponse interface{} `json:"api_response"` - CaptchaKey string `json:"captcha_key"` - ViewToken string `json:"view_token"` - Embedded bool `json:"embedded"` - UserAdsEnabled bool `json:"user_ads_enabled"` -} - -// ServeFileViewer controller for GET /u/:id -func (wc *WebController) serveSvelteFile(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - if p.ByName("id") == "demo" { - wc.serveSvelteViewerDemo(w, r) // Required for a-ads.com quality check - return - } - - // If the user agent is Wget we redirect it to the API so that the file can - // be downloaded directly - if strings.HasPrefix(r.UserAgent(), "Wget/") { - http.Redirect(w, r, "/api/file/"+p.ByName("id"), http.StatusSeeOther) - return - } - - var err error - var ids = strings.Split(p.ByName("id"), ",") - var templateData = wc.newTemplateData(w, r) - - var files []pixelapi.ListFile - for _, id := range ids { - inf, err := templateData.PixelAPI.GetFileInfo(id) - if err != nil { - if pixelapi.ErrIsServerError(err) { - wc.templates.Get().ExecuteTemplate(w, "500", templateData) - return - } - continue - } - files = append(files, pixelapi.ListFile{FileInfo: inf}) - } - - if len(files) == 0 { - w.WriteHeader(http.StatusNotFound) - wc.templates.Get().ExecuteTemplate(w, "file_not_found", templateData) - return - } - - templateData.OGData = wc.metadataFromFile(files[0].FileInfo) - - var vd = fileViewerData{ - CaptchaKey: wc.captchaKey(), - ViewToken: wc.viewTokenOrBust(), - UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), - } - - if len(ids) > 1 { - templateData.Title = fmt.Sprintf("%d files on pixeldrain", len(files)) - vd.Type = "list" - vd.APIResponse = pixelapi.ListInfo{ - Success: true, - Title: "Multiple files", - DateCreated: time.Now(), - Files: files, - } - } else { - templateData.Title = fmt.Sprintf("%s ~ pixeldrain", files[0].Name) - vd.Type = "file" - vd.APIResponse = files[0].FileInfo - } - - if _, ok := r.URL.Query()["embed"]; ok { - vd.Embedded = true - } - - templateData.Other = vd - - for _, file := range files { - if file.AbuseType != "" { - w.WriteHeader(http.StatusUnavailableForLegalReasons) - break - } - } - - var templateName = "file_viewer_svelte" - if browserCompat(r.UserAgent()) { - templateName = "file_viewer_compat" - } - - err = wc.templates.Get().ExecuteTemplate(w, templateName, templateData) - if err != nil && !strings.Contains(err.Error(), "broken pipe") { - log.Error("Error executing template file_viewer: %s", err) - } -} - -func (wc *WebController) serveSvelteList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { - // If the user agent is Wget we redirect it to the API so that the file can - // be downloaded directly - if strings.HasPrefix(r.UserAgent(), "Wget/") { - http.Redirect(w, r, "/api/list/"+p.ByName("id")+"/zip", http.StatusSeeOther) - return - } - - var templateData = wc.newTemplateData(w, r) - var list, err = templateData.PixelAPI.GetListID(p.ByName("id")) - if err != nil { - if err, ok := err.(pixelapi.Error); ok && err.Status == http.StatusNotFound { - w.WriteHeader(http.StatusNotFound) - wc.templates.Get().ExecuteTemplate(w, "list_not_found", templateData) - } else { - log.Error("API request error occurred: %s", err) - w.WriteHeader(http.StatusInternalServerError) - wc.templates.Get().ExecuteTemplate(w, "500", templateData) - } - return - } - if len(list.Files) == 0 { - w.WriteHeader(http.StatusNotFound) - wc.templates.Get().ExecuteTemplate(w, "list_not_found", templateData) - return - } - - templateData.Title = fmt.Sprintf("%s ~ pixeldrain", list.Title) - templateData.OGData = wc.metadataFromList(list) - var vd = fileViewerData{ - Type: "list", - CaptchaKey: wc.captchaSiteKey, - ViewToken: wc.viewTokenOrBust(), - UserAdsEnabled: !(templateData.Authenticated && templateData.User.Subscription.DisableAdDisplay), - APIResponse: list, - } - - if _, ok := r.URL.Query()["embed"]; ok { - vd.Embedded = true - } - templateData.Other = vd - - for _, file := range list.Files { - if file.AbuseType != "" { - w.WriteHeader(http.StatusUnavailableForLegalReasons) - break - } - } - - var templateName = "file_viewer_svelte" - if browserCompat(r.UserAgent()) { - templateName = "file_viewer_compat" - } - - err = wc.templates.Get().ExecuteTemplate(w, templateName, templateData) - if err != nil && !strings.Contains(err.Error(), "broken pipe") { - log.Error("Error executing template file_viewer: %s", err) - } -} - -// ServeFileViewerDemo is a dummy API response that responds with info about a -// non-existent demo file. This is required by the a-ads ad network to allow for -// automatic checking of the presence of the ad unit on this page. -func (wc *WebController) serveSvelteViewerDemo(w http.ResponseWriter, r *http.Request) { - templateData := wc.newTemplateData(w, r) - templateData.Other = fileViewerData{ - Type: "file", - CaptchaKey: wc.captchaSiteKey, - UserAdsEnabled: true, - APIResponse: map[string]interface{}{ - "id": "demo", - "name": "Demo file", - "date_upload": "2017-01-01 12:34:56", - "date_lastview": "2017-01-01 12:34:56", - "size": 123456789, - "views": 1, - "bandwidth_used": 123456789, - "mime_type": "text/demo", - "description": "A file to demonstrate the viewer page", - "mime_image": "/res/img/mime/text.png", - "thumbnail": "/res/img/mime/text.png", - "abuse_type": "", - "show_ads": true, - }, - } - err := wc.templates.Get().ExecuteTemplate(w, "file_viewer_svelte", templateData) - if err != nil && !strings.Contains(err.Error(), "broken pipe") { - log.Error("Error rendering demo file: %s", err) - } -}