From 3cffac479ee998bfdac6821d1ffe3c3ec46528b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Tue, 14 May 2013 21:35:43 +0200 Subject: [PATCH 01/33] Add an handler to access epub internal files. --HG-- extra : rebase_source : 31f7f77fba14f09117d08dd1228da0a8221f8747 --- epubfs.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 epubfs.php diff --git a/epubfs.php b/epubfs.php new file mode 100644 index 0000000..9a5ea3c --- /dev/null +++ b/epubfs.php @@ -0,0 +1,37 @@ +initSpineComponent (); + +$component = $_GET["comp"]; + +if (empty ($component)) { + notFound (); +} + +try { + $data = $book->component ($component); + $directory = dirname ($component); + + $data = preg_replace ("/src=[\"']([^:]*?)[\"']/", "src='epubfs.php?comp=$1'", $data); + $data = preg_replace ("/href=[\"']([^:]*?)[\"']/", "href='epubfs.php?comp=$1'", $data); + $data = preg_replace ("/\@import\s+[\"'](.*?)[\"'];/", "@import 'epubfs.php?comp={$directory}/$1';", $data); + + header ("Content-Type: " . $book->componentContentType($component)); + echo $data; +} +catch (Exception $e) { + notFound (); +} + + +?> \ No newline at end of file From c8a87a37d4f4447a56d1ba2ac802fb49ad19581f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 15 May 2013 09:21:59 +0200 Subject: [PATCH 02/33] Add the epub reader. early stage ;) --HG-- extra : rebase_source : 4e74b8db133f69feca6787063c05b45667c8f64d --- epubreader.php | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 epubreader.php diff --git a/epubreader.php b/epubreader.php new file mode 100644 index 0000000..d9aa339 --- /dev/null +++ b/epubreader.php @@ -0,0 +1,67 @@ +initSpineComponent (); + +?> + + + + + + + COPS's Epub Reader + + + " media="screen" /> + + + + + \ No newline at end of file From 3a61b70445866764cc820fea8fc2781432d96090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 15 May 2013 12:11:47 +0200 Subject: [PATCH 03/33] Complete working example --HG-- extra : rebase_source : d0f38d1aa980ddec8e60dbe8ddd7689509257886 --- epubreader.php | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/epubreader.php b/epubreader.php index d9aa339..771f949 100644 --- a/epubreader.php +++ b/epubreader.php @@ -18,39 +18,32 @@ $book->initSpineComponent (); COPS's Epub Reader - - " media="screen" /> + + " media="screen" /> + +
+
+ \ No newline at end of file From 168ba3994e4d425e5969c4b1bd3090176458cba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 15 May 2013 13:41:08 +0200 Subject: [PATCH 04/33] simplify --HG-- extra : rebase_source : 4bf414bce486565a29ca928e77b55f6d2a55718d --- epubreader.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/epubreader.php b/epubreader.php index 771f949..c48fd33 100644 --- a/epubreader.php +++ b/epubreader.php @@ -35,14 +35,10 @@ $book->initSpineComponent (); getComponent: function (componentId, callback) { $.ajax({ url: "epubfs.php?comp=" + componentId, - type: 'get' - , dataType: 'text' - , error: function () {alert ("error");} - , success: function (data, textStatus, jqXHR ) { - //alert (textStatus); - //alert (data); - callback (data); - } + type: 'get', + dataType: 'text', + error: function () {alert ("error");}, + success: callback }); }, getMetaData: function(key) { From ff30a3b0a32cbbb035a64a738616982883cfffef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 15 May 2013 14:16:09 +0200 Subject: [PATCH 05/33] Borrow Monocle sample style --HG-- extra : rebase_source : 87c21882bc820ec0d253b67e14d3cb1868324cc1 --- cops-monocle.css | 273 +++++++++++++++++++++++++++++++++++++++++++++++ cops-monocle.js | 162 ++++++++++++++++++++++++++++ epubreader.php | 20 +++- 3 files changed, 450 insertions(+), 5 deletions(-) create mode 100644 cops-monocle.css create mode 100644 cops-monocle.js diff --git a/cops-monocle.css b/cops-monocle.css new file mode 100644 index 0000000..7c8c5b6 --- /dev/null +++ b/cops-monocle.css @@ -0,0 +1,273 @@ +body { + margin: 0; + padding: 0; + background: #000; + -webkit-user-select: none; + -webkit-text-size-adjust: none; +} + +#components { + display: none; +} + +#reader, #readerBg { + position: absolute; + width: 100%; + height: 100%; +} + +#reader div pre { + white-space: normal; + font: normal 100% serif; +} + +/* from smallest and outermost to largest and innermost */ +.dummyPage { + position: absolute; + left: 0; + top: 20px; + bottom: 20px; + right: 15px; + background-color: #FCF6F0; + -webkit-box-shadow: 2px 2px 4px #754; + -moz-box-shadow: 2px 2px 4px #754; + box-shadow: 2px 2px 4px #754; + -webkit-border-top-left-radius: 26px 6px; + -webkit-border-bottom-left-radius: 26px 6px; + -moz-border-top-left-radius: 26px 6px; + -moz-border-bottom-left-radius: 26px 6px; + border-top-left-radius: 26px 6px; + border-bottom-left-radius: 26px 6px; +} +.dummyPage + .dummyPage { + top: 16px; + bottom: 16px; + right: 16px; + -webkit-box-shadow: 1px 0 2px #A99; + -moz-box-shadow: 1px 0 2px #A99; + box-shadow: 1px 0 2px #A99; +} +.dummyPage + .dummyPage + .dummyPage { + top: 13px; + bottom: 13px; + right: 18px; + background-color: #FFF9F4; +} +.dummyPage + .dummyPage + .dummyPage + .dummyPage { + top: 10px; + bottom: 10px; + right: 21px; +} +.dummyPage + .dummyPage + .dummyPage + .dummyPage + .dummyPage { + top: 8px; + bottom: 8px; + right: 25px; +} +.jacket { + position: absolute; + top: 1px; + bottom: 1px; + right: 3px; + left: 65%; + -webkit-box-shadow: -3px 0 3px #311; + -moz-box-shadow: -3px 0 3px #311; + box-shadow: -3px 0 3px #311; + -webkit-border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + -moz-border-top-right-radius: 3px; + -moz-border-bottom-right-radius: 3px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + background-color: #F7F7F7; + background: -webkit-linear-gradient(0deg, #DDD, #FFF); + background: -moz-linear-gradient(0deg , #DDD, #FFF); + background: linear-gradient(90deg, #DDD, #FFF); +} +.board { + position: absolute; + top: 1px; + bottom: 1px; + width: 90%; + background-color: #974; + border: 1px solid #852; +} + +.runner { + color: #542; + text-transform: uppercase; + font-size: 82%; +} + +.pageNumber, .bookTitle, .chapterTitle { + padding: 3% 2%; +} + +.bookTitle, .chapterTitle { + position: absolute; + top: 1%; + left: 6%; + cursor: pointer; + padding-left: 0; +} + +.chapterTitle { + top: auto; + bottom: 1%; + right: 20%; +} + +.pageNumber { + position: absolute; + bottom: 1%; + right: 8%; + padding-right: 0; +} + +#readerBg { + background-color: #000; +} + +#toc ul.root { + position: absolute; + top: 50px; + left: 8%; + max-height: 75%; + max-width: 80%; + background: #E0D3C0; + -webkit-box-shadow: 1px 2px 2px #652; + -moz-box-shadow: 1px 2px 2px #652; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + overflow-y: auto; + color: #432; + font: 11pt Georgia, serif; + text-shadow: 1px 1px #EEE6D0; + border: 1px solid #EED; + z-index: 9; +} + +.tocArrow { + position: absolute; + top: 40px; + left: 16%; + width: 20px; + height: 20px; + -webkit-transform: rotateZ(45deg); + background: #E0D3C0; + z-index: 8; +} + +#toc li { + list-style: none; + line-height: 220%; + padding-left: 1em; + padding-right: 2em; + border-bottom: 2px groove #FFF6E9; + cursor: pointer; +} + +#toc li span { + display: block; +} + +#toc ul li:last-child { + border-bottom: none; +} + +#toc ul { + margin: 0; + padding: 0; +} +#toc ul.root { + border-top: none; +} + + + +/* Overrides to core elements */ + +div.monelem_container { + background: none; + width: auto; +} + +div.monelem_page { + top: 6px; + bottom: 6px; + right: 4px; + border-color: #CBA; + outline: none; + -webkit-box-shadow: 1px 0 1px #CBA; + -moz-box-shadow: 1px 0 1px #CBA; + box-shadow: 1px 0 2px #CBA; + -webkit-border-top-left-radius: 26px 4px; + -webkit-border-bottom-left-radius: 26px 4px; + -moz-border-top-left-radius: 26px 4px; + -moz-border-bottom-left-radius: 26px 4px; + border-top-left-radius: 26px 4px; + border-bottom-left-radius: 26px 4px; + background-color: #FFFFFE; + background-image: -webkit-linear-gradient(0deg, #EDEAE8 0px, #FFFFFE 24px); + background-image: -moz-linear-gradient(0deg, #EDEAE8 0px, #FFFFFE 24px); + background-image: linear-gradient(90deg, #EDEAE8 0px, #FFFFFE 24px); +} + +div.monelem_sheaf { + left: 6%; + right: 8%; + top: 8%; + bottom: 8%; +} + + +/* Overriding magnifier button display */ + +div.monelem_controls_magnifier_button { + color: #632; + padding: 2%; + top: 1%; + right: 6%; +} + + +/* Overriding table of contents display */ + +div.monelem_controls_contents_container { + background: #E0D3C0; + border: 1px solid #EED; + font: 11pt Georgia, serif; + color: #432; + text-shadow: 1px 1px #FFF6E0; +} + +div.monelem_controls_contents_chapter { + border-bottom: 2px groove #FFF6E9; +} + +li.monelem_controls_contents_chapter_active { + text-shadow: -1px -1px #876; + background: #BA9; +} + + +/* Overriding the scrubber display */ +div.monelem_controls_scrubber_container { + left: 5.5%; + right: 9%; + bottom: 2%; + background: #FFFEFC; +} + +div.monelem_controls_scrubber_track { + border-color: #432; +} + +div.monelem_controls_scrubber_needle { + border-color: #432; + background: #E0D3C0; +} + +div.monelem_controls_scrubber_trail { + background: #E0D3C0; +} diff --git a/cops-monocle.js b/cops-monocle.js new file mode 100644 index 0000000..222187f --- /dev/null +++ b/cops-monocle.js @@ -0,0 +1,162 @@ +Monocle.DEBUG = true; + +(function () { + + Monocle.Styles.container.right = "24px"; + + // Initialize the reader element. + Monocle.Events.listen( + window, + 'load', + function () { + var readerOptions = {}; + + /* PLACE SAVER */ + var bkTitle = bookData.getMetaData('title'); + var placeSaver = new Monocle.Controls.PlaceSaver(bkTitle); + readerOptions.place = placeSaver.savedPlace(); + readerOptions.panels = Monocle.Panels.Marginal; + readerOptions.stylesheet = "body { " + + "color: #210;" + + "font-family: Palatino, Georgia, serif;" + + "}"; + + /* Initialize the reader */ + window.reader = Monocle.Reader( + 'reader', + bookData, + readerOptions, + function(reader) { + reader.addControl(placeSaver, 'invisible'); + + /* SPINNER */ + var spinner = Monocle.Controls.Spinner(reader); + reader.addControl(spinner, 'page', { hidden: true }); + spinner.listenForUsualDelays('reader'); + + /* Because the 'reader' element changes size on window resize, + * we should notify it of this event. */ + Monocle.Events.listen( + window, + 'resize', + function () { window.reader.resized() } + ); + + /* MAGNIFIER CONTROL */ + var magnifier = new Monocle.Controls.Magnifier(reader); + reader.addControl(magnifier, 'page'); + + /* The stencil activates internal links */ + var stencil = new Monocle.Controls.Stencil(reader); + reader.addControl(stencil); + //stencil.toggleHighlights(); + + /* BOOK TITLE RUNNING HEAD */ + var bookTitle = {} + bookTitle.contentsMenu = Monocle.Controls.Contents(reader); + reader.addControl(bookTitle.contentsMenu, 'popover', { hidden: true }); + bookTitle.createControlElements = function () { + var cntr = document.createElement('div'); + cntr.className = "bookTitle"; + var runner = document.createElement('div'); + runner.className = "runner"; + runner.innerHTML = reader.getBook().getMetaData('title'); + cntr.appendChild(runner); + + Monocle.Events.listenForContact( + cntr, + { + start: function (evt) { + if (evt.preventDefault) { + evt.stopPropagation(); + evt.preventDefault(); + } else { + evt.returnValue = false; + } + reader.showControl(bookTitle.contentsMenu); + } + } + ); + + return cntr; + } + reader.addControl(bookTitle, 'page'); + + + /* CHAPTER TITLE RUNNING HEAD */ + var chapterTitle = { + runners: [], + createControlElements: function (page) { + var cntr = document.createElement('div'); + cntr.className = "chapterTitle"; + var runner = document.createElement('div'); + runner.className = "runner"; + cntr.appendChild(runner); + this.runners.push(runner); + this.update(page); + return cntr; + }, + update: function (page) { + var place = reader.getPlace(page); + if (place) { + this.runners[page.m.pageIndex].innerHTML = place.chapterTitle(); + } + } + } + reader.addControl(chapterTitle, 'page'); + reader.listen( + 'monocle:pagechange', + function (evt) { chapterTitle.update(evt.m.page); } + ); + + + /* PAGE NUMBER RUNNING HEAD */ + var pageNumber = { + runners: [], + createControlElements: function (page) { + var cntr = document.createElement('div'); + cntr.className = "pageNumber"; + var runner = document.createElement('div'); + runner.className = "runner"; + cntr.appendChild(runner); + this.runners.push(runner); + this.update(page, page.m.place.pageNumber()); + return cntr; + }, + update: function (page, pageNumber) { + if (pageNumber) { + this.runners[page.m.pageIndex].innerHTML = pageNumber; + } + } + } + reader.addControl(pageNumber, 'page'); + reader.listen( + 'monocle:pagechange', + function (evt) { + pageNumber.update(evt.m.page, evt.m.pageNumber); + } + ); + + /* Scrubber */ + var scrubber = new Monocle.Controls.Scrubber(reader); + reader.addControl(scrubber, 'popover', { hidden: true }); + var showFn = function (evt) { + evt.stopPropagation(); + reader.showControl(scrubber); + scrubber.updateNeedles(); + } + for (var i = 0; i < chapterTitle.runners.length; ++i) { + Monocle.Events.listenForContact( + chapterTitle.runners[i].parentNode, + { start: showFn } + ); + Monocle.Events.listenForContact( + pageNumber.runners[i].parentNode, + { start: showFn } + ); + } + } + ); + } + ); +})(); diff --git a/epubreader.php b/epubreader.php index c48fd33..ef8dcc1 100644 --- a/epubreader.php +++ b/epubreader.php @@ -19,10 +19,9 @@ $book->initSpineComponent (); COPS's Epub Reader + " media="screen" /> - + " media="screen" /> + + " media="screen" /> -
+
+
+
+
+
+
+
+
+
+
+
- \ No newline at end of file From f368795542db514245164d2bd90b5e25f7990081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 28 Aug 2013 14:44:47 +0200 Subject: [PATCH 06/33] Handle directories a little better. --HG-- extra : rebase_source : 21fb6d3cf27dd6bc9b7949b8ae08fe64f3a7c709 --- resources/php-epub-meta/epub.php | 151 +++++++++++++++---------------- 1 file changed, 71 insertions(+), 80 deletions(-) diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index b30195d..f16e915 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -5,11 +5,11 @@ * @author Andreas Gohr * @author Sébastien Lucas */ - + require_once(realpath( dirname( __FILE__ ) ) . '/tbszip.php'); define ("METADATA_FILE", "META-INF/container.xml"); - + class EPub { public $xml; //FIXME change to protected, later public $toc; @@ -26,13 +26,12 @@ class EPub { * Constructor * * @param string $file path to epub file to work on - * @param string $zipClass class to handle zip * @throws Exception if metadata could not be loaded */ - public function __construct($file, $zipClass = 'clsTbsZip'){ + public function __construct($file){ // open file $this->file = $file; - $this->zip = new $zipClass(); + $this->zip = new clsTbsZip(); if(!$this->zip->Open($this->file)){ throw new Exception('Failed to read epub file'); } @@ -41,7 +40,7 @@ class EPub { if (!$this->zip->FileExists(METADATA_FILE)) { throw new Exception ("Unable to find metadata.xml"); } - + $data = $this->zip->FileRead(METADATA_FILE); if($data == false){ throw new Exception('Failed to access epub container data'); @@ -57,7 +56,7 @@ class EPub { if (!$this->zip->FileExists($this->meta)) { throw new Exception ("Unable to find " . $this->meta); } - + $data = $this->zip->FileRead($this->meta); if(!$data){ throw new Exception('Failed to access epub metadata'); @@ -68,24 +67,24 @@ class EPub { $this->xml->formatOutput = true; $this->xpath = new EPubDOMXPath($this->xml); } - + public function initSpineComponent () { $spine = $this->xpath->query('//opf:spine')->item(0); $tocid = $spine->getAttribute('toc'); $tochref = $this->xpath->query("//opf:manifest/opf:item[@id='$tocid']")->item(0)->attr('href'); - $tocpath = dirname($this->meta).'/'.$tochref; + $tocpath = $this->getFullPath ($tochref); // read epub toc if (!$this->zip->FileExists($tocpath)) { throw new Exception ("Unable to find " . $tocpath); } - + $data = $this->zip->FileRead($tocpath); $this->toc = new DOMDocument(); $this->toc->registerNodeClass('DOMElement','EPubDOMElement'); $this->toc->loadXML($data); $this->toc_xpath = new EPubDOMXPath($this->toc); - $rootNamespace = $this->toc->lookupNamespaceUri($this->toc->namespaceURI); + $rootNamespace = $this->toc->lookupNamespaceUri($this->toc->namespaceURI); $this->toc_xpath->registerNamespace('x', $rootNamespace); } @@ -95,7 +94,7 @@ class EPub { public function file(){ return $this->file; } - + /** * Close the epub file */ @@ -124,7 +123,7 @@ class EPub { $this->download (); $this->zip->close(); } - + /** * Get the updated epub */ @@ -150,7 +149,7 @@ class EPub { } return $spine; } - + /** * Get the component content */ @@ -159,11 +158,11 @@ class EPub { if (!$this->zip->FileExists($path)) { throw new Exception ("Unable to find " . $path); } - + $data = $this->zip->FileRead($path); return $data; } - + /** * Get the component content type */ @@ -186,7 +185,7 @@ class EPub { } return $contents; } - + /** * Get or set the book author(s) * @@ -300,61 +299,6 @@ class EPub { return $this->getset('dc:description',$description); } - /** - * Set or get the book's Unique Identifier - * - * @param string Unique identifier - */ - public function Uuid($uuid = false) - { - $nodes = $this->xpath->query('/opf:package'); - if ($nodes->length !== 1) { - $error = sprintf('Cannot find ebook identifier'); - throw new Exception($error); - } - $identifier = $nodes->item(0)->attr('unique-identifier'); - - $res = $this->getset('dc:identifier', $uuid, 'id', $identifier); - - return $res; - } - - /** - * Set or get the book's creation date - * - * @param string Date eg: 2012-05-19T12:54:25Z - */ - public function CreationDate($date = false) - { - $res = $this->getset('dc:date', $date, 'opf:event', 'creation'); - - return $res; - } - - /** - * Set or get the book's modification date - * - * @param string Date eg: 2012-05-19T12:54:25Z - */ - public function ModificationDate($date = false) - { - $res = $this->getset('dc:date', $date, 'opf:event', 'modification'); - - return $res; - } - - /** - * Set or get the book's URI - * - * @param string URI - */ - public function Uri($uri = false) - { - $res = $this->getset('dc:identifier', $uri, 'opf:scheme', 'URI'); - - return $res; - } - /** * Set or get the book's ISBN number * @@ -381,7 +325,7 @@ class EPub { public function Amazon($amazon=false){ return $this->getset('dc:identifier',$amazon,'opf:scheme','AMAZON'); } - + /** * Set or get the Calibre UUID of the book * @@ -399,7 +343,7 @@ class EPub { public function Serie($serie=false){ return $this->getset('opf:meta',$serie,'name','cops:series','content'); } - + /** * Set or get the Serie Index of the book * @@ -408,7 +352,7 @@ class EPub { public function SerieIndex($serieIndex=false){ return $this->getset('opf:meta',$serieIndex,'name','cops:series_index','content'); } - + /** * Set or get the book's subjects (aka. tags) * @@ -529,11 +473,11 @@ class EPub { 'found' => $path ); } - + public function getCoverItem () { $nodes = $this->xpath->query('//opf:metadata/opf:meta[@name="cover"]'); if(!$nodes->length) return NULL; - + $coverid = (String) $nodes->item(0)->attr('opf:content'); if(!$coverid) return NULL; @@ -542,14 +486,61 @@ class EPub { return $nodes->item(0); } + + public function Combine($a, $b) + { + $isAbsolute = false; + if ($a[0] == "/") + $isAbsolute = true; + if ($b[0] == "/") + throw new InvalidArgumentException("Second path part must not stwar with " . $m_Separator); + + $splittedA = split("/", $a); + $splittedB = split("/", $b); + + $pathParts = array(); + $mergedPath = array_merge($splittedA, $splittedB); + + foreach($mergedPath as $item) + { + if ($item == null || $item == "" || $item == ".") + continue; + + if ($item == "..") + { + array_pop($pathParts); + continue; + } + + array_push($pathParts, $item); + } + + $path = implode("/", $pathParts); + if ($isAbsolute) + return("/" . $path); + else + return($path); + } + + private function getFullPath ($file, $context = NULL) { + $path = dirname('/'.$this->meta).'/'.$file; + $path = ltrim($path,'\\'); + $path = ltrim($path,'/'); + if (!empty ($context)) { + $path = $this->combine (dirname ($path), $context); + } + error_log ("FullPath : $path ($file / $context)"); + return $path; + } + public function updateForKepub () { $item = $this->getCoverItem (); if (!is_null ($item)) { $item->attr('opf:properties', 'cover-image'); } } - + public function Cover2($path=false, $mime=false){ $hascover = true; $item = $this->getCoverItem (); @@ -562,7 +553,7 @@ class EPub { $this->coverpath = ltrim($this->coverpath,'\\'); $this->coverpath = ltrim($this->coverpath,'/'); } - + // set cover if($path !== false){ if (!$hascover) return; // TODO For now only update @@ -576,7 +567,7 @@ class EPub { $this->reparse(); } - + if (!$hascover) return $this->no_cover(); } From a51a2768051b71c0b6245ab14cb12da222cad218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 28 Aug 2013 14:45:37 +0200 Subject: [PATCH 07/33] components does not contain / anymore. --HG-- extra : rebase_source : 0a4eea43929b87c4455cba8c4343586733ae3ffe --- resources/php-epub-meta/epub.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index f16e915..ffc2ee8 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -145,7 +145,7 @@ class EPub { $nodes = $this->xpath->query('//opf:spine/opf:itemref'); foreach($nodes as $node){ $idref = $node->getAttribute('idref'); - $spine[] = $this->xpath->query("//opf:manifest/opf:item[@id='$idref']")->item(0)->getAttribute('href'); + $spine[] = str_replace ("/", "-SLASH-", $this->xpath->query("//opf:manifest/opf:item[@id='$idref']")->item(0)->getAttribute('href')); } return $spine; } @@ -153,8 +153,9 @@ class EPub { /** * Get the component content */ - public function component($comp) { - $path = dirname($this->meta).'/'.$comp; + public function component($comp, $elementPath) { + $path = str_replace ("-SLASH-", "/", $comp); + $path = $this->getFullPath ($path, $elementPath); if (!$this->zip->FileExists($path)) { throw new Exception ("Unable to find " . $path); } @@ -167,6 +168,7 @@ class EPub { * Get the component content type */ public function componentContentType($comp) { + $comp = str_replace ("-SLASH-", "/", $comp); return $this->xpath->query("//opf:manifest/opf:item[@href='$comp']")->item(0)->getAttribute('media-type'); } @@ -181,6 +183,7 @@ class EPub { foreach($nodes as $node){ $title = $this->toc_xpath->query('x:navLabel/x:text', $node)->item(0)->nodeValue; $src = $this->toc_xpath->query('x:content', $node)->item(0)->attr('src'); + $src = str_replace ("/", "-SLASH-", $src); $contents[] = array("title" => $title, "src" => $src); } return $contents; From 881f76d87ae041209dc5467c6f4c0f6e5ab90bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Thu, 29 Aug 2013 08:43:11 +0200 Subject: [PATCH 08/33] Another test --HG-- extra : rebase_source : d6fd95a2c138efdb1901d7b09af47e20e6bf993e --- epubfs.php | 12 ++++++++---- epubreader.php | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/epubfs.php b/epubfs.php index 9a5ea3c..53f32e2 100644 --- a/epubfs.php +++ b/epubfs.php @@ -9,21 +9,25 @@ function notFound () { $_SERVER['REDIRECT_STATUS'] = 404; } -$book = new EPub ("c:/Temp/Alice.epub"); +$book = new EPub ("c:/Temp/Phare.epub"); $book->initSpineComponent (); $component = $_GET["comp"]; +$elementPath = NULL; +if (!empty ($_GET) && isset($_GET["path"]) && $_GET["path"] != "") { + $elementPath = $_GET["path"]; +} if (empty ($component)) { notFound (); } try { - $data = $book->component ($component); + $data = $book->component ($component, $elementPath); $directory = dirname ($component); - $data = preg_replace ("/src=[\"']([^:]*?)[\"']/", "src='epubfs.php?comp=$1'", $data); - $data = preg_replace ("/href=[\"']([^:]*?)[\"']/", "href='epubfs.php?comp=$1'", $data); + $data = preg_replace ("/src=[\"']([^:]*?)[\"']/", "src='epubfs.php?path=$1&comp=$component'", $data); + $data = preg_replace ("/href=[\"']([^:]*?)[\"']/", "href='epubfs.php?path=$1&comp=$component'", $data); $data = preg_replace ("/\@import\s+[\"'](.*?)[\"'];/", "@import 'epubfs.php?comp={$directory}/$1';", $data); header ("Content-Type: " . $book->componentContentType($component)); diff --git a/epubreader.php b/epubreader.php index ef8dcc1..f865914 100644 --- a/epubreader.php +++ b/epubreader.php @@ -6,7 +6,7 @@ require_once ("resources/php-epub-meta/epub.php"); header ("Content-Type: text/html;charset=utf-8"); -$book = new EPub ("c:/Temp/Alice.epub"); +$book = new EPub ("c:/Temp/Phare.epub"); $book->initSpineComponent (); ?> From 30f801443e5190d643a44dd862df751852a434ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Fri, 30 Aug 2013 10:35:15 +0200 Subject: [PATCH 09/33] Simplify relative path handling. --HG-- extra : rebase_source : d20290cad2dca3ea1f04a85f899c026c0991bbe5 --- epubfs.php | 23 +++++++++++++++-------- resources/php-epub-meta/epub.php | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/epubfs.php b/epubfs.php index 53f32e2..e34c79e 100644 --- a/epubfs.php +++ b/epubfs.php @@ -13,27 +13,34 @@ $book = new EPub ("c:/Temp/Phare.epub"); $book->initSpineComponent (); $component = $_GET["comp"]; -$elementPath = NULL; -if (!empty ($_GET) && isset($_GET["path"]) && $_GET["path"] != "") { - $elementPath = $_GET["path"]; -} if (empty ($component)) { notFound (); } try { - $data = $book->component ($component, $elementPath); + $data = $book->component ($component); $directory = dirname ($component); - $data = preg_replace ("/src=[\"']([^:]*?)[\"']/", "src='epubfs.php?path=$1&comp=$component'", $data); - $data = preg_replace ("/href=[\"']([^:]*?)[\"']/", "href='epubfs.php?path=$1&comp=$component'", $data); - $data = preg_replace ("/\@import\s+[\"'](.*?)[\"'];/", "@import 'epubfs.php?comp={$directory}/$1';", $data); + $callback = function ($m) use ($book, $component) { + $method = $m[1]; + $path = $m[2]; + if (preg_match ("/^#/", $path)) { + return $path; + } + $comp = $book->getComponentName ($component, $path); + return "$method'epubfs.php?comp=$comp'"; + }; + + $data = preg_replace_callback ("/(src=)[\"']([^:]*?)[\"']/", $callback, $data); + $data = preg_replace_callback ("/(href=)[\"']([^:]*?)[\"']/", $callback, $data); + $data = preg_replace_callback ("/(\@import\s+)[\"'](.*?)[\"'];/", $callback, $data); header ("Content-Type: " . $book->componentContentType($component)); echo $data; } catch (Exception $e) { + error_log ($e); notFound (); } diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index ffc2ee8..286e2f0 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -153,9 +153,9 @@ class EPub { /** * Get the component content */ - public function component($comp, $elementPath) { + public function component($comp) { $path = str_replace ("-SLASH-", "/", $comp); - $path = $this->getFullPath ($path, $elementPath); + $path = $this->getFullPath ($path); if (!$this->zip->FileExists($path)) { throw new Exception ("Unable to find " . $path); } @@ -164,6 +164,15 @@ class EPub { return $data; } + public function getComponentName ($comp, $elementPath) { + $path = str_replace ("-SLASH-", "/", $comp); + $path = $this->getFullPath ($path, $elementPath); + if (!$this->zip->FileExists($path)) { + throw new Exception ("Unable to find " . $path); + } + return str_replace ("/", "-SLASH-", $path); + } + /** * Get the component content type */ @@ -533,7 +542,7 @@ class EPub { if (!empty ($context)) { $path = $this->combine (dirname ($path), $context); } - error_log ("FullPath : $path ($file / $context)"); + //error_log ("FullPath : $path ($file / $context)"); return $path; } From ea3da650de80e612bd49a98bb20c307744cf9758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Fri, 30 Aug 2013 15:52:28 +0200 Subject: [PATCH 10/33] Working with cops --HG-- extra : rebase_source : 66639c415fc1286e8df50c255d83b0e8f92777d3 --- epubfs.php | 20 +++++++++++++------- epubreader.php | 26 ++++++++++++++++---------- resources/php-epub-meta/epub.php | 8 ++++++++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/epubfs.php b/epubfs.php index e34c79e..587e05f 100644 --- a/epubfs.php +++ b/epubfs.php @@ -1,5 +1,8 @@ getFilePath ("EPUB", $idData)); + $book->initSpineComponent (); $component = $_GET["comp"]; @@ -22,14 +31,14 @@ try { $data = $book->component ($component); $directory = dirname ($component); - $callback = function ($m) use ($book, $component) { + $callback = function ($m) use ($book, $component, $add) { $method = $m[1]; $path = $m[2]; if (preg_match ("/^#/", $path)) { return $path; } $comp = $book->getComponentName ($component, $path); - return "$method'epubfs.php?comp=$comp'"; + return "$method'epubfs.php?{$add}comp=$comp'"; }; $data = preg_replace_callback ("/(src=)[\"']([^:]*?)[\"']/", $callback, $data); @@ -42,7 +51,4 @@ try { catch (Exception $e) { error_log ($e); notFound (); -} - - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/epubreader.php b/epubreader.php index f865914..7b916bb 100644 --- a/epubreader.php +++ b/epubreader.php @@ -1,27 +1,33 @@ + + getFilePath ("EPUB", $idData)); $book->initSpineComponent (); ?> - - COPS's Epub Reader - - - - " media="screen" /> - " media="screen" /> + + + + " media="screen" /> + " media="screen" /> " media="screen" /> @@ -37,14 +36,8 @@ $book->initSpineComponent (); getContents: function () { contents ())) . "];"; ?> }, - getComponent: function (componentId, callback) { - $.ajax({ - url: "epubfs.php?comp=" + componentId, - type: 'get', - dataType: 'text', - error: function () {alert ("error");}, - success: callback - }); + getComponent: function (componentId) { + return { url: "epubfs.php?comp=" + componentId }; }, getMetaData: function(key) { return { From 7f74a172f63754063f27b9f61a670554e3230ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 11 Sep 2013 13:59:30 +0200 Subject: [PATCH 24/33] Change page with keyboard. --HG-- extra : rebase_source : 15d0fc7283e1cab0dcccfe1483d8085f0c2e3309 --- cops-monocle.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cops-monocle.js b/cops-monocle.js index 222187f..1fdbef6 100644 --- a/cops-monocle.js +++ b/cops-monocle.js @@ -41,6 +41,21 @@ Monocle.DEBUG = true; 'resize', function () { window.reader.resized() } ); + + Monocle.Events.listen(window.top.document, 'keyup', function(evt) { + var eventCharCode = evt.charCode || evt.keyCode; + var dir = null; + var flipper = reader.Flipper; + if (eventCharCode == 33 || eventCharCode == 37) { // Page down or Left arrow + dir = -1; + } else if (eventCharCode == 34 || eventCharCode == 39 ) { // Page down or Right arrow + dir = 1; + } + if (dir) { + reader.moveTo({ direction: dir }); + evt.preventDefault(); + } + }); /* MAGNIFIER CONTROL */ var magnifier = new Monocle.Controls.Magnifier(reader); From 3ca4996a41d660ec7bb0485153622bc1e3278bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 23 Oct 2013 16:27:09 +0200 Subject: [PATCH 25/33] Fix some trailing white space. --HG-- extra : rebase_source : 9e4b2ab2381d261b3562f2e4a5c56c7e0e1c7ed7 --- resources/php-epub-meta/epub.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index f30754a..0490604 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -5,11 +5,11 @@ * @author Andreas Gohr * @author Sébastien Lucas */ - + require_once(realpath( dirname( __FILE__ ) ) . '/tbszip.php'); define ("METADATA_FILE", "META-INF/container.xml"); - + class EPub { public $xml; //FIXME change to protected, later public $toc; @@ -26,12 +26,13 @@ class EPub { * Constructor * * @param string $file path to epub file to work on + * @param string $zipClass class to handle zip * @throws Exception if metadata could not be loaded */ - public function __construct($file){ + public function __construct($file, $zipClass = 'clsTbsZip'){ // open file $this->file = $file; - $this->zip = new clsTbsZip(); + $this->zip = new $zipClass(); if(!$this->zip->Open($this->file)){ throw new Exception('Failed to read epub file'); } @@ -40,7 +41,7 @@ class EPub { if (!$this->zip->FileExists(METADATA_FILE)) { throw new Exception ("Unable to find metadata.xml"); } - + $data = $this->zip->FileRead(METADATA_FILE); if($data == false){ throw new Exception('Failed to access epub container data'); @@ -56,7 +57,7 @@ class EPub { if (!$this->zip->FileExists($this->meta)) { throw new Exception ("Unable to find " . $this->meta); } - + $data = $this->zip->FileRead($this->meta); if(!$data){ throw new Exception('Failed to access epub metadata'); @@ -67,7 +68,7 @@ class EPub { $this->xml->formatOutput = true; $this->xpath = new EPubDOMXPath($this->xml); } - + public function initSpineComponent () { $spine = $this->xpath->query('//opf:spine')->item(0); From 62941ccb4b1397018f4913b96421f87090db5d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Wed, 23 Oct 2013 16:39:02 +0200 Subject: [PATCH 26/33] Merge with current github, fix trailing spaces, and tab->space. --HG-- extra : rebase_source : ad44a915f7c4880ee8f4ffc406e97c8fc142ac82 --- resources/php-epub-meta/epub.php | 157 +++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 51 deletions(-) diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index 0490604..deade16 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -74,18 +74,18 @@ class EPub { $spine = $this->xpath->query('//opf:spine')->item(0); $tocid = $spine->getAttribute('toc'); $tochref = $this->xpath->query("//opf:manifest/opf:item[@id='$tocid']")->item(0)->attr('href'); - $tocpath = $this->getFullPath ($tochref); + $tocpath = $this->getFullPath ($tochref); // read epub toc if (!$this->zip->FileExists($tocpath)) { throw new Exception ("Unable to find " . $tocpath); } - + $data = $this->zip->FileRead($tocpath); $this->toc = new DOMDocument(); $this->toc->registerNodeClass('DOMElement','EPubDOMElement'); $this->toc->loadXML($data); $this->toc_xpath = new EPubDOMXPath($this->toc); - $rootNamespace = $this->toc->lookupNamespaceUri($this->toc->namespaceURI); + $rootNamespace = $this->toc->lookupNamespaceUri($this->toc->namespaceURI); $this->toc_xpath->registerNamespace('x', $rootNamespace); } @@ -95,7 +95,7 @@ class EPub { public function file(){ return $this->file; } - + /** * Close the epub file */ @@ -124,7 +124,7 @@ class EPub { $this->download (); $this->zip->close(); } - + /** * Get the updated epub */ @@ -150,7 +150,7 @@ class EPub { } return $spine; } - + /** * Get the component content */ @@ -160,11 +160,11 @@ class EPub { if (!$this->zip->FileExists($path)) { throw new Exception ("Unable to find " . $path); } - + $data = $this->zip->FileRead($path); return $data; } - + public function getComponentName ($comp, $elementPath) { $path = str_replace ("-SLASH-", "/", $comp); $path = $this->getFullPath ($path, $elementPath); @@ -180,7 +180,7 @@ class EPub { } return str_replace ("/", "-SLASH-", $path); } - + /** * Get the component content type */ @@ -195,7 +195,7 @@ class EPub { $src = str_replace ("/", "-SLASH-", $src); return array("title" => $title, "src" => $src); } - + /** * Get the Epub content (TOC) as an array * @@ -206,7 +206,7 @@ class EPub { $nodes = $this->toc_xpath->query('//x:ncx/x:navMap/x:navPoint'); foreach($nodes as $node){ $contents[] = $this->getNavPointDetail ($node); - + $insidenodes = $this->toc_xpath->query('x:navPoint', $node); foreach($insidenodes as $insidenode){ $contents[] = $this->getNavPointDetail ($insidenode); @@ -214,7 +214,7 @@ class EPub { } return $contents; } - + /** * Get or set the book author(s) * @@ -328,6 +328,61 @@ class EPub { return $this->getset('dc:description',$description); } + /** + * Set or get the book's Unique Identifier + * + * @param string Unique identifier + */ + public function Uuid($uuid = false) + { + $nodes = $this->xpath->query('/opf:package'); + if ($nodes->length !== 1) { + $error = sprintf('Cannot find ebook identifier'); + throw new Exception($error); + } + $identifier = $nodes->item(0)->attr('unique-identifier'); + + $res = $this->getset('dc:identifier', $uuid, 'id', $identifier); + + return $res; + } + + /** + * Set or get the book's creation date + * + * @param string Date eg: 2012-05-19T12:54:25Z + */ + public function CreationDate($date = false) + { + $res = $this->getset('dc:date', $date, 'opf:event', 'creation'); + + return $res; + } + + /** + * Set or get the book's modification date + * + * @param string Date eg: 2012-05-19T12:54:25Z + */ + public function ModificationDate($date = false) + { + $res = $this->getset('dc:date', $date, 'opf:event', 'modification'); + + return $res; + } + + /** + * Set or get the book's URI + * + * @param string URI + */ + public function Uri($uri = false) + { + $res = $this->getset('dc:identifier', $uri, 'opf:scheme', 'URI'); + + return $res; + } + /** * Set or get the book's ISBN number * @@ -354,7 +409,7 @@ class EPub { public function Amazon($amazon=false){ return $this->getset('dc:identifier',$amazon,'opf:scheme','AMAZON'); } - + /** * Set or get the Calibre UUID of the book * @@ -372,7 +427,7 @@ class EPub { public function Serie($serie=false){ return $this->getset('opf:meta',$serie,'name','cops:series','content'); } - + /** * Set or get the Serie Index of the book * @@ -381,7 +436,7 @@ class EPub { public function SerieIndex($serieIndex=false){ return $this->getset('opf:meta',$serieIndex,'name','cops:series_index','content'); } - + /** * Set or get the book's subjects (aka. tags) * @@ -502,11 +557,11 @@ class EPub { 'found' => $path ); } - + public function getCoverItem () { $nodes = $this->xpath->query('//opf:metadata/opf:meta[@name="cover"]'); if(!$nodes->length) return NULL; - + $coverid = (String) $nodes->item(0)->attr('opf:content'); if(!$coverid) return NULL; @@ -515,43 +570,43 @@ class EPub { return $nodes->item(0); } - + public function Combine($a, $b) - { - $isAbsolute = false; - if ($a[0] == "/") - $isAbsolute = true; + { + $isAbsolute = false; + if ($a[0] == "/") + $isAbsolute = true; - if ($b[0] == "/") - throw new InvalidArgumentException("Second path part must not stwar with " . $m_Separator); - - $splittedA = split("/", $a); - $splittedB = split("/", $b); + if ($b[0] == "/") + throw new InvalidArgumentException("Second path part must not start with " . $m_Separator); - $pathParts = array(); - $mergedPath = array_merge($splittedA, $splittedB); + $splittedA = split("/", $a); + $splittedB = split("/", $b); - foreach($mergedPath as $item) - { - if ($item == null || $item == "" || $item == ".") - continue; + $pathParts = array(); + $mergedPath = array_merge($splittedA, $splittedB); - if ($item == "..") - { - array_pop($pathParts); - continue; - } + foreach($mergedPath as $item) + { + if ($item == null || $item == "" || $item == ".") + continue; - array_push($pathParts, $item); - } + if ($item == "..") + { + array_pop($pathParts); + continue; + } + + array_push($pathParts, $item); + } + + $path = implode("/", $pathParts); + if ($isAbsolute) + return("/" . $path); + else + return($path); + } - $path = implode("/", $pathParts); - if ($isAbsolute) - return("/" . $path); - else - return($path); - } - private function getFullPath ($file, $context = NULL) { $path = dirname('/'.$this->meta).'/'.$file; $path = ltrim($path,'\\'); @@ -562,14 +617,14 @@ class EPub { //error_log ("FullPath : $path ($file / $context)"); return $path; } - + public function updateForKepub () { $item = $this->getCoverItem (); if (!is_null ($item)) { $item->attr('opf:properties', 'cover-image'); } } - + public function Cover2($path=false, $mime=false){ $hascover = true; $item = $this->getCoverItem (); @@ -582,7 +637,7 @@ class EPub { $this->coverpath = ltrim($this->coverpath,'\\'); $this->coverpath = ltrim($this->coverpath,'/'); } - + // set cover if($path !== false){ if (!$hascover) return; // TODO For now only update @@ -596,7 +651,7 @@ class EPub { $this->reparse(); } - + if (!$hascover) return $this->no_cover(); } From 1d2e37d2593ca554e742e349e6d330066a99bfd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Sat, 11 Jan 2014 18:48:10 +0100 Subject: [PATCH 27/33] Integrate better monocle in COPS --HG-- extra : rebase_source : 9132076c5553d0a2a7c550e7f3523b922e52b693 --- JSON_renderer.php | 5 ++++- templates/default/bookdetail.html | 3 +++ templates/default/main.html | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/JSON_renderer.php b/JSON_renderer.php index 130395a..8e63a67 100644 --- a/JSON_renderer.php +++ b/JSON_renderer.php @@ -72,10 +72,13 @@ class JSONRenderer $out ["datas"] = array (); $dataKindle = $book->GetMostInterestingDataToSendToKindle (); foreach ($book->getDatas() as $data) { - $tab = array ("id" => $data->id, "format" => $data->format, "url" => $data->getHtmlLink (), "mail" => 0); + $tab = array ("id" => $data->id, "format" => $data->format, "url" => $data->getHtmlLink (), "mail" => 0, "readerUrl" => ""); if (!empty ($config['cops_mail_configuration']) && !is_null ($dataKindle) && $data->id == $dataKindle->id) { $tab ["mail"] = 1; } + if ($data->format == "EPUB") { + $tab ["readerUrl"] = "epubreader.php?data={$data->id}&db=0"; //TODO fix the database + } array_push ($out ["datas"], $tab); } $out ["authors"] = array (); diff --git a/templates/default/bookdetail.html b/templates/default/bookdetail.html index 9049978..b9ed403 100644 --- a/templates/default/bookdetail.html +++ b/templates/default/bookdetail.html @@ -12,6 +12,9 @@ {{? data.mail == 1}} {{?}} + {{? data.readerUrl != ""}} + + {{?}}
{{~}} diff --git a/templates/default/main.html b/templates/default/main.html index 063d594..bcbd614 100644 --- a/templates/default/main.html +++ b/templates/default/main.html @@ -32,7 +32,7 @@
-

{{=htmlspecialchars (entry.title)}} +

{{=htmlspecialchars (entry.title)}} {{? entry.book.pubDate != ""}}({{=entry.book.pubDate}}){{?}} {{? entry.book.rating != ""}}{{=entry.book.rating}}{{?}}

From 3eb719cb027ad1cbe766caadc3ba78335917edb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Sat, 11 Jan 2014 18:51:07 +0100 Subject: [PATCH 28/33] Move monocle scripts to styles directory --HG-- extra : rebase_source : c645c75c9df6055050f6b3a4fcabb980a860a4d1 --- epubreader.php | 4 ++-- cops-monocle.css => styles/cops-monocle.css | 0 cops-monocle.js => styles/cops-monocle.js | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename cops-monocle.css => styles/cops-monocle.css (100%) rename cops-monocle.js => styles/cops-monocle.js (100%) diff --git a/epubreader.php b/epubreader.php index 0aa19a0..1c2aaea 100644 --- a/epubreader.php +++ b/epubreader.php @@ -48,8 +48,8 @@ $book->initSpineComponent (); } - - " media="screen" /> + + " media="screen" />
diff --git a/cops-monocle.css b/styles/cops-monocle.css similarity index 100% rename from cops-monocle.css rename to styles/cops-monocle.css diff --git a/cops-monocle.js b/styles/cops-monocle.js similarity index 100% rename from cops-monocle.js rename to styles/cops-monocle.js From 6d57778dc74e78268384fa30e887bb7f0a6ffdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Sat, 11 Jan 2014 18:56:54 +0100 Subject: [PATCH 29/33] it's working in multidatabase --HG-- extra : rebase_source : 3fc7d4958dfa971bf9f18354c4c98254ec2b82cf --- JSON_renderer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/JSON_renderer.php b/JSON_renderer.php index 8e63a67..4f3531e 100644 --- a/JSON_renderer.php +++ b/JSON_renderer.php @@ -65,6 +65,7 @@ class JSONRenderer public static function getFullBookContentArray ($book) { global $config; $out = self::getBookContentArray ($book); + $database = GetUrlParam (DB); $out ["coverurl"] = Data::getLink ($book, "jpg", "image/jpeg", Link::OPDS_IMAGE_TYPE, "cover.jpg", NULL)->hrefXhtml (); $out ["thumbnailurl"] = Data::getLink ($book, "jpg", "image/jpeg", Link::OPDS_THUMBNAIL_TYPE, "cover.jpg", NULL, NULL, $config['cops_html_thumbnail_height'] * 2)->hrefXhtml (); @@ -77,7 +78,7 @@ class JSONRenderer $tab ["mail"] = 1; } if ($data->format == "EPUB") { - $tab ["readerUrl"] = "epubreader.php?data={$data->id}&db=0"; //TODO fix the database + $tab ["readerUrl"] = "epubreader.php?data={$data->id}&db={$database}"; } array_push ($out ["datas"], $tab); } From 8a678a620f0713770d278e6eae021229df26b589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Mon, 13 Jan 2014 21:43:44 +0100 Subject: [PATCH 30/33] Fix hash handling --- epubfs.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/epubfs.php b/epubfs.php index c86c571..76c71bd 100644 --- a/epubfs.php +++ b/epubfs.php @@ -34,18 +34,18 @@ try { $callback = function ($m) use ($book, $component, $add) { $method = $m[1]; $path = $m[2]; + $end = ""; + if (preg_match ("/^src:/", $method)) { + $end = ")"; + } if (preg_match ("/^#/", $path)) { - return $path; + return "{$method}'{$path}'{$end}"; } $hash = ""; if (preg_match ("/^(.+)#(.+)$/", $path, $matches)) { $path = $matches [1]; $hash = "#" . $matches [2]; } - $end = ""; - if (preg_match ("/^src:/", $method)) { - $end = ")"; - } $comp = $book->getComponentName ($component, $path); if (!$comp) return "#"; return str_replace ("&", "&", "{$method}'epubfs.php?{$add}comp={$comp}{$hash}'{$end}"); From 90ffaeda77975769974120a61013221b020f1d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Mon, 13 Jan 2014 22:21:01 +0100 Subject: [PATCH 31/33] Fix the url in CSS when there's not space. Properly test the component before accessing it Don't handle & if handling src:url --- epubfs.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/epubfs.php b/epubfs.php index 76c71bd..f6f5a92 100644 --- a/epubfs.php +++ b/epubfs.php @@ -21,12 +21,13 @@ $book = new EPub ($myBook->getFilePath ("EPUB", $idData)); $book->initSpineComponent (); -$component = $_GET["comp"]; - -if (empty ($component)) { +if (!isset ($_GET["comp"])) { notFound (); + return; } +$component = $_GET["comp"]; + try { $data = $book->component ($component); $directory = dirname ($component); @@ -48,13 +49,17 @@ try { } $comp = $book->getComponentName ($component, $path); if (!$comp) return "#"; - return str_replace ("&", "&", "{$method}'epubfs.php?{$add}comp={$comp}{$hash}'{$end}"); + $out = "{$method}'epubfs.php?{$add}comp={$comp}{$hash}'{$end}"; + if ($end) { + return $out; + } + return str_replace ("&", "&", $out); }; $data = preg_replace_callback ("/(src=)[\"']([^:]*?)[\"']/", $callback, $data); $data = preg_replace_callback ("/(href=)[\"']([^:]*?)[\"']/", $callback, $data); $data = preg_replace_callback ("/(\@import\s+)[\"'](.*?)[\"'];/", $callback, $data); - $data = preg_replace_callback ("/(src:\s+url\()(.*?)\)/", $callback, $data); + $data = preg_replace_callback ("/(src:\s*url\()(.*?)\)/", $callback, $data); $expires = 60*60*24*14; header("Pragma: public"); From 00c25fb9fb3f67144830056ab7f1a9dd005612a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Mon, 13 Jan 2014 22:31:03 +0100 Subject: [PATCH 32/33] Fix another case of missing file. --- epubfs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epubfs.php b/epubfs.php index f6f5a92..26cc481 100644 --- a/epubfs.php +++ b/epubfs.php @@ -48,7 +48,7 @@ try { $hash = "#" . $matches [2]; } $comp = $book->getComponentName ($component, $path); - if (!$comp) return "#"; + if (!$comp) return "{$method}'#'{$end}"; $out = "{$method}'epubfs.php?{$add}comp={$comp}{$hash}'{$end}"; if ($end) { return $out; From 6fdb0dfd584599839ca6c390a4e9c717737acb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Tue, 14 Jan 2014 18:03:22 +0100 Subject: [PATCH 33/33] Handle more cleanly the / and - replacement. --- resources/php-epub-meta/epub.php | 33 +++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/resources/php-epub-meta/epub.php b/resources/php-epub-meta/epub.php index deade16..e44d6cd 100644 --- a/resources/php-epub-meta/epub.php +++ b/resources/php-epub-meta/epub.php @@ -146,7 +146,7 @@ class EPub { $nodes = $this->xpath->query('//opf:spine/opf:itemref'); foreach($nodes as $node){ $idref = $node->getAttribute('idref'); - $spine[] = str_replace ("/", "-SLASH-", $this->xpath->query("//opf:manifest/opf:item[@id='$idref']")->item(0)->getAttribute('href')); + $spine[] = $this->encodeComponentName ($this->xpath->query("//opf:manifest/opf:item[@id='$idref']")->item(0)->getAttribute('href')); } return $spine; } @@ -155,10 +155,10 @@ class EPub { * Get the component content */ public function component($comp) { - $path = str_replace ("-SLASH-", "/", $comp); + $path = $this->decodeComponentName ($comp); $path = $this->getFullPath ($path); if (!$this->zip->FileExists($path)) { - throw new Exception ("Unable to find " . $path); + throw new Exception ("Unable to find {$path} <{$comp}>"); } $data = $this->zip->FileRead($path); @@ -166,7 +166,7 @@ class EPub { } public function getComponentName ($comp, $elementPath) { - $path = str_replace ("-SLASH-", "/", $comp); + $path = $this->decodeComponentName ($comp); $path = $this->getFullPath ($path, $elementPath); if (!$this->zip->FileExists($path)) { error_log ("Unable to find " . $path); @@ -178,21 +178,40 @@ class EPub { if (strlen ($ref) > 0) { $path = str_replace ($ref . "/", "", $path); } - return str_replace ("/", "-SLASH-", $path); + return $this->encodeComponentName ($path); } + /** + * Encode the component name (to replace / and -) + */ + private function encodeComponentName ($src) { + return str_replace (array ("/", "-"), + array ("~SLASH~", "~DASH~"), + $src); + } + + /** + * Decode the component name (to replace / and -) + */ + private function decodeComponentName ($src) { + return str_replace (array ("~SLASH~", "~DASH~"), + array ("/", "-"), + $src); + } + + /** * Get the component content type */ public function componentContentType($comp) { - $comp = str_replace ("-SLASH-", "/", $comp); + $comp = $this->decodeComponentName ($comp); return $this->xpath->query("//opf:manifest/opf:item[@href='$comp']")->item(0)->getAttribute('media-type'); } private function getNavPointDetail ($node) { $title = $this->toc_xpath->query('x:navLabel/x:text', $node)->item(0)->nodeValue; $src = $this->toc_xpath->query('x:content', $node)->item(0)->attr('src'); - $src = str_replace ("/", "-SLASH-", $src); + $src = $this->decodeComponentName ($src); return array("title" => $title, "src" => $src); }