mirror of
https://git.v0l.io/Kieran/void.cat.git
synced 2025-09-26 18:16:34 +02:00
add stats and faq
This commit is contained in:
0
examples/embed/README.md
Normal file
0
examples/embed/README.md
Normal file
40
index.html
40
index.html
@@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="header">
|
<div class="header" onclick="window.location.href = '/'">
|
||||||
void.cat
|
void.cat
|
||||||
</div>
|
</div>
|
||||||
<div id="page-upload">
|
<div id="page-upload">
|
||||||
@@ -109,12 +109,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="page-stats">
|
<div id="page-stats">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="page-faq">
|
<div id="page-faq">
|
||||||
|
<div class="faq-section">
|
||||||
|
<div class="faq-header">
|
||||||
|
Are there any restrictions on what can be uploaded
|
||||||
|
</div>
|
||||||
|
<div class="faq-content">
|
||||||
|
No.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-section">
|
||||||
|
<div class="faq-header">
|
||||||
|
How can I embed content in my site
|
||||||
|
</div>
|
||||||
|
<div class="faq-content">
|
||||||
|
I have created a service worker which you can host on your site which will decrypt the links automatically, find
|
||||||
|
more info <a href="https://github.com/v0l/void.cat/blob/v3-b2b/examples/embed" target="_blank">here on github.</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-section">
|
||||||
|
<div class="faq-header">
|
||||||
|
I have more questions
|
||||||
|
</div>
|
||||||
|
<div class="faq-content">
|
||||||
|
Feel free to join <a href="https://discord.gg/8BkxTGs" target="_blank">Discord</a> or send a mail to <a href="mailto:admin@void.cat">admin@void.cat</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="footer-stats">
|
||||||
|
<div><b>Files:</b><span>0</span></div>
|
||||||
|
<div><b>Total Size:</b><span>0 B</span></div>
|
||||||
|
<div><b>24Hr Transfer:</b><span>0 B</span></div>
|
||||||
|
</div>
|
||||||
|
<div id="footer">
|
||||||
|
<a href="javascript:(function() { window.location.href='/#faq'; App.Init(); })()">FAQ</a> | <a href="http://rv6omygg3ksi3dys.onion/" target="_blank">Tor</a>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ins class="adsbygoogle" style="display:block; margin-left: auto; margin-right: auto;" data-ad-client="ca-pub-3289062345896209"
|
<ins class="adsbygoogle" style="display:block; margin-left: auto; margin-right: auto;" data-ad-client="ca-pub-3289062345896209"
|
||||||
data-ad-slot="9187315106" data-ad-format="auto" data-full-width-responsive="true"></ins>
|
data-ad-slot="9187315106" data-ad-format="auto" data-full-width-responsive="true"></ins>
|
||||||
<script>
|
<script>
|
||||||
|
@@ -18,6 +18,10 @@ html, body {
|
|||||||
background-color: #444;
|
background-color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a { text-decoration: none; color: rgb(0, 9, 94); font-weight: bold; }
|
||||||
|
a:visited { text-decoration: none; }
|
||||||
|
a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
width: $page-width;
|
width: $page-width;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@@ -32,7 +36,7 @@ html, body {
|
|||||||
|
|
||||||
#page-view {
|
#page-view {
|
||||||
display:none;
|
display:none;
|
||||||
padding: $page-padding;
|
padding: 10px 10px 0px 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +58,7 @@ html, body {
|
|||||||
|
|
||||||
#page-upload {
|
#page-upload {
|
||||||
display: none;
|
display: none;
|
||||||
padding: $page-padding;
|
padding: 10px 10px 0px 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,10 +145,61 @@ html, body {
|
|||||||
background-color: #790e00;
|
background-color: #790e00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 33.3% 33.3% 33.3%;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
margin: 0px 10px 10px 10px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-stats {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-faq {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-faq .faq-section {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-faq .faq-section .faq-header {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-faq .faq-section .faq-content {
|
||||||
|
display: none;
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.show {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
|
||||||
#page-view .file-info {
|
#page-view .file-info {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 25% 25% 25% 25%;
|
grid-template-columns: 25% 25% 25% 25%;
|
||||||
line-height: 30px;
|
text-align: center;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
margin: 10px 0px 0px 0px;
|
||||||
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
@@ -2,13 +2,12 @@
|
|||||||
* @constant {Object}
|
* @constant {Object}
|
||||||
*/
|
*/
|
||||||
const App = {
|
const App = {
|
||||||
get Version() { return AppVersion },
|
|
||||||
|
|
||||||
Elements: {
|
Elements: {
|
||||||
get Dropzone() { return $('#dropzone') },
|
get Dropzone() { return $('#dropzone') },
|
||||||
get Uploads() { return $('#uploads') },
|
get Uploads() { return $('#uploads') },
|
||||||
get PageView() { return $('#page-view') },
|
get PageView() { return $('#page-view') },
|
||||||
get PageUpload() { return $('#page-upload') }
|
get PageUpload() { return $('#page-upload') },
|
||||||
|
get PageFaq() { return $('#page-faq') }
|
||||||
},
|
},
|
||||||
|
|
||||||
Templates: {
|
Templates: {
|
||||||
@@ -35,15 +34,34 @@ const App = {
|
|||||||
/**
|
/**
|
||||||
* Sets up the page
|
* Sets up the page
|
||||||
*/
|
*/
|
||||||
Init: function () {
|
Init: async function () {
|
||||||
if (location.hash !== "") {
|
if (location.hash !== "") {
|
||||||
App.Elements.PageUpload.style.display = "none";
|
if (location.hash == "#faq") {
|
||||||
App.Elements.PageView.style.display = "block";
|
let faq_headers = document.querySelectorAll('#page-faq .faq-header');
|
||||||
new ViewManager();
|
for (let x = 0; x < faq_headers.length; x++) {
|
||||||
|
faq_headers[x].addEventListener('click', function() {
|
||||||
|
this.nextElementSibling.classList.toggle("show");
|
||||||
|
}.bind(faq_headers[x]));
|
||||||
|
}
|
||||||
|
App.Elements.PageUpload.style.display = "none";
|
||||||
|
App.Elements.PageFaq.style.display = "block";
|
||||||
|
} else {
|
||||||
|
App.Elements.PageUpload.style.display = "none";
|
||||||
|
App.Elements.PageView.style.display = "block";
|
||||||
|
new ViewManager();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
App.Elements.PageUpload.style.display = "block";
|
App.Elements.PageUpload.style.display = "block";
|
||||||
App.Elements.PageView.style.display = "none";
|
App.Elements.PageView.style.display = "none";
|
||||||
new DropzoneManager(App.Elements.Dropzone);
|
new DropzoneManager(App.Elements.Dropzone);
|
||||||
|
|
||||||
|
let stats = await Api.GetSiteInfo();
|
||||||
|
if(stats.ok){
|
||||||
|
let elms = document.querySelectorAll("#footer-stats div span");
|
||||||
|
elms[0].textContent = stats.data.basic_stats.Files;
|
||||||
|
elms[1].textContent = Utils.FormatBytes(stats.data.basic_stats.Size, 2);
|
||||||
|
elms[2].textContent = Utils.FormatBytes(stats.data.basic_stats.Transfer_24h, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -81,6 +81,12 @@ const Api = {
|
|||||||
return JSON.parse((await JsonXHR('POST', '/api', req)).response);
|
return JSON.parse((await JsonXHR('POST', '/api', req)).response);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
GetSiteInfo: async function (id) {
|
||||||
|
return await Api.DoRequest({
|
||||||
|
cmd: 'site_info'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
GetFileInfo: async function (id) {
|
GetFileInfo: async function (id) {
|
||||||
return await Api.DoRequest({
|
return await Api.DoRequest({
|
||||||
cmd: 'file_info',
|
cmd: 'file_info',
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
class Api implements RequestHandler {
|
class Api implements RequestHandler {
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
Config::LoadConfig(array('upload_folder', 'recaptcha_site_key', 'recaptcha_secret'));
|
Config::LoadConfig(array('max_upload_size', 'upload_folder', 'recaptcha_site_key', 'recaptcha_secret'));
|
||||||
|
|
||||||
ini_set('enable_post_data_reading', 0);
|
ini_set('enable_post_data_reading', 0);
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,14 @@
|
|||||||
$fs = new FileStore(Config::$Instance->upload_folder);
|
$fs = new FileStore(Config::$Instance->upload_folder);
|
||||||
|
|
||||||
switch($cmd->cmd){
|
switch($cmd->cmd){
|
||||||
|
case "site_info": {
|
||||||
|
$rsp->ok = true;
|
||||||
|
$rsp->data = array(
|
||||||
|
"max_upload_size" => Config::$Instance->max_upload_size,
|
||||||
|
"basic_stats" => Stats::Get()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "file_info": {
|
case "file_info": {
|
||||||
$rsp->ok = true;
|
$rsp->ok = true;
|
||||||
$rsp->data = $fs->GetFileInfo($cmd->id);
|
$rsp->data = $fs->GetFileInfo($cmd->id);
|
||||||
|
13
src/php/cron.php
Normal file
13
src/php/cron.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
include_once("init.php");
|
||||||
|
|
||||||
|
StaticRedis::Connect();
|
||||||
|
Config::LoadConfig(array("upload_folder"));
|
||||||
|
|
||||||
|
$fs = new FileStore(Config::$Instance->upload_folder, "/usr/local/nginx/html");
|
||||||
|
|
||||||
|
echo "Loading stats for: " . $fs->GetUploadDirAbsolute() . "\n";
|
||||||
|
//echo "\n\t" . implode("\n\t", $fs->ListFiles()) . "\n";
|
||||||
|
|
||||||
|
Stats::Collect($fs);
|
||||||
|
?>
|
@@ -29,7 +29,7 @@
|
|||||||
$tracking = new Tracking();
|
$tracking = new Tracking();
|
||||||
|
|
||||||
$abuse->CheckDownload($id);
|
$abuse->CheckDownload($id);
|
||||||
$tracking->TrackDownload($id);
|
$tracking->TrackDownload($this->Fs, $id);
|
||||||
|
|
||||||
//allow embeded header from preflight check
|
//allow embeded header from preflight check
|
||||||
if($_SERVER["REQUEST_METHOD"] === "OPTIONS"){
|
if($_SERVER["REQUEST_METHOD"] === "OPTIONS"){
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
class FileStore {
|
class FileStore {
|
||||||
private $UploadFolder;
|
private $UploadFolder;
|
||||||
|
private $DocumentRoot;
|
||||||
|
|
||||||
public function __construct($path) {
|
public function __construct($dir, $root = null) {
|
||||||
$this->UploadFolder = $path;
|
$this->UploadFolder = $dir;
|
||||||
|
$this->DocumentRoot = $root === null ? $_SERVER["DOCUMENT_ROOT"] : $root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function SetFileStats($info) : void {
|
public function SetFileStats($info) : void {
|
||||||
@@ -27,12 +29,16 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetUploadDirAbsolute() : string {
|
||||||
|
return "$this->DocumentRoot/$this->UploadFolder";
|
||||||
|
}
|
||||||
|
|
||||||
public function GetRelativeFilePath($id) : string {
|
public function GetRelativeFilePath($id) : string {
|
||||||
return "$this->UploadFolder/$id";
|
return "$this->UploadFolder/$id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetAbsoluteFilePath($id) : string {
|
public function GetAbsoluteFilePath($id) : string {
|
||||||
return "$_SERVER[DOCUMENT_ROOT]/$this->UploadFolder/$id";
|
return "$this->GetUploadDirAbsolute()/$this->UploadFolder/$id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GetFileInfo($id) : ?FileInfo {
|
public function GetFileInfo($id) : ?FileInfo {
|
||||||
@@ -67,5 +73,13 @@
|
|||||||
fclose($fout);
|
fclose($fout);
|
||||||
fclose($input);
|
fclose($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetFileSize($id) : int {
|
||||||
|
return filesize($this->GetAbsoluteFilePath($id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ListFiles() : array {
|
||||||
|
return glob($this->GetUploadDirAbsolute() . "/*");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
@@ -1,15 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
define('REDIS_CONFIG', 'redis-host');
|
include_once("init.php");
|
||||||
define('REDIS_PREFIX', 'vc:');
|
|
||||||
define('USER_IP', isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR']);
|
|
||||||
|
|
||||||
if(!isset($_COOKIE["VC:UID"])) {
|
|
||||||
setcookie("VC:UID", uniqid());
|
|
||||||
}
|
|
||||||
|
|
||||||
spl_autoload_register(function ($class_name) {
|
|
||||||
include dirname(__FILE__) . '/' . strtolower($class_name) . '.php';
|
|
||||||
});
|
|
||||||
|
|
||||||
//Startup
|
//Startup
|
||||||
if(StaticRedis::Connect() == True) {
|
if(StaticRedis::Connect() == True) {
|
||||||
|
13
src/php/init.php
Normal file
13
src/php/init.php
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
define('REDIS_CONFIG', 'redis-host');
|
||||||
|
define('REDIS_PREFIX', 'vc:');
|
||||||
|
define('USER_IP', isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : "127.0.0.1"));
|
||||||
|
|
||||||
|
if(!isset($_COOKIE["VC:UID"])) {
|
||||||
|
setcookie("VC:UID", uniqid());
|
||||||
|
}
|
||||||
|
|
||||||
|
spl_autoload_register(function ($class_name) {
|
||||||
|
include dirname(__FILE__) . '/' . strtolower($class_name) . '.php';
|
||||||
|
});
|
||||||
|
?>
|
53
src/php/stats.php
Normal file
53
src/php/stats.php
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
class Stats {
|
||||||
|
public $Files;
|
||||||
|
public $Size;
|
||||||
|
public $Transfer_24h;
|
||||||
|
|
||||||
|
private static $TransferStatsKey = REDIS_PREFIX . "stats-transfer-all";
|
||||||
|
private static $GeneralStatsKey = REDIS_PREFIX . "stats-general";
|
||||||
|
|
||||||
|
public static function Get() : Stats {
|
||||||
|
$redis = StaticRedis::$Instance;
|
||||||
|
|
||||||
|
//calculate 24hr transfer stats
|
||||||
|
$tx_24h_array = $redis->zRange(self::$TransferStatsKey, 0, 24, true); //stats are 1hr interval
|
||||||
|
$tx_24h = 0;
|
||||||
|
foreach($tx_24h_array as $tx_key => $tx_bytes) {
|
||||||
|
$tx_24h += $tx_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get general stats
|
||||||
|
$general = (object)$redis->hMGet(self::$GeneralStatsKey, array("files", "size"));
|
||||||
|
|
||||||
|
$ret = new Stats();
|
||||||
|
$ret->Transfer_24h = $tx_24h;
|
||||||
|
$ret->Files = intval($general->files !== False ? $general->files : 0);
|
||||||
|
$ret->Size = intval($general->size !== False ? $general->size : 0);
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function TrackTransfer($id, $size) : void {
|
||||||
|
$redis = StaticRedis::$Instance;
|
||||||
|
|
||||||
|
$stat_member = date("YmdH");
|
||||||
|
$redis->zIncrBy(self::$TransferStatsKey, $size, $stat_member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function Collect($fs) : void {
|
||||||
|
$redis = StaticRedis::$Instance;
|
||||||
|
|
||||||
|
$files = $fs->ListFiles();
|
||||||
|
$total_size = 0;
|
||||||
|
foreach($files as $file) {
|
||||||
|
$total_size += filesize($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$redis->hMSet(self::$GeneralStatsKey, array(
|
||||||
|
"files" => count($files),
|
||||||
|
"size" => $total_size
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@@ -6,7 +6,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function HandleRequest() : void {
|
public function HandleRequest() : void {
|
||||||
|
|
||||||
if(isset($_SERVER["HTTP_X_FILE_ID"])) {
|
if(isset($_SERVER["HTTP_X_FILE_ID"])) {
|
||||||
$id = $_SERVER["HTTP_X_FILE_ID"];
|
$id = $_SERVER["HTTP_X_FILE_ID"];
|
||||||
$fs = new FileStore(Config::$Instance->upload_folder);
|
$fs = new FileStore(Config::$Instance->upload_folder);
|
||||||
@@ -14,7 +13,7 @@
|
|||||||
//resolve the hostnames to ips
|
//resolve the hostnames to ips
|
||||||
$redis = StaticRedis::$Instance;
|
$redis = StaticRedis::$Instance;
|
||||||
$sync_hosts = $redis->sMembers(REDIS_PREFIX . 'sync-hosts');
|
$sync_hosts = $redis->sMembers(REDIS_PREFIX . 'sync-hosts');
|
||||||
|
|
||||||
$sync_hosts_ips = array();
|
$sync_hosts_ips = array();
|
||||||
foreach($sync_hosts as $host) {
|
foreach($sync_hosts as $host) {
|
||||||
$sync_hosts_ips[] = gethostbyname($host);
|
$sync_hosts_ips[] = gethostbyname($host);
|
||||||
@@ -23,16 +22,19 @@
|
|||||||
//check the ip of the host submitting the file for sync
|
//check the ip of the host submitting the file for sync
|
||||||
if(in_array(USER_IP, $sync_hosts_ips)) {
|
if(in_array(USER_IP, $sync_hosts_ips)) {
|
||||||
$fs->StoreFile("php://input", $id);
|
$fs->StoreFile("php://input", $id);
|
||||||
|
http_response_code(201);
|
||||||
} else {
|
} else {
|
||||||
http_response_code(401);
|
http_response_code(401);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
http_response_code(200);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function SyncFile($id, $filename, $host) : void {
|
public static function SyncFile($id, $filename, $host) : int {
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, "https://$host/sync");
|
curl_setopt($ch, CURLOPT_URL, "https://$host/sync");
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||||||
@@ -42,7 +44,10 @@
|
|||||||
"X-File-Id: " . $id
|
"X-File-Id: " . $id
|
||||||
));
|
));
|
||||||
curl_exec($ch);
|
curl_exec($ch);
|
||||||
|
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
|
||||||
curl_close ($ch);
|
curl_close ($ch);
|
||||||
|
|
||||||
|
return intval($status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,27 +1,45 @@
|
|||||||
<?php
|
<?php
|
||||||
class Tracking {
|
class Tracking {
|
||||||
public function TrackDownload($id) : void {
|
public function TrackDownload($fs, $id) : void {
|
||||||
$redis = StaticRedis::$Instance;
|
$redis = StaticRedis::$Instance;
|
||||||
$file_key = REDIS_PREFIX . $id;
|
$file_key = REDIS_PREFIX . $id;
|
||||||
|
|
||||||
|
$file_size = $fs->GetFileSize($id);
|
||||||
|
|
||||||
if(!$this->IsRangeRequest()) {
|
if(!$this->IsRangeRequest()) {
|
||||||
$redis->hIncrBy($file_key, 'views', 1);
|
$redis->hIncrBy($file_key, 'views', 1);
|
||||||
$redis->hSet($file_key, 'lastview', time());
|
$redis->hSet($file_key, 'lastview', time());
|
||||||
|
|
||||||
|
Stats::TrackTransfer($id, $file_size);
|
||||||
|
} else {
|
||||||
|
$range = $this->GetRequestRange($file_size);
|
||||||
|
Stats::TrackTransfer($id, $range->end - $range->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->SendMatomoEvent();
|
$this->SendMatomoEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
function IsRangeRequest() : bool {
|
function GetRequestRange($len) : ?object {
|
||||||
if(isset($_SERVER['HTTP_RANGE'])) {
|
if(isset($_SERVER['HTTP_RANGE'])) {
|
||||||
$rby = explode('=', $_SERVER['HTTP_RANGE']);
|
$rby = explode('=', $_SERVER['HTTP_RANGE']);
|
||||||
$rbv = explode('-', $rby[1]);
|
$rbv = explode('-', $rby[1]);
|
||||||
if($rbv[0] != '0'){
|
return (object)array(
|
||||||
return True;
|
"start" => intval($rbv[0]),
|
||||||
}
|
"end" => intval($rbv[1] == "" ? $len : $rbv[1])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return False;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsRangeRequest() : bool {
|
||||||
|
$range = $this->GetRequestRange(0);
|
||||||
|
if($range !== null){
|
||||||
|
if($range->start != 0){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function SendMatomoEvent() : void {
|
function SendMatomoEvent() : void {
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
public $status = 0;
|
public $status = 0;
|
||||||
public $msg;
|
public $msg;
|
||||||
public $id;
|
public $id;
|
||||||
|
public $sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Upload implements RequestHandler {
|
class Upload implements RequestHandler {
|
||||||
@@ -39,8 +40,7 @@
|
|||||||
$id = $this->SaveUpload($bf);
|
$id = $this->SaveUpload($bf);
|
||||||
|
|
||||||
//sync to other servers
|
//sync to other servers
|
||||||
$this->SyncFileUpload($id);
|
$rsp->sync = $this->SyncFileUpload($id);
|
||||||
|
|
||||||
$rsp->status = 200;
|
$rsp->status = 200;
|
||||||
$rsp->id = $id;
|
$rsp->id = $id;
|
||||||
} else {
|
} else {
|
||||||
@@ -52,16 +52,18 @@
|
|||||||
echo json_encode($rsp);
|
echo json_encode($rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SyncFileUpload($id) : void {
|
function SyncFileUpload($id) : array {
|
||||||
$redis = StaticRedis::$Instance;
|
$redis = StaticRedis::$Instance;
|
||||||
$sync_hosts = $redis->sMembers(REDIS_PREFIX . 'sync-hosts');
|
$sync_hosts = $redis->sMembers(REDIS_PREFIX . 'sync-hosts');
|
||||||
if($sync_hosts !== False) {
|
if($sync_hosts !== False) {
|
||||||
$fs = new FileStore(Config::$Instance->upload_folder);
|
$fs = new FileStore(Config::$Instance->upload_folder);
|
||||||
|
|
||||||
|
$status_codes = [];
|
||||||
foreach($sync_hosts as $host) {
|
foreach($sync_hosts as $host) {
|
||||||
Sync::SyncFile($id, $fs->GetAbsoluteFilePath($id), $host);
|
$status_codes[] = Sync::SyncFile($id, $fs->GetAbsoluteFilePath($id), $host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $status_codes;
|
||||||
/*
|
/*
|
||||||
$sync_threads = array();
|
$sync_threads = array();
|
||||||
foreach($sync_hosts as $host) {
|
foreach($sync_hosts as $host) {
|
||||||
@@ -77,6 +79,8 @@
|
|||||||
$thread->join();
|
$thread->join();
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
function SaveUpload($bf) : string {
|
function SaveUpload($bf) : string {
|
||||||
|
Reference in New Issue
Block a user