- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
504 lines
24 KiB
PHP
504 lines
24 KiB
PHP
<?php
|
|
/*******************************************************************************************************************
|
|
| Software Name : EasyStream
|
|
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
|
| Software Author : (c) Sami Ahmed
|
|
|*******************************************************************************************************************
|
|
|
|
|
|*******************************************************************************************************************
|
|
| This source file is subject to the EasyStream Proprietary License Agreement.
|
|
|
|
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
|
|*******************************************************************************************************************
|
|
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
|
|*******************************************************************************************************************/
|
|
|
|
define('_ISVALID', true);
|
|
|
|
$main_dir = realpath(dirname(__FILE__) . '/../../../');
|
|
|
|
set_time_limit(0);
|
|
//ignore_user_abort(1);
|
|
set_include_path($main_dir);
|
|
ini_set("error_reporting", E_ALL & ~E_STRICT & ~E_NOTICE & ~E_DEPRECATED);
|
|
|
|
include_once 'f_core/config.core.php';
|
|
|
|
if (empty($_SERVER["argv"][1])) {
|
|
exit;
|
|
}
|
|
|
|
$sitemap_basename = 'basename';
|
|
|
|
$limit = null;
|
|
$vidid = null;
|
|
$p = null;
|
|
$mp4 = null;
|
|
$type = $class_filter->clr_str($_SERVER["argv"][1]);
|
|
|
|
if ($type != 'video' and $type != 'short' and $type != 'image') {
|
|
exit;
|
|
}
|
|
|
|
if (isset($_GET['limit'])) {
|
|
$limit = preg_replace("/[^0-9,]/", "", $_GET['limit']);
|
|
if ($limit) {
|
|
$limit = "LIMIT $limit";
|
|
}
|
|
|
|
}
|
|
|
|
if (isset($_GET['vid'])) {
|
|
$vidid = preg_replace("/[^0-9]/", "", $_GET['vid']);
|
|
if ($vidid) {
|
|
$vidid = "AND vid_id > $vidid";
|
|
}
|
|
|
|
}
|
|
|
|
$skey = "last_" . $type . "_sitemap";
|
|
$cfg[] = $class_database->getConfigurations($skey . ',stream_method,stream_server,stream_lighttpd_secure');
|
|
$lvid = $cfg[$skey];
|
|
//$lvid = 0;//reset, start from id0
|
|
$vidid = "AND A.`db_id` > $lvid";
|
|
|
|
$limit = 'LIMIT 1000';
|
|
|
|
$sql = sprintf("SELECT
|
|
A.`db_id`, A.`file_key`, A.`upload_date`, A.`file_duration`, A.`file_views`, A.`upload_server`, A.`thumb_server`, A.`embed_src`, A.`embed_key`, A.`file_hd`, A.`thumb_cache`,
|
|
A.`file_title`, A.`file_description`, A.`file_tags`,
|
|
D.`usr_key`
|
|
FROM `db_%sfiles` A, `db_accountuser` D WHERE
|
|
A.`usr_id`=D.`usr_id` AND
|
|
A.`active`='1' AND A.`deleted`='0' AND A.`approved`='1'
|
|
%s ORDER BY A.`db_id` ASC %s;", $type, $vidid, $limit);
|
|
|
|
$res = $db->execute($sql);
|
|
|
|
//exit;
|
|
|
|
$SitemapNode = new VSitemap($cfg['sitemap_dir'] . '/sm_' . $type, $sitemap_basename, $type);
|
|
|
|
if ($res->fields["file_key"]) {
|
|
while (!$res->EOF) {
|
|
$db_id = $res->fields["db_id"];
|
|
$vid_id = $res->fields["file_key"];
|
|
$usr_id = $res->fields["usr_key"];
|
|
$tmb_srv = $res->fields["thumb_server"];
|
|
$vid_srv = $res->fields["upload_server"];
|
|
$db_title = $res->fields["file_title"];
|
|
$_fsrc = $res->fields["embed_src"];
|
|
$_furl = $res->fields["embed_key"];
|
|
$hd = $res->fields["file_hd"];
|
|
$thumb_cache = $res->fields["thumb_cache"];
|
|
$thumb_cache = $thumb_cache > 1 ? $thumb_cache : null;
|
|
|
|
if ($hd == 0) {
|
|
$hd = '';
|
|
}
|
|
|
|
$title = html_convert_entities(htmlspecialchars($db_title));
|
|
$description = html_convert_entities(htmlspecialchars($res->fields["file_description"]));
|
|
$screenshot = VGenerate::thumbSigned($type, $vid_id, array($usr_id, $thumb_cache), (3600 * 24 * 7), 0);
|
|
$duration = $res->fields["file_duration"];
|
|
$view_count = $res->fields["file_views"];
|
|
$tags = explode(" ", $res->fields["file_tags"]);
|
|
$date = date(DATE_ATOM, strtotime($res->fields["upload_date"]));
|
|
|
|
$url = VGenerate::fileURL($type, $vid_id, 'upload');
|
|
$link = $cfg["main_url"] . '/' . VGenerate::fileHref($type[0], $vid_id, $db_title);
|
|
|
|
$_src = VPlayers::fileSources($type, $usr_id, $vid_id);
|
|
|
|
$sql = sprintf("SELECT
|
|
A.`server_type`, A.`lighttpd_url`, A.`lighttpd_secdownload`, A.`lighttpd_prefix`, A.`lighttpd_key`, A.`cf_enabled`, A.`cf_dist_type`,
|
|
A.`cf_signed_url`, A.`cf_signed_expire`, A.`cf_key_pair`, A.`cf_key_file`, A.`s3_bucketname`, A.`s3_accesskey`, A.`s3_secretkey`,
|
|
B.`upload_server`
|
|
FROM
|
|
`db_servers` A, `db_%sfiles` B
|
|
WHERE
|
|
B.`file_key`='%s' AND
|
|
B.`upload_server` > '0' AND
|
|
A.`server_id`=B.`upload_server` LIMIT 1;", $type, $vid_id);
|
|
$srv = $db->execute($sql);
|
|
|
|
$cf_signed_url = $srv->fields["cf_signed_url"];
|
|
$cf_signed_expire = 3600 * 24 * 2; //$srv->fields["cf_signed_expire"];
|
|
$cf_key_pair = $srv->fields["cf_key_pair"];
|
|
$cf_key_file = $srv->fields["cf_key_file"];
|
|
$aws_access_key_id = $srv->fields["s3_accesskey"];
|
|
$aws_secret_key = $srv->fields["s3_secretkey"];
|
|
$aws_bucket = $srv->fields["s3_bucketname"];
|
|
|
|
if (count($_src) > 0) {
|
|
$_file = array();
|
|
foreach ($_src as $k => $v) {
|
|
if (($srv->fields["lighttpd_url"] != '' and $srv->fields["lighttpd_secdownload"] == 1) or ($cfg["stream_method"] == 2 and $cfg["stream_server"] == 'lighttpd' and $cfg["stream_lighttpd_secure"] == 1)) {
|
|
$l0 = explode("/", $v[0]);
|
|
$loc0 = $cfg["media_files_dir"] . '/' . $l0[6] . '/' . $l0[7] . '/' . $l0[8];
|
|
$l1 = explode("/", $v[1]);
|
|
$loc1 = $cfg["media_files_dir"] . '/' . $l1[6] . '/' . $l1[7] . '/' . $l1[8];
|
|
$l2 = explode("/", $v[2]);
|
|
$loc2 = $cfg["media_files_dir"] . '/' . $l2[6] . '/' . $l2[7] . '/' . $l2[8];
|
|
} elseif ($cfg["stream_method"] == 2 and $cfg["stream_server"] == 'lighttpd' and $cfg["stream_lighttpd_secure"] == 0) {
|
|
$loc0 = str_replace($cfg["stream_lighttpd_url"], $cfg["media_files_dir"], $v[0]);
|
|
$loc1 = str_replace($cfg["stream_lighttpd_url"], $cfg["media_files_dir"], $v[1]);
|
|
$loc2 = str_replace($cfg["stream_lighttpd_url"], $cfg["media_files_dir"], $v[2]);
|
|
} else {
|
|
$loc0 = str_replace($url, $cfg["media_files_dir"], $v[0]);
|
|
$loc1 = str_replace($url, $cfg["media_files_dir"], $v[1]);
|
|
$loc2 = str_replace($url, $cfg["media_files_dir"], $v[2]);
|
|
|
|
if ($srv->fields["server_type"] == 's3' and $srv->fields["cf_enabled"] == 1 and $cf_signed_url == 1) {
|
|
if ($srv->fields["cf_dist_type"] == 'r') {
|
|
$v[0] = strstr($v[0], $videos->fields["usr_key"]);
|
|
$v[1] = strstr($v[1], $videos->fields["usr_key"]);
|
|
$v[2] = strstr($v[2], $videos->fields["usr_key"]);
|
|
|
|
$v[0] = VbeServers::getS3SignedURL($aws_access_key_id, $aws_secret_key, $v[0], $aws_bucket, $cf_signed_expire);
|
|
$v[1] = VbeServers::getS3SignedURL($aws_access_key_id, $aws_secret_key, $v[1], $aws_bucket, $cf_signed_expire);
|
|
$v[2] = VbeServers::getS3SignedURL($aws_access_key_id, $aws_secret_key, $v[2], $aws_bucket, $cf_signed_expire);
|
|
} else {
|
|
$v[0] = VbeServers::getSignedURL($v[0], $cf_signed_expire, $cf_key_pair, $cf_key_file, 0, 0);
|
|
$v[1] = VbeServers::getSignedURL($v[1], $cf_signed_expire, $cf_key_pair, $cf_key_file, 0, 0);
|
|
$v[2] = VbeServers::getSignedURL($v[2], $cf_signed_expire, $cf_key_pair, $cf_key_file, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
if ($hd == '') {
|
|
if (file_exists($loc0)) {
|
|
$_file[] = $v[0];
|
|
} else {
|
|
if (file_exists($loc1)) {
|
|
$_file[] = $v[1];
|
|
}
|
|
}
|
|
} else {
|
|
if (file_exists($loc0)) {
|
|
$_file[] = $v[0];
|
|
} else {
|
|
if (file_exists($loc1)) {
|
|
$_file[] = $v[1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_fsrc != 'local') {
|
|
$info = array();
|
|
$_p = VPlayers::playerInit('view');
|
|
$width = $_p[1];
|
|
$height = $_p[2];
|
|
$info["key"] = $vid_id;
|
|
|
|
switch ($_fsrc) {
|
|
case "youtube":$_url = 'https://www.youtube.com/embed/' . $_furl;
|
|
break;
|
|
case "vimeo":$_url = 'https://player.vimeo.com/video/' . $_furl;
|
|
break;
|
|
case "dailymotion":$_url = 'https://www.dailymotion.com/embed/video/' . $_furl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
$config = array(
|
|
'type' => 'url',
|
|
'params' => array(
|
|
'loc' => $link,
|
|
'video' => array(
|
|
'title' => $title,
|
|
'thumbnail_loc' => $screenshot,
|
|
'description' => str_replace(array("\r", "\n"), array("", ""), $description),
|
|
($_fsrc != 'local' ? 'player_loc' : 'content_loc') => ($_fsrc != 'local' ? $_url : ($hd == '' ? $_file[0] : ($_file[2] != '' ? $_file[2] : $_file[1]))),
|
|
'publication_date' => $date,
|
|
'duration' => $duration,
|
|
'view_count' => $view_count,
|
|
),
|
|
),
|
|
);
|
|
|
|
foreach ($tags as $i => $tag) {
|
|
$final_tag = trim(html_convert_entities(htmlspecialchars($tag)));
|
|
|
|
$config['params']['video']['tag' . $i] = str_replace(array("\r", "\n"), array("", ""), $final_tag);
|
|
}
|
|
|
|
$SitemapNode->add_node($config);
|
|
|
|
$db->execute(sprintf("UPDATE `db_settings` SET `cfg_data`='%s' WHERE `cfg_name`='%s' LIMIT 1;", $db_id, $skey));
|
|
|
|
$res->MoveNext();
|
|
} //endwhile
|
|
} //endif
|
|
|
|
function html_convert_entities($string)
|
|
{
|
|
return preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]+);/',
|
|
'convert_entity', $string);
|
|
}
|
|
|
|
/* Swap HTML named entity with its numeric equivalent. If the entity
|
|
* isn't in the lookup table, this function returns a blank, which
|
|
* destroys the character in the output - this is probably the
|
|
* desired behaviour when producing XML. */
|
|
function convert_entity($matches)
|
|
{
|
|
static $table = array('quot' => '"',
|
|
'amp' => '&',
|
|
'lt' => '<',
|
|
'gt' => '>',
|
|
'OElig' => 'Œ',
|
|
'oelig' => 'œ',
|
|
'Scaron' => 'Š',
|
|
'scaron' => 'š',
|
|
'Yuml' => 'Ÿ',
|
|
'circ' => 'ˆ',
|
|
'tilde' => '˜',
|
|
'ensp' => ' ',
|
|
'emsp' => ' ',
|
|
'thinsp' => ' ',
|
|
'zwnj' => '‌',
|
|
'zwj' => '‍',
|
|
'lrm' => '‎',
|
|
'rlm' => '‏',
|
|
'ndash' => '–',
|
|
'mdash' => '—',
|
|
'lsquo' => '‘',
|
|
'rsquo' => '’',
|
|
'sbquo' => '‚',
|
|
'ldquo' => '“',
|
|
'rdquo' => '”',
|
|
'bdquo' => '„',
|
|
'dagger' => '†',
|
|
'Dagger' => '‡',
|
|
'permil' => '‰',
|
|
'lsaquo' => '‹',
|
|
'rsaquo' => '›',
|
|
'euro' => '€',
|
|
'fnof' => 'ƒ',
|
|
'Alpha' => 'Α',
|
|
'Beta' => 'Β',
|
|
'Gamma' => 'Γ',
|
|
'Delta' => 'Δ',
|
|
'Epsilon' => 'Ε',
|
|
'Zeta' => 'Ζ',
|
|
'Eta' => 'Η',
|
|
'Theta' => 'Θ',
|
|
'Iota' => 'Ι',
|
|
'Kappa' => 'Κ',
|
|
'Lambda' => 'Λ',
|
|
'Mu' => 'Μ',
|
|
'Nu' => 'Ν',
|
|
'Xi' => 'Ξ',
|
|
'Omicron' => 'Ο',
|
|
'Pi' => 'Π',
|
|
'Rho' => 'Ρ',
|
|
'Sigma' => 'Σ',
|
|
'Tau' => 'Τ',
|
|
'Upsilon' => 'Υ',
|
|
'Phi' => 'Φ',
|
|
'Chi' => 'Χ',
|
|
'Psi' => 'Ψ',
|
|
'Omega' => 'Ω',
|
|
'alpha' => 'α',
|
|
'beta' => 'β',
|
|
'gamma' => 'γ',
|
|
'delta' => 'δ',
|
|
'epsilon' => 'ε',
|
|
'zeta' => 'ζ',
|
|
'eta' => 'η',
|
|
'theta' => 'θ',
|
|
'iota' => 'ι',
|
|
'kappa' => 'κ',
|
|
'lambda' => 'λ',
|
|
'mu' => 'μ',
|
|
'nu' => 'ν',
|
|
'xi' => 'ξ',
|
|
'omicron' => 'ο',
|
|
'pi' => 'π',
|
|
'rho' => 'ρ',
|
|
'sigmaf' => 'ς',
|
|
'sigma' => 'σ',
|
|
'tau' => 'τ',
|
|
'upsilon' => 'υ',
|
|
'phi' => 'φ',
|
|
'chi' => 'χ',
|
|
'psi' => 'ψ',
|
|
'omega' => 'ω',
|
|
'thetasym' => 'ϑ',
|
|
'upsih' => 'ϒ',
|
|
'piv' => 'ϖ',
|
|
'bull' => '•',
|
|
'hellip' => '…',
|
|
'prime' => '′',
|
|
'Prime' => '″',
|
|
'oline' => '‾',
|
|
'frasl' => '⁄',
|
|
'weierp' => '℘',
|
|
'image' => 'ℑ',
|
|
'real' => 'ℜ',
|
|
'trade' => '™',
|
|
'alefsym' => 'ℵ',
|
|
'larr' => '←',
|
|
'uarr' => '↑',
|
|
'rarr' => '→',
|
|
'darr' => '↓',
|
|
'harr' => '↔',
|
|
'crarr' => '↵',
|
|
'lArr' => '⇐',
|
|
'uArr' => '⇑',
|
|
'rArr' => '⇒',
|
|
'dArr' => '⇓',
|
|
'hArr' => '⇔',
|
|
'forall' => '∀',
|
|
'part' => '∂',
|
|
'exist' => '∃',
|
|
'empty' => '∅',
|
|
'nabla' => '∇',
|
|
'isin' => '∈',
|
|
'notin' => '∉',
|
|
'ni' => '∋',
|
|
'prod' => '∏',
|
|
'sum' => '∑',
|
|
'minus' => '−',
|
|
'lowast' => '∗',
|
|
'radic' => '√',
|
|
'prop' => '∝',
|
|
'infin' => '∞',
|
|
'ang' => '∠',
|
|
'and' => '∧',
|
|
'or' => '∨',
|
|
'cap' => '∩',
|
|
'cup' => '∪',
|
|
'int' => '∫',
|
|
'there4' => '∴',
|
|
'sim' => '∼',
|
|
'cong' => '≅',
|
|
'asymp' => '≈',
|
|
'ne' => '≠',
|
|
'equiv' => '≡',
|
|
'le' => '≤',
|
|
'ge' => '≥',
|
|
'sub' => '⊂',
|
|
'sup' => '⊃',
|
|
'nsub' => '⊄',
|
|
'sube' => '⊆',
|
|
'supe' => '⊇',
|
|
'oplus' => '⊕',
|
|
'otimes' => '⊗',
|
|
'perp' => '⊥',
|
|
'sdot' => '⋅',
|
|
'lceil' => '⌈',
|
|
'rceil' => '⌉',
|
|
'lfloor' => '⌊',
|
|
'rfloor' => '⌋',
|
|
'lang' => '〈',
|
|
'rang' => '〉',
|
|
'loz' => '◊',
|
|
'spades' => '♠',
|
|
'clubs' => '♣',
|
|
'hearts' => '♥',
|
|
'diams' => '♦',
|
|
'nbsp' => ' ',
|
|
'iexcl' => '¡',
|
|
'cent' => '¢',
|
|
'pound' => '£',
|
|
'curren' => '¤',
|
|
'yen' => '¥',
|
|
'brvbar' => '¦',
|
|
'sect' => '§',
|
|
'uml' => '¨',
|
|
'copy' => '©',
|
|
'ordf' => 'ª',
|
|
'laquo' => '«',
|
|
'not' => '¬',
|
|
'shy' => '­',
|
|
'reg' => '®',
|
|
'macr' => '¯',
|
|
'deg' => '°',
|
|
'plusmn' => '±',
|
|
'sup2' => '²',
|
|
'sup3' => '³',
|
|
'acute' => '´',
|
|
'micro' => 'µ',
|
|
'para' => '¶',
|
|
'middot' => '·',
|
|
'cedil' => '¸',
|
|
'sup1' => '¹',
|
|
'ordm' => 'º',
|
|
'raquo' => '»',
|
|
'frac14' => '¼',
|
|
'frac12' => '½',
|
|
'frac34' => '¾',
|
|
'iquest' => '¿',
|
|
'Agrave' => 'À',
|
|
'Aacute' => 'Á',
|
|
'Acirc' => 'Â',
|
|
'Atilde' => 'Ã',
|
|
'Auml' => 'Ä',
|
|
'Aring' => 'Å',
|
|
'AElig' => 'Æ',
|
|
'Ccedil' => 'Ç',
|
|
'Egrave' => 'È',
|
|
'Eacute' => 'É',
|
|
'Ecirc' => 'Ê',
|
|
'Euml' => 'Ë',
|
|
'Igrave' => 'Ì',
|
|
'Iacute' => 'Í',
|
|
'Icirc' => 'Î',
|
|
'Iuml' => 'Ï',
|
|
'ETH' => 'Ð',
|
|
'Ntilde' => 'Ñ',
|
|
'Ograve' => 'Ò',
|
|
'Oacute' => 'Ó',
|
|
'Ocirc' => 'Ô',
|
|
'Otilde' => 'Õ',
|
|
'Ouml' => 'Ö',
|
|
'times' => '×',
|
|
'Oslash' => 'Ø',
|
|
'Ugrave' => 'Ù',
|
|
'Uacute' => 'Ú',
|
|
'Ucirc' => 'Û',
|
|
'Uuml' => 'Ü',
|
|
'Yacute' => 'Ý',
|
|
'THORN' => 'Þ',
|
|
'szlig' => 'ß',
|
|
'agrave' => 'à',
|
|
'aacute' => 'á',
|
|
'acirc' => 'â',
|
|
'atilde' => 'ã',
|
|
'auml' => 'ä',
|
|
'aring' => 'å',
|
|
'aelig' => 'æ',
|
|
'ccedil' => 'ç',
|
|
'egrave' => 'è',
|
|
'eacute' => 'é',
|
|
'ecirc' => 'ê',
|
|
'euml' => 'ë',
|
|
'igrave' => 'ì',
|
|
'iacute' => 'í',
|
|
'icirc' => 'î',
|
|
'iuml' => 'ï',
|
|
'eth' => 'ð',
|
|
'ntilde' => 'ñ',
|
|
'ograve' => 'ò',
|
|
'oacute' => 'ó',
|
|
'ocirc' => 'ô',
|
|
'otilde' => 'õ',
|
|
'ouml' => 'ö',
|
|
'divide' => '÷',
|
|
'oslash' => 'ø',
|
|
'ugrave' => 'ù',
|
|
'uacute' => 'ú',
|
|
'ucirc' => 'û',
|
|
'uuml' => 'ü',
|
|
'yacute' => 'ý',
|
|
'thorn' => 'þ',
|
|
'yuml' => 'ÿ',
|
|
|
|
);
|
|
// Entity not found? Destroy it.
|
|
return isset($table[$matches[1]]) ? $table[$matches[1]] : '';
|
|
}
|