compuglobal 0.4.0__tar.gz → 0.4.2__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 (26) hide show
  1. {compuglobal-0.4.0 → compuglobal-0.4.2}/PKG-INFO +1 -1
  2. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/__init__.py +1 -1
  3. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/aio.py +43 -10
  4. compuglobal-0.4.2/compuglobal/api/config.py +30 -0
  5. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/font.py +17 -0
  6. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/overlay.py +11 -15
  7. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/subtitle.py +12 -0
  8. compuglobal-0.4.0/compuglobal/api/config.py +0 -16
  9. {compuglobal-0.4.0 → compuglobal-0.4.2}/LICENSE +0 -0
  10. {compuglobal-0.4.0 → compuglobal-0.4.2}/README.rst +0 -0
  11. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/__init__.py +0 -0
  12. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/client.py +0 -0
  13. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/discovery.py +0 -0
  14. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/endpoint.py +0 -0
  15. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/media.py +0 -0
  16. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/api/metadata.py +0 -0
  17. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/errors.py +0 -0
  18. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/__init__.py +0 -0
  19. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/base.py +0 -0
  20. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/comic.py +0 -0
  21. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/episode.py +0 -0
  22. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/frame.py +0 -0
  23. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/screencap.py +0 -0
  24. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/stream.py +0 -0
  25. {compuglobal-0.4.0 → compuglobal-0.4.2}/compuglobal/models/timestamp.py +0 -0
  26. {compuglobal-0.4.0 → compuglobal-0.4.2}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compuglobal
3
- Version: 0.4.0
3
+ Version: 0.4.2
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
@@ -22,7 +22,7 @@ from compuglobal.models.timestamp import Timestamp
22
22
  __title__ = "compuglobal"
23
23
  __author__ = "MitchellAW"
24
24
  __license__ = "MIT"
25
- __version__ = "0.4.0"
25
+ __version__ = "0.4.2"
26
26
 
27
27
  __all__ = [
28
28
  "APIPageStatusError",
@@ -1,5 +1,6 @@
1
1
  """Used for interacting with and building CGHMC APIs."""
2
2
 
3
+ import dataclasses
3
4
  import json
4
5
  import logging
5
6
  from typing import overload
@@ -32,8 +33,10 @@ class AsyncCompuGlobalAPI:
32
33
 
33
34
  Parameters
34
35
  ----------
35
- session : aiohttp.ClientSession, optional
36
+ session : aiohttp.ClientSession
36
37
  The client session to use for all API calls
38
+ default_format : OverlayFormat | None, optional
39
+ The default overlay format to use for all overlays/subtitles
37
40
 
38
41
  Attributes
39
42
  ----------
@@ -41,8 +44,8 @@ class AsyncCompuGlobalAPI:
41
44
  The base url of the API
42
45
  TITLE : str
43
46
  The title of the API
44
- DEFAULT_FORMAT : OverlayFormat
45
- The default formatting to use in all comic/gif overlays
47
+ EXTRA_FONTS : frozenset[FontFamily]
48
+ A frozenset of any extra fonts permitted by the API
46
49
  discovery : DiscoveryAPI
47
50
  The discovery API with all discovery endpoints
48
51
  media : MediaAPI
@@ -54,16 +57,27 @@ class AsyncCompuGlobalAPI:
54
57
 
55
58
  BASE_URL: str
56
59
  TITLE: str
57
- DEFAULT_FORMAT: OverlayFormat
60
+ EXTRA_FONTS: frozenset[FontFamily] = frozenset()
58
61
  _MAX_ALLOWED_SUBTITLES = 4
59
62
 
60
63
  discovery: DiscoveryAPI = DiscoveryAPI()
61
64
  media: MediaAPI = MediaAPI()
62
65
  metadata: MetadataAPI = MetadataAPI()
63
66
 
64
- def __init__(self, session: aiohttp.ClientSession) -> None:
67
+ def __init__(self, session: aiohttp.ClientSession, default_format: OverlayFormat | None = None) -> None:
68
+ extra_fonts = list(self.EXTRA_FONTS)
69
+ if default_format is None:
70
+ chosen_font = extra_fonts[0] if len(extra_fonts) > 0 else FontFamily.IMPACT
71
+ default_format = OverlayFormat(font_family=chosen_font)
72
+
73
+ allowed_fonts = FontFamily.universal_fonts() + extra_fonts
74
+
75
+ self.config = CompuGlobalAPIConfig(
76
+ title=self.TITLE,
77
+ allowed_fonts=allowed_fonts,
78
+ default_format=default_format,
79
+ )
65
80
  self.client = CompuGlobalAPIClient(base_url=self.BASE_URL, session=session)
66
- self.config = CompuGlobalAPIConfig(title=self.TITLE, default_format=self.DEFAULT_FORMAT)
67
81
 
68
82
  async def get_screencap(
69
83
  self,
@@ -476,6 +490,21 @@ class AsyncCompuGlobalAPI:
476
490
  query={"b64": stream.encoded},
477
491
  )
478
492
 
493
+ def _resolve_font(self, overlay_format: OverlayFormat) -> OverlayFormat:
494
+ if overlay_format.font_family in self.config.allowed_fonts:
495
+ return overlay_format
496
+
497
+ log.warning(
498
+ "Font family %s is not allowed for %s, using IMPACT font instead | overlay_format=%s",
499
+ overlay_format.font_family,
500
+ self.config.title,
501
+ overlay_format,
502
+ )
503
+ return dataclasses.replace(overlay_format, font_family=FontFamily.IMPACT)
504
+
505
+ def _resolve_fonts(self, overlay_formats: list[OverlayFormat]) -> list[OverlayFormat]:
506
+ return [self._resolve_font(overlay_format) for overlay_format in overlay_formats]
507
+
479
508
  @overload
480
509
  def _resolve_overlay_inputs(
481
510
  self,
@@ -504,6 +533,12 @@ class AsyncCompuGlobalAPI:
504
533
  if overlay_format != self.config.default_format:
505
534
  log.debug("Using custom overlay format | screencap=%s | overlay_format=%s", screencap, overlay_format)
506
535
 
536
+ # Resolve any disallowed fonts in the format(s)
537
+ if isinstance(overlay_format, list):
538
+ overlay_format = self._resolve_fonts(overlay_format)
539
+ else:
540
+ overlay_format = self._resolve_font(overlay_format)
541
+
507
542
  # Use screencap subtitles if not given
508
543
  subtitles = subtitles or screencap.subtitles
509
544
  if subtitles != screencap.subtitles:
@@ -523,7 +558,6 @@ class CapitalBeatUs(AsyncCompuGlobalAPI):
523
558
 
524
559
  BASE_URL = "https://capitalbeat.us"
525
560
  TITLE = "West Wing"
526
- DEFAULT_FORMAT = OverlayFormat(font_family=FontFamily.IMPACT)
527
561
 
528
562
 
529
563
  class Frinkiac(AsyncCompuGlobalAPI):
@@ -531,7 +565,7 @@ class Frinkiac(AsyncCompuGlobalAPI):
531
565
 
532
566
  BASE_URL = "https://frinkiac.com"
533
567
  TITLE = "Simpsons"
534
- DEFAULT_FORMAT = OverlayFormat(font_family=FontFamily.AKBAR)
568
+ EXTRA_FONTS = frozenset({FontFamily.AKBAR})
535
569
 
536
570
 
537
571
  @deprecated("The MasterOfAllScience API is deprecated, and currently redirects to Frinkiac")
@@ -540,7 +574,6 @@ class MasterOfAllScience(AsyncCompuGlobalAPI):
540
574
 
541
575
  BASE_URL = "https://masterofallscience.com"
542
576
  TITLE = "Rick and Morty"
543
- DEFAULT_FORMAT = OverlayFormat(font_family=FontFamily.IMPACT)
544
577
 
545
578
 
546
579
  class Morbotron(AsyncCompuGlobalAPI):
@@ -548,4 +581,4 @@ class Morbotron(AsyncCompuGlobalAPI):
548
581
 
549
582
  BASE_URL = "https://morbotron.com"
550
583
  TITLE = "Futurama"
551
- DEFAULT_FORMAT = OverlayFormat(font_family=FontFamily.FR_BOLD)
584
+ EXTRA_FONTS = frozenset({FontFamily.FR_BOLD})
@@ -0,0 +1,30 @@
1
+ """The configuration for a CGHMC API (title + font)."""
2
+
3
+ import dataclasses
4
+ import logging
5
+ from dataclasses import dataclass, field
6
+
7
+ from compuglobal.models.font import FontFamily
8
+ from compuglobal.models.overlay import OverlayFormat
9
+
10
+ log = logging.getLogger(__name__)
11
+
12
+
13
+ @dataclass
14
+ class CompuGlobalAPIConfig:
15
+ """The configuration for a CompuGlobal API."""
16
+
17
+ #: The title of the API
18
+ title: str
19
+
20
+ #: The allowed fonts for this API
21
+ allowed_fonts: list[FontFamily] = field(default_factory=FontFamily.universal_fonts)
22
+
23
+ #: The default formatting to use in all stream/comic overlays (subtitles)
24
+ default_format: OverlayFormat = field(default_factory=OverlayFormat)
25
+
26
+ def __post_init__(self) -> None:
27
+ """Validate font family is allowed in API. If not allowed, use IMPACT font."""
28
+ if self.default_format.font_family not in self.allowed_fonts:
29
+ log.warning("Chosen font is not allowed for this API. Using IMPACT font instead.")
30
+ self.default_format = dataclasses.replace(self.default_format, font_family=FontFamily.IMPACT)
@@ -28,6 +28,23 @@ class FontFamily(StrEnum):
28
28
  #: The Fr Bold font family (Morbotron default)
29
29
  FR_BOLD = "fr"
30
30
 
31
+ @staticmethod
32
+ def universal_fonts() -> list["FontFamily"]:
33
+ """Get a list of universal fonts that work across all APIs.
34
+
35
+ Returns
36
+ -------
37
+ list[FontFamily]
38
+ List of universal fonts
39
+
40
+ """
41
+ return [
42
+ FontFamily.IMPACT,
43
+ FontFamily.COMIC_NEUE,
44
+ FontFamily.JOST,
45
+ FontFamily.PACIFICO,
46
+ ]
47
+
31
48
 
32
49
  class FontAlignment(StrEnum):
33
50
  """An enumeration of font alignments."""
@@ -1,13 +1,12 @@
1
1
  """Helper class for formatting of StreamOverlays and ComicOverlays."""
2
2
 
3
- import dataclasses
4
- from dataclasses import dataclass, field
3
+ from pydantic import Field
5
4
 
5
+ from compuglobal.models.base import BaseCompuGlobalModel
6
6
  from compuglobal.models.font import FontAlignment, FontColor, FontFamily
7
7
 
8
8
 
9
- @dataclass(frozen=True)
10
- class OverlayFormat:
9
+ class OverlayFormat(BaseCompuGlobalModel):
11
10
  """The formatting style to use in an overlay.
12
11
 
13
12
  Attributes
@@ -29,19 +28,16 @@ class OverlayFormat:
29
28
 
30
29
  """
31
30
 
32
- font_family: FontFamily = FontFamily.IMPACT
33
- font_size: int = 0
34
- font_color: FontColor = field(default_factory=FontColor)
35
- text_position_x: int = 50
36
- text_position_y: int = 97
37
- text_alignment: FontAlignment = FontAlignment.ALIGN_CENTER
38
- all_caps: bool = True
39
-
40
- def _changed_fields(self) -> dict:
41
- return {f.name: getattr(self, f.name) for f in dataclasses.fields(self) if getattr(self, f.name) != f.default}
31
+ font_family: FontFamily = Field(default=FontFamily.IMPACT)
32
+ font_size: int = Field(ge=0, le=120, default=0)
33
+ font_color: FontColor = Field(default=FontColor())
34
+ text_position_x: int = Field(default=50)
35
+ text_position_y: int = Field(default=97)
36
+ text_alignment: FontAlignment = Field(default=FontAlignment.ALIGN_CENTER)
37
+ all_caps: bool = Field(default=True)
42
38
 
43
39
  def __str__(self) -> str: # noqa: D105
44
- return str(self._changed_fields())
40
+ return str(self.model_dump(exclude_defaults=True))
45
41
 
46
42
  @property
47
43
  def font_color_hex(self) -> str:
@@ -47,3 +47,15 @@ class Subtitle(BaseCompuGlobalModel):
47
47
 
48
48
  """
49
49
  return Timestamp.get_duration(start_timestamp=self.start_timestamp, end_timestamp=self.end_timestamp)
50
+
51
+ @property
52
+ def timecode(self) -> str:
53
+ """A readable timecode for the subtitle's representative timestamp in format ``mm:ss``.
54
+
55
+ Returns
56
+ -------
57
+ str
58
+ A readable timecode in format ``mm:ss``
59
+
60
+ """
61
+ return Timestamp.get_timecode(self.representative_timestamp)
@@ -1,16 +0,0 @@
1
- """The configuration for a CGHMC API (title + font)."""
2
-
3
- from dataclasses import dataclass, field
4
-
5
- from compuglobal.models.overlay import OverlayFormat
6
-
7
-
8
- @dataclass
9
- class CompuGlobalAPIConfig:
10
- """The configuration for a CompuGlobal API."""
11
-
12
- #: The title of the API
13
- title: str
14
-
15
- #: The default formatting to use in all stream/comic overlays (subtitles)
16
- default_format: OverlayFormat = field(default_factory=OverlayFormat)
File without changes
File without changes
File without changes