/* * Copyright 2016 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. * * 12.02.16 17:42 * */ package monakhv.samlib.service; import monakhv.samlib.data.AbstractSettings; import monakhv.samlib.db.AuthorController; import monakhv.samlib.db.SQLController; import monakhv.samlib.db.entity.Author; import monakhv.samlib.exception.SamlibInterruptException; import monakhv.samlib.exception.SamlibParseException; import monakhv.samlib.http.HttpClientController; import monakhv.samlib.log.Log; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; /** * Created by monakhv on 12.02.16. */ public class AuthorUpdateService { private static final String DEBUG_TAG = "AuthorUpdateService"; public static final long SLEEP_INTERVAL_SECONDS = 1L; public static final int SLEEP_DELAY_MIN = 5; public static final int SLEEP_DELAY_MAX = 15; private final AuthorController mAuthorController; private final HttpClientController mHttpClientController; private final AbstractSettings mAbstractSettings; private final List<Author> updatedAuthors; private final GuiEventBus mGuiEventBus; public AuthorUpdateService(AuthorController authorController, AbstractSettings settings, HttpClientController httpClientController, GuiEventBus guiEventBus) { mAuthorController = authorController; mHttpClientController = httpClientController; mAbstractSettings = settings; updatedAuthors = new ArrayList<>(); mGuiEventBus = guiEventBus; } public boolean runUpdateService(Author author, AuthorGuiState authorGuiState) { List<Author> authors = new ArrayList<>(); authors.add(author); return runUpdateService(authors,authorGuiState); } public boolean runUpdateService(AuthorGuiState authorGuiState) { List<Author> authors = mAuthorController.getAll(authorGuiState.mSelectedTagId, SQLController.COL_mtime + " DESC"); return runUpdateService(authors,authorGuiState); } /** * Check update information for the list of authors * * @param authors List of the Authors to check update * @return true if update successful false if error or interrupted */ private boolean runUpdateService(List<Author> authors, AuthorGuiState state) { updatedAuthors.clear(); int skippedAuthors = 0; Random rnd = new Random(Calendar.getInstance().getTimeInMillis()); int total = authors.size(); int iCurrent = 0;//to send update information to pull-to-refresh for (Author a : authors) {//main author cycle mGuiEventBus.post(new GuiUpdateObject(new AuthorUpdateProgress(total, ++iCurrent, a.getName()))); mAuthorController.loadBooks(a); mAuthorController.loadGroupBooks(a); String url = a.getUrl(); Author newA = new Author(); try { newA = mHttpClientController.getAuthorByURL(url, newA); } catch (IOException ex) {//here we abort cycle author and total update Log.i(DEBUG_TAG, "runUpdateAuthors: Connection Error: " + url, ex); finishUpdate(false, updatedAuthors); return false; } catch (SamlibParseException ex) {//skip update for given author Log.e(DEBUG_TAG, "runUpdateAuthors:Error parsing url: " + url + " skip update author ", ex); ++skippedAuthors; newA = a; } catch (SamlibInterruptException e) { Log.i(DEBUG_TAG, "runUpdateAuthors: catch Interrupted", e); finishUpdate(false, updatedAuthors); return false; } if (a.update(newA)) {//we have update for the author Log.i(DEBUG_TAG, "runUpdateAuthors: We need update author: " + a.getName()); mAuthorController.update(a); if (a.isIsNew()) { updatedAuthors.add(a);//sometimes we need update if the author has no new books int idx = getAuthorIndex(a, state); GuiUpdateObject guiUpdateObject = new GuiUpdateObject(a, idx, GuiUpdateObject.UpdateType.UPDATE_UPDATE); mGuiEventBus.post(guiUpdateObject); } if (mAbstractSettings.getAutoLoadFlag()) { loadBook(a); } } long sleep; if (mAbstractSettings.isUpdateDelay()) { sleep = rnd.nextInt(SLEEP_DELAY_MAX - SLEEP_DELAY_MIN + 1) + SLEEP_DELAY_MIN; } else { sleep = SLEEP_INTERVAL_SECONDS; } try { Log.d(DEBUG_TAG, "runUpdateAuthors: sleep " + sleep + " seconds"); TimeUnit.SECONDS.sleep(sleep); } catch (InterruptedException e) { Log.i(DEBUG_TAG, "runUpdateAuthors: Sleep interrupted exiting", e); finishUpdate(false, updatedAuthors); return false; } }//main author cycle END mAuthorController.cleanBooks(); if (authors.size() == skippedAuthors) { //all authors skipped - this is the error finishUpdate(false, updatedAuthors); return false; } else { finishUpdate(true, updatedAuthors); return true; } } private void finishUpdate(boolean b, List<Author> updatedAuthors) { Result result = new Result(b,updatedAuthors); result.numberOfUpdated = updatedAuthors.size(); mGuiEventBus.post(new GuiUpdateObject(result, GuiUpdateObject.UpdateType.UPDATE_UPDATE)); } /** * If need we can start download book service here * * @param a Author to load book for */ @SuppressWarnings("UnusedParameters") public void loadBook(Author a) { } private int getAuthorIndex(Author author, AuthorGuiState state) { if (state.mSorOrder== null){ return -1; } final List<Author> authors = mAuthorController.getAll(state.mSelectedTagId, state.mSorOrder); return authors.indexOf(author); } }