# setUrl 孤儿存档（2026-09-11）

**为什么删**：`/crawler/admin` 的「来源URL」列在 2026-09-11 按用户要求移除（历史残留，10 行里 9 行是 `-`，无信息量）。
该列移除后，改来源 URL 的入口 **在 UI 里已无任何调用方**（`editUrl` 全文件仅剩定义处 1 次，无 `onclick` 引用）——
属于 flat-list 时代的孤儿链路。用户确认后一并移入存档。

**移除清单（3 处，`search_app.py`）**：

| # | 位置 | 内容 |
|---|---|---|
| 1 | do_GET 路由 | `elif parsed.path == '/crawler/admin/set-url':` → 调 `set_crawler_url(n, u)` 返回 JSON |
| 2 | `render_admin_page()` 内嵌 JS | `function editUrl(el, name){ … prompt('请输入 …的来源URL') … fetch('/crawler/admin/set-url?…') }` |
| 3 | 模块级函数 | `def set_crawler_url(name, url)` —— 写回 `CONFIG_PATH`（`c['url']`） |

**注意**：`_display_url` **未删**，仍参与 admin 表格的 `data-search`，
所以客户端搜索依旧能按 URL 命中（只是不再显示该列）。

**恢复方式**：把下面三段贴回 `search_app.py` 对应位置即可（1 在 do_GET 路由链、2 在 admin 页 `<script>` 内、
3 在模块级），无需改其它地方。

```python
# ── 1) do_GET 路由 ──────────────────────────────────────────────
        elif parsed.path == '/crawler/admin/set-url':
            import json
            n = params.get('name', [''])[0]
            u = params.get('url', [''])[0]
            result = set_crawler_url(n, u)
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps(result, ensure_ascii=False).encode())

# ── 2) admin 页内嵌 JS ──────────────────────────────────────────
function editUrl(el, name) {
  var currentUrl = el.textContent === '+添加URL' ? '' : el.textContent;
  var newUrl = prompt('请输入 ' + name + ' 的来源URL:', currentUrl);
  if (newUrl === null) return;
  if (newUrl === currentUrl) return;
  fetch('/crawler/admin/set-url?name=' + encodeURIComponent(name) + '&url=' + encodeURIComponent(newUrl))
    .then(function(r){return r.json()})
    .then(function(data){
      if (data.success) location.reload();
      else alert('设置失败: ' + (data.error || '未知错误'));
    })
    .catch(function(e){ alert('网络错误: ' + e.message); });
}

# ── 3) 模块级函数 ───────────────────────────────────────────────
def set_crawler_url(name, url):
    """设置爬虫的来源URL (保持原 flat-list 格式)"""
    cfg = json.load(open(CONFIG_PATH))
    is_list = isinstance(cfg, list)
    crawlers = cfg if is_list else cfg.get('crawlers', [])
    for c in crawlers:
        cname = c.get('name', c.get('site_name', ''))
        if cname == name:
            if url:
                c['url'] = url
            else:
                c.pop('url', None)
            out = crawlers if is_list else cfg
            json.dump(out, open(CONFIG_PATH, 'w'), ensure_ascii=False, indent=2)
            return {'success': True, 'name': name, 'url': url}
    return {'success': False, 'error': f'Crawler "{name}" not found'}
```

**版本锚点**：删除动作发生在 `29f1ffed…`（去列）→ `e6d7d0f1…`（⌘K）之后，随 `8a1cbf4f…`（工具市场）一并上线。
