@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
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/services/discovery.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACL,YAAY,EAGZ,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAGlB,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAAwC;IAC1D,OAAO,CAAC,SAAS,CAAsD;IACvE,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAuB;gBAE7B,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAW7D;;;OAGG;IACH,OAAO,CAAC,aAAa;IAYrB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;;;OAIG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoDnE;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,WAAW,IAAI,YAAY,EAAE;IAI7B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvE;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,IAAI,GAAG,IAAI;IAIxE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsE1B;;OAEG;IACH,OAAO,CAAC,OAAO;IA2Bf;;OAEG;IACH,OAAO,CAAC,eAAe;CAMxB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,MAAa,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAG3H"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/services/discovery.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,YAAY,EAA+B,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGhH,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC;;;GAGG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAAwC;IAC1D,OAAO,CAAC,SAAS,CAAsD;IACvE,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAuB;gBAE7B,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAS7D;;;OAGG;IACH,OAAO,CAAC,aAAa;IAYrB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0C1B;;;;OAIG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoDnE;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,WAAW,IAAI,YAAY,EAAE;IAI7B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,IAAI,GAAG,IAAI;IAIvE;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,IAAI,GAAG,IAAI;IAIxE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsE1B;;OAEG;IACH,OAAO,CAAC,OAAO;IA2Bf;;OAEG;IACH,OAAO,CAAC,eAAe;CAM1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAClC,OAAO,GAAE,MAAa,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAG7B"}
@@ -54,16 +54,14 @@ class ESCLDiscovery {
54
54
  this.listeners = new Set();
55
55
  this.timeout = 5000;
56
56
  this.processReady = false;
57
- this.pythonPath = 'python3';
57
+ this.pythonPath = "python3";
58
58
  this.binaryPath = null;
59
59
  if (timeout) {
60
60
  this.timeout = timeout;
61
61
  }
62
- if (options?.pythonPath) {
63
- this.pythonPath = options.pythonPath;
64
- }
65
- // Check for pre-built binary
66
- this.binaryPath = this.getBinaryPath();
62
+ this.pythonPath = options?.pythonPath || "python3";
63
+ // pythonPath 명시적으로 전달된 경우 바이너리보다 우선 사용
64
+ this.binaryPath = options?.pythonPath ? null : this.getBinaryPath();
67
65
  }
68
66
  /**
69
67
  * Get path to pre-built binary if available
@@ -71,8 +69,8 @@ class ESCLDiscovery {
71
69
  */
72
70
  getBinaryPath() {
73
71
  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';
72
+ const binDir = path.join(__dirname, "..", "..", "bin", platform);
73
+ const binaryName = platform === "win32" ? "escl-scanner.exe" : "escl-scanner";
76
74
  const binaryPath = path.join(binDir, binaryName);
77
75
  if (fs.existsSync(binaryPath)) {
78
76
  return binaryPath;
@@ -89,7 +87,7 @@ class ESCLDiscovery {
89
87
  if (this.binaryPath) {
90
88
  return;
91
89
  }
92
- // Check if it's an absolute path
90
+ // Absolute path check file exists
93
91
  if (path.isAbsolute(this.pythonPath)) {
94
92
  if (!fs.existsSync(this.pythonPath)) {
95
93
  throw new Error(`Python executable not found at: ${this.pythonPath}\n` +
@@ -97,12 +95,24 @@ class ESCLDiscovery {
97
95
  }
98
96
  return;
99
97
  }
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.`);
98
+ // Relative path (contains separator) resolve from cwd
99
+ if (this.pythonPath.includes(path.sep) || this.pythonPath.includes("/")) {
100
+ const resolvedPath = path.resolve(process.cwd(), this.pythonPath);
101
+ if (!fs.existsSync(resolvedPath)) {
102
+ throw new Error(`Python executable not found at: ${resolvedPath}\n` +
103
+ `Current working directory: ${process.cwd()}\n` +
104
+ `Please ensure the Python virtual environment exists or provide a valid python3 path.`);
105
+ }
106
+ return;
107
+ }
108
+ // Bare command name (e.g. 'python3') → resolve from PATH
109
+ try {
110
+ const cmd = process.platform === "win32" ? "where" : "which";
111
+ (0, child_process_1.execSync)(`${cmd} ${this.pythonPath}`, { stdio: "ignore" });
112
+ }
113
+ catch {
114
+ throw new Error(`Python command '${this.pythonPath}' not found in PATH.\n` +
115
+ `Set ESCL_PYTHON_PATH environment variable or provide pythonPath option.`);
106
116
  }
107
117
  }
108
118
  /**
@@ -126,7 +136,7 @@ class ESCLDiscovery {
126
136
  const scanners = Array.from(this.discovered.values());
127
137
  resolve({
128
138
  success: true,
129
- data: scanners
139
+ data: scanners,
130
140
  });
131
141
  }
132
142
  }, discoveryTimeout);
@@ -139,7 +149,7 @@ class ESCLDiscovery {
139
149
  this.stopDiscovery();
140
150
  resolve({
141
151
  success: true,
142
- data: scanners
152
+ data: scanners,
143
153
  });
144
154
  }
145
155
  };
@@ -147,8 +157,8 @@ class ESCLDiscovery {
147
157
  this.startPythonService();
148
158
  // Send list command to Python subprocess
149
159
  if (this.pythonProcess && this.pythonProcess.stdin) {
150
- const command = { action: 'list' };
151
- this.pythonProcess.stdin.write(JSON.stringify(command) + '\n');
160
+ const command = { action: "list" };
161
+ this.pythonProcess.stdin.write(JSON.stringify(command) + "\n");
152
162
  }
153
163
  }
154
164
  catch (error) {
@@ -192,30 +202,30 @@ class ESCLDiscovery {
192
202
  // Use pre-built binary (production/package environment)
193
203
  console.log(`[eSCL] Using binary: ${this.binaryPath}`);
194
204
  this.pythonProcess = (0, child_process_1.spawn)(this.binaryPath, [], {
195
- stdio: ['pipe', 'pipe', 'pipe'],
196
- windowsHide: true
205
+ stdio: ["pipe", "pipe", "pipe"],
206
+ windowsHide: true,
197
207
  });
198
208
  }
199
209
  else {
200
210
  // Fall back to Python script (development environment)
201
- const pythonScriptPath = path.join(__dirname, '..', '..', 'python', 'escl_main.py');
211
+ const pythonScriptPath = path.join(__dirname, "..", "..", "python", "__main__.py");
202
212
  console.log(`[eSCL] Using Python script: ${pythonScriptPath}`);
203
213
  this.pythonProcess = (0, child_process_1.spawn)(this.pythonPath, [pythonScriptPath], {
204
- stdio: ['pipe', 'pipe', 'pipe'],
205
- windowsHide: true
214
+ stdio: ["pipe", "pipe", "pipe"],
215
+ windowsHide: true,
206
216
  });
207
217
  }
208
218
  // Handle stdout - parse JSON responses
209
219
  if (this.pythonProcess.stdout) {
210
- this.pythonProcess.stdout.on('data', (data) => {
220
+ this.pythonProcess.stdout.on("data", (data) => {
211
221
  try {
212
- const lines = data.toString().split('\n');
222
+ const lines = data.toString().split("\n");
213
223
  for (const line of lines) {
214
224
  if (line.trim()) {
215
225
  const response = JSON.parse(line);
216
226
  if (!response.success && response.error) {
217
227
  // Handle error response from Python
218
- console.error('[eSCL Error]', response.error);
228
+ console.error("[eSCL Error]", response.error);
219
229
  }
220
230
  else if (response.success && response.scanners) {
221
231
  this.discovered.clear();
@@ -228,18 +238,18 @@ class ESCLDiscovery {
228
238
  }
229
239
  }
230
240
  catch (error) {
231
- console.error('Error parsing Python response:', error);
241
+ console.error("Error parsing Python response:", error);
232
242
  }
233
243
  });
234
244
  }
235
245
  // Handle stderr - logging
236
246
  if (this.pythonProcess.stderr) {
237
- this.pythonProcess.stderr.on('data', (data) => {
238
- console.error('[eSCL Python]', data.toString());
247
+ this.pythonProcess.stderr.on("data", (data) => {
248
+ console.error("[eSCL Python]", data.toString());
239
249
  });
240
250
  }
241
251
  // Handle process exit
242
- this.pythonProcess.on('exit', (code) => {
252
+ this.pythonProcess.on("exit", (code) => {
243
253
  console.log(`[eSCL] Python subprocess exited with code ${code}`);
244
254
  this.pythonProcess = null;
245
255
  this.processReady = false;
@@ -247,7 +257,7 @@ class ESCLDiscovery {
247
257
  this.processReady = true;
248
258
  }
249
259
  catch (error) {
250
- console.error('Failed to start Python service:', error);
260
+ console.error("Failed to start Python service:", error);
251
261
  this.pythonProcess = null;
252
262
  }
253
263
  }
@@ -259,8 +269,8 @@ class ESCLDiscovery {
259
269
  try {
260
270
  // Send exit command
261
271
  if (this.pythonProcess.stdin) {
262
- const command = { action: 'exit' };
263
- this.pythonProcess.stdin.write(JSON.stringify(command) + '\n');
272
+ const command = { action: "exit" };
273
+ this.pythonProcess.stdin.write(JSON.stringify(command) + "\n");
264
274
  }
265
275
  // Force kill after timeout
266
276
  setTimeout(() => {
@@ -271,7 +281,7 @@ class ESCLDiscovery {
271
281
  }, 1000);
272
282
  }
273
283
  catch (error) {
274
- console.error('Error during cleanup:', error);
284
+ console.error("Error during cleanup:", error);
275
285
  if (this.pythonProcess) {
276
286
  this.pythonProcess.kill();
277
287
  this.pythonProcess = null;
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/services/discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/services/discovery.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,70 +1,70 @@
1
- {
2
- "name": "@crowsgear/escl-protocol-scanner",
3
- "version": "1.1.1",
4
- "description": "eSCL/AirPrint Protocol Scanner Library - HTTP-based network scanner support with mDNS discovery",
5
- "license": "MIT",
6
- "author": "CrowsGear",
7
- "homepage": "https://github.com/byeong1/escl-protocol-scanner",
8
- "repository": {
9
- "type": "git",
10
- "url": "git@github.com:byeong1/escl-protocol-scanner.git"
11
- },
12
- "bugs": {
13
- "url": "https://github.com/byeong1/escl-protocol-scanner/issues"
14
- },
15
- "main": "dist/index.js",
16
- "types": "dist/index.d.ts",
17
- "exports": {
18
- ".": {
19
- "import": "./dist/index.js",
20
- "require": "./dist/index.js",
21
- "types": "./dist/index.d.ts"
22
- },
23
- "./types": {
24
- "import": "./dist/types.js",
25
- "types": "./dist/types.d.ts"
26
- },
27
- "./client": {
28
- "import": "./dist/client.js",
29
- "types": "./dist/client.d.ts"
30
- }
31
- },
32
- "files": [
33
- "dist",
34
- "python",
35
- "bin",
36
- "scripts",
37
- "README.md",
38
- "LICENSE"
39
- ],
40
- "scripts": {
41
- "build": "tsc",
42
- "build:watch": "tsc --watch",
43
- "clean": "rm -rf dist",
44
- "prepublishOnly": "yarn run build",
45
- "prepack": "yarn run build",
46
- "postinstall": "node scripts/check-python-deps.js",
47
- "publish:npm": "npm publish --registry https://registry.npmjs.org/ --access public",
48
- "publish:github": "npm publish --registry https://npm.pkg.github.com --access public",
49
- "publish:all": "npm version patch && yarn publish:npm && yarn publish:github"
50
- },
51
- "keywords": [
52
- "escl",
53
- "scanner",
54
- "airprint",
55
- "network",
56
- "mfp",
57
- "printer",
58
- "connection",
59
- "auto connection",
60
- "scanner auto connection"
61
- ],
62
- "engines": {
63
- "node": ">=14.0.0"
64
- },
65
- "dependencies": {},
66
- "devDependencies": {
67
- "@types/node": "^24.7.2",
68
- "typescript": "^5.9.3"
69
- }
70
- }
1
+ {
2
+ "name": "@crowsgear/escl-protocol-scanner",
3
+ "version": "1.2.1",
4
+ "description": "eSCL/AirPrint Protocol Scanner Library - HTTP-based network scanner support with mDNS discovery",
5
+ "license": "MIT",
6
+ "author": "CrowsGear",
7
+ "homepage": "https://github.com/byeong1/escl-protocol-scanner",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git@github.com:byeong1/escl-protocol-scanner.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/byeong1/escl-protocol-scanner/issues"
14
+ },
15
+ "main": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "import": "./dist/index.js",
20
+ "require": "./dist/index.js",
21
+ "types": "./dist/index.d.ts"
22
+ },
23
+ "./types": {
24
+ "import": "./dist/types.js",
25
+ "types": "./dist/types.d.ts"
26
+ },
27
+ "./client": {
28
+ "import": "./dist/client.js",
29
+ "types": "./dist/client.d.ts"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "python",
35
+ "bin",
36
+ "scripts",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "build:watch": "tsc --watch",
43
+ "clean": "rm -rf dist",
44
+ "prepublishOnly": "yarn run build",
45
+ "prepack": "yarn run build",
46
+ "postinstall": "node scripts/check-python-deps.js",
47
+ "publish:npm": "npm publish --registry https://registry.npmjs.org/ --access public",
48
+ "publish:github": "npm publish --registry https://npm.pkg.github.com --access public",
49
+ "publish:all": "npm version patch && yarn publish:npm && yarn publish:github"
50
+ },
51
+ "keywords": [
52
+ "escl",
53
+ "scanner",
54
+ "airprint",
55
+ "network",
56
+ "mfp",
57
+ "printer",
58
+ "connection",
59
+ "auto connection",
60
+ "scanner auto connection"
61
+ ],
62
+ "engines": {
63
+ "node": ">=14.0.0"
64
+ },
65
+ "dependencies": {},
66
+ "devDependencies": {
67
+ "@types/node": "^24.7.2",
68
+ "typescript": "^5.9.3"
69
+ }
70
+ }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ eSCL Scanner Service Entry Point
5
+ Dedicated subprocess for eSCL (AirPrint) network scanners
6
+ """
7
+
8
+ import sys
9
+ from common.response import send_response, error_response
10
+ from app import ESCLApplication
11
+
12
+
13
+ def main():
14
+ try:
15
+ app = ESCLApplication()
16
+ app.run()
17
+ except Exception as e:
18
+ send_response(error_response(f'eSCL service error: {e}'))
19
+ sys.exit(1)
20
+
21
+
22
+ if __name__ == '__main__':
23
+ main()
package/python/app.py ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ eSCL Scanner Service Application
5
+ """
6
+
7
+ import sys
8
+ import json
9
+ import logging
10
+ from common.logger import setup_logging
11
+ from common.response import send_response, success_response, error_response
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+ class ESCLApplication:
16
+ """eSCL Scanner Service Application"""
17
+
18
+ def __init__(self):
19
+ setup_logging()
20
+
21
+ self._check_dependencies()
22
+
23
+ from services import ScannerService
24
+
25
+ self.service = ScannerService()
26
+ self._handlers = {
27
+ 'list': lambda cmd: self.service.list_scanners(),
28
+ 'scan': lambda cmd: self.service.scan(cmd.get('params', {})),
29
+ 'capabilities': lambda cmd: self.service.get_capabilities(cmd.get('params', {})),
30
+ }
31
+
32
+ @staticmethod
33
+ def _check_dependencies():
34
+ """필수 라이브러리 존재 여부를 확인하고, 없으면 에러 응답 후 종료한다."""
35
+ missing = []
36
+
37
+ try:
38
+ import zeroconf # noqa: F401
39
+ except ImportError:
40
+ missing.append('zeroconf')
41
+
42
+ try:
43
+ import PIL # noqa: F401
44
+ except ImportError:
45
+ missing.append('pillow')
46
+
47
+ if missing:
48
+ send_response(error_response(
49
+ f'Required Python packages are not installed. '
50
+ f'Install with: pip install {" ".join(missing)}'
51
+ ))
52
+ sys.exit(1)
53
+
54
+ def dispatch(self, command: dict) -> bool:
55
+ """커맨드를 적절한 백엔드 메서드로 라우팅한다."""
56
+ action = command.get('action')
57
+ log.info('Command received: %s', action)
58
+
59
+ if action == 'exit':
60
+ send_response(success_response(message='eSCL service stopped'))
61
+ return False
62
+
63
+ handler = self._handlers.get(action)
64
+ if not handler:
65
+ send_response(error_response(f'Unknown command: {action}'))
66
+ return True
67
+
68
+ result = handler(command)
69
+ send_response(result)
70
+ return True
71
+
72
+ def run(self) -> None:
73
+ """stdin에서 JSON 커맨드를 읽어 처리하는 메인 루프."""
74
+ log.info('Service started')
75
+
76
+ for line in sys.stdin:
77
+ line = line.strip()
78
+ if not line:
79
+ continue
80
+
81
+ try:
82
+ command = json.loads(line)
83
+ except json.JSONDecodeError as e:
84
+ send_response(error_response(f'JSON parsing error: {e}'))
85
+ continue
86
+
87
+ try:
88
+ if not self.dispatch(command):
89
+ break
90
+ except Exception as e:
91
+ send_response(error_response(f'Command processing error: {e}'))
@@ -0,0 +1,2 @@
1
+ """Base abstract classes."""
2
+ from base.service import Service
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Base Service Abstract Class
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+
9
+
10
+ class Service(ABC):
11
+ """Base class for all services."""
12
+
13
+ @abstractmethod
14
+ def list_scanners(self) -> dict:
15
+ """Discover scanners on the network."""
16
+
17
+ @abstractmethod
18
+ def scan(self, params: dict) -> dict:
19
+ """Execute scan with given parameters."""
20
+
21
+ @abstractmethod
22
+ def get_capabilities(self, params: dict) -> dict:
23
+ """Retrieve scanner capabilities."""
@@ -0,0 +1,4 @@
1
+ """Common utilities: logger, exceptions, response helpers."""
2
+ from common.logger import setup_logging
3
+ from common.exceptions import ScannerError
4
+ from common.response import success_response, error_response, send_response
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Scanner exception classes.
5
+ """
6
+
7
+
8
+ class ScannerError(Exception):
9
+ """Raised when a scanner operation fails.
10
+ Caught by handle_scanner_errors decorator to produce {'success': False, 'error': ...}.
11
+ """
12
+
13
+ def __init__(self, message: str, *, context: str | None = None):
14
+ super().__init__(message)
15
+ self.context = context
16
+
17
+ def __str__(self) -> str:
18
+ if self.context:
19
+ return f'{super().__str__()} [{self.context}]'
20
+ return super().__str__()
21
+
22
+ def __repr__(self) -> str:
23
+ return f'{self.__class__.__name__}({super().__str__()!r}, context={self.context!r})'
24
+
25
+ def to_dict(self) -> dict:
26
+ """Convert to error response dict."""
27
+ from common.response import error_response
28
+ return error_response(str(self))
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Logging configuration for eSCL Scanner Backend.
5
+ Uses Python's standard logging module with stderr output.
6
+ """
7
+
8
+ import logging
9
+ import sys
10
+
11
+
12
+ def setup_logging() -> None:
13
+ """Configure root logger for the application.
14
+
15
+ All log output goes to stderr (stdout is reserved for JSON IPC).
16
+ Format: [module.name] message
17
+ Call once at application startup.
18
+ """
19
+ root = logging.getLogger()
20
+
21
+ if not root.handlers:
22
+ handler = logging.StreamHandler(sys.stderr)
23
+ handler.setFormatter(logging.Formatter('[%(name)s] %(message)s'))
24
+ root.addHandler(handler)
25
+ root.setLevel(logging.DEBUG)
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Common response builders for JSON IPC.
5
+ """
6
+
7
+ import sys
8
+ import json
9
+ from typing import Any
10
+
11
+
12
+ def success_response(**kwargs: Any) -> dict:
13
+ """Build a success response dict."""
14
+ return {'success': True, **kwargs}
15
+
16
+
17
+ def error_response(error: str | Exception) -> dict:
18
+ """Build an error response dict."""
19
+ return {'success': False, 'error': str(error)}
20
+
21
+
22
+ def send_response(data: dict) -> None:
23
+ """Send JSON response via stdout."""
24
+ response = json.dumps(data, ensure_ascii=False)
25
+ sys.stdout.write(response + '\n')
26
+ sys.stdout.flush()
@@ -0,0 +1,2 @@
1
+ """Decorators package."""
2
+ from decorators.scanner import handle_scanner_errors
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Scanner error handling decorator.
5
+ """
6
+
7
+ from functools import wraps
8
+ from typing import Callable
9
+ from common.exceptions import ScannerError
10
+ from common.response import error_response
11
+ import logging
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ def handle_scanner_errors(func: Callable) -> Callable:
17
+ """Decorator that catches ScannerError and unexpected exceptions,
18
+ converting them into a consistent error response dict.
19
+ """
20
+ @wraps(func)
21
+ def wrapper(*args, **kwargs) -> dict:
22
+ try:
23
+ return func(*args, **kwargs)
24
+ except ScannerError as e:
25
+ log.error('%s error: %s', func.__name__, e)
26
+ return e.to_dict()
27
+ except Exception as e:
28
+ log.error('%s unexpected error: %s', func.__name__, e)
29
+ return error_response(f'{func.__name__} failed: {e}')
30
+ return wrapper