compuglobal 0.3.7__tar.gz → 0.3.8__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. {compuglobal-0.3.7 → compuglobal-0.3.8}/PKG-INFO +2 -2
  2. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/__init__.py +3 -1
  3. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/frame.py +2 -4
  4. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/screencap.py +26 -3
  5. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/subtitle.py +3 -2
  6. compuglobal-0.3.8/compuglobal/models/timestamp.py +76 -0
  7. {compuglobal-0.3.7 → compuglobal-0.3.8}/pyproject.toml +1 -1
  8. {compuglobal-0.3.7 → compuglobal-0.3.8}/LICENSE +0 -0
  9. {compuglobal-0.3.7 → compuglobal-0.3.8}/README.rst +0 -0
  10. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/aio.py +0 -0
  11. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/__init__.py +0 -0
  12. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/client.py +0 -0
  13. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/config.py +0 -0
  14. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/discovery.py +0 -0
  15. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/endpoint.py +0 -0
  16. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/media.py +0 -0
  17. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/api/metadata.py +0 -0
  18. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/errors.py +0 -0
  19. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/__init__.py +0 -0
  20. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/base.py +0 -0
  21. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/comic.py +0 -0
  22. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/episode.py +0 -0
  23. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/font.py +0 -0
  24. {compuglobal-0.3.7 → compuglobal-0.3.8}/compuglobal/models/stream.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compuglobal
3
- Version: 0.3.7
3
+ Version: 0.3.8
4
4
  Summary: Python wrapper for the CGHMC API (Frinkiac, Morbotron Master Of All Science and more.
5
5
  Keywords: The Simpsons,Futurama,Rick and Morty,West Wing,Frinkiac,Morbotron,Master of all Science,Capital Beat,API,API Wrapper,CompuGlobal,CompuGlobalHyperMegaNet,CGHMC
6
6
  Author: MitchellAW
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.14
12
12
  Classifier: Operating System :: OS Independent
13
13
  Classifier: Intended Audience :: Developers
14
14
  License-File: LICENSE
15
- Requires-Dist: aiohttp>=3.13.0
15
+ Requires-Dist: aiohttp>=3.14.0
16
16
  Requires-Dist: pydantic>=2.13.0
17
17
  Project-URL: Documentation, https://compuglobal.readthedocs.io/en/latest/
18
18
  Project-URL: Source, https://github.com/MitchellAW/CompuGlobal
@@ -16,11 +16,12 @@ from compuglobal.models.frame import Frame, FrameResult
16
16
  from compuglobal.models.screencap import Screencap, ScreencapMoment
17
17
  from compuglobal.models.stream import Stream, StreamOverlay
18
18
  from compuglobal.models.subtitle import Subtitle
19
+ from compuglobal.models.timestamp import Timestamp
19
20
 
20
21
  __title__ = "compuglobal"
21
22
  __author__ = "MitchellAW"
22
23
  __license__ = "MIT"
23
- __version__ = "0.3.7"
24
+ __version__ = "0.3.8"
24
25
 
25
26
  __all__ = [
26
27
  "APIPageStatusError",
@@ -47,4 +48,5 @@ __all__ = [
47
48
  "Stream",
48
49
  "StreamOverlay",
49
50
  "Subtitle",
51
+ "Timestamp",
50
52
  ]
@@ -3,6 +3,7 @@
3
3
  from pydantic import Field
4
4
 
5
5
  from compuglobal.models.base import BaseCompuGlobalModel
6
+ from compuglobal.models.timestamp import Timestamp
6
7
 
7
8
 
8
9
  class Frame(BaseCompuGlobalModel):
@@ -32,10 +33,7 @@ class Frame(BaseCompuGlobalModel):
32
33
  A readable timestamp for the frame in format `mm:ss`.
33
34
 
34
35
  """
35
- seconds = int(self.timestamp / 1000)
36
- minutes = int(seconds / 60)
37
- seconds -= minutes * 60
38
- return f"{minutes}:{seconds:02d}"
36
+ return Timestamp.get_real_timestamp(timestamp=self.timestamp)
39
37
 
40
38
  def __str__(self) -> str:
41
39
  """Get the string representation of the Frame.
@@ -6,6 +6,7 @@ from compuglobal.models.base import BaseCompuGlobalModel
6
6
  from compuglobal.models.episode import EpisodeMetadata
7
7
  from compuglobal.models.frame import Frame
8
8
  from compuglobal.models.subtitle import Subtitle
9
+ from compuglobal.models.timestamp import Timestamp
9
10
 
10
11
 
11
12
  class ScreencapMoment(BaseCompuGlobalModel):
@@ -29,6 +30,17 @@ class ScreencapMoment(BaseCompuGlobalModel):
29
30
  content: str = Field(alias="Content")
30
31
  title: str = Field(alias="Title")
31
32
 
33
+ def get_real_timestamp(self) -> str:
34
+ """Get a readable timestamp for the moments timestamp in format `mm:ss`.
35
+
36
+ Returns
37
+ -------
38
+ str
39
+ A readable timestamp in format `mm:ss`.
40
+
41
+ """
42
+ return Timestamp.get_real_timestamp(self.timestamp)
43
+
32
44
 
33
45
  class Screencap(BaseCompuGlobalModel):
34
46
  """A Screencap of an episode at a point in time of a TV Show.
@@ -58,7 +70,7 @@ class Screencap(BaseCompuGlobalModel):
58
70
  max_timestamp: int = Field(alias="MaxTimestamp", ge=0)
59
71
 
60
72
  def get_real_timestamp(self) -> str:
61
- """Get a readable timestamp for the frame in format "mm:ss".
73
+ """Get a readable timestamp for the frame in format `mm:ss`.
62
74
 
63
75
  Returns
64
76
  -------
@@ -66,10 +78,21 @@ class Screencap(BaseCompuGlobalModel):
66
78
  A readable timestamp for the frame in format `mm:ss`.
67
79
 
68
80
  """
69
- return self.frame.get_real_timestamp()
81
+ return Timestamp.get_real_timestamp(timestamp=self.frame.timestamp)
82
+
83
+ def get_duration(self) -> int:
84
+ """Get duration of screencap subtitles in milliseconds.
85
+
86
+ Returns
87
+ -------
88
+ int
89
+ Duration in milliseconds
90
+
91
+ """
92
+ return Timestamp.get_subtitles_duration(self.subtitles)
70
93
 
71
94
  def captions(self) -> list[str]:
72
- """Get a list of captions for the screencap from all subttiles.
95
+ """Get a list of captions for the screencap from all subtitles.
73
96
 
74
97
  Returns
75
98
  -------
@@ -3,6 +3,7 @@
3
3
  from pydantic import Field
4
4
 
5
5
  from compuglobal.models.base import BaseCompuGlobalModel
6
+ from compuglobal.models.timestamp import Timestamp
6
7
 
7
8
 
8
9
  class Subtitle(BaseCompuGlobalModel):
@@ -41,7 +42,7 @@ class Subtitle(BaseCompuGlobalModel):
41
42
  Returns
42
43
  -------
43
44
  int
44
- The duration in milliseonds.
45
+ The duration in milliseconds.
45
46
 
46
47
  """
47
- return self.end_timestamp - self.start_timestamp
48
+ return Timestamp.get_duration(start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp)
@@ -0,0 +1,76 @@
1
+ """Timestamp module with helper class for working with timestamps."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from compuglobal.models.subtitle import Subtitle
9
+
10
+
11
+ class Timestamp:
12
+ """Helper class for working with timestamps."""
13
+
14
+ @staticmethod
15
+ def get_minutes_seconds(milliseconds: int) -> tuple[int, int]:
16
+ """Get minutes and seconds from milliseconds.
17
+
18
+ Parameters
19
+ ----------
20
+ milliseconds : int
21
+ The length of time in milliseconds
22
+
23
+ Returns
24
+ -------
25
+ tuple[int, int]
26
+ The minutes, and seconds as a tuple
27
+
28
+ """
29
+ seconds = int(milliseconds / 1000)
30
+ minutes = int(seconds / 60)
31
+ seconds -= minutes * 60
32
+ return minutes, seconds
33
+
34
+ @staticmethod
35
+ def get_real_timestamp(timestamp: int) -> str:
36
+ """Get a readable timestamp for the frame in format `mm:ss`.
37
+
38
+ Returns
39
+ -------
40
+ str
41
+ A readable timestamp for the frame in format `mm:ss`.
42
+
43
+ """
44
+ minutes, seconds = Timestamp.get_minutes_seconds(timestamp)
45
+ return f"{minutes}:{seconds:02d}"
46
+
47
+ @staticmethod
48
+ def get_duration(start_timestamp: int, end_timestamp: int) -> int:
49
+ """Get the duration of the subtitle in milliseconds.
50
+
51
+ Returns
52
+ -------
53
+ int
54
+ The duration in milliseconds.
55
+
56
+ """
57
+ return end_timestamp - start_timestamp
58
+
59
+ @staticmethod
60
+ def get_subtitles_duration(subtitles: list[Subtitle]) -> int:
61
+ """Get the duration between the start of the earliest subtitle, and the end of the latest subtitle.
62
+
63
+ Parameters
64
+ ----------
65
+ subtitles : list[Subtitle]
66
+ The subtitles
67
+
68
+ Returns
69
+ -------
70
+ int
71
+ The duration in milliseconds
72
+
73
+ """
74
+ start_timestamp = min(subtitle.start_timestamp for subtitle in subtitles)
75
+ end_timestamp = max(subtitle.end_timestamp for subtitle in subtitles)
76
+ return Timestamp.get_duration(start_timestamp, end_timestamp)
@@ -12,7 +12,7 @@ license = "MIT"
12
12
  requires-python = ">=3.13"
13
13
  dynamic = ["version", "description"]
14
14
  dependencies = [
15
- "aiohttp>=3.13.0", "pydantic>=2.13.0"
15
+ "aiohttp>=3.14.0", "pydantic>=2.13.0"
16
16
  ]
17
17
  classifiers = [
18
18
  "Programming Language :: Python :: 3.13",
File without changes
File without changes