Download modules/paper_printer/tool.py from ASown/agent-iot: direct link, hf CLI and curl.
- Browser
- Download file 5.75 kB
-
https://huggingface.co/spaces/ASown/agent-iot/resolve/main/modules/paper_printer/tool.py
- Command line
-
hf download hf://spaces/ASown/agent-iot/modules/paper_printer/tool.py
-
curl -L -o tool.py https://huggingface.co/spaces/ASown/agent-iot/resolve/main/modules/paper_printer/tool.py
5.75 kB
| """Harness adapter: máy in giấy Brother — CHỈ in (tìm văn bản là tool doc_finder).""" | |
| from __future__ import annotations | |
| import os | |
| import re | |
| import shlex | |
| import sys | |
| from pathlib import Path | |
| HERE = Path(__file__).resolve().parent | |
| ROOT = HERE.parent.parent | |
| for p in (str(HERE), str(ROOT)): | |
| if p not in sys.path: | |
| sys.path.insert(0, p) | |
| from harness.tool_base import Tool, ToolResult | |
| def _on_cloud() -> bool: | |
| """True nếu đang chạy trên HF Space / server đám mây (không cùng WiFi máy in).""" | |
| return bool(os.getenv("SPACE_ID") or os.getenv("SPACE_HOST")) | |
| def _no_printer_msg(err: str | None = None) -> str: | |
| """Thông báo 'không thấy máy in' rõ ràng + đề xuất, phân biệt online vs offline.""" | |
| if _on_cloud(): | |
| return ("Không tìm thấy máy in nào — và sẽ KHÔNG thấy được, vì bạn đang dùng bản " | |
| "ONLINE (HF Space). Máy chủ chạy trong trung tâm dữ liệu, KHÔNG cùng mạng " | |
| "WiFi với máy in ở nhà/văn phòng bạn, nên không quét hay in tới nó được. " | |
| "Muốn IN THẬT: chạy bản OFFLINE (tải mã về, chạy web.ps1) trên máy tính " | |
| "CÙNG WiFi với máy in, rồi in từ đó.") | |
| return ("Không tìm thấy máy in nào trong mạng WiFi hiện tại (đã quét cổng in 631/9100 " | |
| "trên toàn dải /24). Kiểm tra giúp mình: (1) máy in đã BẬT và nối CÙNG WiFi/router " | |
| "với máy tính này chưa? (2) máy in có bật in qua mạng (IPP/AirPrint) không? " | |
| "(3) thử tắt–bật lại máy in. Nếu biết IP máy in, đặt biến môi trường " | |
| "PAPER_PRINTER_HOST=<địa chỉ IP> để ghim thẳng, khỏi cần dò." | |
| + (f"\n(chi tiết kỹ thuật: {err})" if err else "")) | |
| # strip leading print commands so "in cho tôi file X" -> "file X" -> "X" | |
| _LEAD = re.compile( | |
| r"^\s*(hãy\s+|vui lòng\s+|làm ơn\s+)?(in ra giấy|in giúp( tôi)?|in cho tôi|in dùm( tôi)?|" | |
| r"in hộ( tôi)?|in|print)\s+", re.IGNORECASE) | |
| # "chỉ dò/tìm máy in" (thiết bị) -> discovery, không in gì | |
| _FIND_PRINTER = re.compile( | |
| r"(tìm|dò|kiếm|kiểm tra|scan|quét|kết nối|connect).{0,20}(máy in|printer)", re.IGNORECASE) | |
| class PaperPrinterTool(Tool): | |
| name = "paper_printer" | |
| description = ( | |
| "IN RA GIẤY thật trên máy in Brother MFC-L3750CDW (WiFi, tự dò tìm & kết nối). " | |
| "Dùng khi người dùng muốn IN RA GIẤY: in một ảnh, in PDF, in file có sẵn trên máy " | |
| "(tự tìm theo tên trên Desktop), hoặc tả một hình để sinh ảnh rồi in ra giấy A4; " | |
| "hoặc chỉ dò xem có máy in trên mạng. Hỗ trợ --size RxC (mm). KHÔNG dùng để TÌM " | |
| "văn bản trên web (đó là doc_finder), KHÔNG mô phỏng/in 3D." | |
| ) | |
| def run(self, task: str, **ctx) -> ToolResult: | |
| import paper_agent | |
| import paper_print | |
| attachment = ctx.get("attachment") | |
| on_step = ctx.get("on_progress") | |
| low = (task or "").lower() | |
| # --- sub-mode: CHỈ dò máy in (không in) --- | |
| if not attachment and _FIND_PRINTER.search(low): | |
| if callable(on_step): | |
| on_step({"kind": "running", "name": "Dò máy in", "machine": "Discovery"}) | |
| try: | |
| found = paper_print.discover_printer() | |
| except Exception as e: | |
| found = None | |
| err = str(e) | |
| else: | |
| err = None | |
| host = (found or {}).get("host") or (found or {}).get("ip") if found else None | |
| if callable(on_step): | |
| on_step({"kind": "done", "name": "Dò máy in", "machine": "Discovery", | |
| "status": "ok" if found else "warn", | |
| "detail": f"Thấy máy in tại {host}." if found | |
| else "Không thấy máy in nào trên mạng."}) | |
| return ToolResult(bool(found), | |
| f"Đã tìm thấy máy in tại {host}." if found | |
| else _no_printer_msg(err), | |
| {"printer": host}) | |
| req, opts = paper_agent.parse_args(shlex.split(task) if task else []) | |
| req = _LEAD.sub("", req or task).strip() or (req or task) | |
| try: | |
| host = paper_print.resolve_host() # discover + connect (or cache) | |
| except Exception as e: | |
| if callable(on_step): | |
| on_step({"kind": "done", "name": "Dò máy in", "machine": "Discovery", | |
| "status": "warn", "detail": "Không thấy máy in nào trên mạng."}) | |
| return ToolResult(False, _no_printer_msg(str(e)), {"reason": str(e)}) | |
| try: | |
| if attachment: # user uploaded the exact file to print | |
| path, how = attachment, "file tải lên" | |
| else: | |
| path, how = paper_agent.resolve_source(req, interactive=False) | |
| except Exception as e: | |
| return ToolResult(False, f"Không lấy được nội dung để in: {e}") | |
| result = paper_agent.print_path(Path(path), opts) | |
| if result.get("ok"): | |
| pages = f", {result['pages']} trang" if result.get("pages") else "" | |
| return ToolResult( | |
| True, | |
| f"Đã gửi in ({result.get('placed_mm')}{pages}) tới {result.get('printer', host)} " | |
| f"— nguồn: {how}", | |
| result) | |
| return ToolResult(False, f"In thất bại: {result}", result) | |
| def get_tool() -> Tool: | |
| return PaperPrinterTool() | |