showtime-cli 0.3.19__tar.gz → 0.3.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {showtime-cli-0.3.19/showtime_cli.egg-info → showtime_cli-0.3.22}/PKG-INFO +19 -7
  2. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/pyproject.toml +23 -20
  3. showtime_cli-0.3.22/requirements.txt +7 -0
  4. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/setup.py +5 -5
  5. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/__init__.py +1 -1
  6. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/api.py +2 -1
  7. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/command.py +19 -1
  8. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/database.py +21 -3
  9. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/output.py +24 -1
  10. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/showtime.py +9 -3
  11. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/types.py +9 -1
  12. {showtime-cli-0.3.19 → showtime_cli-0.3.22/showtime_cli.egg-info}/PKG-INFO +19 -7
  13. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime_cli.egg-info/SOURCES.txt +0 -1
  14. showtime_cli-0.3.22/showtime_cli.egg-info/requires.txt +10 -0
  15. showtime-cli-0.3.19/requirements.txt +0 -7
  16. showtime-cli-0.3.19/showtime_cli.egg-info/requires.txt +0 -10
  17. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/LICENSE +0 -0
  18. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/MANIFEST.in +0 -0
  19. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/README.md +0 -0
  20. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/setup.cfg +0 -0
  21. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime/config.py +0 -0
  22. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime_cli.egg-info/dependency_links.txt +0 -0
  23. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime_cli.egg-info/entry_points.txt +0 -0
  24. {showtime-cli-0.3.19 → showtime_cli-0.3.22}/showtime_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: showtime-cli
3
- Version: 0.3.19
3
+ Version: 0.3.22
4
4
  Summary: Command line show tracker using the TVMaze public API
5
5
  Home-page: https://github.com/aquilax/showtime
6
6
  Author: Evgeniy Vasilev
@@ -16,15 +16,27 @@ Classifier: Programming Language :: Python :: 3 :: Only
16
16
  Classifier: Topic :: Utilities
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: cmd2==2.4.3
20
- Requires-Dist: urllib3==2.0.7
19
+ Requires-Dist: cmd2==2.5.11
20
+ Requires-Dist: urllib3==2.5.0
21
21
  Requires-Dist: ratelimit==2.2.1
22
- Requires-Dist: tinydb==4.8.0
22
+ Requires-Dist: tinydb==4.8.2
23
23
  Requires-Dist: terminaltables==3.1.10
24
- Requires-Dist: python-dateutil==2.8.2
25
- Requires-Dist: typing-extensions==4.8.0
24
+ Requires-Dist: python-dateutil==2.9.0.post0
25
+ Requires-Dist: typing-extensions==4.12.2
26
26
  Provides-Extra: test
27
27
  Requires-Dist: tox; extra == "test"
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: provides-extra
38
+ Dynamic: requires-dist
39
+ Dynamic: summary
28
40
 
29
41
  # showtime
30
42
 
@@ -13,26 +13,29 @@ max_line_length = 120
13
13
 
14
14
  [tool.tox]
15
15
  legacy_tox_ini = """
16
- [tox]
17
- envlist = py311,mypy,doc
18
- [testenv]
19
- deps =
20
- pytest
21
- pytest-cov
22
- cmd2_ext_test
23
- commands = pytest
24
- [testenv:mypy]
25
- deps =
26
- mypy
27
- ratelimit-stubs
28
- types-python-dateutil
29
- types-requests
30
- types-urllib3
31
- commands = mypy -p showtime
32
- [testenv:doc]
33
- deps = interrogate
34
- skip_install = true
35
- commands = interrogate --quiet --fail-under 80 showtime
16
+ [tox]
17
+ env_list = py311,mypy,doc
18
+
19
+ [testenv]
20
+ deps =
21
+ pytest
22
+ pytest-cov
23
+ cmd2_ext_test
24
+ commands = pytest
25
+
26
+ [testenv:mypy]
27
+ deps =
28
+ mypy
29
+ ratelimit-stubs
30
+ types-python-dateutil
31
+ types-requests
32
+ types-urllib3
33
+ commands = mypy -p showtime
34
+
35
+ [testenv:doc]
36
+ deps = interrogate
37
+ skip_install = true
38
+ commands = interrogate --quiet --fail-under 80 showtime
36
39
  """
37
40
 
38
41
  [tool.interrogate]
@@ -0,0 +1,7 @@
1
+ cmd2==2.5.11
2
+ urllib3==2.5.0
3
+ ratelimit==2.2.1
4
+ tinydb==4.8.2
5
+ terminaltables==3.1.10
6
+ python-dateutil==2.9.0.post0
7
+ typing-extensions==4.12.2
@@ -35,13 +35,13 @@ setup(
35
35
  'Topic :: Utilities',
36
36
  ],
37
37
  install_requires=[
38
- 'cmd2==2.4.3',
39
- 'urllib3==2.0.7',
38
+ 'cmd2==2.5.11',
39
+ 'urllib3==2.5.0',
40
40
  'ratelimit==2.2.1',
41
- 'tinydb==4.8.0',
41
+ 'tinydb==4.8.2',
42
42
  'terminaltables==3.1.10',
43
- 'python-dateutil==2.8.2',
44
- 'typing-extensions==4.8.0',
43
+ 'python-dateutil==2.9.0.post0',
44
+ 'typing-extensions==4.12.2',
45
45
  ],
46
46
  extras_require={
47
47
  'test': ['tox'],
@@ -1,4 +1,4 @@
1
1
  """Common module information"""
2
2
 
3
- __version__ = '0.3.19'
3
+ __version__ = '0.3.22'
4
4
  __url__ = 'https://github.com/aquilax/showtime'
@@ -26,7 +26,8 @@ def show_to_model(show: Dict) -> TVMazeShow:
26
26
  name=show['name'],
27
27
  premiered=show['premiered'],
28
28
  status=show['status'],
29
- url=show['url']
29
+ url=show['url'],
30
+ externals=show['externals']
30
31
  )
31
32
 
32
33
 
@@ -152,7 +152,18 @@ class Showtime(Cmd):
152
152
  self.output.pfeedback('Syncing shows...')
153
153
  self.app.sync(on_show_sync=self.output.status_on_show_sync,
154
154
  on_episode_insert=self.output.status_on_episode_insert,
155
- on_episode_update=self.output.status_on_episode_update)
155
+ on_episode_update=self.output.status_on_episode_update,
156
+ all=False)
157
+ self.output.pfeedback('Done')
158
+
159
+ @cmd2.with_category(EPISODE_CATEGORY)
160
+ def do_sync_all(self, _: Statement) -> None:
161
+ """Synchronize episodes with TVMaze [sync]"""
162
+ self.output.pfeedback('Syncing shows...')
163
+ self.app.sync(on_show_sync=self.output.status_on_show_sync,
164
+ on_episode_insert=self.output.status_on_episode_insert,
165
+ on_episode_update=self.output.status_on_episode_update,
166
+ all=True)
156
167
  self.output.pfeedback('Done')
157
168
 
158
169
  @cmd2.with_category(EPISODE_CATEGORY)
@@ -344,6 +355,13 @@ class Showtime(Cmd):
344
355
  summary_table = self.output.summary_table(month_totals)
345
356
  self.output.ppaged(summary_table)
346
357
 
358
+ @cmd2.with_category(SHOW_CATEGORY)
359
+ def do_unfinished(self, _: Statement) -> None:
360
+ """Show list of unfinished shows"""
361
+ unfinished_shows = self.app.show_get_unfinished()
362
+ unfinished_shows_table = self.output.unfinished_shows_table(unfinished_shows)
363
+ self.output.ppaged(unfinished_shows_table)
364
+
347
365
 
348
366
  def main() -> None:
349
367
  api = Api(get_default_pool_manager())
@@ -11,7 +11,7 @@ from tinydb.queries import QueryLike
11
11
  from tinydb.storages import JSONStorage, MemoryStorage
12
12
 
13
13
  from showtime.types import (Episode, EpisodeId, Show, ShowId, ShowStatus,
14
- TVMazeEpisode, TVMazeShow)
14
+ TVMazeEpisode, TVMazeShow, ShowWithCount)
15
15
 
16
16
  SHOW = 'show'
17
17
  EPISODE = 'episode'
@@ -39,7 +39,8 @@ class Database(TinyDB):
39
39
  'id': tv_maze_show.id,
40
40
  'name': tv_maze_show.name,
41
41
  'premiered': tv_maze_show.premiered,
42
- 'status': tv_maze_show.status
42
+ 'status': tv_maze_show.status,
43
+ 'externals': tv_maze_show.externals,
43
44
  })
44
45
  return ShowId(tv_maze_show.id)
45
46
 
@@ -48,7 +49,8 @@ class Database(TinyDB):
48
49
  return self.table(SHOW).update({
49
50
  'name': tv_maze_show.name,
50
51
  'premiered': tv_maze_show.premiered,
51
- 'status': tv_maze_show.status
52
+ 'status': tv_maze_show.status,
53
+ 'externals': tv_maze_show.externals,
52
54
  }, where('id') == show_id)
53
55
 
54
56
  def add_episode(self, show_id: ShowId, episode: TVMazeEpisode) -> EpisodeId:
@@ -152,6 +154,22 @@ class Database(TinyDB):
152
154
  shows = self.table(SHOW).search(where('id').one_of(show_ids))
153
155
  return cast(List[Show], shows)
154
156
 
157
+ def _get_shows_episodes_totals(self) -> List[ShowWithCount]:
158
+ all_shows = [{**show, 'total': 0, 'seen': 0} for show in self.table(SHOW)]
159
+ all_shows_keyed = {show['id']: show for show in all_shows}
160
+ for episode in self.table(EPISODE):
161
+ show_id = episode['show_id']
162
+ all_shows_keyed[show_id]['total'] += 1
163
+ if episode['watched'] != '':
164
+ all_shows_keyed[show_id]['seen'] += 1
165
+ return cast(List[ShowWithCount], all_shows_keyed.values())
166
+
167
+ def get_unfinished_shows(self) -> List[ShowWithCount]:
168
+ """Returns list of unfinished shows"""
169
+ all_shows_totals = self._get_shows_episodes_totals()
170
+ unfinished_shows = [show for show in all_shows_totals if show['total'] > show['seen']]
171
+ return sorted(unfinished_shows, key=lambda item: item['premiered'] or "")
172
+
155
173
 
156
174
  def get_direct_write_db(file_name: str) -> Database:
157
175
  """Returns database instance with direct interface"""
@@ -6,7 +6,7 @@ from typing import Callable, Dict, List
6
6
  from terminaltables import AsciiTable as Table # type: ignore
7
7
 
8
8
  from showtime.types import (DecoratedEpisode, Episode, Show, TVMazeEpisode,
9
- TVMazeShow)
9
+ TVMazeShow, ShowWithCount)
10
10
 
11
11
  PrintFunction = Callable[[str], None]
12
12
 
@@ -153,6 +153,29 @@ class Output():
153
153
  title = 'Followed shows'
154
154
  return str(Table(data, title=title).table)
155
155
 
156
+ def unfinished_shows_table(self, shows: List[ShowWithCount]) -> str:
157
+ """formats list of shows with episodes count as a table"""
158
+ data = []
159
+ data.append([
160
+ 'ID',
161
+ 'Name',
162
+ 'Premiered',
163
+ 'Status',
164
+ 'Episodes',
165
+ 'Watched'
166
+ ])
167
+ for show in shows:
168
+ data.append([
169
+ str(show['id']),
170
+ show['name'],
171
+ show['premiered'],
172
+ show['status'],
173
+ str(show['total']),
174
+ str(show['seen']),
175
+ ])
176
+ title = 'Unfinished shows'
177
+ return str(Table(data, title=title).table)
178
+
156
179
  def completed_shows_table(self, shows: List[Show]) -> str:
157
180
  """formats list of completed shows as a table"""
158
181
  data = []
@@ -8,7 +8,7 @@ from ratelimit import limits, sleep_and_retry
8
8
  from showtime.api import Api
9
9
  from showtime.config import Config
10
10
  from showtime.database import Database, transaction, NOT_WATCHED_VALUE
11
- from showtime.types import (DecoratedEpisode, Episode, EpisodeId, Show, ShowId,
11
+ from showtime.types import (DecoratedEpisode, Episode, EpisodeId, Show, ShowId, ShowWithCount,
12
12
  TVMazeEpisode, TVMazeShow)
13
13
 
14
14
 
@@ -157,10 +157,12 @@ class ShowtimeApp():
157
157
  def sync(self,
158
158
  on_show_sync: Union[Callable[[Show], None], None] = None,
159
159
  on_episode_insert: Union[Callable[[TVMazeEpisode], None], None] = None,
160
- on_episode_update: Union[Callable[[TVMazeEpisode], None], None] = None):
160
+ on_episode_update: Union[Callable[[TVMazeEpisode], None], None] = None,
161
+ all=False):
161
162
  """Updates episode information for followed shows from tvmaze"""
162
163
  with transaction(self.database) as transacted_db:
163
- shows = transacted_db.get_active_shows()
164
+ shows = transacted_db.get_shows() if all else transacted_db.get_active_shows()
165
+
164
166
  for show in shows:
165
167
  show_id = ShowId(show['id'])
166
168
  if on_show_sync:
@@ -255,3 +257,7 @@ class ShowtimeApp():
255
257
  def episodes_get_watched(self) -> List[Episode]:
256
258
  """Returns all watched episodes"""
257
259
  return self.database.get_watched_episodes()
260
+
261
+ def show_get_unfinished(self) -> List[ShowWithCount]:
262
+ """Returns list of unfinished shows"""
263
+ return self.database.get_unfinished_shows()
@@ -1,7 +1,7 @@
1
1
  """Showtime Types Module"""
2
2
 
3
3
  from enum import Enum
4
- from typing import NamedTuple
4
+ from typing import NamedTuple, Dict
5
5
  from typing_extensions import TypedDict
6
6
 
7
7
  ShowId = int
@@ -16,6 +16,7 @@ class TVMazeShow(NamedTuple):
16
16
  premiered: str
17
17
  status: str
18
18
  url: str
19
+ externals: Dict
19
20
 
20
21
 
21
22
  class TVMazeEpisode(NamedTuple):
@@ -42,6 +43,13 @@ class Show(TypedDict):
42
43
  name: str
43
44
  premiered: Date
44
45
  status: str
46
+ externals: Dict
47
+
48
+
49
+ class ShowWithCount(Show):
50
+ """DB Show with episode counts"""
51
+ total: int
52
+ seen: int
45
53
 
46
54
 
47
55
  class Episode(TypedDict):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: showtime-cli
3
- Version: 0.3.19
3
+ Version: 0.3.22
4
4
  Summary: Command line show tracker using the TVMaze public API
5
5
  Home-page: https://github.com/aquilax/showtime
6
6
  Author: Evgeniy Vasilev
@@ -16,15 +16,27 @@ Classifier: Programming Language :: Python :: 3 :: Only
16
16
  Classifier: Topic :: Utilities
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: cmd2==2.4.3
20
- Requires-Dist: urllib3==2.0.7
19
+ Requires-Dist: cmd2==2.5.11
20
+ Requires-Dist: urllib3==2.5.0
21
21
  Requires-Dist: ratelimit==2.2.1
22
- Requires-Dist: tinydb==4.8.0
22
+ Requires-Dist: tinydb==4.8.2
23
23
  Requires-Dist: terminaltables==3.1.10
24
- Requires-Dist: python-dateutil==2.8.2
25
- Requires-Dist: typing-extensions==4.8.0
24
+ Requires-Dist: python-dateutil==2.9.0.post0
25
+ Requires-Dist: typing-extensions==4.12.2
26
26
  Provides-Extra: test
27
27
  Requires-Dist: tox; extra == "test"
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: provides-extra
38
+ Dynamic: requires-dist
39
+ Dynamic: summary
28
40
 
29
41
  # showtime
30
42
 
@@ -3,7 +3,6 @@ MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
5
  requirements.txt
6
- setup.cfg
7
6
  setup.py
8
7
  showtime/__init__.py
9
8
  showtime/api.py
@@ -0,0 +1,10 @@
1
+ cmd2==2.5.11
2
+ urllib3==2.5.0
3
+ ratelimit==2.2.1
4
+ tinydb==4.8.2
5
+ terminaltables==3.1.10
6
+ python-dateutil==2.9.0.post0
7
+ typing-extensions==4.12.2
8
+
9
+ [test]
10
+ tox
@@ -1,7 +0,0 @@
1
- cmd2==2.4.3
2
- urllib3==2.0.7
3
- ratelimit==2.2.1
4
- tinydb==4.8.0
5
- terminaltables==3.1.10
6
- python-dateutil==2.8.2
7
- typing-extensions==4.8.0
@@ -1,10 +0,0 @@
1
- cmd2==2.4.3
2
- urllib3==2.0.7
3
- ratelimit==2.2.1
4
- tinydb==4.8.0
5
- terminaltables==3.1.10
6
- python-dateutil==2.8.2
7
- typing-extensions==4.8.0
8
-
9
- [test]
10
- tox
File without changes
File without changes
File without changes
File without changes