@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.
Files changed (45) hide show
  1. package/LICENSE +21 -21
  2. package/README.ko.md +177 -0
  3. package/README.md +177 -173
  4. package/dist/main.d.ts +5 -5
  5. package/dist/main.js +1 -1
  6. package/dist/services/client.js +22 -22
  7. package/dist/services/discovery.d.ts +1 -1
  8. package/dist/services/discovery.d.ts.map +1 -1
  9. package/dist/services/discovery.js +45 -35
  10. package/dist/services/discovery.js.map +1 -1
  11. package/package.json +70 -70
  12. package/python/__main__.py +23 -0
  13. package/python/app.py +91 -0
  14. package/python/base/__init__.py +2 -0
  15. package/python/base/service.py +23 -0
  16. package/python/common/__init__.py +4 -0
  17. package/python/common/exceptions.py +28 -0
  18. package/python/common/logger.py +25 -0
  19. package/python/common/response.py +26 -0
  20. package/python/decorators/__init__.py +2 -0
  21. package/python/decorators/scanner.py +30 -0
  22. package/python/escl-scanner.spec +98 -84
  23. package/python/services/__init__.py +2 -0
  24. package/python/services/escl/__init__.py +3 -0
  25. package/python/services/escl/discovery.py +53 -0
  26. package/python/services/escl/protocol.py +358 -0
  27. package/python/services/scanner.py +31 -0
  28. package/scripts/check-python-deps.js +269 -206
  29. package/dist/client.d.ts +0 -78
  30. package/dist/client.d.ts.map +0 -1
  31. package/dist/client.js +0 -384
  32. package/dist/client.js.map +0 -1
  33. package/dist/discovery.d.ts +0 -80
  34. package/dist/discovery.d.ts.map +0 -1
  35. package/dist/discovery.js +0 -304
  36. package/dist/discovery.js.map +0 -1
  37. package/dist/types.d.ts +0 -172
  38. package/dist/types.d.ts.map +0 -1
  39. package/dist/types.js +0 -7
  40. package/dist/types.js.map +0 -1
  41. package/python/__pycache__/base.cpython-312.pyc +0 -0
  42. package/python/__pycache__/escl_backend.cpython-312.pyc +0 -0
  43. package/python/base.py +0 -57
  44. package/python/escl_backend.py +0 -559
  45. package/python/escl_main.py +0 -119
package/dist/discovery.js DELETED
@@ -1,304 +0,0 @@
1
- "use strict";
2
- /**
3
- * eSCL Scanner Discovery via Python Subprocess or Binary
4
- * Uses Python's zeroconf library for mDNS discovery
5
- * Prefers pre-built binary if available, falls back to Python script
6
- */
7
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- var desc = Object.getOwnPropertyDescriptor(m, k);
10
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
- desc = { enumerable: true, get: function() { return m[k]; } };
12
- }
13
- Object.defineProperty(o, k2, desc);
14
- }) : (function(o, m, k, k2) {
15
- if (k2 === undefined) k2 = k;
16
- o[k2] = m[k];
17
- }));
18
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
- Object.defineProperty(o, "default", { enumerable: true, value: v });
20
- }) : function(o, v) {
21
- o["default"] = v;
22
- });
23
- var __importStar = (this && this.__importStar) || (function () {
24
- var ownKeys = function(o) {
25
- ownKeys = Object.getOwnPropertyNames || function (o) {
26
- var ar = [];
27
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
- return ar;
29
- };
30
- return ownKeys(o);
31
- };
32
- return function (mod) {
33
- if (mod && mod.__esModule) return mod;
34
- var result = {};
35
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
- __setModuleDefault(result, mod);
37
- return result;
38
- };
39
- })();
40
- Object.defineProperty(exports, "__esModule", { value: true });
41
- exports.ESCLDiscovery = void 0;
42
- exports.discoverScanners = discoverScanners;
43
- const child_process_1 = require("child_process");
44
- const path = __importStar(require("path"));
45
- const fs = __importStar(require("fs"));
46
- /**
47
- * eSCL Scanner Discovery Service
48
- * Spawns Python subprocess or binary to handle mDNS discovery using zeroconf
49
- */
50
- class ESCLDiscovery {
51
- constructor(timeout, options) {
52
- this.pythonProcess = null;
53
- this.discovered = new Map();
54
- this.listeners = new Set();
55
- this.timeout = 5000;
56
- this.processReady = false;
57
- this.pythonPath = 'python3';
58
- this.binaryPath = null;
59
- if (timeout) {
60
- this.timeout = timeout;
61
- }
62
- if (options?.pythonPath) {
63
- this.pythonPath = options.pythonPath;
64
- }
65
- // Check for pre-built binary
66
- this.binaryPath = this.getBinaryPath();
67
- }
68
- /**
69
- * Get path to pre-built binary if available
70
- * @returns Binary path or null if not found
71
- */
72
- getBinaryPath() {
73
- const platform = process.platform; // 'win32', 'darwin', 'linux'
74
- const binDir = path.join(__dirname, '..', 'bin', platform);
75
- const binaryName = platform === 'win32' ? 'escl-scanner.exe' : 'escl-scanner';
76
- const binaryPath = path.join(binDir, binaryName);
77
- if (fs.existsSync(binaryPath)) {
78
- return binaryPath;
79
- }
80
- return null;
81
- }
82
- /**
83
- * Validate Python path exists and is executable
84
- * Skipped if pre-built binary is available
85
- * @throws Error if Python path is invalid and no binary available
86
- */
87
- validatePythonPath() {
88
- // Skip validation if binary is available
89
- if (this.binaryPath) {
90
- return;
91
- }
92
- // Check if it's an absolute path
93
- if (path.isAbsolute(this.pythonPath)) {
94
- if (!fs.existsSync(this.pythonPath)) {
95
- throw new Error(`Python executable not found at: ${this.pythonPath}\n` +
96
- `Please ensure the Python virtual environment exists or provide a valid python3 path.`);
97
- }
98
- return;
99
- }
100
- // For relative paths like './venv/bin/python3', check from current working directory
101
- const resolvedPath = path.resolve(process.cwd(), this.pythonPath);
102
- if (!fs.existsSync(resolvedPath)) {
103
- throw new Error(`Python executable not found at: ${resolvedPath}\n` +
104
- `Current working directory: ${process.cwd()}\n` +
105
- `Please ensure the Python virtual environment exists or provide a valid python3 path.`);
106
- }
107
- }
108
- /**
109
- * Start discovering scanners
110
- * @param timeout Optional timeout in milliseconds (default: 5000ms)
111
- * @returns Promise resolving with discovery response containing success status and scanner data
112
- */
113
- async startDiscovery(timeout) {
114
- const discoveryTimeout = timeout || this.timeout;
115
- return new Promise((resolve, reject) => {
116
- try {
117
- // Validate Python path before proceeding
118
- this.validatePythonPath();
119
- this.discovered.clear();
120
- let resolved = false;
121
- // Timeout fallback (in case Python doesn't respond)
122
- const timeoutHandle = setTimeout(() => {
123
- if (!resolved) {
124
- resolved = true;
125
- this.stopDiscovery();
126
- const scanners = Array.from(this.discovered.values());
127
- resolve({
128
- success: true,
129
- data: scanners
130
- });
131
- }
132
- }, discoveryTimeout);
133
- // Set up listener for Python response
134
- const responseHandler = (scanners) => {
135
- if (!resolved) {
136
- resolved = true;
137
- clearTimeout(timeoutHandle);
138
- this.offScannerDiscovered(responseHandler);
139
- this.stopDiscovery();
140
- resolve({
141
- success: true,
142
- data: scanners
143
- });
144
- }
145
- };
146
- this.onScannerDiscovered(responseHandler);
147
- this.startPythonService();
148
- // Send list command to Python subprocess
149
- if (this.pythonProcess && this.pythonProcess.stdin) {
150
- const command = { action: 'list' };
151
- this.pythonProcess.stdin.write(JSON.stringify(command) + '\n');
152
- }
153
- }
154
- catch (error) {
155
- reject(error);
156
- }
157
- });
158
- }
159
- /**
160
- * Stop active discovery and cleanup subprocess
161
- */
162
- stopDiscovery() {
163
- this.cleanup();
164
- }
165
- /**
166
- * Get currently discovered scanners
167
- */
168
- getScanners() {
169
- return Array.from(this.discovered.values());
170
- }
171
- /**
172
- * Subscribe to scanner discovery updates
173
- */
174
- onScannerDiscovered(callback) {
175
- this.listeners.add(callback);
176
- }
177
- /**
178
- * Unsubscribe from scanner discovery updates
179
- */
180
- offScannerDiscovered(callback) {
181
- this.listeners.delete(callback);
182
- }
183
- /**
184
- * Start Python subprocess or binary for eSCL operations
185
- */
186
- startPythonService() {
187
- if (this.pythonProcess) {
188
- return; // Already running
189
- }
190
- try {
191
- if (this.binaryPath) {
192
- // Use pre-built binary (production/package environment)
193
- console.log(`[eSCL] Using binary: ${this.binaryPath}`);
194
- this.pythonProcess = (0, child_process_1.spawn)(this.binaryPath, [], {
195
- stdio: ['pipe', 'pipe', 'pipe'],
196
- windowsHide: true
197
- });
198
- }
199
- else {
200
- // Fall back to Python script (development environment)
201
- const pythonScriptPath = path.join(__dirname, '..', 'python', 'escl_main.py');
202
- console.log(`[eSCL] Using Python script: ${pythonScriptPath}`);
203
- this.pythonProcess = (0, child_process_1.spawn)(this.pythonPath, [pythonScriptPath], {
204
- stdio: ['pipe', 'pipe', 'pipe'],
205
- windowsHide: true
206
- });
207
- }
208
- // Handle stdout - parse JSON responses
209
- if (this.pythonProcess.stdout) {
210
- this.pythonProcess.stdout.on('data', (data) => {
211
- try {
212
- const lines = data.toString().split('\n');
213
- for (const line of lines) {
214
- if (line.trim()) {
215
- const response = JSON.parse(line);
216
- if (!response.success && response.error) {
217
- // Handle error response from Python
218
- console.error('[eSCL Error]', response.error);
219
- }
220
- else if (response.success && response.scanners) {
221
- this.discovered.clear();
222
- for (const scanner of response.scanners) {
223
- this.discovered.set(scanner.name, scanner);
224
- }
225
- this.notifyListeners();
226
- }
227
- }
228
- }
229
- }
230
- catch (error) {
231
- console.error('Error parsing Python response:', error);
232
- }
233
- });
234
- }
235
- // Handle stderr - logging
236
- if (this.pythonProcess.stderr) {
237
- this.pythonProcess.stderr.on('data', (data) => {
238
- console.error('[eSCL Python]', data.toString());
239
- });
240
- }
241
- // Handle process exit
242
- this.pythonProcess.on('exit', (code) => {
243
- console.log(`[eSCL] Python subprocess exited with code ${code}`);
244
- this.pythonProcess = null;
245
- this.processReady = false;
246
- });
247
- this.processReady = true;
248
- }
249
- catch (error) {
250
- console.error('Failed to start Python service:', error);
251
- this.pythonProcess = null;
252
- }
253
- }
254
- /**
255
- * Cleanup Python subprocess
256
- */
257
- cleanup() {
258
- if (this.pythonProcess) {
259
- try {
260
- // Send exit command
261
- if (this.pythonProcess.stdin) {
262
- const command = { action: 'exit' };
263
- this.pythonProcess.stdin.write(JSON.stringify(command) + '\n');
264
- }
265
- // Force kill after timeout
266
- setTimeout(() => {
267
- if (this.pythonProcess) {
268
- this.pythonProcess.kill();
269
- this.pythonProcess = null;
270
- }
271
- }, 1000);
272
- }
273
- catch (error) {
274
- console.error('Error during cleanup:', error);
275
- if (this.pythonProcess) {
276
- this.pythonProcess.kill();
277
- this.pythonProcess = null;
278
- }
279
- }
280
- }
281
- this.processReady = false;
282
- }
283
- /**
284
- * Notify all listeners of scanner changes
285
- */
286
- notifyListeners() {
287
- const scanners = Array.from(this.discovered.values());
288
- this.listeners.forEach((callback) => {
289
- callback(scanners);
290
- });
291
- }
292
- }
293
- exports.ESCLDiscovery = ESCLDiscovery;
294
- /**
295
- * Convenience function for quick scanner discovery
296
- * @param timeout Discovery timeout in milliseconds (default: 5000)
297
- * @param options Discovery options including pythonPath
298
- * @returns Discovery response with success status and scanner data
299
- */
300
- async function discoverScanners(timeout = 5000, options) {
301
- const discovery = new ESCLDiscovery(timeout, options);
302
- return discovery.startDiscovery(timeout);
303
- }
304
- //# sourceMappingURL=discovery.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,172 +0,0 @@
1
- /**
2
- * eSCL/AirPrint Protocol Scanner Types
3
- * HTTP-based network scanner protocol for Canon, HP, Epson, and other MFP devices
4
- */
5
- /**
6
- * eSCL Scanner device information
7
- */
8
- export interface ESCLScanner {
9
- /** Device name from mDNS (cleaned of service type suffix) */
10
- name: string;
11
- /** Network hostname or IP address */
12
- host: string;
13
- /** HTTP service port (typically 80) */
14
- port: number;
15
- /** Full mDNS service name */
16
- serviceName?: string;
17
- /** Device model from mDNS TXT record */
18
- model?: string;
19
- /** Device manufacturer */
20
- manufacturer?: string;
21
- }
22
- /**
23
- * Scanner capabilities response
24
- */
25
- export interface ESCLCapabilities {
26
- /** Available scan resolutions in DPI */
27
- resolutions: number[];
28
- /** Supported color modes */
29
- colorModes: ('BlackAndWhite1' | 'Grayscale8' | 'RGB24')[];
30
- /** Available scan sources */
31
- sources: ('Platen' | 'Adf' | 'Feeder')[];
32
- /** Supported document formats (MIME types from scanner, e.g., 'image/jpeg', 'image/png', 'application/pdf') */
33
- documentFormats: string[];
34
- /** Maximum scannable area width in mm */
35
- maxWidth?: number;
36
- /** Maximum scannable area height in mm */
37
- maxHeight?: number;
38
- }
39
- /**
40
- * Scan request parameters
41
- */
42
- export interface ESCLScanParams {
43
- /** Target scanner device */
44
- scanner: ESCLScanner;
45
- /** Resolution in DPI (e.g., 200, 300) */
46
- dpi: number;
47
- /** Color mode for scanning */
48
- mode: 'bw' | 'gray' | 'color';
49
- /** Scan source */
50
- source: 'Platen' | 'Feeder';
51
- }
52
- /**
53
- * Scanned image data
54
- */
55
- export interface ScannedImage {
56
- /** Base64 encoded PNG image data */
57
- data: string;
58
- /** Image dimensions */
59
- width: number;
60
- height: number;
61
- /** Color mode used for scanning */
62
- colorMode: string;
63
- }
64
- /**
65
- * Generic eSCL response wrapper
66
- */
67
- export interface ESCLResponse {
68
- /** Operation success status */
69
- success: boolean;
70
- /** List of discovered scanners */
71
- scanners?: ESCLScanner[];
72
- /** Scanner capabilities */
73
- capabilities?: ESCLCapabilities;
74
- /** Scanned images */
75
- images?: string[];
76
- /** Number of images returned */
77
- count?: number;
78
- /** Error message if operation failed */
79
- error?: string;
80
- /** Additional response metadata */
81
- metadata?: Record<string, unknown>;
82
- }
83
- /**
84
- * Scanner response for local scanner backend
85
- */
86
- export interface ScannerResponse {
87
- success: boolean;
88
- scanners?: Array<{
89
- id: string;
90
- name: string;
91
- type: string;
92
- }>;
93
- images?: string[];
94
- count?: number;
95
- error?: string;
96
- }
97
- /**
98
- * Color mode mapping for UI display
99
- */
100
- export interface ColorModeMap {
101
- [key: string]: {
102
- value: 'bw' | 'gray' | 'color';
103
- label: string;
104
- };
105
- }
106
- /**
107
- * Image save parameters
108
- */
109
- export interface SaveImageParams {
110
- folderPath: string;
111
- fileName: string;
112
- imageData: string;
113
- }
114
- /**
115
- * Image save result
116
- */
117
- export interface SaveImageResult {
118
- success: boolean;
119
- filePath?: string;
120
- error?: string;
121
- }
122
- /**
123
- * Python subprocess command types
124
- */
125
- export type ESCLCommand = {
126
- action: 'list' | 'scan' | 'capabilities' | 'exit';
127
- params?: ESCLScanParams;
128
- };
129
- /**
130
- * Python subprocess command for legacy Python scanner
131
- */
132
- export type PythonCommand = {
133
- type: 'list' | 'scan' | 'exit';
134
- params?: Record<string, unknown>;
135
- };
136
- /**
137
- * Scan parameters for legacy Python scanner
138
- */
139
- export interface ScanParams {
140
- scanner?: {
141
- name: string;
142
- id: string;
143
- };
144
- dpi?: number;
145
- mode?: string;
146
- source?: string;
147
- }
148
- /**
149
- * Python process spawn options
150
- */
151
- export interface ProcessSpawnOptions {
152
- /** Python executable path */
153
- pythonPath?: string;
154
- /** Enable verbose logging */
155
- verbose?: boolean;
156
- /** Timeout for subprocess communication (ms) */
157
- timeout?: number;
158
- /** Environment variables for Python process */
159
- env?: NodeJS.ProcessEnv;
160
- }
161
- /**
162
- * Scanner discovery response
163
- */
164
- export interface DiscoveryResponse {
165
- /** Operation success status */
166
- success: boolean;
167
- /** List of discovered scanners */
168
- data: ESCLScanner[];
169
- /** Error message if operation failed */
170
- error?: string;
171
- }
172
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js DELETED
@@ -1,7 +0,0 @@
1
- "use strict";
2
- /**
3
- * eSCL/AirPrint Protocol Scanner Types
4
- * HTTP-based network scanner protocol for Canon, HP, Epson, and other MFP devices
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
package/python/base.py DELETED
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- Scanner Backend Base Classes and Common Utilities
5
- """
6
-
7
- from abc import ABC, abstractmethod
8
- import sys
9
- import json
10
-
11
-
12
- class ScannerBackend(ABC):
13
- """Abstract base class for scanner backends"""
14
-
15
- @abstractmethod
16
- def list_scanners(self):
17
- """
18
- Return list of available scanners
19
-
20
- Returns:
21
- dict: {'success': bool, 'scanners': list, 'backend': str}
22
- or {'success': False, 'error': str}
23
- """
24
- pass
25
-
26
- @abstractmethod
27
- def scan(self, params):
28
- """
29
- Execute scan with given parameters
30
-
31
- Args:
32
- params (dict): {
33
- 'scanner': str, # Scanner name/ID
34
- 'dpi': int, # Resolution (default: 300)
35
- 'mode': str, # 'gray', 'bw', 'color' (default: 'gray')
36
- 'format': str, # 'a3', 'a4', 'b4', 'b5' (default: 'a3')
37
- 'adf': bool, # Auto Document Feeder (default: True)
38
- 'duplex': bool # Double-sided scanning (default: False)
39
- }
40
-
41
- Returns:
42
- dict: {'success': bool, 'images': list, 'count': int, 'backend': str}
43
- or {'success': False, 'error': str}
44
- """
45
- pass
46
-
47
-
48
- def send_response(data):
49
- """
50
- Send JSON response via stdout
51
-
52
- Args:
53
- data (dict): Response data to send
54
- """
55
- response = json.dumps(data, ensure_ascii=False)
56
- sys.stdout.write(response + '\n')
57
- sys.stdout.flush()