]>
Commit | Line | Data |
---|---|---|
4188f38a | 1 | <?php |
2 | ||
3 | /** | |
4 | * Description of FanFictionNet | |
5 | * | |
6 | * @author Sander | |
7 | */ | |
8 | class FanFictionNet extends MultipleFileHandler { | |
9 | private static $prefix = "http://www.fanfiction.net/s/"; | |
10 | private $downloadedMetadata = false; | |
11 | private $id = 0; | |
12 | private $chapterCount = -1; | |
13 | ||
14 | public function __construct($url) { | |
15 | $ending = substr($url, strlen(self::$prefix)); | |
16 | $this->id = intval(substr($ending, 0, strpos($ending, "/"))); | |
17 | ||
18 | for($i = 1; $i <= max(1, $this->chapterCount); $i++){ | |
19 | $this->addChapter($i); | |
20 | } | |
21 | } | |
22 | ||
23 | private function addChapter($n){ | |
24 | $doc = new DOMDocument(); | |
25 | $file = Http::Request(self::$prefix.$this->id."/".$n."/"); | |
26 | @$doc->loadHTML($file) or die($file); | |
27 | ||
28 | if(!$this->downloadedMetadata){ | |
29 | $this->loadMetadata($doc); | |
30 | $this->downloadedMetadata = true; | |
31 | } | |
32 | if($this->chapterCount < 0){ | |
33 | $this->chapterCount = $this->getNumberChapters($doc); | |
34 | ||
35 | if($this->chapterCount > 4){ | |
36 | die("Too many files to download, don't use php for this!"); | |
37 | } | |
38 | } | |
39 | ||
40 | $textEl = $doc->getElementById("storytext"); | |
41 | if($textEl == null) die("Error: ".$doc->saveHTML()); | |
42 | $horizontalRulebars = $doc->getElementsByTagName('hr'); | |
43 | /** | |
44 | * @var DOMNode | |
45 | */ | |
46 | $hr; | |
47 | foreach($horizontalRulebars as $hr) { | |
48 | $hr->setAttribute("size", null); | |
49 | $hr->setAttribute("noshade", null); | |
50 | } | |
51 | $text = $this->innerHtml($textEl); | |
52 | ||
53 | $title = ""; | |
54 | $selects = $doc->getElementsByTagName('select'); | |
55 | foreach($selects as $select) { | |
56 | if($select->hasAttribute("name") && $select->getAttribute("name") == "chapter"){ | |
57 | $options = $select->getElementsByTagName("option"); | |
58 | ||
59 | $test = $n.". "; | |
60 | foreach($options as $option){ | |
61 | $val = $option->nodeValue; | |
62 | if(substr($val, 0, strlen($test)) == $test){ | |
63 | $title = substr($val, strlen($test)); | |
64 | break; | |
65 | } | |
66 | } | |
67 | break; | |
68 | } | |
69 | } | |
70 | $this->addPage($text, $title); | |
71 | } | |
72 | ||
73 | private function getNumberChapters($doc){ | |
74 | $selects = $doc->getElementsByTagName('select'); | |
75 | foreach($selects as $select) { | |
76 | if($select->hasAttribute("name") && $select->getAttribute("name") == "chapter"){ | |
77 | $options = $select->getElementsByTagName("option"); | |
78 | ||
79 | $count = $options->length; | |
80 | return $count; | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | private function loadMetadata($doc){ | |
86 | //Author | |
87 | $links = $doc->getElementsByTagName('a'); | |
88 | foreach($links as $link) { | |
89 | if($link == null){ | |
90 | var_dump($link); | |
91 | } | |
92 | if($link->hasAttribute("href") && substr($link->getAttribute("href"), 0, 3) == "/u/"){ | |
93 | $this->setMetadata("author", $link->nodeValue); | |
94 | } | |
95 | } | |
96 | //Title | |
97 | /* | |
98 | $links = $doc->getElementsByTagName('link'); | |
99 | foreach($links as $link) { | |
100 | if($link->hasAttribute("rel") && $link->getAttribute("rel") == "canonical"){ | |
101 | $url = $link->getAttribute("href"); | |
102 | $title = str_replace("_", " ", substr($url, strrpos($url, "/")+1)); | |
103 | $this->setMetadata("title", $title); | |
104 | } | |
105 | }*/ | |
106 | ||
107 | //TODO: Find a more reliable way to extract the title | |
108 | $title = $doc->getElementsByTagName("b")->item(0)->nodeValue; | |
109 | $this->setMetadata("title", $title); | |
110 | } | |
111 | ||
112 | private function innerHtml($node){ | |
113 | $doc = new DOMDocument(); | |
114 | foreach ($node->childNodes as $child) | |
115 | $doc->appendChild($doc->importNode($child, true)); | |
116 | ||
117 | return $doc->saveHTML(); | |
118 | } | |
119 | ||
120 | public static function Matches($url){ | |
121 | //TODO: Implement with regex | |
122 | return strpos($url, self::$prefix) !== false; | |
123 | } | |
124 | } | |
125 | ?> |