gecko-web-runtime-client 1.4.3__tar.gz → 1.4.4__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.
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/PACKAGE_README.md +2 -2
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/PKG-INFO +3 -3
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/__init__.py +1 -1
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/__init__.py +12 -12
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/__main__.py +23 -23
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_article.py +110 -110
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_diagnostics.py +207 -207
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_diagnostics_round.py +177 -177
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_frame_context.py +61 -61
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_logging.py +18 -18
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_manual_data.py +135 -135
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_slider_image.py +90 -90
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_variant_resources.py +52 -52
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/client.py +87 -87
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/exceptions.py +5 -5
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/__init__.py +1 -1
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/computed-style.js +89 -89
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/drag-control.js +9 -9
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/drag-motion.js +40 -40
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/drag-target.js +25 -25
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/host-timeline.js +43 -43
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/input-events.js +103 -103
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/manual-gesture.js +39 -39
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/native-gl-client.js +130 -130
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/native-webgl.js +66 -66
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/native_gl.py +323 -323
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/native_gl_service.py +168 -168
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/plugin_profile.json +4 -4
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/sdk-handshake.js +21 -21
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/var-speed-drag-control.js +10 -10
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/window-message-bridge.js +32 -32
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/code.js +841 -841
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/package-lock.json +401 -401
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/package.json +10 -10
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/executor.py +215 -215
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/native_gl_service.py +164 -164
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/resources/frame-context-manifest.json +12 -12
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/resources/migration-manifest.json +259 -259
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/resources/var-speed-resource-manifest.json +28 -28
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/runtime.py +116 -116
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/models.py +54 -54
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/transport.py +48 -48
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime_client.egg-info/PKG-INFO +3 -3
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/pyproject.toml +1 -1
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/README.md +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/__main__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/_leases.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/api/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/api/context.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/api/page.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/api/pool.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/api/runtime.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/data_plane.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/gc_cc.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/logging.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/memory.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/metrics.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/diagnostics/resources.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/http.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/installer.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/_flow.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/capability_profile.json +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/ft.module.js +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/layout_profile.json +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/media_profile.json +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/rtproxy.js +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/tracker.module.js +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/integrations/wechat/js_runtime/environment/assets/webgl_profile.json +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/iocp_pipe.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/media_capture.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/media_downloader.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/models/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/models/navigation.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/_urls.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/client.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/exceptions.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/models.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/network/transport.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/pipe.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/session.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/workflows/__init__.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/workflows/turnstile.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/workflows/wechat.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime/workflows/wechat_challenge.py +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime_client.egg-info/SOURCES.txt +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime_client.egg-info/dependency_links.txt +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime_client.egg-info/requires.txt +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/gecko_web_runtime_client.egg-info/top_level.txt +0 -0
- {gecko_web_runtime_client-1.4.3 → gecko_web_runtime_client-1.4.4}/setup.cfg +0 -0
|
@@ -19,11 +19,11 @@ HTTP imports are retained through `wpr-http`.
|
|
|
19
19
|
|
|
20
20
|
The same distribution includes `gecko_web_runtime.integrations.wechat`.
|
|
21
21
|
It uses `wpr-http` and a local Node.js environment, with no browser Page.
|
|
22
|
-
Install version 1.4.
|
|
22
|
+
Install version 1.4.4 or newer with its optional dependencies, then prepare Node.js
|
|
23
23
|
20+ dependencies in the user's cache:
|
|
24
24
|
|
|
25
25
|
```powershell
|
|
26
|
-
pip install --upgrade "gecko-web-runtime-client[wechat]>=1.4.
|
|
26
|
+
pip install --upgrade "gecko-web-runtime-client[wechat]>=1.4.4"
|
|
27
27
|
python -m gecko_web_runtime.integrations.wechat install-js
|
|
28
28
|
```
|
|
29
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gecko-web-runtime-client
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.4
|
|
4
4
|
Summary: Thin Python client for the Firefox-derived WPR Gecko Worker protocol
|
|
5
5
|
Author: WPR project
|
|
6
6
|
License: MPL-2.0-compatible client; see the runtime bundle notices
|
|
@@ -40,11 +40,11 @@ HTTP imports are retained through `wpr-http`.
|
|
|
40
40
|
|
|
41
41
|
The same distribution includes `gecko_web_runtime.integrations.wechat`.
|
|
42
42
|
It uses `wpr-http` and a local Node.js environment, with no browser Page.
|
|
43
|
-
Install version 1.4.
|
|
43
|
+
Install version 1.4.4 or newer with its optional dependencies, then prepare Node.js
|
|
44
44
|
20+ dependencies in the user's cache:
|
|
45
45
|
|
|
46
46
|
```powershell
|
|
47
|
-
pip install --upgrade "gecko-web-runtime-client[wechat]>=1.4.
|
|
47
|
+
pip install --upgrade "gecko-web-runtime-client[wechat]>=1.4.4"
|
|
48
48
|
python -m gecko_web_runtime.integrations.wechat install-js
|
|
49
49
|
```
|
|
50
50
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"""Optional site integrations shipped with the browser client."""
|
|
1
|
+
"""Optional site integrations shipped with the browser client."""
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"""HTTP and local-JavaScript WeChat article client."""
|
|
2
|
-
|
|
3
|
-
from .client import AsyncWechatClient
|
|
4
|
-
from .exceptions import WechatDependencyError
|
|
5
|
-
from .models import WechatArticle, WechatConfig
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"AsyncWechatClient",
|
|
9
|
-
"WechatArticle",
|
|
10
|
-
"WechatConfig",
|
|
11
|
-
"WechatDependencyError",
|
|
12
|
-
]
|
|
1
|
+
"""HTTP and local-JavaScript WeChat article client."""
|
|
2
|
+
|
|
3
|
+
from .client import AsyncWechatClient
|
|
4
|
+
from .exceptions import WechatDependencyError
|
|
5
|
+
from .models import WechatArticle, WechatConfig
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"AsyncWechatClient",
|
|
9
|
+
"WechatArticle",
|
|
10
|
+
"WechatConfig",
|
|
11
|
+
"WechatDependencyError",
|
|
12
|
+
]
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
"""Install optional Node dependencies into the user's WPR cache."""
|
|
2
|
-
|
|
3
|
-
import argparse
|
|
4
|
-
|
|
5
|
-
from .js_runtime.runtime import LocalJsRuntime
|
|
6
|
-
from .models import WechatConfig
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def main():
|
|
10
|
-
parser = argparse.ArgumentParser()
|
|
11
|
-
parser.add_argument("command", choices=["install-js"])
|
|
12
|
-
parser.add_argument("--cache-dir")
|
|
13
|
-
parser.add_argument("--node", default="node")
|
|
14
|
-
args = parser.parse_args()
|
|
15
|
-
runtime = LocalJsRuntime(
|
|
16
|
-
WechatConfig(js_cache_dir=args.cache_dir, node_executable=args.node)
|
|
17
|
-
)
|
|
18
|
-
print(runtime.install())
|
|
19
|
-
return 0
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if __name__ == "__main__":
|
|
23
|
-
raise SystemExit(main())
|
|
1
|
+
"""Install optional Node dependencies into the user's WPR cache."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
from .js_runtime.runtime import LocalJsRuntime
|
|
6
|
+
from .models import WechatConfig
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
parser = argparse.ArgumentParser()
|
|
11
|
+
parser.add_argument("command", choices=["install-js"])
|
|
12
|
+
parser.add_argument("--cache-dir")
|
|
13
|
+
parser.add_argument("--node", default="node")
|
|
14
|
+
args = parser.parse_args()
|
|
15
|
+
runtime = LocalJsRuntime(
|
|
16
|
+
WechatConfig(js_cache_dir=args.cache_dir, node_executable=args.node)
|
|
17
|
+
)
|
|
18
|
+
print(runtime.install())
|
|
19
|
+
return 0
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
raise SystemExit(main())
|
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
"""Article parsing without a Node dependency or a hard-coded article ID."""
|
|
2
|
-
|
|
3
|
-
from html.parser import HTMLParser
|
|
4
|
-
import hashlib
|
|
5
|
-
import re
|
|
6
|
-
from urllib.parse import parse_qs, urlsplit
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ArticleParser(HTMLParser):
|
|
10
|
-
def __init__(self):
|
|
11
|
-
super().__init__(convert_charrefs=True)
|
|
12
|
-
self.stack = []
|
|
13
|
-
self.title = []
|
|
14
|
-
self.content = []
|
|
15
|
-
self.media = []
|
|
16
|
-
self.body_found = False
|
|
17
|
-
|
|
18
|
-
def handle_starttag(self, tag, attrs):
|
|
19
|
-
values = dict(attrs)
|
|
20
|
-
title = values.get("id") == "activity-name" or any(x[1] for x in self.stack)
|
|
21
|
-
body = values.get("id") == "js_content" or any(x[2] for x in self.stack)
|
|
22
|
-
self.body_found |= values.get("id") == "js_content"
|
|
23
|
-
skip = tag in {"script", "style"} or any(x[3] for x in self.stack)
|
|
24
|
-
if body and tag in {
|
|
25
|
-
"img",
|
|
26
|
-
"iframe",
|
|
27
|
-
"video",
|
|
28
|
-
"mp-video",
|
|
29
|
-
"mp-common-videosnap",
|
|
30
|
-
}:
|
|
31
|
-
self.media.append(
|
|
32
|
-
{
|
|
33
|
-
"tag": tag,
|
|
34
|
-
"src": values.get("data-src") or values.get("src", ""),
|
|
35
|
-
"vid": values.get("vid") or values.get("data-vid", ""),
|
|
36
|
-
}
|
|
37
|
-
)
|
|
38
|
-
if body and tag in {"p", "section", "br", "h1", "h2"}:
|
|
39
|
-
self.content.append("\n")
|
|
40
|
-
if tag not in {
|
|
41
|
-
"area",
|
|
42
|
-
"base",
|
|
43
|
-
"br",
|
|
44
|
-
"col",
|
|
45
|
-
"embed",
|
|
46
|
-
"hr",
|
|
47
|
-
"img",
|
|
48
|
-
"input",
|
|
49
|
-
"link",
|
|
50
|
-
"meta",
|
|
51
|
-
"param",
|
|
52
|
-
"source",
|
|
53
|
-
"track",
|
|
54
|
-
"wbr",
|
|
55
|
-
}:
|
|
56
|
-
self.stack.append((tag, title, body, skip))
|
|
57
|
-
|
|
58
|
-
def handle_startendtag(self, tag, attrs):
|
|
59
|
-
self.handle_starttag(tag, attrs)
|
|
60
|
-
self.handle_endtag(tag)
|
|
61
|
-
|
|
62
|
-
def handle_endtag(self, tag):
|
|
63
|
-
for index in range(len(self.stack) - 1, -1, -1):
|
|
64
|
-
if self.stack[index][0] == tag:
|
|
65
|
-
if self.stack[index][2] and tag in {"p", "section", "h1", "h2"}:
|
|
66
|
-
self.content.append("\n")
|
|
67
|
-
del self.stack[index:]
|
|
68
|
-
break
|
|
69
|
-
|
|
70
|
-
def handle_data(self, data):
|
|
71
|
-
if not self.stack or self.stack[-1][3]:
|
|
72
|
-
return
|
|
73
|
-
if self.stack[-1][1]:
|
|
74
|
-
self.title.append(data)
|
|
75
|
-
if self.stack[-1][2]:
|
|
76
|
-
self.content.append(data)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def parse_article(html, url):
|
|
80
|
-
parser = ArticleParser()
|
|
81
|
-
parser.feed(html)
|
|
82
|
-
title = " ".join("".join(parser.title).split())
|
|
83
|
-
text = re.sub(
|
|
84
|
-
r"\n\s*\n+", "\n\n", re.sub(r"[ \t]+", " ", "".join(parser.content))
|
|
85
|
-
).strip()
|
|
86
|
-
query = parse_qs(urlsplit(url).query)
|
|
87
|
-
identity = {
|
|
88
|
-
f"target_{key}_matches": query[key][0] in html if query.get(key) else None
|
|
89
|
-
for key in ("mid", "sn")
|
|
90
|
-
}
|
|
91
|
-
verified = (
|
|
92
|
-
bool(title)
|
|
93
|
-
and parser.body_found
|
|
94
|
-
and (len(text) > 100 or bool(parser.media))
|
|
95
|
-
and not re.search(r"register_code\s*:", html)
|
|
96
|
-
and all(value is not False for value in identity.values())
|
|
97
|
-
)
|
|
98
|
-
proof = {
|
|
99
|
-
"title": title,
|
|
100
|
-
"content_chars": len(text),
|
|
101
|
-
"media_count": len(parser.media),
|
|
102
|
-
"media": parser.media,
|
|
103
|
-
"html_bytes": len(html.encode("utf-8")),
|
|
104
|
-
"html_sha256": hashlib.sha256(html.encode("utf-8")).hexdigest(),
|
|
105
|
-
"article_verified": verified,
|
|
106
|
-
**identity,
|
|
107
|
-
}
|
|
108
|
-
if not verified:
|
|
109
|
-
raise ValueError("Article title/body/target identity verification failed")
|
|
110
|
-
return proof, text
|
|
1
|
+
"""Article parsing without a Node dependency or a hard-coded article ID."""
|
|
2
|
+
|
|
3
|
+
from html.parser import HTMLParser
|
|
4
|
+
import hashlib
|
|
5
|
+
import re
|
|
6
|
+
from urllib.parse import parse_qs, urlsplit
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ArticleParser(HTMLParser):
|
|
10
|
+
def __init__(self):
|
|
11
|
+
super().__init__(convert_charrefs=True)
|
|
12
|
+
self.stack = []
|
|
13
|
+
self.title = []
|
|
14
|
+
self.content = []
|
|
15
|
+
self.media = []
|
|
16
|
+
self.body_found = False
|
|
17
|
+
|
|
18
|
+
def handle_starttag(self, tag, attrs):
|
|
19
|
+
values = dict(attrs)
|
|
20
|
+
title = values.get("id") == "activity-name" or any(x[1] for x in self.stack)
|
|
21
|
+
body = values.get("id") == "js_content" or any(x[2] for x in self.stack)
|
|
22
|
+
self.body_found |= values.get("id") == "js_content"
|
|
23
|
+
skip = tag in {"script", "style"} or any(x[3] for x in self.stack)
|
|
24
|
+
if body and tag in {
|
|
25
|
+
"img",
|
|
26
|
+
"iframe",
|
|
27
|
+
"video",
|
|
28
|
+
"mp-video",
|
|
29
|
+
"mp-common-videosnap",
|
|
30
|
+
}:
|
|
31
|
+
self.media.append(
|
|
32
|
+
{
|
|
33
|
+
"tag": tag,
|
|
34
|
+
"src": values.get("data-src") or values.get("src", ""),
|
|
35
|
+
"vid": values.get("vid") or values.get("data-vid", ""),
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
if body and tag in {"p", "section", "br", "h1", "h2"}:
|
|
39
|
+
self.content.append("\n")
|
|
40
|
+
if tag not in {
|
|
41
|
+
"area",
|
|
42
|
+
"base",
|
|
43
|
+
"br",
|
|
44
|
+
"col",
|
|
45
|
+
"embed",
|
|
46
|
+
"hr",
|
|
47
|
+
"img",
|
|
48
|
+
"input",
|
|
49
|
+
"link",
|
|
50
|
+
"meta",
|
|
51
|
+
"param",
|
|
52
|
+
"source",
|
|
53
|
+
"track",
|
|
54
|
+
"wbr",
|
|
55
|
+
}:
|
|
56
|
+
self.stack.append((tag, title, body, skip))
|
|
57
|
+
|
|
58
|
+
def handle_startendtag(self, tag, attrs):
|
|
59
|
+
self.handle_starttag(tag, attrs)
|
|
60
|
+
self.handle_endtag(tag)
|
|
61
|
+
|
|
62
|
+
def handle_endtag(self, tag):
|
|
63
|
+
for index in range(len(self.stack) - 1, -1, -1):
|
|
64
|
+
if self.stack[index][0] == tag:
|
|
65
|
+
if self.stack[index][2] and tag in {"p", "section", "h1", "h2"}:
|
|
66
|
+
self.content.append("\n")
|
|
67
|
+
del self.stack[index:]
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
def handle_data(self, data):
|
|
71
|
+
if not self.stack or self.stack[-1][3]:
|
|
72
|
+
return
|
|
73
|
+
if self.stack[-1][1]:
|
|
74
|
+
self.title.append(data)
|
|
75
|
+
if self.stack[-1][2]:
|
|
76
|
+
self.content.append(data)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def parse_article(html, url):
|
|
80
|
+
parser = ArticleParser()
|
|
81
|
+
parser.feed(html)
|
|
82
|
+
title = " ".join("".join(parser.title).split())
|
|
83
|
+
text = re.sub(
|
|
84
|
+
r"\n\s*\n+", "\n\n", re.sub(r"[ \t]+", " ", "".join(parser.content))
|
|
85
|
+
).strip()
|
|
86
|
+
query = parse_qs(urlsplit(url).query)
|
|
87
|
+
identity = {
|
|
88
|
+
f"target_{key}_matches": query[key][0] in html if query.get(key) else None
|
|
89
|
+
for key in ("mid", "sn")
|
|
90
|
+
}
|
|
91
|
+
verified = (
|
|
92
|
+
bool(title)
|
|
93
|
+
and parser.body_found
|
|
94
|
+
and (len(text) > 100 or bool(parser.media))
|
|
95
|
+
and not re.search(r"register_code\s*:", html)
|
|
96
|
+
and all(value is not False for value in identity.values())
|
|
97
|
+
)
|
|
98
|
+
proof = {
|
|
99
|
+
"title": title,
|
|
100
|
+
"content_chars": len(text),
|
|
101
|
+
"media_count": len(parser.media),
|
|
102
|
+
"media": parser.media,
|
|
103
|
+
"html_bytes": len(html.encode("utf-8")),
|
|
104
|
+
"html_sha256": hashlib.sha256(html.encode("utf-8")).hexdigest(),
|
|
105
|
+
"article_verified": verified,
|
|
106
|
+
**identity,
|
|
107
|
+
}
|
|
108
|
+
if not verified:
|
|
109
|
+
raise ValueError("Article title/body/target identity verification failed")
|
|
110
|
+
return proof, text
|