66using System . Threading ;
77using System . Threading . Tasks ;
88using GitHub . Helpers ;
9- using GitHub . Models ;
10- using Task = System . Threading . Tasks . Task ;
119using GitHub . Logging ;
10+ using GitHub . Models ;
11+ using Rothko ;
1212using Serilog ;
13+ using Environment = System . Environment ;
14+ using Task = System . Threading . Tasks . Task ;
1315
1416namespace GitHub . Services
1517{
1618 [ Export ( typeof ( IUsageService ) ) ]
1719 public class UsageService : IUsageService
1820 {
19- static readonly ILogger log = LogManager . ForContext < UsageService > ( ) ;
2021 const string StoreFileName = "ghfvs.usage" ;
22+ const string UserStoreFileName = "user.json" ;
23+
24+ static readonly ILogger log = LogManager . ForContext < UsageService > ( ) ;
2125 static readonly Calendar cal = CultureInfo . InvariantCulture . Calendar ;
26+
2227 readonly IGitHubServiceProvider serviceProvider ;
28+ readonly IEnvironment environment ;
29+
2330 string storePath ;
31+ string userStorePath ;
32+ Guid ? userGuid ;
2433
2534 [ ImportingConstructor ]
26- public UsageService ( IGitHubServiceProvider serviceProvider )
35+ public UsageService ( IGitHubServiceProvider serviceProvider , IEnvironment environment )
2736 {
2837 this . serviceProvider = serviceProvider ;
38+ this . environment = environment ;
39+ }
40+
41+ public async Task < Guid > GetUserGuid ( )
42+ {
43+ await Initialize ( ) ;
44+
45+ if ( ! userGuid . HasValue )
46+ {
47+ try
48+ {
49+ if ( File . Exists ( userStorePath ) )
50+ {
51+ var json = await ReadAllTextAsync ( userStorePath ) ;
52+ var data = SimpleJson . DeserializeObject < UserData > ( json ) ;
53+ userGuid = data . UserGuid ;
54+ }
55+ }
56+ catch ( Exception ex )
57+ {
58+ log . Error ( ex , "Failed reading user metrics GUID" ) ;
59+ }
60+ }
61+
62+ if ( ! userGuid . HasValue || userGuid . Value == Guid . Empty )
63+ {
64+ userGuid = Guid . NewGuid ( ) ;
65+
66+ try
67+ {
68+ var data = new UserData { UserGuid = userGuid . Value } ;
69+ var json = SimpleJson . SerializeObject ( data ) ;
70+ await WriteAllTextAsync ( userStorePath , json ) ;
71+ }
72+ catch ( Exception ex )
73+ {
74+ log . Error ( ex , "Failed writing user metrics GUID" ) ;
75+ }
76+ }
77+
78+ return userGuid . Value ;
2979 }
3080
3181 public bool IsSameDay ( DateTimeOffset lastUpdated )
@@ -49,7 +99,7 @@ public IDisposable StartTimer(Func<Task> callback, TimeSpan dueTime, TimeSpan pe
4999 async _ =>
50100 {
51101 try { await callback ( ) ; }
52- catch { /* log.Warn( "Failed submitting usage data", ex); */ }
102+ catch ( Exception ex ) { log . Warning ( ex , "Failed submitting usage data" ) ; }
53103 } ,
54104 null ,
55105 dueTime ,
@@ -66,7 +116,11 @@ public async Task<UsageData> ReadLocalData()
66116 {
67117 return json != null ?
68118 SimpleJson . DeserializeObject < UsageData > ( json ) :
69- new UsageData { Model = new UsageModel ( ) } ;
119+ new UsageData
120+ {
121+ Model = new UsageModel ( ) ,
122+ LastUpdated = DateTimeOffset . Now . UtcDateTime
123+ } ;
70124 }
71125 catch ( Exception ex )
72126 {
@@ -83,7 +137,7 @@ public async Task WriteLocalData(UsageData data)
83137 var json = SimpleJson . SerializeObject ( data ) ;
84138 await WriteAllTextAsync ( storePath , json ) ;
85139 }
86- catch ( Exception ex )
140+ catch ( Exception ex )
87141 {
88142 log . Error ( ex , "Failed to write usage data" ) ;
89143 }
@@ -96,10 +150,11 @@ async Task Initialize()
96150 await ThreadingHelper . SwitchToMainThreadAsync ( ) ;
97151
98152 var program = serviceProvider . GetService < IProgram > ( ) ;
99- storePath = Path . Combine (
100- Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ,
101- program . ApplicationName ,
102- StoreFileName ) ;
153+
154+ var localApplicationDataPath = environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ;
155+
156+ storePath = Path . Combine ( localApplicationDataPath , program . ApplicationName , StoreFileName ) ;
157+ userStorePath = Path . Combine ( localApplicationDataPath , program . ApplicationName , UserStoreFileName ) ;
103158 }
104159 }
105160
@@ -136,5 +191,10 @@ static int GetIso8601WeekOfYear(DateTimeOffset time)
136191 // Return the week of our adjusted day
137192 return cal . GetWeekOfYear ( time . UtcDateTime , CalendarWeekRule . FirstFourDayWeek , DayOfWeek . Monday ) ;
138193 }
194+
195+ class UserData
196+ {
197+ public Guid UserGuid { get ; set ; }
198+ }
139199 }
140200}
0 commit comments