<?php ############################################ # # # Author: AspieTom (tom@aspietom.co.uk) # # # # Name: FanFiction.net Downloader (v0.1) # # Type: PHP eFiction Module # # License: GPL (see LICENSE.txt) # # # ############################################ class ffmod { // A function to get text from between anchor tags. // Credit: morgan.galpin@gmail.com (at http://uk3.php.net/ereg) function returnSubStrings($text, $openingMarker, $closingMarker) { $openingMarkerLength = strlen($openingMarker); $closingMarkerLength = strlen($closingMarker); $result = array(); $position = 0; while (($position = strpos($text, $openingMarker, $position)) !== false) { $position += $openingMarkerLength; if (($closingMarkerPosition = strpos($text, $closingMarker, $position)) !== false) { $result[] = substr($text, $position, $closingMarkerPosition - $position); $position = $closingMarkerPosition + $closingMarkerLength; } } return $result; } // A function to start the process of archiving a new story. function process($id) { $details = $this->getDetails($id); $path = "./".$details['title']." (".$id.")"; mkdir($path, 0777); if($details['numchapters'] == 1) { $tempdata = $this->getChapter($id, $x); $chapterContent = $this->parseChapter($tempdata); $this->storeChapter($path, $id, $x, $details['chapternames'][$x], $chapterContent, 1); } else { $x = 1; while($x <= $details['numchapters']) { $tempdata = $this->getChapter($id, $x); $chapterContent = $this->parseChapter($tempdata); $this->storeChapter($path, $id, $x, $details['chapternames'][$x], $chapterContent); $x++; } } return true; } // A function to check for updates on all, or a specific archived story. function cycleUpdate($id=null) { include("class.fanficdl.details.php"); $ffDetails = new ffDetails; if(!empty($id)) { # check how many chapters are already stored for $id, and put it in $oldChapters $chapters = $ffDetails->chapters($id); if($chapters[0] > $oldChapters) { # we need to process it } } else { # get a list of all the stories in the database # for each story do the following: # check if it's got new chapters: # if it has then update it, # if it hasnt then finish } return true; } // A function to retrieve the details of a story ID. function getDetails($id) { include("class.fanficdl.details.php"); $ffDetails = new ffDetails; $details = array(); $details['storyid'] = $id; $firstChapterContent = $this->getChapter($id, 1); $thirdLine = $ffDetails->thirdLine($firstChapterContent); $tempChapters = $ffDetails->chapters($firstChapterContent); $details['numchapters'] = $tempChapters[0]; $details['chapternames'] = $tempChapters[1]; $tempAuthor = $ffDetails->author($firstChapterContent); $details['authorid'] = $tempAuthor[0]; $details['author'] = $tempAuthor[1]; $details['title'] = $ffDetails->title($firstChapterContent); $details['rating'] = $ffDetails->rating($thirdLine); $details['category'] = $ffDetails->category($thirdLine); $details['characters'] = $ffDetails->characters($thirdLine); $details['published'] = $ffDetails->published($thirdLine); $details['updated'] = $ffDetails->updated($thirdLine); $tempStatus = $ffDetails->status($thirdLine); $details['status'] = ($tempStatus==2) ? "Complete" : "Incomplete"; $details['summary'] = $ffDetails->summary($id, $details['authorid']); return $details; } // A function to retrieve the code of a required chapter. function getChapter($id, $chapter) { $url = "http://www.fanfiction.net/s/".$id."/".$chapter."/"; $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,"; $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"; $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7"; $header[] = "Accept-Language: en-us,en;q=0.5"; $header[] = "Pragma: "; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); $data = curl_exec($ch); curl_close($ch); return $data; } // A function to parse the code that we retrieved. function parseChapter($content) { $contentSubStr = $this->returnSubStrings($content, "<!-- start story -->", "<!-- end story -->"); return $contentSubStr[0]; } // A function store a chapter under an existing archived story. function storeChapter($path, $id, $chapter, $name, $content, $oneshot=0) { if($oneshot == 1) { $fh = fopen($path."/story.html", "w+"); } else { $fh = fopen($path."/".$chapter." - ".$name.".html", "w+"); } fwrite($fh, $content); fclose($fh); } }$ffmod = new ffmod;#$ffmod->process($_POST['id']);#echo htmlentities($ffmod->getChapter($_GET['id'], 1));echo htmlentities($ffmod->parseChapter($ffmod->getChapter($_GET['id'], 1)));?>