arnaucube
arnaucube/jellyfin-toolsPublic Self-hosted repository
jellyfin-tools/jellyfin-year-review/docs/review.schema.json
jellyfin-year-review/docs/review.schema.jsonRaw
  1{
  2  "$schema": "https://json-schema.org/draft/2020-12/schema",
  3  "$id": "urn:reel-review:review:1",
  4  "title": "Owner-visible Reel Review v1",
  5  "type": "object",
  6  "properties": {
  7    "schemaVersion": {
  8      "const": 1
  9    },
 10    "rules": {
 11      "type": "object",
 12      "properties": {
 13        "minimumSeconds": {
 14          "type": "number",
 15          "minimum": 0
 16        },
 17        "completionPercent": {
 18          "type": "number",
 19          "exclusiveMinimum": 0,
 20          "maximum": 100
 21        },
 22        "marathonGapSeconds": {
 23          "type": "number",
 24          "minimum": 0,
 25          "maximum": 86400
 26        }
 27      },
 28      "required": [
 29        "minimumSeconds",
 30        "completionPercent",
 31        "marathonGapSeconds"
 32      ],
 33      "additionalProperties": false
 34    },
 35    "user": {
 36      "type": "object",
 37      "properties": {
 38        "id": {
 39          "type": "string",
 40          "pattern": "^[a-f0-9]{32}$"
 41        },
 42        "name": {
 43          "type": "string"
 44        }
 45      },
 46      "required": [
 47        "id",
 48        "name"
 49      ],
 50      "additionalProperties": false
 51    },
 52    "year": {
 53      "type": "integer",
 54      "minimum": 1970,
 55      "maximum": 9998
 56    },
 57    "timezone": {
 58      "type": "string"
 59    },
 60    "generatedAt": {
 61      "type": "string",
 62      "format": "date-time"
 63    },
 64    "source": {
 65      "type": "string"
 66    },
 67    "coverage": {
 68      "type": "string"
 69    },
 70    "availability": {
 71      "type": "object",
 72      "required": [
 73        "exactWatchTime",
 74        "completion",
 75        "marathon",
 76        "personality",
 77        "ranking"
 78      ],
 79      "additionalProperties": {
 80        "type": "object",
 81        "properties": {
 82          "available": {
 83            "type": "boolean"
 84          },
 85          "reason": {
 86            "type": "string"
 87          }
 88        },
 89        "required": [
 90          "available"
 91        ],
 92        "additionalProperties": false
 93      }
 94    },
 95    "seconds": {
 96      "type": "number",
 97      "minimum": 0
 98    },
 99    "movieSeconds": {
100      "type": "number",
101      "minimum": 0
102    },
103    "tvSeconds": {
104      "type": "number",
105      "minimum": 0
106    },
107    "records": {
108      "type": "integer",
109      "minimum": 0
110    },
111    "uniqueTitles": {
112      "type": "integer",
113      "minimum": 0
114    },
115    "activeDays": {
116      "type": "integer",
117      "minimum": 0
118    },
119    "movies": {
120      "type": "array",
121      "items": {
122        "type": "object",
123        "properties": {
124          "id": {
125            "type": "string"
126          },
127          "title": {
128            "type": "string"
129          },
130          "poster": {
131            "type": "string",
132            "pattern": "^/art/[a-f0-9]{64}\\.jpg$"
133          },
134          "seconds": {
135            "type": "number",
136            "minimum": 0
137          },
138          "records": {
139            "type": "integer",
140            "minimum": 0
141          },
142          "completionPercent": {
143            "type": "number",
144            "minimum": 0,
145            "maximum": 100
146          }
147        },
148        "required": [
149          "id",
150          "title",
151          "seconds",
152          "records"
153        ],
154        "additionalProperties": false
155      }
156    },
157    "shows": {
158      "type": "array",
159      "items": {
160        "type": "object",
161        "properties": {
162          "id": {
163            "type": "string"
164          },
165          "title": {
166            "type": "string"
167          },
168          "poster": {
169            "type": "string",
170            "pattern": "^/art/[a-f0-9]{64}\\.jpg$"
171          },
172          "seconds": {
173            "type": "number",
174            "minimum": 0
175          },
176          "records": {
177            "type": "integer",
178            "minimum": 0
179          },
180          "completionPercent": {
181            "type": "number",
182            "minimum": 0,
183            "maximum": 100
184          }
185        },
186        "required": [
187          "id",
188          "title",
189          "seconds",
190          "records"
191        ],
192        "additionalProperties": false
193      }
194    },
195    "abandoned": {
196      "type": "array",
197      "items": {
198        "type": "object",
199        "properties": {
200          "id": {
201            "type": "string"
202          },
203          "title": {
204            "type": "string"
205          },
206          "poster": {
207            "type": "string",
208            "pattern": "^/art/[a-f0-9]{64}\\.jpg$"
209          },
210          "seconds": {
211            "type": "number",
212            "minimum": 0
213          },
214          "records": {
215            "type": "integer",
216            "minimum": 0
217          },
218          "completionPercent": {
219            "type": "number",
220            "minimum": 0,
221            "maximum": 100
222          }
223        },
224        "required": [
225          "id",
226          "title",
227          "seconds",
228          "records"
229        ],
230        "additionalProperties": false
231      }
232    },
233    "genres": {
234      "type": "array",
235      "items": {
236        "type": "object",
237        "properties": {
238          "name": {
239            "type": "string"
240          },
241          "seconds": {
242            "type": "number",
243            "minimum": 0
244          },
245          "records": {
246            "type": "integer",
247            "minimum": 0
248          }
249        },
250        "required": [
251          "name",
252          "seconds",
253          "records"
254        ],
255        "additionalProperties": false
256      }
257    },
258    "devices": {
259      "type": "array",
260      "items": {
261        "type": "object",
262        "properties": {
263          "name": {
264            "type": "string"
265          },
266          "seconds": {
267            "type": "number",
268            "minimum": 0
269          },
270          "records": {
271            "type": "integer",
272            "minimum": 0
273          }
274        },
275        "required": [
276          "name",
277          "seconds",
278          "records"
279        ],
280        "additionalProperties": false
281      }
282    },
283    "clients": {
284      "type": "array",
285      "items": {
286        "type": "object",
287        "properties": {
288          "name": {
289            "type": "string"
290          },
291          "seconds": {
292            "type": "number",
293            "minimum": 0
294          },
295          "records": {
296            "type": "integer",
297            "minimum": 0
298          }
299        },
300        "required": [
301          "name",
302          "seconds",
303          "records"
304        ],
305        "additionalProperties": false
306      }
307    },
308    "distributionMetric": {
309      "enum": [
310        "watched minutes",
311        "activity record ends (counts)"
312      ]
313    },
314    "marathon": {
315      "anyOf": [
316        {
317          "type": "object",
318          "properties": {
319            "start": {
320              "type": "string",
321              "format": "date-time"
322            },
323            "end": {
324              "type": "string",
325              "format": "date-time"
326            },
327            "watchedSeconds": {
328              "type": "number",
329              "minimum": 0
330            },
331            "elapsedSeconds": {
332              "type": "number",
333              "minimum": 0
334            },
335            "records": {
336              "type": "integer",
337              "minimum": 0
338            }
339          },
340          "required": [
341            "start",
342            "end",
343            "watchedSeconds",
344            "elapsedSeconds",
345            "records"
346          ],
347          "additionalProperties": false
348        },
349        {
350          "type": "null"
351        }
352      ]
353    },
354    "personality": {
355      "anyOf": [
356        {
357          "type": "object",
358          "properties": {
359            "name": {
360              "enum": [
361                "Night Owl",
362                "Early Bird",
363                "Weekend Warrior",
364                "Marathoner",
365                "Binge Watcher",
366                "Movie Buff",
367                "Series Devotee",
368                "Comfort Rewatcher",
369                "Genre Explorer",
370                "Prime-Time Regular",
371                "Daily Viewer",
372                "Seasonal Viewer",
373                "Short-Session Viewer",
374                "Balanced Viewer"
375              ]
376            },
377            "explanation": {
378              "type": "string"
379            }
380          },
381          "required": [
382            "name",
383            "explanation"
384          ],
385          "additionalProperties": false
386        },
387        {
388          "type": "null"
389        }
390      ]
391    },
392    "ranking": {
393      "anyOf": [
394        {
395          "type": "object",
396          "properties": {
397            "rank": {
398              "type": "integer",
399              "minimum": 1
400            },
401            "cohort": {
402              "type": "integer",
403              "minimum": 1
404            },
405            "percentile": {
406              "type": "number",
407              "minimum": 0,
408              "maximum": 100
409            },
410            "averageSeconds": {
411              "type": "number",
412              "minimum": 0
413            }
414          },
415          "required": [
416            "rank",
417            "cohort",
418            "percentile",
419            "averageSeconds"
420          ],
421          "additionalProperties": false
422        },
423        {
424          "type": "null"
425        }
426      ]
427    },
428    "warnings": {
429      "type": "array",
430      "items": {
431        "type": "string"
432      }
433    },
434    "hourly": {
435      "type": "array",
436      "items": {
437        "type": "number",
438        "minimum": 0
439      },
440      "minItems": 24,
441      "maxItems": 24
442    },
443    "weekdays": {
444      "type": "array",
445      "items": {
446        "type": "number",
447        "minimum": 0
448      },
449      "minItems": 7,
450      "maxItems": 7
451    },
452    "monthly": {
453      "type": "array",
454      "items": {
455        "type": "number",
456        "minimum": 0
457      },
458      "minItems": 12,
459      "maxItems": 12
460    },
461    "platforms": {
462      "type": "array",
463      "items": {
464        "type": "object",
465        "properties": {
466          "name": {
467            "type": "string"
468          },
469          "movies": {
470            "type": "integer",
471            "minimum": 0
472          },
473          "shows": {
474            "type": "integer",
475            "minimum": 0
476          }
477        },
478        "required": [
479          "name",
480          "movies",
481          "shows"
482        ],
483        "additionalProperties": false
484      }
485    }
486  },
487  "required": [
488    "schemaVersion",
489    "rules",
490    "user",
491    "year",
492    "timezone",
493    "generatedAt",
494    "source",
495    "coverage",
496    "availability",
497    "seconds",
498    "movieSeconds",
499    "tvSeconds",
500    "records",
501    "uniqueTitles",
502    "activeDays",
503    "movies",
504    "shows",
505    "abandoned",
506    "genres",
507    "devices",
508    "clients",
509    "distributionMetric",
510    "marathon",
511    "personality",
512    "ranking",
513    "warnings",
514    "hourly",
515    "weekdays",
516    "monthly"
517  ],
518  "additionalProperties": false
519}