X-Git-Url: https://git.mdrn.pl/wl-mobile.git/blobdiff_plain/8b7b42d45674861437a31e9f9125a277ce998721..6e087a91530a9731db6dd4b41bf69eda3409c0e9:/assets/www/js/catalogue.js diff --git a/assets/www/js/catalogue.js b/assets/www/js/catalogue.js index db9c069..615f30f 100644 --- a/assets/www/js/catalogue.js +++ b/assets/www/js/catalogue.js @@ -1,340 +1,27 @@ -// FIXME: htmlescape strings! - -var VERSION = '0.1'; - - -var FileRepo = new function() { - /* API for files repository */ - var self = this; - const WL_URL = 'http://www.wolnelektury.pl'; - this.root = null; - - this.init = function(success, error) { - self.initRoot(success); - }; - - this.initRoot = function(success) { - // fs size is irrelevant, PERSISTENT is futile (on Android, at least) - window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function(fs) { - console.log('local fs found: ' + fs.root.fullPath); - self.root = fs.root; - success && success(); - }, function() { - console.log('local fs not found'); - success && success(); - }); - }; - - - this.withLocalHtml = function(book_id, success, error) { - console.log('info:withLocalHtml: id:' + book_id); - View.spinner('Otwieranie treści utworu'); - if (!self.root) - error && error('info:withLocalHtml: no local html: no usable filesystem'); - - var url = "file://" + self.root.fullPath + "/html/" + book_id; - console.log('info:withLocalHtml: local ajax: ' + url); - var xhr = new XMLHttpRequest(); - xhr.open('GET', url, true); - xhr.onload = function() { - console.log('info:withLocalHtml: fetched by local ajax: ' + url); - success && success(xhr.responseText); - } - xhr.onerror = error; - xhr.send(); - }; - - - // downloads HTML file from server, saves it in cache and calls success with file contents - this.withHtmlFromServer = function(book_id, success, error) { - console.log('info:withHtmlFromServer: id:' + book_id); - // read file from WL - Catalogue.withBook(book_id, function(book) { - var url = WL_URL + book.html_file; - console.log('info:withHtmlFromServer: fetching url: ' + url); - - View.spinner("Pobieranie treści utworu z sieci"); - - if (self.root) { - window.plugins.downloader.downloadFile(url, self.root.fullPath + "/html/", ""+book_id, true, - function(data){ - console.log('info:withHtmlFromServer: loaded file from WL'); - self.withLocalHtml(book_id, success, error); - }, function(data) { - console.log('error downloading file!') - error && error("error: "+data); - }); - } - else { - // there's no big fs, so we'll just get the text from AJAX - console.log('info:withHtmlFromServer: ajax: ' + url); - var xhr = new XMLHttpRequest(); - xhr.open(url); - xhr.onload = function() { - console.log('info:withHtmlFromServer: fetched by ajax: ' + url); - success && success(xhr.responseText); - } - xhr.send(); - } - }); - }; - - // calls the callback with contents of the HTML file for a given book, - // loaded from the server and cached locally - this.withHtml = function(id, success, error) { - console.log('info:withHtml: id:' + id); - self.withLocalHtml(id, success, function() { - self.withHtmlFromServer(id, success, error); - }); - }; -}; - - -var View = new function() { - var self = this; - self.minOffset = 1000; - //self.element - self.categories = { - autor: 'Autorzy', - rodzaj: 'Rodzaje', - gatunek: 'Gatunki', - epoka: 'Epoki' - }; - - - self.init = function() { - console.log('View.init'); - - self.viewStack = []; - self.current; - navigator.app.overrideBackbutton(); - document.addEventListener("backbutton", View.goBack, true); - - self._searchbox = document.getElementById("searchbox"); - self._searchinput = document.getElementById("search"); - self._content = document.getElementById("content"); - - self.enter(location.href); - }; - - - this.sanitize = function(text) { - return text.replace(/&/g, "&").replace(/"; - scroll(0, 0); - }; - - this.content = function(text) { - console.log('content'); - - self._content.innerHTML = ''; - self._content.innerHTML = text; - scroll(0, 0); - } - - this.enter = function(url) { - console.log('View.enter: ' + url); - - self.current = url; - var view = 'Index'; - var arg = null; - - var query_start = url.indexOf('?'); - if (query_start != -1) { - var slash_index = url.indexOf('/', query_start + 1); - if (slash_index != -1) { - view = url.substr(query_start + 1, slash_index - query_start - 1); - arg = url.substr(slash_index + 1); - } - else { - view = url.substr(query_start + 1); - } - } - console.log('View.enter: ' + view + ' ' + arg); - self['enter' + view](arg); - } - - this.enterIndex = function(arg) { - console.log('enterIndex'); - self.showSearch(); - var html = "
"; - for (category in self.categories) - html += self.a('Category', category) + self.categories[category] + "\n"; - html += "
" + - ""; - self.content(html); - }; - - this.enterBook = function(id) { - id = parseInt(id); - console.log('enterBook: ' + id); - self.showSearch(); - - Catalogue.withBook(id, function(book) { - Catalogue.withChildren(id, function(children) { - Catalogue.withAuthors(id, function(authors) { - var html = "

"; - var auths = []; - for (a in authors) auths.push(authors[a].name); - html += auths.join(", "); - html += "" + book.title + "

\n"; - if (book.html_file) { - html += "

" + self.a('BookText', id) + "Czytaj tekst

"; - } - if (children.length) { - html += "
"; - for (c in children) { - child = children[c]; - html += self.a('Book', child.id) + child.title + "\n"; - } - html += "
"; - } - self.content(html); - }); - }); - }); - } - - this.enterBookText = function(id) { - id = parseInt(id); - self.spinner("Otwieranie utworu"); - console.log('enterBookText: ' + id); - self.hideSearch(); - - FileRepo.withHtml(id, function(data) { - self.content(data); - }); - } - - this.enterTag = function(id) { - id = parseInt(id); - console.log('enterTag: ' + id); - self.showSearch(); - - self.spinner("Otwieranie listy utworów"); - - Catalogue.withTag(id, function(tag) { - var html = "

" + tag.category + ': ' + tag.name + "

\n"; - html += "
"; - if (tag._books) { - Catalogue.withBooks(tag._books, function(books) { - for (var i in books) { - var book = books[i]; - html += self.a('Book', book.id) + book.title + "\n"; - } - html += "
"; - self.content(html); - }); - } - }); - }; - - - this.enterCategory = function(category) { - console.log('enterCategory: ' + category); - self.spinner("Otwieranie katalogu"); - self.showSearch(); - - Catalogue.withCategory(category, function(tags) { - var html = "

" + self.categories[category] + "

\n"; - html += "
"; - for (i in tags) { - tag = tags[i]; - html += self.a('Tag', tag.id) + tag.name + "\n"; - } - html += "
"; - self.content(html); - }); - }; - - +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ - this.enterSearch = function(query) { - console.log('enterTag: ' + query); - self.showSearch(); +var DB_VER = '0.9.15'; - var html = "

Szukana fraza:" + View.sanitize(query) + "

\n"; +var WL_INITIAL = WL + '/media/api/mobile/initial/initial.db'; +var WL_UPDATE = WL + '/api/changes/SINCE.json?book_fields=author,html,parent,parent_number,sort_key,title' + + '&tag_fields=books,category,name,sort_key' + + '&tag_categories=author,epoch,genre,kind'; - if (query.length < 2) { - html += "

Szukana fraza musi mieć co najmniej dwa znaki

"; - self.content(html); - return; - } - Catalogue.withSearch(query, function(results) { - if (results.length == 1) { - self.enter(self.href(results[0].view, results[0].id)); - return; - } - if (results.length == 0) { - html += "

Brak wyników wyszukiwania

"; - } - else { - html += "
"; - for (var i in results) { - var result = results[i]; - html += self.a(result.view, result.id) + result.label + "\n"; - } - html += "
"; - } - self.content(html); - }); - }; +var categories = {'author': 'autor', + 'epoch': 'epoka', + 'genre': 'gatunek', + 'kind': 'rodzaj', + 'theme': 'motyw' + } - /* search form submit callback */ - this.search = function() { - self.goTo('?Search/' + self._searchinput.value); - return false; - } - - - this.href = function(view, par) { - return "?"+view+"/"+par; - }; - - this.a = function(view, par) { - return ""; - }; - - this.goTo = function(url) { - self.viewStack.push(self.current); - console.log('goTo: ' + url); - self.enter(url); - }; - - this.goBack = function() { - if (self.viewStack.length > 0) { - var url = self.viewStack.pop(); - console.log('goBack: ' + url); - self.enter(url); - } - else { - console.log('exiting'); - navigator.app.exitApp(); - } - }; -} +// FIXME: htmlescape strings! -/* // for preparing sql statements // use like: // var s = new Sql("INSERT ... '{0}', '{1}' ..."; @@ -350,10 +37,10 @@ var Sql = function(scheme) { self.prepare = function() { var args = arguments; return self.text.replace(/{(\d+)}/g, function(match, number) { - return self.sql_escape(args[number]); + return self.sql_escape(args[parseInt(number)]); }); } -};*/ +}; var Catalogue = new function() { @@ -396,86 +83,79 @@ var Catalogue = new function() { /* check if DB needs updating and upload a fresh copy, if so */ this.updateDB = function(success, error) { - var db_ver = '0.1.4'; - if (window.localStorage.getItem('db_ver') == db_ver) { + var has_ver = window.localStorage.getItem('db_ver'); + if (has_ver == DB_VER) { console.log('db ok, skipping') success && success(); return; } var done = function() { - window.localStorage.setItem('db_ver', db_ver); + FileRepo.clear(); + window.localStorage.setItem('db_ver', DB_VER); console.log('db updated'); success && success(); }; // db initialize // this is Android-specific for now - var version = device.version.split('.')[0]; - switch(version) { - case '1': - self.upload_db_android1(done, error); - break; - case '2': - self.upload_db_android2(done, error); - break; - case '3': - default: - error && error('Błąd migracji: ' + err); + var android = device.version.split('.')[0]; + if (android > 1) { + self.upload_db_android(done, error); + } else { + error && error("Nieobsługiwana wersja systemu. Wymagany Android>=2.0."); }; }; - this.upload_db_android1 = function(success, error) { - console.log('upload db for Android 1.x'); - window.requestFileSystem(LocalFileSystem.APPLICATION, 0, function(fs) { - window.plugins.assetcopy.copy("initial/wolnelektury.db", - fs.root.fullPath + "/databases/wolnelektury.db", true, - function(data) { - console.log('db upload successful'); - success && success(); - }, function(data) { - error && error("database upload error: " + data); - }); - }, error); + this.upload_db_android = function(success, error) { + // TODO: this should be downloaded from teh net, not stored in res + + console.log('upload db for Android 2.x+'); + // upload databases description file + + var dbname = "wolnelektury"; + var db = window.openDatabase(dbname, "1.0", "WL Catalogue", 500000); + if (db) { + console.log('db created successfully'); + DBPut.fetch(WL_INITIAL, function(data) { + console.log('db fetch successful'); + success && success(); + }, function(data) { + error && error('Błąd podczas pobierania bazy danych: ' + data); + }); + } else { + error && error('Błąd podczas inicjowania bazy danych: ' + data); + } }; - this.upload_db_android2 = function(success, error) { - console.log('upload db for Android 2.x'); - window.requestFileSystem(LocalFileSystem.APPLICATION, 0, function(fs) { - - // upload databases description file - window.plugins.assetcopy.copy("initial/Databases.db", - fs.root.fullPath + "/app_database/Databases.db", true, - function(data) { - console.log('db descriptior upload successful'); - - // upload the database file - window.plugins.assetcopy.copy("initial/0000000000000001.db", - fs.root.fullPath + "/app_database/file__0/0000000000000001.db", true, - function(data) { - console.log('db upload successful'); - success && success(); - }, function(data) { - error && error("database upload error: " + data); - }); - - - }, function(data) { - error && error("database descriptor upload error: " + data); + this.withState = function(callback) { + self.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM state", [], + function(tx, results) { + if (results.rows.length) { + callback(results.rows.item(0)); + } + else { + callback({last_checked: 0}); + } }); - - }, error); + }); }; - this.withBook = function(id, callback) { + this.withBook = function(id, callback, error) { console.log('withBook '+id) self.db.transaction(function(tx) { tx.executeSql("SELECT * FROM book WHERE id="+id, [], function(tx, results) { - callback(results.rows.item(0)); + if (results.rows.length) { + callback(results.rows.item(0)); + } + else { + error && error(); + } }); }); }; @@ -483,7 +163,7 @@ var Catalogue = new function() { this.withBooks = function(ids, callback) { console.log('withBooks ' + ids) self.db.transaction(function(tx) { - tx.executeSql("SELECT * FROM book WHERE id IN ("+ids+") ORDER BY title", [], + tx.executeSql("SELECT * FROM book WHERE id IN ("+ids+") ORDER BY sort_key", [], function(tx, results) { var items = []; var count = results.rows.length; @@ -495,29 +175,11 @@ var Catalogue = new function() { }); }; - this.withAuthors = function(id, callback) { - console.log('withAuthors ' + id); - self.db.transaction(function(tx) { - tx.executeSql("SELECT t.name " + - "FROM book_tag bt LEFT JOIN tag t ON t.id=bt.tag " + - "WHERE bt.book="+id+" AND t.category='autor' " + - "ORDER BY t.sort_key", [], - function(tx, results) { - var tags = []; - var count = results.rows.length; - for (var i=0; i