boringhex.top博客

非典型程序员的小破站

在软件开发过程中,创建新的项目往往需要重复执行一系列繁琐的步骤,尤其是在设置项目结构、配置文件和依赖方面。Cookiecutter 是一个开源的命令行工具,旨在帮助开发者快速生成项目模板,从而提高开发效率。本文将深入探讨 Cookiecutter 的功能、工作原理、常见用法以及一些最佳实践。

什么是 Cookiecutter?

Cookiecutter 是一个用于创建项目模板的工具,支持多种语言和框架。它允许开发者定义一个项目的结构,并将其作为模板进行重用。通过 Cookiecutter,用户可以在单一命令下生成新的项目,省去手动设置的麻烦。

主要特点

  • 可扩展性:支持通过 Git 存储库或本地目录来定义模板。
  • 灵活性:可用于任何类型的项目,包括 Python、JavaScript、Go、Ruby 等。
  • 交互式生成:在创建项目时,用户可以通过命令行输入参数,自定义生成的项目。
阅读全文 »

深入理解 OAuth 2.0:现代身份验证与授权框架

在当今互联网时代,随着应用程序和服务的不断增多,安全的身份验证和授权机制变得尤为重要。OAuth 2.0 是一种广泛采用的授权框架,它使得用户能够在不泄露密码的情况下,安全地授予第三方应用程序访问其资源的权限。本文将深入探讨 OAuth 2.0 的工作原理、核心概念以及常见用例。

什么是 OAuth 2.0?

OAuth 2.0 是一种开放的标准协议,允许用户授权第三方应用程序访问其存储在其他服务提供商上的信息。它解决了用户在多种服务之间共享数据所面临的安全问题。OAuth 2.0 于 2012 年正式发布,是 OAuth 的第二个版本。

OAuth 2.0 的核心概念

在深入了解 OAuth 2.0 之前,我们需要了解一些关键概念:

资源所有者(Resource Owner):通常是用户,拥有某些资源(例如,个人信息、照片等)。

客户端(Client):需要访问资源的应用程序,通常是第三方应用。

资源服务器(Resource Server):存储资源的服务器,能够处理来自客户端的请求,并验证其权限。

授权服务器(Authorization Server):负责验证用户身份并发放访问令牌(Access Token)的服务器。

访问令牌(Access Token):客户端用来访问资源的凭证,通常是一个短期有效的字符串。

阅读全文 »

微信扫码登录是一种常见的登录方式,用户打开登录页面,使用微信扫码登录,然后在微信客户端确认登录,这种方式可以减少用户输入账号密码的操作,提高用户体验。很多小伙伴都知道之前 ADLib 也是通过微信扫码的方式进行注册试用的,这里就来分享一下微信扫码登录的实现方式。

为了简化用户登录流程,微信正在灰度网站应用快速登录功能。

当网站应用发起微信登录请求时,如果用户此时已经登录了微信 3.9.11 for Windows及以上版本客户端,且处于非锁定状态,会优先提示用户使用当前微信客户端已登录的账号进行快速登录。快速登录无需扫码,可直接在Windows设备上进行确认。

用户仍可切换其他微信账号或二维码登录。

阅读全文 »

二维码(QR Code)是一种矩阵二维码,由日本Denso Wave公司于1994年发明。它是一种可以通过扫描来获取信息的二维条码,可以存储更多的信息,并且可以包含多种格式的内容,如文本、网址、电话号码、电子邮件地址等。

万万没想到这玩意儿竟然那么早就被发明了。虽然不是国内发明的,但是我觉得二维码绝对是在国内被发扬光大的,如今在国内,二维码已经无处不在了,到处都是扫码。

我们都知道在二维码普及之前还有条码,相比条码,二维码具有如下优点:

  1. 可以存储更多的信息:二维码可以存储更多的信息,包括文本、网址、电话号码、电子邮件地址等,而条形码只能存储数字和字母。
  2. 可以包含多种格式的内容:二维码可以包含多种格式的内容,如文本、网址、电话号码、电子邮件地址等,而条形码只能包含数字和字母。
  3. 可以提高识别率:二维码的识别率比条形码高,因为二维码是一种矩阵二维码,可以包含更多的信息,并且可以包含多种格式的内容。
阅读全文 »

在前一篇文章 聊聊DNS 中已经大致聊了DDNS的一些基本步骤。本文以DNSPod为例,介绍如何利用DNSPod的API实现DDNS。

本教程仅适用于解析托管在DNSPod平台上的域名,其他平台托管的域名请自行通过搜索引擎查找教程。

有需要自定义域名访问自己开发服务器的朋友可以联系我,省得自己再折腾域名了。

DDNS是什么

对于DHCP方式获得的IP,无论对于局域网内来说,还是外网来说,都会有使得IP地址每隔一段时间变化一次,如果想要通过恒定不变的地址访问主机,就需要动态域名解析。用一句话说明原理是:把动态变化的IP地址绑定到固定不变的域名上,这样便是以不变应万变,只要记住域名就可以了。

阅读全文 »

AD软件中元器件库中的元器件可以自定义添加参数,这些参数可以用于元器件的特性描述,也可以用于元器件的特性计算。

在搭建数据库类型的元件库时就会遇到这个问题,如何选择元器件的参数放在库中呢?因为数据库的表结构是固定的,所以元器件的参数字段也是固定的,如果元器件的参数太多,那么表结构就会很复杂,不利于维护。如果元器件的参数太少,那么元器件的特性描述就会不够详细,不利于使用。

“良好的设计就是合理的trade-off的结果”,所以在设计元器件库时,需要权衡元器件的参数数量和表结构的复杂度。

目前我在数据库中采用的字段如下:

阅读全文 »

今天早上朋友发消息说copilot服务掉了,我一开始以为是代理出了问题,登录到服务器发现服务没有问题,但是一直没有请求进来,这才意识到是网络问题。这个服务是通过CNAME解析的,而CNAME的源是一个通过DDNS服务提供商提供的域名,我发现DDNS服务域名解析失败导致服务不可用。

什么是 DDNS?

动态域名系统(Dynamic Domain Name System, DDNS)是一种通过动态更新 DNS 记录来实现域名与动态 IP 地址之间映射的技术。它解决了在互联网中,特别是在家庭网络和小型企业中,使用动态 IP 地址时面临的域名访问问题。

为什么需要 DDNS?

在许多情况下,用户的 Internet 服务提供商(ISP)会分配一个动态 IP 地址,这意味着每次路由器重启或网络连接中断时,用户的 IP 地址可能会变化。这样一来,用户想要通过域名访问自己主机的服务(如游戏服务器、FTP 服务器等)时,就会遇到困难,因为域名对应的 IP 地址已经改变。

DDNS 通过自动更新 DNS 记录,使用户能够始终通过同一个域名访问其设备,无论 IP 地址如何变化。

阅读全文 »

微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开放接口则是提供服务的基础,开发者在公众平台网站中创建公众号、获取接口权限后,可以通过接口实现用户管理、素材管理、消息管理等功能。

最近在重构 在线ADLib服务 这个项目,想用下公众号的接口,结果第一步就卡住了,特此记录下。

大多数情况下,调用接口服务都需要先获取access_token,而我主要想用的是接收公众号消息的接口,并不需要获取access_token,只绑定自己的服务器就可以。所以我的第一步卡在了绑定服务器上,离了大谱!

接入概述

接入微信公众平台开发,开发者需要按照如下步骤完成:

  1. 填写服务器配置
  2. 验证服务器地址的有效性
  3. 依据接口文档实现业务逻辑
阅读全文 »

昨天已经将元器件制造商信息整理更新好了,今天再更新一波元器件分类。之前分享过一篇物料编码规则,里面提到了元器件的一些分类原则,并根据分类给物料进行编码。

经过一段时间的使用,发现按分类进行编码,编码中就包含了分类信息,这样在查找物料时就可以根据编码的前几位就可以知道物料的分类,这样就不需要再去查找分类信息,提高了查找效率。但是分类表其实也比较复杂,并不容易记忆,实践中也很少用到根据编码去给物料进行分类,而且随着数字化水平的提高,信息应该是可以通过数据库查询来获取的,所以编码中包含太多信息越来越不实用,不如给所有物料甚至其它资产赋予唯一编码,而关于它的所有信息都在数据库里。

好了,说回来,今天再更新一波元器件分类,这次重点按元器件的电气特性进行分类,目前有以下分类:

阅读全文 »

前段时间一直在尝试迁移架构方案,OpenECADLib这个仓库就没更新,正好趁着这次迁移,就想内置更多的芯片和元器件制造商,这样就可以在新增元器件时直接关联制造商,为之后数据库更新做好准备。

制造商数据主要包括名称、描述、网址等字段,这一次应该已经覆盖绝大多数主流制造商,文末展示部分,可以从github仓库获取json源文件

从网上获取数据总会遇到不稳定的情况,正常情况下,服务器肯定要对来源IP进行频控,为了解决这个问题,可以使用代理池,或者降低请求频率,我不着急,所以使用了后者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def fetch_with_retry(url, headers=None, proxies=None, retries=5, backoff_factor=0.3):
for attempt in range(retries):
try:
response = requests.get(url, headers=headers, proxies=proxies)
response.raise_for_status() # 如果响应状态码不是 200,抛出 HTTPError
return response
except requests.RequestException as e:
if attempt < retries - 1: # 如果不是最后一次尝试
sleep_time = backoff_factor * (2**attempt) + random.uniform(0, 1)
print(
f"请求失败,正在重试... (尝试次数: {attempt + 1}, 等待时间: {sleep_time:.2f} 秒)"
)
time.sleep(sleep_time)
else:
print(f"请求失败,已达到最大重试次数。错误: {e}")
raise

这个函数会在请求失败时进行重试,重试次数和等待时间会随着尝试次数的增加而增加,这样可以有效降低请求频率,减少被封IP的风险。

还有个问题就是如果数据比较多,要全部获取后再保存的话,时间太长,万一中间出什么问题,之前的数据就白获取了,所以可以每次获取一部分数据后就保存一次,这样即使中途出问题,也不会浪费之前的数据。比较好的方法是根据稳定性和数据量来对数据进行切片处理。

切片获取数据

阅读全文 »
0%