· 8 years ago · Dec 01, 2017, 03:24 PM
1angular.module('sabisMobile.bookShelf')
2
3 .factory('bookService', function ($http, $q, $rootScope, $cordovaFile, $cordovaDevice, $state, $timeout, $interval, $cordovaSQLite, databaseService, userInfoService, storageService, storage, encryptionService, loggerService, ENV, $window) {
4 var bookService = this;
5
6 bookService.bookItems = {};
7 bookService.bookItems.booklist = [];
8 bookService.unfinishedBooks = [];
9 bookService.isReading = false;
10 bookService.shouldCheckAnnotations = false;
11 bookService.currentBookMetadataModifiedAt = '';
12 bookService.annotations = [];
13 var booklistInterval;
14
15 bookService.getDefinition = function (bookid) {
16 var filename = 'definition_file';
17 var extension = 'json';
18 var deferred = $q.defer();
19
20 $http.get(storage.server + '/books/' + bookid + '/definition/' + filename + '/' + extension, { timeout: 15000 })
21 .success(function (success) {
22 deferred.resolve(success);
23 }).error(function (error) {
24 loggerService.logError('bookService', 'getDefinition', error);
25 deferred.reject(error);
26 });
27
28 return deferred.promise;
29 };
30
31 bookService.startBooklistInterval = function () {
32 var deferred = $q.defer();
33 bookService.getBookListFromServer()
34 .then(function () {
35 booklistInterval = $interval(function () {
36 if (storage.loginMode == 'online') {
37 bookService.getBookListFromServer()
38 .then(function (result) {
39 console.log('Booklist interval updated the booklist!');
40 }, function (error) {
41 console.log(error);
42 });
43 }
44 }, 180000);
45 deferred.resolve();
46 }, function (error) {
47 console.log(error);
48 deferred.reject(error);
49 });
50
51 return deferred.promise;
52 };
53
54 bookService.stopBooklistInterval = function () {
55 $interval.cancel(booklistInterval);
56 };
57
58 //TODO: Revert
59
60 bookService.getBookListFromServer = function () {
61 var deferred = $q.defer();
62 var currentUserId = storage.getItem('uniqueId');
63
64 $http.get(storage.server + '/books/booklist/', {
65 headers: { 'Authorization': 'Bearer ' + storage.getItem('accessToken') },
66 timeout: 15000
67 })
68 .success(function (success) {
69 var pathToSave = '';
70 if (storage.storageMode == 'internal') {
71 pathToSave = storage.path;
72 } else if (storage.storageMode == 'sdcard') {
73 pathToSave = storage.altPath;
74 }
75 var encryptedBookList = encryptionService.encryptBookList(JSON.stringify(success));
76 // var decodedBookList = new TextDecoder().decode(encryptedBookList);
77 window.resolveLocalFileSystemURL(pathToSave, function (fileDirectory) {
78 fileDirectory.getFile('booklist.json', { create: true, exclusive: false }, function (fileEntry) {
79 fileEntry.createWriter(function (fileWriter) {
80 fileWriter.write(encryptedBookList.buffer);
81 fileWriter.onwriteend = function () {
82 bookService.bookItems.booklist = success;
83 deferred.resolve(success);
84 };
85 });
86 });
87 });
88 // $cordovaFile.writeFile(pathToSave, 'booklist.json', decodedBookList, true)
89 // .then(function (result) {
90 // bookService.bookItems.booklist = success;
91 // deferred.resolve(success);
92 // }, function (error) {
93 // loggerService.logError('bookService', 'getBookList', error);
94 // });
95
96 }).error(function (error) {
97 loggerService.logError('bookService', 'getBookList', error);
98 deferred.reject(error);
99 });
100 return deferred.promise;
101 };
102
103 bookService.getBookList = function () {
104 var deferred = $q.defer();
105 var currentUserId = storage.getItem('uniqueId');
106
107 var pathToRead = '';
108 if (storage.storageMode == 'internal') {
109 pathToRead = storage.path;
110 } else if (storage.storageMode == 'sdcard') {
111 pathToRead = storage.altPath;
112 }
113
114 // if (storage.loginMode == 'online') {
115 // bookService.getBookListFromServer()
116 // .then(function (result) {
117 // deferred.resolve(result);
118 // }, function (error) {
119 $cordovaFile.readAsArrayBuffer(pathToRead, 'booklist.json')
120 .then(function (result) {
121 // var key = $cordovaDevice.getUUID() + storage.getItem('userId');
122 // encryptionService.decryptFile('', 'booklist.json', key)
123 // .then(function (result) {
124 // var decodedResult = Base64.decode(result);
125 var decryptedBooklist = encryptionService.decryptBookList(result);
126 bookService.bookItems.booklist = JSON.parse(decryptedBooklist);
127 deferred.resolve(JSON.parse(decryptedBooklist));
128
129 // }, function (error) {
130 // console.log(error);
131 // deferred.reject(error);
132 // });
133 }, function (error) {
134 loggerService.logError('bookService', 'getBookList->getBookListFromServer->readAsText', error);
135 deferred.reject(error);
136 });
137 // loggerService.logError('bookService', 'getBookList->getBookListFromServer', error);
138 // });
139 // } else {
140 // $cordovaFile.readAsText(storage.path, 'booklist.json')
141 // .then(function (result) {
142 // // var key = $cordovaDevice.getUUID() + storage.getItem('userId');
143 // // encryptionService.decryptFile('', 'booklist.json', key)
144 // // .then(function (result) {
145 // bookService.bookItems.booklist = JSON.parse(result);
146 // deferred.resolve(JSON.parse(result));
147 // // }, function (error) {
148 // // console.log(error);
149 // // deferred.reject(error);
150 // // });
151 // }, function (error) {
152 // if (error.message) {
153 // loggerService.logError('bookService', 'getBookList->readAsText', error.message);
154 // } else {
155 // loggerService.logError('bookService', 'getBookList->readAsText', error);
156 // }
157 // deferred.reject(error);
158 // });
159 // }
160
161 return deferred.promise;
162 };
163
164 bookService.getBookFiles = function (bookId) {
165 var deferred = $q.defer();
166
167 $http.get(storage.server + '/books/book-files/' + bookId, {
168 headers: { 'Authorization': 'Bearer ' + storage.getItem('accessToken') },
169 timeout: 15000
170 })
171 .success(function (success) {
172 deferred.resolve(success);
173 }).error(function (error) {
174 if (error && error.message) {
175 loggerService.logInfo('bookService', 'getBookFiles', 'book id: ' + bookId);
176 loggerService.logInfo('bookService', 'getBookFiles', 'endpoint: ' + storage.server + '/books/book-files/' + bookId);
177 loggerService.logError('bookService', 'getBookFiles', error.message);
178 deferred.reject(error.message);
179 } else if (error && error.Message) {
180 loggerService.logInfo('bookService', 'getBookFiles', 'book id: ' + bookId);
181 loggerService.logInfo('bookService', 'getBookFiles', 'endpoint: ' + storage.server + '/books/book-files/' + bookId);
182 loggerService.logError('bookService', 'getBookFiles', error.Message);
183 deferred.reject(error.Message);
184 } else {
185 loggerService.logInfo('bookService', 'getBookFiles', 'book id: ' + bookId);
186 loggerService.logInfo('bookService', 'getBookFiles', 'endpoint: ' + storage.server + '/books/book-files/' + bookId);
187 loggerService.logError('bookService', 'getBookFiles', error);
188 deferred.reject(error);
189 }
190 });
191
192 return deferred.promise;
193 };
194
195 bookService.getBookIndex = function (bookId) {
196 var deferred = $q.defer();
197
198 bookService.getBookList()
199 .then(function (booklist) {
200 bookService.getBookDefinition(bookId)
201 .then(function (bookResult) {
202 booklist.forEach(function (currentBook, bookIndex, bookArray) {
203 if (currentBook.Identifier == bookId) {
204 $cordovaFile.createDir(storage.path, 'books', true)
205 .then(function (result) {
206 // storageService.createDirectoryAndFile('books/', currentBook.Identifier, 'book.json', bookResult)
207 // .then(function (result) {
208 var decoded = new TextDecoder().decode(bookResult);
209 // var decoded = String.fromCodePoint.apply(null, new Uint8Array(result));
210 // decoded = decoded + '}';
211 decoded = JSON.parse(decoded);
212 decoded.byteLength = bookResult.byteLength;
213 deferred.resolve(decoded);
214 // });
215 }, function (error) {
216 loggerService.logError('bookService', 'getBookIndex->getBookDefinition->createDir', error);
217 });
218 }
219 });
220 }, function (error) {
221 loggerService.logError('bookService', 'getBookIndex->getBookDefinition', error);
222 deferred.reject(error);
223 });
224 }, function (error) {
225 loggerService.logError('bookService', 'getBookIndex', error);
226 deferred.reject(error);
227 });
228
229 return deferred.promise;
230 };
231
232 // bookService.getThumbnails = function (bookid, index) {
233 // var deferred = $q.defer();
234 // var currentUserId = userInfoService.userinfo.uniqueUserId;
235 // $http.get(storage.server + '/books/' + bookid + '/thumbs/page-1/jpeg', { responseType: 'arraybuffer' })
236 // .success(function (success) {
237 // deferred.resolve(success, index);
238 // }).error(function (error) {
239 // deferred.reject(error);
240 // });
241
242 // return deferred.promise;
243 // };
244
245 bookService.getBookInfo = function () {
246 // var bookDefinitions = bookService.getBookDefinitions();
247
248 var deferred = $q.defer();
249
250
251 bookService.getBooksFromDb()
252 .then(function (books) {
253 var booksToUpdate = [];
254
255 bookService.bookItems.booklist.forEach(function (currentBook, bookIndex, bookArray) {
256 // var bookItem = {};
257 // var bookFound = false;
258 // bookItem.Subject = currentBook.Subject;
259 // bookItem.Size = currentBook.Size;
260 // bookItem.Identifier = currentBook.Identifier;
261
262 if (currentBook.IsReleased === false) {
263 bookService.bookItems.booklist[bookIndex].shouldShow = false;
264 } else {
265 bookService.bookItems.booklist[bookIndex].shouldShow = true;
266 }
267
268 bookService.bookItems.booklist[bookIndex].IsReleased = currentBook.IsReleased;
269
270 books.forEach(function (currentDbBook, dbBookIndex, dbBookArray) {
271 if (currentBook.Identifier == currentDbBook.bookIdentifier) {
272 bookService.bookItems.booklist[bookIndex].Status = currentDbBook.status;
273 bookService.bookItems.booklist[bookIndex].amountOpened = currentDbBook.amountOpened;
274 bookService.bookItems.booklist[bookIndex].path = currentDbBook.storage;
275 bookService.bookItems.booklist[bookIndex].totalSize = currentDbBook.totalSize;
276 bookService.bookItems.booklist[bookIndex].downloadedOnce = currentDbBook.downloadedOnce;
277 bookService.bookItems.booklist[bookIndex].batchDownloaded = currentDbBook.batchDownloaded;
278
279 if (currentDbBook.progress !== undefined) {
280 bookService.bookItems.booklist[bookIndex].Progress = currentDbBook.progress;
281 }
282 if (bookService.bookItems.booklist[bookIndex].ModifiedAt !== currentDbBook.modifiedAt && currentDbBook.modifiedAt !== null || currentDbBook.isUpdate) {
283 bookService.bookItems.booklist[bookIndex].IsNew = false;
284 bookService.bookItems.booklist[bookIndex].hasUpdate = true;
285 } else if (currentDbBook.status !== null && currentDbBook.status == 'Downloaded') {
286 bookService.bookItems.booklist[bookIndex].hasUpdate = false;
287 }
288
289 if (!currentBook.IsReleased && currentDbBook.status !== null && currentDbBook.status == 'Downloaded') {
290 bookService.bookItems.booklist[bookIndex].shouldShow = true;
291 }
292
293 if (currentDbBook.isUpdate !== undefined) {
294 bookService.bookItems.booklist[bookIndex].isUpdate = currentDbBook.isUpdate;
295 }
296
297 if ((currentDbBook.lastDownloadedPage && currentDbBook.lastDownloadedPage > 0) || (currentDbBook.batchDownloaded && currentDbBook.batchDownloaded == 1) || currentDbBook.isUpdate === true) {
298 bookService.bookItems.booklist[bookIndex].isReadable = true;
299 }
300 // bookFound = true;
301 }
302 });
303
304 if (bookService.bookItems.booklist[bookIndex].hasUpdate === true && currentBook.IsReleased === false) {
305 bookService.bookItems.booklist[bookIndex].shouldShowUpdateControls = false;
306 } else {
307 bookService.bookItems.booklist[bookIndex].shouldShowUpdateControls = true;
308 }
309
310 if (!bookService.bookItems.booklist[bookIndex].Status) {
311 bookService.bookItems.booklist[bookIndex].Status = 'Available';
312 bookService.bookItems.booklist[bookIndex].IsNew = true;
313 }
314
315 // booksToUpdate.push(bookItem);
316 });
317
318 deferred.resolve();
319 // debugger;
320 // bookService.bookItems.booklist = angular.copy(booksToUpdate);
321 }, function (error) {
322 loggerService.logError('bookService', 'getBookInfo->getBookList->getAvailableStorage->getBooksFromDb', error);
323 });
324
325 return deferred.promise;
326 };
327
328 bookService.getBookDefinitions = function (booklist) {
329 var bookDefinitions = [];
330
331 booklist.forEach(function (book, array, index) {
332 bookService.getBookDefinition(book.Identifier)
333 .then(function (result) {
334 // TODO: Get all books from both storages and compare them with booklist, also write the context
335
336 bookDefinitions.push(result);
337 }, function (error) {
338 loggerService.logError('bookService', 'getBookDefinitions->getBookDefinition', error);
339 console.log(error);
340 });
341 });
342
343 return bookDefinitions;
344 };
345
346 bookService.getBookDefinition = function (bookId) {
347 var deferred = $q.defer();
348
349 $http({
350 method: "GET",
351 url: storage.server + '/books/' + bookId + '/book/json',
352 responseType: 'arraybuffer',
353 timeout: 15000
354 })
355 .success(function (success) {
356 deferred.resolve(success);
357 }).error(function (error) {
358 loggerService.logError('bookService', 'getBookDefinition', error);
359 deferred.reject(error);
360 });
361
362 return deferred.promise;
363 };
364
365 bookService.getThumbnails = function (bookid, coverFile) {
366 var deferred = $q.defer();
367 var currentUserId = storage.getItem('uniqueId');
368 $http.get(storage.server + '/books/' + bookid + '/' + /[^.]+/.exec(coverFile) + '/' + /[^.]+$/.exec(coverFile), { responseType: 'arraybuffer' })
369 .success(function (success) {
370 success.bookId = bookid;
371 deferred.resolve(success);
372 }).error(function (error) {
373 loggerService.logError('bookService', 'getThumbnails', error);
374 deferred.reject(error);
375 });
376
377 return deferred.promise;
378 };
379
380 bookService.getBooksFromStorage = function (storage) {
381 var deferred = $q.defer();
382 storageService.getDirectories(storage)
383 .then(function (directories) {
384 storageService.getFiles(directories)
385 .then(function (bookDefinitions) {
386 deferred.resolve(bookDefinitions);
387 });
388 });
389 return deferred.promise;
390 };
391
392 bookService.getBooksFromPrimaryStorage = function () {
393
394 };
395
396 bookService.getBooksFromAlternativeStorage = function () {
397
398 };
399
400 bookService.getLocalBookDefinitions = function () {
401 var bookDefinitions = [];
402
403 storageService.getDirectories(storage.path)
404 .then(function (directories) {
405 directories.forEach(function (currentDirectory, directoryIndex, directoryArray) {
406
407 });
408 }, function (error) {
409
410 });
411 };
412
413 bookService.getLocalBookList = function () {
414 var deferred = $q.defer();
415
416 $cordovaFile.readAsText(storage.path, 'booklist.json')
417 .then(function (booklist) {
418 var booklistJson = JSON.parse(booklist);
419 deferred.resolve(booklistJson);
420 }, function (error) {
421 deferred.reject(error);
422 });
423
424 return deferred.promise;
425 };
426
427 //Repository Service
428 bookService.getBooksFromDb = function () {
429 var deferred = $q.defer();
430 var allDownloads = repositoryService.getAllModels('downloads');
431 var allUpdates = repositoryService.getAllModels('updates');
432
433 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=?', [storage.getItem('uniqueId')])
434 // .then(function (result) {
435 // var allDownloads = [];
436 // for (var i = 0; i < result.rows.length; i++) {
437 // allDownloads.push(result.rows.item(i));
438 // }
439
440 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM updates WHERE userId=?', [storage.getItem('uniqueId')])
441 // .then(function (result) {
442 // var allUpdates = [];
443 // for (var i = 0; i < result.rows.length; i++) {
444 // allUpdates.push(result.rows.item(i));
445 // }
446
447 // var downloadsAndUpdates = [];
448
449 // allDownloads.forEach(function (currentDownload, downloadIndex, downloadArray) {
450 // var fileToAdd = currentDownload;
451 // var found = false;
452 // allUpdates.forEach(function (currentUpdate, updateIndex, updateArray) {
453 // if (currentUpdate.userId === currentDownload.userId && currentUpdate.bookIdentifier === currentDownload.bookIdentifier) {
454 // fileToAdd = currentUpdate;
455 // fileToAdd.amountOpened = currentDownload.amountOpened;
456 // fileToAdd.storage = currentDownload.storage;
457 // fileToAdd.batchDownloaded = currentDownload.batchDownloaded;
458 // fileToAdd.annotationsModifiedAt = currentDownload.annotationsModifiedAt;
459 // fileToAdd.isUpdate = true;
460 // found = true;
461 // }
462 // });
463
464 // if (!found) {
465 // fileToAdd.isUpdate = false;
466 // }
467
468 // downloadsAndUpdates.push(fileToAdd);
469 // });
470
471 // deferred.resolve(downloadsAndUpdates);
472 // }, function (error) {
473 // console.log(error);
474 // });
475 // }, function (error) {
476 // console.log(error);
477 // });
478
479
480 var downloadsAndUpdates = [];
481
482 allDownloads.forEach(function (currentDownload, downloadIndex, downloadArray) {
483 var fileToAdd = currentDownload;
484 var found = false;
485 allUpdates.forEach(function (currentUpdate, updateIndex, updateArray) {
486 if (currentUpdate.userId === currentDownload.userId && currentUpdate.bookIdentifier === currentDownload.bookIdentifier) {
487 fileToAdd = currentUpdate;
488 fileToAdd.amountOpened = currentDownload.amountOpened;
489 fileToAdd.storage = currentDownload.storage;
490 fileToAdd.batchDownloaded = currentDownload.batchDownloaded;
491 fileToAdd.annotationsModifiedAt = currentDownload.annotationsModifiedAt;
492 fileToAdd.isUpdate = true;
493 found = true;
494 }
495 });
496
497 if (!found) {
498 fileToAdd.isUpdate = false;
499 }
500 downloadsAndUpdates.push(fileToAdd);
501 });
502 deferred.resolve(downloadsAndUpdates);
503 return deferred.promise;
504 };
505
506 bookService.readBooklist = function () {
507 var deferred = $q.defer();
508
509 //TODO: If storage is changed, booklist must be redownloaded
510 var pathToRead = '';
511 if (storage.storageMode == 'internal') {
512 pathToRead = storage.path;
513 } else if (storage.storageMode) {
514 pathToRead = storage.altPath;
515 }
516 $cordovaFile.readAsText(pathToRead, 'booklist.json')
517 .then(function (booklist) {
518 var booklistJson = JSON.parse(booklist);
519 bookService.getBooksFromDb()
520 .then(function (booksFromDb) {
521 booklistJson.forEach(function (currentBook, bookIndex, bookArray) {
522 booksFromDb.forEach(function (currentDbBook, dbBookIndex, dbBookArray) {
523 if (currentBook.Identifier == currentDbBook.bookIdentifier) {
524 booklistJson[bookIndex].Status = currentDbBook.status;
525 }
526 });
527 if (!booklistJson[bookIndex].Status) {
528 booklistJson[bookIndex].Status = 'Available';
529 }
530 });
531 deferred.resolve(booklistJson);
532 }, function (error) {
533 console.log(error);
534 });
535 }, function (error) {
536 console.log(error);
537 });
538
539 return deferred.promise;
540 };
541
542 bookService.updateLastPageVisited = function (bookId, page) {
543 var deferred = $q.defer();
544 var downloadForUser = repositoryService.updateEntityProperty('downloads', bookid, 'lastVisitedPage', page);
545 if (!downloadForUser) {
546 deferred.reject('Book not found.');
547 } else {
548 deferred.resolve(downloadForUser);
549 }
550
551 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
552 // .then(function (result) {
553 // if (result.rows.length > 0) {
554 // $cordovaSQLite.execute(databaseService.db, 'UPDATE downloads SET lastVisitedPage=? WHERE id=?', [page, result.rows.item(0).id])
555 // .then(function (result) {
556 // deferred.resolve(result.rows.item(0));
557 // }, function (error) {
558 // deferred.reject(error);
559 // });
560 // } else {
561 // deferred.reject('Book not found.');
562 // }
563 // }, function (error) {
564 // console.log(error);
565 // deferred.reject(error);
566 // });
567
568 return deferred.promise;
569 };
570
571 //Repository Service
572 bookService.getLastPageVisited = function (bookId) {
573 var deferred = $q.defer();
574 var downloadModel = repositoryService.getModelByIdentifier('downloads', bookId);
575 if (downloadModel) {
576 deferred.resolve(downloadModel.lastVisitedPage);
577 } else {
578 deferred.reject('Download model was not found');
579 }
580
581 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
582 // .then(function (result) {
583 // if (result.rows.length > 0) {
584 // deferred.resolve(result.rows.item(0).lastVisitedPage);
585 // } else {
586 // deferred.resolve(0);
587 // }
588 // }, function (error) {
589 // console.log(error);
590 // deferred.reject(error);
591 // });
592
593 return deferred.promise;
594 };
595
596 //Repository Service
597 bookService.updateAmountOpened = function (bookId) {
598 var deferred = $q.defer();
599 var downloadModel = repositoryService.getModelByIdentifier('downloads', bookId);
600 if (!downloadModel) {
601 deferred.reject('No books found to update amount of times opened!');
602 } else {
603 var amountOpened = downloadModel.amountOpened;
604 amountOpened += 1;
605 downloadModel.amountOpened = amountOpened;
606 repositoryService.addOrUpdateEntity('downloads', downloadModel, downloadModel[downloadsModel.UNIQUE_ID]);
607 deferred.resolve(amountOpened);
608 }
609
610
611 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
612 // .then(function (result) {
613 // if (result.rows.length > 0) {
614 // var amountToUpdateTo = result.rows.item(0).amountOpened + 1;
615 // $cordovaSQLite.execute(databaseService.db, 'UPDATE downloads SET amountOpened=? WHERE id=?', [amountToUpdateTo, result.rows.item(0).id])
616 // .then(function (result) {
617 // deferred.resolve(amountToUpdateTo);
618 // }, function (error) {
619 // console.log(error);
620 // deferred.reject(error);
621 // });
622 // } else {
623 // deferred.reject('No books found to update amount of times opened!');
624 // }
625 // }, function (error) {
626 // console.log(error);
627 // deferred.reject(error);
628 // });
629
630 return deferred.promise;
631 };
632
633 bookService.renameProperty = function (object, oldName, newName) {
634 if (oldName == newName) {
635 return object;
636 }
637 if (object.hasOwnProperty(oldName)) {
638 object[newName] = object[oldName];
639 delete object[oldName];
640 }
641 return object;
642 };
643
644 bookService.preparePartialBookForPlayer = function (book) {
645 var deferred = $q.defer();
646
647 $cordovaFile.readAsText(book.path + 'books/' + book.Identifier, 'book.json')
648 .then(function (bookJson) {
649 // var decodedJson = new TextDecoder().decode(decryptedJson);
650 // decodedJson = decodedJson + '}';
651 bookJson = JSON.parse(bookJson);
652
653 window.storagePath = book.path + 'books/' + book.Identifier + '/';
654
655 $rootScope.playerDim = true;
656
657 $state.go('mainAuth.player');
658
659 var playerCheck = function () {
660 $timeout(function () {
661 // Check if player exists every 500 ms
662 if (window.frames['sabis-player'].sabisBookPlayer) {
663 $rootScope.playerDim = false;
664 var sabisBookPlayer = window.frames['sabis-player'].sabisBookPlayer;
665 var bookId = book.Identifier;
666 sabisBookPlayer.onPageChanged(function (pageId) {
667 var pageId = pageId;
668 bookService.updateLastPageVisited(bookId, pageId)
669 .then(function (result) {
670 console.log('Updated last visited page to ' + pageId);
671 }, function (error) {
672 console.log(error);
673 });
674 });
675
676 var userMetadata = '';
677 // bookService.annotations.forEach(function (currentAnnotation) {
678 // if (book.Identifier == currentAnnotation.BookIdentifier) {
679 // userMetadata = currentAnnotation.Body;
680 // }
681 // });
682
683 $cordovaFile.readAsText(book.path + 'books/' + book.Identifier + '/', 'annotations.json')
684 .then(function (result) {
685 userMetadata = result;
686
687 if (book.batchDownloaded == 1) {
688 initializePlayerWithBatch(book, bookJson, sabisBookPlayer, userMetadata);
689 } else {
690 initializePlayer(book, bookJson, sabisBookPlayer, userMetadata);
691 }
692 }, function (error) {
693 if (book.batchDownloaded == 1) {
694 initializePlayerWithBatch(book, bookJson, sabisBookPlayer, '{}');
695 } else {
696 initializePlayer(book, bookJson, sabisBookPlayer, '{}');
697 }
698 });
699 } else {
700 playerCheck();
701 }
702 }, 500);
703 };
704
705 playerCheck();
706 }, function (error) {
707 console.log(error);
708 deferred.reject();
709 });
710
711 return deferred.promise;
712 };
713
714 function sendPageToPlayer(book, page, sabisBookPlayer) {
715 return function () {
716 var deferred = $q.defer();
717
718 $cordovaFile.readAsText(book.path + 'books/' + book.Identifier, 'page-' + page + '.json')
719 .then(function (pageJson) {
720
721 var jsonPage = JSON.parse(pageJson);
722
723 encryptionService.decryptFileFromUri(book.path + 'books/' + book.Identifier, 'page-' + page + '.html', book.PrivateKey)
724 .then(function (pageContent) {
725 var decodedPageContent = new TextDecoder().decode(pageContent);
726 decodedPageContent = decodedPageContent;
727
728 sabisBookPlayer.playerHtmlPageInit(decodedPageContent, page);
729 sabisBookPlayer.playerJsonPageInit(jsonPage, page);
730 console.log('Initialized page ' + page);
731 // pages.splice(0, 1);
732 deferred.resolve(page);
733
734 // if (pages.length == pages[0]) {
735 // bookService.startReadingBook(book.Identifier, pages[0]);
736 // }
737 }, function (error) {
738 console.log(error);
739 deferred.reject(error);
740 });
741 }, function (error) {
742 console.log(error);
743 deferred.reject(error);
744 });
745
746 return deferred.promise;
747 };
748 }
749
750 function initializePlayer(book, bookJson, sabisBookPlayer, userMetadata) {
751 sabisBookPlayer.zone.run(function () {
752 sabisBookPlayer.playerBookJsonInit(bookJson, book.path + 'books/' + book.Identifier + '/', userMetadata);
753 });
754
755 getLastDownloadedPage(book.Identifier)
756 .then(function (lastPage) {
757 var pages = [];
758 var lastPage = lastPage;
759 for (var i = 0; i < lastPage; i++) {
760 pages.push(i + 1);
761 }
762
763 pages.forEach(function (currentPage, pageIndex, pageArray) {
764 $cordovaFile.readAsText(book.path + 'books/' + book.Identifier, 'page-' + (pageIndex + 1) + '.json')
765 .then(function (pageJson) {
766 // var decodedPageJson = new TextDecoder().decode(decryptedPageJson);
767 // decodedPageJson = decodedPageJson + '}';
768
769 var jsonPage = JSON.parse(pageJson);
770
771 encryptionService.decryptFileFromUri(book.path + 'books/' + book.Identifier, 'page-' + (pageIndex + 1) + '.html', book.PrivateKey)
772 .then(function (pageContent) {
773 var decodedPageContent = new TextDecoder().decode(pageContent);
774
775 // sabisBookPlayer.zone.run(function () {
776 sabisBookPlayer.playerHtmlPageInit(decodedPageContent, bookJson.pages[pageIndex].id);
777 sabisBookPlayer.playerJsonPageInit(jsonPage, bookJson.pages[pageIndex].id);
778 console.log('Initialized page ' + (pageIndex + 1));
779 // });
780 if (pages.length == (pageIndex + 1)) {
781
782 bookService.startReadingBook(book.Id, book.Identifier, (pageIndex + 1));
783 bookService.updateAmountOpened(book.Identifier)
784 .then(function (result) {
785 console.log('Book has been opened ' + result + ' times');
786 }, function (error) {
787 console.log(error);
788 });
789 bookService.getLastPageVisited(book.Identifier)
790 .then(function (lastPageVisited) {
791 if (lastPageVisited && lastPageVisited > 0) {
792 sabisBookPlayer.navigateToPage(lastPageVisited);
793 } else {
794 sabisBookPlayer.navigateToPage(1);
795 }
796 }, function (error) {
797 console.log(error);
798 });
799 }
800 }, function (error) {
801 console.log(error);
802 });
803 }, function (error) {
804 console.log(error);
805 });
806 });
807 }, function (error) {
808 console.log(error);
809 });
810 }
811
812 function initializePlayerWithBatch(book, bookJson, sabisBookPlayer, userMetadata) {
813 sabisBookPlayer.zone.run(function () {
814 sabisBookPlayer.playerBookJsonInit(bookJson, book.path + 'books/' + book.Identifier + '/', userMetadata);
815 });
816
817 encryptionService.decryptFileFromUri(book.path + 'books/' + book.Identifier, 'pageHtmlBatch.json', book.PrivateKey)
818 .then(function (decryptedHtmlArray) {
819 encryptionService.decryptFileFromUri(book.path + 'books/' + book.Identifier, 'pageJsonBatch.json', book.PrivateKey)
820 .then(function (decryptedJsonArray) {
821 var decodedHtmlArray = new TextDecoder().decode(decryptedHtmlArray);
822 var decodedJsonArray = new TextDecoder().decode(decryptedJsonArray);
823 var htmlArray = JSON.parse(decodedHtmlArray);
824 var jsonArray = JSON.parse(decodedJsonArray);
825
826 htmlArray.forEach(function (currentHtml, htmlIndex) {
827 bookService.renameProperty(htmlArray[htmlIndex], 'Id', 'pageId');
828 bookService.renameProperty(htmlArray[htmlIndex], 'Content', 'pageData');
829 });
830
831 jsonArray.forEach(function (currentJson, jsonIndex) {
832 bookService.renameProperty(jsonArray[jsonIndex], 'Id', 'pageId');
833 bookService.renameProperty(jsonArray[jsonIndex], 'Content', 'pageData');
834 });
835
836 sabisBookPlayer.playerBatchHtmlPageInit(htmlArray);
837 sabisBookPlayer.playerBatchJsonPageInit(jsonArray);
838
839 bookService.startReadingBook(book.Id, book.Identifier, htmlArray.length);
840 bookService.updateAmountOpened(book.Identifier)
841 .then(function (result) {
842 console.log('Book has been opened ' + result + ' times');
843 }, function (error) {
844 console.log(error);
845 });
846 bookService.getLastPageVisited(book.Identifier)
847 .then(function (lastPageVisited) {
848 if (lastPageVisited && lastPageVisited > 0) {
849 sabisBookPlayer.navigateToPage(lastPageVisited);
850 } else {
851 sabisBookPlayer.navigateToPage(1);
852 }
853 }, function (error) {
854 console.log(error);
855 });
856 }, function (error) {
857 console.log(error);
858 deferred.reject(error);
859 });
860 }, function (error) {
861 console.log(error);
862 deferred.reject(error);
863 });
864 }
865
866 bookService.stopReadingBook = function () {
867 //TODO: Implement this
868 bookService.currentlyReadingBook = {};
869 bookService.isReading = false;
870 };
871
872 bookService.startReadingBook = function (id, identifier, page) {
873 //TODO: Implement this
874 bookService.currentlyReadingBook = {
875 identifier: identifier,
876 id: id,
877 page: page
878 };
879 bookService.isReading = true;
880
881 //TODO: call bookService.checkForAnnotationChanges()
882 bookService.checkForAnnotationChanges();
883 //sabisBookPlayer.playerBookJsonInit(bookJson, storage.path + 'books/' + book.Identifier + '/', userMetadata);
884 };
885
886 bookService.checkPagesForPlayer = function (bookDownload) {
887 if (window.frames['sabis-player'] && window.frames['sabis-player'].sabisBookPlayer && bookService.isReading === true && bookService.currentlyReadingBook.identifier == bookDownload.id) {
888 var sabisBookPlayer = window.frames['sabis-player'].sabisBookPlayer;
889 var pages = [];
890 for (var i = (parseInt(bookService.currentlyReadingBook.page) + 1); i <= bookDownload.page; i++) {
891 pages.push(i);
892 }
893
894 bookService.currentlyReadingBook.page = bookDownload.page;
895
896 var chain = $q.when();
897
898 pages.forEach(function (currentPage, pageIndex, pageArray) {
899 bookService.bookItems.booklist.forEach(function (currentBook, bookIndex, bookArray) {
900 if (currentBook.Identifier == bookDownload.id) {
901 chain = chain.then(sendPageToPlayer(currentBook, currentPage, sabisBookPlayer));
902 }
903 });
904 });
905 }
906 };
907
908 bookService.checkBooks = function () {
909 var deferred = $q.defer();
910
911 var sequence = $q.defer();
912 sequence.resolve();
913 sequence = sequence.promise;
914
915 bookService.getBookList()
916 .then(function (booklist) {
917
918 // ewq
919 var books = {};
920 var counter = 0;
921 var booksFromServer = {};
922 booklist.forEach(function (currentBooklistItem, booklistItemIndex, booklistItemArray) {
923 var directorySuffix = '';
924
925 checkIfBookIsUpdate(currentBooklistItem.Identifier)
926 .then(function (isBookUpdate) {
927 if (isBookUpdate) {
928 directorySuffix = '-update';
929 }
930
931 checkBookFolder(currentBooklistItem.Identifier + directorySuffix)
932 .then(function (files) {
933 var files = files;
934 if (Object.keys(files).length !== 0 && files.constructor === Object) {
935 bookService.getBookFiles(currentBooklistItem.Identifier)
936 .then(function (bookfiles) {
937 var bookfiles = bookfiles;
938
939 // var collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
940 angular.forEach(bookfiles, function (value, key) {
941 bookfiles[key].sort(function (a, b) {
942 return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
943 }).reverse();
944 });
945
946 if (books[currentBooklistItem.Identifier] === undefined) {
947 books[currentBooklistItem.Identifier] = files;
948 }
949
950 if (booksFromServer[currentBooklistItem.Identifier] === undefined) {
951 booksFromServer[currentBooklistItem.Identifier] = bookfiles;
952 }
953
954
955 compareBookFiles(books[currentBooklistItem.Identifier], booksFromServer[currentBooklistItem.Identifier])
956 .then(function (result) {
957 var shouldAddBook = false;
958 angular.forEach(result, function (value, key) {
959 if (result[key] instanceof Array) {
960 shouldAddBook = true;
961 }
962 });
963 if (shouldAddBook) {
964 var isUpdate = false;
965 if (directorySuffix != '') {
966 isUpdate = true;
967 }
968 var bookToAdd = {
969 Identifier: currentBooklistItem.Identifier,
970 files: result,
971 isUpdate: isUpdate
972 };
973 bookService.unfinishedBooks.push(bookToAdd);
974 console.log(bookToAdd);
975 }
976 }, function (error) {
977 console.log(error);
978 });
979
980 counter++;
981
982 if (counter == booklist.length) {
983 deferred.resolve(books);
984 }
985 }, function (error) {
986 console.log(error);
987 });
988 } else {
989 counter++;
990
991 if (counter == booklist.length) {
992 deferred.resolve(books);
993 }
994 }
995 }, function (error) {
996 console.log(error);
997 });
998 }, function (error) {
999 console.log(error);
1000 });
1001
1002 });
1003 }, function (error) {
1004 console.log(error);
1005 });
1006
1007 return deferred.promise;
1008 };
1009
1010 bookService.cleanBooks = function (directories, storagePath) {
1011 var deferred = $q.defer();
1012
1013 if (directories.length == 0) {
1014 deferred.resolve();
1015 } else {
1016 bookService.getBookList()
1017 .then(function (booklist) {
1018 var counter = 0;
1019 directories.forEach(function (currentDirectory, directoryIndex, directoryArray) {
1020 var found = false;
1021 booklist.forEach(function (currentBookItem, bookItemIndex, bookItemArray) {
1022 if (currentBookItem.Identifier == currentDirectory) {
1023 found = true;
1024 }
1025 });
1026
1027 if (!found) {
1028 $cordovaFile.removeRecursively(storagePath + 'books/', currentDirectory)
1029 .then(function (result) {
1030 counter++;
1031
1032 if (counter == directories.length) {
1033 deferred.resolve();
1034 }
1035 }, function (error) {
1036 console.log(error);
1037 });
1038 } else {
1039 counter++;
1040
1041 if (counter == directories.length) {
1042 deferred.resolve();
1043 }
1044 }
1045 });
1046 }, function (error) {
1047 console.log(error);
1048 deferred.reject(error);
1049 });
1050 }
1051
1052 return deferred.promise;
1053 };
1054
1055 bookService.checkBooksFromStorage = function () {
1056 var deferred = $q.defer();
1057
1058 var booksFromStorage = JSON.parse(localStorage.getItem('books'));
1059 if (!booksFromStorage) {
1060 deferred.resolve();
1061 } else {
1062 bookService.getBooksFromDb()
1063 .then(function (dbBooks) {
1064 angular.forEach(booksFromStorage, function (value, key) {
1065 if (booksFromStorage[key].userId != storage.getItem('userId')) {
1066 // booksFromStorage[key].splice(bookIndex, 1);
1067 delete booksFromStorage[key];
1068 } else {
1069 var dbBookFound = false;
1070 dbBooks.forEach(function (currentDbBook) {
1071 if (booksFromStorage[key] !== undefined && currentDbBook.bookIdentifier == booksFromStorage[key].Identifier) {
1072 dbBookFound = true;
1073 if (currentDbBook.status == 'Downloaded' && !currentDbBook.isUpdate) {
1074 delete booksFromStorage[key];
1075 } else {
1076 booksFromStorage[key].downloadOption = currentDbBook.downloadOption;
1077 }
1078 }
1079 });
1080
1081 if (!dbBookFound) {
1082 delete booksFromStorage[key];
1083 }
1084 }
1085 });
1086
1087 // booksFromStorage.forEach(function (currentBook, bookIndex, bookArray) {
1088 // if (currentBook.userId != localStorage.getItem('userId')) {
1089 // booksFromStorage.splice(bookIndex, 1);
1090 // }
1091 // });
1092
1093 angular.forEach(booksFromStorage, function (value, key) {
1094 angular.forEach(booksFromStorage[key].files, function (fileValue, fileKey) {
1095 if (fileKey != 'missingBytes' && fileKey != 'downloadedSize') {
1096 booksFromStorage[key].files[fileKey].sort(function (a, b) {
1097 return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
1098 }).reverse();
1099 }
1100 });
1101 });
1102
1103 var books = {};
1104 var counter = 0;
1105 var booksFromServer = {};
1106
1107 bookService.getBookList()
1108 .then(function (booklist) {
1109 // qwe
1110 booklist.forEach(function (currentBooklistItem, booklistItemIndex, booklistItemArray) {
1111 if (Object.keys(booksFromStorage).length > 0) {
1112 angular.forEach(booksFromStorage, function (value, key) {
1113 if (key == currentBooklistItem.Identifier + '.' + storage.getItem('userId')) {
1114 var directorySuffix = '';
1115
1116 checkIfBookIsUpdate(currentBooklistItem.Identifier)
1117 .then(function (isBookUpdate) {
1118 if (isBookUpdate) {
1119 directorySuffix = '-update';
1120 }
1121
1122 bookService.getBookFiles(currentBooklistItem.Identifier)
1123 .then(function (bookfiles) {
1124 if (Object.keys(booksFromStorage).length > 0) {
1125 // angular.forEach(bookfiles, function (value, key) {
1126 // bookfiles[key].sort(function (a, b) {
1127 // return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
1128 // }).reverse();
1129 // });
1130
1131 if (books[currentBooklistItem.Identifier] === undefined) {
1132 books[currentBooklistItem.Identifier] = booksFromStorage[key].files;
1133 }
1134
1135 if (booksFromServer[currentBooklistItem.Identifier] === undefined) {
1136 var indicesToSplice = [];
1137 if (booksFromStorage[key].downloadOption == 'zip') {
1138 bookfiles.base.forEach(function (currentItem, itemIndex) {
1139 if (currentItem.name.indexOf('pageHtmlBatch.json') === -1
1140 && currentItem.name.indexOf('pageJsonBatch.json') === -1
1141 && currentItem.name.indexOf('book.json') === -1
1142 && currentItem.name.indexOf('index.json') === -1) {
1143 indicesToSplice.push(itemIndex);
1144 }
1145 });
1146 } else {
1147 bookfiles.base.forEach(function (currentItem, itemIndex) {
1148 if ((/[^.]+$/.exec(currentItem.name)[0] != 'json' && /[^.]+$/.exec(currentItem.name)[0] != 'html')
1149 || (currentItem.name.indexOf('pageHtmlBatch.json') !== -1 && currentItem.name.indexOf('pageJsonBatch.json') !== -1)) {
1150 indicesToSplice.push(itemIndex);
1151 }
1152 });
1153 }
1154 for (var i = indicesToSplice.length - 1; i >= 0; i--) {
1155 bookfiles.base.splice(indicesToSplice[i], 1);
1156 }
1157 booksFromServer[currentBooklistItem.Identifier] = bookfiles;
1158 }
1159
1160 compareBookFiles(books[currentBooklistItem.Identifier], booksFromServer[currentBooklistItem.Identifier])
1161 .then(function (result) {
1162 var shouldAddBook = false;
1163 angular.forEach(result, function (value, key) {
1164 if (result[key] instanceof Array) {
1165 shouldAddBook = true;
1166 }
1167 });
1168 if (shouldAddBook) {
1169 var isUpdate = false;
1170 if (directorySuffix != '') {
1171 isUpdate = true;
1172 }
1173 var bookToAdd = {
1174 Identifier: currentBooklistItem.Identifier,
1175 files: result,
1176 isUpdate: isUpdate
1177 };
1178
1179 bookService.unfinishedBooks.push(bookToAdd);
1180
1181 // console.log(bookToAdd);
1182 }
1183
1184 counter++;
1185 if (counter == Object.keys(booksFromStorage).length) {
1186 deferred.resolve();
1187 }
1188 }, function (error) {
1189 console.log(error);
1190 deferred.reject(error);
1191 });
1192 } else {
1193 deferred.resolve();
1194 }
1195 });
1196 }, function (error) {
1197 console.log(error);
1198 deferred.reject(error);
1199 });
1200 }
1201 });
1202 } else {
1203 deferred.resolve();
1204 }
1205
1206 // booksFromStorage.forEach(function (currentBookFromStorage, bookFromStorageIndex, bookFromStorageArray) {
1207 // if (currentBookFromStorage.Identifier == currentBooklistItem.Identifier) {
1208 // var directorySuffix = '';
1209
1210 // checkIfBookIsUpdate(currentBooklistItem.Identifier)
1211 // .then(function (isBookUpdate) {
1212 // if (isBookUpdate) {
1213 // directorySuffix = '-update';
1214 // }
1215
1216 // bookService.getBookFiles(currentBooklistItem.Identifier)
1217 // .then(function (bookfiles) {
1218 // angular.forEach(bookfiles, function (value, key) {
1219 // bookfiles[key].sort(function (a, b) {
1220 // return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
1221 // }).reverse();
1222 // });
1223
1224 // if (books[currentBooklistItem.Identifier] === undefined) {
1225 // books[currentBooklistItem.Identifier] = currentBookFromStorage.files;
1226 // }
1227
1228 // if (booksFromServer[currentBooklistItem.Identifier] === undefined) {
1229 // booksFromServer[currentBooklistItem.Identifier] = bookfiles;
1230 // }
1231
1232 // compareBookFiles(books[currentBooklistItem.Identifier], booksFromServer[currentBooklistItem.Identifier])
1233 // .then(function (result) {
1234 // var shouldAddBook = false;
1235 // angular.forEach(result, function (value, key) {
1236 // if (result[key] instanceof Array) {
1237 // shouldAddBook = true;
1238 // }
1239 // });
1240 // if (shouldAddBook) {
1241 // var isUpdate = false;
1242 // if (directorySuffix != '') {
1243 // isUpdate = true;
1244 // }
1245 // var bookToAdd = {
1246 // Identifier: currentBooklistItem.Identifier,
1247 // files: result,
1248 // isUpdate: isUpdate
1249 // };
1250
1251 // counter++;
1252 // bookService.unfinishedBooks.push(bookToAdd);
1253 // if (counter == booklist.length - 1) {
1254 // deferred.resolve();
1255 // }
1256 // // console.log(bookToAdd);
1257 // }
1258 // }, function (error) {
1259 // console.log(error);
1260 // deferred.reject(error);
1261 // });
1262 // });
1263 // }, function (error) {
1264 // console.log(error);
1265 // deferred.reject(error);
1266 // });
1267 // }
1268 // });
1269 });
1270 }, function (error) {
1271 console.log(error);
1272 deferred.reject(error);
1273 });
1274 }, function (error) {
1275 deferred.reject(error);
1276 });
1277 }
1278
1279 return deferred.promise;
1280 };
1281
1282 function compareBookFiles(bookFromStorage, bookFromServer) {
1283 var deferred = $q.defer();
1284
1285 var file = {};
1286 file.missingBytes = 0;
1287 file.downloadedSize = 0;
1288 var counter = 0;
1289
1290 if (bookFromStorage.currentlyDownloadingFile && bookFromStorage.currentlyDownloadingFile.name != '' && bookFromStorage.currentlyDownloadingFile.folder != '') {
1291 var fileToDelete = {
1292 shouldBeDeleted: true,
1293 folderToDeleteFrom: bookFromStorage.currentlyDownloadingFile.folder,
1294 name: bookFromStorage.currentlyDownloadingFile.name,
1295 size: 0
1296 };
1297 if (file[bookFromStorage.currentlyDownloadingFile.folder] === undefined) {
1298 file[bookFromStorage.currentlyDownloadingFile.folder] = [];
1299 }
1300 file[bookFromStorage.currentlyDownloadingFile.folder].push(fileToDelete);
1301 }
1302
1303 angular.forEach(bookFromServer, function (serverFiles, serverFolder) {
1304 var folderFound = false;
1305 angular.forEach(bookFromStorage, function (storageFiles, storageFolder) {
1306 if (storageFolder == serverFolder) {
1307 folderFound = true;
1308 serverFiles.forEach(function (currentServerFile, serverFileIndex, serverFileArray) {
1309 var fileFound = false;
1310 var shouldBeDeleted = false;
1311 storageFiles.forEach(function (currentStorageFile, storageFileIndex, storageFileArray) {
1312 if (currentServerFile.name == currentStorageFile.name) {
1313 if (currentServerFile.size == currentStorageFile.size) {
1314 fileFound = true;
1315 file.downloadedSize += currentStorageFile.size;
1316 } else {
1317 shouldBeDeleted = true;
1318 file.missingBytes += currentStorageFile.size;
1319 }
1320 }
1321 });
1322
1323 if (!fileFound) {
1324 // console.log('File ' + currentServerFile.name + ' not found!');
1325 if (file[serverFolder] === undefined) {
1326 file[serverFolder] = [];
1327 }
1328
1329 if (file[serverFolder].indexOf(currentServerFile) === -1) {
1330 if (shouldBeDeleted === true) {
1331 currentServerFile.shouldBeDeleted = true;
1332 currentServerFile.folderToDeleteFrom = storageFolder;
1333 }
1334 file[serverFolder].push(currentServerFile);
1335 }
1336 }
1337 });
1338 }
1339 });
1340
1341 if (!folderFound) {
1342 if (file[serverFolder] === undefined) {
1343 file[serverFolder] = bookFromServer[serverFolder];
1344 }
1345 }
1346
1347 counter++;
1348
1349 if (Object.keys(bookFromServer).length == counter) {
1350 deferred.resolve(file);
1351 }
1352 });
1353
1354 return deferred.promise;
1355 }
1356
1357 bookService.getBookFolders = function () {
1358 var deferred = $q.defer();
1359
1360 //Check if book is update and add -update
1361
1362 $cordovaFile.checkDir(storage.path, 'books')
1363 .then(function (folder) {
1364 var counter = 0;
1365 var directories = [];
1366 var directoryReader = folder.createReader();
1367 directoryReader.readEntries(function (entries) {
1368 var fileCount = entries.length;
1369 if (fileCount == 0) {
1370 $cordovaFile.checkDir(storage.altPath, 'books')
1371 .then(function (altFolder) {
1372 var altCounter = 0;
1373 var altDirectories = [];
1374 var altDirectoryReader = altFolder.createReader();
1375 altDirectoryReader.readEntries(function (altEntries) {
1376 var altFileCount = altEntries.length;
1377 if (altFileCount == 0) {
1378 var result = {
1379 defaultStorage: directories,
1380 altStorage: altDirectories
1381 };
1382 deferred.resolve(result);
1383 }
1384 altEntries.forEach(function (currentAltEntry, altEntryIndex, altEntryArray) {
1385 if (currentAltEntry.isDirectory) {
1386 altDirectories.push(currentAltEntry.name);
1387 }
1388 altCounter++;
1389 if (altCounter == altFileCount) {
1390 var result = {
1391 defaultStorage: directories,
1392 altStorage: altDirectories
1393 };
1394 deferred.resolve(result);
1395 }
1396 });
1397 });
1398 }, function (error) {
1399 console.log(error);
1400 var result = {
1401 defaultStorage: directories,
1402 altStorage: []
1403 };
1404
1405 deferred.resolve(result);
1406 });
1407 }
1408 entries.forEach(function (currentEntry, entryIndex, entryArray) {
1409 if (currentEntry.isDirectory) {
1410 directories.push(currentEntry.name);
1411 }
1412
1413 counter++;
1414 if (counter == fileCount) {
1415 $cordovaFile.checkDir(storage.altPath, 'books')
1416 .then(function (altFolder) {
1417 var altCounter = 0;
1418 var altDirectories = [];
1419 var altDirectoryReader = altFolder.createReader();
1420 altDirectoryReader.readEntries(function (altEntries) {
1421 var altFileCount = altEntries.length;
1422 if (altFileCount == 0) {
1423 var result = {
1424 defaultStorage: directories,
1425 altStorage: altDirectories
1426 };
1427 deferred.resolve(result);
1428 }
1429 altEntries.forEach(function (currentAltEntry, altEntryIndex, altEntryArray) {
1430 if (currentAltEntry.isDirectory) {
1431 altDirectories.push(currentAltEntry.name);
1432 }
1433 altCounter++;
1434 if (altCounter == altFileCount) {
1435 var result = {
1436 defaultStorage: directories,
1437 altStorage: altDirectories
1438 };
1439 deferred.resolve(result);
1440 }
1441 });
1442 });
1443 }, function (error) {
1444 console.log(error);
1445 var result = {
1446 defaultStorage: directories,
1447 altStorage: []
1448 };
1449
1450 deferred.resolve(result);
1451 });
1452 }
1453 });
1454 });
1455 }, function (error) {
1456 console.log(error);
1457 $cordovaFile.checkDir(storage.altPath, 'books')
1458 .then(function (altFolder) {
1459 var altCounter = 0;
1460 var altDirectories = [];
1461 var altDirectoryReader = altFolder.createReader();
1462 altDirectoryReader.readEntries(function (altEntries) {
1463 var altFileCount = altEntries.length;
1464 if (altFileCount == 0) {
1465 var result = {
1466 defaultStorage: [],
1467 altStorage: altDirectories
1468 };
1469 deferred.resolve(result);
1470 }
1471 altEntries.forEach(function (currentAltEntry, altEntryIndex, altEntryArray) {
1472 if (currentAltEntry.isDirectory) {
1473 altDirectories.push(currentAltEntry.name);
1474 }
1475 altCounter++;
1476 if (altCounter == altFileCount) {
1477 var result = {
1478 defaultStorage: [],
1479 altStorage: altDirectories
1480 };
1481 deferred.resolve(result);
1482 }
1483 });
1484 });
1485 }, function (error) {
1486 console.log(error);
1487 var result = {
1488 defaultStorage: [],
1489 altStorage: []
1490 };
1491
1492 deferred.resolve(result);
1493 });
1494 });
1495
1496 return deferred.promise;
1497 };
1498
1499 function checkBookFolder(folder) {
1500 var deferred = $q.defer();
1501
1502 $cordovaFile.checkDir(storage.path + 'books/', folder)
1503 .then(function (folder) {
1504 var directoryReader = folder.createReader();
1505 directoryReader.readEntries(function (entries) {
1506 var files = {};
1507 var filesCount = entries.length;
1508 var counter = 0;
1509 entries.forEach(function (currentEntry, entryIndex, entryArray) {
1510 if (currentEntry.isDirectory) {
1511 var directoryName = currentEntry.name;
1512 counter++;
1513 var innerDirectoryReader = currentEntry.createReader();
1514 innerDirectoryReader.readEntries(function (fileEntries) {
1515 filesCount += fileEntries.length;
1516 fileEntries.forEach(function (currentFileEntry, fileEntryIndex, fileEntryArray) {
1517 if (currentFileEntry.isFile) {
1518 if (files[directoryName] === undefined) {
1519 files[directoryName] = [];
1520 }
1521
1522 currentFileEntry.file(function (file) {
1523 var fileToAdd = {
1524 name: currentFileEntry.name,
1525 size: file.size
1526 };
1527 files[directoryName].push(fileToAdd);
1528
1529 counter++;
1530 if (counter == filesCount) {
1531 // var collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
1532 angular.forEach(files, function (value, key) {
1533 files[key].sort(function (a, b) {
1534 return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
1535 }).reverse();
1536 });
1537 deferred.resolve(files);
1538 }
1539 });
1540
1541 } else {
1542 console.log('This is not a directory.');
1543 }
1544 });
1545 });
1546 } else {
1547 if (files['base'] === undefined) {
1548 files['base'] = [];
1549 }
1550
1551 currentEntry.file(function (file) {
1552
1553 var fileToAdd = {
1554 name: currentEntry.name,
1555 size: file.size
1556 };
1557
1558 files['base'].push(fileToAdd);
1559
1560 counter++;
1561 if (counter == filesCount) {
1562 // var collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
1563 angular.forEach(files, function (value, key) {
1564 files[key].sort(function (a, b) {
1565 return a.name.localeCompare(b.name, 'en', { numeric: true, sensitivity: 'base' });
1566 }).reverse();
1567 });
1568 deferred.resolve(files);
1569 }
1570 });
1571 }
1572 });
1573 }, function (error) {
1574 console.log(error);
1575 deferred.reject(error);
1576 });
1577 }, function (error) {
1578 deferred.resolve({});
1579 });
1580
1581 return deferred.promise;
1582 }
1583
1584 bookService.getUnfinishedBooks = function () {
1585 var unfinishedBooks = angular.copy(bookService.unfinishedBooks);
1586 bookService.unfinishedBooks = [];
1587 return unfinishedBooks;
1588 };
1589
1590 bookService.checkForAnnotationChanges = function () {
1591 //TODO: while bookService.isReading == true (maybe interval, every 10 seconds), get player's last metadata modifiedAt,
1592 //if it's different from bookService.currentBookMetadataModifiedAt, then call bookService.sendAnnotationToServer()
1593 //finally, update bookService.currentBookMetadataModifiedAt and also update annotationsModifiedAt in database and call self on timeout
1594 if (bookService.isReading === true) {
1595 // window.frames['sabis-player'].sabisBookPlayer.getMetadata();
1596 if (window.frames['sabis-player'].sabisBookPlayer) {
1597 var sabisBookPlayer = window.frames['sabis-player'].sabisBookPlayer;
1598
1599 var metadataTimestamp = sabisBookPlayer.getUserDataTimestamp();
1600 if (metadataTimestamp !== undefined && typeof (metadataTimestamp) != 'string') {
1601 // metadataTimestamp = metadataTimestamp.toString();
1602 var annotation = sabisBookPlayer.getUserData();
1603 var currentlyReadingBook = bookService.currentlyReadingBook;
1604 bookService.getAnnotationsFromDb()
1605 .then(function (annotations) {
1606 annotations.forEach(function (currentAnnotation, annotationIndex) {
1607 var dbModifiedAt = new Date(currentAnnotation.modifiedAt);
1608 // dbModifiedAt = dbModifiedAt.toISOString();
1609 if (currentlyReadingBook.identifier && currentAnnotation.bookIdentifier == currentlyReadingBook.identifier && dbModifiedAt < metadataTimestamp) {
1610 bookService.updateBookAnnotation(currentlyReadingBook.identifier, metadataTimestamp.toISOString())
1611 .then(function (result) {
1612 $cordovaFile.writeFile(currentAnnotation.path + 'books/' + currentAnnotation.bookIdentifier + '/', 'annotations.json', annotation, true)
1613 .then(function (result) {
1614 console.log('Annotation saved locally!');
1615
1616 var annotationToSend = {
1617 UserId: storage.getItem('userId'),
1618 BookId: currentlyReadingBook.id,
1619 UserUniqueId: storage.getItem('uniqueId'),
1620 BookIdentifier: currentlyReadingBook.identifier,
1621 ModifiedAt: metadataTimestamp.toISOString(),
1622 Body: annotation
1623 };
1624
1625 bookService.sendAnnotationToServer(annotationToSend)
1626 .then(function (result) {
1627 console.log('Annotation sent to server!');
1628 // bookService.annotations[annotationIndex] = result;
1629 // bookService.currentBookMetadataModifiedAt = result.ModifiedAt;
1630 }, function (error) {
1631 console.log(error);
1632 });
1633 }, function (error) {
1634 console.log(error);
1635 });
1636 }, function (error) {
1637 console.log(error);
1638 });
1639 }
1640 });
1641 }, function (error) {
1642 console.log(error);
1643 });
1644 }
1645 }
1646
1647 $timeout(function () {
1648 if (bookService.isReading === true) {
1649 bookService.checkForAnnotationChanges();
1650 }
1651 }, 500);
1652 }
1653 };
1654
1655 //Repository service
1656 bookService.updateBookAnnotation = function (bookId, modifiedAt) {
1657 var deferred = $q.defer();
1658
1659 var updatedModel = repositoryService.updateEntityProperty('downloads', bookId, 'annotationsModifiedAt', modifiedAt);
1660 if (updatedModel) {
1661 deferred.resolve(result);
1662 } else {
1663 deferred.reject('Error => updateBookAnnotation');
1664 }
1665
1666 // $cordovaSQLite.execute(databaseService.db, 'UPDATE downloads SET annotationsModifiedAt=? WHERE userId=? AND bookIdentifier=?', [modifiedAt, storage.getItem('uniqueId'), bookId])
1667 // .then(function (result) {
1668 // deferred.resolve(result);
1669 // }, function (error) {
1670 // deferred.reject(error);
1671 // });
1672
1673 return deferred.promise;
1674 };
1675
1676 bookService.sendAnnotationToServer = function (annotation) {
1677 var deferred = $q.defer();
1678
1679 $http.post(storage.server + '/annotations/', annotation, { timeout: 15000 })
1680 .then(function (result) {
1681 deferred.resolve(result);
1682 }, function (error) {
1683 deferred.reject(error);
1684 });
1685
1686 return deferred.promise;
1687 };
1688
1689 bookService.updateServerAnnotation = function (annotation) {
1690 var deferred = $q.defer();
1691
1692 $cordovaFile.readAsText(annotation.path + 'books/' + annotation.bookIdentifier + '/', 'annotations.js')
1693 .then(function (result) {
1694 var annotationToSend = {
1695 UserId: storage.getItem('userId'),
1696 BookId: annotation.bookId,
1697 UserUniqueId: storage.getItem('uniqueId'),
1698 BookIdentifier: annotation.bookIdentifier,
1699 ModifiedAt: annotation.annotationsModifiedAt,
1700 Body: result
1701 };
1702
1703 bookService.sendAnnotationToServer(annotationToSend)
1704 .then(function (result) {
1705 deferred.resolve();
1706 }, function (error) {
1707 console.log(error);
1708 });
1709 }, function (error) {
1710 console.log(error);
1711 });
1712
1713 return deferred.promise;
1714 };
1715
1716
1717 //Repository Service
1718 bookService.getAnnotationsFromDb = function () {
1719 var deferred = $q.defer();
1720
1721 var allDownloads = repositoryService.getAllModels('downloads');
1722 if (allDownloads === null) {
1723 deferred.reject('No entities in downloads table');
1724 }
1725 var currentlyDownloadingAndDownloaded = [];
1726 for (var i = 0; i < allDownloads.length; i++) {
1727 if (allDownloads[i].status == 'Downloaded' || allDownloads[i].status == 'Downloading') {
1728 currentlyDownloadingAndDownloaded.push(allDownloads[i])
1729 }
1730 }
1731
1732 var bookAnnotations = [];
1733 for (var i = 0; i < currentlyDownloadingAndDownloaded.length; i++) {
1734 var bookAnnotationObject = {
1735 bookIdentifier: currentlyDownloadingAndDownloaded.bookIdentifier,
1736 modifiedAt: currentlyDownloadingAndDownloaded.annotationsModifiedAt,
1737 path: currentlyDownloadingAndDownloaded.storage
1738 };
1739 bookAnnotations.push(bookAnnotationObject);
1740 }
1741
1742 deferred.resolve(bookAnnotations);
1743
1744
1745 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=? AND (status=? OR status=?)', [storage.getItem('uniqueId'), 'Downloaded', 'Downloading'])
1746 // .then(function (result) {
1747 // var bookAnnotations = [];
1748 // for (var i = 0; i < result.rows.length; i++) {
1749 // var bookAnnotationObject = {
1750 // bookIdentifier: result.rows.item(i).bookIdentifier,
1751 // modifiedAt: result.rows.item(i).annotationsModifiedAt,
1752 // path: result.rows.item(i).storage
1753 // };
1754 // bookAnnotations.push(bookAnnotationObject);
1755 // }
1756
1757 // deferred.resolve(bookAnnotations);
1758 // }, function (error) {
1759 // deferred.reject(error);
1760 // });
1761
1762 return deferred.promise;
1763 };
1764
1765 bookService.getAnnotationsFromServer = function () {
1766 var deferred = $q.defer();
1767
1768 //TODO: get annotations and their modified dates from server and save them to bookService.annotations array
1769 $http.get(storage.server + '/annotations/' + storage.getItem('userId'), { timeout: 15000 })
1770 .then(function (result) {
1771 // bookService.annotations = result;
1772 deferred.resolve(result.data);
1773 }, function (error) {
1774 deferred.reject(error);
1775 });
1776 // deferred.resolve();
1777
1778 return deferred.promise;
1779 };
1780
1781 bookService.compareAnnotations = function (serverAnnotations, dbAnnotations) {
1782 var annotationsToUpdate = {
1783 annotationsToGet: [],
1784 annotationsToPost: []
1785 };
1786
1787 serverAnnotations.forEach(function (currentServerAnnotation) {
1788 var found = false;
1789 currentServerAnnotation.bookIdentifier = currentServerAnnotation.BookIdentifier;
1790 dbAnnotations.forEach(function (currentDbAnnotation) {
1791 if (currentServerAnnotation.BookIdentifier == currentDbAnnotation.bookIdentifier) {
1792 found = true;
1793
1794 if (currentDbAnnotation.modifiedAt !== undefined) {
1795 var dbModifiedAt = new Date(currentDbAnnotation.modifiedAt);
1796 var serverModifiedAt = new Date(currentServerAnnotation.ModifiedAt);
1797
1798 if (dbModifiedAt > serverModifiedAt) {
1799 currentDbAnnotation.bookId = currentServerAnnotation.BookId;
1800 annotationsToUpdate.annotationsToPost.push(currentDbAnnotation);
1801 } else if (dbModifiedAt < serverModifiedAt) {
1802 currentServerAnnotation.path = currentDbAnnotation.path;
1803 annotationsToUpdate.annotationsToGet.push(currentServerAnnotation);
1804 }
1805 } else {
1806 currentServerAnnotation.path = currentDbAnnotation.path;
1807 annotationsToUpdate.annotationsToGet.push(currentServerAnnotation);
1808 }
1809 }
1810 });
1811
1812 // if (!found) {
1813 // annotationsToUpdate.annotationsToGet.push(currentServerAnnotation);
1814 // }
1815 });
1816
1817 return annotationsToUpdate;
1818 };
1819
1820 bookService.getAnnotationFileFromServer = function (bookId, bookIdentifier, bookPath) {
1821 //TODO: call server to get annotation file and save it to user's book folder
1822 var deferred = $q.defer();
1823
1824 $http.get(storage.server + '/annotations/' + storage.getItem('userId') + '/' + bookId, { timeout: 15000 })
1825 .then(function (success) {
1826 $cordovaFile.writeFile(bookPath + 'books/' + bookIdentifier + '/', 'annotations.json', success.data.Body, true)
1827 .then(function (result) {
1828 deferred.resolve(success.data);
1829 }, function (error) {
1830 deferred.reject(error);
1831 });
1832 }, function (error) {
1833 deferred.reject(error);
1834 });
1835
1836 return deferred.promise;
1837 };
1838
1839
1840 //Repostory Service
1841 function checkIfBookIsUpdate(bookId) {
1842 var deferred = $q.defer();
1843
1844 var updatedBookFound = repositoryService.getModelByIdentifier('updates', bookId);
1845 if (updatedBookFound) {
1846 deferred.resolve(true);
1847 } else {
1848 deferred.resolve(false);
1849 }
1850
1851 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM updates WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
1852 // .then(function (result) {
1853 // if (result.rows.item(0)) {
1854 // deferred.resolve(true);
1855 // } else {
1856 // deferred.resolve(false);
1857 // }
1858 // }, function (error) {
1859 // console.log(error);
1860 // deferred.reject(error);
1861 // });
1862
1863 return deferred.promise;
1864 }
1865
1866 //Repository Service
1867 function deleteBookFromDb(bookId) {
1868 var deferred = $q.defer();
1869 repositoryService.removeEntity('downloads', bookId);
1870 repositoryService.removeEntity('updates', bookId);
1871 deferred.resolve('book removed');
1872
1873 // $cordovaSQLite.execute(databaseService.db, 'DELETE FROM downloads WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
1874 // .then(function (result) {
1875 // $cordovaSQLite.execute(databaseService.db, 'DELETE FROM updates WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
1876 // .then(function (result) {
1877 // deferred.resolve(result);
1878 // }, function (error) {
1879 // deferred.reject(error);
1880 // });
1881 // }, function (error) {
1882 // deferred.reject(error);
1883 // });
1884 }
1885
1886 //Repository Service
1887 function getLastDownloadedPage(bookId) {
1888 var deferred = $q.defer();
1889 var currentBook = repositoryService.getModelByIdentifier('downloads', bookId);
1890 if (currentBook) {
1891 deferred.resolve(currentBook.lastDownloadedPage);
1892 } else {
1893 deferred.reject('Downloaded book not found');
1894 }
1895
1896 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=? AND bookIdentifier=?', [storage.getItem('uniqueId'), bookId])
1897 // .then(function (result) {
1898 // if (result.rows.length > 0) {
1899 // deferred.resolve(result.rows.item(0).lastDownloadedPage);
1900 // }
1901 // }, function (error) {
1902 // deferred.reject(error);
1903 // });
1904
1905 return deferred.promise;
1906 }
1907
1908
1909 //Repository Service
1910 bookService.checkQueuedBooksFromDb = function () {
1911 var deferred = $q.defer();
1912 var allDownloads = repositoryService.getAllModels('downloads');
1913 if (!allDownloads) {
1914 deferred.reject('No downloads found');
1915 } else {
1916 var allUpdates = repositoryService.getAllModels('updates');
1917 var downloadsBooks = [];
1918 for (var i = 0; i < allDownloads.length; i++) {
1919 if (allDownloads[i].status == 'Queued') {
1920 downloadsBooks.push(allDownloads[i]);
1921 }
1922 }
1923 var allUpdates = repositoryService.getAllModels('updates');
1924 if (allUpdates) {
1925 var updatesBooks = [];
1926 for (var i = 0; i < allUpdates.length; i++) {
1927 if (allUpdates[i].status == 'Queued') {
1928 updatesBooks.push(allUpdates[i]);
1929 }
1930 }
1931 } else {
1932 updatesBooks = [];
1933 }
1934 var allQueuedDownloads = [];
1935 downloadsBooks.forEach(function (currentBook) {
1936 var bookObject = {
1937 Identifier: currentBook.bookIdentifier,
1938 isUpdate: false
1939 };
1940
1941 allQueuedDownloads.push(bookObject);
1942 });
1943
1944 updatesBooks.forEach(function (currentBook) {
1945 var bookObject = {
1946 Identifier: currentBook.bookIdentifier,
1947 isUpdate: true
1948 };
1949
1950 allQueuedDownloads.push(bookObject);
1951 });
1952
1953 allQueuedDownloads.forEach(function (currentBook) {
1954 bookService.unfinishedBooks.push(currentBook);
1955 });
1956
1957 deferred.resolve(allQueuedDownloads);
1958 }
1959
1960
1961 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM downloads WHERE userId=?', [storage.getItem('uniqueId')])
1962 // .then(function (result) {
1963 // var downloadsBooks = [];
1964 // for (var i = 0; i < result.rows.length; i++) {
1965 // if (result.rows.item(i).status == 'Queued') {
1966 // downloadsBooks.push(result.rows.item(i));
1967 // }
1968 // }
1969
1970 // $cordovaSQLite.execute(databaseService.db, 'SELECT * FROM updates WHERE userId=?', [storage.getItem('uniqueId')])
1971 // .then(function (result) {
1972 // var updatesBooks = [];
1973 // for (var i = 0; i < result.rows.length; i++) {
1974 // if (result.rows.item(i).status == 'Queued') {
1975 // updatesBooks.push(result.rows.item(i));
1976 // }
1977 // }
1978
1979 // var allQueuedDownloads = [];
1980
1981 // downloadsBooks.forEach(function (currentBook) {
1982 // var bookObject = {
1983 // Identifier: currentBook.bookIdentifier,
1984 // isUpdate: false
1985 // };
1986
1987 // allQueuedDownloads.push(bookObject);
1988 // });
1989
1990 // updatesBooks.forEach(function (currentBook) {
1991 // var bookObject = {
1992 // Identifier: currentBook.bookIdentifier,
1993 // isUpdate: true
1994 // };
1995
1996 // allQueuedDownloads.push(bookObject);
1997 // });
1998
1999 // allQueuedDownloads.forEach(function (currentBook) {
2000 // bookService.unfinishedBooks.push(currentBook);
2001 // });
2002
2003 // deferred.resolve(allQueuedDownloads);
2004 // }, function (error) {
2005 // deferred.reject(error);
2006 // });
2007 // }, function (error) {
2008 // deferred.reject(error);
2009 // });
2010
2011 return deferred.promise;
2012 };
2013
2014 return bookService;
2015 });