package Ġcom . c ra iov adata . android . sun sh ine . data . database Ċ Ċ import Ġandroid . text . format . Date Utils Ċ import Ġandroid . text . format . Date Utils . DAY _ IN _ M ILL IS Ċ import Ġandroid . text . format . Date Utils . HOUR _ IN _ M ILL IS Ċ import Ġandroidx . lifecycle . LiveData Ċ import Ġcom . c ra iov adata . android . sun sh ine . utilities . App Executors Ċ import Ġcom . c ra iov adata . android . sun sh ine . data . network . Network DataSource Ċ import Ġcom . c ra iov adata . android . sun sh ine . City Data Ċ import Ġcom . c ra iov adata . android . sun sh ine . City Data . is Test Mode Ċ import Ġcom . c ra iov adata . android . sun sh ine . ui . models . List Weather Entry Ċ import Ġcom . c ra iov adata . android . sun sh ine . ui . models . Weather Entry Ċ import Ġcom . c ra iov adata . android . sun sh ine . ui . models . Web cam Entry Ċ import Ġcom . c ra iov adata . android . sun sh ine . utilities . Log Utils . log Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . launch Ċ import Ġjava . lang . System . currentTimeMillis Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ /** Ċ Ġ* ĠHandles Ġdata Ġoperations Ġin ĠSun sh ine . ĠAct s Ġas Ġa Ġmedi ator Ġbetween Ġ[ Network DataSource ] Ċ Ġ* Ġand Ġ[ Weather Dao ] Ċ Ġ*/ Ċ class ĠRepository Ġprivate Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġm Weather Dao : ĠWeather Dao , ĊĠĠĠ Ġprivate Ġval Ġm Network DataSource : ĠNetwork DataSource , ĊĠĠĠ Ġprivate Ġval Ġm Executors : ĠApp Executors Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġinitialized Forecast Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġinitialized Current Weather Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġinitialized Web c ams Ġ= Ġfalse ĊĊĠĠĠ Ġinit Ġ{ ĊĊĠĠĠĠĠĠĠ ĠGlobal Scope . launch ( Dispatch ers . Main ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . forecast s . observe Fore ver Ġ{ Ġnew Forecast s From Network Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDeletes Ġold Ġhistorical Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelete Old Weather Data () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInsert Ġour Ġnew Ġweather Ġdata Ġinto ĠSun sh ine 's Ġdatabase ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Weather Dao . bulk Insert (* new Forecast s From Network ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog ( Ġ" Old Ġweather Ġdeleted . ĠNew Ġvalues Ġinserted .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . current Weather . observe Fore ver Ġ{ ĠnewData From Network Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Weather Dao . bulk Insert (* new Data From Network ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . web c ams . observe Fore ver Ġ{ Ġnew Web c ams From Network Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDeletes Ġold Ġhistorical Ġdata ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelete Old Web c ams Data () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInsert Ġour Ġnew Ġweather Ġdata Ġinto ĠSun sh ine 's Ġdatabase ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Weather Dao . bulk Insert Web c ams (* new Web c ams From Network ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog ( Ġ" Old Ġweb c ams Ġdeleted . ĠNew Ġvalues Ġinserted .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun Ġrefresh Data Current Weather () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Fetch Current Weather Needed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . fetch Current Weather () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġday Weather Entries : ĠLive Data < List < List Weather Entry >> ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitialize Forecast Data () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoffset Ġ= ĠCity Data . get City Offset () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdays Since Epoch Ġ= ĠTimeUnit . MILLISECONDS . to Days ( currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtomorrow Mid night Normalized Utc Ġ= Ġ( days Since Epoch Ġ+ Ġ 1 ) Ġ* ĠDAY _ IN _ M ILL IS ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Weather Dao . get Mid Day Forecast ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDate ( tom orrow Mid night Normalized Utc ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoffset , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠHO UR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġweb c ams Entries : ĠLive Data < List < Web cam Entry >> ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitialize Web cam Data ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Weather Dao . getAll Web cam Entries () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġcurrent Weather List : ĠList < Weather Entry > ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Data Current Weather () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecently M ills Ġ= ĠcurrentTime Millis () Ġ- ĠDate Utils . MINUTE _ IN _ M ILL IS Ġ* Ġdelay ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecent Date Ġ= ĠDate ( recent ly M ills ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġm Weather Dao . getCurrent Weather List ( recent Date ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠChecks Ġif Ġthere Ġare Ġenough Ġdays Ġof Ġfuture Ġweather Ġfor Ġthe Ġapp Ġto Ġdisplay Ġall Ġthe Ġneeded Ġdata . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ return ĠWhether Ġa Ġfetch Ġis Ġneeded ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġis Fetch Forecast Needed : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠDate ( currentTimeMillis ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġm Weather Dao . count All Future Weather Entries ( now ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcount Ġ< ĠNetwork DataSource . NUM _ MIN _ DATA _ COUNT S ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġis Fetch Current Weather Needed : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdate Recent ly Ġ= ĠDate ( currentTimeMillis () Ġ- ĠDate Utils . MINUTE _ IN _ M ILL IS Ġ* Ġdelay ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġm Weather Dao . count Current Weather ( date Recent ly ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Fetch Needed CW Ġ= Ġcount Ġ< Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" is Fetch Needed CW : Ġ$ is Fetch Needed CW ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġis Fetch Needed CW ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġis Fetch Web c ams Needed : ĠBoolean ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġweb c ams Ġ= Ġm Weather Dao . get Latest Web cam () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( web c ams . isNull OrEmpty ()) Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġif Ġdata Ġweb c ams Ġis Ġolder Ġthan Ġone Ġweek ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġone Week Ago Ġ= ĠDate ( currentTimeMillis () Ġ- Ġ 7 Ġ* ĠDAY _ IN _ M ILL IS Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Old Web c ams Data Ġ= Ġweb c ams [ 0 ]. update Date Ġ< Ġone Week Ago ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġis Old Web c ams Data ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠCreates Ġperiodic Ġsync Ġtasks Ġand Ġchecks Ġto Ġsee Ġif Ġan Ġimmediate Ġsync Ġis Ġrequired . ĠIf Ġan ĊĠĠĠĠ Ġ* Ġimmediate Ġsync Ġis Ġrequired , Ġthis Ġmethod Ġwill Ġtake Ġcare Ġof Ġmaking Ġsure Ġthat Ġsync Ġoccurs . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġfun Ġinitialize Forecast Data () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠOnly Ġperform Ġinitialization Ġonce Ġper Ġapp Ġlifetime . ĠIf Ġinitialization Ġhas Ġalready Ġbeen ĊĠĠĠĠĠĠĠ Ġ// Ġperformed , Ġwe Ġhave Ġnothing Ġto Ġdo Ġin Ġthis Ġmethod . ĊĠĠĠĠĠĠĠ Ġif Ġ( initialized Forecast ) Ġreturn ĊĠĠĠĠĠĠĠ Ġinitialized Forecast Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġm Network DataSource . schedule Fetch Weather () Ċ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġjava . lang . IllegalStateException : ĠCannot Ġaccess Ġdatabase Ġon Ġthe Ġmain Ġthread Ġsince Ġit Ġmay Ġpotentially Ġlock Ġthe ĠUI Ġfor Ġa Ġlong Ġperiod Ġof Ġtime . ĊĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Fetch Forecast Needed ) Ġreturn @ execute ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . fetch Weather Ġ{ Ġfirst Weather Entry Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( first Weather Entry Ġ!= Ġnull ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinitialize Web cam Data ( first Weather Entry ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġinitialize Web cam Data ( weather Entry : ĠWeather Entry ?) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġweather Ġ= Ġweather Entry Ġ?: Ġm Weather Dao . getOne Random Weather Entry () Ġ?: Ġreturn @ execute ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( initialized Web c ams ) Ġreturn @ execute ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitialized Web c ams Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . schedule Fetch Web c ams ( weather ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Fetch Web c ams Needed ) Ġreturn @ execute ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . fetch Web c ams Ġ( weather . lat , Ġweather . lon ){ success Ġ-> ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Synchron ized ĊĠĠĠ Ġprivate Ġfun Ġinit Data Current Weather () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( initialized Current Weather ) Ġreturn ĊĠĠĠĠĠĠĠ Ġinitialized Current Weather Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġm Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Fetch Current Weather Needed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġm Network DataSource . fetch Current Weather () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdelete Old Weather Data () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠĠĠĠĠ ĠDate Ġtoday Ġ= ĠSun sh ine Date Utils . get Normalized Utc Date For Today (); ĊĠĠĠĠĠĠĠ Ġval Ġold Time Ġ= ĠcurrentTime Millis () Ġ- ĠHO UR _ IN _ M ILL IS ĊĠĠĠĠĠĠĠ Ġval Ġdate Ġ= ĠDate ( old Time ) ĊĠĠĠĠĠĠĠ Ġm Weather Dao . delete Old Weather ( date ) ĊĠĠĠ Ġ} Ċ Ġprivate Ġfun Ġdelete Old Web c ams Data () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Weather Dao . delete Old Web c ams ( Date ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetCurrent Weather ( timestamp : ĠLong ): ĠLive Data < List < Weather Entry >> ? Ġ{ ĊĠĠĠĠĠĠĠ Ġrefresh Data Current Weather () ĊĠĠĠĠĠĠĠ Ġval Ġrecently M ills Ġ= Ġtimestamp Ġ- ĠDate Utils . MINUTE _ IN _ M ILL IS Ġ* Ġdelay ĊĠĠĠĠĠĠĠ Ġval Ġrecent Date Ġ= ĠDate ( recent ly M ills ) ĊĠĠĠĠĠĠĠ Ġval Ġlimit Count Data Ġ= Ġif Ġ( is Test Mode ) Ġ 3 Ġelse Ġ 1 ĊĠĠĠĠĠĠĠ Ġlog (" get Ġcurrent Weather Ġmore Ġrecent Ġthan Ġ$ recent Date ") ĊĠĠĠĠĠĠĠ Ġreturn Ġm Weather Dao . getCurrent Weather ( recent Date , Ġlimit Count Data ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Weather Next Hours ( timestamp : ĠLong ): ĠLive Data < List < List Weather Entry >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdate Ġ= ĠDate ( timestamp Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġm Weather Dao . getCurrent Forecast ( date ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠFor ĠSingleton Ġinstantiation ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOCK Ġ= ĠAny () ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġs Instance : ĠRepository ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ@ Synchron ized ĊĠĠĠĠĠĠĠ Ġfun ĠgetInstance ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweather Dao : ĠWeather Dao , Ġnetwork DataSource : ĠNetwork DataSource , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexec utors : ĠApp Executors ĊĠĠĠĠĠĠĠ Ġ): ĠRepository Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Getting Ġthe Ġrepository ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( s Instance Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( LOCK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġs Instance Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRepository ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġweather Dao , Ġnetwork DataSource , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexec utors ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog (" Made Ġnew Ġrepository ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġs Instance !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval Ġdelay Ġ= Ġ 1 0 ĊĠĠĠ Ġ} Ċ }