1- import { Bucket , listBuckets } from "@api/quantified-resume"
1+ import { batchCreateItems , Bucket , createBucket , Item , listAllItems , listBuckets , removeBucket , updateBucket } from "@api/quantified-resume"
2+ import metaMessages , { } from "@i18n/message/common/meta"
3+ import { t } from "@i18n"
4+ import { groupBy } from "@util/array"
5+ import { formatTimeYMD , parseTime } from "@util/time"
26
37export type QuantifiedResumeCache = {
48 bucketIds : {
@@ -7,34 +11,54 @@ export type QuantifiedResumeCache = {
711 }
812}
913
10- async function getBucketId ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > ) : Promise < number > {
11- const { cid, cache } = context || { }
14+ async function createNewBucket ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > ) : Promise < number > {
15+ const { cid, cname } = context || { }
16+ const { endpoint } = context ?. ext || { }
17+ const appName = t ( metaMessages , { key : msg => msg . name } )
18+ const bucket : Bucket = {
19+ name : `${ appName } : ${ cid } ` ,
20+ builtin : "BrowserTime" ,
21+ builtinRefId : cid ,
22+ payload : { name : cname }
23+ }
24+ return createBucket ( { endpoint } , bucket )
25+ }
26+
27+ async function getBucketId ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , specificCid ?: string ) : Promise < number > {
28+ const cid = specificCid || context ?. cid
29+ const { cache } = context || { }
1230 // 1. query from cache
1331 let bucketId = cache ?. bucketIds ?. [ cid ]
14- if ( ! bucketId ) return bucketId
32+ if ( bucketId ) return bucketId
1533
1634 const { endpoint } = context ?. ext || { }
1735 // 2. query again
18- bucketId = ( await listBuckets ( { endpoint } , cid ) ) ?. [ 0 ] ?. id
19- // TODO
36+ bucketId = ( await listBuckets ( { endpoint } , cid ) ) ?. filter ( b => b . builtinRefId === cid ) ?. [ 0 ] ?. id
2037 if ( ! bucketId ) {
2138 // 3. create one
22- const bucket : Bucket = {
23- name : "Time Tracker: " + cid ,
24- builtin : "BrowserTime" ,
25- builtinRefId : cid ,
26- payload : {
27- name : ""
28- }
29- }
39+ bucketId = await createNewBucket ( context )
3040 }
31- throw new Error ( "TODO" )
41+ return bucketId
3242}
3343
3444export default class QuantifiedResumeCoordinator implements timer . backup . Coordinator < QuantifiedResumeCache > {
35-
36- updateClients ( _ : timer . backup . CoordinatorContext < QuantifiedResumeCache > , clients : timer . backup . Client [ ] ) : Promise < void > {
37- throw new Error ( "Method not implemented." ) ;
45+ async updateClients ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , clients : timer . backup . Client [ ] ) : Promise < void > {
46+ const { endpoint } = context ?. ext || { }
47+ const existBuckets = groupBy ( await listBuckets ( { endpoint } ) || [ ] , b => b . builtinRefId , l => l ?. [ 0 ] )
48+ if ( ! clients ?. length ) return
49+ const promises = Promise . all ( clients . map (
50+ async ( { id, name, minDate, maxDate } ) => {
51+ const exist = existBuckets [ id ]
52+ if ( exist ) {
53+ // update payload
54+ exist . payload = { name, minDate, maxDate }
55+ await updateBucket ( { endpoint } , exist )
56+ } else {
57+ await createNewBucket ( context )
58+ }
59+ } )
60+ )
61+ await promises
3862 }
3963
4064 async listAllClients ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > ) : Promise < timer . backup . Client [ ] > {
@@ -60,13 +84,44 @@ export default class QuantifiedResumeCoordinator implements timer.backup.Coordin
6084 return result
6185 }
6286
63- download ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , dateStart : Date , dateEnd : Date , targetCid ?: string ) : Promise < timer . stat . RowBase [ ] > {
64- throw new Error ( "Method not implemented." ) ;
87+ async download ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , dateStart : Date , dateEnd : Date , targetCid ?: string ) : Promise < timer . stat . RowBase [ ] > {
88+ let bucketId = await getBucketId ( context , targetCid )
89+ if ( ! bucketId ) return [ ]
90+ const items = await listAllItems ( { endpoint : context ?. ext ?. endpoint } , bucketId )
91+ return items ?. map ( ( { name, timestamp, metrics } ) => ( {
92+ host : name ,
93+ date : formatTimeYMD ( timestamp ) ,
94+ focus : metrics ?. focus ,
95+ time : metrics ?. visit ,
96+ } satisfies timer . stat . RowBase ) ) || [ ]
6597 }
6698
6799 async upload ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , rows : timer . stat . RowBase [ ] ) : Promise < void > {
100+ if ( ! rows ?. length ) return
101+
68102 const bucketId = await getBucketId ( context )
69- throw new Error ( "Method not implemented." ) ;
103+ let items = rows . map ( ( { host, date, focus, time : visit } ) => {
104+ const time = parseTime ( date )
105+ time . setHours ( 0 )
106+ time . setMinutes ( 0 )
107+ time . setSeconds ( 0 )
108+ time . setMilliseconds ( 0 )
109+ const item : Item = {
110+ refId : `${ date } ${ host } ` ,
111+ timestamp : time . getTime ( ) ,
112+ metrics : { visit, focus } ,
113+ action : "web_time" ,
114+ name : host ,
115+ payload : { date, host, cid : context . cid } ,
116+ }
117+ return item
118+ } )
119+ const groups = groupBy ( items , ( _ , idx ) => Math . floor ( idx / 2000 ) , l => l )
120+
121+ const { endpoint } = context ?. ext || { }
122+ for ( const group of Object . values ( groups ) ) {
123+ await batchCreateItems ( { endpoint } , bucketId , group )
124+ }
70125 }
71126
72127 async testAuth ( _auth : timer . backup . Auth , ext : timer . backup . TypeExt ) : Promise < string > {
@@ -78,7 +133,9 @@ export default class QuantifiedResumeCoordinator implements timer.backup.Coordin
78133 }
79134 }
80135
81- clear ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , client : timer . backup . Client ) : Promise < void > {
82- throw new Error ( "Method not implemented." ) ;
136+ async clear ( context : timer . backup . CoordinatorContext < QuantifiedResumeCache > , client : timer . backup . Client ) : Promise < void > {
137+ const bucketId = await getBucketId ( context , client . id )
138+ if ( ! bucketId ) return
139+ await removeBucket ( { endpoint : context ?. ext ?. endpoint } , bucketId )
83140 }
84141}
0 commit comments