Stop synchronization on holidays (#142)

This commit is contained in:
Mikołaj Pich 2018-07-14 14:06:57 +02:00 committed by Rafał Borcz
parent 8725640168
commit 5a4b8b22f3
23 changed files with 381 additions and 242 deletions

View File

@ -87,11 +87,8 @@ jobs:
name: Upload unit code coverage to codecov name: Upload unit code coverage to codecov
command: bash <(curl -s https://codecov.io/bash) -F app command: bash <(curl -s https://codecov.io/bash) -F app
- store_artifacts: - store_artifacts:
path: ./app/build/reports/tests/ path: ./app/build/reports/
destination: tests_reports/ destination: reports/
- store_artifacts:
path: ./app/build/reports/jacoco/jacocoTestDebugUnitTestReport/
destination: coverage_reports/
- store_test_results: - store_test_results:
path: ./app/build/test-results path: ./app/build/test-results
- persist_to_workspace: - persist_to_workspace:
@ -112,11 +109,8 @@ jobs:
name: Upload code coverage to codecov name: Upload code coverage to codecov
command: bash <(curl -s https://codecov.io/bash) -F api command: bash <(curl -s https://codecov.io/bash) -F api
- store_artifacts: - store_artifacts:
path: ./api/build/reports/tests/ path: ./api/build/reports/
destination: tests_reports/ destination: reports/
- store_artifacts:
path: ./api/build/reports/jacoco/test/
destination: coverage_reports/
- store_test_results: - store_test_results:
path: ./api/build/test-results path: ./api/build/test-results
- persist_to_workspace: - persist_to_workspace:
@ -130,7 +124,7 @@ jobs:
- *attach_workspace - *attach_workspace
- run: - run:
name: Setup emulator name: Setup emulator
command: sdkmanager "system-images;android-19;google_apis;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-19;google_apis;armeabi-v7a" command: sdkmanager "system-images;android-16;default;armeabi-v7a" && echo "no" | avdmanager create avd -n test -k "system-images;android-16;default;armeabi-v7a"
- run: - run:
name: Launch emulator name: Launch emulator
command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel on command: export LD_LIBRARY_PATH=${ANDROID_HOME}/emulator/lib64:${ANDROID_HOME}/emulator/lib64/qt/lib && emulator64-arm -avd test -noaudio -no-boot-anim -no-window -accel on

View File

@ -10,6 +10,6 @@
[Pobierz wersję beta](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs) [Pobierz wersję beta](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs)
[Pobierz wersję rozwojową](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/app-debug-bitrise-signed.apk) [Pobierz wersję DEV](https://bitrise-redirector.herokuapp.com/v0.1/apps/daeff1893f3c8128/builds/master/artifacts/0)
Androidowy klient dziennika VULCAN UONET+. Androidowy klient dziennika VULCAN UONET+.

View File

@ -119,29 +119,3 @@ artifacts {
archives sourcesJar archives sourcesJar
archives javadocJar archives javadocJar
} }
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
mavenCentral()
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}

View File

@ -17,11 +17,13 @@ repositories {
maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.fabric.io/public' }
} }
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' apply plugin: 'org.greenrobot.greendao'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' // sync warning probably caused by bug https://issuetracker.google.com/issues/74537216
apply plugin: 'io.fabric' apply plugin: 'io.fabric'
apply from: '../jacoco.gradle' apply from: 'jacoco.gradle'
apply from: '../android-sonarqube.gradle' apply from: 'android-sonarqube.gradle'
apply plugin: 'com.google.gms.oss.licenses.plugin' apply plugin: 'com.google.gms.oss.licenses.plugin'
apply plugin: 'com.github.triplet.play' apply plugin: 'com.github.triplet.play'
@ -128,12 +130,12 @@ dependencies {
transitive = true transitive = true
} }
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger2" kapt "com.google.dagger:dagger-compiler:$dagger2"
annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife" kapt "com.google.dagger:dagger-android-processor:$dagger2"
kapt "com.jakewharton:butterknife-compiler:$butterknife"
debugImplementation "com.amitshekhar.android:debug-db:$debugDb" debugImplementation "com.amitshekhar.android:debug-db:$debugDb"
debugImplementation "net.zetetic:android-database-sqlcipher:$sqlcipher"
testImplementation "junit:junit:$junit" testImplementation "junit:junit:$junit"
testImplementation "org.mockito:mockito-core:$mockito" testImplementation "org.mockito:mockito-core:$mockito"

56
app/jacoco.gradle Normal file
View File

@ -0,0 +1,56 @@
apply plugin: "jacoco"
jacoco {
toolVersion "0.8.1"
reportsDir = file("$buildDir/reports")
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
// run ./gradlew clean createDebugCoverageReport jacocoTestReport
task jacocoTestReport(type: JacocoReport) {
group = "Reporting"
description = "Generate Jacoco coverage reports"
reports {
xml.enabled = true
html.enabled = true
}
def excludes = [
"**/R.class",
"**/R\$*.class",
"**/*\$ViewInjector*.*",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*Test*.*",
"android/**/*.*",
"**/*Fragment.*",
"**/*Activity.*"
]
// generated classes
classDirectories = fileTree(
// Java generated classes on Android project (debug build)
dir: "$buildDir/intermediates/classes/debug",
excludes: excludes
) + fileTree(
// Kotlin generated classes on Android project (debug build)
dir: "$buildDir/tmp/kotlin-classes/debug",
excludes: excludes
)
// sources
sourceDirectories = files([
android.sourceSets.main.java.srcDirs,
"src/main/kotlin"
])
executionData = fileTree(
dir: project.projectDir,
includes: ["**/*.exec" , "**/*.ec"]
)
}

View File

@ -30,6 +30,8 @@ import io.github.wulkanowy.ui.main.MainActivity;
import io.github.wulkanowy.utils.FabricUtils; import io.github.wulkanowy.utils.FabricUtils;
import timber.log.Timber; import timber.log.Timber;
import static io.github.wulkanowy.utils.TimeUtilsKt.isHolidays;
public class SyncJob extends SimpleJobService { public class SyncJob extends SimpleJobService {
public static final String JOB_TAG = "SyncJob"; public static final String JOB_TAG = "SyncJob";
@ -66,6 +68,12 @@ public class SyncJob extends SimpleJobService {
@Override @Override
public int onRunJob(JobParameters job) { public int onRunJob(JobParameters job) {
if (isHolidays()) {
stop(getApplicationContext());
return JobService.RESULT_FAIL_NORETRY;
}
try { try {
repository.getSyncRepo().initLastUser(); repository.getSyncRepo().initLastUser();
repository.getSyncRepo().syncAll(); repository.getSyncRepo().syncAll();

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.main; package io.github.wulkanowy.ui.main;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import javax.inject.Inject; import javax.inject.Inject;
@ -8,6 +7,8 @@ import javax.inject.Inject;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.base.BasePresenter;
import static io.github.wulkanowy.utils.TimeUtilsKt.isHolidays;
public class MainPresenter extends BasePresenter<MainContract.View> public class MainPresenter extends BasePresenter<MainContract.View>
implements MainContract.Presenter { implements MainContract.Presenter {
@ -35,7 +36,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
getView().initiationBottomNav(tabPosition); getView().initiationBottomNav(tabPosition);
getView().initiationViewPager(tabPosition); getView().initiationViewPager(tabPosition);
if (getRepository().getSharedRepo().isServicesEnable()) { if (getRepository().getSharedRepo().isServicesEnable() && !isHolidays()) {
getView().startSyncService(getRepository().getSharedRepo().getServicesInterval(), getView().startSyncService(getRepository().getSharedRepo().getServicesInterval(),
getRepository().getSharedRepo().isMobileDisable()); getRepository().getSharedRepo().isMobileDisable());
} }

View File

@ -10,10 +10,12 @@ import javax.inject.Inject;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
import io.github.wulkanowy.utils.TimeUtils;
import io.github.wulkanowy.utils.async.AbstractTask; import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners; import io.github.wulkanowy.utils.async.AsyncListeners;
import static io.github.wulkanowy.utils.TimeUtilsKt.getFirstDayOfCurrentWeek;
import static io.github.wulkanowy.utils.TimeUtilsKt.getMondaysFromCurrentSchoolYear;
public class AttendancePresenter extends BasePresenter<AttendanceContract.View> public class AttendancePresenter extends BasePresenter<AttendanceContract.View>
implements AttendanceContract.Presenter, AsyncListeners.OnFirstLoadingListener { implements AttendanceContract.Presenter, AsyncListeners.OnFirstLoadingListener {
@ -42,11 +44,11 @@ public class AttendancePresenter extends BasePresenter<AttendanceContract.View>
} }
if (dates.isEmpty()) { if (dates.isEmpty()) {
dates = TimeUtils.getMondaysFromCurrentSchoolYear(); dates = getMondaysFromCurrentSchoolYear();
} }
if (positionToScroll == 0) { if (positionToScroll == 0) {
positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); positionToScroll = dates.indexOf(getFirstDayOfCurrentWeek());
} }
if (!isFirstSight) { if (!isFirstSight) {

View File

@ -10,10 +10,12 @@ import javax.inject.Inject;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
import io.github.wulkanowy.utils.TimeUtils;
import io.github.wulkanowy.utils.async.AbstractTask; import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners; import io.github.wulkanowy.utils.async.AsyncListeners;
import static io.github.wulkanowy.utils.TimeUtilsKt.getFirstDayOfCurrentWeek;
import static io.github.wulkanowy.utils.TimeUtilsKt.getMondaysFromCurrentSchoolYear;
public class ExamsPresenter extends BasePresenter<ExamsContract.View> public class ExamsPresenter extends BasePresenter<ExamsContract.View>
implements ExamsContract.Presenter, AsyncListeners.OnFirstLoadingListener { implements ExamsContract.Presenter, AsyncListeners.OnFirstLoadingListener {
@ -42,11 +44,11 @@ public class ExamsPresenter extends BasePresenter<ExamsContract.View>
} }
if (dates.isEmpty()) { if (dates.isEmpty()) {
dates = TimeUtils.getMondaysFromCurrentSchoolYear(); dates = getMondaysFromCurrentSchoolYear();
} }
if (positionToScroll == 0) { if (positionToScroll == 0) {
positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); positionToScroll = dates.indexOf(getFirstDayOfCurrentWeek());
} }
if (!isFirstSight) { if (!isFirstSight) {

View File

@ -18,6 +18,8 @@ import io.github.wulkanowy.services.jobs.SyncJob;
import io.github.wulkanowy.ui.main.MainActivity; import io.github.wulkanowy.ui.main.MainActivity;
import io.github.wulkanowy.utils.AppConstant; import io.github.wulkanowy.utils.AppConstant;
import static io.github.wulkanowy.utils.TimeUtilsKt.isHolidays;
public class SettingsFragment extends PreferenceFragmentCompat public class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener { implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -86,7 +88,13 @@ public class SettingsFragment extends PreferenceFragmentCompat
findPreference(SHARED_KEY_ABOUT_VERSION).setOnPreferenceClickListener(onProgrammerListener); findPreference(SHARED_KEY_ABOUT_VERSION).setOnPreferenceClickListener(onProgrammerListener);
findPreference(SHARED_KEY_ABOUT_REPO).setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(AppConstant.REPO_URL))); findPreference(SHARED_KEY_ABOUT_REPO).setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(AppConstant.REPO_URL)));
findPreference(SHARED_KEY_ABOUT_LICENSES).setIntent(new Intent(getActivity(), OssLicensesMenuActivity.class) findPreference(SHARED_KEY_ABOUT_LICENSES).setIntent(new Intent(getActivity(), OssLicensesMenuActivity.class)
.putExtra("title", getString(R.string.pref_about_osl))); .putExtra("title", R.string.pref_about_osl));
if (isHolidays()) {
Preference services = findPreference(SHARED_KEY_SERVICES_ENABLE);
services.setSummary(R.string.pref_services_suspended_on_holidays);
services.setEnabled(false);
}
} }
@Override @Override

View File

@ -10,10 +10,12 @@ import javax.inject.Inject;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener;
import io.github.wulkanowy.utils.TimeUtils;
import io.github.wulkanowy.utils.async.AbstractTask; import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners; import io.github.wulkanowy.utils.async.AsyncListeners;
import static io.github.wulkanowy.utils.TimeUtilsKt.getFirstDayOfCurrentWeek;
import static io.github.wulkanowy.utils.TimeUtilsKt.getMondaysFromCurrentSchoolYear;
public class TimetablePresenter extends BasePresenter<TimetableContract.View> public class TimetablePresenter extends BasePresenter<TimetableContract.View>
implements TimetableContract.Presenter, AsyncListeners.OnFirstLoadingListener { implements TimetableContract.Presenter, AsyncListeners.OnFirstLoadingListener {
@ -42,11 +44,11 @@ public class TimetablePresenter extends BasePresenter<TimetableContract.View>
} }
if (dates.isEmpty()) { if (dates.isEmpty()) {
dates = TimeUtils.getMondaysFromCurrentSchoolYear(); dates = getMondaysFromCurrentSchoolYear();
} }
if (positionToScroll == 0) { if (positionToScroll == 0) {
positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); positionToScroll = dates.indexOf(getFirstDayOfCurrentWeek());
} }
if (!isFirstSight) { if (!isFirstSight) {

View File

@ -16,10 +16,12 @@ import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.ui.base.BasePresenter; import io.github.wulkanowy.ui.base.BasePresenter;
import io.github.wulkanowy.utils.AppConstant; import io.github.wulkanowy.utils.AppConstant;
import io.github.wulkanowy.utils.FabricUtils; import io.github.wulkanowy.utils.FabricUtils;
import io.github.wulkanowy.utils.TimeUtils;
import io.github.wulkanowy.utils.async.AbstractTask; import io.github.wulkanowy.utils.async.AbstractTask;
import io.github.wulkanowy.utils.async.AsyncListeners; import io.github.wulkanowy.utils.async.AsyncListeners;
import static io.github.wulkanowy.utils.TimeUtilsKt.getParsedDate;
import static io.github.wulkanowy.utils.TimeUtilsKt.isDateInWeek;
public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.View> public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.View>
implements TimetableTabContract.Presenter, AsyncListeners.OnRefreshListener, implements TimetableTabContract.Presenter, AsyncListeners.OnRefreshListener,
AsyncListeners.OnFirstLoadingListener { AsyncListeners.OnFirstLoadingListener {
@ -162,9 +164,9 @@ public class TimetableTabPresenter extends BasePresenter<TimetableTabContract.Vi
} }
private void expandCurrentDayHeader() { private void expandCurrentDayHeader() {
LocalDate monday = TimeUtils.getParsedDate(date, AppConstant.DATE_PATTERN); LocalDate monday = getParsedDate(date, AppConstant.DATE_PATTERN);
if (TimeUtils.isDateInWeek(monday, LocalDate.now()) && !isFirstSight) { if (isDateInWeek(monday, LocalDate.now()) && !isFirstSight) {
getView().expandItem(LocalDate.now().getDayOfWeek().getValue() - 1); getView().expandItem(LocalDate.now().getDayOfWeek().getValue() - 1);
} }
} }

View File

@ -17,7 +17,9 @@ import io.github.wulkanowy.R;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.data.db.dao.entities.TimetableLesson; import io.github.wulkanowy.data.db.dao.entities.TimetableLesson;
import io.github.wulkanowy.data.db.dao.entities.Week; import io.github.wulkanowy.data.db.dao.entities.Week;
import io.github.wulkanowy.utils.TimeUtils;
import static io.github.wulkanowy.utils.TimeUtilsKt.getFirstDayOfCurrentWeek;
import static io.github.wulkanowy.utils.TimeUtilsKt.getTodayOrNextDayOrder;
public class TimetableWidgetFactory implements RemoteViewsService.RemoteViewsFactory { public class TimetableWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
@ -44,8 +46,8 @@ public class TimetableWidgetFactory implements RemoteViewsService.RemoteViewsFac
if (repository.getSharedRepo().isUserLoggedIn()) { if (repository.getSharedRepo().isUserLoggedIn()) {
Week week = repository.getDbRepo().getWeek(TimeUtils.getDateOfCurrentMonday(true)); Week week = repository.getDbRepo().getWeek(getFirstDayOfCurrentWeek());
int valueOfDay = TimeUtils.getTodayOrNextDayValue(repository.getSharedRepo().getTimetableWidgetState()); int valueOfDay = getTodayOrNextDayOrder(repository.getSharedRepo().getTimetableWidgetState());
if (valueOfDay != 5 && valueOfDay != 6 && week != null) { if (valueOfDay != 5 && valueOfDay != 6 && week != null) {
week.resetDayList(); week.resetDayList();

View File

@ -16,7 +16,8 @@ import io.github.wulkanowy.R;
import io.github.wulkanowy.data.RepositoryContract; import io.github.wulkanowy.data.RepositoryContract;
import io.github.wulkanowy.services.widgets.TimetableWidgetServices; import io.github.wulkanowy.services.widgets.TimetableWidgetServices;
import io.github.wulkanowy.ui.main.MainActivity; import io.github.wulkanowy.ui.main.MainActivity;
import io.github.wulkanowy.utils.TimeUtils;
import static io.github.wulkanowy.utils.TimeUtilsKt.getTodayOrNextDay;
public class TimetableWidgetProvider extends AppWidgetProvider { public class TimetableWidgetProvider extends AppWidgetProvider {
@ -95,7 +96,7 @@ public class TimetableWidgetProvider extends AppWidgetProvider {
: R.string.widget_timetable_today); : R.string.widget_timetable_today);
views.setTextViewText(R.id.timetable_widget_toggle, toggleText); views.setTextViewText(R.id.timetable_widget_toggle, toggleText);
views.setTextViewText(R.id.timetable_widget_date, TimeUtils.getTodayOrNextDay(nextDay)); views.setTextViewText(R.id.timetable_widget_date, getTodayOrNextDay(nextDay));
} }
private void updateWidget(RemoteViews views, AppWidgetManager appWidgetManager, int appWidgetId) { private void updateWidget(RemoteViews views, AppWidgetManager appWidgetManager, int appWidgetId) {

View File

@ -1,81 +0,0 @@
package io.github.wulkanowy.utils;
import org.threeten.bp.DayOfWeek;
import org.threeten.bp.LocalDate;
import org.threeten.bp.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public final class TimeUtils {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(AppConstant.DATE_PATTERN);
private TimeUtils() {
throw new IllegalStateException("Utility class");
}
public static LocalDate getParsedDate(String dateString, String dateFormat) {
return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(dateFormat));
}
public static List<String> getMondaysFromCurrentSchoolYear() {
LocalDate startDate = LocalDate.of(getCurrentSchoolYear(), 9, 1);
LocalDate endDate = LocalDate.of(getCurrentSchoolYear() + 1, 8, 31);
List<String> dateList = new ArrayList<>();
LocalDate thisMonday = startDate.with(DayOfWeek.MONDAY);
if (startDate.isAfter(thisMonday)) {
startDate = thisMonday.plusWeeks(1);
} else {
startDate = thisMonday;
}
while (startDate.isBefore(endDate)) {
dateList.add(startDate.format(formatter));
startDate = startDate.plusWeeks(1);
}
return dateList;
}
public static int getCurrentSchoolYear() {
LocalDate localDate = LocalDate.now();
return localDate.getMonthValue() <= 8 ? localDate.getYear() - 1 : localDate.getYear();
}
public static String getDateOfCurrentMonday(boolean normalize) {
LocalDate currentDate = LocalDate.now();
if (currentDate.getDayOfWeek() == DayOfWeek.SATURDAY && normalize) {
currentDate = currentDate.plusDays(2);
} else if (currentDate.getDayOfWeek() == DayOfWeek.SUNDAY && normalize) {
currentDate = currentDate.plusDays(1);
} else {
currentDate = currentDate.with(DayOfWeek.MONDAY);
}
return currentDate.format(formatter);
}
public static int getTodayOrNextDayValue(boolean nextDay) {
DayOfWeek day = LocalDate.now().getDayOfWeek();
if (nextDay) {
if (day == DayOfWeek.SUNDAY) {
return 0;
}
return day.getValue();
}
return day.getValue() - 1;
}
public static String getTodayOrNextDay(boolean nextDay) {
LocalDate current = LocalDate.now();
return nextDay ? current.plusDays(1).format(formatter) : current.format(formatter);
}
public static boolean isDateInWeek(LocalDate firstWeekDay, LocalDate date) {
return date.isAfter(firstWeekDay.minusDays(1)) && date.isBefore(firstWeekDay.plusDays(5));
}
}

View File

@ -0,0 +1,97 @@
package io.github.wulkanowy.utils
import org.threeten.bp.DayOfWeek.*
import org.threeten.bp.LocalDate
import org.threeten.bp.Year
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.temporal.TemporalAdjusters
import java.util.*
private val formatter = DateTimeFormatter.ofPattern(AppConstant.DATE_PATTERN)
fun getParsedDate(dateString: String, dateFormat: String): LocalDate {
return LocalDate.parse(dateString, DateTimeFormatter.ofPattern(dateFormat))
}
fun getMondaysFromCurrentSchoolYear() = getMondaysFromCurrentSchoolYear(LocalDate.now())
fun getMondaysFromCurrentSchoolYear(date: LocalDate): List<String> {
val startDate = getFirstSchoolDay(getSchoolYearForDate(date))
?.with(TemporalAdjusters.previousOrSame(MONDAY))
val endDate = getFirstSchoolDay(getSchoolYearForDate(date) + 1)
?.with(TemporalAdjusters.previousOrSame(MONDAY))
val dateList = ArrayList<String>()
var monday = startDate as LocalDate
while (monday.isBefore(endDate)) {
dateList.add(monday.format(formatter))
monday = monday.plusWeeks(1)
}
return dateList
}
fun getSchoolYearForDate(date: LocalDate): Int {
return if (date.monthValue <= 8) date.year - 1 else date.year
}
fun getFirstDayOfCurrentWeek(): String = getFirstDayOfCurrentWeek(LocalDate.now())
fun getFirstDayOfCurrentWeek(date: LocalDate): String {
return when (date.dayOfWeek) {
SATURDAY -> date.plusDays(2)
SUNDAY -> date.plusDays(1)
else -> date.with(MONDAY)
}.format(formatter)
}
fun getTodayOrNextDayOrder(next: Boolean): Int = getTodayOrNextDayOrder(next, LocalDate.now())
fun getTodayOrNextDayOrder(next: Boolean, date: LocalDate): Int {
val day = date.dayOfWeek
return if (next) {
if (day == SUNDAY) {
0
} else day.value
} else day.value - 1
}
fun getTodayOrNextDay(next: Boolean): String? = getTodayOrNextDay(next, LocalDate.now())
fun getTodayOrNextDay(next: Boolean, date: LocalDate): String? {
return (if (next) {
date.plusDays(1)
} else date).format(formatter)
}
fun isDateInWeek(firstWeekDay: LocalDate, date: LocalDate): Boolean {
return date.isAfter(firstWeekDay.minusDays(1)) && date.isBefore(firstWeekDay.plusDays(5))
}
/**
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
*/
fun isHolidays(): Boolean = isHolidays(LocalDate.now(), Year.now().value)
fun isHolidays(day: LocalDate, year: Int): Boolean {
return day.isAfter(getLastSchoolDay(year)) && day.isBefore(getFirstSchoolDay(year))
}
fun getFirstSchoolDay(year: Int): LocalDate? {
val firstSeptember = LocalDate.of(year, 9, 1)
return when (firstSeptember.dayOfWeek) {
FRIDAY,
SATURDAY,
SUNDAY -> firstSeptember.with(TemporalAdjusters.firstInMonth(MONDAY))
else -> {
firstSeptember
}
}
}
fun getLastSchoolDay(year: Int): LocalDate? {
return LocalDate
.of(year, 6, 20)
.with(TemporalAdjusters.next(FRIDAY))
}

View File

@ -136,6 +136,7 @@
<string name="pref_services_header">Usługi</string> <string name="pref_services_header">Usługi</string>
<string name="pref_services_switch">Włącz odświeżanie danych w tle</string> <string name="pref_services_switch">Włącz odświeżanie danych w tle</string>
<string name="pref_services_suspended_on_holidays">Zawieszone na wakacjach</string>
<string name="pref_services_interval">Interwał między odświeżaniem danych</string> <string name="pref_services_interval">Interwał między odświeżaniem danych</string>
<string name="pref_services_mobile_data">Synchronizacja tylko przez WiFi</string> <string name="pref_services_mobile_data">Synchronizacja tylko przez WiFi</string>

View File

@ -132,6 +132,7 @@
<string name="pref_services_header">Services</string> <string name="pref_services_header">Services</string>
<string name="pref_services_switch">Enable background data refreshing</string> <string name="pref_services_switch">Enable background data refreshing</string>
<string name="pref_services_suspended_on_holidays">Suspended on holidays</string>
<string name="pref_services_interval">Interval between data refreshing</string> <string name="pref_services_interval">Interval between data refreshing</string>
<string name="pref_services_mobile_data">Synchronization via WiFi only</string> <string name="pref_services_mobile_data">Synchronization via WiFi only</string>

View File

@ -1,48 +0,0 @@
package io.github.wulkanowy.utils;
import org.junit.Assert;
import org.junit.Test;
import org.threeten.bp.LocalDate;
public class TimeUtilsTest {
@Test
public void getParsedDateTest() {
Assert.assertEquals(LocalDate.of(1970, 1, 1),
TimeUtils.getParsedDate("1970-01-01", "yyyy-MM-dd"));
}
@Test
public void isDateInWeekInsideTest() {
Assert.assertTrue(TimeUtils.isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 31)
));
}
@Test
public void isDateInWeekExtremesTest() {
Assert.assertTrue(TimeUtils.isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 28)
));
Assert.assertTrue(TimeUtils.isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 6, 1)
));
}
@Test
public void isDateInWeekOutOfTest() {
Assert.assertFalse(TimeUtils.isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 6, 2)
));
Assert.assertFalse(TimeUtils.isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 27)
));
}
}

View File

@ -0,0 +1,140 @@
package io.github.wulkanowy.utils
import org.junit.Test
import org.threeten.bp.LocalDate
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
class TimeUtilsTest {
@Test fun getParsedDateTest() {
assertEquals(LocalDate.of(1970, 1, 1),
getParsedDate("1970-01-01", "yyyy-MM-dd"))
}
@Test fun getMondaysFromCurrentSchoolYearTest() {
val y201718 = getMondaysFromCurrentSchoolYear(LocalDate.of(2018, 1, 1))
assertEquals("2017-09-04", y201718.first())
assertEquals("2018-08-27", y201718.last())
val y202122 = getMondaysFromCurrentSchoolYear(LocalDate.of(2022, 1, 1))
assertEquals("2021-08-30", y202122.first())
assertEquals("2022-08-22", y202122.last())
val y202223 = getMondaysFromCurrentSchoolYear(LocalDate.of(2023, 1, 1))
assertEquals("2022-08-29", y202223.first())
assertEquals("2023-08-28", y202223.last())
}
@Test fun getCurrentSchoolYearTest() {
assertEquals(2017, getSchoolYearForDate(LocalDate.of(2018, 8, 31)))
assertEquals(2018, getSchoolYearForDate(LocalDate.of(2018, 9, 1)))
}
@Test fun getFirstWeekDayTest() {
assertEquals("2018-06-18", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 21)))
assertEquals("2018-06-18", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 22)))
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 23)))
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 24)))
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 25)))
assertEquals("2018-06-25", getFirstDayOfCurrentWeek(LocalDate.of(2018, 6, 26)))
}
@Test fun getTodayOrNextDayOrderTest() {
assertEquals(0, getTodayOrNextDayOrder(true, LocalDate.of(2018, 6, 24))) // sunday
assertEquals(6, getTodayOrNextDayOrder(false, LocalDate.of(2018, 6, 24)))
assertEquals(1, getTodayOrNextDayOrder(true, LocalDate.of(2018, 6, 25)))
assertEquals(0, getTodayOrNextDayOrder(false, LocalDate.of(2018, 6, 25)))
}
@Test fun getTodayOrNextDayTest() {
assertEquals("2018-06-26", getTodayOrNextDay(false, LocalDate.of(2018, 6, 26)))
assertEquals("2018-06-27", getTodayOrNextDay(true, LocalDate.of(2018, 6, 26)))
}
@Test fun isDateInWeekInsideTest() {
assertTrue(isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 31)
))
}
@Test fun isDateInWeekExtremesTest() {
assertTrue(isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 28)
))
assertTrue(isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 6, 1)
))
}
@Test fun isDateInWeekOutOfTest() {
assertFalse(isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 6, 2)
))
assertFalse(isDateInWeek(
LocalDate.of(2018, 5, 28),
LocalDate.of(2018, 5, 27)
))
}
@Test fun isHolidaysInSchoolEndTest() {
assertFalse(isHolidays(LocalDate.of(2017, 6, 23), 2017))
assertFalse(isHolidays(LocalDate.of(2018, 6, 22), 2018))
assertFalse(isHolidays(LocalDate.of(2019, 6, 21), 2019))
assertFalse(isHolidays(LocalDate.of(2020, 6, 26), 2020))
assertFalse(isHolidays(LocalDate.of(2021, 6, 25), 2021))
assertFalse(isHolidays(LocalDate.of(2022, 6, 24), 2022))
assertFalse(isHolidays(LocalDate.of(2023, 6, 23), 2023))
assertFalse(isHolidays(LocalDate.of(2024, 6, 21), 2024))
assertFalse(isHolidays(LocalDate.of(2025, 6, 27), 2025))
}
@Test fun isHolidaysInHolidaysStartTest() {
assertTrue(isHolidays(LocalDate.of(2017, 6, 24), 2017))
assertTrue(isHolidays(LocalDate.of(2018, 6, 23), 2018))
assertTrue(isHolidays(LocalDate.of(2019, 6, 22), 2019))
assertTrue(isHolidays(LocalDate.of(2020, 6, 27), 2020))
assertTrue(isHolidays(LocalDate.of(2021, 6, 26), 2021))
assertTrue(isHolidays(LocalDate.of(2022, 6, 25), 2022))
assertTrue(isHolidays(LocalDate.of(2023, 6, 24), 2023))
assertTrue(isHolidays(LocalDate.of(2024, 6, 22), 2024))
assertTrue(isHolidays(LocalDate.of(2025, 6, 28), 2025))
}
@Test fun isHolidaysInHolidaysEndTest() {
assertTrue(isHolidays(LocalDate.of(2017, 9, 1), 2017)) // friday
assertTrue(isHolidays(LocalDate.of(2017, 9, 2), 2017)) // saturday
assertTrue(isHolidays(LocalDate.of(2017, 9, 3), 2017)) // sunday
assertTrue(isHolidays(LocalDate.of(2018, 9, 1), 2018)) // saturday
assertTrue(isHolidays(LocalDate.of(2018, 9, 2), 2018)) // sunday
assertTrue(isHolidays(LocalDate.of(2019, 9, 1), 2019)) // sunday
assertTrue(isHolidays(LocalDate.of(2020, 8, 31), 2020)) // monday
assertTrue(isHolidays(LocalDate.of(2021, 8, 31), 2021)) // tuesday
assertTrue(isHolidays(LocalDate.of(2022, 8, 31), 2022)) // wednesday
assertTrue(isHolidays(LocalDate.of(2023, 9, 1), 2023)) // friday
assertTrue(isHolidays(LocalDate.of(2023, 9, 2), 2023)) // saturday
assertTrue(isHolidays(LocalDate.of(2023, 9, 3), 2023)) // sunday
assertTrue(isHolidays(LocalDate.of(2024, 9, 1), 2024)) // sunday
assertTrue(isHolidays(LocalDate.of(2025, 8, 31), 2025)) // sunday
}
@Test fun isHolidaysInSchoolStartTest() {
assertFalse(isHolidays(LocalDate.of(2017, 9, 4), 2017)) // monday
assertFalse(isHolidays(LocalDate.of(2018, 9, 3), 2018)) // monday
assertFalse(isHolidays(LocalDate.of(2019, 9, 2), 2019)) // monday
assertFalse(isHolidays(LocalDate.of(2020, 9, 1), 2020)) // tuesday
assertFalse(isHolidays(LocalDate.of(2021, 9, 1), 2021)) // wednesday
assertFalse(isHolidays(LocalDate.of(2022, 9, 1), 2022)) // thursday
assertFalse(isHolidays(LocalDate.of(2023, 9, 4), 2023)) // monday
assertFalse(isHolidays(LocalDate.of(2024, 9, 2), 2024)) // monday
assertFalse(isHolidays(LocalDate.of(2025, 9, 1), 2025)) // monday
}
}

View File

@ -1,4 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.2.51'
repositories { repositories {
mavenCentral() mavenCentral()
google() google()
@ -8,18 +9,21 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.3' classpath 'com.android.tools.build:gradle:3.1.3'
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2"
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
plugins { plugins {
// gradle dependencyUpdates -Drevision=release // gradle dependencyUpdates -Drevision=release
id "com.github.ben-manes.versions" version "0.17.0" id "com.github.ben-manes.versions" version "0.20.0"
} }
project.ext.preDexLibs = !project.hasProperty("disablePreDex") project.ext.preDexLibs = !project.hasProperty("disablePreDex")
subprojects { subprojects {
apply plugin: 'build-dashboard' // build/reports/buildDashboard/index.html
project.plugins.whenPluginAdded { plugin -> project.plugins.whenPluginAdded { plugin ->
if ("com.android.build.gradle.AppPlugin" == plugin.class.name) { if ("com.android.build.gradle.AppPlugin" == plugin.class.name) {
project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs
@ -52,17 +56,16 @@ ext {
slf4jApi = "1.7.25" slf4jApi = "1.7.25"
slf4jTimber = "1.0.1" slf4jTimber = "1.0.1"
timber = "4.7.0" timber = "4.7.1"
debugDb = "1.0.3" debugDb = "1.0.4"
sqlcipher = "3.5.9"
junit = "4.12" junit = "4.12"
mockito = "2.18.3" mockito = "2.19.0"
testRunner = "1.0.2" testRunner = "1.0.2"
fabricGradle = "1.25.4" fabricGradle = "1.25.4"
crashlyticsSdk = "2.9.3" crashlyticsSdk = "2.9.4"
crashlyticsAnswers = "1.4.2" crashlyticsAnswers = "1.4.2"
playPublisher = "1.2.2" playPublisher = "1.2.2"
@ -73,10 +76,22 @@ allprojects {
mavenCentral() mavenCentral()
google() google()
jcenter() jcenter()
maven { url "https://jitpack.io" }
} }
} }
task clean(type: Delete) { task clean(type: Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }
dependencyUpdates.resolutionStrategy {
componentSelection { rules ->
rules.all { ComponentSelection selection ->
boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier ->
selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/
}
if (rejected) {
selection.reject('Release candidate')
}
}
}
}

View File

@ -1,40 +0,0 @@
apply plugin: "jacoco"
jacoco {
toolVersion "0.8.1"
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
// run ./gradlew clean createDebugCoverageReport jacocoTestReport
task jacocoTestReport(type: JacocoReport) {
group = "Reporting"
description = "Generate Jacoco coverage reports"
reports {
xml.enabled = true
html.enabled = true
}
def fileFilter = ["**/R.class",
"**/R\$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"android/**/*.*",
"**/Lambda.class",
"**/*Lambda.class",
"**/*Lambda*.class",
"**/*Lambda*.*",
"**/*Builder.*"
]
def debugTree = fileTree(dir: "${buildDir}/intermediates/classes/debug", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories = files([mainSrc])
classDirectories = files([debugTree])
executionData = fileTree(dir: project.projectDir, includes: ["**/*.exec" , "**/*.ec"])
}