From 6c602be266b63b5ac302083a82702317578a3b91 2017-06-12 18:44:05 From: DarkMorford Date: 2017-06-12 18:44:05 Subject: [PATCH] Add root-directory files. --- diff --git a/.gitattributes b/.gitattributes index 6648fc2..4d041af 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,3 +12,4 @@ *.jpg binary *.gif binary *.psd binary +*.ico binary diff --git a/.gitignore b/.gitignore index e69de29..33b8183 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +LocalSettings.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..ba89bd5 --- /dev/null +++ b/.htaccess @@ -0,0 +1,34 @@ +DirectoryIndex index.php +Options -MultiViews + +# Redirects for main page + + RewriteEngine On + + # Base URL for site + # This MUST be changed when moving to the production servers + RewriteBase / + + # Pretty URLs for dynamic pages + RewriteRule ^strip/([0-9]+)/?$ index.php?strip_id=$1 [L] + RewriteRule ^transcript/([0-9]+)/?$ index.php?transcript_id=$1 [L] + RewriteRule ^rant/([0-9]+)/?$ index.php?rant_id=$1 [L] + RewriteRule ^archive(/by_(.+))?/?$ archive.php?list_by=$2 [L] + RewriteRule ^search/?$ search.php [L] + RewriteRule ^nameplates - [L] + RewriteRule ^strips - [L] + + RewriteCond %{REQUEST_FILENAME} !-F + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.+)/? static.php?name=$1 [L,NS] + + + +Order Deny,Allow +Deny from All + + + +ExpiresActive on +ExpiresDefault "modification plus 5 years" + diff --git a/analytics.php b/analytics.php new file mode 100644 index 0000000..fc5b246 --- /dev/null +++ b/analytics.php @@ -0,0 +1,14 @@ + diff --git a/archive.css b/archive.css new file mode 100644 index 0000000..c1237a7 --- /dev/null +++ b/archive.css @@ -0,0 +1,16 @@ +.content ol { + padding: 1ex 3em; + background-color: #757b81; + margin: 0px; +} + +.content ul { + list-style-type: none; + padding: 1ex 2em; + background-color: #757b81; + margin: 0px; +} + +.content a { color: #f6b33d; } +.content a:visited { color:#ececa3; } +.content a:hover { color:#eb5252; } diff --git a/archive.php b/archive.php new file mode 100644 index 0000000..4b8c72b --- /dev/null +++ b/archive.php @@ -0,0 +1,77 @@ + + +
+

View By:

+
+
+ +

Comics by Date

'; +} + +#elseif(!isset($_REQUEST['list_by']) || $_REQUEST['list_by'] == "type") +else +{ +?> + +

', htmlentities($type['description']), '

    '; + + while($comic = mysqli_fetch_assoc($comics)) + printf('
  1. %04d - %s
  2. ', $comic['pubdate'], $comic['id'], $comic['id'], $comic['id'], utfentities($comic['title'])); + + echo '
'; + } +} + ?> + + + + diff --git a/characters.css b/characters.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/characters.css diff --git a/characters.php b/characters.php new file mode 100644 index 0000000..3f64bc2 --- /dev/null +++ b/characters.php @@ -0,0 +1,18 @@ + +
+

All right, all right! I still don't feel like finishing these sections, but whatever (grumble)...
+piro - fall 2007

+ +

Believe it or not, the (page) is in production and will be incorporated into the new site launch. We just are not including them as part of this beta test + (because they still need some work).

+ +
+ + + + diff --git a/community.css b/community.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/community.css diff --git a/external.php b/external.php new file mode 100644 index 0000000..fa6b318 --- /dev/null +++ b/external.php @@ -0,0 +1,296 @@ +'; + foreach($script as $id => $line) + { + $ret .= ''; + $ret .= utfentities($script[$id]['speech']); + $ret .= ''; + } + $ret .= ''; + } + return $ret; + } + + static function getStripTranscript($comic, $xml=false) + { + if(!validate_comic_id($comic)) + { + return false; + } + $script = array(); + $panels = MTAPIi::getNumPanels((int)$comic); + #Panel numbering is 1-indexed, not 0-indexed, for semantic reasons + for($i=1; $i <= $panels; $i++) + { + $script[]= MTAPIi::getPanelTranscript($comic, $i, $xml); + } + if(!$xml) + { + return $script; + } + else + { + $ret = ''; + $ret .= implode($script, ''); + $ret .= ''; + } + return $ret; + } + + static function getCharactersByPanel($comic, $panel, $speakersOnly=false) + { + if(!validate_panel_id($comic, $panel)) + { + return false; + } + + $panels = MTAPIi::getNumPanels($comic); + + $query = 'SELECT DISTINCT speaker FROM transcript WHERE strip = '.(int)$comic; + $query .= ' AND panel = '.(int)$panel; + $query .= ' AND speaker NOT LIKE "#%" '; + if($speakersOnly) + { + $query .= " AND search != '' "; + } + $query .= 'ORDER BY speaker'; + + return query_to_array($query); + } + + static function getCharactersByStrip($comic, $speakersOnly=false) + { + if(!validate_comic_id($comic)) + { + return false; + } + + $query = 'SELECT DISTINCT speaker FROM transcript WHERE strip = '.(int)$comic; + $query .= ' AND speaker NOT LIKE "#%" '; + if($speakersOnly) + { + $query .= " AND search != '' "; + } + $query .= 'ORDER BY speaker'; + + return query_to_array($query); + } + + static function getStripTitle($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $strip = load_strip($comic); + return $strip['title']; + } + + static function getStripPubdate($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $strip = load_strip($comic); + return $strip['published']; + } + + static function getStripType($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $strip = load_strip($comic); + return $strip['type']; + } + + static function getStripTypeName($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + #load_strip() really isn't the best tool for this job, as it would mean two queries instead of one + $query = 'SELECT description FROM strip_t + JOIN strip ON strip.type = strip_t.id + WHERE strip.id = '.(int)$comic; + + $qr = query_to_array($query); + return $qr[0]; + } + + + static function getStripMeta($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $query = 'SELECT meta_t.id FROM meta_t + JOIN meta ON meta_t.id = meta.meta + JOIN strip_t ON meta.type = strip_t.id + JOIN strip ON strip.type = strip_t.id + WHERE strip.id = '.(int)$comic.' ORDER BY meta_t.id'; + + $qr = query_to_array($query); + return $qr; + } + + static function getStrip($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $strip = load_strip($comic); + $strip['type'] = self::getStripTypeName($strip['type']); + $strip['number'] = self::getStripNumberInType($comic); + + unset($strip['udate']); + + return $strip; + } + + static function getStripNumberInType($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + + $type = self::getStripType($comic); + + $query = "SELECT count(*) + FROM strip_t JOIN strip ON strip_t.id = strip.type + WHERE strip.id < {$comic}+1 + AND strip.type = {$type}"; + + $qr = query_to_array($query); + return $qr[0]; + } + + static function getStripMetaName($comic) + { + if(!validate_comic_id($comic)) + { + return false; + } + $query = 'SELECT meta_t.name FROM meta_t + JOIN meta ON meta_t.id = meta.meta + JOIN strip_t ON meta.type = strip_t.id + JOIN strip ON strip.type = strip_t.id + WHERE strip.id = '.(int)$comic.' ORDER BY meta_t.name'; + + $qr = query_to_array($query); + return $qr; + } + + static function getTypeMeta($type) + { + if(!validate_type_id($type)) + { + return false; + } + + $query = 'SELECT meta_t.id FROM meta_t + JOIN meta ON meta_t.id = meta.meta + JOIN strip_t ON meta.type = strip_t.id + WHERE strip_t.id = '.(int)$type.' ORDER BY meta_t.id'; + + $qr = query_to_array($query); + return $qr; + } + + static function getTypeMetaName($type) + { + if(!validate_type_id($type)) + { + return false; + } + + $query = 'SELECT meta_t.name FROM meta_t + JOIN meta ON meta_t.id = meta.meta + JOIN strip_t ON meta.type = strip_t.id + WHERE strip_t.id = '.(int)$type.' ORDER BY meta_t.name'; + + $qr = query_to_array($query); + return $qr; + } + + static function getStripsByType($type) + { + if(!validate_type_id($type)) + { + return false; + } + + $query = 'SELECT strip.id FROM strip WHERE strip.type = '.(int)$type.' ORDER BY strip.id'; + $qr = query_to_array($query); + return $qr; + } + + + static function getStripsByMeta($meta) + { + if(!ctype_digit($meta) || $meta < 1) + { + return false; + } + + $query = 'SELECT strip.id FROM strip + JOIN strip_t ON strip.type = strip_t.id + JOIN meta ON strip_t.id = meta.type + JOIN meta_t ON meta.meta = meta_t.id + WHERE meta_t.id = '.(int)$meta.' ORDER BY strip.id'; + $qr = query_to_array($query); + return $qr; + } +} +?> diff --git a/faq.css b/faq.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/faq.css diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1b0ed266e4e9dd04d99121babc36d8505a6c4c87 GIT binary patch literal 2626 zc%1E&zfZzo5Qg8D0;NzD6l_cDAc-;2&B2AiL}N@Gb#l|41t%5~2L{;~G)zRDjFS_F z$%N=ia7A|5`v=tfs3l@8nD`?h>C?2|o4Y6JHMtbv=*nb3PZ8@9kOHtuH_e)Nz{6q2KSpG);70 zJJ>ur#`9AXmlqXuyB#E}O}w;QC>9HdU$xMtym68P9xYgwg`MrJdmbMjpMS@g%v3rY z5nzd@z_Sn-mO?RA*B4Sq6B;Wh6ciRTrxep|#yBB;vXfx_#G*Vu#-UksbujaI2UG3v zjw5q5uE@ literal 0 Hc$@ max_strip_id() || (int)$comic < 1) + { + return false; + } + return $comic; +} + +function validate_panel_id($comic, $panel) +{ + $panels = get_num_panels($comic); + if(!ctype_digit((string)$panel) || $panel === false || $panel > $panels || $panel < 1) + { + return false; + } + return $panel; +} + +function validate_type_id($type) +{ + if(!ctype_digit((string)$type) || $type < 1 || count_by_type($type) == 0) + { + return false; + } +} + +function get_num_panels($comic) +{ + global $link; + if(!validate_comic_id($comic)) + { + return false; + } + + $rs = mysqli_query($link,'SELECT MAX(panel) FROM transcript WHERE strip = '.(int)$comic); + return current(mysqli_fetch_row($rs)); +} + +function build_panel_transcript($comic, $panel) +{ + $query = 'SELECT speaker, speech FROM transcript + WHERE strip = '.(int)$comic.' AND panel = '.(int)$panel.' + AND speaker NOT LIKE "#%" ORDER BY line'; + + $qr = query_to_nested($query); + return $qr; +} + +function query_to_nested($query) +{ + global $link; + $ret = array(); + $rs = mysqli_query($link,$query) or die(mysqli_error($link)); + while($row = mysqli_fetch_assoc($rs)) + { + $ret[]= $row; + } + mysqli_free_result($rs); + + return $ret; +} + +#Runs a query +#Compresses the specified column in the returned columns into a single array +function query_to_array($query, $col=0) +{ + global $link; + $ret = array(); + $rs = mysqli_query($link,$query) or die(mysqli_error($link)); + while($row = mysqli_fetch_array($rs)) + { + $ret[]= $row[0]; + } + mysqli_free_result($rs); + + return $ret; +} + +function count_by_type($type) +{ + global $link; + $qr = mysqli_query($link,'SELECT COUNT(*) FROM strip WHERE type = '.(int)$type) or die(mysqli_error($link)); + return current(mysqli_fetch_row($qr)); +} + +function max_rant_id() +{ + global $link; + $qr = mysqli_query($link,'SELECT MAX(id) FROM rant WHERE published < NOW()') or die(mysqli_error($link)); + return current(mysqli_fetch_row($qr)); +} + + +function max_transcript_strip_id() +{ + global $link; + $qr = mysqli_query($link,'SELECT MAX(strip) FROM transcript') or die(mysqli_error($link)); + return current(mysqli_fetch_row($qr)); +} + +function max_strip_id() +{ + global $link; + $qr = mysqli_query($link,'SELECT MAX(id) FROM strip WHERE published < NOW()') or die(mysqli_error($link)); + return current(mysqli_fetch_row($qr)); +} + +function load_strip($id) +{ + global $link; + $qr = mysqli_query($link,"SELECT UNIX_TIMESTAMP(s.published) as udate, + s.title AS title, media.extension AS ext, s.type AS type, + s.book AS book, s.page AS page, + DATE_FORMAT(s.published, '%M %D, %Y') AS pubdate + FROM media_t media, strip s + WHERE s.media = media.id AND s.id = $id") or die(mysqli_error($link)); + + return mysqli_fetch_assoc($qr); +} + +function load_transcript($id) +{ + global $link; + $qr = mysqli_query($link,"SELECT panel, speaker, speech + FROM transcript WHERE strip = $id + AND (transcript.speaker NOT LIKE \"#%\") + ORDER BY panel, line") or die(mysqli_error($link)); + return $qr; +} + +function conditional_exit($mtime) +{ + if(!PERFORM_CONDITIONAL_CACHE) + return; + + $f_date = gmdate( 'D, d M Y H:i:s T', $mtime ); + header("Last-Modified: $f_date"); + + if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $f_date) { + header('HTTP/1.0 304 Not Modified'); + exit(0); + } +} + +function mt_query($link,$sql) { + global $link; + $r = mysqli_query($link,$sql); + if( !$r ) trigger_error("SQL Error", E_USER_ERROR); + return $r; +} + +function mtdie($errno, $errstr, $errfile, $errline, $errcontext) { + $extra = ''; + switch ($errno) { + case E_NOTICE: + break; + case E_WARNING: // for SQL errors + case E_USER_WARNING: + case E_USER_NOTICE: + + case E_CORE_WARNING: + case E_COMPILE_WARNING: + case E_USER_ERROR: + case E_ERROR: + case E_PARSE: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + + @header('Content-Type: text/html; charset=utf-8'); + + $message = "$errstr in $errfile at line $errline"; + if (strcasecmp('sql', $errstr) == 0 ) { + $message .= "\r\nSQL Error " .': ' . mysqli_error($link); + } + + error_log( $message, 0 ); // Log to Syslog + + $message .= "\r\n\r\nBacktrace:"; + $backtrace = array_reverse(debug_backtrace()); + $i=2; + $message .= "\r\n1: " . $err_context . " at $errfile:$errline"; + foreach($backtrace as $k=>$call) { + $message .= "\r\n" . str_pad("$i:", $i+4 ) . $call['function'] . '( ' . implode(', ', $call['args']) . ' ) at ' . $call['file'] . ':' . $call['line']; + $i++; + } + $message .= "\r\n"; + + $message .= "\r\nRequest Details:" + . "\r\nscript_url: " . $_SERVER["SCRIPT_URL"] + . "\r\nquery_string: " . $_SERVER["QUERY_STRING"] + . "\r\nremote_addr: " . $_SERVER["REMOTE_ADDR"] + . "\r\nhttp_user_agent: " . $_SERVER["HTTP_USER_AGENT"]; + print_r($message); + error_log( "Megatokyo Site Error at " .date('Y-m-d H:i'). "\r\n\r\n$message\r\n", 1, SITE_CONTACT ); //, "Subject: Megatokyo Site Errors for " . date('Y-m-d') ); // Log to email + + // Log to user on screen + + ?> + + + + <?php echo $title?$title:'Megatokyo Administration Editor'; ?> + + + + +

Megatokyo

+

Encountered a problem servicing your request.

+

- Administrators have been notified, we'll try to have things fixed shortly.

+

‹ Back to Megatokyo.com

+ + + + + + + + + + + + + + + + MegaTokyo - <?php echo $title ?> + + + + + '; + echo $style; + echo ''; + } + ?> + + + + + + + + /www/delivery/spcjs.php?id=1'> */ ?> + + + + + +
+ MegaGear + MegaTokyo Visual Novel + MegaGear +
+ + + +
+

credits

+

megatokyo the comic - + copyright © 2000 - + fred gallagher. + all rights reserved.

+

'megatokyo' is a registered trademark of + fredart studios llc.

+
diff --git a/index.css b/index.css new file mode 100644 index 0000000..174d854 --- /dev/null +++ b/index.css @@ -0,0 +1,614 @@ +h2, +h3 a { + margin: 0px; + padding: 0px; + color: #f6b33d; +} + +.content .column { width:330px } + +/* Dress up the comic */ +#comic { + margin-top: 0px; + height: 1%; /* Give IE hasLayout to fix a neg margin bug */ + width: auto; +} + + +#comic .nl { + padding-top: 5px; + padding-bottom: 5px; + background-color: black; + margin: -5em auto 0px; + border-top: solid 5em #b7bfc7; + width: 700px; + text-align: center; +} + +#comic .navpanel { + position: relative; + margin: auto; +} + +#comic div.navpanel { + position: relative; /* Make IE draw panel above glow border */ + z-index: 1; + height: 33px; + padding: 0px; + width: 650px; +} + +#comic form.navpanel { + margin-top: -28px; + padding: 0px; + width: 625px; +} + +/* Need to gank the button out of the document flow somehow */ +#comic .search-field { position:relative } +#comic .search-field a { position:absolute } + +#comic .search-filter { + padding:0px 25px; + margin-bottom: 15px; +} + +#comic .navpanel .navcontrols { + position: absolute; + z-index: 1; +} + +#comic div.navpanel .navcontrols { right:25px } +#comic form.navpanel .navcontrols { right:0px } + +#comic .navpanel .navcontrols ul { + width: 124px; height: 33px; + margin: 0px; + padding: 0px; + clear: both; +} + +#comic .navpanel .navcontrols ul li { + display: block; + float: left; +} + +#comic .navpanel .navcontrols ul li a, +#comic .navpanel .navcontrols ul li span { + display: block; + padding-top: 33px; + width: 62px; + height: 0px; + overflow: hidden; +} + + +/* Top Nav */ + +#comic .navpanel .navcontrols.top li.prev { + background: url(parts/nav2-top-prev.png) no-repeat; +} + +#comic .navpanel .navcontrols.top li.next { + background: url(parts/nav2-top-next.png) no-repeat; +} + +#comic .navpanel .navcontrols.top li.prevoff { + background: url(parts/nav2-top-prevoff.png) no-repeat; +} + +#comic .navpanel .navcontrols.top li.nextoff { + background: url(parts/nav2-top-nextoff.png) no-repeat; +} + +/* Bottom Nav */ + +#comic .navpanel .navcontrols.bottom li.prev { + background: url(parts/nav2-bottom-prev.png) no-repeat; +} + +#comic .navpanel .navcontrols.bottom li.next { + background: url(parts/nav2-bottom-next.png) no-repeat; +} + +#comic .navpanel .navcontrols.bottom li.prevoff { + background: url(parts/nav2-bottom-prevoff.png) no-repeat; +} + +#comic .navpanel .navcontrols.bottom li.nextoff { + background: url(parts/nav2-bottom-nextoff.png) no-repeat; +} + +/* Form Nav only for disable */ + +#comic .navpanel .navcontrols li.findprevoff { + background: url(parts/nav2-prevfindoff.png) no-repeat; +} + +#comic .navpanel .navcontrols li.findnextoff { + background: url(parts/nav2-nextfindoff.png) no-repeat; +} + +#comic .navpanel .navcontrols ul#searchprevnext li { + height: 33px; +} + +#comic div.navpanel #title { + padding: 1ex; +} + +#comic .navpanel .search-filter { + margin-bottom: 15px; +} + +#comic .navpanel #q { + width: 350px; +} + +#comic .navpanel #go, +#comic .navpanel #iego { + vertical-align: middle; + padding-bottom: 2px; +} + +#comic .transcript { + list-style-type:none; + padding: 66px 50px; + margin: 0px; +} + +#comic .transcript .panelhead { + font-size: larger; + font-weight: bold; +} + +#comic .transcript dl { padding-left:50px } +#comic .transcript dt { + float: left; + padding-right: 1em; + font-weight: bold; +} + +#comic .transcript dd { + margin-left: 5.5em; + padding-left: 0px; + padding-bottom: 0.5ex; +} + +/* Make the archive link stand out */ +#comic #archivelink { background-color:#b7bfc7 } +#comic #archivelink a { color:black } +#comic #archivelink a:hover { color:#eb5252 } + +/* Boxes between the comic and the rants */ +#megagear { text-align:center } + +#newsbox a { color:#f6b33d } +#newsbox ul { + margin-left: 3ex; + padding-left: 0px; +} +#newsbox h3 { + text-align: center; +} +#support { font-size: 80%; } + +#status dl { + margin: 1em; +} + +#status dt { + float: left; +} + +#status dd { + margin-left: 7em; + color: #f6b33d; +} + +#status dd div#percentbox { + padding: 1px; + width: 90%; + border: 1px solid #567; + margin: 0px; +} + +#newsbox div.thewrap, +#support div.thewrap { + border-bottom:none; + margin:0; + padding:0; + background: url(parts/twitter-seperator.png) 6px 0 #23272B; +} + +/* Fix a bug caused by OpenAds injecting a
into the status area which + * partially obscures the 'support' heading + */ +#support div.thewrap div { + background-color: transparent; +} + +.content div.column.leftcol, +.content div.column.rightcol { border: none; } + +.content div#status, +.content div#fred_twitter { border: none; background: none; } + +#support { border-bottom: 5px solid black; } + +#status ul, #fred_twitter ul { margin-top:0px } + +#status li, #fred_twitter li { + padding-top: 4px; + padding-right: 1em; +} + +#newsbox { + overflow: visible; + height: 60px; +} + +/* +#newsbox .leftcol { + left: 5px; +} + +#newsbox .rightcol { + right: 5px; +} +*/ + +#newsbox div { + border:none; + overflow:visible; +} + +#blogbits { + padding: 0px; + width: 370px; +} + +#blogbits ul +{ + margin: 0px; + padding: 0px; + text-align: center; + list-style-type: none; +} + +#blogbits ul#blogbitslist { margin-left:250px } +#blogbits ul#feed-list { + margin: auto; +} + +#blogbits #feed-list ul { + display: none; + position: absolute; + z-index: 1; + border: solid 5px black; + width: 400px; + background: #4c565e; + text-align: left; +} + +#blogbits ul#feed-list li { + display: inline-block; + margin: 0px; + padding: 7.5px 4px; + color: #B7BFC7; +} + +#blogbits a.rightcol img, +#blogbits a.leftcol img { + width: 180px; +} + +#blogbits a.rightcol img { + padding-left: 5px; +} + +#blogbits a.leftcol img { + padding-right: 5px; +} + +#facebook img { + width: 300px; + height: 60px; +} + +#facebook { + border: none; + padding: 0px; +} + +#support { position:relative } + +#support .thewrap .column .glowwrap, +#support .thewrap .column .glowwrap a { + display: block; + width: 100%; +} + +#support .thewrap .column .glowwrap img, +#support .thewrap .column .glowwrap embed { + display: block; + margin: auto; +} + +#support .glowwrap div { + border: none; +} + +#newsbox .adinfo, #support .adinfo { + position: absolute; + top: 2px; + right: 10px; + height: 16px; + + margin: 0px; + border: 0px; + padding: 0px; + + background-color: transparent; +} + +#newsbox .adinfo a, #support .adinfo a { + color: #f6b33d; + font-size: 11px; +} + +#newsbox .adinfo p, #support .adinfo p { + margin: 0px 10px 0px 0px; +} + +/* Rant Columns */ +#console { + overflow: hidden; +} + +#console h3 { + padding: 0.75ex; + background-color: #757b81; + + font-family: monospace; + font-size: xx-large; + text-align: center; +} + +#console .date, +#console .rantbody { + margin: 5px; + padding: 5px; + width: 330px; +} + +#feed-list h4 { + margin: auto; + color: #F6B33D; + text-align: center; + font-size: medium; + width: 400px; +} + +#console h4 { + margin: auto; + padding: 0.75ex 0px; + width: 330px; + + background-color: #757b81; + color: #F6B33D; + + text-align: center; + font-size: medium; +} + +#console h4 a {color:#f6b33d} + +#console .rantbody { + margin-top: 0px; + padding-top: 0px; +} + +/* force
 to not break our boxes */
+#console .rantbody pre {
+	white-space: pre-wrap;
+	white-space: -moz-pre-wrap;
+	word-wrap: break-word;
+}
+
+#console .leftcol {
+	width: 350px;
+	color: #b7bfc7;
+}
+
+#console .rightcol {
+	width: 350px;
+	color: #f6b33D;
+}
+
+#console .rantimage {
+	background: url(parts/mt-glow-mainrant-vert.png) repeat-y;
+	width: 350px;
+	height: 285px;
+}
+
+#console .ri-top {
+	background: url(parts/mt-glow-mainrant-top.png) top no-repeat;
+	width: 350px;
+	height: 245px;
+}
+
+#console .ri-bottom {
+	background: url(parts/mt-glow-mainrant-bottom.png) bottom no-repeat;
+	width: 350px;
+}
+
+#console .ri-matte {
+	padding: 20px 0px 20px 0px;
+	margin: 0px 25px;
+	width: 300px;
+	height: 245px;
+}
+
+#console .rantimage p,
+#console .rantimage p img {
+	float: none;
+	width: 300px;
+	height: 245px;
+	text-align: left;
+	padding: 0px;
+	margin: 0px;
+}
+
+#console .rantnav {
+	margin: 2em 0px;
+	text-align: center;
+}
+
+#console .nameplate {
+	background-color: #757B81;
+	width: 350px
+}
+
+#console .nameplate span {
+	display: block;
+	height: 48px;
+	background-repeat: no-repeat;
+	background-position: top center;
+}
+
+#console .nameplate h3 {
+	display: none;
+}
+
+#console .oldrant {
+	margin-top: 1.5em;
+	border-top: medium solid #B7BFC7;
+	padding-top: 1em;
+	width: 345px;
+}
+
+#console .oldrant .rantimage {
+	float:left;
+	background: url(parts/mt-glow-oldrant-vert.png) repeat-y;
+	width: 176px;
+	height: 141px;
+}
+
+#console .oldrant .ri-top {
+	background: url(parts/mt-glow-oldrant-top.png) top no-repeat;
+	width: 178px;
+	height: 123px;
+}
+
+#console .oldrant .ri-bottom {
+	background: url(parts/mt-glow-oldrant-bottom.png) bottom no-repeat;
+	width: 178px;
+}
+
+#console .oldrant .ri-matte {
+	padding: 9px 0px 9px 0px;
+	margin: 0px 13px;
+	width: 150px;
+	height: 123px;
+}
+
+										#console .oldrant .rantimage p,
+#console .oldrant .rantimage p img {
+	float: none;
+	width: 150px;
+	height: 123px;
+	text-align: left;
+	padding: 0px;
+	margin: 0px;
+}
+
+#console .oldrant .nameplate {
+	margin-top: 43px;
+	background-color: #757B81;
+	width: 150px;
+	float: right;
+}
+
+#console .oldrant h4 {
+	float: right;
+	margin:5px 0pt 5px 5px;
+}
+
+/* Shaded borders around images */
+#strip,
+#strip span {
+	display: block;        /* Everyone treat  like 
*/ + display: inline-block; /* Shrinkwrap blocks for IE */ +} + +/* hasLayout */ +* html #strip, * html #strip span { height: 1%; } + +#strip { + display: table; /* Shrinkwrap blocks for everyone else */ + position: relative; + margin: -33px auto 0px; + min-width: 650px; +} + +div#strip { + width:700px; + background-color: white; +} + +#strip-tl { + background: url(parts/mt-corner-UL.png) no-repeat left top; +} + +#strip-tr { + background: url(parts/mt-corner-UR.png) no-repeat right top; +} + +#strip-t { + background: url(parts/mt-slice-vert-top.png) repeat-x top; +} + +#strip-bl { + background: url(parts/mt-corner-LL.png) no-repeat left bottom; +} + +#strip-br { + background: url(parts/mt-corner-LR.png) no-repeat right bottom; +} + +#strip-b { + background: url(parts/mt-slice-vert-bottom.png) repeat-x bottom; +} + +#strip-l { + background: url(parts/mt-shadow-vert-left.png) repeat-y left; +} + +#strip-r { + background: url(parts/mt-shadow-vert-right.png) repeat-y right; +} + +#strip img { + margin: 33px 25px; +} + +#strip iframe { + border: none; + margin: 33px 25px; + width: 1024px; + height: 576px; +} + +#strip-transcript { + padding: 10px 10px 10px 10px; +} + +/* Center the comic */ +#comic { text-align:center } +#comic * { text-align:left } + +/* Overload header texts */ +#metabox h2 span { background: url(parts/mt-blk_bar-metabox.png) no-repeat } +#support h2 span { background: url(parts/mt-blk_bar-support.png) no-repeat } +#console h2 span { background: url(parts/mt-blk_bar-console.png) no-repeat } diff --git a/index.js b/index.js new file mode 100644 index 0000000..21ecc2c --- /dev/null +++ b/index.js @@ -0,0 +1,13 @@ +$(document).ready(function() { + /* Load up the Twitters and UI */ + /* XXX This doesn't work anymore. + $.getJSON('https://twitter.com/statuses/user_timeline/megatokyo.json?count=3&callback=?', function(obj) { + $('#feed-twitter-megatokyo').append(twitterToHTML(obj)); + $('#feed-twitter-megatokyo').hover(function(){ $(this).children('ul').show() }, function(){ $(this).children('ul').hide() }); + }); + $.getJSON('https://twitter.com/statuses/user_timeline/fredrin.json?count=3&callback=?', function(obj) { + $('#feed-twitter-fredrin').append(twitterToHTML(obj)); + $('#feed-twitter-fredrin').hover(function(){ $(this).children('ul').show() }, function(){ $(this).children('ul').hide() }); + }); + */ +}); diff --git a/index.php b/index.php new file mode 100644 index 0000000..b0470d8 --- /dev/null +++ b/index.php @@ -0,0 +1,504 @@ + $MAX_METHOD_ID) +{ + header('HTTP/1.0 404 Not Found'); + $EFFECTIVE_ID = $MAX_METHOD_ID; +} + +#$MTIME = mysqli_query($link,"SELECT UNIX_TIMESTAMP(MAX(pd)) +# FROM (SELECT MAX(pubdate) AS pd FROM fredart +# UNION SELECT published AS pd FROM strip WHERE id = $EFFECTIVE_ID +# UNION SELECT MAX(published) AS pd FROM rant) t") or die(mysqli_error($link)); +#conditional_exit(current(mysqli_fetch_row($MTIME))); + +$STRIP = load_strip($EFFECTIVE_ID) or term(410); +$TRANSCRIPT = load_transcript($EFFECTIVE_ID); +$HAS_TRANSCRIPT = mysqli_num_rows($TRANSCRIPT) > 0; + +$CONTROLS = load_nav_controls(); + +#$STATUS = load_status(); +$FREDART = load_fredart(); +$RANT['left'] = load_rant($EFFECTIVE_ID, 'left'); +$RANT['right'] = load_rant($EFFECTIVE_ID, 'right'); + +header("XX-Powered-By: Taiyaki"); +flock(fopen(SITE_PATH_ABS.'/'.SITE_STRIP.'/'.SITE_STRIP_LOCK, 'r'), LOCK_SH) or + trigger_error('Down for maintenance. Try again in a moment. (Bad lock)', E_USER_ERROR); + + +if(isset($_GET['strip_id']) || isset($_GET['transcript_id'])) + pagehead('index', "[$EFFECTIVE_ID] " . numeric_entities(utfentities($STRIP['title']))); +else + pagehead('index'); +?> + +
+ + + + + + + + + '); +} else { + printf('%s', SITE_STRIP, $EFFECTIVE_ID, $STRIP['ext'], $alttext, utfentities($tooltip)); +} +?> + + + + + + +
+
+
+
+
+
    + Panel $panel:
    "; + + # Print out all speaking characters + if(strlen($line[2]) > 0) { + $has_speakers = true; + do { + echo "
    $line[1]:
    ".($line[2] ? utfentities($line[2]) : ' ').'
    '; + } while(($line = mysqli_fetch_row($TRANSCRIPT)) && $line[0] == $panel && strlen($line[2]) > 0); + } + + # Given an "also shown" list if there is at least one silent character + if($line && $line[0] == $panel && strlen($line[2]) == 0) { + echo '
    ', ($has_speakers ? 'Also' : 'Characters'), ' shown:
    '; + $also = Array(); + do { + array_push($also, $line[1]); + } while(($line = mysqli_fetch_row($TRANSCRIPT)) && $line[0] == $panel); + sort($also, SORT_STRING); + echo '
    ' . join(', ', $also) . '
    '; + } + + echo '
    '; + } ?> +
+
+
+
+
+
+ + + + + +
+ + + + +
+

newsbox

+
+
+ +
+
+ A Fredart banner + S-Words +
    +
  • Megatokyo Twitter
  • +
  • Megatokyo RSS feed
  • +
  • Fred's Twitter
  • +
  • Fredart RSS Feed
  • +
+
+
+
+ +
+

support

+ +
+ + + MegaTokyo Visual Novel +
+ + + +
+ +
+

console

+ + +
+
+ + + + + + r.published AND r1.published < NOW() ORDER BY r1.published ASC LIMIT 1 ) AS next"; + $rantinfo = "rant r JOIN media_t m ON m.id = r.imagetype + JOIN contributor c ON c.id = r.author + JOIN strip s"; + $rantlimit = "( r.side = '$side' AND r.published < NOW() AND r.status = 'published' AND s.id = $id )"; + + # Create a window of previous days' rants on the most recent strip + if($MAX_METHOD_ID == $EFFECTIVE_ID) + $rantwindow = "UNION DISTINCT (SELECT $parameters FROM $rantinfo WHERE $rantlimit AND DATEDIFF(NOW(), r.published) < " . RANT_DATE_WINDOW . ')'; + + $lookahead = mysqli_query($link,"( SELECT $parameters + FROM $rantinfo LEFT JOIN strip sn ON sn.id = s.id + 1 + WHERE $rantlimit AND ( s.id = $id AND r.published >= s.published) AND ( r.published < sn.published OR sn.published IS NULL ) ) + $rantwindow + ORDER BY published DESC") or die(mysqli_error($link)); + + if(mysqli_num_rows($lookahead) > 0) + return $lookahead; + + $lookbehind = mysqli_query($link,"(SELECT $parameters + FROM $rantinfo + WHERE $rantlimit AND r.published < s.published + ORDER BY r.published DESC LIMIT 1) + $rantwindow + ORDER BY published DESC") or die(mysqli_error($link)); + + return $lookbehind; +} + +function load_status() +{ + global $link; + //"%a %c.%d.%Y [%I:%i %p EST (-5 GMT)]" + $qr = mysqli_query($link,'SELECT UNIX_TIMESTAMP(published) as udate, + DATE_FORMAT(published, "%a %c.%d.%Y [%I:%i %p EST (-5 GMT)]") AS published, + DATE_FORMAT(eta, "%a %c.%d.%Y [%I:%i %p EST (-5 GMT)]") AS eta, percentage, text + FROM status + ORDER BY udate DESC LIMIT 1') or die(mysqli_error($link)); + return mysqli_fetch_assoc($qr); +} + +function show_rantcol($side) +{ + global $RANT, $link; + ?> +
+ +
+
+ +

< >

+
+ +

%s', + $rant['link'], SITE_RANT, $rant['rantnum'], $rant['extension'], + utfentities($rant['alttext']), utfentities($rant['alttext'])) + ?>

+ +

""

+ + ', date('l - F j, Y', $rant['date']), '

'?> + [%s] - %s - [link here]

', $rant['email'], $rant['author'], date('H:i:s', $rant['date']), $rant['rantnum']) ?> + +
+ +
previous rant]"; + } + + echo ' - [rant archive]'; + + if($rant['next'] && $rant['prev']) + { + echo ' - '; + } + + if($rant['next']) + { + echo "[next rant]"; + } + ?>
+
+ +
+

%s', + $rant['link'], SITE_RANT, $rant['rantnum'], $rant['extension'], + utfentities($rant['alttext']), utfentities($rant['alttext'])) + ?>

+ +
+ +

< >

+
+ +

""

+
+ + ', date('l - F j, Y', $rant['date']), '

'?> + [%s] - %s - [link here]

', $rant['email'], $rant['author'], date('H:i:s', $rant['date']), $rant['rantnum']) ?> + +
+ +
previous rant]"; + } + + echo ' - [rant archive]'; + + if($rant['next'] && $rant['prev']) + { + echo ' - '; + } + + if($rant['next']) + { + echo "[next rant]"; + } + ?>
+
+ +
+ $lines) { + if(!is_numeric($panel)) + continue; + + $idx = array_push($transcript, Array()) - 1; + + foreach($lines as $line) { + array_push($transcript[$idx], $line['speaker']); + + if($line['speech']) + array_push($transcript, wordwrap("\t$line[speaker]:\t$line[speech]", 80, "\n\t\t")); + } + + $transcript[$idx] = "Panel $panel: " . implode(', ', array_unique($transcript[$idx])); + } + + return implode("\n", $transcript); +} + +function numeric_entities($string){ + $mapping = array(); + foreach (get_html_translation_table(HTML_ENTITIES, ENT_QUOTES) as $char => $entity){ + $mapping[$entity] = '&#' . ord($char) . ';'; + } + return str_replace(array_keys($mapping), $mapping, $string); +} + +?> diff --git a/main.css b/main.css new file mode 100644 index 0000000..56b5bd9 --- /dev/null +++ b/main.css @@ -0,0 +1,182 @@ +/* Set basic element styles */ +img { border:none } + +a { + text-decoration: none; + color: #f60; +} + +a:visited { color:#ececa3; } +a:hover { color:#eb5252; } + +body { + position: relative; /* Make IE not hate positioned elements */ + + margin: auto; + padding: 14px; + + background-color: #4c565e; + + font-size: 0.8em; + font-family: Verdana, Arial, Helvetica, sans-serif; +} + +/* Set default widths for page boxes */ +body div { + position: relative; + margin: auto; + width: 700px; +} +body div div { width:auto } + +/* Make the headers look nice */ +h1 { margin:0px } + +h2 { + text-align: left; + color: #f6b33d; +} + +/* Create special elements and classes */ +h2, .blackbar { + height: 18px; /* Take that, old gecko! */ + margin: 0px; + padding: 0px 1ex; + + overflow: hidden; + background-color: black; + + font-size: 16px; + font-weight: 150; + font-family: monospace; + letter-spacing: 0.5ex; +} + +h2 span, .blackbar span { + display: block; + width: 100%; + height: 100%; +} + +.clearer { clear:both } +br.clearer { line-height:0px } +.leftcol { float:left } +.rightcol { float:right } + +.nl { + margin: 0px; + padding: 0px; + + background-color: black; + text-align: center; + + list-style-type: none; +} + +.nl li { + display: inline; + margin: 0px; + padding: 0em 0.5ex; + color: #B7BFC7; +} + +.nl a { color:#b7bfc7; text-decoration:none } +.nl a:link, .nl a:visited { color:#b7bfc7 } +.nl a:hover { color:#eb5252 } + +.content { + margin-top: 1em; + margin-bottom: 1em; + background-color: black; + color: #b7bfc7; +} + +.content div { + /* Satisfy internal floated elements */ + overflow: hidden; + height: 100%; + + border: solid 5px black; + background-color: #23272b; + padding: 5px; +} + +.content .clearer { + border: none; + padding: 0px; +} + +/* Correct a word wrapping bug in the ad bar */ +#adbar { + position: relative; + height: 90px; + text-align: center; + font-size: 1px; + letter-spacing: 500px; +} + +#adbar #megagear-ad { + position: absolute; + top: 14px; + left: 0px; +} + +#adbar #kickstarter-ad { + position: absolute; + top: 14px; + left: 115px; +} + +#adbar #cologuys-ad { + position: absolute; + top: 14px; + right: 0px; +} + +#adbar .glowwrap { + position: absolute; + display: block; + top: 0px; + left: 50%; + width: 468px; + margin-left: -246px; + + background-image:url(parts/banner_bg.gif); + padding: 14px 12px; +} + +/* Style the top banner */ +#banner { + background-color: black; + text-align: center; +} + +#banner h2 { + color: #b7bfc7; + font-family: monospace; +} + +#banner .nl { + padding-bottom: 5px; + padding-top: 5px; +} + +/* Style the footer */ +#credits { + background-color: #757b81; + color: #e4e4d6; + padding-bottom: 0.5ex; + margin-top: 1em; +} + +#credits p { + margin: 0px; + text-align: center; + padding: 0.5ex; + font-family: Arial, helvetica, sans-serif; + font-size: x-small; +} + +/* Overload header texts */ +#banner .blackbar span { background: url(parts/mt3-bar-comic.gif) no-repeat } +#credits h2 span { background: url(parts/mt-blk_bar-credits.png) no-repeat } \ No newline at end of file diff --git a/menu.php b/menu.php new file mode 100644 index 0000000..0bd793f --- /dev/null +++ b/menu.php @@ -0,0 +1,10 @@ + diff --git a/mt-blk_bar-metabox.png b/mt-blk_bar-metabox.png new file mode 100644 index 0000000000000000000000000000000000000000..4f3bafd37c224e2527bdd9ff2047c79486aa09fa GIT binary patch literal 1749 zc$@*%1}gc9P)p5-&mKC79_1Z$!C!BM@02#yB)FU;<<~Q6}-jVle2u-;j-)jCEr}$~Lxk^sMV; zuOG(B#srt1>Sq1_k|#NRn?C1F&zGl9o^vVz5FjEVA|eV?x}n|x5fKp)(LX8d3f=^> z0=-Te>TL|#qjQq*_}rwS-Ubm75mDF*yMp(}x30&dbN)L8H)#@=sQkQi@3=9nmKDsMzp zjYHE3^*Ra5?jD2r(=9M6I<$6pQSwnEDt~Izls7#&67Md}z|_oG*xNj4c6b2*)ixIj zHyzWI8vqnpLiws3j2>YC0NCtqy!A;FzO2^veUz=pMuein=fAdNL0$q3iiBTk&tuK@ zdYo%&g$`r>S0?Wuwk#761y z+Rg@zyCxzcA_|=W9o})HBQSeP9A3OH6-GtE`oal#a()WNjx?gQI79OZ-&>Y})entF z-5EE&KjuV~QIC&T=i;us1WkEeZa=DRE_4flGi@FmJb6A4q2Tii{C3h6$e9>t!0r{< zh>6hNO}=IF2)zDC8vZ!vLA6cA9n&qSTz`$`+zV%o!k*Q+Feo~Ff6R$f&0Sdca2noz zTKjd>NfJtnGjQ`HGXUU@85XQBoB+N4zcW8gL_|dYAEIw$kBb&+g;f+4q=@S$#t5~- zDi+QfB^Ku=3bn#2A`Cil>1PHTqed8nT45EB%}old=_H7~>vF}HnQ=YOF*`l>PPuxDu5?Gs>X%cFMRor$%yr$e$CD(}$SLO(v zbaAbyAVsJZRx#47Xv%GnCGq)&YemzJ8Dicvi?El?6y>Y>pNqj@Fc=I5V>pD2%c!xr z0>|}sH_{R#002fs2e+sDav!^*c+?0T+pTNS`4&$qm z>#%!8HjXr?ShVq|=1~bEA|j$tyKKRGDYv($$Tce3?{nL{Bz?eIb)N!zxXBqGjqNX7 zjn95Khl9;MBN8bIMgTyhQTz8Hg8Th2on&jA|fIRr9l_GT_Nc3+U#yLwRE8{KM6+~)P5a7e~7xAhwEL) z%Q54?AqNbygm;QFP%C1ZWz1la6u)SU_b2LJ#R z6{KKsej=7^IgV|Wc652WvGRd&sJ6MVbN|`DPe4ROMD#BiQ1JG48J(&h?dLBXclzP% z>?uxzo!Xj$2Uiuh>MZ2cWo|!o+nN`vH3V`c5Pkn z7v4RI1hazDXD&XK;l$}qELdBkY1URJ0c#!_kIj1;v8~b$0C;0p1G2_OVfBOKS@04O z5z(+R;5ocN&wOfAOV@zoWQzf(TeUwM)*wsB8XMhjJmSP@H_mkge-l+-Mn#87Y0>EP zboaaYPOFJ2k%)_t;q?m~s&l~-tDx2Ch0h;+_1OC-8J(VPWQ~o2LDu2-rp~|*k5K5{ zx7*u|BMoXu#u*ah4Y0R)Ao`?|^%CMuN=Tj`OhiOP6e@pN@DdRb5fO!pu={IaA|fIp rqP|%05)ly*QCMTaOGHFOL}Beun!wN{6rc(600000NkvXXu0mjfTIMbS literal 0 Hc$@openMemory(); + $xml->startDocument('1.0', 'UTF-8'); + $xml->startElement('root'); + + function write(XMLWriter $xml, $data) + { + foreach($data as $key => $value) + { + if(is_array($value)) + { + echo "$key\n"; + $xml->startElement($key); + write($xml, $value); + $xml->endElement(); + continue; + } + $xml->writeElement($key, $value); + } + } + write($xml, $data); + + $xml->endElement(); + return $xml->outputMemory(true); +} + +$API = new ReflectionClass('MTAPIi'); + +if( $API->hasMethod($_GET['method']) ) { + $method = $API->getMethod($_GET['method']); + $parameters = $method->getParameters(); + + $method_parameters = Array(); + foreach($parameters as $parameter) { + $param = (Array) $parameter; + $parameter_name = reset($param); + if(isset( $_GET[$parameter_name] )) + array_push($method_parameters, $_GET[$parameter_name]); + elseif( 'xml' == $parameter->getName() && 'xml' == $_GET['output-type'] ) + array_push($method_parameters, true); + elseif( $parameter->isOptional() ) + { /* empty */ } + else { + header('HTTP/1.0 400 Bad Request'); + printf( 'Parameter %s is required but not supplied', $parameter_name ); + } + } + + $result = $method->invokeArgs($API, $method_parameters); + + switch($_GET['output-type']) { + case 'json': + $result = json_encode($result); + header('Content-Type: application/json'); + echo $result; + break; + case 'xml': + header('Content-Type: application/xml'); + echo $result; + break; + default: + header('HTTP/1.0 400 Bad Request'); + header('Content-Type: text/plain'); + print_r($result); + break; + } +} else { + header('HTTP/1.0 404 Not Found'); + echo 'There is no such method in the MT API.'; +} + +?> diff --git a/navswitch.js b/navswitch.js new file mode 100644 index 0000000..2960569 --- /dev/null +++ b/navswitch.js @@ -0,0 +1,59 @@ + +var PageLoaded = 0; + +window.onload = function() { + PageLoaded = 1; +} + +function navwait(i) { + if ( document.getElementById && document.getElementById(i) !== null ) { + navinit(); + } else if ( !PageLoaded ) { + setTimeout('navwait(\''+i+'\')', 100); + } +} + +function navinit() { + f = document.getElementById('searchprevnext'); + f.style.display="none"; + + b = document.getElementById('q'); + for( i=0; i + + + + MegaTokyo - Fredarting + + + + +
+ + + + + + + + + + +
+ + + diff --git a/rant-archive.php b/rant-archive.php new file mode 100644 index 0000000..87d7d42 --- /dev/null +++ b/rant-archive.php @@ -0,0 +1,80 @@ + + +
+

View By:

+ +
+ +

Rants by Date

    '; + + while($rant = mysqli_fetch_assoc($rants)) + { + printf('
  1. %s - %s
  2. ', $rant['pubdate'], $rant['id'], $rant['id'], + $rant['author'], utfentities($rant['title'])); + } + + echo '
'; +} +else +{ +?> + +

', utfentities($author['name']), '

    '; + + while($rant = mysqli_fetch_assoc($rants)) + { + printf('
  1. %s
  2. ', $rant['pubdate'], $rant['id'], $rant['id'], + utfentities($rant['title'])); + } + echo '
'; + } +} + +pagefoot(); +?> + + diff --git a/resources.js b/resources.js new file mode 100644 index 0000000..74b0e8a --- /dev/null +++ b/resources.js @@ -0,0 +1,61 @@ +function relative_time(time_value) { + var values = time_value.split(" "); + time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3]; + var parsed_date = Date.parse(time_value); + var relative_to = (arguments.length > 1) ? arguments[1] : new Date(); + var delta = parseInt((relative_to.getTime() - parsed_date) / 1000); + delta = delta + (relative_to.getTimezoneOffset() * 60); + + if (delta < 60) { + return 'less than a minute ago'; + } else if(delta < 120) { + return 'about a minute ago'; + } else if(delta < (60*60)) { + return (parseInt(delta / 60)).toString() + ' minutes ago'; + } else if(delta < (120*60)) { + return 'about an hour ago'; + } else if(delta < (24*60*60)) { + return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago'; + } else if(delta < (48*60*60)) { + return '1 day ago'; + } else { + return (parseInt(delta / 86400)).toString() + ' days ago'; + } +} + +function twitterToHTML(twitters, title) { + var statusHTML = ''; + + for (var i=0; i]*[^.,;'">\:\s\<\>\)\]\!])/ig, "$1"); + var uri = 'https://twitter.com/' + twitters[i].user.screen_name + '/statuses/' + twitters[i].id; + statusHTML += '
  • · ' + tweet + ' ' + relative_time(twitters[i].created_at) + '
  • '; + } + + return ''; +} + +function mtCallback(obj) { + $('#feed-twitter-megatokyo').html(twitterToHTML(obj, "Megatokyo Twitter")); +} + +function fredCallback(obj) { + $('#feed-twitter-fredrin').html(twitterToHTML(obj, "Fred's Twitter")); +} + +function generateAd(zone, root) +{ + if (!document.phpAds_used) + document.phpAds_used = ','; + + phpAds_random = new String (Math.random()); + phpAds_random = phpAds_random.substring(2,11); + + document.write (""); +} diff --git a/rewrite_searchbox.js b/rewrite_searchbox.js new file mode 100644 index 0000000..c78f988 --- /dev/null +++ b/rewrite_searchbox.js @@ -0,0 +1,22 @@ +var textbox = document.getElementById('q'); +var filters = document.getElementById('search-filters'); + +var metarx = new RegExp(/\bmeta:"(.*?)"/); + +while(match = metarx.exec(textbox.value)) { + var checks = document.getElementById('search-filters'); + checks = checks.getElementsByTagName('input'); + + var t = checks[4].checked; + checks[4].checked = true; + checks[4].checked = false; + checks[4].checked = t; + + for(i=0; i + +

    About Searching

    +As the guy who wrote the search, I'm the logical candidate to +explain the thing. I'm not quite sure what they other guys make of +it, except that questions about it are bounced to me with remarkable +alacrity.

    + +Without further delay, I'll cut right to the subject: taming the +vicious search ninjas. I mean, using the search engine. Same +difference.

    + +There are two main modes to the search. There's search, which +displays a list of results, and find, which just takes you directly +to a strip. Both are accessible from the index page. +Hitting 'enter' or pushing the "go" +button will initiate a normal search. Entering any text in the +searchbox or checking any of the checkboxes will cause the find +buttons to appear. They take you to the previous or next comic +fitting the criteria you've provided. Or the search ninjas apologize +for not being able to find anything, either way.

    + +A brief note about the checkboxes - none checked is the same as +all checked. It makes no difference, except that the latter may take +slightly longer.

    + +The search does a lot of interesting little things. One of the +more useful ones is that if just put in a number and hit enter, +you'll be taken to that strip. Go on, try it. I'll be here when you +get back. One of the side-effects of this is that if you want to +search for a number you have to enclose +it in quotes, but that's the price of convenience.

    + +The most important operator is the colon. It distinguishes between +someone speaking and what's being said. The next most important +operator is the asterisk: *. It's a wildcard, denoting that something +goes there. There's a big difference between looking +for Largo and looking for someone +talking about Largo. Then there's looking for Erika +talking about Largo, in which the colon makes a very +big difference in the results you get.

    + +There are a few useful magic words - note the highly technical +term. One of them is "chapter". For illustration, here's +Kimiko +in Chapter 6. There's also "min" and "max", +which do pretty much what you might expect. Just so we're clear, +here's what +Piro was up to between comics 400 and 500. There are other magic +words. One of them is "meta", and it's documented on the +search page.

    + +There's one deserving of special mention: "#:random". It +takes you to a random strip within the criteria you specify. So if +you're Alpicola, you can go to a +random Megumi strip with ease.

    + +There may or may not be others. Explore as you will. Just watch +out for the ninjas.

    + +--Kalium +
    + + + + \ No newline at end of file diff --git a/search.css b/search.css new file mode 100644 index 0000000..fc3206a --- /dev/null +++ b/search.css @@ -0,0 +1,31 @@ +.search { + margin: 10px; +} + +.search #q { + width: 45%; +} + +.results { + margin: 0px; + padding: 1ex 2em; + background-color: #757b81; +} + +.results, .results a { color: #f6b33d; } +.results a:visited { color:#ececa3; } +.results a:hover { color:#eb5252; } + +#syntax code { color:#f6b33d } +#syntax form { margin:0px } + +dt { + font-size:larger; +} + +ol { + list-style-type: none; +} + +/* Overload header texts */ +#syntax h2 span { background:url(parts/mt-blk_bar-search_syntax.png) no-repeat } diff --git a/search.php b/search.php new file mode 100644 index 0000000..7066a96 --- /dev/null +++ b/search.php @@ -0,0 +1,598 @@ += $_REQUEST['q'] && $_REQUEST['q'] > 0) + { + header('HTTP/1.0 301 Moved Permanently'); + header('Location: ' . SITE_HOST . SITE_PATH . "/strip/$_REQUEST[q]"); + exit(0); + } +} + +#check if it's a date +#try these three different formats +# mm dd yyyy first +$date = strptime($_REQUEST['q'], "%m.%d.%Y"); +if(!$date) $date = strptime($_REQUEST['q'], "%m/%d/%Y"); +if(!$date) $date = strptime($_REQUEST['q'], "%m-%d-%Y"); + +#then yyyy mm dd +if(!$date) $date = strptime($_REQUEST['q'], "%Y/%m/%d"); +if(!$date) $date = strptime($_REQUEST['q'], "%Y.%m.%d"); +if(!$date) $date = strptime($_REQUEST['q'], "%Y-%m-%d"); + +#if date, convert to unix timestamp +if($date) +{ + $date_formatted = (1900+$date['tm_year']).'-'.(1+$date['tm_mon']).'-'.$date['tm_mday']; + $date_f = strtotime($date_formatted); + $date_f = strtotime("+1 day", $date_f); +} + +#if unix timestamp, try to go there +if($date_f && $date) +{ + $goto = get_by_date($date_f); + if(isset($goto) && $goto > 0) + { + header('HTTP/1.0 301 Moved Permanently'); + header('Location: ' . SITE_HOST . SITE_PATH . "/strip/$goto"); + exit(0); + } +} + +if(isset($_REQUEST['q'])) +{ + + if( isset($_GET['method-fp_x']) || isset($_GET['method-fp_y']) + || isset($_GET['method-fp.x']) || isset($_GET['method-fp.y']) ) { + array_push($magic, 'max'); + array_push($value, $_GET['current'] - 1); + + array_push($magic, 'method'); + array_push($value, 'Find Previous'); + } + if( isset($_GET['method-fn_x']) || isset($_GET['method-fn_y']) + || isset($_GET['method-fn.x']) || isset($_GET['method-fn.y']) ) { + array_push($magic, 'min'); + array_push($value, $_GET['current'] + 1); + + array_push($magic, 'method'); + array_push($value, 'Find Next'); + } + + // Turn named parameters into query string items + $_REQUEST['q'] = trim($_REQUEST['q']); + foreach($_GET as $k => $v) { + if( $k == 'x' || $k == 'y' ) continue; + if( $k == 'q' || $k == 'current' ) continue; + if( substr($k, 0, 7) == 'method-' ) continue; + if(is_array($v)) { + foreach($v as $val) + $_REQUEST['q'] = trim("$_REQUEST[q] $k:\"$val\""); + } else { + $_REQUEST['q'] = trim("$_REQUEST[q] $k:\"$v\""); + } + } + + if(get_magic_quotes_gpc()) + $_REQUEST['q'] = stripslashes($_REQUEST['q']); + + $tokens = tpw_parse_line('\s+', $_REQUEST['q']); + + # Protect against SQL injection in the event of Register Globals being on. + $SEARCH_MIN = $SEARCH_MAX = null; + + foreach($tokens as $token) { + $token = strtolower($token); + + # Determine if we want to subtract + if($token[0] == '-') { + $token = substr($token, 1); + $loop_magic =& $sub_magic; + $loop_value =& $sub_value; + } else { + $loop_magic =& $magic; + $loop_value =& $value; + } + + $subtokens = preg_match('/(?:\w+|[#*]):/', $token) ? preg_split('/:/', $token, 2) : Array( false, $token ); + + # Magic values are easy, just throw them on the list + array_push($loop_magic, $subtokens[0]); + + # Values, however, need a bit more cleaning up first + if('""' == $subtokens[1]) + array_push($loop_value, '""'); + else + array_push($loop_value, preg_replace('/[[:punct:]]|(?<=\s)\s+/', '', $subtokens[1])); + } + + #DEBUG + #print_r($magic); + #echo "
    "; + #print_r($value); + #echo "
    "; + + #do subtraction logic first + if(count($sub_magic) > 0) + { + #iterate over all subtraction magic/value pairs + foreach($sub_magic as $i => $m) + { + $query = "SELECT DISTINCT strip.id FROM strip + LEFT JOIN transcript ON strip.id = transcript.strip + JOIN strip_t ON strip.type = strip_t.id + LEFT JOIN meta ON strip_t.id = meta.type + LEFT JOIN meta_t ON meta.meta = meta_t.id + WHERE (strip.published < NOW()) + AND (transcript.speaker NOT LIKE \"#%\" + OR transcript.speaker IS NULL) "; + + $flag = false; + + if($m) #attempt to short-circuit on no magic + { + # well, we have magic + if($m == "type" || $m == "chapter") + { + if(ctype_digit(strval($sub_value[$i]))) + { + $modifier .= " AND (strip_t.description NOT LIKE '%chapter ".mysqli_real_escape_string($link,$sub_value[$i])."%')"; + continue; + } + else + { + $modifier .= " AND (strip_t.description NOT LIKE '%".mysqli_real_escape_string($link,$sub_value[$i])."%')"; + continue; + } + } + else if($m == "meta") + { + $modifier .= " AND (meta_t.name NOT LIKE '".mysqli_real_escape_string($link,$sub_value[$i])."%')"; + continue; + } + else if($m == "*") + { + #we want to exclude the speaker from this search + # but here, we don't actually need to do much + $m = mysqli_real_escape_string($link,$m); + } + else + { + #it's not a special operator, so assume they mean a character speaking + $tmp = mysqli_real_escape_string($link,$m); + $query .= "AND (transcript.speaker LIKE \"%$tmp%\" ) "; + $flag = true; + } + } + + #now, handle the $value portion of the string + # first, handle for "" + switch($sub_value[$i]) { + case '""': + $query .= "AND (transcript.search = '' ) "; + break; + case '': + break; + case '*': + $query .= "AND (transcript.search != '' ) "; + break; + default: + $tmp = mysqli_real_escape_string($link,$sub_value[$i]); + $query .= "AND (transcript.search LIKE \"%$tmp%\""; + if($m != '*' && !$flag) + { + $query.= "OR transcript.speaker = \"$tmp\" + OR strip.title LIKE \"%$tmp%\" "; + } + $query.=") "; + } + + array_push($sub_queries, $query); + } + + foreach($sub_queries as $q) + { + #DEBUG: run the search + #echo $q; + $result = mysqli_query($link,$q); + + if(!$result) + { + continue; + } + + while($row = mysqli_fetch_row($result)) + { + #and put all the hits onto an array + array_push($sub_rhits, $row[0]); + } + } + } + + foreach($magic as $i => $m) + { + $query = "SELECT DISTINCT strip.id FROM strip + LEFT JOIN transcript ON strip.id = transcript.strip + JOIN strip_t ON strip.type = strip_t.id + LEFT JOIN meta ON strip_t.id = meta.type + LEFT JOIN meta_t ON meta.meta = meta_t.id + WHERE (strip.published < NOW()) + AND (transcript.speaker NOT LIKE \"#%\" + OR transcript.speaker IS NULL) "; + + $flag = false; + + if($m) #attempt to short-circuit on no magic + { + # well, we have magic + # so handle special operators first + # max and min don't really generate queries, so they short-circuit the loop + if($m == "min") + { + if(ctype_digit(strval($value[$i]))) + $SEARCH_MIN = (int)$value[$i]; + continue; + } + else if($m == "max") + { + if(ctype_digit(strval($value[$i]))) + $SEARCH_MAX = (int)$value[$i]; + continue; + } + else if($m == "#") + { + if(ctype_digit(strval($value[$i]))) + { + header('HTTP/1.0 301 Moved Permanently'); + header('Location: ' . SITE_HOST . SITE_PATH . "/strip/$value[$i]"); + exit(0); + } + elseif($value[$i] == "random") + { + $random = true; + } + continue; + } + else if($m == "type" || $m == "chapter") + { + if(ctype_digit(strval($value[$i]))) + { + array_push($SEARCH_TYPES, mysqli_real_escape_string($link,"chapter ".$value[$i])); + continue; + } + else + { + array_push($SEARCH_TYPES, mysqli_real_escape_string($link,$value[$i])); + continue; + } + } + else if($m == "meta") + { + array_push($META_TYPES, mysqli_real_escape_string($link,$value[$i])); + continue; + } + else if($m == "book") + { + if(ctype_digit(strval($value[$i]))) + { + $BOOK = " AND (strip.book =" . (int)$value[$i] . ") "; + continue; + } + } + else if($m == "page") + { + if(ctype_digit(strval($value[$i]))) + { + $PAGE = " AND (strip.page =" . (int)$value[$i] . ") "; + continue; + } + } + else if($m == "method") + { + $METHOD = $value[$i]; + continue; + } + else if($m == "*") + { + #we want to exclude the speaker from this search + # but here, we don't actually need to do much + $m = mysqli_real_escape_string($link,$m); + } + else + { + #it's not a special operator, so assume they mean a character speaking + $tmp = mysqli_real_escape_string($link,$m); + $query .= "AND (transcript.speaker LIKE \"%$tmp%\" ) "; + $flag = true; + } + } + + #now, handle the $value portion of the string + # first, handle for "" + switch($value[$i]) { + case '""': + $query .= "AND (transcript.search = '' ) "; + break; + case '': + break; + case '*': + $query .= "AND (transcript.search != '' ) "; + break; + default: + $tmp = mysqli_real_escape_string($link,$value[$i]); + $query .= "AND (transcript.search LIKE \"%$tmp%\""; + if($m != '*' && !$flag) + { + $query.= "OR transcript.speaker = \"$tmp\" + OR strip.title LIKE \"%$tmp%\" "; + } + $query.=") "; + } + + array_push($queries, $query); + } + + if(count($queries) == 0) + { + array_push($queries, $query); + } + + #additive search logic + + #generate type and metatype strings now + #searching for a specific type is a little messy + if(count($SEARCH_TYPES) > 0) + { + foreach($SEARCH_TYPES as $SEARCH) + { + array_push($SEARCH_TEMP, "strip_t.description LIKE '%$SEARCH%' + OR strip_t.name LIKE '%$SEARCH%'"); + } + #second, collapse them into one clause + $modifier .= " AND (" . implode(" OR ", $SEARCH_TEMP) . ") "; + } + + #now the metatypes, just like the types + if(count($META_TYPES) > 0) + { + #OK, now apply the metatype restrictions... + foreach($META_TYPES as $META) + { + #first, generate the restriction strings + array_push($META_TEMP, "meta_t.name LIKE '" . $META . "%'"); + } + #second, collapse them into one clause + $modifier .= " AND (" . implode(" OR ", $META_TEMP) . ") "; + } + + #now do min and max + if(isset($SEARCH_MIN)) + { + $modifier .= "AND ($SEARCH_MIN <= strip.id) "; + } + if(isset($SEARCH_MAX)) + { + $modifier .= "AND (strip.id <= $SEARCH_MAX) "; + } + + #and now book and page + if(isset($BOOK)) + { + $modifier .= $BOOK; + } + if(isset($PAGE)) + { + $modifier .= $PAGE; + } + + foreach($queries as $q) + { + #apply modifiers + $q .= $modifier; + #DEBUG: run the search + #echo $q; + if(empty($q)) { + continue; + } + $result = mysqli_query($link,$q); + + if(!$result) + { + continue; + } + + while($row = mysqli_fetch_row($result)) + { + #and put all the hits onto an array + array_push($rhits, $row[0]); + } + } + + #so, now all the raw hits are in the same spot + #now comes The Magic + + # if book and page are used, break out + if(isset($BOOK) && isset($PAGE) && count($rhits) != 0) + { + header('HTTP/1.0 301 Moved Permanently'); + header('Location: ' . SITE_HOST . SITE_PATH . "/strip/$rhits[0]"); + exit(0); + } + + #first, reverse sort and uniquify a copy + rsort($rhits); + $uhits = array_unique($rhits); + #do the same for the subtraction hits + $sub_uhits = array_unique($sub_rhits); + + #now... the subtraction! + $uhits = array_diff($uhits, $sub_uhits); + + #if we're redirecting, break out of the normal search logic here + if(isset($METHOD) && count($uhits) > 0) + { + #$METHOD has a value, so we're bustin' outta here! + if($METHOD == "Find Next") + { + $target = end($rhits); + } + else if($METHOD == "Find Previous") + { + $target = $rhits[0]; + } + + //die($METHOD); + + header('HTTP/1.0 301 Moved Permanently'); + header('Location: ' . SITE_HOST . SITE_PATH . "/index.php?strip_id=$target" . "&q=" . urlencode($_REQUEST['q'])); + exit(0); + } + + $revhits = array_reverse($rhits); + #now create a count for each unique hit + foreach($uhits as $key => $value) + { + $first = array_search($value, $rhits); + $last = array_search($value, $revhits); + + $numhits = count($rhits) - $first - $last; + + array_push($hcount, $numhits); + } + + if(count($uhits) > 0) { + if($random) + { + $rand = mt_rand(1, count($uhits)); + header('Location: ' . SITE_HOST . SITE_PATH . "/index.php?strip_id=$uhits[$rand]" . "&q=" . urlencode($_REQUEST['q'])); + } + $qsearch = mysqli_query($link,'SELECT id, title FROM strip WHERE id IN(' . implode(', ', $uhits) . ') GROUP BY id ORDER BY id DESC'); + while($result = mysqli_fetch_array($qsearch)) + { + $entry = "
  • ".str_pad($result[0], 4, 0, STR_PAD_LEFT); + $entry.= " - ". htmlentities($result[1]) . "
  • "; + array_push($strings, $entry); + } + + #now, a clever multisort... + array_multisort($hcount, SORT_DESC, SORT_NUMERIC, + $uhits, SORT_DESC, SORT_NUMERIC, + $strings, SORT_ASC, SORT_STRING); + } +} + +pagehead('search', 'Search'); +?> + + + + 0) { + echo '
      '; + /*$qsearch = mysqli_query($link,'SELECT id, title FROM strip WHERE id IN(' . implode(', ', $uhits) . ')'); + while($result = mysqli_fetch_array($qsearch)) + printf('
    1. %s - %s
    2. ', + $result[0], str_pad($result[0], 4, 0, STR_PAD_LEFT), $result[1]);*/ + foreach($strings as $str) + { + echo $str; + } + echo '
    '; + echo '
    '; + + ?> + + 0)) { + echo '

    So sorry. Search ninjas obey without fail, yet find nothing.

    '; + echo '
    '; + } else + { + echo ''; + } + #search_help(); + + ?> + + + + + diff --git a/static.css b/static.css new file mode 100644 index 0000000..70e2e71 --- /dev/null +++ b/static.css @@ -0,0 +1 @@ +h3, h4, h5, h6 { color:#f6b33d } diff --git a/static.php b/static.php new file mode 100644 index 0000000..dc1bf17 --- /dev/null +++ b/static.php @@ -0,0 +1,32 @@ + + +
    +

    +
    + +
    + + + + diff --git a/story.css b/story.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/story.css diff --git a/support.css b/support.css new file mode 100644 index 0000000..0784fc4 --- /dev/null +++ b/support.css @@ -0,0 +1,19 @@ +#inner { + /* Satisfy internal floated elements */ + overflow: hidden; + height: 100%; + border: none; + margin: 0em 1em; +} + +#inner img +{ + display: block; + margin-left: auto; + margin-right: auto +} + +#inner h3 +{ + color:#F6B33D; +} \ No newline at end of file