-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathchangelog.txt
More file actions
704 lines (612 loc) · 35.5 KB
/
changelog.txt
File metadata and controls
704 lines (612 loc) · 35.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
EasyTV Changelog
================
v1.5.1 (2026-03-24)
--------------------------
New Features:
- Showcase browse view: Fifth view style with horizontal poster filmstrip
layout. Shows watched badges on poster thumbnails.
- Heading areas on all five browse views: Each view now displays the addon
name, item count, and accent-line separator at the top.
- Icon theme selection: Choose from four bundled icon styles (Golden Hour,
Ultraviolet, Ember, Nightfall) or browse for a custom image. Kodi's texture
cache is automatically invalidated so icon changes appear immediately.
icon_default.png added for reliable icon reset. Custom icon choice persists
across addon upgrades.
- Dialog preview rewrite: Previews all eight dialog types using real library
data. Supports clone addon preview via third argument. Module-level data
caching for efficient "All Dialogs" cycling. Theme color picker menu before
main dialog menu.
- Missed episode warning upgraded to a poster-style dialog with show artwork,
matching the visual style of other EasyTV dialogs.
Improvements:
- EasyMovie UI parity: Harmonized visual design across both addons. Genre
display switched to slash-separated format. Duration format shortened
(e.g., "43m" instead of "43 min"). Big Screen view redesigned with show
title, episode title, and plot replacing fanart reflection. Split View
poster resized to fit between accent lines. Show selector now displays
selection count. Synopsis prefix removed from plot display.
- Clone updates are now mandatory — version mismatch enforces Update or
Cancel with no Skip option.
- Settings help text reworded for five settings for improved clarity.
- Added year, genres, and duration fields to browse ListItems for richer
metadata display in all view styles.
Internal:
- Added GitHub Actions CI validation workflow (syntax, pyflakes, pyright,
kodi-addon-checker, pytest).
- Simplified attribution to single-line historical acknowledgment.
- Added _temp to pyrightconfig.json exclude list.
v1.5.0 (2026-03-18)
--------------------------
New Features:
- Four browse view styles: Card List (default, data-dense rows with poster and
stats), Posters (visual poster grid), Big Screen (large artwork for 10-foot
viewing), and Split View (two-column layout with show list and detail panel).
- Theme selection: Choose from Golden Hour (default), Ultraviolet, Ember, or
Nightfall accent color themes. Configurable in Settings > Appearance.
- Custom icon selection: Set a custom addon icon for EasyTV or any clone via
Settings > Appearance. Reset to default also available.
- Redesigned dialogs: Main dialog, next-up prompt, playlist finished dialog,
and confirmation dialogs all use the new themed styling.
- Show selector redesign: Dedicated centered window with inline search, Enable
All/Ignore All bulk actions, and poster preview for the focused show.
- In-place browse list updates: The browse list refreshes after playback
completes without requiring a full window reload.
- Abandoned playback detection: The service detects when playback was stopped
early and handles episode tracking appropriately.
- Genre and duration info in browse views: All four view styles display the
show's genre and average episode duration with compact S01E01 notation.
- Duration sort and random sort options in browse mode.
- 3-state premiere filter: Series and season premieres settings now offer
Skip (exclude), Mix in (default), or Only (show exclusively premieres).
Bug Fixes:
- Fixed: Python 3.10+ type hints (X | Y syntax) breaking compatibility with
Kodi Windows builds running Python 3.8.
- Fixed: File handle leaks in log file initialization and clone updater when
exceptions occur during file operations.
- Fixed: Median duration calculation incorrect for shows with an even number
of episodes (off-by-one in middle element selection).
- Fixed: Episode and season numbers displayed as floats (e.g., "2.0") instead
of integers in some browse view layouts.
- Fixed: Potential infinite loop in browse mode when the dialog window fails
to open within the expected timeout.
- Fixed: Clone dialogs showing hardcoded "EasyTV" instead of the clone's
own addon name.
Improvements:
- Added top-level exception handlers to all script entry points, preventing
silent crashes from unhandled exceptions.
- Calendar-aware "last watched" display (shows "today", "yesterday" instead
of "0 days", "1 day").
Internal:
- Entry points (service.py, default.py) are now thin stubs delegating to
cached library modules for improved startup performance.
- Added unit test suite with 208 tests covering pure logic functions.
- Consolidated window property names and setting IDs into constants module.
- Replaced deprecated setInfo() calls with InfoTagVideo API.
- Removed dead code, added database column validation for shared sync storage.
v1.4.0 (2026-03-02)
--------------------------
New Features:
- Multi-instance sync: Share watch progress across multiple Kodi devices via
shared MariaDB database. Auto-detects configuration from advancedsettings.xml.
Includes automatic recovery after library rebuilds via title+year matching,
automatic cleanup of orphaned database entries on startup, and graceful
fallback to Kodi video DB if dedicated easytv database is unavailable.
Enable in Settings → Advanced → "Multi-instance sync".
- Positioned specials support: TVDB-positioned specials can now be included in
the watch order. Some shows (like SpongeBob) have specials that are
plot-relevant and should be watched between specific episodes. Non-positioned
specials remain excluded. Enable in Settings → Shows → "Include positioned
specials in watch order". Default: OFF.
- Replaced "Movie ratio" setting (0.0-1.0 slider) with "Movie chance" percentage
slider (0-100% in steps of 5). Added budget enforcement to playlist building —
both batch mode and lazy queue now track movies vs. shows and defer over-budget
items, ensuring the final playlist closely matches the configured percentage.
- Playlist continuation is now fully configurable. Added "If countdown expires"
setting to choose the default action (Stop or Generate new playlist). Countdown
timer displayed in prompt heading. Prompt only appears when the playlist finishes
naturally — manually stopping no longer triggers it. Countdown sliders now use
1-second steps. Works correctly in clones.
Bug Fixes:
- Fixed: Clone creation fails on SteamOS and other Arch-based Linux systems where
the system locale defaults to ASCII (POSIX/C locale). Replaced all
fileinput.input(inplace=True) calls with explicit open(..., encoding='utf-8')
read/write pattern.
- Fixed: Spurious "Show ID shifted, migrated to new ID" log messages on every
startup when all show IDs were unchanged. Validation logic now correctly treats
same-ID lookups as unchanged rather than migrated.
- Fixed: Partial prioritization in random playlists — stale resume points on
watched episodes (playcount > 0) no longer cause deterministic show ordering.
Only genuinely in-progress episodes are now treated as partials.
- Fixed: When a partial episode is detected and prioritized, the specific episode
is now served on first encounter in both batch and lazy queue playlist paths.
Previously the system detected the partial but discarded the episode ID.
- Fixed: Movie playlist filter bypassed the movie weight limit entirely. The limit
is now applied after playlist filter intersection.
- Fixed: Clone addon repeatedly prompting to update on every other launch after
main addon update. Clone update script now refreshes Kodi's in-memory addon
metadata cache before re-registering.
- Fixed: DialogProgress.update() called with 3 positional args (broke on Kodi 19+
which only accepts percent and message).
Performance:
- Batch write operations now use a single database transaction with one COMMIT at
the end, instead of committing independently per show. For 399 shows, reduces
fsync overhead from ~20s to ~50ms.
Diagnostics:
- Kodi video database backend (shared MariaDB vs local SQLite) is now logged at
service startup via advancedsettings.xml detection.
Internal:
- Resolved all 115 pyright type-checking errors across 12 files (now 0).
- Updated json_query() signature to accept batch queries (list of dicts).
- Code quality fixes in clone.py and update_clone.py (errorHandle defaults, XML
tree.find None checks).
- Batch ownership lifted from daemon.py to StorageBackend interface.
- Removed non-functional "Watch Order" settings from clone settings template.
v1.4.0~alpha8 (2026-02-28)
--------------------------
Bug Fixes:
- Fix playlist continuation settings ignored in clones — the per-addon setting
for generating a new playlist now works correctly. Previously only the master
addon's setting was used.
v1.4.0~alpha7 (2026-02-20)
--------------------------
New Features:
- Playlist continuation: Added "If countdown expires" setting to choose the default
action (Stop or Generate new playlist). When set to "Generate", the button layout
swaps so the timeout triggers playlist generation instead of stopping.
- Playlist continuation prompt now only appears when the playlist finishes naturally.
Manually stopping a playlist no longer triggers the continuation dialog.
- Playlist continuation heading now shows the countdown timer
(e.g., "Playlist Finished (auto-closing in 20 seconds)"), matching the next
episode prompt style.
- Countdown timer sliders now use 1-second steps (was 5) for both next episode prompt
and playlist continuation duration.
Bug Fixes:
- Fixed: DialogProgress.update() called with 3 positional args (broke on
Kodi 19+ which only accepts percent and message).
- Fixed: clone.py and update_clone.py errorHandle() used False as default
for path parameter — now correctly uses None with Optional[str] type.
- Fixed: XML tree.find('.//summary') result used without None check in
both clone.py and update_clone.py.
- Fixed: Clone addon repeatedly prompting to update on every other launch after main
addon update. The clone update script now calls UpdateLocalAddons to refresh Kodi's
in-memory addon metadata cache before re-registering (matching what clone creation
already did). The update-complete flag also persists for the full Kodi session as a
safety net, clearing naturally on restart.
Internal:
- Resolved all 115 pyright type-checking errors across 12 files (now 0).
Includes proper typing.cast() for Kodi getControl() stubs, assert guards
for Optional fields in daemon/service layer, and interface signature fixes
for abstract storage methods.
- Updated json_query() signature to accept batch queries (list of dicts).
v1.4.0~alpha6 (2026-02-19)
--------------------------
New Features:
- Replaced "Movie ratio" setting (0.0-1.0 slider) with "Movie chance" percentage
slider (0-100% in steps of 5). The new setting directly controls what fraction
of the playlist should be movies: 0% = no movies, 25% = default, 50% = equal
mix, 100% = all movies. New setting ID: movie_chance (old: movieweight).
- Added budget enforcement to playlist building. Both batch mode and lazy queue
now track movies vs. shows added and defer over-budget items, ensuring the
final playlist closely matches the configured movie chance percentage.
Bug Fixes:
- Fixed: Movie playlist filter bypassed the movie weight limit entirely. When a
playlist filter was configured, the limit was ignored during the query phase
and never re-applied after intersection, resulting in all matching movies being
included regardless of the weight setting. The limit is now applied after
playlist filter intersection.
Internal:
- Added calculate_movie_target() function for percentage-to-count conversion
- Movie target count now logged in playlist.create event for debugging
v1.4.0~alpha5 (2026-02-19)
--------------------------
Bug Fixes:
- Fixed: Partial prioritization in random playlists — stale resume points on
watched episodes (playcount > 0) no longer cause deterministic show ordering
in WATCHED and BOTH modes. Only genuinely in-progress episodes (playcount=0
with resume point) are now treated as partials.
- Fixed: When a partial episode is detected and prioritized, the specific
episode is now served on first encounter in both batch and lazy queue
playlist paths. Previously, the system detected the partial but discarded
the episode ID, picking a different episode instead.
v1.4.0~alpha4 (2026-02-15)
--------------------------
Bug Fixes:
- Fixed: Clone creation fails on SteamOS and other Arch-based Linux systems
where the system locale defaults to ASCII (POSIX/C locale). The clone script
used Python's fileinput module which inherits the locale encoding, failing on
UTF-8 characters (bullet character '•') in skin XML files. Replaced all
fileinput.input(inplace=True) calls with explicit open(..., encoding='utf-8')
read/write pattern. Affects clone.py at 4 call sites: settings.xml, strings.po,
Python scripts, and skin XML files.
- Fixed: Spurious "Show ID shifted, migrated to new ID" log messages on every
startup and library scan when all show IDs were unchanged. The validation
logic compared stored show IDs against the unwatched-only show list
(current_show_ids), so fully-watched shows in random_order_shows were not
found in the set. The title lookup then found the same ID back, logging a
false migration with old_id == new_id. Now correctly treats same-ID lookups
as unchanged rather than migrated.
Diagnostics:
- Added: Kodi video database backend (shared MariaDB vs local SQLite) is now
logged at service startup via advancedsettings.xml detection. Helps quickly
identify multi-device setups during troubleshooting.
v1.4.0~alpha3 (2026-02-10)
--------------------------
Bug Fixes:
- Fixed: Toggling "Include positioned specials in watch order" did not take
effect until the next Kodi restart or library scan. The setting change handler
(_on_settings_changed) reloaded the value but never triggered a refresh of
episode tracking data. Now detects the change and triggers bulk_refresh,
following the same pattern as the existing smart playlist toggle.
Performance:
- Batch write operations now use a single database transaction with one COMMIT
at the end, instead of committing independently per show. For 399 shows, this
reduces fsync overhead from ~399 × 50ms ≈ 20s to a single ~50ms commit.
Applies to service startup, post-scan refresh, and initial migration.
Root cause: Each set_show_tracking() call within batch_write() executed its
own revision UPDATE + conn.commit(), triggering an InnoDB fsync per write.
Fix: set_show_tracking() now defers the revision UPDATE and commit when
_batch_active is True. A new _batch_finalize() method performs a single
bulk revision bump (int_value + N) and one commit when the batch exits.
Refactor:
- Batch ownership lifted from daemon.py to StorageBackend interface. daemon.py
no longer uses isinstance(storage, SharedDatabaseStorage) or accesses
storage.db directly for batch operations. Instead, it calls the abstract
storage.batch_write(show_ids) which each backend implements appropriately:
- WindowPropertyStorage: no-op (inherited default)
- SharedDatabaseStorage: preload + deferred commit + revision management
v1.4.0~alpha2 (2026-02-10)
--------------------------
Bug Fixes:
- Fixed silent service crash during overnight library scans with multi-instance
sync enabled. Three layered failures combined to kill the service without any
error log, requiring a Kodi restart to recover.
Root cause: When the MariaDB connection goes idle overnight and is transparently
re-established, the new session has no database selected. Queries using
unqualified table names fail with error 1046 ("No database selected"). This
exception propagated unhandled through the entire call stack, terminating the
background service silently.
Fix 1 — Re-select database after reconnect (shared_db.py):
_get_connection() now calls _ensure_db_selected() after ping(reconnect=True)
or fallback _connect() to restore the session-level database selection.
Fix 2 — Graceful degradation for bulk preload (daemon.py):
The shareddb preload in refresh_show_episodes() is now wrapped in try/except.
On failure, the refresh proceeds without batch optimization rather than
crashing. Per-show writes in cache_next_episode() already had their own
try/except, so individual writes also degrade gracefully.
Fix 3 — Top-level exception handler in daemon loop (daemon.py):
_process_events() is now wrapped in try/except within the run() loop. Any
unhandled exception is logged with full stack trace via log.exception() and
the service continues. This prevents any single-cycle failure from killing
the service permanently.
v1.4.0~alpha1 (2026-02-04)
--------------------------
New Features:
- Positioned specials support: Include TVDB-positioned specials in watch order
- Some shows (like SpongeBob) have specials that are plot-relevant and should
be watched between specific episodes
- Kodi stores TVDB positioning data (e.g., "airs before S10E56") in episode
metadata (specialsortseason, specialsortepisode fields)
- When enabled, positioned specials appear at their designated position
- Non-positioned specials (those without TVDB data) remain excluded
- Enable in Settings → Shows → "Include positioned specials in watch order"
- Default: OFF (preserves existing behavior for current users)
Multi-Instance Note:
- The "Include positioned specials" setting affects episode ordering
- For consistent "next episode" across devices, configure this setting
identically on all Kodi instances sharing the same database
v1.3.0~beta1 (2026-01-29)
-------------------------
New Features:
- Multi-instance sync: Share watch progress across multiple Kodi devices
- When you watch Episode 5 on one device, all other devices know to queue Episode 6
- Requires Kodi configured with a shared MySQL/MariaDB video database
- Requires script.module.pymysql addon (auto-installed with EasyTV)
- Enable in Settings → Advanced → "Multi-instance sync"
- Auto-detects database configuration from advancedsettings.xml
- Automatic recovery after Kodi library rebuilds via title+year matching
- Automatic cleanup of orphaned database entries on startup
- Graceful fallback to Kodi video DB if dedicated easytv database unavailable
Known Limitations:
- For consistent "next episode" recommendations, configure random_order_shows
identically on all Kodi devices sharing the same database
Internal:
- Removed non-functional "Watch Order" settings from clone settings template
v1.2.4 (2026-01-25)
-------------------
BREAKING CHANGE:
- Smart playlist filenames have changed! If you have skin widgets or menu
entries pointing to EasyTV playlists, you must update them:
Old: "EasyTV - All Shows.xsp" → New: "EasyTV - Episode - All Shows.xsp"
Old: "EasyTV - Continue Watching.xsp" → New: "EasyTV - Episode - Continue Watching.xsp"
Old: "EasyTV - Start Fresh.xsp" → New: "EasyTV - Episode - Start Fresh.xsp"
- Old playlist files are automatically deleted on upgrade
- Settings migrate automatically
New Features:
- TVShow smart playlists for skin widgets - browse your next episodes by show
instead of episode list (great for home screen widgets)
- Two new playlist categories:
- Show Premieres - shows you haven't started yet (S01E01)
- Season Premieres - new seasons of shows you're watching (S02E01, S03E01, etc.)
- Apply your show filter to smart playlists (main addon only, since it
maintains the playlists) - if you filter random playback to a playlist,
your smart playlists can now use the same filter
Bug Fixes:
- Fixed clones repeatedly asking to update after each launch
- Fixed clone settings changes saving to the wrong addon
- Fixed clone updates sometimes failing with errors
Improvements:
- Clone updates now show a progress dialog so you know what's happening
Internal:
- Major code cleanup and refactoring of smart playlist system
- Removed ~285 lines of unused code
v1.2.3 (2026-01-24)
-------------------
Improvements:
- Added visual feedback during slow operations
- Browse mode: "Loading shows..." indicator during data fetch
- Random playlist: "Building playlist..." indicator during playlist creation
- Clone creation: Modal progress dialog with step-by-step status updates
- Particularly helpful on low-powered devices like OSMC Vero V where
browse mode can take ~6.5 seconds to open with network-attached databases
Bug Fixes:
- Fixed show selections becoming invalid after Kodi library rebuild
- When Kodi reassigns show IDs (after delete + rescan), settings now
detect the ID shift by comparing stored titles with current titles
- Shows are automatically migrated to their new IDs via title matching
- Protects both 'random_order_shows' and 'selection' settings
- Fixed browse mode buttons triggering unintended episode playback
- Cancel and empty buttons in Estuary's DialogSelect skin are now hidden
- Clicking any visible button correctly closes the dialog without playback
- Fixed smart playlists accumulating orphaned show entries
- After library wipe/rescan, deleted shows no longer persist in .xsp files
- Batch mode now performs full rebuild instead of merging with existing file
- Fixed duration filter being applied twice in browse mode
- Fixed version parsing crash with prerelease suffixes (e.g., "1.2.3~beta1")
Internal:
- New storage format for show selections: {id: title} instead of [id]
- Enables title-based ID shift detection
- Existing settings auto-migrate on first load
- Refactored browse mode for cleaner architecture
- Data fetching moved into build_episode_list()
- default.py simplified to routing logic only
- New utilities: busy_progress() context manager, parse_version(), compare_versions()
- Added constants for DialogSelect button control IDs
- Added debug logging for onClick control ID (aids future debugging)
v1.2.2 (2026-01-22)
------------------------
Bug Fixes:
- Fixed smart playlists not updating when skipping quickly through episodes
- Previously, using 10-minute jumps to reach the end of an episode would
leave playlists stale because the update was deferred to a processing
cycle that never ran after playback ended
- Now updates playlists immediately when Kodi marks an episode as watched
Internal:
- Removed monitor_override flag mechanism (~48 lines of code removed)
- Replaced deferred flag processing with direct refresh calls
- Simplifies code path and eliminates race condition
v1.2.1 (2026-01-22)
-------------------
New Features:
- Two new smart playlists for premiere episodes:
- "EasyTV - Show Premieres" — Shows at S01E01 (brand new shows to start)
- "EasyTV - Season Premieres" — Shows at S02E01+ (new seasons of existing shows)
- Smart playlists now work with Jellyfin and other plugin-based libraries
- Plugin URLs (plugin://...) are now preserved in playlist rules
- Previously only local file paths worked correctly
Bug Fixes:
- Fixed smart playlists breaking with special characters in filenames
- Characters like & < > are now properly XML-escaped
- Example: "Pam & Tommy" now works correctly
- Fixed potential XML parsing issues with show names containing "--"
- Playlist entries now use numeric show IDs instead of show names as markers
Internal:
- Smart playlist format versioning for safe upgrades
- Playlists automatically regenerate when format changes
- Version tracked in: special://profile/addon_data/script.easytv/playlist_format.json
- Removed unused 'showname' field from internal playlist data structures
v1.2.0 (2026-01-21)
-------------------
New Features:
- Episode duration filter: Filter shows by typical episode length
- Enable filter and set min/max duration in minutes (0-120, step 5)
- Works in both Browse Mode and Random Playlist mode
- Duration calculated as median from episode file metadata
- Shows without duration data are excluded when filter is active
- Set filter to "All" to include shows with unknown duration
- Warning shown if min > max (filter disabled, all shows included)
- Both mode now uses dynamic playlist building ("lazy queue")
- Playlist starts with 2-3 items visible instead of full length
- Additional items are added automatically as you watch
- On-deck episodes now progress naturally when same show appears multiple times
(S02E05 → S02E06 → S02E07 as each episode is watched)
- Unwatched/Watched modes unchanged (still build full playlist upfront)
- Requires "Allow multiple episodes of same TV Show" to be enabled
- Fixed LANGUAGE_ARTICLES for proper alphabetical sorting:
- Removed languages without articles (Russian, Polish, Turkish)
- Added indefinite articles (a/an) for English and other languages
- Added missing languages: Italian, Portuguese, Norwegian, Catalan, Romanian, Greek
- Example: "A Man in Full" now sorts under M, not A
Bug Fixes:
- Fixed library scan not triggering EasyTV refresh
- New shows/episodes now appear after library scan completes
- Added onScanFinished handler (was missing)
- Fixed Poster/BigScreen views showing only numbers without labels
- Added missing language strings (32220-32226) for skin labels
- Labels like "Season", "Episode", "Unwatched", etc. now display correctly
- Affects both main addon and clones
- Fixed show selector sorting issues ("Pick shows manually", "Random order shows")
- Now case-insensitive ("black-ish" sorts with B's, not after Z)
- Now handles articles ("A Man in Full" sorts under M, not A)
- Uses same sorting logic as Browse mode for consistency
- Fixed show selector missing artwork (showed placeholder icons)
- Now uses modern art.poster property instead of legacy thumbnail
- Fixed clone Browse mode showing "EasyTV" instead of clone name in title
- Fixed clone skin XML files not updated during clone creation/update
- Skin XML files now updated to use clone addon ID for language strings
- Clone update script now applies all fixes (was missing several updates)
- Existing clones can be updated via the update mechanism to get these fixes
- Fixed random playlist picking same show repeatedly when "Allow multiple episodes" enabled
- Shows are now properly distributed throughout the playlist
- After adding an episode, show moves to end of candidate list
Performance:
- Duration cache optimization: Significantly reduced startup time
- Median episode durations are now cached to disk
- Streamdetails only queried for shows with changed episode counts
- First startup: one-time full calculation
- Subsequent startups: ~81% faster on OSMC Vero V (32s → 6s)
- Cache file: special://profile/addon_data/script.easytv/duration_cache.json
- Cache now includes show titles for easier debugging
- Removed redundant full refresh on every database update
- Watch state changes now handled surgically via notifications
- Full refresh only triggers on library scan completion
- Art now lazy-loaded when Browse mode opens (~1s one-time cost per session)
- Reduces data fetched during startup
Default Settings Changed:
- "Include series premieres" now enabled by default (was disabled)
- "Playlist content" now defaults to "TV episodes only" (was "TV and movies")
- "Ask to watch next episode" now disabled by default (was enabled)
- "Prompt timeout" now defaults to 5 seconds (was 20)
- "Warn about earlier unwatched episodes" now enabled by default (was disabled)
Internal:
- Added timing instrumentation for performance monitoring (DEBUG level)
- Removed unused episode thumbnail (Art(thumb)) caching
- New module: resources/lib/data/duration_cache.py
- Reorganized strings.po with documented ID ranges for maintainability:
- 32000-32099: UI Elements (sort options, view styles, spinner values)
- 32100-32199: Dialogs and Messages
- 32200-32299: Context Menu and Skin Labels
- 32300-32399: Addon Metadata
- 32400-32499: Help Text
- 32500-32599: Settings UI (labels, categories, groups)
- 32600-32699: Feature-Specific Strings
- Removed legacy comments and empty string placeholders from strings.po
- Moved misplaced string IDs: 32032→32522, 32037→32523
v1.1.1 (2026-01-20)
-------------------
Bug Fixes:
- Fixed clone settings showing blank labels (no text visible)
- Clone settings.xml section ID now matches clone addon ID
- Clone strings.po header now matches clone addon ID
- Clone now built in temp folder before moving to addons (helps with caching)
- Fixed clone missing v1.1.0 settings (season premieres, unwatched ratio,
movie playlist filter, playlist continuation, random order shows)
- Fixed clone version now inherits parent version (was always 1.0.0)
- Fixed clone default settings now match parent defaults
- Clone startup logs now include addon_id for identification
- Clone naming keyboard now pre-fills with "EasyTV - " prefix
- Added safeguards to prevent overwriting existing addons during clone creation
Performance Improvements:
- Partial prioritization 99% faster (14.6s → 0.2s on test library)
- TV partial episode query: 14,200ms → 94ms (99.3% faster)
- Movie partial query: 427ms → 109ms (74% faster)
- Total random playlist build time reduced from ~18s to ~4s (78% faster)
- Uses Kodi's native 'inprogress' filter instead of per-show queries
- Test environment: OSMC Vero V with 168 shows, 5646 episodes, 846 movies
Improvements:
- Enhanced action logging at INFO level:
- Random playlist: logs content type, target length, show/movie counts
- Browse mode: logs start/stop with show count
- Clone creation now updates ALL language files (future Weblate support)
- Added timing instrumentation for partial prioritization queries
Known Issues:
- On Windows, clone uninstall may fail due to file locking. Workaround:
restart Kodi after uninstalling a clone before creating a new one with
the same name.
- Clone settings labels require Kodi restart to appear (Kodi caches
language strings at startup - this is a Kodi limitation).
v1.1.0 (2026-01-19)
-------------------
New Features:
- Episode selection: Choose which TV episodes to include in random playlists
- Unwatched only (default - matches original behavior)
- Watched only (re-watch your favorites)
- Both (true channel surfing with any episode)
- Movie playlist filtering: Limit which movies appear in random playlists
- Use any Kodi smart playlist to filter movies by genre, year, rating, etc.
- Works with both "TV and movies" and "Movies only" content modes
- Season premieres setting: Control season premiere episodes (S02E01, S03E01, etc.)
independently from series premieres (S01E01)
- Playlist continuation: Option to prompt when a random playlist ends
- Configurable countdown timer (0-60 seconds)
- Generate another playlist with same settings or stop
- Playlist picker now filters by type (TV playlists for TV filter, movie
playlists for movie filter)
- Default launch option changed to "Ask me" for new installs
- Separate partial/resume settings for TV and Movies:
- "Start playlist with unfinished episodes" - prioritize partial TV episodes
- "Start playlist with unfinished movies" - prioritize partial movies
- "Seek to resume point for episodes" - auto-resume TV episodes
- "Seek to resume point for movies" - auto-resume movies
- Enhanced partial prioritization:
- ALL partial items now moved to front of playlist (not just one)
- Partials sorted by recency (most recently watched first)
- Episodes from the same show maintain episode order
Performance Improvements:
- Startup time reduced from ~11 seconds to <1 second for large libraries
- Replaced per-show episode queries with single bulk query
- Batched smart playlist writes: 831 file operations reduced to 3
- Server-side random sorting reduces data transfer and processing time
Bug Fixes:
- Fixed "Both" mode episode selection when same show appears multiple times
- On-deck (next unwatched) episode now appears at most once per show
- Watched episodes no longer duplicate within a single playlist
- Playlist gracefully shortens when episodes are exhausted
- Fixed partial episode resume reliability
- Uses Kodi's actual resume data instead of stale window property flags
- Respects Kodi's advancedsettings.xml resume thresholds
- Deferred seek to onAVStarted when player is ready
- Uses absolute time for precise 10-second rewind
- Fixed repeated show selection when stopping/starting playlists quickly
Settings Reorganization:
- "Episode List" category renamed to "Browse Mode" for clarity
- "TV Options" and "Movie Options" merged into "Content Options"
- Standardized terminology: "Shuffle-Friendly" → "Random-Order" throughout
- New "Playlist Continuation" group in Random Playlist settings
- Partial/resume settings split into TV and Movie variants (see Breaking Changes)
Breaking Changes:
- Partial/resume settings replaced with separate TV and movie variants:
- "start_partials" → "start_partials_tv" + "start_partials_movies"
- "resume_partials" → "resume_partials_tv" + "resume_partials_movies"
- All partial settings now default to enabled (previously disabled)
- Existing users may want to disable if they preferred the old defaults
Developer/Debugging:
- Added logging for Kodi's resume point thresholds at startup
- Enhanced log_timing utility with phase breakdown support
- Detailed timing instrumentation for performance monitoring
- Added playlist.continuation and playlist.regenerate events
v1.0.1 (2026-01-16)
-------------------
- Updated addon icon
v1.0.0 (2026-01-16)
-------------------
Initial release as EasyTV - a fork and complete rewrite of LazyTV by KODeKarnage.
What is EasyTV?
No scrolling. No deciding. Just watching.
EasyTV tracks your TV shows and always knows your next episode. When you're
ready for something new, it suggests a show you haven't started. Mix in movies
if you want. Just sit down, press play, and enjoy.
Major Changes from LazyTV:
- Complete rewrite for Kodi 21+ (Python 3.8+)
- Modernized settings system (Kodi 19+ format)
- Modular architecture for better maintainability
- Improved logging system with separate debug log file
- Enhanced error handling throughout
Features:
- Episode List Mode: Browse next unwatched episodes for all your shows
- Random Playlist Mode: Channel-surf through episodes (and optionally movies)
- Smart Playlists: Auto-maintained playlists for use with other addons/skins
- EasyTV - All Shows
- EasyTV - Continue Watching
- EasyTV - Start Fresh
- Random Order Shows: Designate shows to play episodes in any order
- Next Episode Prompts: Get notified when an episode ends
- Previous Episode Check: Warning if you're about to skip episodes
- Clone Support: Create multiple configurations for your home screen
- Episode Export: Copy episodes to external storage
Credits:
Original LazyTV created by KODeKarnage (2013)
https://github.com/KODeKarnage/script.lazytv
Modernized and maintained by Rouzax (2024-2026)
https://github.com/Rouzax/script.easytv
License:
GPL-3.0-or-later