diff --git a/go.mod b/go.mod
index 944be5d..ed98957 100644
--- a/go.mod
+++ b/go.mod
@@ -6,24 +6,10 @@ require (
fornaxian.com/pixeldrain-api v0.0.0-20191216095319-0533f903c681
github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70
github.com/Fornaxian/log v0.0.0-20190617093801-1c7ce9a7c9b3
+ github.com/Fornaxian/pd_mime_type v0.0.0-20200204165508-2815edf3a145
github.com/google/uuid v1.1.1
- github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de // indirect
github.com/julienschmidt/httprouter v1.3.0
- github.com/k0kubun/pp v3.0.1+incompatible // indirect
- github.com/kisielk/gotool v1.0.0 // indirect
- github.com/mattn/go-colorable v0.1.4 // indirect
- github.com/mattn/go-isatty v0.0.11 // indirect
github.com/microcosm-cc/bluemonday v1.0.2
- github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86 // indirect
- github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab // indirect
- github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
- github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
- github.com/spf13/cobra v0.0.5 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8
- golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 // indirect
- golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 // indirect
- golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2 // indirect
gopkg.in/russross/blackfriday.v2 v2.0.0
)
diff --git a/go.sum b/go.sum
index 0e9f7da..569b4b2 100644
--- a/go.sum
+++ b/go.sum
@@ -10,6 +10,10 @@ github.com/Fornaxian/config v0.0.0-20180915150834-ac41cf746a70 h1:yRkXab8h+BAWEp
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-20200204164318-fc5d8b4479f9 h1:8cg0suW9Ny88xGYnaFyfXG5CH7Vxu8jm8PAwnZM4JOk=
+github.com/Fornaxian/pd_mime_type v0.0.0-20200204164318-fc5d8b4479f9/go.mod h1:Ew6h8nlacK6H8aABMDUYN3uaO4Rpw2HLKQZ2ntEybqM=
+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/Fornaxian/unifilter v0.0.0-20180623154047-e65e144d5942/go.mod h1:ofV5syadd2nI4gOc/rP1yPnXkARgm+E1D/U38mbUj44=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -17,6 +21,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/threefish v0.0.0-20120919164726-3ecf4c494abf/go.mod h1:bXVurdTuvOiJu7NHALemFe0JMvC2UmwYHW+7fcZaZ2M=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
@@ -25,6 +30,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de h1:F7WD09S8QB4LrkEpka0dFPLSotH11HRpCsLIbIcJ7sU=
@@ -45,6 +51,9 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
+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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -67,9 +76,12 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
+github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
@@ -86,7 +98,9 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8 h1:gw/M1/pCu7oELGHZ6rvktNmMbdWhf9kHc7WYrbLeKdo=
github.com/timakin/gonvert v0.0.0-20170112000238-5dce59dbd0d8/go.mod h1:oqLl90kSlp4+8wMQKql9ZdQGa4/5pVCxOOpTVWkoyV0=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
@@ -104,6 +118,7 @@ gitlab.com/NebulousLabs/threadgroup v0.0.0-20180716154133-88a11db9e46c/go.mod h1
gitlab.com/NebulousLabs/writeaheadlog v0.0.0-20190703190009-cb822c37bc94/go.mod h1:Lhpa9AcbWcYKcc4amZsOHqJdQglnkWrGuUI68XC7U2Q=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
@@ -112,13 +127,17 @@ golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9Q
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -135,11 +154,24 @@ golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2 h1:FAGfnR+fyptW02iTeG8Lytc+6v8yqyQJIx/JMZhMA5M=
golang.org/x/tools v0.0.0-20200114052453-d31a08c2edf2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130224948-02f1738cbe39 h1:5ERHXLQfA0b8cHOwaOfWaaGekrA4+Ka/N74zilLnsIk=
+golang.org/x/tools v0.0.0-20200130224948-02f1738cbe39/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74 h1:KW20qMcLRWuIgjdCpHFJbVZA7zsDKtFXPNcm7/eI5ZA=
+golang.org/x/tools/gopls v0.3.0 h1:l9KKK1/n6CIbfgaUvHBWAvCfOxcl1N+KSOK79OlPIao=
+golang.org/x/tools/gopls v0.3.0/go.mod h1:vvBkm7WBjHNudDeK7Sg7HeR+sKt6yp5TD/4NQaTZzRs=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/russross/blackfriday.v2 v2.0.0 h1:+FlnIV8DSQnT7NZ43hcVKcdJdzZoeCmJj4Ql8gq5keA=
gopkg.in/russross/blackfriday.v2 v2.0.0/go.mod h1:6sSBNz/GtOm/pJTuh5UmBK2ZHfmnxGbl2NZg1UliSOI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+mvdan.cc/xurls/v2 v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA=
+mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E=
diff --git a/pixelapi/pixelapi.go b/pixelapi/pixelapi.go
index f7cdd3f..78ca2f6 100644
--- a/pixelapi/pixelapi.go
+++ b/pixelapi/pixelapi.go
@@ -7,11 +7,12 @@ import (
"net/http"
"net/url"
"strings"
+ "time"
"github.com/Fornaxian/log"
)
-var client = &http.Client{}
+var client = &http.Client{Timeout: time.Minute * 5}
// PixelAPI is the Pixeldrain API client
type PixelAPI struct {
diff --git a/res/include/script/dependencies/util.js b/res/include/script/dependencies/util.js
index f0694c7..769ae7f 100644
--- a/res/include/script/dependencies/util.js
+++ b/res/include/script/dependencies/util.js
@@ -22,6 +22,17 @@ function addUploadHistory(fileID) {
localStorage.setItem("uploaded_files", fileID + "," + uploads);
}
+function printDate(date, hours, minutes, seconds) {
+ let dateStr = date.getFullYear()
+ +"-"+("00"+(date.getMonth()+1)).slice(-2)
+ +"-"+("00"+date.getDate()).slice(-2)
+
+ if (hours) { dateStr += " "+("00"+date.getHours()).slice(-2) }
+ if (minutes) { dateStr += ":"+("00"+date.getMinutes()).slice(-2) }
+ if (seconds) { dateStr += ":"+("00"+date.getMinutes()).slice(-2) }
+ return dateStr
+}
+
function copyText(text) {
// Create a textarea to copy the text from
let ta = document.createElement("textarea");
diff --git a/res/include/script/file_manager/DirectoryElement.js b/res/include/script/file_manager/DirectoryElement.js
index b9f544a..7c8c994 100644
--- a/res/include/script/file_manager/DirectoryElement.js
+++ b/res/include/script/file_manager/DirectoryElement.js
@@ -190,12 +190,7 @@ DirectoryElement.prototype.createFileButton = function(file, index) {
let cell = document.createElement("div")
cell.style.width = this.fieldDateWidth
let label = document.createElement("span")
- let date = new Date(file.dateCreated)
- label.innerText = date.getFullYear()
- +"-"+("00"+(date.getMonth()+1)).slice(-2)
- +"-"+("00"+date.getDate()).slice(-2)
- +" "+("00"+date.getHours()).slice(-2)
- +":"+("00"+date.getMinutes()).slice(-2)
+ label.innerText = printDate(new Date(file.dateCreated), true, true, false)
cell.appendChild(label)
el.appendChild(cell)
}
diff --git a/res/include/script/file_viewer/DetailsWindow.js b/res/include/script/file_viewer/DetailsWindow.js
index 5dbb51f..66325e2 100644
--- a/res/include/script/file_viewer/DetailsWindow.js
+++ b/res/include/script/file_viewer/DetailsWindow.js
@@ -1,86 +1,86 @@
function DetailsWindow(viewer) {
- this.viewer = viewer;
- this.visible = false;
- this.fileID = "";
- this.graph = 0;
+ this.viewer = viewer
+ this.visible = false
+ this.fileID = ""
+ this.graph = 0
- this.divPopup = document.getElementById("details_popup");
- this.btnDetails = document.getElementById("btn_details");
- this.btnCloseDetails = document.getElementById("btn_close_details");
- this.divFileDetails = document.getElementById("info_file_details");
+ this.divPopup = document.getElementById("details_popup")
+ this.btnDetails = document.getElementById("btn_details")
+ this.btnCloseDetails = document.getElementById("btn_close_details")
+ this.divFileDetails = document.getElementById("info_file_details")
- this.btnDetails.addEventListener("click", () => { this.toggle(); });
- this.btnCloseDetails.addEventListener("click", () => { this.toggle(); });
+ this.btnDetails.addEventListener("click", () => { this.toggle() })
+ this.btnCloseDetails.addEventListener("click", () => { this.toggle() })
}
DetailsWindow.prototype.toggle = function() {
if (this.visible) {
- this.divPopup.style.opacity = "0";
- this.divPopup.style.visibility = "hidden";
- this.btnDetails.classList.remove("button_highlight");
- this.visible = false;
+ this.divPopup.style.opacity = "0"
+ this.divPopup.style.visibility = "hidden"
+ this.btnDetails.classList.remove("button_highlight")
+ this.visible = false
} else {
- this.divPopup.style.opacity = "1";
- this.divPopup.style.visibility = "visible";
- this.btnDetails.classList.add("button_highlight");
- this.visible = true;
+ this.divPopup.style.opacity = "1"
+ this.divPopup.style.visibility = "visible"
+ this.btnDetails.classList.add("button_highlight")
+ this.visible = true
// This is a workaround for a chrome bug which makes it so hidden
// windows can't be scrolled after they are shown
- this.divPopup.focus();
+ this.divPopup.focus()
if (this.graph === 0) {
- this.renderGraph();
+ this.renderGraph()
}
- this.updateGraph(this.fileID);
+ this.updateGraph(this.fileID)
}
}
DetailsWindow.prototype.setDetails = function(file) {
- let desc = "";
+ let desc = ""
if (this.viewer.isList) {
- desc = file.description;
+ desc = file.description
}
- this.fileID = file.id;
+ this.fileID = file.id
this.divFileDetails.innerHTML = "
"
+ "Name | | " + escapeHTML(file.name) + " |
"
- + "URL | | "+domainURL()+"/u/" + file.id + " |
"
+ + "URL | | "+file.link+" |
"
+ "Mime Type | | " + escapeHTML(file.mime_type) + " |
"
+ "ID | | " + file.id + " |
"
+ "Size | | " + formatDataVolume(file.size, 4) + " |
"
+ "Bandwidth | | " + formatDataVolume(file.bandwidth_used, 4) + " |
"
- + "Upload Date | | " + file.date_upload + " |
"
+ + "Upload Date | | " + printDate(file.date_created, true, true, true) + " |
"
+ "Description | | " + escapeHTML(desc) + " |
"
- + "
";
+ + ""
- if(this.visible) {
- this.updateGraph(file.id);
+ if(this.visible && file.timeseries_href !== "") {
+ this.updateGraph(file)
}
}
-DetailsWindow.prototype.updateGraph = function(fileID) {
- console.log("updating graph "+fileID);
- fetch(apiEndpoint+"/file/" + fileID + "/timeseries?interval=60?days=14").then(resp => {
- if (!resp.ok) {return null;}
- return resp.json();
+DetailsWindow.prototype.updateGraph = function(file) {
+ console.log("updating graph")
+ fetch(file.timeseries_href+"?interval=60?days=14").then(resp => {
+ if (!resp.ok) {return null}
+ return resp.json()
}).then(resp => {
- this.graph.data.labels = resp.labels;
- this.graph.data.datasets[0].data = resp.downloads;
- this.graph.data.datasets[1].data = resp.views;
- this.graph.update();
+ this.graph.data.labels = resp.labels
+ this.graph.data.datasets[0].data = resp.downloads
+ this.graph.data.datasets[1].data = resp.views
+ this.graph.update()
})
}
DetailsWindow.prototype.renderGraph = function() {
- console.log("rendering graph");
- Chart.defaults.global.defaultFontColor = "#b3b3b3";
- Chart.defaults.global.defaultFontSize = 15;
- Chart.defaults.global.defaultFontFamily = "Ubuntu";
- Chart.defaults.global.aspectRatio = 2.5;
- 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;
+ console.log("rendering graph")
+ Chart.defaults.global.defaultFontColor = "#b3b3b3"
+ Chart.defaults.global.defaultFontSize = 15
+ Chart.defaults.global.defaultFontFamily = "Ubuntu"
+ Chart.defaults.global.aspectRatio = 2.5
+ 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
this.graph = new Chart(
document.getElementById('bandwidth_chart'),
{
@@ -148,5 +148,5 @@ DetailsWindow.prototype.renderGraph = function() {
}
}
}
- );
+ )
}
diff --git a/res/include/script/file_viewer/ListNavigator.js b/res/include/script/file_viewer/ListNavigator.js
index b514d7e..990331f 100644
--- a/res/include/script/file_viewer/ListNavigator.js
+++ b/res/include/script/file_viewer/ListNavigator.js
@@ -1,178 +1,178 @@
function ListNavigator(viewer, files) {
- this.viewer = viewer;
- this.files = files;
- this.length = files.length;
- this.position = 0;
- this.history = [];
- this.shuffle = false;
+ this.viewer = viewer
+ this.files = files
+ this.length = files.length
+ this.position = 0
+ this.history = []
+ this.shuffle = false
- this.divListNavigator = document.getElementById("list_navigator");
+ this.divListNavigator = document.getElementById("list_navigator")
- this.btnDownloadList = document.getElementById("btn_download_list");
+ this.btnDownloadList = document.getElementById("btn_download_list")
if (files.id !== "") {
- this.btnDownloadList.style.display = "";
- this.btnDownloadList.addEventListener("click", () => { this.downloadList(); });
+ this.btnDownloadList.style.display = ""
+ this.btnDownloadList.addEventListener("click", () => { this.downloadList() })
}
- this.btnShuffle = document.getElementById("btn_shuffle");
- this.btnShuffle.style.display = "";
- this.btnShuffle.addEventListener("click", () => { this.toggleShuffle(); });
+ this.btnShuffle = document.getElementById("btn_shuffle")
+ this.btnShuffle.style.display = ""
+ this.btnShuffle.addEventListener("click", () => { this.toggleShuffle() })
// Render list contents in list navigator div
files.forEach((item, i) => {
- let filename;
+ let filename
if(item.name !== "null"){
- filename = item.name;
+ filename = item.name
}else{
- filename = "Removed File";
+ filename = "Removed File"
}
- let d = document.createElement("div");
- d.classList = "file_button list_item";
- d.addEventListener("click", () => { this.setItem(i); });
- d.innerText = filename;
- this.divListNavigator.appendChild(d);
- });
+ let d = document.createElement("div")
+ d.classList = "file_button list_item"
+ d.addEventListener("click", () => { this.setItem(i) })
+ d.innerText = filename
+ this.divListNavigator.appendChild(d)
+ })
// Make the navigator visible
- this.divListNavigator.style.display = "inline-block";
+ this.divListNavigator.style.display = "inline-block"
// Skip to the file defined in the link hash
- let matches = location.hash.match(new RegExp('item=([^&]*)'));
- let hashID = matches ? matches[1] : null;
+ let matches = location.hash.match(new RegExp('item=([^&]*)'))
+ let hashID = matches ? matches[1] : null
if(Number.isInteger(parseInt(hashID))){
- this.setItem(parseInt(hashID));
+ this.setItem(parseInt(hashID))
}else{
- this.setItem(0);
+ this.setItem(0)
}
}
ListNavigator.prototype.nextItem = function() {
if(this.shuffle){
- this.randItem();
- return;
+ this.randItem()
+ return
}
if (this.position >= this.length) {
- this.position = 0;
+ this.position = 0
} else {
- this.position++;
+ this.position++
}
- this.setItem(this.position);
+ this.setItem(this.position)
}
ListNavigator.prototype.previousItem = function() {
if(this.position === 0){
- this.position = this.length - 1;
+ this.position = this.length - 1
}else{
- this.position--;
+ this.position--
}
- this.setItem(this.position);
+ this.setItem(this.position)
}
ListNavigator.prototype.randItem = function() {
// Avoid viewing the same file multiple times
- let rand;
+ let rand
do {
- rand = Math.round(Math.random() * this.length);
- console.log("rand is " + rand);
- } while(this.history.indexOf(rand) > -1);
+ rand = Math.round(Math.random() * this.length)
+ console.log("rand is " + rand)
+ } while(this.history.indexOf(rand) > -1)
- this.setItem(rand);
+ this.setItem(rand)
}
ListNavigator.prototype.setItem = function(index) {
if(index >= this.length){
- this.position = 0;
+ this.position = 0
}else{
- this.position = index;
+ this.position = index
}
// Set the URL hash
- location.hash = "item=" + this.position;
- this.viewer.setFile(this.files[this.position]);
+ location.hash = "item=" + this.position
+ this.viewer.setFile(this.files[this.position])
- this.addToHistory(index);
- this.loadThumbnails(index);
+ this.addToHistory(index)
+ this.loadThumbnails(index)
document.querySelectorAll("#list_navigator > .file_button_selected").forEach(el => {
- el.classList.remove("file_button_selected");
- });
+ el.classList.remove("file_button_selected")
+ })
- let selectedItem = this.divListNavigator.children[this.position];
- selectedItem.classList.add("file_button_selected");
+ let selectedItem = this.divListNavigator.children[this.position]
+ selectedItem.classList.add("file_button_selected")
- let cst = window.getComputedStyle(selectedItem);
- let itemWidth = selectedItem.offsetWidth + parseInt(cst.marginLeft) + parseInt(cst.marginRight);
+ let cst = window.getComputedStyle(selectedItem)
+ let itemWidth = selectedItem.offsetWidth + parseInt(cst.marginLeft) + parseInt(cst.marginRight)
- let start = this.divListNavigator.scrollLeft;
- let end = ((this.position * itemWidth) + (itemWidth / 2)) - (this.divListNavigator.clientWidth / 2);
- let steps = 60; // One second
- let stepSize = (end - start)/steps;
+ let start = this.divListNavigator.scrollLeft
+ let end = ((this.position * itemWidth) + (itemWidth / 2)) - (this.divListNavigator.clientWidth / 2)
+ let steps = 60 // One second
+ let stepSize = (end - start)/steps
let animateScroll = (pos, step) => {
- this.divListNavigator.scrollLeft = pos;
+ this.divListNavigator.scrollLeft = pos
if (step < steps) {
requestAnimationFrame(() => {
- animateScroll(pos+stepSize, step+1);
- });
+ animateScroll(pos+stepSize, step+1)
+ })
}
- };
- animateScroll(start, 0);
+ }
+ animateScroll(start, 0)
}
ListNavigator.prototype.downloadList = function() {
- document.getElementById("download_frame").src = "/api/list/" + this.viewer.listId + "/zip";
+ document.getElementById("download_frame").src = "/api/list/" + this.viewer.listId + "/zip"
}
ListNavigator.prototype.addToHistory = function(index) {
if(this.history.length >= (this.length - 6)){
- this.history.shift();
+ this.history.shift()
}
- this.history.push(index);
+ this.history.push(index)
}
ListNavigator.prototype.toggleShuffle = function() {
- this.shuffle = !this.shuffle; // :P
+ this.shuffle = !this.shuffle // :P
if(this.shuffle){
- document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☑"; // Check icon
- this.btnShuffle.classList.add("button_highlight");
+ document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☑" // Check icon
+ this.btnShuffle.classList.add("button_highlight")
}else{
- document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☐"; // Empty checkbox
- this.btnShuffle.classList.remove("button_highlight");
+ document.querySelector("#btn_shuffle > span").innerHTML = "Shuffle ☐" // Empty checkbox
+ this.btnShuffle.classList.remove("button_highlight")
}
}
ListNavigator.prototype.loadThumbnails = function(index) {
- let startPos = +index - 50;
- let endPos = +index + 50;
+ let startPos = +index - 50
+ let endPos = +index + 50
// fyi, the + is to let javascript know it's actually a number instead of a string
if(startPos < 0){
- startPos = 0;
+ startPos = 0
}
if(endPos >= this.length){
- endPos = this.length - 1;
+ endPos = this.length - 1
}
let navigatorItems = document.getElementById("list_navigator").children
for (let i = startPos; i <= endPos; i++){
if (navigatorItems[i].innerHTML.includes("list_item_thumbnail")) {
- continue; // Thumbnail already loaded
+ continue // Thumbnail already loaded
}
- let thumb = "/api/file/" + this.files[i].id + "/thumbnail?width=48&height=48";
- let name = this.files[i].name;
+ let thumb = "/api/file/" + this.files[i].id + "/thumbnail?width=48&height=48"
+ let name = this.files[i].name
let itemHtml = "
"
- + escapeHTML(name);
+ + escapeHTML(name)
- navigatorItems[i].innerHTML = itemHtml;
+ navigatorItems[i].innerHTML = itemHtml
}
}
diff --git a/res/include/script/file_viewer/Toolbar.js b/res/include/script/file_viewer/Toolbar.js
index bd9b777..ce0cfc6 100644
--- a/res/include/script/file_viewer/Toolbar.js
+++ b/res/include/script/file_viewer/Toolbar.js
@@ -1,41 +1,49 @@
function Toolbar(viewer) {
- this.viewer = viewer;
- this.visible = false;
- this.sharebarVisible = false;
+ this.viewer = viewer
+ this.visible = false
+ this.sharebarVisible = false
+ this.currentFile = null
- this.divToolbar = document.getElementById("toolbar");
- this.divFilePreview = document.getElementById("filepreview");
- this.downloadFrame = document.getElementById("download_frame");
- this.spanViews = document.getElementById("stat_views");
- this.spanDownloads = document.getElementById("stat_downloads");
- this.spanSize = document.getElementById("stat_size");
+ this.divToolbar = document.getElementById("toolbar")
+ this.divFilePreview = document.getElementById("filepreview")
+ this.downloadFrame = document.getElementById("download_frame")
+ this.spanViews = document.getElementById("stat_views")
+ this.spanDownloads = document.getElementById("stat_downloads")
+ this.spanSize = document.getElementById("stat_size")
- this.btnToggleToolbar = document.getElementById("btn_toggle_toolbar");
- this.btnDownload = document.getElementById("btn_download");
- this.btnCopyLink = document.getElementById("btn_copy");
- this.spanCopyLink = document.querySelector("#btn_copy > span");
- this.btnShare = document.getElementById("btn_share");
- this.divSharebar = document.getElementById("sharebar");
+ this.btnToggleToolbar = document.getElementById("btn_toggle_toolbar")
+ this.btnDownload = document.getElementById("btn_download")
+ this.btnCopyLink = document.getElementById("btn_copy")
+ this.spanCopyLink = document.querySelector("#btn_copy > span")
+ this.btnShare = document.getElementById("btn_share")
+ this.divSharebar = document.getElementById("sharebar")
- this.btnToggleToolbar.addEventListener("click", () => { this.toggle(); });
- this.btnDownload.addEventListener("click", () => { this.download(); });
- this.btnCopyLink.addEventListener("click", () => { this.copyUrl(); });
- this.btnShare.addEventListener("click", () => { this.toggleSharebar(); });
+ this.btnToggleToolbar.addEventListener("click", () => { this.toggle() })
+ this.btnDownload.addEventListener("click", () => { this.download() })
+ this.btnCopyLink.addEventListener("click", () => { this.copyUrl() })
+ this.btnShare.addEventListener("click", () => { this.toggleSharebar() })
+}
+
+Toolbar.prototype.setFile = function(file) {
+ this.currentFile = file
+ this.spanViews.innerText = file.views
+ this.spanDownloads.innerText = Math.round((file.bandwidth_used/file.size)*10)/10
+ this.spanSize.innerText = formatDataVolume(file.size, 3)
}
Toolbar.prototype.toggle = function() {
if (this.visible) {
- if (this.sharebarVisible) { this.toggleSharebar(); }
+ if (this.sharebarVisible) { this.toggleSharebar() }
- this.divToolbar.style.left = "-8em";
- this.divFilePreview.style.left = "0px";
- this.btnToggleToolbar.classList.remove("button_highlight");
- this.visible = false;
+ this.divToolbar.style.left = "-8em"
+ this.divFilePreview.style.left = "0px"
+ this.btnToggleToolbar.classList.remove("button_highlight")
+ this.visible = false
} else {
- this.divToolbar.style.left = "0px";
- this.divFilePreview.style.left = "8em";
- this.btnToggleToolbar.classList.add("button_highlight");
- this.visible = true;
+ this.divToolbar.style.left = "0px"
+ this.divFilePreview.style.left = "8em"
+ this.btnToggleToolbar.classList.add("button_highlight")
+ this.visible = true
}
}
@@ -45,132 +53,124 @@ Toolbar.prototype.toggleSharebar = function() {
title: this.viewer.title,
text: "Download " + this.viewer.title + " here",
url: window.location.href
- });
- return;
+ })
+ return
}
if(this.sharebarVisible){
- this.divSharebar.style.left = "-8em";
+ this.divSharebar.style.left = "-8em"
this.btnShare.classList.remove("button_highlight")
- this.sharebarVisible = false;
+ this.sharebarVisible = false
}else{
- this.divSharebar.style.left = "8em";
+ this.divSharebar.style.left = "8em"
this.btnShare.classList.add("button_highlight")
- this.sharebarVisible = true;
+ this.sharebarVisible = true
}
}
Toolbar.prototype.download = function() {
let triggerDL = (captchaResp = "") => {
if (captchaResp === "") {
- this.downloadFrame.src = apiEndpoint+"/file/"+
- this.viewer.currentFile+"?download";
+ this.downloadFrame.src = this.currentFile.download_href
} else {
- this.downloadFrame.src = apiEndpoint+"/file/"+
- this.viewer.currentFile+"?download&recaptcha_response="+captchaResp;
+ this.downloadFrame.src = this.currentFile.download_href+"&recaptcha_response="+captchaResp
}
}
- if (captchaKey === "none"){
+ if (captchaKey === "none" || captchaKey === ""){
// If the server doesn't support captcha there's no use in checking
// availability
- triggerDL();
- return;
+ triggerDL()
+ return
}
if (recaptchaResponse !== "") {
// Captcha already filled in. Use the saved captcha responsse to
// download the file
- triggerDL(recaptchaResponse);
+ triggerDL(recaptchaResponse)
// Reset the key
- recaptchaResponse = "";
- return;
+ recaptchaResponse = ""
+ return
}
- fetch(apiEndpoint+"/file/"+this.viewer.currentFile+"/availability").then(resp => {
- return resp.json();
+ fetch(this.currentFile.file_availability_href).then(resp => {
+ return resp.json()
}).then(resp => {
- let popupDiv = document.getElementById("captcha_popup");
- let popupTitle = document.getElementById("captcha_popup_title");
- let popupContent = document.getElementById("captcha_popup_content");
+ let popupDiv = document.getElementById("captcha_popup")
+ let popupTitle = document.getElementById("captcha_popup_title")
+ let popupContent = document.getElementById("captcha_popup_content")
let showCaptcha = () => {
// Load the recaptcha script with a load function
- let script = document.createElement("script");
- script.src = "https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit";
- document.body.appendChild(script);
+ let script = document.createElement("script")
+ script.src = "https://www.google.com/recaptcha/api.js?onload=loadCaptcha&render=explicit"
+ document.body.appendChild(script)
// Show the popup
- popupDiv.style.opacity = "1";
- popupDiv.style.visibility = "visible";
+ popupDiv.style.opacity = "1"
+ popupDiv.style.visibility = "visible"
}
if (resp.value === "file_rate_limited_captcha_required") {
- popupTitle.innerText = "Rate limiting enabled!";
+ popupTitle.innerText = "Rate limiting enabled!"
popupContent.innerText = "This file is using a suspicious "+
"amount of bandwidth relative to its popularity. To "+
"continue downloading this file you will have to "+
- "prove that you're a human first.";
- showCaptcha();
+ "prove that you're a human first."
+ showCaptcha()
} else if (resp.value === "virus_detected_captcha_required") {
- popupTitle.innerText = "Malware warning!";
+ popupTitle.innerText = "Malware warning!"
popupContent.innerText = "According to our scanning "+
"systems this file may contain a virus of type '"+
resp.extra+"'. You can continue downloading this file at "+
"your own risk, but you will have to prove that you're a "+
- "human first.";
- showCaptcha();
+ "human first."
+ showCaptcha()
} else {
- console.warn("resp.value not valid: "+resp.value);
- triggerDL();
+ console.warn("resp.value not valid: "+resp.value)
+ triggerDL()
}
}).catch(e => {
- console.warn("fetch availability failed: "+e);
- triggerDL();
- });
+ console.warn("fetch availability failed: "+e)
+ triggerDL()
+ })
}
Toolbar.prototype.copyUrl = function() {
if(copyText(window.location.href)) {
- console.log('Text copied');
- this.spanCopyLink.innerText = "Copied!";
+ console.log('Text copied')
+ this.spanCopyLink.innerText = "Copied!"
this.btnCopyLink.classList.add("button_highlight")
} else {
- console.log('Copying not supported');
- this.spanCopyLink.innerText = "Error!";
- alert("Your browser does not support copying text.");
+ console.log('Copying not supported')
+ this.spanCopyLink.innerText = "Error!"
+ alert("Your browser does not support copying text.")
}
// Return to normal
setTimeout(() => {
- this.spanCopyLink.innerText = "Copy";
+ this.spanCopyLink.innerText = "Copy"
this.btnCopyLink.classList.remove("button_highlight")
- }, 60000);
-}
-
-Toolbar.prototype.setStats = function(file) {
- this.spanViews.innerText = file.views
- this.spanDownloads.innerText = Math.round((file.bandwidth_used/file.size)*10)/10;
- this.spanSize.innerText = formatDataVolume(file.size, 3);
+ }, 60000)
}
// Called by the google recaptcha script
-let recaptchaResponse = "";
+let recaptchaResponse = ""
function loadCaptcha(){
grecaptcha.render("captcha_popup_captcha", {
sitekey: captchaKey,
theme: "dark",
callback: token => {
- recaptchaResponse = token;
- document.getElementById("btn_download").click();
+ recaptchaResponse = token
+ document.getElementById("btn_download").click()
// Hide the popup
setTimeout(() => {
- let popupDiv = document.getElementById("captcha_popup");
- popupDiv.style.opacity = "0";
- popupDiv.style.visibility = "hidden";
+ let popupDiv = document.getElementById("captcha_popup")
+ popupDiv.style.opacity = "0"
+ popupDiv.style.visibility = "hidden"
}, 1000)
}
- });
+ })
}
diff --git a/res/include/script/file_viewer/Viewer.js b/res/include/script/file_viewer/Viewer.js
index 9ae714d..bf0c77e 100644
--- a/res/include/script/file_viewer/Viewer.js
+++ b/res/include/script/file_viewer/Viewer.js
@@ -1,27 +1,26 @@
function Viewer(type, viewToken, data) {
// Set defaults
- this.toolbar = null;
- this.listNavigator = null;
- this.detailsWindow = null;
- this.divFilepreview = null;
- this.currentFile = "";
- this.title = ""; // Contains either the file name or list title
- this.listId = "";
- this.viewToken = "";
- this.isList = false;
- this.isFile = false;
- this.initialized = false;
+ this.toolbar = null
+ this.listNavigator = null
+ this.detailsWindow = null
+ this.divFilepreview = null
+ this.title = "" // Contains either the file name or list title
+ this.listId = ""
+ this.viewToken = ""
+ this.isList = false
+ this.isFile = false
+ this.initialized = false
- this.viewToken = viewToken;
- this.toolbar = new Toolbar(this);
- this.detailsWindow = new DetailsWindow(this);
+ this.viewToken = viewToken
+ this.toolbar = new Toolbar(this)
+ this.detailsWindow = new DetailsWindow(this)
- this.divFilepreview = document.getElementById("filepreview");
+ this.divFilepreview = document.getElementById("filepreview")
// On small screens the toolbar takes too much space, so it collapses
// automatically
if (this.divFilepreview.clientWidth > 600 && !this.toolbar.visible) {
- this.toolbar.toggle();
+ this.toolbar.toggle()
}
// The close button only works if the window has an opener. So we hide
@@ -31,106 +30,122 @@ function Viewer(type, viewToken, data) {
}
if (type === "file") {
- this.isFile = true;
- this.currentFile = data.id;
- this.title = data.name;
- this.setFile(data);
+ this.isFile = true
+ this.title = data.name
+ this.setFile(fileFromAPIResp(data))
} else if (type === "list") {
- this.isList = true;
- this.listId = data.id;
- this.title = data.title;
- this.listNavigator = new ListNavigator(this, data.files);
+ this.isList = true
+ this.listId = data.id
+ this.title = data.title
+
+ let files = []
+ for (let i in data.files) {
+ files.push(fileFromAPIResp(data.files[i]))
+ }
+ this.listNavigator = new ListNavigator(this, files)
+ } else if (type === "skylink") {
+ this.isFile = true
+ this.title = data.name
+ document.getElementById("btn_details").remove()
+ document.getElementById("stat_views_label").remove()
+ document.getElementById("stat_views").remove()
+ document.getElementById("stat_downloads_label").remove()
+ document.getElementById("stat_downloads").remove()
+
+ let file = fileFromSkyNet(data)
+ console.log(file)
+ this.setFile(file)
}
- this.renderSponsors();
- window.addEventListener("resize", e => { this.renderSponsors(e); });
+ this.renderSponsors()
+ window.addEventListener("resize", e => { this.renderSponsors(e) })
// Register keyboard shortcuts
- document.addEventListener("keydown", e => { this.keyboardEvent(e); });
+ document.addEventListener("keydown", e => { this.keyboardEvent(e) })
- this.initialized = true;
+ this.initialized = true
}
Viewer.prototype.setFile = function(file) {
- this.currentFile = file.id;
if (this.isList) {
- document.getElementById("file_viewer_headerbar_title").style.lineHeight = "1em";
- document.getElementById("file_viewer_list_title").innerText = this.title;
- document.getElementById("file_viewer_file_title").innerText = file.name;
- document.title = this.title + " ~ " + file.name + " ~ pixeldrain";
+ document.getElementById("file_viewer_headerbar_title").style.lineHeight = "1em"
+ document.getElementById("file_viewer_list_title").innerText = this.title
+ document.getElementById("file_viewer_file_title").innerText = file.name
+ document.title = this.title + " ~ " + file.name + " ~ pixeldrain"
} else {
- document.getElementById("file_viewer_file_title").innerText = file.name;
- document.title = file.name + " ~ pixeldrain";
+ document.getElementById("file_viewer_file_title").innerText = file.name
+ document.title = file.name + " ~ pixeldrain"
}
// Update the file details
- this.detailsWindow.setDetails(file);
- this.toolbar.setStats(file);
+ this.detailsWindow.setDetails(file)
+ this.toolbar.setFile(file)
// Register a new view. We don't care what this returns becasue we can't
// do anything about it anyway
- fetch(apiEndpoint+"/file/"+file.id+"/view",
- {
- method: "POST",
- headers: {"Content-Type": "application/x-www-form-urlencoded"},
- body: "token="+this.viewToken
- }
- );
+ if (file.view_href !== "") {
+ fetch(file.view_href, {
+ method: "POST",
+ headers: {"Content-Type": "application/x-www-form-urlencoded"},
+ body: "token="+this.viewToken
+ }
+ )
+ }
// Clear the canvas
- this.divFilepreview.innerHTML = "";
+ this.divFilepreview.innerHTML = ""
let nextItem = () => {
if (this.listNavigator !== null) {
- this.listNavigator.nextItem();
+ this.listNavigator.nextItem()
}
- };
+ }
if (
file.mime_type.startsWith("image")
) {
- new ImageViewer(this, file).render(this.divFilepreview);
+ new ImageViewer(this, file).render(this.divFilepreview)
} else if (
file.mime_type.startsWith("video") ||
file.mime_type === "application/matroska" ||
file.mime_type === "application/x-matroska"
) {
- new VideoViewer(this, file, nextItem).render(this.divFilepreview);
+ new VideoViewer(this, file, nextItem).render(this.divFilepreview)
} else if (
file.mime_type.startsWith("audio") ||
file.mime_type === "application/ogg" ||
file.name.endsWith(".mp3")
) {
- new AudioViewer(this, file, nextItem).render(this.divFilepreview);
+ new AudioViewer(this, file, nextItem).render(this.divFilepreview)
} else if (
file.mime_type === "application/pdf" ||
file.mime_type === "application/x-pdf"
) {
- new PDFViewer(this, file).render(this.divFilepreview);
+ new PDFViewer(this, file).render(this.divFilepreview)
} else if (
file.mime_type.startsWith("text") ||
file.id === "demo"
) {
- new TextViewer(this, file).render(this.divFilepreview);
+ new TextViewer(this, file).render(this.divFilepreview)
} else {
- new FileViewer(this, file).render(this.divFilepreview);
+ new FileViewer(this, file).render(this.divFilepreview)
}
}
Viewer.prototype.renderSponsors = function() {
- let scale = 1;
- let scaleWidth = 1;
- let scaleHeight = 1;
- let minWidth = 728;
- let minHeight = 800;
+ let scale = 1
+ let scaleWidth = 1
+ let scaleHeight = 1
+ let minWidth = 728
+ let minHeight = 800
if (window.innerWidth < minWidth) {
- scaleWidth = window.innerWidth/minWidth;
+ scaleWidth = window.innerWidth/minWidth
}
if (window.innerHeight < minHeight) {
- scaleHeight = window.innerHeight/minHeight;
+ scaleHeight = window.innerHeight/minHeight
}
- scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
+ scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight
// Because of the scale transformation the automatic margins don't work
// anymore. So we have to maunally calculate the margin. Where we take the
@@ -141,14 +156,14 @@ Viewer.prototype.renderSponsors = function() {
if (offset < 0) {
offset = 0
}
- document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px";
+ document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px"
if (scale == 1) {
- document.querySelector(".sponsors > iframe").style.transform = "none";
- document.querySelector(".sponsors").style.height = "90px";
+ document.querySelector(".sponsors > iframe").style.transform = "none"
+ document.querySelector(".sponsors").style.height = "90px"
} else {
- document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")";
- document.querySelector(".sponsors").style.height = (scale*90)+"px";
+ document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")"
+ document.querySelector(".sponsors").style.height = (scale*90)+"px"
}
}
@@ -161,36 +176,36 @@ Viewer.prototype.keyboardEvent = function(evt) {
case 65: // A or left arrow key go to previous file
case 37:
if (this.listNavigator != null) {
- this.listNavigator.previousItem();
+ this.listNavigator.previousItem()
}
- break;
+ break
case 68: // D or right arrow key go to next file
case 39:
if (this.listNavigator != null) {
- this.listNavigator.nextItem();
+ this.listNavigator.nextItem()
}
- break;
+ break
case 83:
if (evt.shiftKey) {
- this.listNavigator.downloadList(); // SHIFT + S downloads all files in list
+ this.listNavigator.downloadList() // SHIFT + S downloads all files in list
} else {
- this.toolbar.download(); // S to download the current file
+ this.toolbar.download() // S to download the current file
}
- break;
+ break
case 82: // R to toggle list shuffle
if (this.listNavigator != null) {
- this.listNavigator.toggleShuffle();
+ this.listNavigator.toggleShuffle()
}
- break;
+ break
case 67: // C to copy to clipboard
- this.toolbar.copyUrl();
- break;
+ this.toolbar.copyUrl()
+ break
case 73: // I to open the details window
- this.detailsWindow.toggle();
- break;
+ this.detailsWindow.toggle()
+ break
case 81: // Q to close the window
- window.close();
- break;
+ window.close()
+ break
}
}
@@ -203,3 +218,39 @@ function escapeHTML(str) {
.replace(/>/g, '>')
.replace(/"/g, '"');
}
+
+function fileFromAPIResp(resp) {
+ let file = {
+ id: resp.id,
+ name: resp.name,
+ mime_type: resp.mime_type,
+ size: resp.size,
+ date_created: new Date(resp.date_upload),
+ date_last_view: new Date(resp.date_last_view),
+ views: resp.views,
+ bandwidth_used: resp.bandwidth_used,
+ description: "",
+ icon_href: apiEndpoint+"/file/"+resp.id+"/thumbnail",
+ get_href: apiEndpoint+"/file/"+resp.id,
+ download_href: apiEndpoint+"/file/"+resp.id+"?download",
+ availability_href: apiEndpoint+"/file/"+resp.id+"/availability",
+ view_href: apiEndpoint+"/file/"+resp.id+"/view",
+ timeseries_href: apiEndpoint+"/file/"+resp.id+"/timeseries",
+ link: domainURL()+"/u/"+resp.id,
+ }
+ if (resp.description !== undefined) {
+ file.description = resp.description
+ }
+ return file
+}
+function fileFromSkyNet(resp) {
+ let file = fileFromAPIResp(resp)
+ file.icon_href = "/res/img/mime/empty.png"
+ file.get_href = "https://siasky.net/"+resp.id
+ file.download_href = "https://siasky.net/"+resp.id
+ file.availability_href = ""
+ file.view_href = ""
+ file.timeseries_href = ""
+ file.link = domainURL()+"/s/"+resp.id
+ return file
+}
diff --git a/res/include/script/file_viewer/viewer_scripts/AudioViewer.js b/res/include/script/file_viewer/viewer_scripts/AudioViewer.js
index a782137..0e24492 100644
--- a/res/include/script/file_viewer/viewer_scripts/AudioViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/AudioViewer.js
@@ -1,33 +1,33 @@
function AudioViewer(viewer, file, next) {
- this.viewer = viewer;
- this.file = file;
- this.next = next;
+ this.viewer = viewer
+ this.file = file
+ this.next = next
- this.container = document.createElement("div");
- this.container.classList = "image-container";
- this.container.appendChild(document.createElement("br"));
+ this.container = document.createElement("div")
+ this.container.classList = "image-container"
+ this.container.appendChild(document.createElement("br"))
- this.icon = document.createElement("img");
- this.icon.src = "/res/img/mime/audio.png";
- this.container.appendChild(this.icon);
+ this.icon = document.createElement("img")
+ this.icon.src = "/res/img/mime/audio.png"
+ this.container.appendChild(this.icon)
- this.container.appendChild(document.createElement("br"));
- this.container.appendChild(document.createTextNode(file.name));
- this.container.appendChild(document.createElement("br"));
- this.container.appendChild(document.createElement("br"));
+ this.container.appendChild(document.createElement("br"))
+ this.container.appendChild(document.createTextNode(this.file.name))
+ this.container.appendChild(document.createElement("br"))
+ this.container.appendChild(document.createElement("br"))
- this.element = document.createElement("audio");
- this.element.autoplay = "autoplay";
- this.element.controls = "controls";
- this.element.style.width = "90%";
- this.element.addEventListener("ended", () => { this.next(); }, false);
+ this.element = document.createElement("audio")
+ this.element.autoplay = "autoplay"
+ this.element.controls = "controls"
+ this.element.style.width = "90%"
+ this.element.addEventListener("ended", () => { this.next() }, false)
- this.source = document.createElement("source");
- this.source.src = apiEndpoint+"/file/"+this.file.id;
- this.element.appendChild(this.source);
- this.container.appendChild(this.element);
+ this.source = document.createElement("source")
+ this.source.src = this.file.get_href
+ this.element.appendChild(this.source)
+ this.container.appendChild(this.element)
}
AudioViewer.prototype.render = function(parent) {
- parent.appendChild(this.container);
+ parent.appendChild(this.container)
}
diff --git a/res/include/script/file_viewer/viewer_scripts/FileViewer.js b/res/include/script/file_viewer/viewer_scripts/FileViewer.js
index c634832..1d7d20c 100644
--- a/res/include/script/file_viewer/viewer_scripts/FileViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/FileViewer.js
@@ -1,27 +1,27 @@
function FileViewer(viewer, file, next) {
- this.viewer = viewer;
- this.file = file;
- this.next = next;
+ this.viewer = viewer
+ this.file = file
+ this.next = next
- this.container = document.createElement("div");
- this.container.classList = "image-container";
- this.container.appendChild(document.createElement("br"));
+ this.container = document.createElement("div")
+ this.container.classList = "image-container"
+ this.container.appendChild(document.createElement("br"))
- this.icon = document.createElement("img");
- this.icon.src = apiEndpoint+"/"+file.thumbnail_href;
- this.container.appendChild(this.icon);
+ this.icon = document.createElement("img")
+ this.icon.src = this.file.icon_href
+ this.container.appendChild(this.icon)
- this.container.appendChild(document.createElement("br"));
- this.container.appendChild(document.createTextNode(file.name));
- this.container.appendChild(document.createElement("br"));
- this.container.appendChild(document.createTextNode("Type: "+file.mime_type));
- this.container.appendChild(document.createElement("br"));
- this.container.appendChild(document.createElement("br"));
+ this.container.appendChild(document.createElement("br"))
+ this.container.appendChild(document.createTextNode(file.name))
+ this.container.appendChild(document.createElement("br"))
+ this.container.appendChild(document.createTextNode("Type: "+file.mime_type))
+ this.container.appendChild(document.createElement("br"))
+ this.container.appendChild(document.createElement("br"))
this.container.appendChild(document.createTextNode(
"Press the 'Download' button in the menu to download this file"
- ));
+ ))
}
FileViewer.prototype.render = function(parent) {
- parent.appendChild(this.container);
+ parent.appendChild(this.container)
}
diff --git a/res/include/script/file_viewer/viewer_scripts/ImageViewer.js b/res/include/script/file_viewer/viewer_scripts/ImageViewer.js
index a916ab9..600c468 100644
--- a/res/include/script/file_viewer/viewer_scripts/ImageViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/ImageViewer.js
@@ -1,88 +1,86 @@
function ImageViewer(viewer, file) {
- this.viewer = viewer;
- this.file = file;
- this.zoomed = false;
- this.x = 0;
- this.y = 0;
- this.dragging = false;
+ this.viewer = viewer
+ this.file = file
+ this.zoomed = false
+ this.x = 0
+ this.y = 0
+ this.dragging = false
- this.container = document.createElement("dv");
- this.container.classList = "image-container";
- // this.container.style.lineHeight = "0";
+ this.container = document.createElement("dv")
+ this.container.classList = "image-container"
- this.element = document.createElement("img");
- this.element.classList = "pannable center drop-shadow";
- this.element.src = apiEndpoint+"/file/"+this.file.id;
- this.element.addEventListener("dblclick", (e) => { return this.doubleclick(e); });
- this.element.addEventListener("doubletap", (e) => { return this.doubleclick(e); });
- this.element.addEventListener("mousedown", (e) => { return this.mousedown(e); });
- document.addEventListener("mousemove", (e) => { return this.mousemove(e); });
- document.addEventListener("mouseup", (e) => { return this.mouseup(e); });
+ this.element = document.createElement("img")
+ this.element.classList = "pannable center drop-shadow"
+ this.element.src = this.file.get_href
+ this.element.addEventListener("dblclick", (e) => { return this.doubleclick(e) })
+ this.element.addEventListener("doubletap", (e) => { return this.doubleclick(e) })
+ this.element.addEventListener("mousedown", (e) => { return this.mousedown(e) })
+ document.addEventListener("mousemove", (e) => { return this.mousemove(e) })
+ document.addEventListener("mouseup", (e) => { return this.mouseup(e) })
- this.container.appendChild(this.element);
+ this.container.appendChild(this.element)
}
ImageViewer.prototype.render = function(parent) {
- parent.appendChild(this.container);
+ parent.appendChild(this.container)
}
ImageViewer.prototype.doubleclick = function(e) {
if (this.zoomed) {
- this.element.style.maxWidth = "100%";
- this.element.style.maxHeight = "100%";
- this.element.style.top = "50%";
- this.element.style.left = "auto";
- this.element.style.transform = "translateY(-50%)";
- this.container.style.overflow = "hidden";
- this.zoomed = false;
+ this.element.style.maxWidth = "100%"
+ this.element.style.maxHeight = "100%"
+ this.element.style.top = "50%"
+ this.element.style.left = "auto"
+ this.element.style.transform = "translateY(-50%)"
+ this.container.style.overflow = "hidden"
+ this.zoomed = false
} else {
- this.element.style.maxWidth = "none";
- this.element.style.maxHeight = "none";
- this.element.style.top = "0";
- this.element.style.left = "";
- this.element.style.transform = "none";
- this.container.style.overflow = "scroll";
- this.zoomed = true;
+ this.element.style.maxWidth = "none"
+ this.element.style.maxHeight = "none"
+ this.element.style.top = "0"
+ this.element.style.left = ""
+ this.element.style.transform = "none"
+ this.container.style.overflow = "scroll"
+ this.zoomed = true
}
- e.preventDefault();
- e.stopPropagation();
- return false;
+ e.preventDefault()
+ e.stopPropagation()
+ return false
}
ImageViewer.prototype.mousedown = function(e) {
if (!this.dragging && e.which === 1 && this.zoomed) {
- this.x = e.pageX;
- this.y = e.pageY;
- this.dragging = true;
+ this.x = e.pageX
+ this.y = e.pageY
+ this.dragging = true
- e.preventDefault();
- e.stopPropagation();
- return false;
+ e.preventDefault()
+ e.stopPropagation()
+ return false
}
}
ImageViewer.prototype.mousemove = function(e) {
if (this.dragging) {
- this.container.scrollLeft = this.container.scrollLeft - (e.pageX - this.x);
- this.container.scrollTop = this.container.scrollTop - (e.pageY - this.y);
+ this.container.scrollLeft = this.container.scrollLeft - (e.pageX - this.x)
+ this.container.scrollTop = this.container.scrollTop - (e.pageY - this.y)
- this.x = e.pageX;
- this.y = e.pageY;
+ this.x = e.pageX
+ this.y = e.pageY
- e.preventDefault();
- e.stopPropagation();
- return false;
+ e.preventDefault()
+ e.stopPropagation()
+ return false
}
-
}
ImageViewer.prototype.mouseup = function(e) {
if (this.dragging) {
- this.dragging = false;
+ this.dragging = false
- e.preventDefault();
- e.stopPropagation();
- return false;
+ e.preventDefault()
+ e.stopPropagation()
+ return false
}
}
diff --git a/res/include/script/file_viewer/viewer_scripts/PDFViewer.js b/res/include/script/file_viewer/viewer_scripts/PDFViewer.js
index 7e79c60..00bb7d1 100644
--- a/res/include/script/file_viewer/viewer_scripts/PDFViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/PDFViewer.js
@@ -1,13 +1,12 @@
function PDFViewer(viewer, file) {
- this.viewer = viewer;
- this.file = file;
+ this.viewer = viewer
+ this.file = file
- this.container = document.createElement("iframe");
- this.container.classList = "image-container";
- this.container.style.border = "none";
- this.container.src = "/res/misc/pdf-viewer/web/viewer.html?file="+apiEndpoint+"/file/"+file.id;
+ this.container = document.createElement("iframe")
+ this.container.classList = "image-container"
+ this.container.style.border = "none"
+ this.container.src = "/res/misc/pdf-viewer/web/viewer.html?file="+this.file.get_href
}
-
PDFViewer.prototype.render = function(parent) {
- parent.appendChild(this.container);
+ parent.appendChild(this.container)
}
diff --git a/res/include/script/file_viewer/viewer_scripts/TextViewer.js b/res/include/script/file_viewer/viewer_scripts/TextViewer.js
index 867ed0f..c182a09 100644
--- a/res/include/script/file_viewer/viewer_scripts/TextViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/TextViewer.js
@@ -1,56 +1,58 @@
function TextViewer(viewer, file) {
- this.viewer = viewer;
- this.file = file;
- this.pre = null;
- this.prettyprint = null;
+ this.viewer = viewer
+ this.file = file
+ this.pre = null
+ this.prettyprint = null
- this.container = document.createElement("div");
- this.container.classList = "text-container";
+ this.container = document.createElement("div")
+ this.container.classList = "text-container"
- if (file.name.endsWith(".md") || file.name.endsWith(".markdown") || file.id === "demo") {
- this.getMarkdown();
+ if (this.file.name.endsWith(".md") || this.file.name.endsWith(".markdown") || file.mime_type === "text/demo") {
+ this.getMarkdown()
} else {
- this.getText();
+ this.getText()
}
}
TextViewer.prototype.getText = function() {
- this.pre = document.createElement("pre");
- this.pre.classList = "pre-container prettyprint linenums";
- this.pre.innerText = "Loading...";
- this.container.appendChild(this.pre);
+ this.pre = document.createElement("pre")
+ this.pre.classList = "pre-container prettyprint linenums"
+ this.pre.innerText = "Loading..."
+ this.container.appendChild(this.pre)
if (this.file.size > 1<<20) { // File larger than 1 MiB
- this.pre.innerText = "File is too large to view online.\nPlease download and view it locally.";
- return;
+ this.pre.innerText = "File is too large to view online.\nPlease download and view it locally."
+ return
}
- fetch(apiEndpoint+"/file/"+this.file.id).then(resp => {
- if (!resp.ok) { return Promise.reject(resp.status); }
- return resp.text();
+ fetch(this.file.get_href).then(resp => {
+ if (!resp.ok) { return Promise.reject(resp.status) }
+ return resp.text()
}).then(resp => {
- this.pre.innerText = resp;
+ this.pre.innerText = resp
// Load prettyprint script
- this.prettyprint = document.createElement("script");
- this.prettyprint.src = "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert";
- this.container.appendChild(this.prettyprint);
+ this.prettyprint = document.createElement("script")
+ this.prettyprint.src = "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"
+ this.container.appendChild(this.prettyprint)
}).catch(err => {
- this.pre.innerText = "Error loading file: "+err;
- });
+ this.pre.innerText = "Error loading file: "+err
+ })
}
TextViewer.prototype.getMarkdown = function() {
- fetch("/u/"+this.file.id+"/preview").then(resp => {
- if (!resp.ok) { return Promise.reject(resp.status); }
- return resp.text();
+ fetch(
+ domainURL()+window.location.pathname+"/preview"
+ ).then(resp => {
+ if (!resp.ok) { return Promise.reject(resp.status) }
+ return resp.text()
}).then(resp => {
- this.container.innerHTML = resp;
+ this.container.innerHTML = resp
}).catch(err => {
- this.container.innerText = "Error loading file: "+err;
- });
+ this.container.innerText = "Error loading file: "+err
+ })
}
TextViewer.prototype.render = function(parent) {
- parent.appendChild(this.container);
+ parent.appendChild(this.container)
}
diff --git a/res/include/script/file_viewer/viewer_scripts/VideoViewer.js b/res/include/script/file_viewer/viewer_scripts/VideoViewer.js
index bc9a467..48716df 100644
--- a/res/include/script/file_viewer/viewer_scripts/VideoViewer.js
+++ b/res/include/script/file_viewer/viewer_scripts/VideoViewer.js
@@ -1,24 +1,24 @@
function VideoViewer(viewer, file, next) {
- this.viewer = viewer;
- this.file = file;
- this.next = next;
+ this.viewer = viewer
+ this.file = file
+ this.next = next
- this.vidContainer = document.createElement("div");
- this.vidContainer.classList = "image-container";
+ this.vidContainer = document.createElement("div")
+ this.vidContainer.classList = "image-container"
- this.vidElement = document.createElement("video");
- this.vidElement.autoplay = "autoplay";
- this.vidElement.controls = "controls";
- this.vidElement.classList = "center drop-shadow";
- this.vidElement.addEventListener("ended", () => { this.next(); }, false);
+ this.vidElement = document.createElement("video")
+ this.vidElement.autoplay = "autoplay"
+ this.vidElement.controls = "controls"
+ this.vidElement.classList = "center drop-shadow"
+ this.vidElement.addEventListener("ended", () => { this.next() }, false)
- this.videoSource = document.createElement("source");
- this.videoSource.src = apiEndpoint+"/file/"+this.file.id;
+ this.videoSource = document.createElement("source")
+ this.videoSource.src = this.file.get_href
- this.vidElement.appendChild(this.videoSource);
- this.vidContainer.appendChild(this.vidElement);
+ this.vidElement.appendChild(this.videoSource)
+ this.vidContainer.appendChild(this.vidElement)
}
VideoViewer.prototype.render = function(parent) {
- parent.appendChild(this.vidContainer);
+ parent.appendChild(this.vidContainer)
}
diff --git a/res/include/script/history.js b/res/include/script/history.js
index 5656eab..f35b496 100644
--- a/res/include/script/history.js
+++ b/res/include/script/history.js
@@ -1,78 +1,77 @@
function renderFileButton(apiURL, id, title, subtitle) {
- let btn = document.createElement("a");
- btn.classList = "file_button";
- btn.href = "/u/"+id;
- btn.target = "_blank";
- let thumbnail = document.createElement("img");
- thumbnail.src = apiURL+"/file/"+id+"/thumbnail?width=80&height=80";
- thumbnail.alt = title;
- let titleSpan = document.createElement("span");
- titleSpan.classList = "file_button_title";
- titleSpan.innerText = title;
- let br = document.createElement("br");
- let subtitleSpan = document.createElement("span");
- subtitleSpan.classList = "file_button_subtitle";
- subtitleSpan.innerText = subtitle;
+ let btn = document.createElement("a")
+ btn.classList = "file_button"
+ btn.href = "/u/"+id
+ btn.target = "_blank"
+ let thumbnail = document.createElement("img")
+ thumbnail.src = apiURL+"/file/"+id+"/thumbnail?width=80&height=80"
+ thumbnail.alt = title
+ let titleSpan = document.createElement("span")
+ titleSpan.classList = "file_button_title"
+ titleSpan.innerText = title
+ let br = document.createElement("br")
+ let subtitleSpan = document.createElement("span")
+ subtitleSpan.classList = "file_button_subtitle"
+ subtitleSpan.innerText = subtitle
- btn.appendChild(thumbnail);
- btn.appendChild(titleSpan);
- btn.appendChild(br);
- btn.appendChild(subtitleSpan);
- return btn;
+ btn.appendChild(thumbnail)
+ btn.appendChild(titleSpan)
+ btn.appendChild(br)
+ btn.appendChild(subtitleSpan)
+ return btn
}
function getCookie(name) {
- var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie);
- return result ? result[1] : null;
+ var result = new RegExp('(?:^|; )' + encodeURIComponent(name) + '=([^;]*)').exec(document.cookie)
+ return result ? result[1] : null
}
// Get the uploads from localstorage
-let uploadsStr = localStorage.getItem("uploaded_files");
-if (uploadsStr === null) { uploadsStr = ""; }
+let uploadsStr = localStorage.getItem("uploaded_files")
+if (uploadsStr === null) { uploadsStr = "" }
-let uploads = Array();
+let uploads = Array()
if (uploadsStr != "") {
- uploadsStr = uploadsStr.slice(0, -1); // Strip the trailing comma
- uploads = uploadsStr.split(",");
+ uploadsStr = uploadsStr.slice(0, -1) // Strip the trailing comma
+ uploads = uploadsStr.split(",")
}
// Get the uploads from a cookie
-uploadsStr = getCookie("pduploads");
-if (uploadsStr === null) { uploadsStr = ""; }
+uploadsStr = getCookie("pduploads")
+if (uploadsStr === null) { uploadsStr = "" }
if (uploadsStr != "") {
- uploadsStr = uploadsStr.slice(0, -1); // Strip the trailing dot
- uploads.push(uploadsStr.split(".").reverse());
+ uploadsStr = uploadsStr.slice(0, -1) // Strip the trailing dot
+ uploads.push(uploadsStr.split(".").reverse())
}
// Render all the items
function getHistoryItem() {
- let item = uploads.shift();
- if (item === undefined || item === "") { return; }
+ let item = uploads.shift()
+ if (item === undefined || item === "") { return }
fetch(
apiEndpoint+"/file/"+item+"/info"
).then(resp => {
if (!resp.ok) {
- return Promise.reject();
+ return Promise.reject()
}
- return resp.json();
+ return resp.json()
}).then(resp => {
- let date = new Date(resp.date_upload);
document.getElementById("uploaded_files").appendChild(
renderFileButton(
apiEndpoint,
resp.id,
resp.name,
- date.getFullYear()+"-"+("00"+(date.getMonth()+1)).slice(-2)+"-"+("00"+date.getDate()).slice(-2)
+ printDate(new Date(resp.date_upload), true, true, true),
)
- );
- getHistoryItem();
+ )
+ getHistoryItem()
}).catch(err => {
console.log("Fetch failed: "+err)
- getHistoryItem();
+ getHistoryItem()
})
}
-getHistoryItem();
+getHistoryItem()
diff --git a/res/include/script/homepage.js b/res/include/script/homepage.js
index bf91592..a74ce7f 100644
--- a/res/include/script/homepage.js
+++ b/res/include/script/homepage.js
@@ -1,27 +1,27 @@
function UploadProgressBar(uploadManager, queueDiv, file){
- this.uploadManager = uploadManager;
- this.file = file;
- this.name = file.name;
+ this.uploadManager = uploadManager
+ this.file = file
+ this.name = file.name
- this.uploadDiv = document.createElement("a");
- this.uploadDiv.classList.add("file_button");
- this.uploadDiv.style.opacity = "0";
- this.uploadDiv.innerText = "Queued\n" + this.file.name;
- queueDiv.appendChild(this.uploadDiv);
+ this.uploadDiv = document.createElement("a")
+ this.uploadDiv.classList.add("file_button")
+ this.uploadDiv.style.opacity = "0"
+ this.uploadDiv.innerText = "Queued\n" + this.file.name
+ queueDiv.appendChild(this.uploadDiv)
// Start uploading the file
this.uploadManager.addFile(
this.file,
this.name,
- (progress) => { this.onProgress(progress); },
- (id) => { this.onFinished(id); },
- (val, msg) => { this.onFailure(val, msg); }
- );
+ (progress) => { this.onProgress(progress) },
+ (id) => { this.onFinished(id) },
+ (val, msg) => { this.onFailure(val, msg) }
+ )
// Browsers don't render the transition if the opacity is set and
// updated in the same frame. So we have to wait a frame (or more)
// before changing the opacity to make sure the transition triggers
- window.setTimeout(() => {this.uploadDiv.style.opacity = "1";}, 100)
+ window.setTimeout(() => {this.uploadDiv.style.opacity = "1"}, 100)
}
UploadProgressBar.prototype.onProgress = function(progress){
@@ -33,7 +33,7 @@ UploadProgressBar.prototype.onProgress = function(progress){
+'var(--file_background_color) '+ ((progress*100)+1) +'%)'
}
UploadProgressBar.prototype.onFinished = function(id){
- console.log("Upload finished: "+this.file.name+" "+id);
+ console.log("Upload finished: "+this.file.name+" "+id)
this.uploadDiv.style.background = 'var(--file_background_color)'
this.uploadDiv.href = '/u/'+id
@@ -55,7 +55,7 @@ UploadProgressBar.prototype.onFinished = function(id){
}
UploadProgressBar.prototype.onFailure = function(val, msg) {
if (val === "") {
- val = "Could not connect to server";
+ val = "Could not connect to server"
}
this.uploadDiv.innerHTML = "" // Remove uploading progress
@@ -65,21 +65,21 @@ UploadProgressBar.prototype.onFailure = function(val, msg) {
this.uploadDiv.appendChild(document.createTextNode(msg+" ("+val+")"))
this.uploadDiv.appendChild(document.createElement("br"))
this.uploadDiv.appendChild(document.createTextNode(this.file.name))
- console.log(msg);
+ console.log(msg)
}
-let uploader = null;
-let shareTitle = "";
-let shareLink = "";
+let uploader = null
+let shareTitle = ""
+let shareLink = ""
function handleUploads(files) {
if (uploader === null){
- uploader = new UploadManager(apiEndpoint, uploadsFinished);
+ uploader = new UploadManager(apiEndpoint, uploadsFinished)
}
if (files.length === 0) {
- return;
+ return
}
for (let i = 0; i < files.length; i++) {
@@ -87,10 +87,10 @@ function handleUploads(files) {
uploader,
document.getElementById("uploads_queue"),
files.item(i)
- );
+ )
}
- hideShareButtons();
+ hideShareButtons()
}
function uploadsFinished() {
@@ -98,35 +98,35 @@ function uploadsFinished() {
shareTitle = ""
// Get the finished uploads from the uploader
- let uploadLog = uploader.finishedUploads();
+ let uploadLog = uploader.finishedUploads()
if (uploadLog.length === 1) {
- shareTitle = "Download "+uploadLog[0].fileName+" here";
- shareLink = domainURL()+"/u/"+uploadLog[0].fileID;
+ shareTitle = "Download "+uploadLog[0].fileName+" here"
+ shareLink = domainURL()+"/u/"+uploadLog[0].fileID
- showShareButtons();
+ showShareButtons()
} else if (uploadLog.length > 1) {
- let title = uploadLog.length + " files";
+ let title = uploadLog.length + " files"
createList(
title, true,
).then(resp => {
- console.log("Automatic list ID "+resp.id);
- shareTitle = "View "+title+" here";
- shareLink = domainURL()+"/l/"+resp.id;
+ console.log("Automatic list ID "+resp.id)
+ shareTitle = "View "+title+" here"
+ shareLink = domainURL()+"/l/"+resp.id
- showShareButtons();
+ showShareButtons()
}).catch(err => {
- alert("Failed to generate link. Please check your internet connection and try again.\nError: "+err);
- });
+ alert("Failed to generate link. Please check your internet connection and try again.\nError: "+err)
+ })
}
}
function createList(title, anonymous) {
- let uploads = uploader.finishedUploads();
- let files = Array();
+ let uploads = uploader.finishedUploads()
+ let files = Array()
for (let i = 0; i < uploads.length; i++) {
- files.push({ "id": uploads[i].fileID });
+ files.push({ "id": uploads[i].fileID })
}
return fetch(
@@ -142,34 +142,34 @@ function createList(title, anonymous) {
}
).then(resp => {
if (!resp.ok) {
- return Promise.reject("HTTP error: "+resp.status);
+ return Promise.reject("HTTP error: "+resp.status)
}
- return resp.json();
+ return resp.json()
})
}
function hideShareButtons() {
- document.getElementById("instruction_3_after").style.display = "none";
+ document.getElementById("instruction_3_after").style.display = "none"
}
function showShareButtons() {
- document.getElementById("instruction_3_after").style.display = "";
+ document.getElementById("instruction_3_after").style.display = ""
if (window.navigator && window.navigator.share) {
- document.getElementById("social_buttons").style.display = "none";
+ document.getElementById("social_buttons").style.display = "none"
} else {
- document.getElementById("navigator_share_button").style.display = "none";
+ document.getElementById("navigator_share_button").style.display = "none"
}
}
function copyLink() {
if(copyText(shareLink)) {
- console.log('Text copied');
- document.querySelector("#btn_copy_link>span").textContent = "Copied!";
- document.getElementById("btn_copy_link").classList.add("button_highlight");
+ console.log('Text copied')
+ document.querySelector("#btn_copy_link>span").textContent = "Copied!"
+ document.getElementById("btn_copy_link").classList.add("button_highlight")
} else {
- console.log('Copying not supported');
- alert("Your browser does not support copying text.");
+ console.log('Copying not supported')
+ alert("Your browser does not support copying text.")
}
}
@@ -179,33 +179,39 @@ function copyLink() {
// Relay click event to hidden file field
document.getElementById("upload_file_button").onclick = function() {
- document.getElementById("file_input_field").click();
+ document.getElementById("file_input_field").click()
}
document.getElementById("file_input_field").onchange = function(evt){
// Start uploading the files async
- window.setTimeout(handleUploads(evt.target.files), 1);
+ window.setTimeout(handleUploads(evt.target.files), 1)
// This resets the file input field
- document.getElementById("file_input_field").nodeValue = "";
+ document.getElementById("file_input_field").nodeValue = ""
}
document.getElementById("upload_text_button").onclick = function() {
- window.location.href = '/t/';
+ window.location.href = '/t/'
}
/*
* Drag 'n Drop upload handlers
*/
-document.ondragover = function(e) { e.preventDefault(); e.stopPropagation(); }
-document.ondragenter = function(e) { e.preventDefault(); e.stopPropagation(); }
+document.ondragover = function(e) {
+ e.preventDefault()
+ e.stopPropagation()
+}
+document.ondragenter = function(e) {
+ e.preventDefault()
+ e.stopPropagation()
+}
document.addEventListener('drop', function(e){
if (e.dataTransfer && e.dataTransfer.files.length > 0) {
e.preventDefault()
e.stopPropagation()
// Run async to not freeze the page
- window.setTimeout(handleUploads(e.dataTransfer.files), 1);
+ window.setTimeout(handleUploads(e.dataTransfer.files), 1)
}
})
@@ -218,42 +224,65 @@ document.getElementById("btn_social_share").addEventListener("click", function()
title: "Pixeldrain",
text: shareTitle,
url: shareLink
- });
-});
+ })
+})
document.getElementById("btn_copy_link").addEventListener("click", function() {
- copyLink();
-});
+ copyLink()
+})
document.getElementById("btn_open_link").addEventListener("click", function() {
- window.open(shareLink, '_blank');
-});
+ window.open(shareLink, '_blank')
+})
document.getElementById("btn_social_email").addEventListener("click", function() {
- window.open('mailto:please@set.address?subject=File%20on%20pixeldrain&body=' + shareLink);
-});
+ window.open('mailto:please@set.address?subject=File%20on%20pixeldrain&body=' + shareLink)
+})
document.getElementById("btn_social_twitter").addEventListener("click", function() {
- window.open('https://twitter.com/share?url=' + shareLink);
-});
+ window.open('https://twitter.com/share?url=' + shareLink)
+})
document.getElementById("btn_social_facebook").addEventListener("click", function() {
- window.open('http://www.facebook.com/sharer.php?u=' + shareLink);
-});
+ window.open('http://www.facebook.com/sharer.php?u=' + shareLink)
+})
document.getElementById("btn_social_reddit").addEventListener("click", function() {
- window.open('https://www.reddit.com/submit?url=' + shareLink);
-});
+ window.open('https://www.reddit.com/submit?url=' + shareLink)
+})
document.getElementById("btc_social_tumblr").addEventListener("click", function() {
- window.open('http://www.tumblr.com/share/link?url=' + shareLink);
-});
+ window.open('http://www.tumblr.com/share/link?url=' + shareLink)
+})
/*
* Link copy buttons
*/
+function renderListButton(apiURL, id, title, subtitle) {
+ let btn = document.createElement("a")
+ btn.classList = "file_button"
+ btn.href = "/l/"+id
+ btn.target = "_blank"
+ let thumbnail = document.createElement("img")
+ thumbnail.src = apiURL+"/list/"+id+"/thumbnail?width=80&height=80"
+ thumbnail.alt = title
+ let titleSpan = document.createElement("span")
+ titleSpan.classList = "file_button_title"
+ titleSpan.innerText = title
+ let br = document.createElement("br")
+ let subtitleSpan = document.createElement("span")
+ subtitleSpan.classList = "file_button_subtitle"
+ subtitleSpan.innerText = subtitle
+
+ btn.appendChild(thumbnail)
+ btn.appendChild(titleSpan)
+ btn.appendChild(br)
+ btn.appendChild(subtitleSpan)
+ return btn
+}
+
// Create list button
document.getElementById("btn_create_list").addEventListener("click", function(evt) {
let title = prompt(
"You are creating a list containing " + uploader.finishedUploads().length + " files.\n"
+ "What do you want to call it?", "My New Album"
- );
+ )
if(title === null){
- return;
+ return
}
createList(title, false).then(resp => {
document.getElementById("created_lists").appendChild(
@@ -263,91 +292,91 @@ document.getElementById("btn_create_list").addEventListener("click", function(ev
domainURL()+'/l/'+resp.id,
"List creation finished!",
)
- );
- window.open('/l/'+resp.id, '_blank');
+ )
+ window.open('/l/'+resp.id, '_blank')
}).catch(err => {
let div = document.createElement("div")
- div.className = "file_button";
+ div.className = "file_button"
div.innerHTML = "List creation failed
"
+ "The server responded with:
"
- + err;
- document.getElementById("created_lists").append(div);
- });
-});
+ + err
+ document.getElementById("created_lists").append(div)
+ })
+})
-let btnCopyLinks = document.getElementById("btn_copy_links");
+let btnCopyLinks = document.getElementById("btn_copy_links")
btnCopyLinks.addEventListener("click", function(){
- let text = "";
- let uploads = uploader.finishedUploads();
+ let text = ""
+ let uploads = uploader.finishedUploads()
// Add the text to the textarea
for (let i = 0; i < uploads.length; i++) {
// Example: https://pixeldrain.com/u/abcd1234: Some_file.png
- text += domainURL()+"/u/"+uploads[i].fileID+" "+uploads[i].fileName+"\n";
+ text += domainURL()+"/u/"+uploads[i].fileID+" "+uploads[i].fileName+"\n"
}
if (shareLink.includes("/l/")) {
- text += "\n"+shareLink+" All "+uploads.length+" files\n";
+ text += "\n"+shareLink+" All "+uploads.length+" files\n"
}
// Copy the selected text
if(copyText(text)){
- btnCopyLinks.classList.add("button_highlight");
+ btnCopyLinks.classList.add("button_highlight")
btnCopyLinks.innerHTML = "Links copied to clipboard!"
}else{
- btnCopyLinks.classList.add("button_red");
+ btnCopyLinks.classList.add("button_red")
btnCopyLinks.innerHTML = "Copying links failed"
}
-});
+})
-let btnCopyBBCode = document.getElementById("btn_copy_bbcode");
+let btnCopyBBCode = document.getElementById("btn_copy_bbcode")
btnCopyBBCode.addEventListener("click", function(){
- let text = "";
- let uploads = uploader.finishedUploads();
+ let text = ""
+ let uploads = uploader.finishedUploads()
// Add the text to the textarea
for (let i = 0; i < uploads.length; i++) {
// Example: [url=https://pixeldrain.com/u/abcd1234]Some_file.png[/url]
- text += "[url="+domainURL()+"/u/"+uploads[i].fileID+"]"+uploads[i].fileName+"[/url]\n";
+ text += "[url="+domainURL()+"/u/"+uploads[i].fileID+"]"+uploads[i].fileName+"[/url]\n"
}
if (shareLink.includes("/l/")) {
- text += "\n[url="+shareLink+"]All "+uploads.length+" files[/url]\n";
+ text += "\n[url="+shareLink+"]All "+uploads.length+" files[/url]\n"
}
// Copy the selected text
if(copyText(text)){
- btnCopyBBCode.classList.add("button_highlight");
+ btnCopyBBCode.classList.add("button_highlight")
btnCopyBBCode.innerHTML = "BBCode copied to clipboard!"
}else{
- btnCopyBBCode.classList.add("button_red");
+ btnCopyBBCode.classList.add("button_red")
btnCopyBBCode.innerHTML = "Copying links failed"
}
-});
+})
-let btnCopyMarkdown = document.getElementById("btn_copy_markdown");
+let btnCopyMarkdown = document.getElementById("btn_copy_markdown")
btnCopyMarkdown.addEventListener("click", function(){
- let text = "";
- let uploads = uploader.finishedUploads();
+ let text = ""
+ let uploads = uploader.finishedUploads()
// Add the text to the textarea
for (let i = 0; i < uploads.length; i++) {
// Example: * [Some_file.png](https://pixeldrain.com/u/abcd1234)
- if (uploads.length > 1) { text += " * "; }
- text += "["+uploads[i].fileName+"]("+domainURL()+"/u/"+uploads[i].fileID+")\n";
+ if (uploads.length > 1) { text += " * " }
+ text += "["+uploads[i].fileName+"]("+domainURL()+"/u/"+uploads[i].fileID+")\n"
}
if (shareLink.includes("/l/")) {
- text += " * [All "+uploads.length+" files]("+shareLink+")\n";
+ text += " * [All "+uploads.length+" files]("+shareLink+")\n"
}
// Copy the selected text
if(copyText(text)){
- btnCopyMarkdown.classList.add("button_highlight");
+ btnCopyMarkdown.classList.add("button_highlight")
btnCopyMarkdown.innerHTML = "Markdown copied to clipboard!"
}else{
- btnCopyMarkdown.classList.add("button_red");
+ btnCopyMarkdown.classList.add("button_red")
btnCopyMarkdown.innerHTML = "Copying links failed"
}
-});
+})
/*
@@ -359,13 +388,13 @@ document.addEventListener("keydown", function(event){
}
if (event.keyCode === 67) { // c
// Copy links to clipboard
- document.getElementById("btn_copy_link").click();
+ document.getElementById("btn_copy_link").click()
} else if (event.keyCode === 85) { // u
// Click the upload button
- document.getElementById("file_input_field").click();
+ document.getElementById("file_input_field").click()
} else if (event.keyCode === 84) { // t
// Click the text button
- document.getElementById("upload_text_button").click();
+ document.getElementById("upload_text_button").click()
}
console.log(event.keyCode)
-});
+})
diff --git a/webcontroller/admin_panel.go b/webcontroller/admin_panel.go
index 3098170..520b1e4 100644
--- a/webcontroller/admin_panel.go
+++ b/webcontroller/admin_panel.go
@@ -95,3 +95,45 @@ func (wc *WebController) adminGlobalsForm(td *TemplateData, r *http.Request) (f
}
return f
}
+
+// func (wc *WebController) adminFileDeleteForm(td *TemplateData, r *http.Request) (f Form) {
+// if isAdmin, err := td.PixelAPI.UserIsAdmin(); err != nil {
+// td.Title = err.Error()
+// return Form{Title: td.Title}
+// } else if !isAdmin.IsAdmin {
+// td.Title = ";)"
+// return Form{Title: td.Title}
+// }
+
+// td.Title = "Admin file removal"
+// f = Form{
+// Name: "admin_file_removal",
+// Title: td.Title,
+// PreFormHTML: template.HTML("Paste any pixeldrain file links in here to remove them
"),
+// Fields: []Field{
+// {
+// Name: "files",
+// Label: "Files to delete",
+// Type: FieldTypeTextarea,
+// },
+// },
+// BackLink: "/admin",
+// SubmitLabel: "Submit",
+// }
+
+// if f.ReadInput(r) {
+// filesText := f.FieldVal("files")
+
+// // Get all links from the text
+// strings.Index(filesText, "/u/")
+
+// if len(f.SubmitMessages) == 0 {
+// // Request was a success
+// f.SubmitSuccess = true
+// f.SubmitMessages = []template.HTML{template.HTML(
+// fmt.Sprintf("Success! %d values updated", successfulUpdates),
+// )}
+// }
+// }
+// return f
+// }
diff --git a/webcontroller/file_viewer.go b/webcontroller/file_viewer.go
index 331f8a7..c6432e2 100644
--- a/webcontroller/file_viewer.go
+++ b/webcontroller/file_viewer.go
@@ -2,10 +2,14 @@ package webcontroller
import (
"fmt"
+ "io/ioutil"
"net/http"
+ "strconv"
"strings"
"time"
+ pdmimetype "github.com/Fornaxian/pd_mime_type"
+
"fornaxian.com/pixeldrain-web/pixelapi"
"github.com/Fornaxian/log"
"github.com/julienschmidt/httprouter"
@@ -152,3 +156,90 @@ func (wc *WebController) serveListViewer(w http.ResponseWriter, r *http.Request,
log.Error("Error executing template file_viewer: %s", err)
}
}
+
+// ServeFileViewer controller for GET /s/:id
+func (wc *WebController) serveSkynetViewer(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
+ var err error
+ templateData := wc.newTemplateData(w, r)
+
+ // Get the first few bytes from the file to probe the content type and
+ // length
+ rq, err := http.NewRequest("GET", "https://siasky.net/"+p.ByName("id"), nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // Range header limits the number of bytes which will be read
+ rq.Header.Set("Range", "bytes=0-1023")
+
+ resp, err := wc.httpClient.Do(rq)
+ if err != nil {
+ panic(err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode >= 500 {
+ w.WriteHeader(http.StatusInternalServerError)
+ wc.templates.Get().ExecuteTemplate(w, "500", templateData)
+ return
+ } else if resp.StatusCode >= 400 {
+ w.WriteHeader(http.StatusNotFound)
+ wc.templates.Get().ExecuteTemplate(w, "file_not_found", templateData)
+ return
+ }
+
+ head, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ wc.templates.Get().ExecuteTemplate(w, "500", templateData)
+ return
+ }
+
+ var fileType = resp.Header.Get("Content-Type")
+ if fileType == "application/octet-stream" || fileType == "" {
+ fileType = pdmimetype.Detect(head)
+ }
+
+ // Now get the size of the file from the content-range header
+ contentRange := resp.Header.Get("Content-Range")
+ if contentRange == "" {
+ w.WriteHeader(http.StatusInternalServerError)
+ wc.templates.Get().ExecuteTemplate(w, "500", templateData)
+ return
+ }
+ contentRange = strings.TrimPrefix(contentRange, "bytes ")
+ size, err := strconv.ParseUint(strings.Split(contentRange, "/")[1], 10, 64)
+ if err != nil {
+ panic(err)
+ }
+
+ templateData.OGData = ""
+ templateData.Title = fmt.Sprintf("Skylink ~ pixeldrain")
+ templateData.Other = viewerData{
+ Type: "skylink",
+ APIResponse: pixelapi.FileInfo{
+ Success: true,
+ ID: p.ByName("id"),
+ Name: "skynet_file.dat",
+ Size: size,
+ Views: 0,
+ BandwidthUsed: 0,
+ DateUpload: time.Now(),
+ DateLastView: time.Now(),
+ MimeType: fileType,
+ MimeImage: "",
+ ThumbnailHREF: "",
+ Availability: "",
+ },
+ }
+
+ var templateName = "file_viewer"
+ 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)
+ }
+}
diff --git a/webcontroller/web_controller.go b/webcontroller/web_controller.go
index 6d8e8ef..a7dcc72 100644
--- a/webcontroller/web_controller.go
+++ b/webcontroller/web_controller.go
@@ -6,6 +6,7 @@ import (
"net/http"
"os"
"strings"
+ "time"
"github.com/google/uuid"
@@ -30,6 +31,8 @@ type WebController struct {
// page-specific variables
captchaSiteKey string
+
+ httpClient *http.Client
}
// New initializes a new WebController by registering all the request handlers
@@ -50,6 +53,7 @@ func New(
apiURLInternal: apiURLInternal,
apiURLExternal: apiURLExternal,
sessionCookieDomain: sessionCookieDomain,
+ httpClient: &http.Client{Timeout: time.Minute * 10},
}
wc.templates = NewTemplateManager(resourceDir, apiURLExternal, debugMode)
wc.templates.ParseTemplates(false)
@@ -88,6 +92,7 @@ func New(
r.GET(p+"/u/:id" /* */, wc.serveFileViewer)
r.GET(p+"/u/:id/preview" /**/, wc.serveFilePreview)
r.GET(p+"/l/:id" /* */, wc.serveListViewer)
+ r.GET(p+"/s/:id" /* */, wc.serveSkynetViewer)
r.GET(p+"/t" /* */, wc.serveTemplate("paste", false))
r.GET(p+"/donation" /* */, wc.serveTemplate("donation", false))
r.GET(p+"/widgets" /* */, wc.serveTemplate("widgets", false))