@crowsgear/escl-protocol-scanner 1.1.1 → 1.2.1
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.
- package/LICENSE +21 -21
- package/README.ko.md +177 -0
- package/README.md +177 -173
- package/dist/main.d.ts +5 -5
- package/dist/main.js +1 -1
- package/dist/services/client.js +22 -22
- package/dist/services/discovery.d.ts +1 -1
- package/dist/services/discovery.d.ts.map +1 -1
- package/dist/services/discovery.js +45 -35
- package/dist/services/discovery.js.map +1 -1
- package/package.json +70 -70
- package/python/__main__.py +23 -0
- package/python/app.py +91 -0
- package/python/base/__init__.py +2 -0
- package/python/base/service.py +23 -0
- package/python/common/__init__.py +4 -0
- package/python/common/exceptions.py +28 -0
- package/python/common/logger.py +25 -0
- package/python/common/response.py +26 -0
- package/python/decorators/__init__.py +2 -0
- package/python/decorators/scanner.py +30 -0
- package/python/escl-scanner.spec +98 -84
- package/python/services/__init__.py +2 -0
- package/python/services/escl/__init__.py +3 -0
- package/python/services/escl/discovery.py +53 -0
- package/python/services/escl/protocol.py +358 -0
- package/python/services/scanner.py +31 -0
- package/scripts/check-python-deps.js +269 -206
- package/dist/client.d.ts +0 -78
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -384
- package/dist/client.js.map +0 -1
- package/dist/discovery.d.ts +0 -80
- package/dist/discovery.d.ts.map +0 -1
- package/dist/discovery.js +0 -304
- package/dist/discovery.js.map +0 -1
- package/dist/types.d.ts +0 -172
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
- package/python/__pycache__/base.cpython-312.pyc +0 -0
- package/python/__pycache__/escl_backend.cpython-312.pyc +0 -0
- package/python/base.py +0 -57
- package/python/escl_backend.py +0 -559
- package/python/escl_main.py +0 -119
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 eSCL Protocol Scanner Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 eSCL Protocol Scanner Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# @crowsgear/escl-protocol-scanner
|
|
2
|
+
|
|
3
|
+
[English](./README.md)
|
|
4
|
+
|
|
5
|
+
eSCL/AirPrint 프로토콜 기반 네트워크 스캐너 라이브러리입니다.
|
|
6
|
+
|
|
7
|
+
> **참고**: 네트워크에 연결된 스캐너(WiFi 또는 LAN)만 지원합니다. USB 스캐너는 지원되지 않을 수 있습니다.
|
|
8
|
+
|
|
9
|
+
## 설치
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @crowsgear/escl-protocol-scanner
|
|
13
|
+
# 또는
|
|
14
|
+
yarn add @crowsgear/escl-protocol-scanner
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Python 설치가 필요하지 않습니다!** Windows, macOS, Linux용 사전 빌드 바이너리가 포함되어 있습니다.
|
|
18
|
+
별도의 Python 경로를 지정하여 사용할 수도 있습니다. 자세한 내용은 [Application (사용자 설정)](#application-사용자-설정)을 참고하세요.
|
|
19
|
+
|
|
20
|
+
## 빠른 시작
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { eSCLScanner } from '@crowsgear/escl-protocol-scanner';
|
|
24
|
+
|
|
25
|
+
// 1. 스캐너 탐색 (result: IDiscoveryResponse)
|
|
26
|
+
const result = await eSCLScanner.discoverScanners(10000);
|
|
27
|
+
if (result.success && result.data.length > 0) {
|
|
28
|
+
console.log('발견된 스캐너:', result.data);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. 스캐너 기능 조회 (result.data: IESCLScanner[])
|
|
32
|
+
const scanner = result.data[0]; // 첫 번째 스캐너 선택
|
|
33
|
+
const capabilities = await eSCLScanner.getCapabilities(scanner);
|
|
34
|
+
console.log('해상도:', capabilities?.resolutions);
|
|
35
|
+
console.log('색상 모드:', capabilities?.colorModes);
|
|
36
|
+
|
|
37
|
+
// 3. 스캔 실행
|
|
38
|
+
const filePaths = await eSCLScanner.quickScan({
|
|
39
|
+
scanner: scanner,
|
|
40
|
+
dpi: 300,
|
|
41
|
+
mode: 'color',
|
|
42
|
+
source: 'Platen',
|
|
43
|
+
documentFormat: 'image/jpeg',
|
|
44
|
+
savePath: '/path/to/save',
|
|
45
|
+
});
|
|
46
|
+
console.log('저장된 파일:', filePaths);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
### eSCLScanner
|
|
52
|
+
|
|
53
|
+
기본 인스턴스로, 바로 사용할 수 있습니다.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { eSCLScanner } from '@crowsgear/escl-protocol-scanner';
|
|
57
|
+
|
|
58
|
+
// 스캐너 탐색
|
|
59
|
+
const result = await eSCLScanner.discoverScanners(timeout?: number);
|
|
60
|
+
|
|
61
|
+
// 스캐너 기능 조회
|
|
62
|
+
const caps = await eSCLScanner.getCapabilities(scanner: IESCLScanner);
|
|
63
|
+
|
|
64
|
+
// 빠른 스캔
|
|
65
|
+
const files = await eSCLScanner.quickScan(params: IQuickScanParams);
|
|
66
|
+
|
|
67
|
+
// 스캔 작업 생성
|
|
68
|
+
const jobId = await eSCLScanner.createScanJob(scanner, dpi, colorMode, source, documentFormat, width?, height?);
|
|
69
|
+
|
|
70
|
+
// 스캔 작업 상태 조회
|
|
71
|
+
const status = await eSCLScanner.getScanJobStatus(scanner, jobId);
|
|
72
|
+
|
|
73
|
+
// 이미지 다운로드
|
|
74
|
+
const buffer = await eSCLScanner.downloadImage(scanner, imageUrl);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Application (사용자 설정)
|
|
78
|
+
|
|
79
|
+
사용자 설정을 위한 새 인스턴스를 생성합니다.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Application } from '@crowsgear/escl-protocol-scanner';
|
|
83
|
+
|
|
84
|
+
const myScanner = new Application({
|
|
85
|
+
timeout: 15000,
|
|
86
|
+
pythonPath: '/path/to/.venv/bin/python3', // 선택: Python 경로
|
|
87
|
+
debug: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const result = await myScanner.discoverScanners();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
> **참고**: `pythonPath`를 지정하면 사전 빌드 바이너리보다 우선 적용됩니다.
|
|
94
|
+
|
|
95
|
+
### quickScan 매개변수
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
interface IQuickScanParams {
|
|
99
|
+
scanner: IESCLScanner; // 스캐너 장치
|
|
100
|
+
dpi: number; // 해상도 (예: 200, 300, 600)
|
|
101
|
+
mode: 'bw' | 'gray' | 'color'; // 색상 모드
|
|
102
|
+
source: 'Platen' | 'Feeder'; // 스캔 소스 (평판/ADF)
|
|
103
|
+
documentFormat: string; // MIME 타입 (예: 'image/jpeg')
|
|
104
|
+
savePath?: string; // 저장 경로 (기본값: 현재 디렉터리)
|
|
105
|
+
width?: number; // 스캔 너비 mm (기본값: 210)
|
|
106
|
+
height?: number; // 스캔 높이 mm (기본값: 297)
|
|
107
|
+
timeout?: number; // 타임아웃 ms
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 타입
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface IESCLScanner {
|
|
115
|
+
name: string;
|
|
116
|
+
host: string;
|
|
117
|
+
port: number;
|
|
118
|
+
model?: string;
|
|
119
|
+
manufacturer?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
interface IESCLCapabilities {
|
|
123
|
+
resolutions: number[];
|
|
124
|
+
colorModes: ('BlackAndWhite1' | 'Grayscale8' | 'RGB24')[];
|
|
125
|
+
sources: ('Platen' | 'Adf' | 'Feeder')[];
|
|
126
|
+
documentFormats: string[];
|
|
127
|
+
maxWidth?: number;
|
|
128
|
+
maxHeight?: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface IDiscoveryResponse {
|
|
132
|
+
success: boolean;
|
|
133
|
+
data: IESCLScanner[];
|
|
134
|
+
error?: string;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 용지 크기 참고
|
|
139
|
+
|
|
140
|
+
| 용지 | 너비 (mm) | 높이 (mm) |
|
|
141
|
+
|---------|-----------|-----------|
|
|
142
|
+
| A4 | 210 | 297 |
|
|
143
|
+
| A3 | 297 | 420 |
|
|
144
|
+
| Letter | 216 | 279 |
|
|
145
|
+
| Legal | 216 | 356 |
|
|
146
|
+
|
|
147
|
+
## 지원 스캐너
|
|
148
|
+
|
|
149
|
+
eSCL(AirPrint Scan) 프로토콜을 지원하는 모든 네트워크 스캐너 및 복합기에서 사용할 수 있습니다.
|
|
150
|
+
Brother, Canon, Epson, HP, Ricoh, Xerox 등 주요 제조사의 최신 네트워크 복합기는 대부분 eSCL을 지원합니다.
|
|
151
|
+
|
|
152
|
+
> eSCL은 Apple이 설계하고 [Mopria Alliance](https://mopria.org)가 업계 표준으로 관리하는 프로토콜입니다. 호환 기기 목록은 [Apple AirPrint 페이지](https://support.apple.com/en-us/102895)에서 확인할 수 있습니다.
|
|
153
|
+
> 모든 기기에 대해 충분한 테스트가 이루어지지 않았으므로, 특정 기기에서 문제가 발생하면 [이슈](https://github.com/crowsgear/escl-protocol-scanner/issues)를 등록해 주세요.
|
|
154
|
+
|
|
155
|
+
## 개발
|
|
156
|
+
|
|
157
|
+
사전 빌드 바이너리 없이 개발하려면 Python 3과 `zeroconf`, `pillow`가 필요합니다.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
python3 -m venv .venv
|
|
161
|
+
source .venv/bin/activate
|
|
162
|
+
pip install zeroconf pillow
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { Application } from '@crowsgear/escl-protocol-scanner';
|
|
167
|
+
|
|
168
|
+
const scanner = new Application({
|
|
169
|
+
pythonPath: '/path/to/.venv/bin/python3',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const result = await scanner.discoverScanners();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## 라이선스
|
|
176
|
+
|
|
177
|
+
MIT
|
package/README.md
CHANGED
|
@@ -1,173 +1,177 @@
|
|
|
1
|
-
# @crowsgear/escl-protocol-scanner
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
//
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
1
|
+
# @crowsgear/escl-protocol-scanner
|
|
2
|
+
|
|
3
|
+
[한국어](./README.ko.md)
|
|
4
|
+
|
|
5
|
+
Network scanner library based on eSCL/AirPrint protocol.
|
|
6
|
+
|
|
7
|
+
> **Note**: This library only supports network-connected scanners (WiFi or LAN). USB scanners may not be supported.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @crowsgear/escl-protocol-scanner
|
|
13
|
+
# or
|
|
14
|
+
yarn add @crowsgear/escl-protocol-scanner
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**No Python installation required!** Pre-built binaries for Windows, macOS, and Linux are included.
|
|
18
|
+
You can also specify a custom Python path. See [Application (Custom Configuration)](#application-custom-configuration) for details.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { eSCLScanner } from '@crowsgear/escl-protocol-scanner';
|
|
24
|
+
|
|
25
|
+
// 1. Discover scanners (result: IDiscoveryResponse)
|
|
26
|
+
const result = await eSCLScanner.discoverScanners(10000);
|
|
27
|
+
if (result.success && result.data.length > 0) {
|
|
28
|
+
console.log('Found scanners:', result.data);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. Get scanner capabilities (result.data: IESCLScanner[])
|
|
32
|
+
const scanner = result.data[0]; // Select first scanner
|
|
33
|
+
const capabilities = await eSCLScanner.getCapabilities(scanner);
|
|
34
|
+
console.log('Resolutions:', capabilities?.resolutions);
|
|
35
|
+
console.log('Color modes:', capabilities?.colorModes);
|
|
36
|
+
|
|
37
|
+
// 3. Perform scan
|
|
38
|
+
const filePaths = await eSCLScanner.quickScan({
|
|
39
|
+
scanner: scanner,
|
|
40
|
+
dpi: 300,
|
|
41
|
+
mode: 'color',
|
|
42
|
+
source: 'Platen',
|
|
43
|
+
documentFormat: 'image/jpeg',
|
|
44
|
+
savePath: '/path/to/save',
|
|
45
|
+
});
|
|
46
|
+
console.log('Saved files:', filePaths);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
### eSCLScanner
|
|
52
|
+
|
|
53
|
+
Default instance, ready to use.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { eSCLScanner } from '@crowsgear/escl-protocol-scanner';
|
|
57
|
+
|
|
58
|
+
// Discover scanners
|
|
59
|
+
const result = await eSCLScanner.discoverScanners(timeout?: number);
|
|
60
|
+
|
|
61
|
+
// Get scanner capabilities
|
|
62
|
+
const caps = await eSCLScanner.getCapabilities(scanner: IESCLScanner);
|
|
63
|
+
|
|
64
|
+
// Quick scan
|
|
65
|
+
const files = await eSCLScanner.quickScan(params: IQuickScanParams);
|
|
66
|
+
|
|
67
|
+
// Create scan job
|
|
68
|
+
const jobId = await eSCLScanner.createScanJob(scanner, dpi, colorMode, source, documentFormat, width?, height?);
|
|
69
|
+
|
|
70
|
+
// Get scan job status
|
|
71
|
+
const status = await eSCLScanner.getScanJobStatus(scanner, jobId);
|
|
72
|
+
|
|
73
|
+
// Download image
|
|
74
|
+
const buffer = await eSCLScanner.downloadImage(scanner, imageUrl);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Application (Custom Configuration)
|
|
78
|
+
|
|
79
|
+
Create a new instance for custom configuration.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Application } from '@crowsgear/escl-protocol-scanner';
|
|
83
|
+
|
|
84
|
+
const myScanner = new Application({
|
|
85
|
+
timeout: 15000,
|
|
86
|
+
pythonPath: '/path/to/.venv/bin/python3', // Optional: Python path
|
|
87
|
+
debug: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const result = await myScanner.discoverScanners();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
> **Note**: When `pythonPath` is provided, it takes priority over pre-built binaries.
|
|
94
|
+
|
|
95
|
+
### quickScan Parameters
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
interface IQuickScanParams {
|
|
99
|
+
scanner: IESCLScanner; // Scanner device
|
|
100
|
+
dpi: number; // Resolution (e.g., 200, 300, 600)
|
|
101
|
+
mode: 'bw' | 'gray' | 'color'; // Color mode
|
|
102
|
+
source: 'Platen' | 'Feeder'; // Scan source (flatbed/ADF)
|
|
103
|
+
documentFormat: string; // MIME type (e.g., 'image/jpeg')
|
|
104
|
+
savePath?: string; // Save path (default: cwd)
|
|
105
|
+
width?: number; // Scan width in mm (default: 210)
|
|
106
|
+
height?: number; // Scan height in mm (default: 297)
|
|
107
|
+
timeout?: number; // Timeout in ms
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Types
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface IESCLScanner {
|
|
115
|
+
name: string;
|
|
116
|
+
host: string;
|
|
117
|
+
port: number;
|
|
118
|
+
model?: string;
|
|
119
|
+
manufacturer?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
interface IESCLCapabilities {
|
|
123
|
+
resolutions: number[];
|
|
124
|
+
colorModes: ('BlackAndWhite1' | 'Grayscale8' | 'RGB24')[];
|
|
125
|
+
sources: ('Platen' | 'Adf' | 'Feeder')[];
|
|
126
|
+
documentFormats: string[];
|
|
127
|
+
maxWidth?: number;
|
|
128
|
+
maxHeight?: number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface IDiscoveryResponse {
|
|
132
|
+
success: boolean;
|
|
133
|
+
data: IESCLScanner[];
|
|
134
|
+
error?: string;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Paper Size Reference
|
|
139
|
+
|
|
140
|
+
| Paper | Width (mm) | Height (mm) |
|
|
141
|
+
|--------|------------|-------------|
|
|
142
|
+
| A4 | 210 | 297 |
|
|
143
|
+
| A3 | 297 | 420 |
|
|
144
|
+
| Letter | 216 | 279 |
|
|
145
|
+
| Legal | 216 | 356 |
|
|
146
|
+
|
|
147
|
+
## Supported Scanners
|
|
148
|
+
|
|
149
|
+
Works with any network scanner or MFP that supports the eSCL (AirPrint Scan) protocol.
|
|
150
|
+
Most modern network MFPs from Brother, Canon, Epson, HP, Ricoh, Xerox, and others support eSCL.
|
|
151
|
+
|
|
152
|
+
> eSCL is a protocol designed by Apple and maintained as an industry standard by the [Mopria Alliance](https://mopria.org). For a list of compatible devices, see the [Apple AirPrint page](https://support.apple.com/en-us/102895).
|
|
153
|
+
> Not all devices have been fully tested. If you encounter issues with a specific device, please [open an issue](https://github.com/crowsgear/escl-protocol-scanner/issues).
|
|
154
|
+
|
|
155
|
+
## Development
|
|
156
|
+
|
|
157
|
+
For development without pre-built binaries, Python 3 with `zeroconf` and `pillow` is required.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
python3 -m venv .venv
|
|
161
|
+
source .venv/bin/activate
|
|
162
|
+
pip install zeroconf pillow
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { Application } from '@crowsgear/escl-protocol-scanner';
|
|
167
|
+
|
|
168
|
+
const scanner = new Application({
|
|
169
|
+
pythonPath: '/path/to/.venv/bin/python3',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const result = await scanner.discoverScanners();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
MIT
|
package/dist/main.d.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* 애플리케이션 진입점
|
|
5
5
|
* Application 인스턴스를 생성하고 export
|
|
6
6
|
*/
|
|
7
|
-
import { Application } from
|
|
8
|
-
export * from
|
|
9
|
-
export { Application } from
|
|
10
|
-
export { ESCLClient } from
|
|
11
|
-
export { ESCLDiscovery } from
|
|
7
|
+
import { Application } from "./core/application";
|
|
8
|
+
export * from "./types";
|
|
9
|
+
export { Application } from "./core/application";
|
|
10
|
+
export { ESCLClient } from "./services/client";
|
|
11
|
+
export { ESCLDiscovery } from "./services/discovery";
|
|
12
12
|
declare const eSCLScanner: Application;
|
|
13
13
|
export { eSCLScanner };
|
|
14
14
|
export declare const VERSION: string;
|
package/dist/main.js
CHANGED
|
@@ -36,5 +36,5 @@ const eSCLScanner = new application_1.Application();
|
|
|
36
36
|
exports.eSCLScanner = eSCLScanner;
|
|
37
37
|
// Version (package.json에서 가져옴)
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
39
|
-
exports.VERSION = require(
|
|
39
|
+
exports.VERSION = require("../package.json").version;
|
|
40
40
|
//# sourceMappingURL=main.js.map
|
package/dist/services/client.js
CHANGED
|
@@ -163,28 +163,28 @@ class ESCLClient {
|
|
|
163
163
|
/* mm to 1/300 inch 변환 */
|
|
164
164
|
const widthInUnits = Math.round((width || 210) / 25.4 * 300);
|
|
165
165
|
const heightInUnits = Math.round((height || 297) / 25.4 * 300);
|
|
166
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
167
|
-
<scan:ScanSettings xmlns:scan="${ESCL_NS}" xmlns:pwg="${PWG_NS}">
|
|
168
|
-
<pwg:Version>2.0</pwg:Version>
|
|
169
|
-
<scan:Intent>Document</scan:Intent>
|
|
170
|
-
<pwg:ScanRegions>
|
|
171
|
-
<pwg:ScanRegion>
|
|
172
|
-
<pwg:ContentRegionUnits>escl:ThreeHundredthsOfInches</pwg:ContentRegionUnits>
|
|
173
|
-
<pwg:XOffset>0</pwg:XOffset>
|
|
174
|
-
<pwg:YOffset>0</pwg:YOffset>
|
|
175
|
-
<pwg:Width>${widthInUnits}</pwg:Width>
|
|
176
|
-
<pwg:Height>${heightInUnits}</pwg:Height>
|
|
177
|
-
</pwg:ScanRegion>
|
|
178
|
-
</pwg:ScanRegions>
|
|
179
|
-
<scan:Justification>
|
|
180
|
-
<pwg:XImagePosition>Center</pwg:XImagePosition>
|
|
181
|
-
<pwg:YImagePosition>Center</pwg:YImagePosition>
|
|
182
|
-
</scan:Justification>
|
|
183
|
-
<pwg:InputSource>${source}</pwg:InputSource>
|
|
184
|
-
<scan:ColorMode>${colorMode}</scan:ColorMode>
|
|
185
|
-
<scan:XResolution>${dpi}</scan:XResolution>
|
|
186
|
-
<scan:YResolution>${dpi}</scan:YResolution>
|
|
187
|
-
<pwg:DocumentFormat>${documentFormat}</pwg:DocumentFormat>
|
|
166
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
167
|
+
<scan:ScanSettings xmlns:scan="${ESCL_NS}" xmlns:pwg="${PWG_NS}">
|
|
168
|
+
<pwg:Version>2.0</pwg:Version>
|
|
169
|
+
<scan:Intent>Document</scan:Intent>
|
|
170
|
+
<pwg:ScanRegions>
|
|
171
|
+
<pwg:ScanRegion>
|
|
172
|
+
<pwg:ContentRegionUnits>escl:ThreeHundredthsOfInches</pwg:ContentRegionUnits>
|
|
173
|
+
<pwg:XOffset>0</pwg:XOffset>
|
|
174
|
+
<pwg:YOffset>0</pwg:YOffset>
|
|
175
|
+
<pwg:Width>${widthInUnits}</pwg:Width>
|
|
176
|
+
<pwg:Height>${heightInUnits}</pwg:Height>
|
|
177
|
+
</pwg:ScanRegion>
|
|
178
|
+
</pwg:ScanRegions>
|
|
179
|
+
<scan:Justification>
|
|
180
|
+
<pwg:XImagePosition>Center</pwg:XImagePosition>
|
|
181
|
+
<pwg:YImagePosition>Center</pwg:YImagePosition>
|
|
182
|
+
</scan:Justification>
|
|
183
|
+
<pwg:InputSource>${source}</pwg:InputSource>
|
|
184
|
+
<scan:ColorMode>${colorMode}</scan:ColorMode>
|
|
185
|
+
<scan:XResolution>${dpi}</scan:XResolution>
|
|
186
|
+
<scan:YResolution>${dpi}</scan:YResolution>
|
|
187
|
+
<pwg:DocumentFormat>${documentFormat}</pwg:DocumentFormat>
|
|
188
188
|
</scan:ScanSettings>`;
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Uses Python's zeroconf library for mDNS discovery
|
|
4
4
|
* Prefers pre-built binary if available, falls back to Python script
|
|
5
5
|
*/
|
|
6
|
-
import { IESCLScanner, IDiscoveryResponse, IESCLDiscoveryOptions } from
|
|
6
|
+
import { IESCLScanner, IDiscoveryResponse, IESCLDiscoveryOptions } from "../types";
|
|
7
7
|
export type { IESCLDiscoveryOptions };
|
|
8
8
|
/**
|
|
9
9
|
* eSCL Scanner Discovery Service
|