MoreRSS

site iconlhasa | 游钓四方修改

千禧年生,长途骑行、野钓路亚、振出并继、古典乐、摇滚、布鲁斯、茶叶爱好者。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

lhasa | 游钓四方的 RSS 预览

热成铁板烧,又被暴雨淋成落汤鸡:西湖,我来了!

2025-07-19 20:06:00

从义乌出发去杭州

上次骑行是在6月24日,转眼半个月过去了,忍不住又开始怀念行驶在路上的感觉。

7月17日 清晨,一时心血来潮,换上骑行服,简单带了件便装,便推车下楼。目的地:杭州。

除骑行服外,只带了一件便装

二零二五 - 六七月读书随笔

2025-07-15 16:16:00

书犹药也,善读之可以医愚

C3环球游记Ⅲ:加勒比没有那么远 | 徒步进藏 | 不去会死

这个 RSS 有意思

2025-07-10 02:26:00

晚上逛 #UNTAG 发现一个有意思的项目 —— RSS.Beauty

一款开源 RSS 美化工具。支持 RSS 2.0 和 Atom 1.0 格式,可将原始订阅源转换加以渲染。

此外,根据项目文档,作者还提供了四种食用方法,包括:

  • 在线美化
  • 本地 XSL 样式
  • Base64 内嵌样式
  • Docker / Node.js 部署

一、在线美化 RSS

只需提供 RSS 地址,即可通过服务端转换美化:

https://rss.lhasa.icu/rss?url=https://lhasa.icu/rss.xml
RSS

二、食用 XSL 模板

  • XSL 文件必须与 RSS 源在同一域名下,否则会有跨域限制。

下载模板:

# RSS 2.0
wget https://rss.lhasa.icu/rss.xsl

# Atom 1.0
wget https://rss.lhasa.icu/atom.xsl

在 RSS 文件头部添加如下声明:

<?xml-stylesheet href="/style/rss.xsl" type="text/xsl"?>

三、Base64 编码

适合不想托管样式文件,可以将样式直接内嵌进 RSS 文件中

步骤如下:

  1. 访问:https://rss.lhasa.icu
  2. 切换到 “Base64” 选项卡
  3. 根据 RSS / Atom 格式选择对应样式
  4. 将复制的代码插入 RSS 文件中,例如:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="data:text/xsl;base64,PD94bWw..." type="text/xsl"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">

四、Docker 部署

扒拉下来,启动:

docker pull ghcr.io/ccbikai/rss.beauty:main
docker run -d --name rss-beauty -p 4321:4321 ghcr.io/ccbikai/rss.beauty:main

Nginx 反代:

# /etc/nginx/conf.d/rss.conf
server {
  listen 80;
  server_name rss.lhasa.icu;
  location / {
      proxy_pass         http://127.0.0.1:4321;
      proxy_http_version 1.1;
      proxy_set_header   Host $host;
      proxy_set_header   X-Real-IP $remote_addr;
      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header   X-Forwarded-Proto $scheme;
  }
}

# 重载 Nginx
sudo nginx -t && sudo nginx -s reload

Node.js 部署就不赘述了,天天接触,不新鲜。

我小改了一下配色,不过目前还不支持输出文章配图和全文。等明天下班再来折腾吧。

我去看看

RSS

相关链接:

项目主页:RSS.Beauty

官方部署指南

生日骑遇“死亡摇摆”,差点成忌日骑

2025-06-25 20:53:00

农历五月二十九,二十五岁生日到了

一边上班,一边创业,这样的活法让我骑车的时间越来越少。这不是我想要的状态,但为了三十岁之前出发环球骑行的梦想,我没有办法。

前几日申请了调休,可算睡个安稳觉。早上睡到十点钟,吃完午饭,我觉得今天不能再碰电脑了,我现在很想出去骑车。可只剩下一个下午的时间了,太远去不了,近的没意思。打开高德地图扒拉半天,去横店。

横店十里街 · 江南大桥方向

独立开发者创业了

2025-06-12 13:07:00

我们生命中最美好的时刻,并非是那些接受给予、放松享受的时刻,而是那些为了完成一件困难而有价值的事情,自愿将身心发挥到极限的时刻。

像咱这种人,我觉得只有一种死法 —— 猝死。

从6月10日早上九点,一直干到6月11日下午一点半,眼睛都没怎么合过。足足三十多个小时,一口气用Go,把整个企业级的RESTful API给撸完了!

这可不是简单的CtrlCV,为了支持硬件,软件下了点功夫:MySQL做了主从复制架构 + Redis缓存 + 负载均衡。支持 Docker 一键部署。还没做压力测试,自我感觉并发二三十万如喝水。

上午测完接口,兴奋的饭都顾不上吃,更别说休息了。立马开始写文档。接口文档、数据库文档…

先用Cursor生成基本文档,再改改。每份大概3000字800行左右,足足写了八份。

还有商业计划书的思维导图,2M的大小,不放大到190%字体都看不清楚,内容密度可想而知。

截图

真的要特别感谢 Cursor,这AI工具真是赶上了好时代!要是没有它,就凭这些工作量,外包团队没一个月起步都别想搞定。

不敢想象,我竟然在三十多个小时里,就搞定了这么多事,而且落地质量高!

接下来,还剩微信小程序对接接口,以及和硬件的联调。先给这些小卡拉米放放假,我要好好休息一个下午。

此刻,精力充沛去吃个早饭骑骑车。

6.12 注册公司:

实际上,我做的这些事情有没有公司都能推进,但没办法,就为了微信小程序后续的企业认证需求.

在浙江线上办理,全程可以不出门。

項目 內容
企业名称 浪泳科技(义乌)有限公司
自主申报预选号 [2025]******
拟登记机关 义乌市市场监督管理局
住所所在地 ******
生产经营地 ******
法定代表人 ******
从业人数 2
联系电话 186****7426
邮政编码 322000
注册资本 0.001万元
企业类型 有限责任公司(自然人独资)
行业 (6513) 应用软件开发
是否一照多址
经营范围 写不下

被驳回

提交申请还不到俩小时,我就收到了驳回通知:

您申报的“浪泳科技(义乌)有限公司”设立登记申请,预审未通过,请补齐材料后再次申报。

    1. 注册资本显著过低,不符实际,请调整;
    1. 身份证照片裁剪旋转摆正上传, 要求照片只保留身份证、其余无关背景裁去并放正上传;
    1. 部门产权信息核验不通过,需要提供产权证或是前往地名办办理登记,若房屋登记用途为住宅的,仅能从事电子商务、计算机数据处理、软件和信息服务、网络技术、文化创意、动漫游戏开发、翻译服务、工业设计,审核人将在经营范围最后添加以上销售仅限网上销售,咨询电话:0579-85232920/85117280/85518797/85518798(业务咨询电话:0579-85232920)

注册资本一元行不通,调整到了一万

经营范围调整为:

  • 软件开发;信息系统集成服务;网络与信息安全软件开发;人工智能基础软件开发;数字技术服务;网络技术服务;软件外包服务;信息技术咨询服务;数字内容制作服务(不含出版发行);数据处理和存储支持服务;互联网销售(除销售需要许可的商品);软件销售(除依法须经批准的项目外,凭营业执照依法自主开展经营活动)。

EasyFill 重大更新,全面提升用户体验

2025-06-02 23:27:00

版本:v1.1.1

经过两个月的偷懒,EasyFill 迎来了 v1.1.1 版本的重大更新。这次更新主要在匹配算法上进行大幅度优化,全面提升匹配效率

更新概览

  • 支持动态 Shadow DOM 和三种全新识别方式
  • 可自定义数据源,智能缓存机制
  • Markdown 文本异步并行加载
  • 自适应三级别日志,支持控制台调试
  • 更新隐私政策

全新识别方式

1. 动态 Shadow DOM 支持

我发现有些评论系统通过 Shadow DOM 来实现封装,导致 v1.0 版本无法识别 Shadow DOM 生成的表单。在 v1.1.1 中,EasyFill 新增了对动态创建的 Shadow DOM 的完整支持。

function traverseShadowDOM(root: Document | ShadowRoot | Element) {
  const inputs = root.querySelectorAll('input, textarea');
  elements.push(...Array.from(inputs));
  
  const allElements = root.querySelectorAll('*');
  allElements.forEach(element => {
    if (element.shadowRoot) {
      logger.info('发现 Shadow DOM,正在遍历', { 
        tagName: element.tagName, 
        shadowRootMode: element.shadowRoot.mode 
      });
      traverseShadowDOM(element.shadowRoot);
    }
  });
}

2. 三种识别方式全覆盖

在 v1.0 版本,EasyFill 只支持 name 字段识别。为了更加准确的匹配字段,引入了全新三种字段识别方式,确保在各种稀奇古怪的表单都可以识别:

Placeholder 识别

通过分析输入框的 placeholder 属性来识别字段类型:

<input placeholder="请输入您的姓名" />
<input placeholder="邮箱地址" />
<input placeholder="个人网站" />

Type 识别

基于 HTML5 标准的 type 属性进行智能识别:

<input type="email" />
<input type="url" />
<input type="text" name="username" />

ID 识别

通过元素的 id 属性进行精确匹配:

<input id="author" />
<input id="email" />
<input id="website" />

匹配策略:

inputs.forEach((input) => {
  const typeAttr = (input.getAttribute("type") || "").toLowerCase();
  const nameAttr = (input.getAttribute("name") || "").toLowerCase();
  const idAttr = (input.getAttribute("id") || "").toLowerCase();
  let valueToSet = ""; // 要填充的值
  let matchedBy = "";  // 匹配方式(id, name, type)
  let fieldType = "";  // 字段类型(name, email, url)

  // 匹配 URL 字段
  if (keywordSets.url.has(nameAttr) || keywordSets.url.has(`#${idAttr}`)) {
    valueToSet = url;
    matchedBy = keywordSets.url.has(`#${idAttr}`) ? "id" : "name";
    fieldType = "url";
  } else if (typeAttr === "url" && url) {
    valueToSet = url;
    matchedBy = "type";
    fieldType = "url";
  }

  // 匹配 Email 字段
  else if (keywordSets.email.has(nameAttr) || keywordSets.email.has(`#${idAttr}`)) {
    valueToSet = email;
    matchedBy = keywordSets.email.has(`#${idAttr}`) ? "id" : "name";
    fieldType = "email";
  } else if (typeAttr === "email" && email) {
    valueToSet = email;
    matchedBy = "type";
    fieldType = "email";
  }

  // 匹配 Name 字段
  else if ((keywordSets.name.has(nameAttr) || keywordSets.name.has(`#${idAttr}`)) && name) {
    valueToSet = name;
    matchedBy = keywordSets.name.has(`#${idAttr}`) ? "id" : "name";
    fieldType = "name";
  }

  // 没有匹配上就跳过
  if (!valueToSet) return;

  // 设置值并触发事件
  (input as HTMLInputElement).value = valueToSet;
  input.dispatchEvent(new Event('input', { bubbles: true }));
  input.dispatchEvent(new Event('change', { bubbles: true }));

  // 记录日志
  logger.info('填充表单字段', {
    name: nameAttr || "",
    id: idAttr || "",
    type: typeAttr || "",
    matchedBy,
    valueToSet,
    inShadowDOM: isInShadowDOM(input)
  });
});

数据同步

1. 自定义数据源功能

v1.1.1 版本允许用户完全自定义关键字数据源。

该源来自我的腾讯云 COS,且由腾讯云境内 CDN 加速,基本上无延迟:

https://cos.lhasa.icu/EasyFill/keywords.json

自定义数据源格式示例:

{
  "name": ["name", "author", "username", "昵称", "姓名"],
  "email": ["email", "mail", "邮箱", "电子邮件"],
  "url": ["url", "website", "blog", "网站", "博客"]
}

2. 缓存机制

实现了基于 HTTP 标准的智能缓存系统,大幅减少不必要的网络请求:

  • 304 Not Modified 响应处理
  • 自动缓存有效期管理(24小时)
  • 网络失败时自动回退到缓存
  • 支持强制刷新机制

ETag 和 Last-Modified 支持:

if (etag && !forceSync) {
  headers['If-None-Match'] = etag;
}
if (lastModified && !forceSync) {
  headers['If-Modified-Since'] = lastModified;
}

性能优化

1. localStorage 持久化存储

实现 Markdown 内容的持久化机制:

const fetchMarkdown = async (url: string) => {
  try {
    // 检查 localStorage 是否已有缓存
    const cachedMarkdown = localStorage.getItem(url);
    if (cachedMarkdown) {
      logger.info(`从缓存加载 Markdown 文件: ${url}`);
      return cachedMarkdown;
    }

    // 如果没有缓存,从网络加载
    const response = await fetch(url);
    const markdown = await response.text();

    // 将加载的内容存入 localStorage
    localStorage.setItem(url, markdown);
    return marked(markdown);
  } catch (error) {
    logger.error(`加载 Markdown 文件失败: ${url}`, error);
  }
};

2. 异步并行加载优化

实现 Markdown 内容的异步并行加载:

const loadContent = async () => {
  const [aboutAuthor, recommendedPlugins, updateLog, privacyPolicy] = await Promise.all([
    fetchMarkdown('/markdowns/about-author.md'),
    fetchMarkdown('/markdowns/recommended-plugins.md'),
    fetchMarkdown('/markdowns/UpdateLog.md'),
    fetchMarkdown('/markdowns/privacy-policy.md'),
  ]);

  setAboutAuthorContent(aboutAuthor);
  setRecommendedPluginsContent(recommendedPlugins);
  setUpdateLogContent(updateLog);
  setPrivacyPolicyContent(privacyPolicy);
};

日志系统

1. 三级别日志架构

EasyFill v1.1.1 实现了单例日志系统,支持 INFO、WARN、ERROR 三个级别:

export enum LogLevel {
  INFO = 'INFO',
  WARN = 'WARN',
  ERROR = 'ERROR',
}

2. 智能环境适配

日志系统能够根据运行环境自动调整输出策略:

public configureByEnvironment(): Logger {
  const isProd = typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production';
  
  if (isProd) {
    // 生产环境:只显示警告和错误
    this.setLevel(LogLevel.WARN);
  } else {
    // 开发环境:显示所有日志,并启用彩色和时间戳
    this.setLevel(LogLevel.INFO)
        .useColors(true)
        .showTimestamp(true);
  }
  
  return this;
}

3. 控制台命令

生产状态下,日志默认关闭。所以,增加了命令调试:

// 启用日志系统
EasyFillLogger.enable()

// 关闭日志系统
EasyFillLogger.disable()

// 查看当前状态
EasyFillLogger.status()

命令绑定在全局 window 对象上,重启浏览器仍有效。

在浏览器扩展环境中,使用 chrome.storage.local 来存储,在普通网页环境中,使用 localStorage。

一样的是都用 easyfill_logger_enabled 这个键来存储

4. 链式配置接口

支持灵活的链式配置:

logger
  .setLevel(LogLevel.INFO)
  .useColors(true)
  .showTimestamp(true)
  .setPrefix('[EasyFill]')
  .setPrefixColor('color: #4CAF50; font-weight: bold');

配置选项:

  • 自定义日志前缀和颜色
  • 时间戳显示控制
  • 彩色输出开关
  • 级别过滤设置

隐私权政策

v1.1.1 版本对隐私权政策进行了全面更新:

主要更新内容:

  • 明确了关键字数据同步的目的和方式
  • 增加了用户控制权的说明

界面改进

1. 同步设置

新增了直观的同步设置界面,轻松管理数据同步:

  • 同步开关:一键启用/禁用自动同步
  • 同步频率:支持 1 小时到 1 周的灵活设置
  • 网络条件:可选择任何网络或仅 WiFi
  • 数据源管理:支持自定义 URL 和一键重置

2. 状态反馈优化

  • 实时显示同步状态和下次同步时间
  • 提供详细的操作成功/失败反馈
  • 使用 Snackbar 组件统一消息提示风格

短期计划

  • 实现黑白名单机制,控制填充权限
  • 支持多身份设置,满足不同用户需求
  • 完成在 Edge 和 Firefox 浏览器上的上架与兼容

长远计划

  • 使用 TensorFlow 训练机器学习模型,实现自动识别和评论补全功能
  • 在无性能开销的情况下,实现移动端跨平台支持(iOS 与 Android)
  • 依托 EasyFill 建立独立博客生态社区,面向计算机学生及爱好者提供系统性新手指南

致谢与支持

EasyFill 的每一次进步都离不开用户的支持和反馈。特别感谢:Mainbranch 的反馈与支持

如果您觉得 EasyFill 对您有帮助,欢迎:

请我喝一杯咖啡

立即体验

EasyFill v1.1.1 现已在 Chrome 应用商店正式发布,您可以:

  1. 新用户:直接在 Chrome 应用商店搜索 “EasyFill” 安装
  2. 现有用户:通过梯子 Chrome 扩展将自动更新到最新版本
  3. 开发者:访问 GitHub 仓库 查看源代码

EasyFill - 简易填充,让每一次评论更自然,与你的博友互动无缝连接