• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brotherlogic / recordstats / 21038857004

15 Jan 2026 04:36PM UTC coverage: 63.232%. First build
21038857004

Pull #1794

github

brotherlogic
Track completion time
Pull Request #1794: Track completion time

6 of 9 new or added lines in 1 file covered. (66.67%)

270 of 427 relevant lines covered (63.23%)

0.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.97
/recordstatsutils.go
1
package main
2

3
import (
4
        "fmt"
5
        "math"
6
        "sort"
7
        "strings"
8
        "time"
9

10
        "github.com/prometheus/client_golang/prometheus"
11
        "github.com/prometheus/client_golang/prometheus/promauto"
12
        "golang.org/x/net/context"
13
        "google.golang.org/grpc/codes"
14
        "google.golang.org/grpc/status"
15

16
        rcpb "github.com/brotherlogic/recordcollection/proto"
17
        pb "github.com/brotherlogic/recordstats/proto"
18
)
19

20
var (
21
        unlistenedCDs = promauto.NewGauge(prometheus.GaugeOpts{
22
                Name: "recordstats_unlistened_cds",
23
                Help: "The oldest physical record",
24
        })
25
        unlistened12s = promauto.NewGauge(prometheus.GaugeOpts{
26
                Name: "recordstats_unlistened_12s",
27
                Help: "The oldest physical record",
28
        })
29
        unlistened45s = promauto.NewGauge(prometheus.GaugeOpts{
30
                Name: "recordstats_unlistened_45s",
31
                Help: "The oldest physical record",
32
        })
33
        unlistenedDigital = promauto.NewGauge(prometheus.GaugeOpts{
34
                Name: "recordstats_unlistened_digital",
35
                Help: "The oldest physical record",
36
        })
37

38
        oldest = promauto.NewGauge(prometheus.GaugeOpts{
39
                Name: "recordstats_oldest",
40
                Help: "The oldest physical record",
41
        })
42

43
        oldestIC = promauto.NewGauge(prometheus.GaugeOpts{
44
                Name: "recordstats_oldest_in_collection",
45
                Help: "The oldest physical record",
46
        })
47

48
        processed = promauto.NewGauge(prometheus.GaugeOpts{
49
                Name: "recordstats_processed",
50
                Help: "The number of records processed",
51
        })
52

53
        totalSales = promauto.NewGauge(prometheus.GaugeOpts{
54
                Name: "recordstats_total_sales",
55
                Help: "The number of records processed",
56
        })
57

58
        totalCompleteSales = promauto.NewGauge(prometheus.GaugeOpts{
59
                Name: "recordstats_total_sales_complete",
60
                Help: "The number of records processed",
61
        })
62

63
        totalToAuditions = promauto.NewGauge(prometheus.GaugeOpts{
64
                Name: "recordstats_total_to_be_auditioned",
65
                Help: "The number of records processed",
66
        })
67
        totalAuditions = promauto.NewGauge(prometheus.GaugeOpts{
68
                Name: "recordstats_total_auditioned",
69
                Help: "The number of records processed",
70
        })
71
        weekAuditioned = promauto.NewGauge(prometheus.GaugeOpts{
72
                Name: "recordstats_auditioned_week",
73
                Help: "Number of auditions this week",
74
        })
75
        scoreAuditioned = promauto.NewGaugeVec(prometheus.GaugeOpts{
76
                Name: "recordstats_auditioned_scores",
77
                Help: "All the auditioned scores",
78
        }, []string{"score"})
79
        totalUnfilled = promauto.NewGauge(prometheus.GaugeOpts{
80
                Name: "recordstats_unfiled",
81
                Help: "The number of records processed",
82
        })
83
        totalFilled = promauto.NewGauge(prometheus.GaugeOpts{
84
                Name: "recordstats_filed",
85
                Help: "The number of records processed",
86
        })
87
        rateFiled = promauto.NewGauge(prometheus.GaugeOpts{
88
                Name: "recordstats_filed_rate",
89
                Help: "The number of records processed",
90
        })
91
        oldestLBStaged = promauto.NewGauge(prometheus.GaugeOpts{
92
                Name: "recordstats_oldest_lb_staged",
93
                Help: "The number of records processed",
94
        })
95
        oldestLBHigh = promauto.NewGauge(prometheus.GaugeOpts{
96
                Name: "recordstats_oldest_lb_highschool",
97
                Help: "The number of records processed",
98
        })
99
        lastListen = promauto.NewGauge(prometheus.GaugeOpts{
100
                Name: "recordstats_last_listen",
101
                Help: "The number of records processed",
102
        })
103
        listenRate = promauto.NewGauge(prometheus.GaugeOpts{
104
                Name: "recordstats_listen_rate",
105
        })
106
        listenTodayRate = promauto.NewGauge(prometheus.GaugeOpts{
107
                Name: "recordstats_listen_today_rate",
108
        })
109
        listenTotal = promauto.NewGauge(prometheus.GaugeOpts{
110
                Name: "recordstats_days_to_listen",
111
        })
112
        cwidths = promauto.NewGauge(prometheus.GaugeOpts{
113
                Name: "recordstats_cwidths",
114
        })
115
        medianListen = promauto.NewGauge(prometheus.GaugeOpts{
116
                Name: "recordstats_median_listen",
117
                Help: "The number of records processed",
118
        })
119
        unlistened = promauto.NewGauge(prometheus.GaugeOpts{
120
                Name: "recordstats_unlistened",
121
                Help: "The number of records processed",
122
        })
123
        tValue = promauto.NewGaugeVec(prometheus.GaugeOpts{
124
                Name: "recordstats_total_value",
125
                Help: "The number of records processed",
126
        }, []string{"category", "filed"})
127

128
        aValue = promauto.NewGaugeVec(prometheus.GaugeOpts{
129
                Name: "recordstats_average_value",
130
                Help: "The number of records processed",
131
        }, []string{"category", "filed"})
132

133
        keeps = promauto.NewGaugeVec(prometheus.GaugeOpts{
134
                Name: "recordstats_keepers",
135
                Help: "The number of records kept",
136
        }, []string{"folder"})
137
        categories = promauto.NewGaugeVec(prometheus.GaugeOpts{
138
                Name: "recordstats_categories",
139
                Help: "The number of records kept",
140
        }, []string{"category", "filed"})
141
        withWeight = promauto.NewGaugeVec(prometheus.GaugeOpts{
142
                Name: "recordstats_weights",
143
                Help: "Records that have weights",
144
        }, []string{"category"})
145

146
        cdsToListen = promauto.NewGauge(prometheus.GaugeOpts{
147
                Name: "recordstats_cdstogo",
148
        })
149

150
        ripped = promauto.NewGaugeVec(prometheus.GaugeOpts{
151
                Name: "recordstats_ripped",
152
        }, []string{"ripped"})
153

154
        rippedInLastTwoWeeks = promauto.NewGauge(prometheus.GaugeOpts{
155
                Name: "recordstats_rippped_2w",
156
        })
157

158
        rippedCompletion = promauto.NewGauge(prometheus.GaugeOpts{
159
                Name: "recordstats_rip_completion",
160
        })
161
)
162

163
const (
164
        // CONFIG - where we store the stats config
165
        CONFIG = "/github.com/brotherlogic/recordstats/config"
166
)
167

168
func (s *Server) cleanCategories(ctx context.Context) error {
×
169
        data, _, err := s.KSclient.Read(ctx, CONFIG, &pb.Config{})
×
170
        if err != nil {
×
171
                return err
×
172
        }
×
173
        config := data.(*pb.Config)
×
174

×
175
        for id := range config.GetCategories() {
×
176
                _, err := s.getRecord(ctx, id)
×
177
                if status.Code(err) == codes.OutOfRange {
×
178
                        delete(config.Categories, id)
×
179
                }
×
180
        }
181

182
        return s.KSclient.Save(ctx, CONFIG, config)
×
183
}
184

185
func (s *Server) update(ctx context.Context, id int32) error {
1✔
186
        data, _, err := s.KSclient.Read(ctx, CONFIG, &pb.Config{})
1✔
187
        if err != nil {
1✔
188
                return err
×
189
        }
×
190
        config := data.(*pb.Config)
1✔
191
        cleanAuditions(config)
1✔
192

1✔
193
        if config.GetFiled() == nil {
2✔
194
                config.Filed = make(map[int32]rcpb.ReleaseMetadata_FileSize)
1✔
195
        }
1✔
196
        if config.GetFiledTime() == nil {
2✔
197
                config.FiledTime = make(map[int32]int64)
1✔
198
        }
1✔
199
        if config.GetLbLastTime() == nil {
2✔
200
                s.CtxLog(ctx, "RESTTING LB")
1✔
201
                config.LbLastTime = make(map[int32]int64)
1✔
202
        }
1✔
203
        if config.GetLbLastTimeHigh() == nil {
2✔
204
                s.CtxLog(ctx, "RESETTING LB HIGH")
1✔
205
                config.LbLastTimeHigh = make(map[int32]int64)
1✔
206
        }
1✔
207
        if config.GetLastListen() == nil {
2✔
208
                s.CtxLog(ctx, "RESETTING LB HIGH")
1✔
209
                config.LastListen = make(map[int32]int64)
1✔
210
        }
1✔
211
        if config.GetKeeps() == nil {
2✔
212
                config.Keeps = make(map[int32]rcpb.ReleaseMetadata_KeepState)
1✔
213
        }
1✔
214
        if config.GetFolder() == nil {
2✔
215
                config.Folder = make(map[int32]int32)
1✔
216
        }
1✔
217
        if config.GetCategories() == nil {
2✔
218
                config.Categories = make(map[int32]rcpb.ReleaseMetadata_Category)
1✔
219
        }
1✔
220
        if config.GetWeights() == nil {
2✔
221
                config.Weights = make(map[int32]int32)
1✔
222
        }
1✔
223
        if config.GetSleeves() == nil {
2✔
224
                config.Sleeves = make(map[int32]rcpb.ReleaseMetadata_SleeveState)
1✔
225
        }
1✔
226
        if config.GetIsDirty() == nil {
2✔
227
                config.IsDirty = make(map[int32]bool)
1✔
228
        }
1✔
229
        if config.GetScore() == nil {
2✔
230
                config.Score = make(map[int32]int32)
1✔
231
        }
1✔
232
        if config.GetLastRipDates() == nil {
2✔
233
                config.LastRipDates = make(map[int32]int64)
1✔
234
        }
1✔
235

236
        defer func() {
2✔
237
                s.computeUnlistenedCDs(ctx, config)
1✔
238
                s.computeUnlistened45s(ctx, config)
1✔
239
                s.computeUnlistened12s(ctx, config)
1✔
240
                s.computeUnlistenedDigital(ctx, config)
1✔
241
                s.computeLastRips(ctx, config)
1✔
242

1✔
243
                sleeveCount := float64(0)
1✔
244
                for id, state := range config.GetSleeves() {
2✔
245
                        if state == rcpb.ReleaseMetadata_VINYL_STORAGE_NO_INNER {
1✔
246
                                if config.GetCategories()[id] != rcpb.ReleaseMetadata_LISTED_TO_SELL && config.GetCategories()[id] != rcpb.ReleaseMetadata_SOLD_ARCHIVE {
×
247
                                        sleeveCount++
×
248
                                }
×
249
                        }
250
                }
251
                cwidths.Set(sleeveCount)
1✔
252
                weightCount := make(map[string]float64)
1✔
253
                for id, weight := range config.GetWeights() {
2✔
254
                        if weight > 0 {
2✔
255
                                weightCount[config.GetCategories()[id].String()]++
1✔
256
                        }
1✔
257
                }
258
                for cat, count := range weightCount {
2✔
259
                        withWeight.With(prometheus.Labels{"category": cat}).Set(count)
1✔
260
                }
1✔
261

262
                keepCount := make(map[int32]float64)
1✔
263
                for key, value := range config.GetKeeps() {
2✔
264
                        if value == rcpb.ReleaseMetadata_KEEPER {
1✔
265
                                keepCount[config.GetFolder()[key]]++
×
266
                        }
×
267
                }
268
                for folder, count := range keepCount {
1✔
269
                        keeps.With(prometheus.Labels{"folder": fmt.Sprintf("%v", folder)}).Set(count)
×
270
                }
×
271

272
                catCount := make(map[string]float64)
1✔
273
                for id, value := range config.GetCategories() {
2✔
274
                        catCount[fmt.Sprintf("%v|%v", value, config.GetFiled()[id])]++
1✔
275
                }
1✔
276
                for category, count := range catCount {
2✔
277
                        elems := strings.Split(category, "|")
1✔
278
                        categories.With(prometheus.Labels{"category": elems[0], "filed": elems[1]}).Set(count)
1✔
279
                }
1✔
280

281
                for _, value := range config.GetValues() {
2✔
282
                        tl := float32(0)
1✔
283
                        for _, v := range value.GetValue() {
2✔
284
                                tl += v
1✔
285
                        }
1✔
286

287
                        tValue.With(prometheus.Labels{"category": value.GetCategory(), "filed": value.GetFilling()}).Set(float64(tl))
1✔
288
                        aValue.With(prometheus.Labels{"category": value.GetCategory(), "filed": value.GetFilling()}).Set(float64(tl / float32(len(value.GetValue()))))
1✔
289
                }
290

291
                tA := 0
1✔
292
                tAA := 0
1✔
293

1✔
294
                wCount := 0
1✔
295
                sa := make(map[int32]int32)
1✔
296
                for _, auditioned := range config.GetAuditions() {
2✔
297
                        if auditioned.GetAudScore() > 0 {
1✔
298
                                sa[auditioned.GetAudScore()]++
×
299
                        }
×
300
                        if auditioned.GetValid() {
1✔
301
                                tA++
×
302
                                if auditioned.GetLastAudition() > 0 {
×
303
                                        tAA++
×
304
                                }
×
305
                        }
306
                        if time.Since(time.Unix(auditioned.GetLastAudition(), 0)) < time.Hour*24*7 {
1✔
307
                                wCount++
×
308
                        }
×
309
                }
310
                weekAuditioned.Set(float64(wCount))
1✔
311
                totalToAuditions.Set(float64(tA))
1✔
312
                totalAuditions.Set(float64(tAA))
1✔
313
                for key, val := range sa {
1✔
314
                        scoreAuditioned.With(prometheus.Labels{"score": fmt.Sprintf("%v", key)}).Set(float64(val))
×
315
                }
×
316

317
                tF := float64(0)
1✔
318
                tUF := float64(0)
1✔
319
                for _, fu := range config.GetFiled() {
2✔
320
                        if fu == rcpb.ReleaseMetadata_FILE_UNKNOWN {
2✔
321
                                tUF++
1✔
322
                        } else {
1✔
323
                                tF++
×
324
                        }
×
325
                }
326
                totalFilled.Set(tF)
1✔
327
                totalUnfilled.Set(tUF)
1✔
328

1✔
329
                rate := float64(0)
1✔
330
                for _, t := range config.GetFiledTime() {
1✔
331
                        if time.Since(time.Unix(t, 0)) < time.Hour*24*7 {
×
332
                                rate++
×
333
                        }
×
334
                }
335
                rateFiled.Set(rate / 7)
1✔
336

1✔
337
                lax := time.Now().Unix()
1✔
338
                for _, v := range config.GetLbLastTime() {
1✔
339
                        if v < lax {
×
340
                                lax = v
×
341
                        }
×
342
                }
343
                oldestLBStaged.Set(float64(time.Since(time.Unix(lax, 0)).Seconds()))
1✔
344

1✔
345
                ll := time.Now().Unix()
1✔
346
                unlisten := float64(0)
1✔
347
                listens := make([]int, 0)
1✔
348
                last14 := float64(0)
1✔
349
                today := float64(0)
1✔
350
                for iid, v := range config.GetLastListen() {
2✔
351
                        if time.Since(time.Unix(v, 0)) < time.Hour*24*14 {
1✔
352
                                last14++
×
353
                        }
×
354
                        if time.Since(time.Unix(v, 0)) < time.Hour*24 {
1✔
355
                                s.CtxLog(ctx, fmt.Sprintf("FOUND TODAY: %v", iid))
×
356
                                today++
×
357
                        }
×
358
                        if v < ll && v > 0 {
1✔
359
                                ll = v
×
360
                        }
×
361
                        if v == 0 {
2✔
362
                                unlisten++
1✔
363
                        } else {
1✔
364
                                listens = append(listens, int(v))
×
365
                        }
×
366
                }
367
                sort.Ints(listens)
1✔
368
                if len(listens) > 0 {
1✔
369
                        medianListen.Set(float64(listens[len(listens)/2]))
×
370
                }
×
371

372
                lastListen.Set(float64(ll))
1✔
373
                unlistened.Set(unlisten)
1✔
374

1✔
375
                listenTodayRate.Set(float64(today))
1✔
376
                listenRate.Set(float64(last14 / 14))
1✔
377
                listenTotal.Set(float64(len(config.GetLastListen())) / (last14 / 14))
1✔
378

1✔
379
                laxhs := time.Now().Unix()
1✔
380
                for _, v := range config.GetLbLastTimeHigh() {
1✔
381
                        if v < laxhs {
×
382
                                laxhs = v
×
383
                        }
×
384
                }
385
                oldestLBHigh.Set(float64(time.Since(time.Unix(laxhs, 0)).Seconds()))
1✔
386

1✔
387
                oldestInCollection := int64(math.MaxInt64)
1✔
388
                boing := int32(0)
1✔
389
                for iid, v := range config.GetLastListen() {
2✔
390
                        if config.GetCategories()[iid] == rcpb.ReleaseMetadata_IN_COLLECTION {
1✔
391
                                if v < int64(oldestInCollection) {
×
392
                                        oldestInCollection = v
×
393
                                        boing = iid
×
394
                                }
×
395
                        }
396
                }
397
                oldestIC.Set(float64(oldestInCollection))
1✔
398

1✔
399
                s.CtxLog(ctx, fmt.Sprintf("THE OLDEST IC IS %v", boing))
1✔
400
        }()
401

402
        if id > 1 {
2✔
403
                rec, err := s.getRecord(ctx, id)
1✔
404
                if err != nil {
1✔
405
                        if status.Convert(err).Code() == codes.OutOfRange {
×
406
                                delete(config.LastListen, id)
×
407
                                delete(config.LbLastTimeHigh, id)
×
408
                                delete(config.LbLastTime, id)
×
409
                                delete(config.Categories, id)
×
410
                                return s.KSclient.Save(ctx, CONFIG, config)
×
411
                        }
×
412
                        return err
×
413
                }
414

415
                config.IsDirty[id] = rec.GetMetadata().GetDirty()
1✔
416
                config.Weights[id] = rec.GetMetadata().GetWeightInGrams()
1✔
417
                config.Folder[id] = rec.GetRelease().GetFolderId()
1✔
418
                config.Keeps[id] = rec.GetMetadata().GetKeep()
1✔
419
                config.Categories[id] = rec.GetMetadata().GetCategory()
1✔
420
                config.Sleeves[id] = rec.GetMetadata().GetSleeve()
1✔
421
                config.Score[id] = rec.GetRelease().GetRating()
1✔
422
                if rec.GetMetadata().GetSetRating() != 0 {
1✔
423
                        if rec.GetMetadata().GetSetRating() < 0 {
×
424
                                config.Score[id] = 0
×
425
                        } else {
×
426
                                config.Score[id] = rec.GetMetadata().GetSetRating()
×
427
                        }
×
428
                }
429
                s.CtxLog(ctx, fmt.Sprintf("Score (%v) -> %v", id, config.Score[id]))
1✔
430

1✔
431
                vfound := false
1✔
432
                for _, value := range config.GetValues() {
1✔
433
                        if rec.Metadata.GetCategory().String() == value.GetCategory() && rec.Metadata.GetFiledUnder().String() == value.GetFilling() {
×
434
                                vfound = true
×
435
                                if value.Value == nil {
×
436
                                        value.Value = make(map[int32]float32)
×
437
                                }
×
438
                                value.Value[rec.GetRelease().GetInstanceId()] = float32(rec.GetMetadata().GetCurrentSalePrice())
×
439
                        } else {
×
440
                                delete(value.GetValue(), rec.GetRelease().GetInstanceId())
×
441
                        }
×
442
                }
443
                if !vfound {
2✔
444
                        val := &pb.Values{
1✔
445
                                Category: rec.GetMetadata().GetCategory().String(),
1✔
446
                                Filling:  rec.GetMetadata().GetFiledUnder().String(),
1✔
447
                                Value:    make(map[int32]float32),
1✔
448
                        }
1✔
449
                        val.Value[rec.Release.GetInstanceId()] = float32(rec.GetMetadata().GetCurrentSalePrice())
1✔
450
                        config.Values = append(config.Values, val)
1✔
451
                }
1✔
452

453
                if rec.Metadata.GetCategory() != rcpb.ReleaseMetadata_SOLD_ARCHIVE &&
1✔
454
                        rec.Metadata.GetCategory() != rcpb.ReleaseMetadata_PARENTS {
2✔
455
                        config.LastListen[rec.GetRelease().GetInstanceId()] = rec.GetMetadata().GetLastListenTime()
1✔
456
                } else {
1✔
457
                        delete(config.LastListen, rec.GetRelease().GetInstanceId())
×
458
                }
×
459

460
                if rec.Release.GetFolderId() == 673768 || rec.Release.GetFolderId() == 3578980 {
1✔
461
                        if rec.GetMetadata().GetCategory() == rcpb.ReleaseMetadata_STAGED {
×
462
                                config.LbLastTime[rec.GetRelease().GetInstanceId()] = rec.GetMetadata().GetLastListenTime()
×
463
                                delete(config.LbLastTimeHigh, rec.GetRelease().GetInstanceId())
×
464
                        } else if rec.GetMetadata().GetCategory() == rcpb.ReleaseMetadata_HIGH_SCHOOL {
×
465
                                config.LbLastTimeHigh[rec.GetRelease().GetInstanceId()] = rec.GetMetadata().GetLastListenTime()
×
466
                                delete(config.LbLastTime, rec.GetRelease().GetInstanceId())
×
467
                        } else {
×
468
                                delete(config.LbLastTimeHigh, rec.GetRelease().GetInstanceId())
×
469
                                delete(config.LbLastTime, rec.GetRelease().GetInstanceId())
×
470
                        }
×
471
                } else {
1✔
472
                        delete(config.LbLastTime, rec.GetRelease().GetInstanceId())
1✔
473
                        delete(config.LbLastTimeHigh, rec.GetRelease().GetInstanceId())
1✔
474
                }
1✔
475

476
                exist, ok := config.Filed[id]
1✔
477
                config.Filed[id] = rec.Metadata.GetFiledUnder()
1✔
478
                if (!ok || exist == rcpb.ReleaseMetadata_FILE_UNKNOWN) && rec.GetMetadata().GetFiledUnder() != rcpb.ReleaseMetadata_FILE_UNKNOWN {
1✔
479
                        config.FiledTime[id] = time.Now().Unix()
×
480
                }
×
481

482
                found := false
1✔
483
                for _, aud := range config.GetAuditions() {
1✔
484
                        if aud.GetInstanceId() == id {
×
485
                                aud.Valid = rec.GetMetadata().GetCategory() == rcpb.ReleaseMetadata_IN_COLLECTION &&
×
486
                                        (rec.GetMetadata().GetBoxState() == rcpb.ReleaseMetadata_BOX_UNKNOWN ||
×
487
                                                rec.GetMetadata().GetBoxState() == rcpb.ReleaseMetadata_OUT_OF_BOX)
×
488
                                aud.LastAudition = rec.GetMetadata().GetLastAudition()
×
489
                                aud.AudScore = rec.GetMetadata().GetAuditionScore()
×
490
                                found = true
×
491
                                break
×
492
                        }
493
                }
494

495
                if !found {
2✔
496
                        config.Auditions = append(config.Auditions, &pb.Auditioned{
1✔
497
                                Valid: rec.GetMetadata().GetCategory() == rcpb.ReleaseMetadata_IN_COLLECTION &&
1✔
498
                                        (rec.GetMetadata().GetBoxState() == rcpb.ReleaseMetadata_BOX_UNKNOWN ||
1✔
499
                                                rec.GetMetadata().GetBoxState() == rcpb.ReleaseMetadata_OUT_OF_BOX),
1✔
500
                                LastAudition: rec.GetMetadata().GetLastAudition(),
1✔
501
                                AudScore:     rec.GetMetadata().GetAuditionScore(),
1✔
502
                                InstanceId:   rec.GetRelease().GetInstanceId(),
1✔
503
                        })
1✔
504
                }
1✔
505

506
                if rec.GetMetadata().GetCategory() == rcpb.ReleaseMetadata_SOLD_ARCHIVE {
1✔
507
                        found := false
×
508
                        for _, entry := range config.GetCompleteSales() {
×
509
                                if entry.GetInstanceId() == rec.GetRelease().GetInstanceId() {
×
510
                                        found = true
×
511
                                        entry.HasCost = rec.GetMetadata().GetSoldPrice() > 0
×
512
                                }
×
513
                        }
514

515
                        if !found {
×
516
                                config.CompleteSales = append(config.CompleteSales,
×
517
                                        &pb.CompleteSale{
×
518
                                                InstanceId: rec.GetRelease().GetInstanceId(),
×
519
                                                HasCost:    rec.GetMetadata().GetSoldPrice() > 0,
×
520
                                        })
×
521
                        }
×
522
                } else {
1✔
523
                        var centries []*pb.CompleteSale
1✔
524
                        for _, entry := range config.GetCompleteSales() {
1✔
525
                                if entry.GetInstanceId() != rec.GetRelease().GetInstanceId() {
×
526
                                        centries = append(centries, entry)
×
527
                                }
×
528
                        }
529
                        config.CompleteSales = centries
1✔
530
                }
531

532
                completes := 0
1✔
533
                fullCompletes := 0
1✔
534
                for _, entry := range config.GetCompleteSales() {
1✔
535
                        completes++
×
536
                        if entry.HasCost {
×
537
                                fullCompletes++
×
538
                        }
×
539
                }
540
                totalSales.Set(float64(completes))
1✔
541
                totalCompleteSales.Set(float64(fullCompletes))
1✔
542

1✔
543
                if rec.GetMetadata().GetLastListenTime() < config.GetLastListenTime() && rec.GetMetadata().GetLastListenTime() > 0 {
1✔
544
                        config.LastListenTime = rec.GetMetadata().GetLastListenTime()
×
545
                        oldest.Set(float64(config.LastListenTime))
×
546
                }
×
547

548
                config.LastRipDates[rec.GetRelease().GetInstanceId()] = rec.GetMetadata().GetLastRipDate()
1✔
549
        }
550

551
        return s.KSclient.Save(ctx, CONFIG, config)
1✔
552
}
553

554
func (s *Server) computeUnlistenedCDs(ctx context.Context, config *pb.Config) {
1✔
555
        count := 0
1✔
556
        for id, val := range config.GetCategories() {
2✔
557
                if val == rcpb.ReleaseMetadata_UNLISTENED {
1✔
558
                        if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_CD && config.GetScore()[id] == 0 && config.GetWeights()[id] == 0 && !config.GetIsDirty()[id] {
×
559
                                s.CtxLog(ctx, fmt.Sprintf("FOUND_CD %v (%v)", id, config.GetScore()[id]))
×
560
                                count++
×
561
                        }
×
562
                }
563
        }
564
        unlistenedCDs.Set(float64(count))
1✔
565
}
566

567
func (s *Server) computeUnlistened12s(ctx context.Context, config *pb.Config) {
1✔
568
        count := 0
1✔
569
        for id, val := range config.GetCategories() {
2✔
570
                if val == rcpb.ReleaseMetadata_UNLISTENED {
1✔
571
                        if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_12_INCH && config.GetScore()[id] == 0 && !config.GetIsDirty()[id] {
×
572
                                s.CtxLog(ctx, fmt.Sprintf("FOUND_12 %v (%v)", id, config.GetScore()[id]))
×
573
                                count++
×
574
                        }
×
575
                }
576
        }
577
        unlistened12s.Set(float64(count))
1✔
578
}
579

580
func (s *Server) computeUnlistened45s(ctx context.Context, config *pb.Config) {
1✔
581
        count := 0
1✔
582
        for id, val := range config.GetCategories() {
2✔
583
                if val == rcpb.ReleaseMetadata_UNLISTENED || val == rcpb.ReleaseMetadata_ARRIVED {
1✔
584
                        if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_7_INCH && config.GetScore()[id] == 0 && !config.GetIsDirty()[id] {
×
585
                                s.CtxLog(ctx, fmt.Sprintf("FOUND_45 %v (%v)", id, config.GetScore()[id]))
×
586
                                count++
×
587
                        }
×
588
                }
589

590
                if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_7_INCH {
1✔
591
                        s.CtxLog(ctx, fmt.Sprintf("FOUND_45 %v", id))
×
592
                }
×
593
        }
594
        unlistened45s.Set(float64(count))
1✔
595
}
596

597
func (s *Server) computeUnlistenedDigital(ctx context.Context, config *pb.Config) {
1✔
598
        count := 0
1✔
599
        for id, val := range config.GetCategories() {
2✔
600
                if val == rcpb.ReleaseMetadata_UNLISTENED {
1✔
601
                        s.CtxLog(ctx, fmt.Sprintf("FOUND_DIG: %v -> %v", id, config.GetFiled()[id]))
×
602
                        if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_DIGITAL && config.GetScore()[id] == 0 && config.GetWeights()[id] == 0 && !config.GetIsDirty()[id] {
×
603
                                count++
×
604
                        }
×
605
                }
606
        }
607
        unlistenedDigital.Set(float64(count))
1✔
608
}
609

610
func (s *Server) computeOldest(ctx context.Context) (err error) {
1✔
611
        folders, err := s.getPhysicalFolders(ctx)
1✔
612
        if err != nil {
1✔
613
                return err
×
614
        }
×
615
        oldestTime := time.Now().Unix()
1✔
616
        var r *rcpb.Record
1✔
617
        s.CtxLog(ctx, fmt.Sprintf("Folders are %v", folders))
1✔
618

1✔
619
        for _, folder := range folders {
2✔
620
                ids, err := s.getInstanceIds(ctx, folder)
1✔
621
                if err != nil {
1✔
622
                        return err
×
623
                }
×
624

625
                for _, id := range ids {
2✔
626
                        rec, err := s.getRecord(ctx, id)
1✔
627
                        if err != nil {
1✔
628
                                return err
×
629
                        }
×
630
                        if rec.GetMetadata().GetLastListenTime() < oldestTime {
2✔
631
                                oldestTime = rec.GetMetadata().GetLastListenTime()
1✔
632
                                r = rec
1✔
633
                        }
1✔
634
                }
635
        }
636

637
        s.CtxLog(ctx, fmt.Sprintf("Found %v - %v", r.GetRelease().GetInstanceId(), r.GetRelease().GetTitle()))
1✔
638
        oldest.Set(float64(oldestTime))
1✔
639

1✔
640
        return nil
1✔
641
}
642

643
func (s *Server) computeLastRips(ctx context.Context, config *pb.Config) {
1✔
644
        cripped := 0
1✔
645
        notRipped := 0
1✔
646
        last2w := 0
1✔
647

1✔
648
        for id, category := range config.GetCategories() {
2✔
649
                if category != rcpb.ReleaseMetadata_SOLD_ARCHIVE && category != rcpb.ReleaseMetadata_LISTED_TO_SELL {
2✔
650
                        if config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_12_INCH || config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_7_INCH || config.GetFiled()[id] == rcpb.ReleaseMetadata_FILE_TAPE {
1✔
651
                                if config.GetLastRipDates()[id] > 0 {
×
NEW
652
                                        if time.Since(time.Unix(config.GetLastRipDates()[id], 0)) < time.Hour*24*14 {
×
NEW
653
                                                last2w++
×
NEW
654
                                        }
×
655
                                        cripped++
×
656
                                } else {
×
657
                                        notRipped++
×
658
                                }
×
659
                        }
660
                }
661
        }
662

663
        ripped.With(prometheus.Labels{"ripped": "ripped"}).Set(float64(cripped))
1✔
664
        ripped.With(prometheus.Labels{"ripped": "notripped"}).Set(float64(notRipped))
1✔
665
        rippedInLastTwoWeeks.Set(float64(last2w))
1✔
666

1✔
667
        perDay := float64(last2w) / 14.0
1✔
668
        daysToDo := float64(notRipped) / perDay
1✔
669
        rippedCompletion.Set(float64(time.Now().Unix()) + daysToDo*24*60*60)
1✔
670
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc