Skip to content

Commit b9556d1

Browse files
committed
v1.4.12.41
1 parent ec4acaa commit b9556d1

40 files changed

+478
-357
lines changed

.vscode/settings.json

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"python.analysis.diagnosticMode": "workspace",
2323
// formatter & import sort
2424
"ruff.format.args": ["--line-length=115"],
25+
"ruff.lint.args": ["--line-length=115"],
2526
"[python]": {
2627
"editor.codeActionsOnSave": {
2728
"source.organizeImports": "explicit",

README.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
* Insert an _All_ category when missing so you can easily **search your entire catalog**.
44
<kbd><img src="resources/readme/all.png"></kbd>
55
* Update ***[Mpv](https://mpv.io/)*** and **Sfvip Player** so you can enjoy their latest features.
6+
* Cache MAC acccounts all categories to access it faster.
67
* Translated in all **Sfvip Player** languages.
78
* Support an **external EPG**[^1].
89

910
[^1]: External EPG doesn't work with **local** m3u accounts.
1011
# Downloads
11-
[<img src="https://custom-icon-badges.demolab.com/badge/Sfvip All v1.4.12.40-informational?logo=download-cloud&logoSource=feather&logoColor=white&style=flat-square" height="35"><img src="https://img.shields.io/badge/x64-informational?logo=Windows10&logoColor=lightblue&style=flat-square" height="35"><img src="https://custom-icon-badges.demolab.com/badge/clean-brightgreen?logo=shield-check&logoColor=white&style=flat-square" height="35">](https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.40/Install.Sfvip.All.1.4.12.40.x64.exe)
12-
<sup><sup>_by MS Defender • 1.1.24020.9 • 1.407.423.0_</sup></sup>
12+
[<img src="https://custom-icon-badges.demolab.com/badge/Sfvip All v1.4.12.41-informational?logo=download-cloud&logoSource=feather&logoColor=white&style=flat-square" height="35"><img src="https://img.shields.io/badge/x64-informational?logo=Windows10&logoColor=lightblue&style=flat-square" height="35"><img src="https://custom-icon-badges.demolab.com/badge/clean-brightgreen?logo=shield-check&logoColor=white&style=flat-square" height="35">](https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.41/Install.Sfvip.All.1.4.12.41.x64.exe)
13+
<sup><sup>_by MS Defender • 1.1.24020.9 • 1.407.578.0_</sup></sup>
1314

14-
[<img src="https://custom-icon-badges.demolab.com/badge/Sfvip All v1.4.12.40-informational?logo=download-cloud&logoSource=feather&logoColor=white&style=flat-square" height="35"><img src="https://img.shields.io/badge/x86-informational?logo=Windows10&logoColor=lightblue&style=flat-square" height="35"><img src="https://custom-icon-badges.demolab.com/badge/clean-brightgreen?logo=shield-check&logoColor=white&style=flat-square" height="35">](https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.40/Install.Sfvip.All.1.4.12.40.x86.exe)
15-
<sup><sup>_by MS Defender • 1.1.24020.9 • 1.407.423.0_</sup></sup>
15+
[<img src="https://custom-icon-badges.demolab.com/badge/Sfvip All v1.4.12.41-informational?logo=download-cloud&logoSource=feather&logoColor=white&style=flat-square" height="35"><img src="https://img.shields.io/badge/x86-informational?logo=Windows10&logoColor=lightblue&style=flat-square" height="35"><img src="https://custom-icon-badges.demolab.com/badge/clean-brightgreen?logo=shield-check&logoColor=white&style=flat-square" height="35">](https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.41/Install.Sfvip.All.1.4.12.41.x86.exe)
16+
<sup><sup>_by MS Defender • 1.1.24020.9 • 1.407.578.0_</sup></sup>
1617

1718
[<a href="https://tooomm.github.io/github-release-stats/?username=sebdelsol&repository=sfvip-all"><img src="https://img.shields.io/github/downloads/sebdelsol/sfvip-all/total?color=informational&logo=github&labelColor=informational&style=flat-square" height="25"></a><a href="https://github.com/sebdelsol/sfvip-all/issues?q=is%3Aopen"><img src="https://img.shields.io/github/issues/sebdelsol/sfvip-all?labelColor=success&style=flat-square" height="25"></a>]()
1819

@@ -43,7 +44,7 @@ You'll find them in the app folder:
4344

4445
# Build
4546
[![version](https://custom-icon-badges.demolab.com/badge/Build%201.4.12.41-informational?logo=github)](/build_config.py#L27)
46-
[![Sloc](https://custom-icon-badges.demolab.com/badge/Sloc%208.3k-informational?logo=file-code)](https://api.codetabs.com/v1/loc/?github=sebdelsol/sfvip-all)
47+
[![Sloc](https://custom-icon-badges.demolab.com/badge/Sloc%208.4k-informational?logo=file-code)](https://api.codetabs.com/v1/loc/?github=sebdelsol/sfvip-all)
4748
[![Ruff](https://custom-icon-badges.demolab.com/badge/Ruff-informational?logo=ruff-color)](https://docs.astral.sh/ruff/)
4849
[![Python](https://custom-icon-badges.demolab.com/badge/Python%203.11.8-linen?logo=python-color)](https://www.python.org/downloads/release/python-3118/)
4950
[![mitmproxy](https://custom-icon-badges.demolab.com/badge/Mitmproxy%2010.2.4-linen?logo=mitmproxy-black)](https://mitmproxy.org/)

build/changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
## 1.4.12.41
2+
* Faster MAC accounts cache for all categories.
3+
* MAC accounts cache handles partial update.
4+
* All categories are added only when needed.
25
* Tooltips added.
36

47
## 1.4.12.40

build/update_x64.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"url": "https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.40/Install.Sfvip.All.1.4.12.40.x64.exe",
3-
"md5": "56f26c63ad43e960435271ee0adf5c6b",
4-
"version": "1.4.12.40"
2+
"url": "https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.41/Install.Sfvip.All.1.4.12.41.x64.exe",
3+
"md5": "682fd7104bcd7f932c191fbae9ad1bc8",
4+
"version": "1.4.12.41"
55
}

build/update_x86.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"url": "https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.40/Install.Sfvip.All.1.4.12.40.x86.exe",
3-
"md5": "898db7fcb22fc3d80b0c435e444f6d7d",
4-
"version": "1.4.12.40"
2+
"url": "https://github.com/sebdelsol/sfvip-all/releases/download/Sfvip.All.1.4.12.41/Install.Sfvip.All.1.4.12.41.x86.exe",
3+
"md5": "6e596f25bb6b878a8d72c2c725c053bf",
4+
"version": "1.4.12.41"
55
}

dev/tools/release.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
from pathlib import Path
22
from typing import Optional
33

4-
from github import (
5-
Auth,
6-
BadCredentialsException,
7-
Github,
8-
GithubException,
9-
UnknownObjectException,
10-
)
4+
from github import Auth, BadCredentialsException, Github, GithubException, UnknownObjectException
115
from github.GitRelease import GitRelease
126

137
from api_keys import GITHUB_TOKEN

dev/tools/templater.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,7 @@
1313
from .scanner.file import ScanFile
1414
from .utils.color import Low, Ok, Title, Warn
1515
from .utils.dist import human_format, repr_size
16-
from .utils.protocols import (
17-
CfgBuild,
18-
CfgEnvironments,
19-
CfgGithub,
20-
CfgTemplate,
21-
CfgTemplates,
22-
)
16+
from .utils.protocols import CfgBuild, CfgEnvironments, CfgGithub, CfgTemplate, CfgTemplates
2317

2418

2519
def _version_of(python_envs: PythonEnvs, name: str) -> Optional[str]:

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# packages to run the app for both environments
22
mitmproxy>=10.1.6
3+
msgspec>=0.18.6
34
tkinter-tooltip>=2.2.0
45
watchdog>=3.0.0
56
# for downloading the player and libmpv

resources/README_template.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Insert an _All_ category when missing so you can easily **search your entire catalog**.
44
<kbd><img src="resources/readme/all.png"></kbd>
55
* Update ***[Mpv](https://mpv.io/)*** and **Sfvip Player** so you can enjoy their latest features.
6+
* Cache MAC acccounts all categories to access it faster.
67
* Translated in all **Sfvip Player** languages.
78
* Support an **external EPG**[^1].
89

sfvip_all_config.py

-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,3 @@ class EPG:
2525
confidence: int = 30
2626
requests_timeout: int = 5
2727
prefer_internal: bool = True
28-
29-
class AllCategory:
30-
inject_in_live: bool = False

src/mitm/addon/__init__.py

+55-46
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from mitmproxy import http
99
from mitmproxy.proxy.server_hooks import ServerConnectionHookData
1010

11-
from ..cache import AllUpdated, MACCache, UpdateCacheProgressT
11+
from ..cache import AllCached, MACCache, UpdateCacheProgressT
1212
from ..epg import EPG, EpgCallbacks
1313
from ..utils import APItype, get_query_key, response_json
1414
from .all import AllCategoryName, AllPanels
@@ -63,16 +63,20 @@ def set_epg_server(flow: http.HTTPFlow, epg: EPG, api: APItype) -> None:
6363

6464

6565
class ApiRequest:
66-
_api = {"portal.php?": APItype.MAC, "player_api.php?": APItype.XC}
66+
_api = {
67+
"player_api.php": APItype.XC,
68+
"stalker_portal": APItype.MAC,
69+
"portal.php": APItype.MAC,
70+
"load.php": APItype.MAC,
71+
}
6772

6873
def __init__(self, accounts_urls: set[str]) -> None:
6974
self.accounts_urls = accounts_urls
7075

71-
def __call__(self, flow: http.HTTPFlow) -> Optional[APItype]:
76+
async def __call__(self, flow: http.HTTPFlow) -> Optional[APItype]:
7277
request = flow.request
73-
for request_part, api in ApiRequest._api.items():
74-
if request_part in request.path:
75-
return api
78+
if api := ApiRequest._api.get(request.path_components[0]):
79+
return api
7680
return APItype.M3U if request.url in self.accounts_urls else None
7781

7882

@@ -135,7 +139,7 @@ def disconnect(self, data: ServerConnectionHookData) -> None:
135139

136140
class AddonAllConfig(NamedTuple):
137141
all_name: AllCategoryName
138-
all_updated: AllUpdated
142+
all_cached: AllCached
139143

140144

141145
class SfVipAddOn:
@@ -152,7 +156,7 @@ def __init__(
152156
timeout: int,
153157
) -> None:
154158
self.api_request = ApiRequest(accounts_urls)
155-
self.mac_cache = MACCache(roaming, update_progress, all_config.all_updated)
159+
self.mac_cache = MACCache(roaming, update_progress, all_config.all_cached)
156160
self.epg = EPG(roaming, epg_callbacks, timeout)
157161
self.m3u_stream = M3UStream(self.epg)
158162
self.panels = AllPanels(all_config.all_name)
@@ -176,56 +180,61 @@ def wait_running(self, timeout: int) -> bool:
176180
return self.epg.wait_running(timeout)
177181

178182
async def request(self, flow: http.HTTPFlow) -> None:
179-
logger.debug("REQUEST %s", flow.request.pretty_url)
180-
if api := self.api_request(flow):
183+
# logger.debug("REQUEST %s", flow.request.pretty_url)
184+
if api := await self.api_request(flow):
181185
match api, get_query_key(flow, "action"):
182186
case APItype.MAC, "get_ordered_list":
183-
self.mac_cache.load_response(flow)
187+
await self.mac_cache.load_response(flow)
184188
case APItype.MAC, _:
185189
self.mac_cache.stop(flow)
186190
case APItype.XC, action if action:
187191
self.panels.serve_all(flow, action)
188192

189-
async def response(self, flow: http.HTTPFlow) -> None:
190-
logger.debug("RESPONSE %s %s", flow.request.pretty_url, flow.response and flow.response.status_code)
191-
if not self.m3u_stream.start(flow):
192-
if flow.response and not flow.response.stream:
193-
if api := self.api_request(flow):
194-
match api, get_query_key(flow, "action"):
195-
case APItype.M3U, _:
196-
set_epg_server(flow, self.epg, api)
197-
case APItype.MAC, "get_short_epg":
198-
get_short_epg(flow, self.epg, api)
199-
case APItype.MAC, "get_all_channels":
200-
set_epg_server(flow, self.epg, api)
201-
case APItype.MAC, "get_ordered_list":
202-
self.mac_cache.save_response(flow)
203-
case APItype.MAC, "get_categories":
204-
self.mac_cache.inject_all_cached_category(flow)
205-
case APItype.XC, "get_series_info":
206-
fix_series_info(flow.response)
207-
case APItype.XC, "get_live_streams":
208-
set_epg_server(flow, self.epg, api)
209-
case APItype.XC, "get_short_epg" if not get_query_key(flow, "category_id"):
210-
get_short_epg(flow, self.epg, api)
211-
case APItype.XC, action if action:
212-
self.panels.inject_all(flow, action)
193+
async def responseheaders(self, flow: http.HTTPFlow) -> None:
194+
"""all reponses are streamed except the api requests"""
195+
# logger.debug("STREAM %s", flow.request.pretty_url)
196+
if not await self.api_request(flow):
197+
if flow.response:
198+
flow.response.stream = True
213199

200+
async def response(self, flow: http.HTTPFlow) -> None:
201+
# logger.debug("RESPONSE %s %s", flow.request.pretty_url, flow.response and flow.response.status_code)
202+
if not flow.response:
203+
return
204+
if not flow.response.stream:
205+
if api := await self.api_request(flow):
206+
match api, get_query_key(flow, "action"):
207+
case APItype.MAC, "get_ordered_list":
208+
await self.mac_cache.save_response(flow)
209+
case APItype.MAC, "get_short_epg":
210+
get_short_epg(flow, self.epg, api)
211+
case APItype.MAC, "get_all_channels":
212+
set_epg_server(flow, self.epg, api)
213+
case APItype.MAC, "get_categories":
214+
self.mac_cache.inject_all_cached_category(flow)
215+
case APItype.XC, "get_series_info":
216+
fix_series_info(flow.response)
217+
case APItype.XC, "get_live_streams":
218+
set_epg_server(flow, self.epg, api)
219+
case APItype.XC, "get_short_epg" if not get_query_key(flow, "category_id"):
220+
get_short_epg(flow, self.epg, api)
221+
case APItype.XC, action if action:
222+
self.panels.inject_all(flow, action)
223+
case APItype.M3U, _:
224+
set_epg_server(flow, self.epg, api)
225+
else:
226+
self.m3u_stream.start(flow)
227+
self.mac_cache.stop_all()
228+
229+
# TODO progress for MAC Cache not hiding !! nee to call self.mac_cache.stop_all(), but where?
214230
async def error(self, flow: http.HTTPFlow):
215-
logger.debug("ERROR %s", flow.request.pretty_url)
231+
# logger.debug("ERROR %s", flow.request.pretty_url)
216232
if not self.m3u_stream.stop(flow):
217-
if api := self.api_request(flow):
233+
if api := await self.api_request(flow):
218234
match api, get_query_key(flow, "action"):
219235
case APItype.MAC, "get_ordered_list":
220236
self.mac_cache.stop(flow)
221237

222-
async def responseheaders(self, flow: http.HTTPFlow) -> None:
223-
"""all reponses are streamed except the api requests"""
224-
logger.debug("STREAM %s", flow.request.pretty_url)
225-
if not self.api_request(flow):
226-
if flow.response:
227-
flow.response.stream = True
228-
229-
async def server_disconnected(self, data: ServerConnectionHookData) -> None:
230-
logger.debug("DISCONNECT %s %s", data.server.peername, data.server.transport_protocol)
238+
def server_disconnected(self, data: ServerConnectionHookData) -> None:
239+
# logger.debug("DISCONNECT %s %s", data.server.peername, data.server.transport_protocol)
231240
self.m3u_stream.disconnect(data)

src/mitm/addon/all.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
class AllCategoryName(NamedTuple):
1515
live: Optional[str]
16-
series: str
17-
vod: str
16+
series: Optional[str]
17+
vod: Optional[str]
1818

1919

2020
@dataclass
@@ -56,10 +56,11 @@ def _log(verb: str, panel: Panel, action: str) -> None:
5656

5757
class AllPanels:
5858
def __init__(self, all_name: AllCategoryName) -> None:
59-
panels = [
60-
_get_panel(PanelType.VOD, all_name.vod),
61-
_get_panel(PanelType.SERIES, all_name.series, streams=False),
62-
]
59+
panels = []
60+
if all_name.series:
61+
panels.append(_get_panel(PanelType.SERIES, all_name.series, streams=False))
62+
if all_name.vod:
63+
panels.append(_get_panel(PanelType.VOD, all_name.vod))
6364
if all_name.live:
6465
panels.append(_get_panel(PanelType.LIVE, all_name.live))
6566
self.category_panel = {panel.get_category: panel for panel in panels}

0 commit comments

Comments
 (0)