Merge branch 'master' of github.com:shish/shimmie2
This commit is contained in:
commit
3082266a94
@ -103,7 +103,7 @@ abstract class BaseConfig implements Config {
|
|||||||
return $this->get($name, $default);
|
return $this->get($name, $default);
|
||||||
}
|
}
|
||||||
public function get_bool(/*string*/ $name, $default=null) {
|
public function get_bool(/*string*/ $name, $default=null) {
|
||||||
return undb_bool($this->get($name, $default));
|
return bool_escape($this->get($name, $default));
|
||||||
}
|
}
|
||||||
public function get_array(/*string*/ $name, $default=array()) {
|
public function get_array(/*string*/ $name, $default=array()) {
|
||||||
return explode(",", $this->get($name, ""));
|
return explode(",", $this->get($name, ""));
|
||||||
|
@ -412,12 +412,34 @@ class Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a table from pseudo-SQL
|
* Create a table from pseudo-SQL
|
||||||
*/
|
*/
|
||||||
public function create_table($name, $data) {
|
public function create_table($name, $data) {
|
||||||
$this->execute($this->engine->create_table_sql($name, $data));
|
$this->execute($this->engine->create_table_sql($name, $data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of tables present in the current database.
|
||||||
|
*/
|
||||||
|
public function count_tables() {
|
||||||
|
if($this->engine->name === "mysql") {
|
||||||
|
return count(
|
||||||
|
$this->get_all("SHOW TABLES")
|
||||||
|
);
|
||||||
|
} else if ($this->engine->name === "pgsql") {
|
||||||
|
return count(
|
||||||
|
$this->get_all("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'")
|
||||||
|
);
|
||||||
|
} else if ($this->engine->name === "sqlite") {
|
||||||
|
return count(
|
||||||
|
$this->get_all(".tables")
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Hard to find a universal way to do this...
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -56,7 +56,7 @@ class Image {
|
|||||||
$this->$name = $value; // hax
|
$this->$name = $value; // hax
|
||||||
}
|
}
|
||||||
$this->posted_timestamp = strtotime($this->posted); // pray
|
$this->posted_timestamp = strtotime($this->posted); // pray
|
||||||
$this->locked = undb_bool($this->locked);
|
$this->locked = bool_escape($this->locked);
|
||||||
|
|
||||||
assert(is_numeric($this->id));
|
assert(is_numeric($this->id));
|
||||||
assert(is_numeric($this->height));
|
assert(is_numeric($this->height));
|
||||||
@ -385,14 +385,64 @@ class Image {
|
|||||||
/**
|
/**
|
||||||
* Get the image's mime type
|
* Get the image's mime type
|
||||||
*
|
*
|
||||||
* FIXME: now we handle more than just images
|
|
||||||
*
|
|
||||||
* @retval string
|
* @retval string
|
||||||
*/
|
*/
|
||||||
public function get_mime_type() {
|
public function get_mime_type() {
|
||||||
$type = strtolower($this->ext);
|
return __getMimeType( get_image_filename() );
|
||||||
if($type === "jpg") $type = "jpeg";
|
}
|
||||||
return 'image/'.$type;
|
|
||||||
|
/**
|
||||||
|
* Get MIME type for file
|
||||||
|
*
|
||||||
|
* The contents of this function are taken from the __getMimeType() function
|
||||||
|
* from the "Amazon S3 PHP class" which is Copyright (c) 2008, Donovan Schönknecht
|
||||||
|
* and released under the 'Simplified BSD License'.
|
||||||
|
*
|
||||||
|
* @internal Used to get mime types
|
||||||
|
* @param string &$file File path
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function __getMimeType(&$file)
|
||||||
|
{
|
||||||
|
$type = false;
|
||||||
|
// Fileinfo documentation says fileinfo_open() will use the
|
||||||
|
// MAGIC env var for the magic file
|
||||||
|
if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
|
||||||
|
($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false)
|
||||||
|
{
|
||||||
|
if (($type = finfo_file($finfo, $file)) !== false)
|
||||||
|
{
|
||||||
|
// Remove the charset and grab the last content-type
|
||||||
|
$type = explode(' ', str_replace('; charset=', ';charset=', $type));
|
||||||
|
$type = array_pop($type);
|
||||||
|
$type = explode(';', $type);
|
||||||
|
$type = trim(array_shift($type));
|
||||||
|
}
|
||||||
|
finfo_close($finfo);
|
||||||
|
|
||||||
|
// If anyone is still using mime_content_type()
|
||||||
|
} elseif (function_exists('mime_content_type'))
|
||||||
|
$type = trim(mime_content_type($file));
|
||||||
|
|
||||||
|
if ($type !== false && strlen($type) > 0) return $type;
|
||||||
|
|
||||||
|
// Otherwise do it the old fashioned way
|
||||||
|
static $exts = array(
|
||||||
|
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
||||||
|
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
||||||
|
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
||||||
|
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
||||||
|
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
||||||
|
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
||||||
|
'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
|
||||||
|
'css' => 'text/css', 'js' => 'text/javascript',
|
||||||
|
'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
|
||||||
|
'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
|
||||||
|
'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
|
||||||
|
'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
|
||||||
|
);
|
||||||
|
$ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
|
||||||
|
return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -439,7 +489,7 @@ class Image {
|
|||||||
$sln = $database->engine->scoreql_to_sql('SCORE_BOOL_'.$ln);
|
$sln = $database->engine->scoreql_to_sql('SCORE_BOOL_'.$ln);
|
||||||
$sln = str_replace("'", "", $sln);
|
$sln = str_replace("'", "", $sln);
|
||||||
$sln = str_replace('"', "", $sln);
|
$sln = str_replace('"', "", $sln);
|
||||||
if(undb_bool($sln) !== $this->locked) {
|
if(bool_escape($sln) !== $this->locked) {
|
||||||
$database->execute("UPDATE images SET locked=:yn WHERE id=:id", array("yn"=>$sln, "id"=>$this->id));
|
$database->execute("UPDATE images SET locked=:yn WHERE id=:id", array("yn"=>$sln, "id"=>$this->id));
|
||||||
log_info("core-image", "Setting Image #{$this->id} lock to: $ln");
|
log_info("core-image", "Setting Image #{$this->id} lock to: $ln");
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,24 @@ function int_escape($input) {
|
|||||||
* @retval string
|
* @retval string
|
||||||
*/
|
*/
|
||||||
function url_escape($input) {
|
function url_escape($input) {
|
||||||
|
/*
|
||||||
|
Shish: I have a feeling that these three lines are important, possibly for searching for tags with slashes in them like fate/stay_night
|
||||||
|
green-ponies: indeed~
|
||||||
|
|
||||||
|
$input = str_replace('^', '^^', $input);
|
||||||
|
$input = str_replace('/', '^s', $input);
|
||||||
|
$input = str_replace('\\', '^b', $input);
|
||||||
|
|
||||||
|
/* The function idn_to_ascii is used to support Unicode domains / URLs as well.
|
||||||
|
See here for more: http://php.net/manual/en/function.filter-var.php
|
||||||
|
However, it is only supported by PHP version 5.3 and up
|
||||||
|
|
||||||
|
if (function_exists('idn_to_ascii')) {
|
||||||
|
return filter_var(idn_to_ascii($input), FILTER_SANITIZE_URL);
|
||||||
|
} else {
|
||||||
|
return filter_var($input, FILTER_SANITIZE_URL);
|
||||||
|
}
|
||||||
|
*/
|
||||||
if(is_null($input)) {
|
if(is_null($input)) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -61,16 +79,32 @@ function sql_escape($input) {
|
|||||||
* @retval boolean
|
* @retval boolean
|
||||||
*/
|
*/
|
||||||
function bool_escape($input) {
|
function bool_escape($input) {
|
||||||
$input = strtolower($input);
|
/*
|
||||||
|
Sometimes, I don't like PHP -- this, is one of those times...
|
||||||
|
"a boolean FALSE is not considered a valid boolean value by this function."
|
||||||
|
Yay for Got'chas!
|
||||||
|
http://php.net/manual/en/filter.filters.validate.php
|
||||||
|
*/
|
||||||
|
if (is_bool($input)) {
|
||||||
|
return $input;
|
||||||
|
} else if (is_numeric($input)) {
|
||||||
|
return ($input === 1);
|
||||||
|
} else {
|
||||||
|
$value = filter_var($input, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
if (!is_null($value)) {
|
||||||
|
return $value;
|
||||||
|
} else {
|
||||||
|
$input = strtolower( trim($input) );
|
||||||
return (
|
return (
|
||||||
$input === "y" ||
|
$input === "y" ||
|
||||||
$input === "yes" ||
|
$input === "yes" ||
|
||||||
$input === "t" ||
|
$input === "t" ||
|
||||||
$input === "true" ||
|
$input === "true" ||
|
||||||
$input === "on" ||
|
$input === "on" ||
|
||||||
$input === 1 ||
|
$input === "1"
|
||||||
$input === true
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,15 +239,6 @@ function show_ip($ip, $ban_reason) {
|
|||||||
return $ip;
|
return $ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Different databases have different ways to represent booleans; this
|
|
||||||
* will try and standardise them
|
|
||||||
*/
|
|
||||||
function undb_bool($val) {
|
|
||||||
if($val === true || $val == 'Y' || $val == 'y' || $val == 'T' || $val == 't' || $val === 1) return true;
|
|
||||||
if($val === false || $val == 'N' || $val == 'n' || $val == 'F' || $val == 'f' || $val === 0) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a given string contains another at the beginning.
|
* Checks if a given string contains another at the beginning.
|
||||||
*
|
*
|
||||||
|
@ -54,9 +54,29 @@ xanax
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onCommentPosting(CommentPostingEvent $event) {
|
public function onCommentPosting(CommentPostingEvent $event) {
|
||||||
|
$this->test_text($event->comment, new CommentPostingException("Comment contains banned terms"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSourceSet(SourceSetEvent $event) {
|
||||||
|
$this->test_text($event->source, new SCoreException("Source contains banned terms"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTagSet(TagSetEvent $event) {
|
||||||
|
$this->test_text(Tag::implode($event->tags), new SCoreException("Tags contain banned terms"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSetupBuilding(SetupBuildingEvent $event) {
|
||||||
|
$sb = new SetupBlock("Banned Phrases");
|
||||||
|
$sb->add_label("One per line, lines that start with slashes are treated as regex<br/>");
|
||||||
|
$sb->add_longtext_option("banned_words");
|
||||||
|
$event->panel->add_block($sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function test_text($comment, $ex) {
|
||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
$banned = $config->get_string("banned_words");
|
$banned = $config->get_string("banned_words");
|
||||||
$comment = strtolower($event->comment);
|
$comment = strtolower($comment);
|
||||||
|
|
||||||
foreach(explode("\n", $banned) as $word) {
|
foreach(explode("\n", $banned) as $word) {
|
||||||
$word = trim(strtolower($word));
|
$word = trim(strtolower($word));
|
||||||
@ -67,25 +87,18 @@ xanax
|
|||||||
else if($word[0] == '/') {
|
else if($word[0] == '/') {
|
||||||
// lines that start with slash are regex
|
// lines that start with slash are regex
|
||||||
if(preg_match($word, $comment)) {
|
if(preg_match($word, $comment)) {
|
||||||
throw new CommentPostingException("Comment contains banned terms");
|
throw $ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// other words are literal
|
// other words are literal
|
||||||
if(strpos($comment, $word) !== false) {
|
if(strpos($comment, $word) !== false) {
|
||||||
throw new CommentPostingException("Comment contains banned terms");
|
throw $ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onSetupBuilding(SetupBuildingEvent $event) {
|
|
||||||
$sb = new SetupBlock("Banned Phrases");
|
|
||||||
$sb->add_label("One per line, lines that start with slashes are treated as regex<br/>");
|
|
||||||
$sb->add_longtext_option("banned_words");
|
|
||||||
$event->panel->add_block($sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get_priority() {return 30;}
|
public function get_priority() {return 30;}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
@ -50,6 +50,12 @@ class ET extends Extension {
|
|||||||
to_shorthand_int(disk_total_space("./"));
|
to_shorthand_int(disk_total_space("./"));
|
||||||
$info['sys_server'] = $_SERVER["SERVER_SOFTWARE"];
|
$info['sys_server'] = $_SERVER["SERVER_SOFTWARE"];
|
||||||
|
|
||||||
|
$info['thumb_engine'] = $config->get_string("thumb_engine");
|
||||||
|
$info['thumb_quality'] = $config->get_int('thumb_quality');
|
||||||
|
$info['thumb_width'] = $config->get_int('thumb_width');
|
||||||
|
$info['thumb_height'] = $config->get_int('thumb_height');
|
||||||
|
$info['thumb_mem'] = $config->get_int("thumb_max_memory");
|
||||||
|
|
||||||
$info['stat_images'] = $database->get_one("SELECT COUNT(*) FROM images");
|
$info['stat_images'] = $database->get_one("SELECT COUNT(*) FROM images");
|
||||||
$info['stat_comments'] = $database->get_one("SELECT COUNT(*) FROM comments");
|
$info['stat_comments'] = $database->get_one("SELECT COUNT(*) FROM comments");
|
||||||
$info['stat_users'] = $database->get_one("SELECT COUNT(*) FROM users");
|
$info['stat_users'] = $database->get_one("SELECT COUNT(*) FROM users");
|
||||||
|
@ -32,6 +32,13 @@ Database: {$info['sys_db']}
|
|||||||
Server: {$info['sys_server']}
|
Server: {$info['sys_server']}
|
||||||
Disk use: {$info['sys_disk']}
|
Disk use: {$info['sys_disk']}
|
||||||
|
|
||||||
|
Thumbnail Generation:
|
||||||
|
Engine: {$info['thumb_engine']}
|
||||||
|
Memory: {$info['thumb_mem']}
|
||||||
|
Quality: {$info['thumb_quality']}
|
||||||
|
Width: {$info['thumb_width']}
|
||||||
|
Height: {$info['thumb_height']}
|
||||||
|
|
||||||
Shimmie stats:
|
Shimmie stats:
|
||||||
Images: {$info['stat_images']}
|
Images: {$info['stat_images']}
|
||||||
Comments: {$info['stat_comments']}
|
Comments: {$info['stat_comments']}
|
||||||
|
@ -42,7 +42,7 @@ class Featured extends Extension {
|
|||||||
$image = Image::by_id($config->get_int("featured_id"));
|
$image = Image::by_id($config->get_int("featured_id"));
|
||||||
if(!is_null($image)) {
|
if(!is_null($image)) {
|
||||||
$page->set_mode("data");
|
$page->set_mode("data");
|
||||||
$page->set_type("image/jpeg");
|
$page->set_type($image->get_mime_type());
|
||||||
$page->set_data(file_get_contents($image->get_image_filename()));
|
$page->set_data(file_get_contents($image->get_image_filename()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,8 @@ class PostListBuildingEvent extends Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Index extends Extension {
|
class Index extends Extension {
|
||||||
|
var $val_id = 0;
|
||||||
|
|
||||||
public function onInitExt(InitExtEvent $event) {
|
public function onInitExt(InitExtEvent $event) {
|
||||||
global $config;
|
global $config;
|
||||||
$config->set_default_int("index_images", 24);
|
$config->set_default_int("index_images", 24);
|
||||||
@ -206,10 +208,11 @@ class Index extends Extension {
|
|||||||
$event->add_querylet(new Querylet('width / height '.$cmp.' :width / :height', $args));
|
$event->add_querylet(new Querylet('width / height '.$cmp.' :width / :height', $args));
|
||||||
}
|
}
|
||||||
else if(preg_match("/^(filesize|id)(<|>|<=|>=|=)(\d+[kmg]?b?)$/i", $event->term, $matches)) {
|
else if(preg_match("/^(filesize|id)(<|>|<=|>=|=)(\d+[kmg]?b?)$/i", $event->term, $matches)) {
|
||||||
|
$this->val_id++;
|
||||||
$col = $matches[1];
|
$col = $matches[1];
|
||||||
$cmp = $matches[2];
|
$cmp = $matches[2];
|
||||||
$val = parse_shorthand_int($matches[3]);
|
$val = parse_shorthand_int($matches[3]);
|
||||||
$event->add_querylet(new Querylet("images.$col $cmp :val", array("val"=>$val)));
|
$event->add_querylet(new Querylet("images.$col $cmp :val{$this->val_id}", array("val{$this->val_id}"=>$val)));
|
||||||
}
|
}
|
||||||
else if(preg_match("/^(hash|md5)=([0-9a-fA-F]*)$/i", $event->term, $matches)) {
|
else if(preg_match("/^(hash|md5)=([0-9a-fA-F]*)$/i", $event->term, $matches)) {
|
||||||
$hash = strtolower($matches[2]);
|
$hash = strtolower($matches[2]);
|
||||||
|
@ -2,9 +2,13 @@ function find_thumb_link_containers () {
|
|||||||
|
|
||||||
var post_link = "a[href*='/post/view/']";
|
var post_link = "a[href*='/post/view/']";
|
||||||
var has_thumb_img = ":has(img[src*='/thumb/'])";
|
var has_thumb_img = ":has(img[src*='/thumb/'])";
|
||||||
|
|
||||||
var list = $( post_link + has_thumb_img ).parent();
|
var list = $( post_link + has_thumb_img ).parent();
|
||||||
|
|
||||||
|
if (list) { return list; }
|
||||||
|
|
||||||
|
has_thumb_img = ":has(img[src*='_thumbs/'])";
|
||||||
|
list = $( post_link + has_thumb_img ).parent();
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class PM {
|
|||||||
$this->sent_date = $a["sent_date"];
|
$this->sent_date = $a["sent_date"];
|
||||||
$this->subject = $a["subject"];
|
$this->subject = $a["subject"];
|
||||||
$this->message = $a["message"];
|
$this->message = $a["message"];
|
||||||
$this->is_read = undb_bool($a["is_read"]);
|
$this->is_read = bool_escape($a["is_read"]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->id = -1;
|
$this->id = -1;
|
||||||
|
@ -41,7 +41,7 @@ class RandomImage extends Extension {
|
|||||||
if($action === "download") {
|
if($action === "download") {
|
||||||
if(!is_null($image)) {
|
if(!is_null($image)) {
|
||||||
$page->set_mode("data");
|
$page->set_mode("data");
|
||||||
$page->set_type("image/jpeg");
|
$page->set_type($image->get_mime_type());
|
||||||
$page->set_data(file_get_contents($image->get_image_filename()));
|
$page->set_data(file_get_contents($image->get_image_filename()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,6 +300,14 @@ function create_tables() { // {{{
|
|||||||
try {
|
try {
|
||||||
$db = new Database();
|
$db = new Database();
|
||||||
|
|
||||||
|
if ( $db->count_tables() > 0 ) {
|
||||||
|
echo "
|
||||||
|
<p>Warning: The Database schema is not empty!</p>
|
||||||
|
<p>Please ensure that the database you are installing Shimmie with is empty before continuing.</p>
|
||||||
|
<p>Once you have emptied the database of any tables, please hit 'refresh' to continue.</p>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$db->create_table("aliases", "
|
$db->create_table("aliases", "
|
||||||
oldtag VARCHAR(128) NOT NULL PRIMARY KEY,
|
oldtag VARCHAR(128) NOT NULL PRIMARY KEY,
|
||||||
newtag VARCHAR(128) NOT NULL,
|
newtag VARCHAR(128) NOT NULL,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user