Skip to content

Commit eccec77

Browse files
committed
fix
1 parent 8df3a01 commit eccec77

File tree

4 files changed

+189
-7
lines changed

4 files changed

+189
-7
lines changed

barcode-reader/web/configuration/read-from-existing-files.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ let results = await router.capture("blob:https://demo.dynamsoft.com/afb84bd2-e8c
1919
// Release the resources after the job is finished.
2020
router.dispose();
2121
```
22+
> [this article](https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/samples-demos/index.html) shows more details.
2223
2324
## Version 9.x
2425
```javascript
2526
let reader = await Dynamsoft.DBR.BarcodeReader.createInstance();
2627
let results = await reader.decode(imageSource);
2728
```
2829

29-
> [this article](https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/samples-demos/index.html) shows more details.
30+

barcode-reader/web/scan-setting/difference-between-barcodeReader-and-barcodeScanner.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ needAutoGenerateSidebar: false
1212

1313
**_NOTE:_** - This is for version 9 or lower of barcode reader sdk
1414

15-
No, as each offers a different functionality than the other. The `BarcodeReader` class is used to decode static images (via one of the [decode\*](https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/api-reference/BarcodeReader.html#decode-barcodes) methods) and does not have the ability to open the camera stream and decode barcodes directly from the video stream.
15+
No, as each offers a different functionality than the other. The `BarcodeReader` class is used to decode static images (via one of the [decode\*](https://www.dynamsoft.com/barcode-reader/docs/v9/web/programming/javascript/api-reference/BarcodeReader.html#decode) methods) and does not have the ability to open the camera stream and decode barcodes directly from the video stream.
1616

1717
The `BarcodeScanner` class on the other hand has the ability to decode barcodes directly from a video input, but it can also capture a still image using the camera when `singleFrameMode` is toggled.

barcode-reader/web/scan-setting/enable-supported-barcode-format.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,19 @@ settings.barcodeSettings.barcodeFormatIds =
4141
Dynamsoft.DBR.EnumBarcodeFormat.BF_ONED | Dynamsoft.DBR.EnumBarcodeFormat.BF_QR_CODE;
4242
await router.updateSettings("ReadSingleBarcode", settings);
4343
await router.startCapturing("ReadSingleBarcode");
44+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/web/programming/javascript/api-reference/enum-barcode-format.html?lang=js)
4445
```
4546
>
4647
```objc
4748
DSBarcodeScannerConfig *config = [[DSBarcodeScannerConfig alloc] init];
48-
config.barcodeFormats = DSBarcodeFormatQRCode | DSBarcodeFormatOned; ;
49+
config.barcodeFormats = DSBarcodeFormatQRCode | DSBarcodeFormatOned;
50+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/mobile/programming/objectivec-swift/api-reference/enum/barcode-format.html)
4951
```
5052
>
5153
```swift
5254
let config = BarcodeScannerConfig()
5355
config.barcodeFormats = [.oneD, .qrCode]
56+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/mobile/programming/objectivec-swift/api-reference/enum/barcode-format.html)
5457
```
5558
>
5659
```java
@@ -64,6 +67,7 @@ try {
6467
} catch (CaptureVisionRouterException e) {
6568
e.printStackTrace();
6669
}
70+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/server/programming/java/api-reference/enum-barcode-format.html)
6771
```
6872
>
6973
```python
@@ -75,6 +79,7 @@ err_code, err_str, settings = cvr_instance.get_simplified_settings(EnumPresetTem
7579
settings.barcode_settings.barcode_format_ids = EnumBarcodeFormat.BF_QR_CODE.value | EnumBarcodeFormat.BF_ONED. value
7680
# Update the settings.
7781
err_code, err_str = cvr_instance.update_settings(EnumPresetTemplate.PT_READ_BARCODES.value, settings)
82+
# View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/server/programming/python/api-reference/enum-barcode-format.html)
7883
```
7984
>
8085
```c++
@@ -88,6 +93,7 @@ cvr->GetSimplifiedSettings(CPresetTemplate::PT_READ_BARCODES, &settings);
8893
settings.barcodeSettings.barcodeFormatIds = BF_QR_CODE | BF_ONED;
8994
// Update the settings.
9095
cvr->UpdateSettings(CPresetTemplate::PT_READ_BARCODES, &settings, szErrorMsg, 256);
96+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/server/programming/cplusplus/api-reference/enum-barcode-format.html?lang=cpp)
9197
```
9298
>
9399
```csharp
@@ -103,7 +109,5 @@ using (CaptureVisionRouter cvr = new CaptureVisionRouter())
103109
// Update the settings.
104110
cvr.UpdateSettings(PresetTemplate.PT_READ_BARCODES, settings, out errorMsg);
105111
}
106-
```
107-
108-
#### Step 3. Verify Supported Formats
109-
View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/capture-vision/docs/core/enums/barcode-reader/barcode-format.html?product=dbr)
112+
// View the complete list of supported barcode formats and their corresponding IDs here: [Barcode Format Documentation](https://www.dynamsoft.com/barcode-reader/docs/server/programming/dotnet/api-reference/enum-barcode-format.html?product=dcv&lang=dotnet)
113+
```

check_links.py

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import os
2+
import re
3+
import urllib.request
4+
import urllib.error
5+
import ssl
6+
import concurrent.futures
7+
8+
# Configuration
9+
ROOT_DIR = os.getcwd()
10+
MAX_THREADS = 20
11+
SOFT_404_KEYWORDS = [
12+
'id="pageNotFound"',
13+
"Oops! That page can't be found.",
14+
"alt=\"Page Not Found\"",
15+
"illus-404.png",
16+
]
17+
18+
19+
# Context for https requests
20+
ctx = ssl.create_default_context()
21+
ctx.check_hostname = False
22+
ctx.verify_mode = ssl.CERT_NONE
23+
24+
def find_md_files(root_dir):
25+
md_files = []
26+
for root, dirs, files in os.walk(root_dir):
27+
if '.git' in dirs: dirs.remove('.git')
28+
if '_site' in dirs: dirs.remove('_site')
29+
30+
for file in files:
31+
if file.endswith('.md'):
32+
md_files.append(os.path.join(root, file))
33+
return md_files
34+
35+
DS_SOFT_404_MARKERS = [
36+
'id="pagenotfound"', # DOM id(你 lower() 了,所以用小写)
37+
'illus-404.png', # 404 图片
38+
"oops! that page can't be found.", # 404 H1 文案
39+
'alt="page not found"', # 图片 alt
40+
]
41+
42+
def is_soft_404(content_lower: str) -> str | None:
43+
# 返回命中的 marker,便于 debug
44+
for m in DS_SOFT_404_MARKERS:
45+
if m in content_lower:
46+
return m
47+
return None
48+
49+
def check_url(url):
50+
try:
51+
req = urllib.request.Request(
52+
url,
53+
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
54+
)
55+
with urllib.request.urlopen(req, timeout=15, context=ctx) as response:
56+
code = response.getcode()
57+
58+
# 3xx 也算 OK(已允许重定向则一般拿到最终 200,这里保留逻辑)
59+
if 200 <= code < 400:
60+
try:
61+
# 建议读多一点,Dynamsoft 的 pageNotFound 区块可能不在前 15KB
62+
content = response.read(50000).decode('utf-8', errors='ignore').lower()
63+
64+
# ✅ 先做“强特征” soft-404 判断(更准)
65+
hit = is_soft_404(content)
66+
if hit:
67+
return False, code, f"Soft 404 (marker: {hit})"
68+
69+
# ✅ 再做你原来的 title/h1 关键词检测(兜底)
70+
if "<title>" in content:
71+
title_part = content.split("<title>", 1)[1].split("</title>", 1)[0]
72+
for keyword in SOFT_404_KEYWORDS:
73+
if keyword in title_part:
74+
return False, code, f"Soft 404 (Title: '{keyword}')"
75+
76+
# h1 可能有属性,例如 <h1 class="...">,所以用更宽松的方式找
77+
if "<h1" in content and "</h1>" in content:
78+
h1_block = content.split("<h1", 1)[1].split("</h1>", 1)[0]
79+
for keyword in SOFT_404_KEYWORDS:
80+
if keyword in h1_block:
81+
return False, code, f"Soft 404 (H1: '{keyword}')"
82+
83+
except Exception:
84+
pass
85+
86+
return True, code, "OK"
87+
else:
88+
return False, code, f"Status {code}"
89+
90+
except urllib.error.HTTPError as e:
91+
return False, e.code, f"HTTP Error {e.code}"
92+
except urllib.error.URLError as e:
93+
return False, 0, f"URL Error: {e.reason}"
94+
except Exception as e:
95+
return False, 0, f"Error: {str(e)}"
96+
97+
def scan_file_for_https_links(file_path):
98+
links = []
99+
try:
100+
with open(file_path, 'r', encoding='utf-8') as f:
101+
content = f.read()
102+
103+
md_links = re.findall(r'\[.*?\]\((https://.*?)\)', content)
104+
html_srcs = re.findall(r'src=["\'](https://.*?)["\']', content)
105+
106+
for link in md_links + html_srcs:
107+
clean_link = link.split()[0].strip('()')
108+
links.append(clean_link)
109+
except Exception as e:
110+
print(f"Error reading {file_path}: {e}")
111+
return links
112+
113+
def main():
114+
print(f"Scanning for HTTPS links in: {ROOT_DIR}")
115+
files = find_md_files(ROOT_DIR)
116+
117+
file_links_map = {}
118+
all_urls = set()
119+
120+
for file_path in files:
121+
links = scan_file_for_https_links(file_path)
122+
if links:
123+
file_links_map[file_path] = links
124+
all_urls.update(links)
125+
126+
print(f"Found {len(all_urls)} unique HTTPS links to check.")
127+
print(f"Checking links (Concurrent Status + Soft 404 Check) ...")
128+
129+
url_status = {}
130+
131+
with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
132+
future_to_url = {executor.submit(check_url, url): url for url in all_urls}
133+
completed = 0
134+
total = len(all_urls)
135+
136+
for future in concurrent.futures.as_completed(future_to_url):
137+
url = future_to_url[future]
138+
try:
139+
result = future.result()
140+
url_status[url] = result
141+
except Exception as e:
142+
url_status[url] = (False, 0, str(e))
143+
144+
completed += 1
145+
if completed % 10 == 0 or completed == total:
146+
print(f"Progress: {completed}/{total}", end='\r')
147+
148+
print(f"\nProgress: {total}/{total}")
149+
print("\n--- Broken or Soft 404 Links Report ---\n")
150+
151+
broken_count = 0
152+
files_with_issues = 0
153+
154+
for file_path, links in file_links_map.items():
155+
issues_in_file = []
156+
for link in links:
157+
if link in url_status:
158+
is_valid, code, msg = url_status[link]
159+
if not is_valid:
160+
issues_in_file.append((link, code, msg))
161+
162+
if issues_in_file:
163+
files_with_issues += 1
164+
rel_path = os.path.relpath(file_path, ROOT_DIR)
165+
print(f"📄 {rel_path}")
166+
for link, code, msg in issues_in_file:
167+
print(f" ❌ [{code}] {link} -> {msg}")
168+
broken_count += 1
169+
print("")
170+
171+
if broken_count == 0:
172+
print("✅ No broken links found!")
173+
else:
174+
print(f"❌ Found {broken_count} issues in {files_with_issues} files.")
175+
176+
if __name__ == "__main__":
177+
main()

0 commit comments

Comments
 (0)