package monakhv.samlib.data;
import monakhv.samlib.db.entity.Book;
import monakhv.samlib.http.ProxyData;
import monakhv.samlib.log.Log;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/*
* Copyright 2015 Dmitry Monakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* 2/12/15.
*/
public abstract class AbstractSettings {
private static final String DEBUG_TAG = "AbstractSettings";
private static final String DATE_FORMAT_BOOK_FILE = "dd-MM-yyyy_HH-mm-ss";
public static final String BOOKS_DIR = "Book//";
public static final String sep = System.getProperty("file.separator");
public static final long INTERVAL_FIFTEEN_MINUTES = 15 * 60 * 1000;
public static final long INTERVAL_HALF_HOUR = 2*INTERVAL_FIFTEEN_MINUTES;
public static final long INTERVAL_HOUR = 2*INTERVAL_HALF_HOUR;
public static final long INTERVAL_HALF_DAY = 12*INTERVAL_HOUR;
public static final long INTERVAL_DAY = 2*INTERVAL_HALF_DAY;
public enum FileType {
HTML(".html","text/html"),
FB2(".fb2",null);
public final String ext;
public final String mime;
FileType(String ext,String mime) {
this.ext=ext;
this.mime = mime;
}
}
public abstract String getFirstMirror();
public abstract ProxyData getProxy();
public abstract File getDataDirectory();//where to store books
public abstract String getCollationRule();//get Collation rule string
public abstract boolean isUpdateDelay();//make delay after each author update
/**
*
* @return day number to live book into store
*/
public abstract String getBookLifeTime();
public abstract FileType getFileType();
/**
* need we download new book during update process or not
* @return true make download book
*/
public abstract boolean getAutoLoadFlag();
/**
* Limit book file life time or not
* @return true make life time limitation
*/
public abstract boolean getLimitBookLifeTimeFlag();
/**
* Setting file to store book content
* making parent directories if need
*
* @param book Book object to get File for
* @return File object to sore book to
*/
public File getBookFile(Book book, FileType fileType) {
String ff;
if (book.isPreserve()){
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT_BOOK_FILE);
ff= BOOKS_DIR +sep+ book.getUri() + sep+ df.format(Calendar.getInstance().getTime())+ fileType.ext;
}
else {
ff= BOOKS_DIR +sep+ book.getUri() + fileType.ext;
}
File ss = new File(getDataDirectory(), ff);
File pp = ss.getParentFile();
boolean res =pp.mkdirs();
Log.d(DEBUG_TAG, "getBookFile: parent directory Path: >" + pp.getAbsolutePath() + "< result is: " + res);
Log.d(DEBUG_TAG,"getBookFile: book file - "+ss.getAbsolutePath());
return ss;
}
/**
* Return absolute path data directory preference
* get Default directory as SD-path + Samlib-Info
* <p/>
* Create if need
*
* @return Absolute path to the data directory
*/
public String getDataDirectoryPath() {
return getDataDirectory().getAbsolutePath();
}
/**
* Create directory to store many versions for the book
* Move existing version into the directory
* @param book Book object
*/
public void makePreserved(Book book){
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT_BOOK_FILE);
File dir = new File(getDataDirectory(), BOOKS_DIR +sep+ book.getUri() );
boolean resMk= dir.mkdirs();
boolean resEx = dir.exists();
Log.d(DEBUG_TAG,"makePreserved: directory path: >" +dir.getAbsolutePath() + "< created = "+resMk+" exist = "+resEx);
File old = getBookFile(book,book.getFileType());
if (old.exists()){
Date lm = Calendar.getInstance().getTime();
lm.setTime(old.lastModified());
old.renameTo(new File(dir,df.format(lm)+book.getFileType().ext));
}
}
/**
* get All version for book files for read selection
* @param book Book object
* @return List of all versions of file
*/
public String[] getBookFileVersions(Book book){
File dir = new File(getDataDirectory(), BOOKS_DIR +sep+ book.getUri() );
Log.d(DEBUG_TAG,"getBookFileVersions: looking in directory: "+dir.getAbsolutePath());
Log.d(DEBUG_TAG,"getBookFileVersions: file ext: "+book.getFileType().ext);
List<String> files = new ArrayList<>();
for (String fn : dir.list()){
if (fn.endsWith(book.getFileType().ext)){
Log.d(DEBUG_TAG,"getBookFileVersions: add file - "+fn);
files.add(fn);
}
}
// if (files.isEmpty()){
// return null;
// }
return files.toArray(new String[files.size()]);
}
/**
* get Book file to read it
* @param book Book object
* @param fileType Type of file to opent
* @return file object of book
*/
public File getBookFile4Read(Book book,FileType fileType){
if (book.isPreserve()){//choose latest version to read
File dir = new File(getDataDirectory(), BOOKS_DIR +sep+ book.getUri() );
File res = null;
long lastmod=0L;
for (String fn : dir.list()){
if (fn.endsWith(fileType.ext)){
File file = new File(dir,fn);
Log.i(DEBUG_TAG,"test file "+fn+" - "+file.getAbsolutePath());
if (file.lastModified()>lastmod){
lastmod=file.lastModified();
res=file;
}
}
}//file cycle
return res;
}
else {
return getBookFile(book,fileType);//we have the only version just open it
}
}
/**
* Get URL to open book for offline reading
* @return construct URL to start external program for offline reading
*/
public String getBookFileURL(Book book) {
return "file://" + getBookFile4Read(book, book.getFileType()).getAbsolutePath();
}
/**
* Delete book file with expired life time
* For book clean up usage only
* @param file Book file
*/
void checkDeleteBook(File file) {
String str = getBookLifeTime();
int limit;
try {
limit = Integer.parseInt(str);
} catch (NumberFormatException ex) {
Log.e(DEBUG_TAG, "Error parse Auto-load limit: " + str, ex);
return;
}
long interval = INTERVAL_DAY * limit;
long curTime = Calendar.getInstance().getTimeInMillis();
//Log.d("checkDeleteBook", file.getAbsolutePath());
if ((curTime - file.lastModified()) > interval) {
Log.i("checkDeleteBook", "delete book: " + file.getAbsolutePath());
if (!file.delete()) {
Log.e(DEBUG_TAG, "Can not delete the book: " + file.getAbsolutePath());
}
}
}
/**
* Get URL to open book for offline reading
* To read particular version of file
* @param book Book object
* @param file version file name
* @return file URL to READ
*/
public String getBookFileURL(Book book,String file) {
File dir = new File(getDataDirectory(), BOOKS_DIR +sep+ book.getUri() );
File f=new File(dir,file);
return "file://" +f.getAbsolutePath();
}
/**
* Clean downloaded files of any types
* Find all book for read and delete them
*
* @param book Book object
*/
public void cleanBookFile(Book book){
for (AbstractSettings.FileType ft : AbstractSettings.FileType.values()){
File ff = getBookFile4Read(book, ft);
if (ff!=null && ff.exists()) {
ff.delete();
}
}
}
}