mirror of https://github.com/wallabag/wallabag.git
travis configuration
This commit is contained in:
parent
99410a21eb
commit
3d99ce9dad
|
@ -0,0 +1,3 @@
|
|||
branches:
|
||||
only:
|
||||
- refactor
|
|
@ -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
|
||||
*
|
||||
*/
|
||||
}
|
||||
?>
|
|
@ -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();
|
||||
}
|
||||
|
||||
?>
|
|
@ -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
|
||||
);
|
||||
}
|
|
@ -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)."}";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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))."}";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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)."}";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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);
|
||||
}
|
||||
?>
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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)."}";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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"), " ", $this->serialize())."\"}";
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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)."}";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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!
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -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'] : '');
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue