package Ġeu . s ou f ian e . analytics . service Ċ Ċ import Ġcom . google . common . net . Internet DomainName Ċ import Ġcom . max mind . geo ip 2 . Database Reader Ċ import Ġcom . max mind . geo ip 2 . exception . Address NotFoundException Ċ import Ġcom . max mind . geo ip 2 . model . Country Response Ċ import Ġeu . s ou f ian e . analytics . model . Visitor Ċ import Ġeu . s ou f ian e . analytics . utils . ip To Inet Address Ċ import Ġkotlinx . coroutines .* Ċ import Ġmu . K Logging Ċ import Ġorg . eclipse . micro profile . config . inject . Config Property Ċ import Ġjava . net . URI Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjavax . inject . Inject Ċ import Ġjavax . inject . Singleton Ċ Ċ @ Singleton Ċ class ĠAnalytics Service ( private Ġval Ġindex Service : ĠIndex Service ) Ġ{ ĊĠ Ġcompanion Ġobject Ġ: ĠK Logging () ĊĊĠ Ġ@ Jvm Field ĊĠ Ġ@ Config Property ( name Ġ= Ġ" analytics . include - ip ") ĊĠ Ġvar Ġinclude Ip Ġ= Ġfalse ĊĊĠ Ġ@ Inject ĊĠ Ġlateinit Ġvar Ġuser Agent Service : ĠUser Agent Service ĊĊĠ Ġprivate Ġval Ġip Country Db Reader : ĠDatabase Reader ĊĠ Ġprivate Ġval Ġip Reader Context : ĠExecutor Coroutine Dispatcher Ġ= ĠExec utors . new Fixed ThreadPool ( 4 ). as Coroutine Dispatcher () ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġval Ġip Country Database Ġ= ĠAnalytics Service :: class . java . getResource AsStream ("/ Geo Lite 2 - Country . m mdb ") ĊĠĠĠ Ġip Country Db Reader Ġ= ĠDatabase Reader . Builder ( ip Country Database ). build () ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun Ġpage View ( data : ĠVisitor , Ġdry Run : ĠBoolean Ġ= Ġfalse ): ĠMap < String , ĠString > Ġ{ ĊĠĠĠ Ġval Ġdto Ġ= ĠLinkedHashMap < String , ĠString >() ĊĠĠĠ Ġval Ġother Parameters Ġ= Ġdata . other Parameters ĊĠĠĠ Ġdto [" date "] Ġ= Ġdata . date ĊĠĠĠ Ġdto [" page "] Ġ= Ġdata . page Ġ?: Ġ"" ĊĠĠĠ Ġ( other Parameters [" refer er "] Ġ?: Ġ""). let Ġ{ Ġrefer er Ġ-> ĊĠĠĠĠĠ Ġdto [" refer er "] Ġ= Ġrefer er ĊĠĠĠĠĠ Ġdto [" refer er Domain "] Ġ= Ġparse Refer er Domain ( refer er ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġip Ġ= Ġother Parameters [" ip "] Ġ?: Ġdata . ip ĊĠĠĠ Ġdto [" ip "] Ġ= Ġip ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ Ġparse Ip ( ip )?. let Ġ{ Ġ( country , Ġcontin ent ) Ġ-> ĊĠĠĠĠĠĠĠ Ġdto [" country "] Ġ= Ġcountry ĊĠĠĠĠĠĠĠ Ġdto [" cont inent "] Ġ= Ġcontin ent ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġua Ġ= Ġuser Agent Service . parse ( data . userAgent ) ĊĠĠĠĠĠ Ġdto [" device "] Ġ= Ġua . device ĊĠĠĠĠĠ Ġdto [" browser Name "] Ġ= Ġua . browser Name ĊĠĠĠĠĠ Ġdto [" browser "] Ġ= Ġua . browser ĊĠĠĠĠĠ Ġdto [" os "] Ġ= Ġua . os ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠ Ġdto [" browser "] Ġ= Ġdata . userAgent ĊĠĠĠĠĠ Ġlogger . error ( e ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Error Ġwhile Ġparsing Ġanalytics Ġdata " ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġdto . put All ( other Parameters ) ĊĠĠĠ Ġif Ġ(! include Ip ) Ġ{ ĊĠĠĠĠĠ Ġdto . remove (" ip ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( dry Run ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġdto ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġid Ġ= Ġgenerate Id () ĊĠĠĠ Ġval Ġdeferred s Ġ= Ġindex Service . page Views DAO s . map Ġ{ ĊĠĠĠĠĠ ĠGlobal Scope . async Ġ{ Ġit . index ( id , Ġdto ) Ġ} ĊĠĠĠ Ġ}. to Typed Array () ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ Ġawait All (* deferred s ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠ Ġlogger . error ( e ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Error Ġwhile Ġsending Ġdata Ġto Ġindex : Ġ${ e . message }\ n $ dto " ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġdto ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun Ġparse Ip ( ip : ĠString ): ĠPair < String , ĠString >? Ġ{ ĊĠĠĠ Ġif Ġ( ip Ġ== Ġ" 1 2 7 . 0 . 0 . 1 ") Ġ{ ĊĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġwith Context ( ip Reader Context ) Ġ{ ĊĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcountry Res Ġ= Ġparse Country ( ip ) ĊĠĠĠĠĠĠĠ Ġval Ġcountry Ġ= Ġcountry Res . country . name ĊĠĠĠĠĠĠĠ Ġval Ġcontin ent Ġ= Ġcountry Res . cont inent . name ĊĠĠĠĠĠĠĠ ĠPair ( country , Ġcontin ent ) ĊĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠAddress NotFoundException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġparse Country ( ip : ĠString ): ĠCountry Response Ġ= Ġip Country Db Reader . country ( ip To Inet Address ( ip )) ĊĊĠ Ġprivate Ġfun Ġgenerate Id () Ġ= ĠUUID . randomUUID (). toString () ĊĊĠ Ġprivate Ġfun Ġparse Refer er Domain ( refer er : ĠString ): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠ Ġif Ġ( refer er . startsWith (" android - app :// ")) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrefer er ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġdomain Ġ= ĠURI ( refer er ). host ?. toLowerCase () Ġ?: Ġreturn Ġ"" ĊĠĠĠĠĠ Ġif Ġ( domain . startsWith (" www . google .")) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" www . google . com " ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ@ Suppress (" Un stable Api Usage ") ĊĠĠĠĠĠ Ġreturn ĠInternet DomainName . from ( domain ). run Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Public Suffix ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġtop Private Domain (). toString () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġdomain ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠ Ġlogger . error Ġ{ Ġ" Error Ġwhile Ġparsing Ġthe Ġrefer er Ġdomain Ġfor : Ġ$ refer er " Ġ} ĊĠĠĠĠĠ Ġ"" ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ