travis configuration

This commit is contained in:
Nicolas Lœuillet 2015-01-19 13:37:32 +01:00
parent 99410a21eb
commit 3d99ce9dad
31 changed files with 3 additions and 4106 deletions

3
.travis.yml Normal file
View file

@ -0,0 +1,3 @@
branches:
only:
- refactor

View file

@ -1,413 +0,0 @@
<?php
/**
* Description of CharacterEntities
*
* @author Sander
*/
class CharacterEntities {
public static function convert($str){
//Assume the encoding is UTF-8 -> output is UTF-8
return $str;
//return utf8_encode($str);
//Convert to CP1252
list($from, $to) = CharacterEntities::generateTables();
return str_replace($from, $to, $str);
}
private static function generateTables(){
$from = array();
$to = array();
for($i = 0; $i < 256; $i++){
$from[$i] = $to[$i] = chr($i);
}
$from[0x80] = "";
$from[0x82] = "";
$from[0x83] = "ƒ";
$from[0x84] = "";
$from[0x85] = "";
$from[0x86] = "";
$from[0x87] = "";
$from[0x88] = "ˆ";
$from[0x89] = "";
$from[0x8A] = "Š";
$from[0x8B] = "";
$from[0x8C] = "Œ";
$from[0x8E] = "Ž";
$from[0x91] = "";
$from[0x92] = "";
$from[0x93] = "";
$from[0x94] = "";
$from[0x95] = "";
$from[0x96] = "";
$from[0x97] = "";
$from[0x98] = "˜";
$from[0x99] = "";
$from[0x9A] = "š";
$from[0x9B] = "";
$from[0x9C] = "œ";
$from[0x9E] = "ž";
$from[0x9F] = "Ÿ";
$from[0xA1] = "¡";
$from[0xA2] = "¢";
$from[0xA3] = "£";
$from[0xA4] = "¤";
$from[0xA5] = "¥";
$from[0xA6] = "¦";
$from[0xA7] = "§";
$from[0xA8] = "¨";
$from[0xA9] = "©";
$from[0xAA] = "ª";
$from[0xAB] = "«";
$from[0xAC] = "¬";
$from[0xAE] = "®";
$from[0xAF] = "¯";
$from[0xB0] = "°";
$from[0xB1] = "±";
$from[0xB2] = "²";
$from[0xB3] = "³";
$from[0xB4] = "´";
$from[0xB5] = "µ";
$from[0xB6] = "";
$from[0xB7] = "·";
$from[0xB8] = "¸";
$from[0xB9] = "¹";
$from[0xBA] = "º";
$from[0xBB] = "»";
$from[0xBC] = "¼";
$from[0xBD] = "½";
$from[0xBE] = "¾";
$from[0xBF] = "¿";
$from[0xC0] = "À";
$from[0xC1] = "Á";
$from[0xC2] = "Â";
$from[0xC3] = "Ã";
$from[0xC4] = "Ä";
$from[0xC5] = "Å";
$from[0xC6] = "Æ";
$from[0xC7] = "Ç";
$from[0xC8] = "È";
$from[0xC9] = "É";
$from[0xCA] = "Ê";
$from[0xCB] = "Ë";
$from[0xCC] = "Ì";
$from[0xCD] = "Í";
$from[0xCE] = "Î";
$from[0xCF] = "Ï";
$from[0xD0] = "Ð";
$from[0xD1] = "Ñ";
$from[0xD2] = "Ò";
$from[0xD3] = "Ó";
$from[0xD4] = "Ô";
$from[0xD5] = "Õ";
$from[0xD6] = "Ö";
$from[0xD7] = "×";
$from[0xD8] = "Ø";
$from[0xD9] = "Ù";
$from[0xDA] = "Ú";
$from[0xDB] = "Û";
$from[0xDC] = "Ü";
$from[0xDD] = "Ý";
$from[0xDE] = "Þ";
$from[0xDF] = "ß";
$from[0xE0] = "à";
$from[0xE1] = "á";
$from[0xE2] = "â";
$from[0xE3] = "ã";
$from[0xE4] = "ä";
$from[0xE5] = "å";
$from[0xE6] = "æ";
$from[0xE7] = "ç";
$from[0xE8] = "è";
$from[0xE9] = "é";
$from[0xEA] = "ê";
$from[0xEB] = "ë";
$from[0xEC] = "ì";
$from[0xED] = "í";
$from[0xEE] = "î";
$from[0xEF] = "ï";
$from[0xF0] = "ð";
$from[0xF1] = "ñ";
$from[0xF2] = "ò";
$from[0xF3] = "ó";
$from[0xF4] = "ô";
$from[0xF5] = "õ";
$from[0xF6] = "ö";
$from[0xF7] = "÷";
$from[0xF8] = "ø";
$from[0xF9] = "ù";
$from[0xFA] = "ú";
$from[0xFB] = "û";
$from[0xFC] = "ü";
$from[0xFD] = "ý";
$from[0xFE] = "þ";
$from[0xFF] = "ÿ";
return array($from, $to);
}
/*
00 = U+0000 : NULL
01 = U+0001 : START OF HEADING
02 = U+0002 : START OF TEXT
03 = U+0003 : END OF TEXT
04 = U+0004 : END OF TRANSMISSION
05 = U+0005 : ENQUIRY
06 = U+0006 : ACKNOWLEDGE
07 = U+0007 : BELL
08 = U+0008 : BACKSPACE
09 = U+0009 : HORIZONTAL TABULATION
0A = U+000A : LINE FEED
0B = U+000B : VERTICAL TABULATION
0C = U+000C : FORM FEED
0D = U+000D : CARRIAGE RETURN
0E = U+000E : SHIFT OUT
0F = U+000F : SHIFT IN
10 = U+0010 : DATA LINK ESCAPE
11 = U+0011 : DEVICE CONTROL ONE
12 = U+0012 : DEVICE CONTROL TWO
13 = U+0013 : DEVICE CONTROL THREE
14 = U+0014 : DEVICE CONTROL FOUR
15 = U+0015 : NEGATIVE ACKNOWLEDGE
16 = U+0016 : SYNCHRONOUS IDLE
17 = U+0017 : END OF TRANSMISSION BLOCK
18 = U+0018 : CANCEL
19 = U+0019 : END OF MEDIUM
1A = U+001A : SUBSTITUTE
1B = U+001B : ESCAPE
1C = U+001C : FILE SEPARATOR
1D = U+001D : GROUP SEPARATOR
1E = U+001E : RECORD SEPARATOR
1F = U+001F : UNIT SEPARATOR
20 = U+0020 : SPACE
21 = U+0021 : EXCLAMATION MARK
22 = U+0022 : QUOTATION MARK
23 = U+0023 : NUMBER SIGN
24 = U+0024 : DOLLAR SIGN
25 = U+0025 : PERCENT SIGN
26 = U+0026 : AMPERSAND
27 = U+0027 : APOSTROPHE
28 = U+0028 : LEFT PARENTHESIS
29 = U+0029 : RIGHT PARENTHESIS
2A = U+002A : ASTERISK
2B = U+002B : PLUS SIGN
2C = U+002C : COMMA
2D = U+002D : HYPHEN-MINUS
2E = U+002E : FULL STOP
2F = U+002F : SOLIDUS
30 = U+0030 : DIGIT ZERO
31 = U+0031 : DIGIT ONE
32 = U+0032 : DIGIT TWO
33 = U+0033 : DIGIT THREE
34 = U+0034 : DIGIT FOUR
35 = U+0035 : DIGIT FIVE
36 = U+0036 : DIGIT SIX
37 = U+0037 : DIGIT SEVEN
38 = U+0038 : DIGIT EIGHT
39 = U+0039 : DIGIT NINE
3A = U+003A : COLON
3B = U+003B : SEMICOLON
3C = U+003C : LESS-THAN SIGN
3D = U+003D : EQUALS SIGN
3E = U+003E : GREATER-THAN SIGN
3F = U+003F : QUESTION MARK
40 = U+0040 : COMMERCIAL AT
41 = U+0041 : LATIN CAPITAL LETTER A
42 = U+0042 : LATIN CAPITAL LETTER B
43 = U+0043 : LATIN CAPITAL LETTER C
44 = U+0044 : LATIN CAPITAL LETTER D
45 = U+0045 : LATIN CAPITAL LETTER E
46 = U+0046 : LATIN CAPITAL LETTER F
47 = U+0047 : LATIN CAPITAL LETTER G
48 = U+0048 : LATIN CAPITAL LETTER H
49 = U+0049 : LATIN CAPITAL LETTER I
4A = U+004A : LATIN CAPITAL LETTER J
4B = U+004B : LATIN CAPITAL LETTER K
4C = U+004C : LATIN CAPITAL LETTER L
4D = U+004D : LATIN CAPITAL LETTER M
4E = U+004E : LATIN CAPITAL LETTER N
4F = U+004F : LATIN CAPITAL LETTER O
50 = U+0050 : LATIN CAPITAL LETTER P
51 = U+0051 : LATIN CAPITAL LETTER Q
52 = U+0052 : LATIN CAPITAL LETTER R
53 = U+0053 : LATIN CAPITAL LETTER S
54 = U+0054 : LATIN CAPITAL LETTER T
55 = U+0055 : LATIN CAPITAL LETTER U
56 = U+0056 : LATIN CAPITAL LETTER V
57 = U+0057 : LATIN CAPITAL LETTER W
58 = U+0058 : LATIN CAPITAL LETTER X
59 = U+0059 : LATIN CAPITAL LETTER Y
5A = U+005A : LATIN CAPITAL LETTER Z
5B = U+005B : LEFT SQUARE BRACKET
5C = U+005C : REVERSE SOLIDUS
5D = U+005D : RIGHT SQUARE BRACKET
5E = U+005E : CIRCUMFLEX ACCENT
5F = U+005F : LOW LINE
60 = U+0060 : GRAVE ACCENT
61 = U+0061 : LATIN SMALL LETTER A
62 = U+0062 : LATIN SMALL LETTER B
63 = U+0063 : LATIN SMALL LETTER C
64 = U+0064 : LATIN SMALL LETTER D
65 = U+0065 : LATIN SMALL LETTER E
66 = U+0066 : LATIN SMALL LETTER F
67 = U+0067 : LATIN SMALL LETTER G
68 = U+0068 : LATIN SMALL LETTER H
69 = U+0069 : LATIN SMALL LETTER I
6A = U+006A : LATIN SMALL LETTER J
6B = U+006B : LATIN SMALL LETTER K
6C = U+006C : LATIN SMALL LETTER L
6D = U+006D : LATIN SMALL LETTER M
6E = U+006E : LATIN SMALL LETTER N
6F = U+006F : LATIN SMALL LETTER O
70 = U+0070 : LATIN SMALL LETTER P
71 = U+0071 : LATIN SMALL LETTER Q
72 = U+0072 : LATIN SMALL LETTER R
73 = U+0073 : LATIN SMALL LETTER S
74 = U+0074 : LATIN SMALL LETTER T
75 = U+0075 : LATIN SMALL LETTER U
76 = U+0076 : LATIN SMALL LETTER V
77 = U+0077 : LATIN SMALL LETTER W
78 = U+0078 : LATIN SMALL LETTER X
79 = U+0079 : LATIN SMALL LETTER Y
7A = U+007A : LATIN SMALL LETTER Z
7B = U+007B : LEFT CURLY BRACKET
7C = U+007C : VERTICAL LINE
7D = U+007D : RIGHT CURLY BRACKET
7E = U+007E : TILDE
7F = U+007F : DELETE
80 = U+20AC : EURO SIGN
82 = U+201A : SINGLE LOW-9 QUOTATION MARK
83 = U+0192 : LATIN SMALL LETTER F WITH HOOK
84 = U+201E : DOUBLE LOW-9 QUOTATION MARK
85 = U+2026 : HORIZONTAL ELLIPSIS
86 = U+2020 : DAGGER
87 = U+2021 : DOUBLE DAGGER
88 = U+02C6 : MODIFIER LETTER CIRCUMFLEX ACCENT
89 = U+2030 : PER MILLE SIGN
8A = U+0160 : LATIN CAPITAL LETTER S WITH CARON
8B = U+2039 : SINGLE LEFT-POINTING ANGLE QUOTATION MARK
8C = U+0152 : LATIN CAPITAL LIGATURE OE
8E = U+017D : LATIN CAPITAL LETTER Z WITH CARON
91 = U+2018 : LEFT SINGLE QUOTATION MARK
92 = U+2019 : RIGHT SINGLE QUOTATION MARK
93 = U+201C : LEFT DOUBLE QUOTATION MARK
94 = U+201D : RIGHT DOUBLE QUOTATION MARK
95 = U+2022 : BULLET
96 = U+2013 : EN DASH
97 = U+2014 : EM DASH
98 = U+02DC : SMALL TILDE
99 = U+2122 : TRADE MARK SIGN
9A = U+0161 : LATIN SMALL LETTER S WITH CARON
9B = U+203A : SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
9C = U+0153 : LATIN SMALL LIGATURE OE
9E = U+017E : LATIN SMALL LETTER Z WITH CARON
9F = U+0178 : LATIN CAPITAL LETTER Y WITH DIAERESIS
A0 = U+00A0 : NO-BREAK SPACE
A1 = U+00A1 : INVERTED EXCLAMATION MARK
A2 = U+00A2 : CENT SIGN
A3 = U+00A3 : POUND SIGN
A4 = U+00A4 : CURRENCY SIGN
A5 = U+00A5 : YEN SIGN
A6 = U+00A6 : BROKEN BAR
A7 = U+00A7 : SECTION SIGN
A8 = U+00A8 : DIAERESIS
A9 = U+00A9 : COPYRIGHT SIGN
AA = U+00AA : FEMININE ORDINAL INDICATOR
AB = U+00AB : LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
AC = U+00AC : NOT SIGN
AD = U+00AD : SOFT HYPHEN
AE = U+00AE : REGISTERED SIGN
AF = U+00AF : MACRON
B0 = U+00B0 : DEGREE SIGN
B1 = U+00B1 : PLUS-MINUS SIGN
B2 = U+00B2 : SUPERSCRIPT TWO
B3 = U+00B3 : SUPERSCRIPT THREE
B4 = U+00B4 : ACUTE ACCENT
B5 = U+00B5 : MICRO SIGN
B6 = U+00B6 : PILCROW SIGN
B7 = U+00B7 : MIDDLE DOT
B8 = U+00B8 : CEDILLA
B9 = U+00B9 : SUPERSCRIPT ONE
BA = U+00BA : MASCULINE ORDINAL INDICATOR
BB = U+00BB : RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
BC = U+00BC : VULGAR FRACTION ONE QUARTER
BD = U+00BD : VULGAR FRACTION ONE HALF
BE = U+00BE : VULGAR FRACTION THREE QUARTERS
BF = U+00BF : INVERTED QUESTION MARK
C0 = U+00C0 : LATIN CAPITAL LETTER A WITH GRAVE
C1 = U+00C1 : LATIN CAPITAL LETTER A WITH ACUTE
C2 = U+00C2 : LATIN CAPITAL LETTER A WITH CIRCUMFLEX
C3 = U+00C3 : LATIN CAPITAL LETTER A WITH TILDE
C4 = U+00C4 : LATIN CAPITAL LETTER A WITH DIAERESIS
C5 = U+00C5 : LATIN CAPITAL LETTER A WITH RING ABOVE
C6 = U+00C6 : LATIN CAPITAL LETTER AE
C7 = U+00C7 : LATIN CAPITAL LETTER C WITH CEDILLA
C8 = U+00C8 : LATIN CAPITAL LETTER E WITH GRAVE
C9 = U+00C9 : LATIN CAPITAL LETTER E WITH ACUTE
CA = U+00CA : LATIN CAPITAL LETTER E WITH CIRCUMFLEX
CB = U+00CB : LATIN CAPITAL LETTER E WITH DIAERESIS
CC = U+00CC : LATIN CAPITAL LETTER I WITH GRAVE
CD = U+00CD : LATIN CAPITAL LETTER I WITH ACUTE
CE = U+00CE : LATIN CAPITAL LETTER I WITH CIRCUMFLEX
CF = U+00CF : LATIN CAPITAL LETTER I WITH DIAERESIS
D0 = U+00D0 : LATIN CAPITAL LETTER ETH
D1 = U+00D1 : LATIN CAPITAL LETTER N WITH TILDE
D2 = U+00D2 : LATIN CAPITAL LETTER O WITH GRAVE
D3 = U+00D3 : LATIN CAPITAL LETTER O WITH ACUTE
D4 = U+00D4 : LATIN CAPITAL LETTER O WITH CIRCUMFLEX
D5 = U+00D5 : LATIN CAPITAL LETTER O WITH TILDE
D6 = U+00D6 : LATIN CAPITAL LETTER O WITH DIAERESIS
D7 = U+00D7 : MULTIPLICATION SIGN
D8 = U+00D8 : LATIN CAPITAL LETTER O WITH STROKE
D9 = U+00D9 : LATIN CAPITAL LETTER U WITH GRAVE
DA = U+00DA : LATIN CAPITAL LETTER U WITH ACUTE
DB = U+00DB : LATIN CAPITAL LETTER U WITH CIRCUMFLEX
DC = U+00DC : LATIN CAPITAL LETTER U WITH DIAERESIS
DD = U+00DD : LATIN CAPITAL LETTER Y WITH ACUTE
DE = U+00DE : LATIN CAPITAL LETTER THORN
DF = U+00DF : LATIN SMALL LETTER SHARP S
E0 = U+00E0 : LATIN SMALL LETTER A WITH GRAVE
E1 = U+00E1 : LATIN SMALL LETTER A WITH ACUTE
E2 = U+00E2 : LATIN SMALL LETTER A WITH CIRCUMFLEX
E3 = U+00E3 : LATIN SMALL LETTER A WITH TILDE
E4 = U+00E4 : LATIN SMALL LETTER A WITH DIAERESIS
E5 = U+00E5 : LATIN SMALL LETTER A WITH RING ABOVE
E6 = U+00E6 : LATIN SMALL LETTER AE
E7 = U+00E7 : LATIN SMALL LETTER C WITH CEDILLA
E8 = U+00E8 : LATIN SMALL LETTER E WITH GRAVE
E9 = U+00E9 : LATIN SMALL LETTER E WITH ACUTE
EA = U+00EA : LATIN SMALL LETTER E WITH CIRCUMFLEX
EB = U+00EB : LATIN SMALL LETTER E WITH DIAERESIS
EC = U+00EC : LATIN SMALL LETTER I WITH GRAVE
ED = U+00ED : LATIN SMALL LETTER I WITH ACUTE
EE = U+00EE : LATIN SMALL LETTER I WITH CIRCUMFLEX
EF = U+00EF : LATIN SMALL LETTER I WITH DIAERESIS
F0 = U+00F0 : LATIN SMALL LETTER ETH
F1 = U+00F1 : LATIN SMALL LETTER N WITH TILDE
F2 = U+00F2 : LATIN SMALL LETTER O WITH GRAVE
F3 = U+00F3 : LATIN SMALL LETTER O WITH ACUTE
F4 = U+00F4 : LATIN SMALL LETTER O WITH CIRCUMFLEX
F5 = U+00F5 : LATIN SMALL LETTER O WITH TILDE
F6 = U+00F6 : LATIN SMALL LETTER O WITH DIAERESIS
F7 = U+00F7 : DIVISION SIGN
F8 = U+00F8 : LATIN SMALL LETTER O WITH STROKE
F9 = U+00F9 : LATIN SMALL LETTER U WITH GRAVE
FA = U+00FA : LATIN SMALL LETTER U WITH ACUTE
FB = U+00FB : LATIN SMALL LETTER U WITH CIRCUMFLEX
FC = U+00FC : LATIN SMALL LETTER U WITH DIAERESIS
FD = U+00FD : LATIN SMALL LETTER Y WITH ACUTE
FE = U+00FE : LATIN SMALL LETTER THORN
FF = U+00FF : LATIN SMALL LETTER Y WITH DIAERESIS
*
*/
}
?>

View file

@ -1,22 +0,0 @@
<?php
abstract class ContentProvider{
/**
* Get the text data to be integrated in the MOBI file
* @return string
*/
public abstract function getTextData();
/**
* Get the images (an array containing the jpeg data). Array entry 0 will
* correspond to image record 0.
* @return array
*/
public abstract function getImages();
/**
* Get the metadata in the form of a hashtable (for example, title or author).
* @return array
*/
public abstract function getMetaData();
}
?>

View file

@ -1,132 +0,0 @@
<?php
//Reference: http://wiki.mobileread.com/wiki/MOBI
class EXTHHelper{
static function typeToText($type){
$types = self::$types;
if(isset($types[$type])){
return $types[$type];
}
return $type;
}
static function textToType($text){
$text = strtolower($text);
if(isset(self::$flippedTypes[$text])){
return self::$flippedTypes[$text];
}
return false;
}
static function convert($n, $size){
$mask = 0xFF;
$out = "";
for($i = 0; $i < $size; $i++){
$out = chr(($n & $mask) >> (8*$i)).$out;
$mask = $mask << 8;
}
return $out;
}
static function getRightRepresentation($type, $value){
if($type >= 100 && $type < 200){
return $value;
}else{
return self::toHex($value);
}
}
static function toHex($value){
$out = "";
for($i = 0, $len = strlen($value); $i < $len; $i++){
if($i > 0) $out .= " ";
$hex = dechex(ord($value[$i]));
if(strlen($hex) < 2) $hex = "0".$hex;
$out .= $hex;
}
return $out;
}
static private $types = array(
1 => "drm server id",
2 => "drm commerce id",
3 => "drm ebookbase book id",
100 => "author",
101 => "publisher",
102 => "imprint",
103 => "description",
104 => "isbn",
105 => "subject",
106 => "publishingdate",
107 => "review",
108 => "contributor",
109 => "rights",
110 => "subjectcode",
111 => "type",
112 => "source",
113 => "asin",
114 => "versionnumber",
115 => "sample",
116 => "startreading",
118 => "retail price",
119 => "retail price currency",
201 => "coveroffset",
202 => "thumboffset",
203 => "hasfakecover",
204 => "Creator Software",
205 => "Creator Major Version",
206 => "Creator Minor Version",
207 => "Creator Build Number",
208 => "watermark",
209 => "tamper proof keys",
300 => "fontsignature",
401 => "clippinglimit",
402 => "publisherlimit",
403 => "403",
404 => "ttsflag",
501 => "cdetype",
502 => "lastupdatetime",
503 => "updatedtitle"
);
static private $flippedTypes = array(
"drm server id" => 1,
"drm commerce id" => 2,
"drm ebookbase book id" => 3,
"author" => 100,
"publisher" => 101,
"imprint" => 102,
"description" => 103,
"isbn" => 104,
"subject" => 105,
"publishingdate" => 106,
"review" => 107,
"contributor" => 108,
"rights" => 109,
"subjectcode" => 110,
"type" => 111,
"source" => 112,
"asin" => 113,
"versionnumber" => 114,
"sample" => 115,
"startreading" => 116,
"retail price" => 118,
"retail price currency" => 119,
"coveroffset" => 201,
"thumboffset" => 202,
"hasfakecover" => 203,
"Creator Software" => 204,
"Creator Major Version" => 205,
"Creator Minor Version" => 206,
"Creator Build Number" => 207,
"watermark" => 208,
"tamper proof keys" => 209,
"fontsignature" => 300,
"clippinglimit" => 401,
"publisherlimit" => 402,
"403" => 403,
"ttsflag" => 404,
"cdetype" => 501,
"lastupdatetime" => 502,
"updatedtitle" => 503
);
}

View file

@ -1,41 +0,0 @@
<?php
/**
* Description of FileByte
*
* @author Sander
*/
class FileByte extends FileObject {
private $data;
/**
* Make a short to be stored in a file
* @param short $n
*/
public function __construct($n = 0){
parent::__construct(1);
$this->set($n);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = intval($value) & 0xFF;
}
public function serialize() {
return $this->byteToString($this->data);
}
public function unserialize($data) {
__construct($this->toInt($data));
}
public function __toString(){
return "FileByte: {".$this->byteAsString($this->data)."}";
}
}
?>

View file

@ -1,40 +0,0 @@
<?php
/**
* Description of FileDate
*
* @author Sander
*/
class FileDate extends FileObject {
private $data;
/**
* Make an integer to be stored in a file
* @param int $n
*/
public function __construct($n = 0){
parent::__construct(4);
$this->set($n);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = intval($value);
}
public function serialize() {
return $this->intToString($this->data);
}
public function unserialize($data) {
__construct($this->toInt($data));
}
public function __toString(){
return "FileDate: {".(date("r", $this->data-94694400))."}";
}
}
?>

View file

@ -1,89 +0,0 @@
<?php
/**
* Description of FileElement
*
* @author Sander
*/
class FileElement {
/**
* @var FileObject
*/
public $elements;
/**
* Make a record to be stored in a file
* @param Record $record
*/
public function __construct($elements = array()){
$this->elements = $elements;
}
public function getByteLength(){
return $this->getLength();
}
public function getLength(){
$total = 0;
foreach($this->elements as $val){
$total += $val->getByteLength();
}
return $total;
}
public function offsetToEntry($name){
$pos = 0;
foreach($this->elements as $key=>$value){
if($name == $key){
break;
}
$pos += $value->getByteLength();
}
return $pos;
}
public function exists($key){
return isset($this->elements[$key]);
}
/**
* @param string $key
* @return FileObject
*/
public function get($key){
return $this->elements[$key];
}
/**
* @param string $key
* @param FileObject $value
*/
public function set($key, $value){
$this->elements[$key] = $value;
}
public function add($key, $value){
$this->elements[$key] = $value;
}
public function serialize() {
$result = "";
foreach($this->elements as $val){
$result .= $val->serialize();
}
return $result;
}
public function unserialize($data) {
//TODO: If reading is needed -> way more complex
}
public function __toString(){
$output = "FileElement (".$this->getByteLength()." bytes): {\n";
foreach($this->elements as $key=>$value){
$output .= "\t".$key.": ".$value."\n";
}
$output .= "}";
return $output;
}
}
?>

View file

@ -1,40 +0,0 @@
<?php
/**
* Description of FileInt
*
* @author Sander
*/
class FileInt extends FileObject {
private $data;
/**
* Make an integer to be stored in a file
* @param int $n
*/
public function __construct($n = 0){
parent::__construct(4);
$this->set($n);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = intval($value);
}
public function serialize() {
return $this->intToString($this->data);
}
public function unserialize($data) {
__construct($this->toInt($data));
}
public function __toString(){
return "FileInt: {".$this->intAsString($this->data)."}";
}
}
?>

View file

@ -1,168 +0,0 @@
<?php
/**
* Description of FileObject
*
* @author Sander
*/
abstract class FileObject {
private $byteLength = -1;
public function __construct($byteLength = -1){
$this->byteLength = $byteLength;
}
public function getByteLength(){
if($this->byteLength >= 0){
return $this->byteLength;
}
return $this->getLength();
}
public function getLength(){
throw new Exception("Sub-class needs to implement this if it doesn't have a fixed length");
}
/**
* Convert a string to byte format (maximum 4 bytes)
* @param string $string Input string
* @return int Output integer
*/
public function toInt($string){
$out = 0;
for($i = 0, $len = min(4, strlen($string)); $i < $len; $i++){
$out = $out | (ord($string[$i]) << (($len-$i-1)*8));
}
return $out;
}
/**
* Convert a byte (stored in an integer) to a string
* @param byte $int
* @return string
*/
public function byteToString($int){
return $this->toString($int, 1);
}
/**
* Convert a byte (stored in an integer) to a string
* @param byte $int
* @return string
*/
public function byteAsString($int){
return $this->asString($int, 1);
}
/**
* Convert a short (stored in an integer) to a string
* @param short $int
* @return string
*/
public function shortToString($int){
return $this->toString($int, 2);
}
/**
* Convert a short (stored in an integer) to a string
* @param short $int
* @return string
*/
public function shortAsString($int){
return $this->asString($int, 2);
}
/**
* Convert a tri-byte (stored in an integer) to a string
* @param tri-byte $int
* @return string
*/
public function triToString($int){
return $this->toString($int, 3);
}
/**
* Convert a tri-byte (stored in an integer) to a string
* @param tri-byte $int
* @return string
*/
public function triAsString($int){
return $this->asString($int, 3);
}
/**
* Convert an integer to a string
* @param int $int
* @return string
*/
public function intToString($int){
return $this->toString($int, 4);
}
/**
* Convert an integer to a string
* @param int $int
* @return string
*/
public function intAsString($int){
return $this->asString($int, 4);
}
/**
* Convert a number of n bytes to a string
* @param int $int Number that should be converted
* @param int $size Number of bytes to convert
* @return string Output string
*/
private function toString($int, $size){
$out = "";
for($i = 0; $i < $size; $i++){
$out = chr($int & 0xFF).$out;
$int = $int >> 8;
}
return $out;
}
/**
* Convert a number of n bytes to a string
* @param int $int Number that should be converted
* @param int $size Number of bytes to convert
* @return string Output string
*/
private function asString($int, $size){
$out = "";
for($i = 0; $i < $size; $i++){
if($i > 0) $out = " ".$out;
$byte = dechex($int & 0xFF);
if(strlen($byte) == 1) $byte = "0".$byte;
$out = $byte.$out;
$int = $int >> 8;
}
return $out;
}
/**
* Get the value
* @return mixed Value to get
*/
abstract public function get();
/**
* Set the value
* @return mixed Value to set
*/
abstract public function set($value);
/**
* Serialize the object
* @return string String representation
*/
abstract public function serialize();
/**
* Unserialize the object
* @param string $data String representation
*/
abstract public function unserialize($data);
}
?>

View file

@ -1,46 +0,0 @@
<?php
/**
* Description of FileRecord
*
* @author Sander
*/
class FileRecord extends FileObject {
/**
* @var Record
*/
private $record;
/**
* Make a record to be stored in a file
* @param Record $record
*/
public function __construct($record){
$this->record = $record;
}
public function getByteLength(){
return $this->getLength();
}
public function getLength(){
return $this->record->getLength();
}
public function get(){
return $this->record;
}
public function set($record){
$this->record = $record;
}
public function serialize() {
return $this->record->serialize();
}
public function unserialize($data) {
__construct($this->record->unserialize($data));
}
}
?>

View file

@ -1,41 +0,0 @@
<?php
/**
* Description of FileShort
*
* @author Sander
*/
class FileShort extends FileObject {
private $data;
/**
* Make a short to be stored in a file
* @param short $n
*/
public function __construct($n = 0){
parent::__construct(2);
$this->set($n);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = intval($value) & 0xFFFF;
}
public function serialize() {
return $this->shortToString($this->data);
}
public function unserialize($data) {
__construct($this->toInt($data));
}
public function __toString(){
return "FileShort: {".$this->shortAsString($this->data)."}";
}
}
?>

View file

@ -1,83 +0,0 @@
<?php
/**
* Description of FileString
*
* @author Sander
*/
class FileString extends FileObject {
private $forcedLength;
private $data;
/**
* Make a string to be stored in a file
* @param string|int $first Optional, if it is a string, it will be the contents,
* if it is a number, it will set the forced length.
* @param int $second Optional, will set the forced length. Can only be used when the
* first argument is contents.
*/
public function __construct($first = null, $second = null){
$this->forcedLength = -1;
$this->data = "";
if($second != null){
$this->data = $first;
$this->forcedLength = $second;
}else if($first != null){
if(is_string($first)){
$this->data = $first;
}else{
$this->forcedLength = $first;
}
}
}
public function getByteLength(){
return $this->getLength();
}
public function getLength(){
if($this->forcedLength >= 0){
return $this->forcedLength;
}
return strlen($this->data);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = $value;
}
public function serialize() {
$output = $this->data;
$curLength = strlen($output);
if($this->forcedLength >= 0){
if($this->forcedLength > $curLength){
return str_pad($output, $this->forcedLength, "\0", STR_PAD_RIGHT);
}elseif($this->forcedLength == $curLength){
return $output;
}else{
return substr($output, 0, $this->forcedLength);
}
}
return $output;
}
public function unserialize($data) {
__construct($data);
}
public function __toString(){
$out = "FileString";
if($this->forcedLength >= 0){
$out .= " ".$this->forcedLength;
}
$out .= ": {\"".str_replace(array(" ", "\0"), "&nbsp;", $this->serialize())."\"}";
return $out;
}
}
?>

View file

@ -1,41 +0,0 @@
<?php
/**
* Description of FileTri
*
* @author Sander
*/
class FileTri extends FileObject {
private $data;
/**
* Make a tri-byte to be stored in a file
* @param tri-byte $n
*/
public function __construct($n = 0){
parent::__construct(3);
$this->set($n);
}
public function get(){
return $this->data;
}
public function set($value){
$this->data = intval($value) & 0xFFFFFF;
}
public function serialize() {
return $this->triToString($this->data);
}
public function unserialize($data) {
__construct($this->toInt($data));
}
public function __toString(){
return "FileTri: {".$this->triAsString($this->data)."}";
}
}
?>

View file

@ -1,171 +0,0 @@
<?php
class Http{
private static $cache = false;
public static function Request($url){
$url_parts = parse_url($url);
$url_parts["port"] = isset($url_parts["port"]) ? $url_parts["port"] : 80;
$url_parts["path"] = isset($url_parts["path"]) ? $url_parts["path"] : "/";
return self::FullRequest("GET", $url_parts["host"], $url_parts["port"], $url_parts["path"]);
}
public static function FullRequest(
$verb = 'GET', /* HTTP Request Method (GET and POST supported) */
$ip, /* Target IP/Hostname */
$port = 80, /* Target TCP port */
$uri = '/', /* Target URI */
$getdata = array(), /* HTTP GET Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$postdata = array(), /* HTTP POST Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$cookie = array(), /* HTTP Cookie Data ie. array('var1' => 'val1', 'var2' => 'val2') */
$custom_headers = array(), /* Custom HTTP headers ie. array('Referer: http://localhost/ */
$timeout = 1000, /* Socket timeout in milliseconds */
$req_hdr = false, /* Include HTTP request headers */
$res_hdr = false, /* Include HTTP response headers */
$depth = 4 /* Depth of the iteration left (to avoid redirection loops) */
)
{
if(self::$cache){
$cacheFile = "cache/".$ip."/".str_replace("/", "...", $uri);
if(is_file($cacheFile)){
$data = file_get_contents($cacheFile);
return self::resolveTruncated($data);
}
}
$ret = '';
$verb = strtoupper($verb);
$cookie_str = '';
$getdata_str = count($getdata) ? '?' : '';
$postdata_str = '';
foreach ($getdata as $k => $v)
$getdata_str .= urlencode($k) .'='. urlencode($v);
foreach ($postdata as $k => $v)
$postdata_str .= urlencode($k) .'='. urlencode($v) .'&';
foreach ($cookie as $k => $v)
$cookie_str .= urlencode($k) .'='. urlencode($v) .'; ';
$crlf = "\r\n";
$req = $verb .' '. $uri . $getdata_str .' HTTP/1.1' . $crlf;
$req .= 'Host: '. $ip . $crlf;
$req .= 'User-Agent: Mozilla/5.0 Firefox/3.6.12' . $crlf;
$req .= 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' . $crlf;
$req .= 'Accept-Language: en-us,en;q=0.5' . $crlf;
$req .= 'Accept-Encoding: deflate' . $crlf;
$req .= 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7' . $crlf;
foreach ($custom_headers as $k => $v)
$req .= $k .': '. $v . $crlf;
if (!empty($cookie_str))
$req .= 'Cookie: '. substr($cookie_str, 0, -2) . $crlf;
if ($verb == 'POST' && !empty($postdata_str))
{
$postdata_str = substr($postdata_str, 0, -1);
$req .= 'Content-Type: application/x-www-form-urlencoded' . $crlf;
$req .= 'Content-Length: '. strlen($postdata_str) . $crlf . $crlf;
$req .= $postdata_str;
}
else $req .= $crlf;
if ($req_hdr)
$ret .= $req;
if (($fp = @fsockopen($ip, $port, $errno, $errstr)) == false)
return "Error $errno: $errstr\n";
stream_set_timeout($fp, 0, $timeout * 1000);
fputs($fp, $req);
$ret .= stream_get_contents($fp);
fclose($fp);
$headerSplit = strpos($ret, "\r\n\r\n");
$header = substr($ret, 0, $headerSplit);
$redirectURL = self::CheckForRedirect($header);
if($redirectURL !== false){
if($depth > 0){
$url_parts = parse_url($redirectURL);
$url_parts["port"] = isset($url_parts["port"]) ? $url_parts["port"] : 80;
$url_parts["path"] = isset($url_parts["path"]) ? $url_parts["path"] : "/";
return self::FullRequest($verb, $url_parts["host"], $url_parts["port"], $url_parts["path"], $getdata, $postdata, $cookie, $custom_headers, $timeout, $req_hdr, $res_hdr, $depth-1);
}else{
return "Redirect loop, stopping...";
}
}
$truncated = false;
$headerLines = explode("\r\n", $header);
foreach($headerLines as $line){
list($name, $value) = explode(":", $line);
$name = trim($name);
$value = trim($value);
if(strtolower($name) == "transfer-encoding" && strtolower($value) == "chunked"){ //TODO: Put right values!
$truncated = true;
}
}
if (!$res_hdr)
$ret = substr($ret, $headerSplit + 4);
if($truncated){
$ret = self::resolveTruncated($ret);
}
if(self::$cache){
if(!is_dir("cache")){
mkdir("cache");
}
if(!is_dir("cache/".$ip)){
mkdir("cache/".$ip);
}
if(!is_file("cache/".$ip."/".str_replace("/", "...", $uri))){
$h = fopen("cache/".$ip."/".str_replace("/", "...", $uri), "w");
fwrite($h, $ret);
fclose($h);
}
}
return $ret;
}
private static function resolveTruncated($data){
$pos = 0;
$end = strlen($data);
$out = "";
while($pos < $end){
$endVal = strpos($data, "\r\n", $pos);
$value = hexdec(substr($data, $pos, $endVal-$pos));
$out .= substr($data, $endVal+2, $value);
$pos = $endVal+2+$value;
}
return $out;
}
private static function CheckForRedirect($header){
$firstLine = substr($header, 0, strpos($header, "\r\n"));
list($httpVersion, $statusCode, $message) = explode(" ", $firstLine);
if(substr($statusCode, 0, 1) == "3"){
$part = substr($header, strpos(strtolower($header), "location: ")+strlen("location: "));
$location = trim(substr($part, 0, strpos($part, "\r\n")));
if(strlen($location) > 0){
return $location;
}
}
return false;
}
}
?>

View file

@ -1,40 +0,0 @@
<?php
class ImageHandler {
/**
* Download an image
* @param string $url Url to the image
* @return false|string False if failed, else the data of the image (converted to grayscale jpeg)
*/
public static function DownloadImage($url){
$data = Http::Request($url);
$imgFile = @imagecreatefromstring($data);
if($imgFile !== false){
$result = self::CreateImage($imgFile);
imagedestroy($imgFile);
return $result;
}
return false;
}
/**
* Create an image
* @param resource $img Create an image created with createimagetruecolor
* @return false|string False if failed, else the data of the image (converted to grayscale jpeg)
*/
public static function CreateImage($img){
try{
imagefilter($img, IMG_FILTER_GRAYSCALE);
ob_start();
imagejpeg($img);
$image = ob_get_contents();
ob_end_clean();
return $image;
}catch(Exception $e){
return false;
}
}
}
?>

View file

@ -1,192 +0,0 @@
<?php
require_once(dirname(__FILE__)."/../readability/Readability.php");
require_once(dirname(__FILE__).'/CharacterEntities.php');
require_once(dirname(__FILE__).'/constants.php');
require_once(dirname(__FILE__).'/ContentProvider.php');
require_once(dirname(__FILE__).'/MultipleFileHandler.php');
require_once(dirname(__FILE__)."/downloaders/FanFictionNet.php");
require_once(dirname(__FILE__).'/EXTHHelper.php');
require_once(dirname(__FILE__).'/FileObject.php');
require_once(dirname(__FILE__).'/FileByte.php');
require_once(dirname(__FILE__).'/FileDate.php');
require_once(dirname(__FILE__).'/FileElement.php');
require_once(dirname(__FILE__).'/FileInt.php');
require_once(dirname(__FILE__).'/FileRecord.php');
require_once(dirname(__FILE__).'/FileShort.php');
require_once(dirname(__FILE__).'/FileString.php');
require_once(dirname(__FILE__).'/FileTri.php');
require_once(dirname(__FILE__).'/Http.php');
require_once(dirname(__FILE__).'/http_build_url.php');
require_once(dirname(__FILE__).'/ImageHandler.php');
require_once(dirname(__FILE__).'/MOBIFile.php');
require_once(dirname(__FILE__).'/OnlineArticle.php');
require_once(dirname(__FILE__).'/PalmRecord.php');
require_once(dirname(__FILE__).'/Prc.php');
require_once(dirname(__FILE__).'/PreprocessedArticle.php');
require_once(dirname(__FILE__).'/RecognizeURL.php');
require_once(dirname(__FILE__).'/Record.php');
require_once(dirname(__FILE__).'/RecordFactory.php');
require_once(dirname(__FILE__).'/Settings.php');
/**
* Description of MOBI.
*
* Usage:
* include("MOBIClass/MOBI.php");
*
* $mobi = new MOBI();
*
* //Then use one of the following ways to prepare information (it should be in the form of valid html)
* $mobi->setInternetSource($url); //Load URL, the result will be cleaned using a Readability port
* $mobi->setFileSource($file); //Load a local file without any extra changes
* $mobi->setData($data); //Load data
*
* //If you want, you can set some optional settings (see Settings.php for all recognized settings)
* $options = array(
* "title"=>"Insert title here",
* "author"=>"Author"
* );
* $mobi->setOptions($options);
*
* //Then there are two ways to output it:
* $mobi->save($file); //Save the file locally
* $mobi->download($name); //Let the client download the file, make sure the page
* //that calls it doesn't output anything, otherwise it might
* //conflict with the download. $name contains the file name,
* //usually something like "title.mobi" (where the title should
* //be cleaned so as not to contain illegal characters).
*
*
* @author Sander Kromwijk
*/
class MOBI {
private $source = false;
private $images = array();
private $optional = array();
private $imgCounter = 0;
private $debug = false;
private $prc = false;
public function __construct(){
}
public function getTitle(){
if(isset($this->optional["title"])){
return $this->optional["title"];
}
return false;
}
/**
* Set a content provider as source
* @param ContentProvider $content Content Provider to use
*/
public function setContentProvider($content){
$this->setOptions($content->getMetaData());
$this->setImages($content->getImages());
$this->setData($content->getTextData());
}
/**
* Set a local file as source
* @param string $file Path to the file
*/
public function setFileSource($file){
$this->setData(file_get_contents($file));
}
/**
* Set the data to use
* @param string $data Data to put in the file
*/
public function setData($data){
//$data = utf8_encode($data);
$data = CharacterEntities::convert($data);
//$data = utf8_decode($data);
//$this->source = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $data);
$this->source = $data;
$this->prc = false;
}
/**
* Set the images to use
* @param array $data Data to put in the file
*/
public function setImages($data){
$this->images = $data;
$this->prc = false;
}
/**
* Set options, usually for things like titles, authors, etc...
* @param array $options Options to set
*/
public function setOptions($options){
$this->optional = $options;
$this->prc = false;
}
/**
* Prepare the prc file
* @return Prc The file that can be used to be saved/downloaded
*/
private function preparePRC(){
if($this->source === false){
throw new Exception("No data set");
}
if($this->prc !== false) return $this->prc;
$data = $this->source;
$len = strlen($data);
$settings = new Settings($this->optional);
$rec = new RecordFactory($settings);
$dataRecords = $rec->createRecords($data);
$nRecords = sizeof($dataRecords);
$mobiHeader = new PalmRecord($settings, $dataRecords, $nRecords, $len, sizeof($this->images));
array_unshift($dataRecords, $mobiHeader);
$dataRecords = array_merge($dataRecords, $this->images);
$dataRecords[] = $rec->createFLISRecord();
$dataRecords[] = $rec->createFCISRecord($len);
$dataRecords[] = $rec->createEOFRecord();
$this->prc = new Prc($settings, $dataRecords);
return $this->prc;
}
/**
* Save the file locally
* @param string $filename Path to save the file
*/
public function save($filename){
$prc = $this->preparePRC();
$prc->save($filename);
}
/**
* Let the client download the file. Warning! No data should be
* outputted before or after.
* @param string $name Name used for download, usually "title.mobi"
*/
public function download($name){
$prc = $this->preparePRC();
$data = $prc->serialize();
$length = strlen($data);
if($this->debug) return; //In debug mode, don't start the download
header("Content-Type: application/x-mobipocket-ebook");
header("Content-Disposition: attachment; filename=\"".$name."\"");
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Content-Length: ".$length);
echo $data;
//Finished!
}
}
?>

View file

@ -1,157 +0,0 @@
<?php
/**
* This is the way MOBI files should be created if you want all features (TOC, images).
*
* File modified by Dawson for use in eBook Creator
* Added pagebreaks and a setting to remove table of contents.
*/
class MOBIFile extends ContentProvider {
const PARAGRAPH = 0;
const H2 = 1;
const H3 = 2;
const IMAGE = 3;
const PAGEBREAK = 4;
private $settings = array("title" => "Unknown Title", "toc" => true);
private $parts = array();
private $images = array();
/**
* Get the text data (the "html" code)
*/
public function getTextData(){
$prefix = "<html><head><guide><reference title='CONTENT' type='toc' filepos=0000000000 /></guide></head><body>";
$title = "<h1>".$this->settings["title"]."</h1>";
list($text, $entries) = $this->generateText();
if($this->settings["toc"]) {
$toc = $this->generateTOC($entries); //Generate TOC to get the right length
$toc = $this->generateTOC($entries, strlen($prefix)+strlen($toc)+strlen($title)); //Generate the real TOC
}
$suffix = "</body></html>";
return $prefix.$toc.$title.$text.$suffix;
}
/**
* Generate the body's text and the chapter entries
* @return array($string, $entries) $string is the html data, $entries
* contains the level, the title and the position of the titles.
*/
public function generateText(){
$str = "";
$entries = array();
for($i = 0; $i < sizeof($this->parts); $i++){
list($type, $data) = $this->parts[$i];
$id = "title_".$i;
switch($type){
case self::PARAGRAPH:
$str .= "<p>".$data."</p>";
break;
case self::PAGEBREAK:
$str .= '<mbp:pagebreak/>';
break;
case self::H2:
$entries[] = array("level" => 2, "position" => strlen($str), "title" => $data, "id" => $id);
$str .= "<h2 id='" . $id . "'>".$data."</h2>";
break;
case self::H3:
$entries[] = array("level" => 3, "position" => strlen($str), "title" => $data, "id" => $id);
$str .= "<h3 id='" . $id . "'>".$data."</h3>";
break;
case self::IMAGE:
$str .= "<img recindex=".str_pad($data+1, 10, "0", STR_PAD_LEFT)." />";
break;
}
}
return array($str, $entries);
}
/**
* Generate a TOC
* @param $entries The entries array generated by generateText
* @param $base The zero position
*/
public function generateTOC($entries, $base = 0){
$toc = "<h2>Contents</h2>";
$toc .= "<blockquote><table summary='Table of Contents'><col/><tbody>";
for($i = 0, $len = sizeof($entries); $i < $len; $i++){
$entry = $entries[$i];
$pos = str_pad($entry["position"]+$base, 10, "0", STR_PAD_LEFT);
$toc .= "<tr><td><a href='#".$entry["id"]."' filepos='".$pos."'>".$entry["title"]."</a></td></tr>";
}
return $toc."</tbody></b></table></blockquote><mbp:pagebreak/>";
}
/**
* Get the file records of the images
*/
public function getImages(){
return $this->images;
}
/**
* Get the metadata
*/
public function getMetaData(){
return $this->settings;
}
/**
* Change the file's settings. For example set("author", "John Doe") or set("title", "The adventures of John Doe").
* @param $key Key of the setting to insert.
*/
public function set($key, $value){
$this->settings[$key] = $value;
}
/**
* Get the file's settings.
*/
public function get($key){
return $this->settings[$key];
}
/**
* Append a paragraph of text to the file.
* @param string $text The text to insert.
*/
public function appendParagraph($text){
$this->parts[] = array(self::PARAGRAPH, $text);
}
/**
* Append a chapter title (H2)
* @param string $title The title to insert.
*/
public function appendChapterTitle($title){
$this->parts[] = array(self::H2, $title);
}
/**
* Append a section title (H3)
* @param string $title The title to insert.
*/
public function appendSectionTitle($title){
$this->parts[] = array(self::H3, $title);
}
public function appendPageBreak() {
$this->parts[] = array(self::PAGEBREAK, null);
}
/**
* Append an image.
* @param resource $img An image file (for example, created by `imagecreate`)
*/
public function appendImage($img){
$imgIndex = sizeof($this->images);
$this->images[] = new FileRecord(new Record(ImageHandler::CreateImage($img)));
$this->parts[] = array(self::IMAGE, $imgIndex);
}
}

View file

@ -1,136 +0,0 @@
<?php
/**
* Description of MultipleFileHandler
*
* @author Sander
*/
abstract class MultipleFileHandler extends ContentProvider {
/**
* @var array
*/
private $files = array();
/**
* @var array
*/
private $images = array();
/**
* @var array
*/
private $metadata = array();
private $toc = array();
/**
* Add a page to the file
* @param string $contents Contents of the chapter/page
* @param string $title Optional, title of the chapter/page. Will automatically add a h2
* before the contents
*/
public function addPage($contents, $title = ""){
if($title != ""){
//TODO: Add in TOC (and add a way of generating it
$contents = "<h2>".$title."</h2>".$contents."<mbp:pagebreak>";
}
$pos = 0;
if(sizeof($this->toc) > 0){
$lastToc = $this->toc[sizeof($this->toc)-1];
$lastFile = $this->files[sizeof($this->files)-1];
$pos = $lastToc["pos"] + strlen($lastFile) + 1;
}
$this->files[] = $contents;
$this->toc[] = array("title"=>$title, "pos"=>$pos);
}
/**
* Add an image to the file
* @param string $imageContents Data string containing the binary data of the image
* @return int The reference of the image
*/
public function addImage($imageContents){
$this->images[] = $imageContents;
return sizeof($this->images)-1;
}
/**
* Add an image to the file
* @param string $url Url to the image
* @return int The reference of the image, false if the image couldn't be downloaded
*/
public function addImageFromUrl($url){
$image = ImageHandler::DownloadImage($url);
if($image === false) return false;
return $this->addImage($image);
}
/**
* Set the metadata
* @param string $key Key
* @param string $value Value
*/
public function setMetadata($key, $value){
$this->metadata[$key] = $value;
}
/**
* Get the text data to be integrated in the MOBI file
* @return string
*/
public function getTextData(){
$data = implode("\n", $this->files);
$begin = "<html><head><guide><reference title='CONTENT' type='toc' filepos=0000000000 /></guide></head><body>";
$beforeTOC = $begin.$data;
$tocPos = strlen($beforeTOC);
$toc = $this->generateTOC(strlen($begin));
$customBegin = "<html><head><guide><reference title='CONTENT' type='toc' filepos=".$this->forceLength($tocPos, 10)." /></guide></head><body>";
$data = $customBegin.$data.$toc."</body></html>";
return $data;
}
public function forceLength($n, $l){
$str = $n."";
$cur = strlen($str);
while($cur < $l){
$str = "0".$str;
$cur++;
}
return $str;
}
public function generateTOC($base = 0){
$toc = "<h2>Contents</h2>";
$toc .= "<blockquote><table summary='Table of Contents'><b><col/><col/><tbody>";
for($i = 0, $len = sizeof($this->toc); $i < $len; $i++){
$entry = $this->toc[$i];
$position = $entry["pos"]+$base;
$toc .= "<tr><td>".($i+1).".</td><td><a filepos=".$position.">".$entry["title"]."</a></td></tr>";
}
$toc .= "</tbody></b></table></blockquote>";
return $toc;
}
/**
* Get the images (an array containing the jpeg data). Array entry 0 will
* correspond to image record 0.
* @return array
*/
public function getImages(){
return $this->images;
}
/**
* Get the metadata in the form of a hashtable (for example, title or author).
* @return array
*/
public function getMetaData(){
return $this->metadata;
}
}
?>

View file

@ -1,116 +0,0 @@
<?php
/**
* Description of OnlineArticle
*
* @author Sander
*/
class OnlineArticle extends ContentProvider {
private $text;
private $images;
private $metadata = array();
private $imgCounter = 0;
public function __construct($url) {
if (!preg_match('!^https?://!i', $url)) $url = 'http://'.$url;
$data = Http::Request($url);
//$enc = mb_detect_encoding($str, "UTF-8,ISO-8859-1,ASCII");
$html = mb_convert_encoding($data, "UTF-8", "UTF-8,ISO-8859-1,ASCII");
//$html = utf8_encode($html);
$r = new Readability($html, $url);
$r->init();
if(!isset($this->metadata["title"])){
$this->metadata["title"] = CharacterEntities::convert(strip_tags($r->getTitle()->innerHTML));
}
if(!isset($this->metadata["author"])){
$parts = parse_url($url);
$this->metadata["author"] = $parts["host"];
}
$article = $r->getContent()->innerHTML;
if(substr($article, 0, 5) == "<body"){
$article = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head>".$article."</html>";
}else{
$article = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body>".$article."</body></html>";
}
$doc = new DOMDocument();
@$doc->loadHTML($article) or die($article);
$doc->normalizeDocument();
$this->images = $this->handleImages($doc, $url);
$this->text = $doc->saveHTML();
}
/**
* Get the text data to be integrated in the MOBI file
* @return string
*/
public function getTextData(){
return $this->text;
}
/**
* Get the images (an array containing the jpeg data). Array entry 0 will
* correspond to image record 0.
* @return array
*/
public function getImages(){
return $this->images;
}
/**
* Get the metadata in the form of a hashtable (for example, title or author).
* @return array
*/
public function getMetaData(){
return $this->metadata;
}
/**
*
* @param DOMElement $dom
* @return array
*/
private function handleImages($dom, $url){
$images = array();
$parts = parse_url($url);
$savedImages = array();
$imgElements = $dom->getElementsByTagName('img');
foreach($imgElements as $img) {
$src = $img->getAttribute("src");
$is_root = false;
if(substr($src, 0, 1) == "/"){
$is_root = true;
}
$parsed = parse_url($src);
if(!isset($parsed["host"])){
if($is_root){
$src = http_build_url($url, $parsed, HTTP_URL_REPLACE);
}else{
$src = http_build_url($url, $parsed, HTTP_URL_JOIN_PATH);
}
}
$img->setAttribute("src", "");
if(isset($savedImages[$src])){
$img->setAttribute("recindex", $savedImages[$src]);
}else{
$image = ImageHandler::DownloadImage($src);
if($image !== false){
$images[$this->imgCounter] = new FileRecord(new Record($image));
$img->setAttribute("recindex", $this->imgCounter);
$savedImages[$src] = $this->imgCounter;
$this->imgCounter++;
}
}
}
return $images;
}
}
?>

View file

@ -1,136 +0,0 @@
<?php
/**
* A Record of a PDB file
*
* @author Sander
*/
class PalmRecord extends FileObject {
/**
* @var FileElement
*/
private $elements;
public function __construct($settings, $records, $textRecords, $textLength, $images){
$this->elements = new FileElement(array(
"compression"=>new FileShort(),
"unused"=>new FileShort(),
"textLength"=>new FileInt(),
"recordCount"=>new FileShort(),
"recordSize"=>new FileShort(),
"encryptionType"=>new FileShort(),
"unused2"=>new FileShort(),
//MOBI Header
"mobiIdentifier"=>new FileString("MOBI", 4),
"mobiHeaderLength"=>new FileInt(),
"mobiType"=>new FileInt(),
"textEncoding"=>new FileInt(),
"uniqueID"=>new FileInt(),
"fileVersion"=>new FileInt(),
"reserved"=>new FileString(40),
"firstNonBookIndex"=>new FileInt(),
"fullNameOffset"=>new FileInt(),
"fullNameLength"=>new FileInt(),
"locale"=>new FileInt(),
"inputLanguage"=>new FileInt(),
"outputLanguage"=>new FileInt(),
"minimumVersion"=>new FileInt(),
"firstImageIndex"=>new FileInt(),
"huffmanRecordOffset"=>new FileInt(),
"huffmanRecordCount"=>new FileInt(),
"unused3"=>new FileString(8),
"exthFlags"=>new FileInt(0x40),
"unknown"=>new FileString(32),
"drmOffset"=>new FileInt(0xFFFFFFFF),
"drmCount"=>new FileShort(0xFFFFFFFF),
"drmSize"=>new FileShort(),
"drmFlags"=>new FileInt(),
"mobiFiller"=>new FileString(72),
//EXTH Header
"exthIdentifier"=>new FileString("EXTH", 4),
"exthHeaderLength"=>new FileInt(),
"exthRecordCount"=>new FileInt(),
"exthRecords"=>new FileElement(),
"exthPadding"=>new FileString(),
//"fullNamePadding"=>new FileString(100),
"fullName"=>new FileString()
));
//Set values from the info block
foreach($settings->values as $name => $val){
//echo $name.", ";
if($this->elements->exists($name)){
$this->elements->get($name)->set($settings->get($name));
}
}
$els = $settings->values;
$exthElems = new FileElement();
$i = 0;
$l = 0;
foreach($els as $name=>$val){
$type = EXTHHelper::textToType($name);
if($type !== false){
$type = new FileInt($type);
$length = new FileInt(8+strlen($val));
$data = new FileString($val);
$l += 8+strlen($val);
$exthElems->add("type".$i, $type);
$exthElems->add("length".$i, $length);
$exthElems->add("data".$i, $data);
$i++;
}
}
if($images > 0){
$this->elements->get("firstImageIndex")->set($textRecords+1);
}
$this->elements->get("firstNonBookIndex")->set($textRecords+2+$images);
$this->elements->get("reserved")->set(str_pad("", 40, chr(255), STR_PAD_RIGHT));
$this->elements->get("exthRecordCount")->set($i);
$this->elements->set("exthRecords", $exthElems);
$pad = $l%4;
$pad = (4-$pad)%4;
$this->elements->get("exthPadding")->set(str_pad("", $pad, "\0", STR_PAD_RIGHT));
$this->elements->get("exthHeaderLength")->set(12+$l+$pad);
$this->elements->get("recordCount")->set($textRecords);
$this->elements->get("fullNameOffset")->set($this->elements->offsetToEntry("fullName"));
$this->elements->get("fullNameLength")->set(strlen($settings->get("title")));
$this->elements->get("fullName")->set($settings->get("title"));
$this->elements->get("textLength")->set($textLength);
}
public function getByteLength(){
return $this->getLength();
}
public function getLength(){
return $this->elements->getByteLength();
}
public function get(){
return $this;
}
public function set($elements){
throw new Exception("Unallowed set");
}
public function serialize() {
return $this->elements->serialize();
}
public function unserialize($data) {
$this->elements->unserialize($data);
}
public function __toString(){
$output = "PalmDoc Record (".$this->getByteLength()." bytes):\n";
$output .= $this->elements;
return $output;
}
}
?>

View file

@ -1,97 +0,0 @@
<?php
/**
* Description of Prc
*
* @author Sander
*/
class Prc extends FileElement {
public function __construct($settings, $records){
parent::__construct(array(
"title"=>new FileString(32),
"attributes"=>new FileShort(),
"version"=>new FileShort(),
"creationTime"=>new FileDate(),
"modificationTime"=>new FileDate(),
"backupTime"=>new FileDate(),
"modificationNumber"=>new FileInt(),
"appInfoID"=>new FileInt(),
"sortInfoID"=>new FileInt(),
"prcType"=>new FileString(4),
"creator"=>new FileString(4),
"uniqueIDSeed"=>new FileInt(),
"nextRecordListID"=>new FileInt(),
"numberRecords"=>new FileShort(),
"recordList"=>new FileElement(),
"filler"=>new FileShort(),
"records"=>new FileElement()
));
//Set values from the info block
foreach($this->elements as $name => $val){
if($settings->exists($name)){
$this->get($name)->set($settings->get($name));
}
}
$this->get("numberRecords")->set(sizeof($records));
$i = 0;
foreach($records as $record){
$offset = new FileInt();
$attr = new FileByte();
$uniqueID = new FileTri($i);
$this->elements["recordList"]->add("Rec".$i, new FileElement(array(
"offset"=>$offset,
"attribute"=>$attr,
"uniqueID"=>$uniqueID
)));
$this->elements["records"]->add("Rec".$i, $record);
$i++;
}
$this->updateOffsets($records);
}
public function getByteLength(){
throw new Exception("Test");
}
public function updateOffsets($records){
$base = $this->offsetToEntry("records");
$i = 0;
foreach($records as $record){
$el = $this->elements["recordList"]->get("Rec".$i);
$local = $this->elements["records"]->offsetToEntry("Rec".$i);
$el->get("offset")->set($base+$local);
$i++;
}
}
public function save($file){
$handle = fopen($file, "w");
fwrite($handle, $this->serialize());
fclose($handle);
}
public function output(){
echo $this->serialize();
}
public function __toString(){
$output = "Prc (".$this->getByteLength()." bytes): {\n";
foreach($this->elements as $key=>$value){
$output .= "\t".$key.": ".$value."\n";
}
$output .= "}";
return $output;
}
}
?>

View file

@ -1,89 +0,0 @@
<?php
/**
* Description of OnlineArticle
*
* @author Sander
*/
class PreprocessedArticle extends ContentProvider {
private $text;
private $images;
private $metadata = array();
private $imgCounter = 0;
public function __construct($textData, $imageLinks, $metadata) {
$this->text = $textData;
$this->metadata = $metadata;
$this->images = $this->downloadImages($imageLinks);
}
/**
* Create a Preprocessed article from a json string
* @param string $json JSON data. Should be of the following format:
* {"text": "TEXT", "images: ["imageURL1", "imageURL2"], "metadata": {"key": "value"}}
*
* Note: Any image tags should have the recindex attribute set to the appropriate index (the
* same index as the image in the array)
* @return PreprocessedArticle The generated preprocessed array
*/
static public function CreateFromJson($json){
$data = json_decode($json);
return new PreprocessedArticle($data["text"], $data["images"], $data["metadata"]);
}
/**
* Get the text data to be integrated in the MOBI file
* @return string
*/
public function getTextData(){
return $this->text;
}
/**
* Get the images (an array containing the jpeg data). Array entry 0 will
* correspond to image record 0.
* @return array
*/
public function getImages(){
return $this->images;
}
/**
* Get the metadata in the form of a hashtable (for example, title or author).
* @return array
*/
public function getMetaData(){
return $this->metadata;
}
/**
*
* @param DOMElement $dom
* @return array
*/
private function downloadImages($links){
$images = array();
foreach($links as $link) {
$imgFile = @imagecreatefromstring(Http::Request($link));
if($imgFile === false){
$imgFile = @imagecreate(1, 1);
$black = @imagecolorallocate($imgFile, 255, 255, 255);
}
if($imgFile !== false){
@imagefilter($imgFile, IMG_FILTER_GRAYSCALE);
ob_start();
@imagejpeg($imgFile);
$image = ob_get_contents();
ob_end_clean();
$images[$this->imgCounter] = new FileRecord(new Record($image));
imagedestroy($imgFile);
$this->imgCounter++;
}
}
return $images;
}
}
?>

View file

@ -1,16 +0,0 @@
<?php
/**
* Description of RecognizeURL
*
* @author Sander
*/
class RecognizeURL {
public static function GetContentHandler($url){
if(FanFictionNet::Matches($url)){
return new FanFictionNet($url);
}
return null;
}
}
?>

View file

@ -1,96 +0,0 @@
<?php
/**
* A Record of a PDB file
*
* @author Sander
*/
class Record extends FileObject {
/**
* Data in the record
* @var string
*/
private $data;
/**
* Length of the record
* @var int
*/
private $length;
/**
* Create a record
* @param string $data Data contained in the record
* @param int $length Length of the record (if set to -1,
* the length of $data will be taken)
*/
public function __construct($data = "", $length = -1){
$this->data = $data;
if($length >= 0){
$this->length = $length;
}else{
$this->length = strlen($data);
}
}
public function compress($compression_method){
switch($compression_method){
case NO_COMPRESSION:
//Finished!
break;
case PALMDOC_COMPRESSION:
throw new Exception("Not implemented yet");
break;
case HUFF:
throw new Exception("Not implemented yet");
break;
default:
throw new Exception("Invalid argument");
}
}
public function getByteLength(){
return $this->getLength();
}
/**
* Get the length of the record
* @return int Length of the data
*/
public function getLength(){
return $this->length;
}
/**
* Get the data contained in the record
* @return string Data contained in the record
*/
public function get(){
return $this->data;
}
/**
* Set the data contained in the record
* @param string $value Data contained in the record
*/
public function set($value){
$this->data = $value;
}
public function serialize(){
return $this->data;
}
public function unserialize($data){
__construct($data);
}
public function __toString() {
$toShow = $this->data;
if(strlen($this->data) > 103){
$toShow = substr($this->data, 0, 100)."...";
}
$out = "Record: {\n";
$out .= "\t".htmlspecialchars($toShow)."\n";
$out .= "}";
return $out;
}
}
?>

View file

@ -1,115 +0,0 @@
<?php
/**
* Helper class to help with creating records from a
* long data stream
*
* @author Sander
*/
class RecordFactory {
/**
* Settings for the record factory
* @var Settings
*/
private $settings;
/**
* Create the helper class
* @param Settings $settings The Settings to be used for the records
*/
public function __construct($settings){
$this->settings = $settings;
}
/**
* Create records from a data string
* @param string $data
* @return array(Record)
*/
public function createRecords($data){
$records = array();
$size = $this->settings->get("recordSize");
$compression = $this->settings->get("compression");
$dataEntries = mb_str_split($data, $size);
for($i = 0, $len = sizeof($dataEntries); $i < $len; $i++){
$records[$i] = new Record($dataEntries[$i]);
$records[$i]->compress($compression);
}
return $records;
}
public function createEOFRecord(){
return new Record(0xe98e0d0a);
}
public function createFCISRecord($textLength){
$r = "FCIS";
$r .= $this->asString(20, 4);
$r .= $this->asString(16, 4);
$r .= $this->asString(1, 4);
$r .= $this->asString(0, 4);
$r .= $this->asString($textLength, 4);
$r .= $this->asString(0, 4);
$r .= $this->asString(32, 4);
$r .= $this->asString(8, 4);
$r .= $this->asString(1, 2);
$r .= $this->asString(1, 2);
$r .= $this->asString(0, 4);
return new Record($r);
}
public function createFLISRecord(){
$r = "FLIS";
$r .= $this->asString(8, 4);
$r .= $this->asString(65, 2);
$r .= $this->asString(0, 2);
$r .= $this->asString(0, 4);
$r .= $this->asString(-1, 4);
$r .= $this->asString(1, 2);
$r .= $this->asString(3, 2);
$r .= $this->asString(3, 4);
$r .= $this->asString(1, 4);
$r .= $this->asString(-1, 4);
return new Record($r);
}
private function asString($int, $size){
$out = "";
for($i = 0; $i < $size; $i++){
if($i > 0) $out = " ".$out;
$byte = dechex($int & 0xFF);
if(strlen($byte) == 1) $byte = "0".$byte;
$out = $byte.$out;
$int = $int >> 8;
}
return $out;
}
public function __toString() {
$out = "Record Factory: {\n";
$out .= "\tRecord Size: ".$this->settings->get("recordSize")."\n";
$out .= "\tCompression: ".$this->settings->get("compression")."\n";
$out .= "}";
return $out;
}
}
function mb_str_split($string, $split_length = 1){
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');
$split_length = ($split_length <= 0) ? 1 : $split_length;
$mb_strlen = mb_strlen($string, 'utf-8');
$array = array();
for($i = 0; $i < $mb_strlen; $i += $split_length){
$array[] = mb_substr($string, $i, $split_length);
}
return $array;
}
?>

View file

@ -1,97 +0,0 @@
<?php
/**
* Description of Settings
*
* @author Sander
*/
class Settings {
/**
* Values of the settings
* @var array
*/
public $values;
/**
* Construct a Settings object with the default settings. If necessary,
* those settings can be extended with additional settings
* @param array $additionalSettings Additional settings to add (should
* be added with a key/value pair format.
*/
public function __construct($additionalSettings = array()) {
// Most values shouldn't be changed (the result will be an invalid file)
$this->values = array(
"attributes"=>0,
"version"=>0,
"creationTime"=>time()+94694400,
"modificationTime"=>time()+94694400,
"backupTime"=>0,
"modificationNumber"=>0,
"appInfoID"=>0,
"sortInfoID"=>0,
"prcType"=>"BOOK",
"creator"=>"MOBI",
"uniqueIDSeed"=>rand(),
"nextRecordListID"=>0,
"recordAttributes"=>0,
"compression"=>NO_COMPRESSION,
"recordSize"=>RECORD_SIZE,
"encryptionType"=>NO_ENCRYPTION,
"mobiIdentifier"=>"MOBI",
"mobiHeaderLength"=>0xe8,
"mobiType"=>MOBIPOCKET_BOOK,
"textEncoding"=>UTF8,
"uniqueID"=>rand(),
"fileVersion"=>6,
"locale"=>0x09,
"inputLanguage"=>0,
"outputLanguage"=>0,
"minimumVersion"=>6,
"huffmanRecordOffset"=>0,
"huffmanRecordCount"=>0,
"exthFlags"=>0x40,
"drmOffset"=>0xFFFFFFFF,
"drmCount"=>0,
"drmSize"=>0,
"drmFlags"=>0,
"extraDataFlags"=>0,
"exthIdentifier"=>"EXTH",
// These can be changed without any risk
"title"=>"Unknown title",
"author"=>"Unknown author",
"subject"=>"Unknown subject"
);
foreach($additionalSettings as $key=>$value){
$this->values[$key] = $value;
}
}
/**
* Get a value from the settings
* @param string $key Key of the setting
* @return mixed The value of the setting
*/
public function get($key){
return $this->values[$key];
}
/**
* Checks if a value is set
* @param string $key Key of the setting
* @return bool True if the value exists
*/
public function exists($key){
return isset($this->values[$key]);
}
public function __toString() {
$out = "Settings: {\n";
foreach($this->values as $key=>$value){
$out .= "\t".$key.": ".$value."\n";
}
$out .= "}";
return $out;
}
}
?>

View file

@ -1,11 +0,0 @@
<?php
define("NO_COMPRESSION", 1);
define("PALMDOC_COMPRESSION", 2);
define("HUFF", 17480);
define("RECORD_SIZE", 4096);
define("NO_ENCRYPTION", 0);
define("MOBIPOCKET_BOOK", 2);
define("CP1252", 1252);
define("UTF8", 65001);

View file

@ -1,125 +0,0 @@
<?php
/**
* Description of FanFictionNet
*
* @author Sander
*/
class FanFictionNet extends MultipleFileHandler {
private static $prefix = "http://www.fanfiction.net/s/";
private $downloadedMetadata = false;
private $id = 0;
private $chapterCount = -1;
public function __construct($url) {
$ending = substr($url, strlen(self::$prefix));
$this->id = intval(substr($ending, 0, strpos($ending, "/")));
for($i = 1; $i <= max(1, $this->chapterCount); $i++){
$this->addChapter($i);
}
}
private function addChapter($n){
$doc = new DOMDocument();
$file = Http::Request(self::$prefix.$this->id."/".$n."/");
@$doc->loadHTML($file) or die($file);
if(!$this->downloadedMetadata){
$this->loadMetadata($doc);
$this->downloadedMetadata = true;
}
if($this->chapterCount < 0){
$this->chapterCount = $this->getNumberChapters($doc);
if($this->chapterCount > 4){
die("Too many files to download, don't use php for this!");
}
}
$textEl = $doc->getElementById("storytext");
if($textEl == null) die("Error: ".$doc->saveHTML());
$horizontalRulebars = $doc->getElementsByTagName('hr');
/**
* @var DOMNode
*/
$hr;
foreach($horizontalRulebars as $hr) {
$hr->setAttribute("size", null);
$hr->setAttribute("noshade", null);
}
$text = $this->innerHtml($textEl);
$title = "";
$selects = $doc->getElementsByTagName('select');
foreach($selects as $select) {
if($select->hasAttribute("name") && $select->getAttribute("name") == "chapter"){
$options = $select->getElementsByTagName("option");
$test = $n.". ";
foreach($options as $option){
$val = $option->nodeValue;
if(substr($val, 0, strlen($test)) == $test){
$title = substr($val, strlen($test));
break;
}
}
break;
}
}
$this->addPage($text, $title);
}
private function getNumberChapters($doc){
$selects = $doc->getElementsByTagName('select');
foreach($selects as $select) {
if($select->hasAttribute("name") && $select->getAttribute("name") == "chapter"){
$options = $select->getElementsByTagName("option");
$count = $options->length;
return $count;
}
}
}
private function loadMetadata($doc){
//Author
$links = $doc->getElementsByTagName('a');
foreach($links as $link) {
if($link == null){
var_dump($link);
}
if($link->hasAttribute("href") && substr($link->getAttribute("href"), 0, 3) == "/u/"){
$this->setMetadata("author", $link->nodeValue);
}
}
//Title
/*
$links = $doc->getElementsByTagName('link');
foreach($links as $link) {
if($link->hasAttribute("rel") && $link->getAttribute("rel") == "canonical"){
$url = $link->getAttribute("href");
$title = str_replace("_", " ", substr($url, strrpos($url, "/")+1));
$this->setMetadata("title", $title);
}
}*/
//TODO: Find a more reliable way to extract the title
$title = $doc->getElementsByTagName("b")->item(0)->nodeValue;
$this->setMetadata("title", $title);
}
private function innerHtml($node){
$doc = new DOMDocument();
foreach ($node->childNodes as $child)
$doc->appendChild($doc->importNode($child, true));
return $doc->saveHTML();
}
public static function Matches($url){
//TODO: Implement with regex
return strpos($url, self::$prefix) !== false;
}
}
?>

View file

@ -1,94 +0,0 @@
<?php
if(!is_callable("http_build_url")){
define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
// Build an URL
// The parts of the second URL will be merged into the first according to the flags argument.
//
// @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
// @param mixed Same as the first argument
// @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
// @param array If set, it will be filled with the parts of the composed url like parse_url() would return
function http_build_url($url, $parts = array (), $flags = HTTP_URL_REPLACE, &$new_url = false) {
$keys = array (
'user',
'pass',
'port',
'path',
'query',
'fragment'
);
// HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
if ($flags & HTTP_URL_STRIP_ALL) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
$flags |= HTTP_URL_STRIP_PORT;
$flags |= HTTP_URL_STRIP_PATH;
$flags |= HTTP_URL_STRIP_QUERY;
$flags |= HTTP_URL_STRIP_FRAGMENT;
}
// HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
else if ($flags & HTTP_URL_STRIP_AUTH) {
$flags |= HTTP_URL_STRIP_USER;
$flags |= HTTP_URL_STRIP_PASS;
}
// Parse the original URL
$parse_url = parse_url($url);
// Scheme and Host are always replaced
if (isset($parts['scheme']))
$parse_url['scheme'] = $parts['scheme'];
if (isset($parts['host']))
$parse_url['host'] = $parts['host'];
// (If applicable) Replace the original URL with it's new parts
if ($flags & HTTP_URL_REPLACE) {
foreach ($keys as $key) {
if (isset($parts[$key]))
$parse_url[$key] = $parts[$key];
}
} else {
// Join the original URL path with the new path
if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
if (isset($parse_url['path']))
$parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
else
$parse_url['path'] = $parts['path'];
}
// Join the original query string with the new query string
if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
if (isset($parse_url['query']))
$parse_url['query'] .= '&' . $parts['query'];
else
$parse_url['query'] = $parts['query'];
}
}
// Strips all the applicable sections of the URL
// Note: Scheme and Host are never stripped
foreach ($keys as $key) {
if ($flags & (int)constant('HTTP_URL_STRIP_' . strtoupper($key)))
unset($parse_url[$key]);
}
$new_url = $parse_url;
return ((isset($parse_url['scheme'])) ? $parse_url['scheme'] . '://' : '') . ((isset($parse_url['user'])) ? $parse_url['user'] . ((isset($parse_url['pass'])) ? ':' . $parse_url['pass'] : '') . '@' : '')
. ((isset($parse_url['host'])) ? $parse_url['host'] : '') . ((isset($parse_url['port'])) ? ':' . $parse_url['port'] : '') . ((isset($parse_url['path'])) ? $parse_url['path'] : '')
. ((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '') . ((isset($parse_url['fragment'])) ? '#' . $parse_url['fragment'] : '');
}
}

View file

@ -1,110 +0,0 @@
<?php
/**
* JavaScript-like HTML DOM Element
*
* This class extends PHP's DOMElement to allow
* users to get and set the innerHTML property of
* HTML elements in the same way it's done in
* JavaScript.
*
* Example usage:
* @code
* require_once 'JSLikeHTMLElement.php';
* header('Content-Type: text/plain');
* $doc = new DOMDocument();
* $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
* $elem = $doc->getElementsByTagName('div')->item(0);
*
* // print innerHTML
* echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'
* echo "\n\n";
*
* // set innerHTML
* $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';
* echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'
* echo "\n\n";
*
* // print document (with our changes)
* echo $doc->saveXML();
* @endcode
*
* @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net
* @see http://fivefilters.org (the project this was written for)
*/
class JSLikeHTMLElement extends DOMElement
{
/**
* Used for setting innerHTML like it's done in JavaScript:
* @code
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
* @endcode
*/
public function __set($name, $value) {
if ($name == 'innerHTML') {
// first, empty the element
for ($x=$this->childNodes->length-1; $x>=0; $x--) {
$this->removeChild($this->childNodes->item($x));
}
// $value holds our new inner HTML
if ($value != '') {
$f = $this->ownerDocument->createDocumentFragment();
// appendXML() expects well-formed markup (XHTML)
$result = @$f->appendXML($value); // @ to suppress PHP warnings
if ($result) {
if ($f->hasChildNodes()) $this->appendChild($f);
} else {
// $value is probably ill-formed
$f = new DOMDocument();
$value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');
// Using <htmlfragment> will generate a warning, but so will bad HTML
// (and by this point, bad HTML is what we've got).
// We use it (and suppress the warning) because an HTML fragment will
// be wrapped around <html><body> tags which we don't really want to keep.
// Note: despite the warning, if loadHTML succeeds it will return true.
$result = @$f->loadHTML('<htmlfragment>'.$value.'</htmlfragment>');
if ($result) {
$import = $f->getElementsByTagName('htmlfragment')->item(0);
foreach ($import->childNodes as $child) {
$importedNode = $this->ownerDocument->importNode($child, true);
$this->appendChild($importedNode);
}
} else {
// oh well, we tried, we really did. :(
// this element is now empty
}
}
}
} else {
$trace = debug_backtrace();
trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
}
}
/**
* Used for getting innerHTML like it's done in JavaScript:
* @code
* $string = $div->innerHTML;
* @endcode
*/
public function __get($name)
{
if ($name == 'innerHTML') {
$inner = '';
foreach ($this->childNodes as $child) {
$inner .= $this->ownerDocument->saveXML($child);
}
return $inner;
}
$trace = debug_backtrace();
trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE);
return null;
}
public function __toString()
{
return '['.$this->tagName.']';
}
}
?>

File diff suppressed because it is too large Load diff