From 7e4002dc001e4943d2ab4783fb826cc8c0884d8a Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 9 Nov 2017 15:49:18 +0800 Subject: [PATCH] v2 --- .gitignore | 2 +- .gitmodules | 3 - README.md | 95 --------- bower.json | 22 +++ config.php.sample | 15 -- db.sql | 12 -- download.php | 82 -------- download2.php | 28 --- file.php | 17 -- gensitemap.php | 18 -- index.html | 26 +++ index.php | 138 ------------- polymer.json | 22 +++ public/main.css | 188 ------------------ public/main.js | 308 ----------------------------- robots.txt | 3 - src/css/style.css | 41 ++++ src/db.sql | 13 ++ src/js/util.js | 86 ++++++++ src/modules/dropzone.html | 157 +++++++++++++++ src/modules/main.html | 54 +++++ src/modules/upload.html | 249 +++++++++++++++++++++++ src/modules/view.html | 126 ++++++++++++ src/php/api.php | 95 +++++++++ src/php/config.php.sample | 25 +++ clean.php => src/php/cron.php | 2 +- db.php => src/php/db.php | 52 ++--- discord.php => src/php/discord.php | 2 +- src/php/download.php | 77 ++++++++ src/php/file.php | 20 ++ upload.php => src/php/upload.php | 57 +++--- views/audio.php | 6 - views/default.php | 6 - views/image.php | 4 - views/stats.php | 36 ---- views/video.php | 7 - 36 files changed, 1077 insertions(+), 1017 deletions(-) delete mode 100644 .gitmodules delete mode 100644 README.md create mode 100644 bower.json delete mode 100644 config.php.sample delete mode 100644 db.sql delete mode 100644 download.php delete mode 100644 download2.php delete mode 100644 file.php delete mode 100644 gensitemap.php create mode 100644 index.html delete mode 100644 index.php create mode 100644 polymer.json delete mode 100644 public/main.css delete mode 100644 public/main.js delete mode 100644 robots.txt create mode 100644 src/css/style.css create mode 100644 src/db.sql create mode 100644 src/js/util.js create mode 100644 src/modules/dropzone.html create mode 100644 src/modules/main.html create mode 100644 src/modules/upload.html create mode 100644 src/modules/view.html create mode 100644 src/php/api.php create mode 100644 src/php/config.php.sample rename clean.php => src/php/cron.php (99%) rename db.php => src/php/db.php (56%) rename discord.php => src/php/discord.php (98%) create mode 100644 src/php/download.php create mode 100644 src/php/file.php rename upload.php => src/php/upload.php (73%) delete mode 100644 views/audio.php delete mode 100644 views/default.php delete mode 100644 views/image.php delete mode 100644 views/stats.php delete mode 100644 views/video.php diff --git a/.gitignore b/.gitignore index 36b145e..294a377 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ out/ *.xml -config.php +src/php/config.php google*.html diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index c581fd6..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "sitemap-php"] - path = sitemap-php - url = https://github.com/o/sitemap-php diff --git a/README.md b/README.md deleted file mode 100644 index b73f378..0000000 --- a/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# baba -Simple file upload with statistics - -## Features - - * Async uploads - * View counter - * Copy/Paste uploads - * Drag&Drop uploads - * File browser uploads - * Eye pain while reading logo text - * Random background colors - -## Screenshots - -![screenshot1](http://shit.host/d37c6bcb25b42d8493d43634a12ee6e2b6241f8aa33eb3b5b55c7552f90c1b65/baba0.PNG) -![screenshot2](http://shit.host/4e6e7c4598533d2e29b1b10d14600333c9fae901ff477b5f05ad8fcfadc080c2/baba1.PNG) -![screenshot3](http://shit.host/bf544fd2b1cc9f32b4556062c7bb77bd64647211c134e7d3811fbd8b43707ca6/baba2.PNG) - -## Roadmap - -See issues. - - -##Install - -### Requirements - - * nginx (or other) - * php5 - * php5-mysql - * mysql-server - -### Setup - -Start by configuring your ```config.php``` with details for you mysql server. - -Next import the sql script to create the table - -``` -cat db.sql | mysql -p -D baba -``` - -Next you need to add a rule to you webserver to use index.php for 404 errors, below is an example for nginx - -``` -location / { - try_files $uri index.php?hash=$uri; -} -``` - -If this is not setup correctly your file links will not work. - - -Another thing you will need to do is adjust the max post size in PHP and nginx, for nginx you add the following: - -``` -client_max_body_size 512M; -``` - -Or whatever you want to the max file size to be. - -In ```php.ini``` change the following: - -``` -memory_limit = 512M -post_max_size = 512M -``` - -You will need to set the memory limit to the same size as your desired max file size since the file is stored in memory while reading from the client. - -```post_max_size``` is the size you will see on the home page. - -Finally make sure the PHP process has access to the directory where files will be saved. - -The default directory is ```out``` in the root of the site. To set this up do the following. - -``` -mkdir out -mkdir out/thumbs -chown www-data:www-data out -R -chmod 770 out -R -``` - -Make sure to reset php5 and your webserver so settings apply - -Run composer - -``` -php composer.phar install -``` - -## License - -Whats that? \ No newline at end of file diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..e7b35f9 --- /dev/null +++ b/bower.json @@ -0,0 +1,22 @@ +{ + "name": "void.cat", + "description": "void.cat", + "main": "index.html", + "authors": [ + "v0l" + ], + "license": "MIT", + "homepage": "https://github.com/v0l/void.cat", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "polymer": "polymer/polymer#^2.0.0", + "webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.17" + } +} diff --git a/config.php.sample b/config.php.sample deleted file mode 100644 index b61832f..0000000 --- a/config.php.sample +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/db.sql b/db.sql deleted file mode 100644 index 41e1f4d..0000000 --- a/db.sql +++ /dev/null @@ -1,12 +0,0 @@ -CREATE TABLE `files` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `hash160` varchar(40) DEFAULT NULL, - `hash256` varchar(64) DEFAULT NULL, - `mime` varchar(64) DEFAULT NULL, - `path` varchar(512) DEFAULT NULL, - `filename` varchar(255) DEFAULT NULL, - `views` int(11) DEFAULT 0 NULL, - `created` timestamp NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (`id`), - KEY `hs160` (`hash160`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=latin1 diff --git a/download.php b/download.php deleted file mode 100644 index 2088169..0000000 --- a/download.php +++ /dev/null @@ -1,82 +0,0 @@ - diff --git a/download2.php b/download2.php deleted file mode 100644 index dbd99f9..0000000 --- a/download2.php +++ /dev/null @@ -1,28 +0,0 @@ - \ No newline at end of file diff --git a/file.php b/file.php deleted file mode 100644 index fc3af4e..0000000 --- a/file.php +++ /dev/null @@ -1,17 +0,0 @@ - \ No newline at end of file diff --git a/gensitemap.php b/gensitemap.php deleted file mode 100644 index b0be66a..0000000 --- a/gensitemap.php +++ /dev/null @@ -1,18 +0,0 @@ -setPath('sitemap/'); - $sitemap->addItem('/', '1.0'); - - $db = new DB(); - $links = $db->GetFiles(); - - foreach($links as $f){ - $url = '/' . $f->hash160 . '&v'; - $sitemap->addItem($url, '0.8', 'daily'); - } - - $sitemap->createSitemapIndex('https://example.com/sitemap/', 'Today'); -?> diff --git a/index.html b/index.html new file mode 100644 index 0000000..6a09f41 --- /dev/null +++ b/index.html @@ -0,0 +1,26 @@ + + + + void.cat + + + + + + + + + + + + +
+
+ void.cat +
+
+ +
+
+ + \ No newline at end of file diff --git a/index.php b/index.php deleted file mode 100644 index eaefa42..0000000 --- a/index.php +++ /dev/null @@ -1,138 +0,0 @@ -GetFile($hash); - if($f->id != 0){ - include_once('download2.php'); - XFastDownload(_UPLOADDIR . $f->hash160, $f->filename, $f->mime); - - if(!isset($_SERVER['HTTP_RANGE'])){ - $db->AddView($f->hash160); - } - } - - exit; - } -?> - - - - GetFile($hash); - } - $title = 'void.cat'; - $maxsizeM = ini_get('post_max_size'); - $maxsize = (int)(str_replace('M', '', $maxsizeM) * 1024 * 1024); - echo ""; - ?> - <?= $title . ($f != null ? ' - ' . $f->filename : '') ?> - - - - - id != 0){ - echo "filename . "\" />"; - echo ""; - - $content_url = _SITEURL . $f->hash160; - if(strpos($f->mime, "image/") === 0) { - echo ""; - echo "mime . "\" />"; - }else if(strpos($f->mime, "audio/") === 0) { - echo ""; - echo "mime . "\" />"; - }else if(strpos($f->mime, "video/") === 0) { - echo ""; - echo "mime . "\" />"; - - $ld = array( - "@context" => "http://schema.org", - "@type" => "VideoObject", - "name" => $f->filename, - "description" => $f->filename . " Video", - "thumbnailUrl" => $content_url . "&thumb", - "uploadDate" => $f->created, - "contentUrl" => $content_url . "&v", - "embedUrl" => $content_url, - "interactionCount" => $f->views - ); - - echo ""; - } - } - } - ?> - - - - - -
- - - id != 0){ - $db->AddView($f->hash160); - - if(strpos($f->mime, "image/") === 0) { - require_once('views/image.php'); - }else if(strpos($f->mime, "audio/") === 0) { - require_once('views/audio.php'); - }else if(strpos($f->mime, "video/") === 0) { - require_once('views/video.php'); - }else { - require_once('views/default.php'); - } - - require_once('views/stats.php'); - }else{ - echo "

File Not Found :/

"; - } - }else{ - echo "
Drop Files < " . $maxsizeM . "
"; - } - ?> -
-

Your Uploads

- History is saved in localStorage (clear) -
- -
- - - - diff --git a/polymer.json b/polymer.json new file mode 100644 index 0000000..a40f535 --- /dev/null +++ b/polymer.json @@ -0,0 +1,22 @@ +{ + "entrypoint": "index.html", + "fragments": [ + "src/modules/main.html", + "src/modules/dropzone.html", + "src/modules/upload.html", + "src/modules/view.html" + ], + "sources": [ + "src/php/*.php", + "src/js/*.js", + "src/css/*.css" + ], + "builds": [ + { + "bundle": true, + "js": { "compile": true, "minify": true }, + "css": { "minify": true }, + "html": { "minify": true } + } + ] +} \ No newline at end of file diff --git a/public/main.css b/public/main.css deleted file mode 100644 index db1e8d1..0000000 --- a/public/main.css +++ /dev/null @@ -1,188 +0,0 @@ -html, body { - margin: 0; - padding: 0; - font-family: Arial; -} - -a { text-decoration: underline; color: inherit; } -a:link { text-decoration: underline; color: inherit; } -a:visited { text-decoration: underline; color: inherit; } -a:hover { text-decoration: underline; color: inherit; } - -audio { - margin-top: 10px; - margin-bottom:10px; -} - -video { - max-height: 500px; - width: 100%; -} - -#main { - width: 700px; - border: 1px solid #555; - background-color: #4B898C; - margin-left: auto; - margin-right: auto; - margin-top: 20px; - border-radius: 3px; - box-shadow: 0px 0px 20px 2px #000; - overflow: hidden; -} - -#main #header -{ - text-align: center; - text-shadow: rgba(7, 255, 255, 0.78) 3px 0px 0px, rgba(255, 75, 75, 0.73) -3px 0px 0px; - color: #555555; - font-size: 50px; - padding: 10px; - border-bottom: 1px solid #aaa; - background-color: #E4E4E4; -} - -#main #header:hover { - cursor: pointer; -} - -#main .imglink -{ - text-align: center; - display: block; -} - -#main .imgview -{ - max-width: 100%; - margin-top: 10px; - margin-bottom: 10px; -} - -#uploads { - margin: 10px; - border: 2px solid #eee; -} - -#uploads .uploadItem{ - height: 50px; - line-height: 45px; - border-bottom: 1px solid #efefef; -} - -#uploads .uploadItem .previewImage { - float: left; - height: 45px; - margin-right: 10px; -} - -#uploads .uploadItem .uploadTitle { - float: left; -} - -#uploads .uploadItem .uploadTitle small{ - color: #bbb; -} - -#uploads .uploadItem .progress { - height: 5px; - display: block; - background-color: #ccc; - float: left; - width: 100%; -} - -#uploads .uploadItem .progress .progressCurrent { - width: 1px; - background-color: green; - height: 5px; - display: block; -} - -#upload { - margin: 10px; - height: 350px; - border: 2px dashed #eee; - background-color: rgba(238, 238, 238, 0.18); - text-align: center; - line-height: 320px; - font-size: 40px; - color: rgba(238, 238, 238, 0.5); -} - -#upload:hover { - cursor: pointer; -} - -#footer { - text-align: center; - line-height: 38px; -} - -#stats -{ - width: 500px; - margin-left: auto; - margin-right: auto; - background-color: #565656; - color: #eee; - padding: 10px; -} - -#download { - text-align: center; - padding: 20px; - margin: 10px; - background-color: #565656; - border: 1px solid #333; - border-radius: 5px; - font-size: 25px; - font-weight: bold; -} - -#history { - margin: 10px; - padding: 10px; - border: 2px solid #eee; - background-color: rgba(238, 238, 238, 0.18); -} - -#history a { - display: block; - margin: 5px; -} - -/* MEDIA OVERWRITE QUERIES */ -@media (max-width: 720px) { - #main { - width: auto; - box-shadow: none; - margin: 0; - } -} - -@media (min-width: 1044px) { - #main { - width: 1024px; - } - #upload { - height: 500px; - line-height: 470px; - } - video { - max-height: 576px; - } -} - -@media (min-width: 2048px) { - #main { - width: 1280px; - } - #upload { - height: 700px; - line-height: 670px; - } - video { - max-height: 720px; - } -} diff --git a/public/main.js b/public/main.js deleted file mode 100644 index e28360b..0000000 --- a/public/main.js +++ /dev/null @@ -1,308 +0,0 @@ -function $(str) { if (str[0] === '.') { return document.getElementsByClassName(str.substring(1)); } else if (str[0] === '#') { return document.getElementById(str.substring(1)); } else { return document.getElementsByTagName(str.substring(1)); } } -function co(b){var a={r:1,g:1,b:1};.25>b?(a.r=0,a.g=4*b):.5>b?(a.r=0,a.b=1+4*(.25-b)):(.75>b?a.r=4*(b-.5):a.g=1+4*(.75-b),a.b=0);return a}; - -//http://stackoverflow.com/questions/18638900/javascript-crc32 -var makeCRCTable = function(){ - var c; - var crcTable = []; - for(var n =0; n < 256; n++){ - c = n; - for(var k =0; k < 8; k++){ - c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - crcTable[n] = c; - } - return crcTable; -} - -var crc32 = function(str) { - var crcTable = window.crcTable || (window.crcTable = makeCRCTable()); - var crc = 0 ^ (-1); - - for (var i = 0; i < str.length; i++ ) { - crc = (crc >>> 8) ^ crcTable[(crc ^ str.charCodeAt(i)) & 0xFF]; - } - - return (crc ^ (-1)) >>> 0; -}; - -function setBG() -{ - var x = Math.random(); - var c = co(x); - document.documentElement.style.backgroundColor = 'rgb(' + parseInt(255*c.r, 10) + ',' + parseInt(255*c.g, 10) + ',' + parseInt(255*c.b, 10) + ')'; -} - -function addDropZoneFunctions() -{ - var dz = document.getElementById('upload'); - dz.addEventListener('dragover', handleDragOver, false); - dz.addEventListener('drop', handleFileSelect, false); - dz.addEventListener('click', handleDropClick, false); -} - -function checkForFrag() -{ - if($('#upload') !== null) - { - addDropZoneFunctions(); - addPasteFunctions(); - } -} - -function addPasteFunctions() -{ - document.addEventListener('paste', handleFilePaste, false); -} - -function loadHistory(){ - var hist = localStorage.getItem("history"); - if(hist !== null && hist.length > 0) { - hist = JSON.parse(hist); - } else { - hist = []; - } - - return hist; -} - -function saveToHistory(r){ - var hist = loadHistory(); - - hist[hist.length] = r; - - localStorage.setItem("history", JSON.stringify(hist)); -} - -function uploadComplete(rsp, id, s) -{ - var upl = $('#' + id); - var upl_p = $('#' + id + '_imagePreview'); - - //remove progress bar - var pb = $('#' + id + '_progress'); - pb.parentElement.parentElement.removeChild(pb.parentElement); - - //resize box - upl.style.height = '100px'; - upl.style.lineHeight = '20px'; - if(upl_p !== null) - { - upl_p.style.height = '100px'; - upl_p.style.maxWidth = '100px'; - } - - //update links etc - if(rsp !== null) - { - switch(rsp.status) - { - case 0: { - //generic error - break; - } - case 1: { - //udupe - break; - } - case 2: { - //save failed - break; - } - case 200:{ - //ok - //upl.innerText = upl.innerText + '' + rsp.hash + ''; - var lk = window.location.host + ((window.location.port !== '80' || window.location.port !== '443') && window.location.port !== '' ? ':' + window.location.port : '') + window.location.pathname + (window.location.pathname.indexOf('/') >= 0 ? '' : '/') + rsp.publichash; - var upl_t = $('#' + id + '_title'); - upl_t.innerHTML = upl_t.innerHTML - + '
Hash256: ' + rsp.hash - + '
Hash160: ' + rsp.publichash + '' - + '
(link)'; - - //save to history - saveToHistory(rsp); - break; - } - } - } -} - -function uploadProgress(evt, id) -{ - switch(evt.type){ - case 'readystatechange':{ - if(evt.target.readyState == 4) - { - uploadComplete(JSON.parse(evt.target.response), id, 0); - } - break; - } - case 'progress':{ - var p = parseFloat(evt.loaded) / parseFloat(evt.total); - var pb = $('#' + id + '_progress'); - pb.style.width = (pb.parentElement.offsetWidth * p) + 'px'; - break; - } - case 'error':{ - break; - } - } -} - -function changeUI() -{ - if($('#uploads').style.display === 'none') - { - //minimize dz - $('#upload').style.lineHeight = "150px"; - $('#upload').style.height = "167px"; - $('#uploads').style.minHeight = "167px"; - $('#uploads').style.display = "block"; - } -} - -/* - * Accepts File/Blob type ONLY -*/ -function uploadFile(f, id) -{ - if(typeof f === "string"){ - var fx = new File([], 'remote'); - fx.type = "text/plain"; - fx.size = 0; - fx.url = f; - - f = fx; - } - - if(f instanceof Blob || f instanceof File) - { - if($('#' + id) === null){ - var nf = document.createElement('div'); - nf.id = id; - nf.className = "uploadItem"; - - //check is image type, add preview pane - if(f.type.indexOf('image') >= 0) - { - var pid = id + '_imagePreview'; - var pi = document.createElement('img'); - pi.id = pid; - pi.className = "previewImage"; - nf.appendChild(pi); - - var fr = new FileReader(); - fr.onload = function (res) { - $('#' + pid).src = res.target.result; - }; - fr.readAsDataURL(f); - } - - //title - var nf_t = document.createElement('div'); - nf_t.id = id + '_title'; - nf_t.className = 'uploadTitle'; - nf_t.innerHTML = f.name; - nf.appendChild(nf_t); - - //progress bar - var nfp = document.createElement('span'); - nfp.className = "progress"; - nf.appendChild(nfp); - - //progress bar inner - var nfp_c = document.createElement('span'); - nfp_c.id = id + '_progress'; - nfp_c.className = "progressCurrent"; - nfp.appendChild(nfp_c); - - $('#uploads').appendChild(nf); - - changeUI(); - - if(f.size > max_upload_size) - { - uploadComplete(null, id, 1); - } - else - { - var xhr = new XMLHttpRequest(); - - xhr.upload.addEventListener('progress', function(evt) { uploadProgress(evt, id); }); - xhr.upload.addEventListener('load', function(evt) { uploadProgress(evt, id); }); - xhr.upload.addEventListener('error', function(evt) { uploadProgress(evt, id); }); - xhr.upload.addEventListener('abort', function(evt) { uploadProgress(evt, id); }); - xhr.addEventListener('readystatechange', function(evt) { uploadProgress(evt, id); }); - - xhr.open("POST", "upload.php?filename=" + f.name + (f.url !== undefined ? "&remote=" + encodeURIComponent(f.url) : "")); - xhr.send(f); - } - } - } -} - -function handleDropClick(evt){ - var i = document.createElement('input'); - i.setAttribute('type', 'file'); - i.addEventListener('change', function(evt){ - var fl = evt.path[0].files; - for(var i = 0; i < fl.length; i++) - { - var file = fl[i]; - - var fid = crc32(file.name); - uploadFile(file, fid); - } - }); - i.click(); -} - -function handleDragOver(evt) -{ - evt.stopPropagation(); - evt.preventDefault(); - evt.dataTransfer.dropEffect = 'copy'; -} - -function handleFileSelect(evt) -{ - evt.stopPropagation(); - evt.preventDefault(); - - var files = evt.dataTransfer.files; - console.log(files); - - for(var i = 0; i < files.length; i++){ - var file = files[i]; - - var fid = crc32(file.name); - if(file.type === ''){ - file.type = 'application/octet-stream'; - } - uploadFile(file, fid); - } -} - -function handleFilePaste(evt) -{ - for(var i = 0; i < evt.clipboardData.items.length; i++) - { - var fid = crc32('' + new Date().getTime()); - var file = evt.clipboardData.items[i]; - if(file.kind === 'file') - { - var file_t = file.getAsFile(); - file_t.name = "clipboard.png"; - uploadFile(file_t, fid); - }else if(file.kind === 'string' && file.type === 'text/plain'){ - var file_t = file.getAsString(function(url){ - if(url.indexOf('http://') === 0 || url.indexOf('https://') === 0) { - uploadFile(url); - } - }); - } - } -} - -setBG(); -checkForFrag(); \ No newline at end of file diff --git a/robots.txt b/robots.txt deleted file mode 100644 index df147db..0000000 --- a/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-agent: * -Disallow: /m/ -Disallow: /mobile/ diff --git a/src/css/style.css b/src/css/style.css new file mode 100644 index 0000000..18ffed4 --- /dev/null +++ b/src/css/style.css @@ -0,0 +1,41 @@ +html, body { + background-color: #dbedf5; + font-family: 'Roboto', sans-serif; + font-size: 12px; + padding: 0; + margin: 0; +} + +.page { + width:1024px; + margin-left:auto; + margin-right:auto; + margin-top:20px; + background-color: #a5d4ea; + border-radius: 5px; + border: 1px solid #aaa; +} + +.content { + padding:20px; +} + +.header{ + text-align: center; + color: #555555; + font-size: 50px; + padding: 10px; + border-bottom: 1px solid #aaa; + background-color: #E4E4E4; + border-radius: 5px 5px 0px 0px; +} + +@media(max-width: 1024px){ + .page { + width: auto; + margin: 10px 0 0 0; + } + .content { + padding: 5px; + } +} \ No newline at end of file diff --git a/src/db.sql b/src/db.sql new file mode 100644 index 0000000..d80cb5b --- /dev/null +++ b/src/db.sql @@ -0,0 +1,13 @@ +CREATE TABLE `files` ( + `hash160` varchar(40) NOT NULL, + `hash256` varchar(64) NOT NULL, + `filename` varchar(255) NOT NULL, + `mime` varchar(64) NOT NULL, + `size` int(11) NOT NULL, + `path` varchar(512) NOT NULL, + `views` int(11) DEFAULT 0 NULL, + `isAdminFile` bit(1) DEFAULT 0 NULL, + `uploaded` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `lastview` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`hash160`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 \ No newline at end of file diff --git a/src/js/util.js b/src/js/util.js new file mode 100644 index 0000000..0cab74c --- /dev/null +++ b/src/js/util.js @@ -0,0 +1,86 @@ +const API = { + xhr: function (method, url, data, cb) { + let x = new XMLHttpRequest(); + x.onreadystatechange = function () { + if (x.readyState === 4 && cb !== undefined && cb !== null && typeof cb === 'function') { + cb(this); + } + } + x.open(method, url, true); + if (data !== null) { + x.setRequestHeader('Content-Type', 'application/json'); + x.send(JSON.stringify(data)); + } else { + x.send(); + } + }, + + sendAPICommand: function (data, cb) { + API.xhr('POST', '/src/php/api.php', data, function (xhr) { + if(xhr.status == 200) { + cb(JSON.parse(xhr.response)); + } + }); + }, + + getServerConfig: function (cb) { + API.sendAPICommand({ cmd: 'config' }, function (data) { + cb(data); + }); + }, + + getFileInfo: function(hash, cb) { + API.sendAPICommand({ cmd: 'file', hash: hash }, function (data) { + cb(data); + }); + } +}; + +const Util = { + formatBytes: function (b, f) { + f = f === undefined ? 2 : f; + if (b >= 1073741824) { + return (b / 1073741824.0).toFixed(f) + ' GiB'; + } else if (b >= 1048576) { + return (b / 1048576.0).toFixed(f) + ' MiB'; + } else if (b >= 1024) { + return (b / 1024.0).toFixed(f) + ' KiB'; + } + return b.toFixed(f | 2) + ' B' + } +}; + +const doCaptcha = function(view){ + API.sendAPICommand({ cmd: 'captcha_config' }, function(data){ + this.view.captchaKey = data.cap_key; + this.view.captchaDL = data.cap_dl; + + window['capLoad'] = function(){ + window["capCb"] = function(rsp){ + API.sendAPICommand({ cmd: 'captcha_verify', hash: this.view.fileInfo.hash160, token: rsp }, function(data){ + if(window.location.search.indexOf('?dl') === 0){ + window.location = window.location.href.replace('?dl#', ''); + }else{ + window.location.reload(); + } + }.bind({ view: this.view })); + }.bind({ view: this.view }); + + grecaptcha.render(document.querySelector('#g-recaptcha'), + { + sitekey: this.view.captchaKey, + callback: 'capCb' + } + ); + }.bind({ view: this.view }); + let cb = document.createElement('div'); + cb.id = 'g-recaptcha'; + + let par = document.querySelector('.content'); + par.insertBefore(cb, par.firstChild); + + let ct = document.createElement('script'); + ct.src = 'https://www.google.com/recaptcha/api.js?onload=capLoad&render=explicit'; + document.head.appendChild(ct); + }.bind({ view: view })); +}; \ No newline at end of file diff --git a/src/modules/dropzone.html b/src/modules/dropzone.html new file mode 100644 index 0000000..6919f7d --- /dev/null +++ b/src/modules/dropzone.html @@ -0,0 +1,157 @@ + + + + + + \ No newline at end of file diff --git a/src/modules/main.html b/src/modules/main.html new file mode 100644 index 0000000..2668285 --- /dev/null +++ b/src/modules/main.html @@ -0,0 +1,54 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/modules/upload.html b/src/modules/upload.html new file mode 100644 index 0000000..d4fb5bd --- /dev/null +++ b/src/modules/upload.html @@ -0,0 +1,249 @@ + + + + + \ No newline at end of file diff --git a/src/modules/view.html b/src/modules/view.html new file mode 100644 index 0000000..1f8706b --- /dev/null +++ b/src/modules/view.html @@ -0,0 +1,126 @@ + + + + + + \ No newline at end of file diff --git a/src/php/api.php b/src/php/api.php new file mode 100644 index 0000000..9cb8831 --- /dev/null +++ b/src/php/api.php @@ -0,0 +1,95 @@ + $c + ); + + switch($c->cmd){ + case "config": + { + require_once("db.php"); + + $db = new DB(); + $rsp["stats"] = $db->GetStats(); + + $maxsizeM = ini_get('post_max_size'); + $maxsize = (int)(str_replace('M', '', $maxsizeM) * 1000 * 1000); + $rsp["maxsize"] = $maxsize; + $rsp["expire"] = _FILE_EXPIRE_TIME; + break; + } + case "file": + { + require_once("db.php"); + + $db = new DB(); + $fi = $db->GetFile($c->hash); + if($fi->hash160 != NULL) + { + unset($fi->path); //block internal path value + $fi->url = _SITEURL . $fi->hash160; + $rsp["file"] = $fi; + + $hashKey = $_SERVER['REMOTE_ADDR'] . ':' . $fi->hash160; + + $redis = new Redis(); + $redis->connect(_REDIS_SERVER); + + $dlCounter = $redis->get($hashKey); + if($dlCounter != False && $dlCounter >= _DL_CAPTCHA) { + $rsp["captcha"] = True; + } + + $redis->close(); + } + break; + } + case "captcha_config": + { + $rsp["cap_key"] = _CAPTCHA_KEY; + $rsp["cap_dl"] = _DL_CAPTCHA; + break; + } + case "captcha_verify": + { + $redis = new Redis(); + $redis->connect(_REDIS_SERVER); + + $hashKey = $_SERVER['REMOTE_ADDR'] . ':' . $c->hash; + + $dlCounter = $redis->get($hashKey); + if($dlCounter != FALSE) { + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify'); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, 'secret=' . _CAPTCHA_SECRET . '&response=' . $c->token . '&remoteip=' . $_SERVER['REMOTE_ADDR']); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $crsp = json_decode(curl_exec($ch)); + curl_close ($ch); + + if($crsp->success == True){ + $dlCounter = 0; + $redis->setEx($hashKey, _CAPTCHA_DL_EXPIRE, 0); + $rsp["ok"] = True; + }else{ + $rsp["ok"] = False; + } + }else{ + $rsp["ok"] = True; + } + + $redis->close(); + break; + } + } + + header('Content-Type: application/json'); + echo json_encode($rsp); +?> \ No newline at end of file diff --git a/src/php/config.php.sample b/src/php/config.php.sample new file mode 100644 index 0000000..0024087 --- /dev/null +++ b/src/php/config.php.sample @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/clean.php b/src/php/cron.php similarity index 99% rename from clean.php rename to src/php/cron.php index 8065fbf..c5369b0 100644 --- a/clean.php +++ b/src/php/cron.php @@ -19,4 +19,4 @@ $discord_data = array("content" => 'Deleted ' . count($fl) . ' expired files.'); include('discord.php'); } -?> +?> \ No newline at end of file diff --git a/db.php b/src/php/db.php similarity index 56% rename from db.php rename to src/php/db.php index e213c77..8df75b2 100644 --- a/db.php +++ b/src/php/db.php @@ -9,7 +9,7 @@ $this->mysqli = new mysqli(_DB_HOST, _DB_USER, _DB_PASS, _DB_DATABASE); if ($this->mysqli->connect_errno) { - $this->error = "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error; + $this->error = "Failed to connect to MySQL: (" . $this->mysqli->connect_errno . ") " . $this->mysqli->connect_error; } } @@ -23,14 +23,18 @@ function Exists256($hash) { - $res = new FileUpload(); + return $this->GetFile($hash, "hash256"); + } + + function GetStats() + { + $res = new FileStats(); - $stmt = $this->mysqli->prepare("select id, hash160, hash256, mime, path, filename, views, created, expire from files where hash256 = ? limit 1"); + $stmt = $this->mysqli->prepare("select count(hash160), sum(size), avg(size) from files"); if($stmt) { - $stmt->bind_param("s", $hash); $stmt->execute(); - $stmt->bind_result($res->id, $res->hash160, $res->hash256, $res->mime, $res->path, $res->filename, $res->views, $res->created, $res->expire); + $stmt->bind_result($res->files, $res->size, $res->avgSize); $stmt->fetch(); $stmt->close(); } @@ -38,16 +42,16 @@ return $res; } - function GetFile($hash) + function GetFile($hash, $hc = "hash160") { $res = new FileUpload(); - $stmt = $this->mysqli->prepare("select id, hash160, hash256, mime, path, filename, views, created, expire from files where hash160 = ? limit 1"); + $stmt = $this->mysqli->prepare("select hash160, hash256, filename, mime, size, path, views, isAdminFile, uploaded, lastview from files where " . $hc . " = ? limit 1"); if($stmt) { $stmt->bind_param("s", $hash); $stmt->execute(); - $stmt->bind_result($res->id, $res->hash160, $res->hash256, $res->mime, $res->path, $res->filename, $res->views, $res->created, $res->expire); + $stmt->bind_result($res->hash160, $res->hash256, $res->filename, $res->mime, $res->size, $res->path, $res->views, $res->isAdminFile, $res->uploaded, $res->lastview); $stmt->fetch(); $stmt->close(); } @@ -59,22 +63,23 @@ { $res = array(); - $stmt = $this->mysqli->prepare("select id, hash160, hash256, mime, path, filename, views, created, expire from files"); + $stmt = $this->mysqli->prepare("select hash160, hash256, filename, mime, size, path, views, isAdminFile, uploaded, lastview from files"); if($stmt) { $stmt->execute(); - $stmt->bind_result($id, $hash160, $hash256, $mime, $path, $filename, $views, $created, $expire); + $stmt->bind_result($hash160, $hash256, $filename, $mime, $size, $path, $views, $isAdminFile, $uploaded, $lastview); while($stmt->fetch()){ $nf = new FileUpload(); - $nf->id = $id; $nf->hash160 = $hash160; $nf->hash256 = $hash256; - $nf->mime = $mime; - $nf->path = $path; $nf->filename = $filename; + $nf->mime = $mime; + $nf->size = $size; + $nf->path = $path; $nf->views = $views; - $nf->created = $created; - $nf->expire = $expire; + $nf->isAdminFile = $isAdminFile; + $nf->uploaded = uploaded; + $nf->lastview = $lastview; array_push($res, $nf); } @@ -86,27 +91,29 @@ function InsertFile($f) { - $stmt = $this->mysqli->prepare("insert into files(hash160, hash256, mime, path, filename, expire) values(?,?,?,?,?, DATE_ADD(NOW(), INTERVAL " . _FILE_EXPIRE_TIME . " DAY))"); + $stmt = $this->mysqli->prepare("insert into files(hash160, hash256, filename, mime, size, path) values(?,?,?,?,?,?)"); if($stmt) { - $stmt->bind_param("sssss", $f->hash160, $f->hash256, $f->mime, $f->path, $f->filename); + $stmt->bind_param("ssssss", $f->hash160, $f->hash256, $f->filename, $f->mime, $f->size, $f->path); $stmt->execute(); $stmt->close(); } } + function DeleteFile($f) { - $stmt = $this->mysqli->prepare("delete from files where id = ?"); + $stmt = $this->mysqli->prepare("delete from files where hash160 = ?"); if($stmt) { - $stmt->bind_param("d", $f->id); + $stmt->bind_param("s", $f->id); $stmt->execute(); $stmt->close(); } } + function AddView($hash160) { - $stmt = $this->mysqli->prepare("update files set views = views + 1, expire = DATE_ADD(NOW(), INTERVAL " . _FILE_EXPIRE_TIME . " DAY) where hash160 = ?"); + $stmt = $this->mysqli->prepare("update files set views = views + 1, lastview = NOW() where hash160 = ?"); if($stmt) { $stmt->bind_param("s", $hash160); @@ -114,11 +121,12 @@ $stmt->close(); } } + function GetExpiredFiles() { $res = array(); - $stmt = $this->mysqli->prepare("select id, hash160, hash256, mime, path, filename, views, created, expire from files where expire < CURRENT_TIMESTAMP"); + $stmt = $this->mysqli->prepare("select hash160 from files where date_add(lastview, INTERVAL " . _FILE_EXPIRE_TIME . " DAY) >= CURRENT_TIMESTAMP"); if($stmt) { $stmt->execute(); @@ -143,4 +151,4 @@ return $res; } }; -?> +?> \ No newline at end of file diff --git a/discord.php b/src/php/discord.php similarity index 98% rename from discord.php rename to src/php/discord.php index b9ecec3..96bc385 100644 --- a/discord.php +++ b/src/php/discord.php @@ -7,4 +7,4 @@ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_exec($curl); } -?> +?> \ No newline at end of file diff --git a/src/php/download.php b/src/php/download.php new file mode 100644 index 0000000..552f2d5 --- /dev/null +++ b/src/php/download.php @@ -0,0 +1,77 @@ +connect(_REDIS_SERVER); + + $dlCounter = $redis->get($hashKey); + if($dlCounter != FALSE) { + if($dlCounter >= _DL_CAPTCHA){ + //redirect for captcha check + $redis->close(); + header('location: ' . _SITEURL . '?dl#' . $hash); + exit(); + } + }else{ + $redis->setEx($hashKey, _CAPTCHA_DL_EXPIRE, 0); + } + + include_once('db.php'); + $db = new DB(); + $f = $db->GetFile($hash); + if($f->hash160 != NULL){ + XFastDownload(_UPLOADDIR . $f->hash160, $f->filename, $f->mime); + + if($validRequest){ + $db->AddView($f->hash160); + $redis->incr($hashKey); + } + } + + $redis->close(); +?> \ No newline at end of file diff --git a/src/php/file.php b/src/php/file.php new file mode 100644 index 0000000..fedab8c --- /dev/null +++ b/src/php/file.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/upload.php b/src/php/upload.php similarity index 73% rename from upload.php rename to src/php/upload.php index 75c2cf2..e649162 100644 --- a/upload.php +++ b/src/php/upload.php @@ -1,6 +1,6 @@ 0, "msg" => null, @@ -20,7 +20,7 @@ if($fsize > $maxsize) { - $response["msg"] = "File size larger than " . $maxsizeM; + $response["msg"] = "File too big"; } else { @@ -71,10 +71,12 @@ //check for dupes $f_e = $db->Exists256($fh); - if($f_e->id != 0) + if($f_e->hash160 != NULL) { //file already exists + $response["status"] = 200; $response["publichash"] = $f_e->hash160; + $response["link"] = _SITEURL . $f_e->hash160; $response["mime"] = $f_e->mime; } else @@ -85,37 +87,40 @@ hash_update($phc, $fh); $ph = hash_final($phc); $response["publichash"] = $ph; - //save to disk $op = _FILEPATH . $ph; $fo = fopen($op, 'wb+'); - stream_copy_to_stream($tmpf, $fo); - fclose($fo); - - //save to db - $f_e = new FileUpload(); - $f_e->hash160 = $ph; - $f_e->hash256 = $fh; - $f_e->mime = $mime; - $f_e->path = $op; - $f_e->filename = $fname; - - $db->InsertFile($f_e); - - $discord_data = array("content" => _SITEURL . $f_e->hash160 . '&v'); - include("discord.php"); + if($fo !== False){ + stream_copy_to_stream($tmpf, $fo); + fclose($fo); + + //save to db + $f_e = new FileUpload(); + $f_e->hash160 = $ph; + $f_e->hash256 = $fh; + $f_e->mime = $mime; + $f_e->size = filesize($op); + $f_e->path = $op; + $f_e->filename = $fname; + + $db->InsertFile($f_e); + $discord_data = array("content" => _SITEURL . $f_e->hash160 . '&v'); + include_once("discord.php"); + + $response["status"] = 200; + $response["link"] = _SITEURL . $f_e->hash160; + $response["mime"] = $mime; + }else{ + $response["status"] = 500; + $response["msg"] = "Server error!"; + } } - //close streams fclose($rawf); fclose($tmpf); - - $response["status"] = 200; - $response["link"] = _SITEURL . $f_e->hash160; - $response["mime"] = $mime; } //return response header('Content-Type: application/json'); echo json_encode($response); -?> +?> \ No newline at end of file diff --git a/views/audio.php b/views/audio.php deleted file mode 100644 index 790e865..0000000 --- a/views/audio.php +++ /dev/null @@ -1,6 +0,0 @@ -hash160; -?> - \ No newline at end of file diff --git a/views/default.php b/views/default.php deleted file mode 100644 index a957dc3..0000000 --- a/views/default.php +++ /dev/null @@ -1,6 +0,0 @@ -hash160; -?> -
- Download filename; ?> -
\ No newline at end of file diff --git a/views/image.php b/views/image.php deleted file mode 100644 index 307a90e..0000000 --- a/views/image.php +++ /dev/null @@ -1,4 +0,0 @@ -hash160; -?> - \ No newline at end of file diff --git a/views/stats.php b/views/stats.php deleted file mode 100644 index 9600eae..0000000 --- a/views/stats.php +++ /dev/null @@ -1,36 +0,0 @@ -= 1073741824) - { - $bytes = number_format($bytes / 1073741824, 2) . ' GB'; - } - elseif ($bytes >= 1048576) - { - $bytes = number_format($bytes / 1048576, 2) . ' MB'; - } - elseif ($bytes >= 1024) - { - $bytes = number_format($bytes / 1024, 2) . ' kB'; - } - elseif ($bytes > 1) - { - $bytes = $bytes . ' bytes'; - } - elseif ($bytes == 1) - { - $bytes = $bytes . ' byte'; - } - else - { - $bytes = '0 bytes'; - } - - return $bytes; - } - - $size = filesize($f->path); -?> -
-
Views: views; ?> Size:
-
diff --git a/views/video.php b/views/video.php deleted file mode 100644 index be1005a..0000000 --- a/views/video.php +++ /dev/null @@ -1,7 +0,0 @@ -hash160; -?> - \ No newline at end of file