?@[\\]^_`", "ABCDEFGabcdef"); $trip = substr(crypt($cap, $salt), -10); } if($is_secure_trip){ if(!empty($cap)) $trip .= "!"; $trip .= "!".substr(md5($cap_secure.SEED),2,10); } return array($real,$trip); } return array($name,null); } /** * Escape and format post text */ static function text($string,$literal){ if(mb_strlen($string) > X::$conf['kt']['textsize']){ $string = mb_substr($string, 0, X::$conf['kt']['textsize'] - 1).'…'; new Note('Text was too long, truncated.', Note::WARNING); } # FORMATTING $layout = function($string) use ($literal){ $pat = array( #Regex::GENERIC_DASH => ' — ', Regex::GENERIC_REF_NUM => '>>$2', Regex::GENERIC_REF_LIT => '>>>$2/$3', Regex::GENERIC_QUOTE => '
$0', #Regex::TRIFORCE => '
▲\n▲ ▲
'.Regex::escape(str_replace('
',"\r\n",$matches[2])).'';
},
Regex::T_LATEX => function($matchee){
if(X::$conf['xt']['latex']){
#
}
return ''.Regex::escape(str_replace('
',"\r\n",$matches[2])).'';
},
Regex::T_WM_CODE => function($matches){
if(X::$conf['xt']['geshi']){
#
}
return ''.Regex::escape(trim(str_replace('
',"\r\n",$matches[2]))).'';
},
Regex::T_BB_CODE => function($matches){
if(X::$conf['xt']['geshi']){
#
}
return ''.Regex::escape(trim(str_replace('
',"\r\n",$matches[2]))).'';
},
Regex::GENERIC_LINK => function($matches){
return $matches[1].$matches[2].'';
#return ''.$matches[0].'';
},
Regex::FS_GOOGLE => function($matches){
return ''.$matches[1].'';
},
Regex::FS_DDG => function($matches){
return ''.$matches[1].'';
},
Regex::FS_WIKI => function($matches){
return ''.$matches[1].'';
},
Regex::FS_WOLFRAM => function($matches){
return ''.$matches[1].'';
},
Regex::FS_GIT => function($matches){
return ''.$matches[1].'';
}
], $string);
$string = $layout($string);
return $string;
}
/**
* Escape and format external service links
*/
static function link($url){
$result = null;
if(preg_match(Regex::INTERNAL, $url) || preg_match(Regex::EXTERNAL, $url)){
$preg = [
'img' => Regex::TYPE_IMAGE,
'aud' => Regex::TYPE_AUDIO,
'vid' => Regex::TYPE_VIDEO,
'fla' => Regex::TYPE_FLASH,
'txt' => Regex::TYPE_PASTE,
'arc' => Regex::TYPE_ARCHIVE,
'bit' => Regex::TYPE_BITTORRENT,
'key' => Regex::TYPE_CIPHER,
'vlt' => Regex::TYPE_CONTAINER
];
foreach($preg as $lst => $reg){
if(preg_match($reg,$url,$ff)){
return array(
'link'=>$url,
'name'=>"",
'info'=>"{$ff[1]}.{$ff[2]} (external)"
);
}
}
}
$type = 0;
if(preg_match(Regex::SERVICE_YT, $url)) $type = 1;
elseif(preg_match(Regex::SERVICE_VI, $url)) $type = 2;
elseif(preg_match(Regex::SERVICE_SC, $url)) $type = 3;
else deny(E::link__service_type());
$time = time().substr(microtime(),2,3);
$types = array(
1 => ["http://www.youtube.com/oembed?url=",Regex::SERVICE_YT_ID,"YouTube"],
2 => ["http://vimeo.com/api/oembed.json?url=",Regex::SERVICE_VI_ID,"Vimeo"],
3 => ["http://soundcloud.com/oembed?format=json&url=",Regex::SERVICE_SC_ID,"SoundCloud"]
);
$curl = function($svc){
$curl = curl_init($svc);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($curl);
curl_close($curl);
$result = json_decode($result, true);
return $result;
};
$save = function($from,$to){
$path = ROOT."static/node/".X::$node."/pre/";
$prev = $path.$to;
if(file_exists($prev)) return $to;
$ch = curl_init($from);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch,CURLOPT_USERAGENT,'Mozilla/5.0');
$exec = curl_exec($ch);
curl_close($ch);
$fp = fopen($prev,'w+');
fwrite($fp, $exec);
fclose($fp);
return $to;
};
$result = $curl($types[$type][0].$url);
if(empty($result)){
deny(E::link__request());
}
if(!preg_match($types[$type][1],$result['html'],$id)){
deny(E::link__uri());
}
switch($type){
case 1:
return array(
'link'=>"https://www.youtube-nocookie.com/embed/{$id[2]}",
'name'=>$save($result['thumbnail_url'],"yt-{$id[2]}.jpg"),
'info'=>$result['title']." (YouTube)"
);
break;
case 2:
return array(
'link'=>"https://player.vimeo.com/video/{$id[2]}?color=bbd531&title=0&byline=0&portrait=0&badge=0",
'name'=>$save($result['thumbnail_url'],"vi-{$id[2]}.jpg"),
'info'=>$result['title']." (Vimeo)"
);
break;
case 3:
return array(
'link'=>"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/{$id[2]}&auto_play=false&show_artwork=true",
'name'=>$save($result['thumbnail_url'],"sc-{$id[2]}.jpg"),
'info'=>$result['title']." (SoundCloud)"
);
break;
default: deny(E::link__response()); break;
}
return false;
}
/**
* Copy and format files as many-to-many structure
*/
static function files($literal, $tid, $pid, $data){
if(!empty($data)){
$iterator = 0;
$lid = X::$tree[$literal]['id'];
while(!empty($data["name"][$iterator])){
if($iterator > X::$conf['kt']['maxfiles']){ break; }
$hash = md5_file($data["tmp_name"][$iterator]);
$existing = Q::file__find_hash($literal, $lid, $hash);
if(empty($existing)){
$temp = Handle::file(
$data["name"][$iterator],
$data["tmp_name"][$iterator],
$data["size"][$iterator],
$data["type"][$iterator],
$data["error"][$iterator]
);
$unique_name = addslashes($temp['unique_name']);
$original_name = addslashes($temp['original_name']);
$finfo = addslashes($temp['finfo']);
$size = $data["size"][$iterator];
} else {
$unique_name = $existing['name'];
$original_name = $existing['orig'];
$finfo = $existing['info'];
$size = $existing['size'];
}
Q::file__push($literal, $lid, $tid, $pid, $unique_name, $original_name, $finfo, $size, $hash);
$iterator++;
}
}
}
/**
* Move and convert the file
*/
static function file($original_name, $tmp_name, $size, $type, $error){
$WINDOWS = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
if(!static::validate($tmp_name, $size, $error)){
return false;
}
$name = mb_substr(Regex::get_file_name($original_name), 0, 96);
$type = mb_substr(mb_strtolower(Regex::get_extension($original_name)), 0, 8);
$mark = time().substr(microtime(),2,3);
if(!isset($type[1])){
deny(E::file__proc_name());
}
$unique_name = $mark.".".$type;
$dir = ROOT."static/node/".X::$node;
if(!file_exists($d = "{$dir}/src")) mkdir($d, 0770);
if(!file_exists($d = "{$dir}/pre")) mkdir($d, 0770);
$src = $dir."/src/".$unique_name;
$pre = $dir."/pre/".$unique_name;
if(!move_uploaded_file($tmp_name, $src)){
deny(E::file__proc_copy());
}
if(!file_exists($src) || !file_get_contents($src,0,NULL,0,1)){
deny(E::file__proc_read_size($original_name));
}
$mime = $WINDOWS
? mb_strtolower(trim(mime_content_type($src)))
: mb_strtolower(trim(array_pop(explode(' ',`mimetype -M "{$src}"`))));
$information = ""; $dim = ""; $duration = "";
#$size = Chrona::bytes($size);
$attach = function($finfo) use ($original_name, $unique_name){
return array(
'unique_name' => $unique_name,
'original_name' => $original_name,
'finfo' => $finfo
);
};
# image
if(preg_match(Regex::MIME_IMAGE_STRICT, $mime)){
$x = X::$conf['kt']['prevsize'];
$y = $x;
switch(X::$conf['gl']){
case "im":
$img = new Imagick($src);
$dim = $img->getImageGeometry();
$x = $dim['width'];
$y = $dim['height'];
break;
case "gd":
$temp = getimagesize($src);
$x = $temp[0];
$y = $temp[1];
break;
default:
if($WINDOWS){
# well, fuck
} else {
$dim = shell_exec("identify -format '%wx%h' ".escapeshellarg($src));
if(preg_match('/(\d+)x(\d+)/', $dim, $dim_matches)){
$x = $dim_matches[1];
$y = $dim_matches[2];
}
}
}
self::unexif($src, $WINDOWS);
if($x > X::$conf['kt']['prevsize'] || $y > X::$conf['kt']['prevsize'] || $size > 8 * 1024) {
self::thumbnail($src, $pre, $mime);
} else {
copy($src, Regex::get_file_name($pre).".jpg");
}
$information = "{$x}x{$y}";
return $attach($information);
}
# audio/video/flash
elseif(preg_match(Regex::MIME_MULTIMEDIA, $mime)){
$stderr = ($WINDOWS ? "" : "2>&1");
$ffprobe = empty(X::$conf['ff']['probe'])
? "ffprobe"
: X::$conf['ff']['probe'];
$ffprobe_flags = implode(' ', [
"-v quiet",
"-hide_banner",
"-print_format json",
"-show_format",
"-show_streams",
#"-read_frames"
]);
$filepath = $src;
#dump(`{$ffprobe} -i {$filepath} {$ffprobe_flags} {$stderr}`);
$output = `{$ffprobe} {$ffprobe_flags} {$filepath} {$stderr}`;
$info = json_decode($output, true);
if(empty($info)){
unlink($src);
deny(E::file__proc_corrupt(basename($src)));
}
$d = Chrona::time(abs(intval($info['streams'][0]['duration'])));
$ct = $info['streams'][0]['codec_type'];
$xy = X::$conf['kt']['prevsize'];
if(preg_match(Regex::MIME_AUDIO_STRICT, $mime)){
$br = Chrona::bits($info['streams'][0]['bit_rate']);
return $attach("{$d}