用homebrew来设置Python开发环境

Homebrew已经是macOS里非常好的包管理工具了,目前在macOS上设置Python开发环境主要解决几个问题

  • Python的多个版本,python2和python3共存,毕竟还有一些老的项目在用Python2
  • virturalenv,没有这个不同项目怎么活
  • pip安装一些扩展的问题
$ brew install python2 python3
$ pip install virtualenv virtualenvwrapper

在安装mysql-python的时候可能会遇到openssl头文件无法找到的问题

$ env LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" pip install mysql

机械键盘

目前为止手里用过三把机械键盘,分别是

  • Filco 87圣手,红轴
  • iKBC Poker II,青轴
  • KeyWalker 87键有线蓝牙,茶轴

从整体感觉上来说,Filco 87圣手无论是做工还是手感都是这三把中最好的,敲击起来的那种沉着感,声音浑厚,手感轻盈精准,缺点就是小贵了一些,并且没有更多的设置,也没有灯(虽然我不care),而且之后出的蓝牙版是3.0版。

其次是Keywalker(键行者),这是一套由国内深圳的一家手工厂做的键盘,整体来说完整度很不错,键盘的编程功能很好用,使用一个windows版的软件进行操作,比一般的口诀式录制模式好很多,也很直观。目前所使用的茶轴也充分的发挥了茶轴的特点,算是蛮不错的一款。缺点是品控需要加强,第一次发货的版本一个B键有瑕疵,客服倒是很直接的给换了新的。另外一点就是键盘的某些键有弹簧的音颤,这一点不是特别好,虽然有那么一点敲击IBM M键盘的感觉,但是我并不是很喜欢这种感觉,还是特别喜欢Filco的那种浑厚的感觉。

最后是Poker II这一把,整体来说没有亮点,但是也没有太大的缺点,67键的布局导致我在很长一段

Macbook Pro 连接4K显示器的转换头

从朋友那里入手了一个4K显示器,之后就为适配这个4K显示器的转换头发愁了一段时间,所有买到的转接头不是不能用就是4k无法到60hz刷新率,就连苹果原厂的

后来终于是发现了MI 小米 USB-C至Mini DisplayPort多功能转接器,买回来用了2个月,现在坏了。

升级Homebrew中的PostgreSQL

最后还是入手了新版的MBP,开发环境都是重新设置的,用PostgreSQL的时候,启动提醒版本不兼容

FATAL:  database files are incompatible with server
DETAIL:  The data directory was initialized by PostgreSQL version 9.5, which is not compatible with this version 9.6.2.

所以要升级一下原来的库,作弊条开始

  • brew services stop postgresql
  • brew install postgresql@9.5
  • initdb /usr/local/var/postgres9.6 -E utf8
  • 开始升级数据库
pg_upgrade \
  -d /usr/local/var/postgres \
  -D /usr/local/var/postgres9.6 \
  -b /usr/local/Cellar/postgresql@9.5/9.5.6/bin \
  -B /usr/local/Cellar/postgresql/9.6.2/bin/ \
  -v
  • mv /usr/local/var/postgres /usr/local/var/postgres9.5
  • mv /usr/local/var/postgres9.6 /usr/local/var/postgres
  • brew services start postgresql

完成

写给SaaS创业公司的安全基础知识

头两天看到了写给SaaS创业公司的安全101,内容涵盖了不少,非常值得一读,其实不光是给SaaS企业了,其他公司一样适用。

我摘了几个贴在这里

  • 密码共享和密码管理,所有系统都有一个终极的Admin账户,这个账户是共享的,防止这个人的单点故障,同时一旦共享了,那么密码是需要加密共享的,所以要有密码管理。
  • 全盘加密,Mac/Windows都有很好的加密方法了,几乎一键加密。
  • 买3个以上域名,第一个用于公开的品牌和企业的邮箱。第二个用于自己的SaaS服务,比如googleapis.com之类的。第三个域名用于内部的后勤支持,比如公司vpn等基础设施等等,而且这个域名最好匿名,这样别人就难以猜测了。营销邮件应该使用独立的域名,以防反垃圾系统标记后影响公司业务邮件来往。
  • 所有地方都使用HTTPS
  • API密钥,每一个客户都应该拥有不同的API钥匙对。
  • 物理安全:
    • 使用屏保,并且从屏保恢复需要输入密码。
    • 不要使用U盘,这是入侵的最方便最直接的方法了。
  • 企业内部沟通用Slack,客户间沟通用邮件,国内可以适用企业内部用BearyChat,客户沟通用邮件+微信。
  • 认证服务支持SSO和OAuth
  • 备份
    • 冷备/热备/异地容灾
    • 自动化备份
    • 定期恢复演练
    • 备份加密
  • 防火墙和访问权限
    • 服务访问需要认证,比如ElasticSearch, MongoDB, MySQL等
    • Review防火墙设置,只能允许必要的服务和端口开放。
    • 自动扫描。

可以照这个列一个checklist,看看自己公司都做到了哪些?

继续留在Mac OS X

macOS 10.12 发布之后我升级过了两次,但是体验都不是很好,本身系统的变化不大,但是带来的问题并不小,对我最大的影响是外接显示器之后的风扇狂转不止。甚至让我产生了它们要修复系统在老机器上运行过于流畅的bug了。

本身我自己的MBP也已经用了4年之久了,是应该更新一下了,然而对于新版MBP的失望,配件的短缺,看来我的MBP还要继续服役1年以上,等配件比较齐全的时候再下手了,希望到时候macOS能稳定一些。

我常读的Joel On Software主角,Joel Spolsky也表达了同样的

@spolsky: Sorry Apple. After 10 years loyalty, this latest MBPro with useless touchbar and unreliable keyboard was last straw. Switched to Dell XPS13👋

tweets

selenium wait 和 iframe

还是从朋友那个小事儿做的时候弄出来的问题

  1. selenium 如何切换driver到一个ID设置为中文iframe?
  2. 遇到alert了怎么处理?
  3. 检查某个元素是不是出现了?

不要问我为啥id会用中文,说多了都是泪,总之这是一个一言难尽的问题,一句话,国有企业你懂的。

  1. 切换到特定的iframe/frame
driver.switch_to_frame(driver.find_element_by_id('some_id'))

这样就可以在这个frame/iframe里做相应的find element操作了,但是要记住操作完了要切换回来

driver.switch_to_default_content()

多层嵌套的iframe也没有问题,只要一步一步的切换进去就好了

  1. 接受alert

一个简单的方法就是预计有alert的地方,写上接受就好了

driver.switch_to.alert.accept()

这样很粗暴,但是也很有效,精细一些的做法看文档,比如:

  • 确认或者取消
from selenium.webdriver.common.alert import Alert
Alert(driver).accept()
Alert(driver).dismiss()
  • 读取alert的文字内容
Alert(driver).text
  • 认证的用户名和密码
driver.switch_to.alert.authenticate(username,password)
  • 输入内容
name_prompt = Alert(driver) name_prompt.send_keys(“Willian Shakesphere”) 
name_prompt.accept()
  1. 检查某个元素是否出现

以前的一个很粗暴的做法是time.sleep(N),但是这种情况下非常粗旷,selenium 提供了更精细的一些控制方法

  • 等待某个元素出现以后获取这个元素
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10) #10秒,超过这个时间就会raise Exception
element = wait.until(EC.element_to_be_clickable((By.ID,'someid')))
  • 这里的expected_conditions可以是下面的这些条件
    • title_is
    • title_contains
    • presence_of_element_located #元素可以找到
    • visibility_of_element_located #元素可见
    • visibility_of
    • presence_of_all_elements_located #所有元素可以被找到
    • text_to_be_present_in_element #元素中包含text
    • text_to_be_present_in_element_value #元素的value值包含text
    • frame_to_be_available_and_switch_to_it #iframe可以切换
    • invisibility_of_element_located #不可见元素被找到
    • element_to_be_clickable #不但可见,而且可点
    • staleness_of
    • element_to_be_selected #元素被选中
    • element_located_to_be_selected #
    • element_selection_state_to_be
    • element_located_selection_state_to_be
    • alert_is_present #弹框出现

这些基本覆盖了常见的情况了,足够用了,记得处理异常,否则就挂了。

Selenium 连接一个已有的连接

帮朋友弄个东西,需要先登录,有一个不复杂的验证码,但是上OCR也太重,所以就先起一个driver,然后手工登录之后再连过来进行操作.

  • 先启动一个Driver和Session,并且打印出连接的URL和Session
url = driver.command_executor._url       #"http://127.0.0.1:60622/hub"
session_id = driver.session_id            #'4e167f26-dc1d-4f51-a207-f761eaf73c31'
  • 然后再连接过去
driver = webdriver.Remote(command_executor=url,desired_capabilities={})
driver.session_id = session_id

REF:
Stackoverflow: Connect to an already running instance of chrome using selenium in python

还是不要全局 .gitignore 了

昨天踩了一个小坑,使用bower安装了一堆的组件进来,我这里是好的,但是同事去构建的时候就不对了。

发现我git commit的时候,jQuery包里的dist目录没有添加进去,进而发现实际是我在很久以前在~/.gitignore里添加了一个dist导致彻底忽略了。

索性就把这个家目录下的.gitignore给删除了,反正都是跟着项目走的,新建git repo的之后添加一个.gitignore就好了。