IT

关于 Pyblic 写作系统

2021 年 01 月 07 日 IT No comments

Pyblic 是什么?

基于 Flask(Python 生态最简单的 web 框架)和 Markdown 的 git 写作系统。设计目标是极简的实现逻辑和随心所欲的掌控。

多余取景器」是基于这套系统实现。

为什么要做 Pyblic?

首先需要问的是,为什么要用 git 管理自己的写作?

写作是一种知识树的重组织。基于有限的文档撰写经验,我发现用 git 更新文档是一种非常舒服的方式,好处包括:

一、版本化、可追溯

对于知识体系而言,思路变化的过程其实很可能非常值得记录。对于同一个主题,可能出现结构上的大幅调整,而这时如果出现大段删节,其实会挺「心疼」的。有了 git 机制,现在就可以大刀阔斧,反正万一删掉的东西有用,后面版本需要的话还可以找回。

二、版本的合适粒度

现在大部分的文档工具,包括石墨文档、WPS 都开始支持类似「时光机」无限历史版本回滚,是不是已经远好于 git 了呢?其实不是。

「时光机」的回滚是自动生成的,索引的唯一方式是时间。而 git 每一次 commit,都会要求你手动撰写 note。这其实是梳理自己想法变化的一个很好时机。而 git 管理工具基于 commit note 的清晰时间线,能够让想法变化的整个过程一目了然。

三、集中和专注

传统写作的过程会打若干版本的草稿,放在印象笔记/熊掌记的不同条目下。成稿的时候再去索引、查找和组织成篇。使用 git 之后,写文章就和写代码一样,始终只需要面对一份代码库,不断往前迭代即可(实在不确定性太大还可以开分支),这种工作方式带来的集中和专注感是界面上的优化无法带来的。

更直接的,是可以用自己熟悉的代码编辑器,比如 Sublime Text、VS Code 等等,直接像写代码一样写文章。无需习惯调整,还更方便直接用代码控制内容之外的部分——比如样式和页面结构。

除了是 git 写作,Pyblic 还有什么特性?

Pyblic 为把技术栈压缩到极简,省去了大部分功能,包括但不限于:

  1. 互动/留言功能
  2. 丰富的样式
  3. 多级导航
  4. 复杂的分类和存档
  5. 图形化后台

这样的好处是什么呢?直接的变化是,你可以直接把代码库作为你的文章库:只有一个 repo,无需费心处理子母 repo 的关联关系;也不用考虑 RDS 的备份或各种文件存储方式的备份——你的 repo 里已经包括了你所有的劳动成果:无论是文章内容,还是对页面样式、网站结构的调整。

Pyblic 基于 Python 生态,也把搭建部署简化到了极致。整套代码只有非常简单的依赖:Flask、Markdown,以及用于搭建服务的 gunicorn 和 supervisor。安装流程指引也在同一个代码库中,无需四处翻找。

总之,从里到外删繁就简,从而达到「一手掌控」的效果。

Pyblic 适合什么人?

工具栈的极度简化(只有 Python 和 Markdown),直接结果是 Pyblic 几乎没有让人分心的「可玩性」。没有琳琅满目的模板、插件可供选择,反而能逼迫自己立即开始写作。同时把底层的 Python 代码逻辑暴露给你,也使得定制设计的难度完全可把握,也丝毫不用担心创造力受限。

如果你略懂代码,同时保持专注对你来说很难也很重要,Pyblic 就是很不错的选择。

推荐的工作流程

顾名思义,Pyblic 是一个公开发表工具,因此它并不试图替代熊掌记、Typora 这类笔记应用。

我的使用方法是:

  • 平日在熊掌记中随时记录灵感,并起草文章。
  • 到准备正式发稿的时候,打开 Sublime Text,将熊掌记的代码复制到 .md 文档中,在本地执行./dev.sh 预览,做最后的审阅。
  • 完稿后通过 git 推送到 github,再部署到服务器上。
  • 如果需要修改,就直接在版本库中进行,不必再回到笔记应用了。

听着挺不错,代码开源么?

暂时不。Pyblic 是一时心血来潮,总共只花了两个晚上写出来(作为强迫症患者,大半时间在雕琢样式)的东西,目的是自用,代码质量尚不足以开源。其实一共也只有 50 行 Python 代码 ;告知技术栈后,相信普通程序员一个晚上也能轻松搞定:

  1. Python3 库:Flask、Markdown、gunicorn、supervisor
  2. CSS 库:typo.css
  3. 服务器:nginx

当然实在有兴趣也可以私聊,单独发你。

结语

最近十多年,独立网志一直是个人很重要的知识来源。即便如今互联网生态日趋封闭,在微信微博知乎之外稍加探索,仍然能够发现「别有洞天」——剩下的都是陈皓、阳志平、阮一峰、池建强这样的老「学究」,味道绝对独特。这个群体的内容特征,可以用陈皓先生的一句话概括:

信息的传播正确姿势,是被检索、讨论、引用、整理、补充和更新,而不是社交网络的转发、点赞、粉丝、订阅和打赏。
—— 陈皓《为什么我不在微信公众号上写文章 》

祝写作愉快!

 

基于Ruby on Rails的Redmine在Windows下安装备忘

2012 年 03 月 29 日 IT No comments

组里需要一个跟踪项目需求的系统,比照了JIRA(Confluence)、Trac、Redmine和国内的一大堆PHP平台的系统后,最终选择了基于Ruby的Redmine。不愧是Ruby社区的产物,界面清爽、配置便捷、逻辑明晰,甚是讨喜。现将安装配置步骤记录如下:

一、配置Ruby on Rails环境

  • 下载最新版的ruby1.8(1.8.7 p358,1.9 尚不被稳定版支持)和DEVELOPMENT KIT:http://rubyinstaller.org/downloads/
  • 分别安装之,安装ruby时将[将路径添加到环境变量path中]和[关联ruby文件]两个选项选中。
  • 以管理员权限cmd进命令行,执行ruby -v检查版本。
  • 如提示“‘ruby’不是内部或外部命令”,将 c:\Ruby187\bin\ 手动加入到系统PATH变量中(计算机->属性->高级系统设置->环境变量)。
  • 解压devkit,在devkit目录中执行ruby dk.rb init,ruby dk.rb install(参考:https://github.com/oneclick/rubyinstaller/wiki/development-kit
  • 执行gem install rails –include-dependencies命令。安装后,执行rails -v检查。(我得到的提示是Rails 3.2.2)

二、安装Redmine

  • 下载redmine1.3.2:http://rubyforge.org/frs/?group_id=1850. 参照http://www.redmine.org/projects/redmine/wiki/RedmineInstall 建立数据库及用户。(注意编辑database.yml时,密码和冒号(:)之间要加空格,否则rake会出错)
  • 解压redmine到devkit根目录下。进入redmine目录执行:
    gem install rake -v 1.1.0 #其它版本貌似有依赖问题
    gem install mysql
    rake generate_session_store
    gem update bundler #更新所有的gem,避免NOTE: Gem.source_index is deprecated 之类的告警

    如果提示缺少libmysql.dll,下载这个到你的ruby/bin目录。
  • 继续执行如下命令,配置初始数据库、启动服务:
    set RAILS_ENV=production
    rake db:migrate
    rake redmine:load_default_data #选择语言zh
    ruby script/server webrick -e production #启动webrick服务器

此时打开 http://localhost:3000/ 就可以访问了。默认用户名:admin,密码:admin。

三、让Redmine自动运行

gem install mongrel_service
mongrel_rails service::install -N Redmine -c C:\devkit\redmine -p 3000 -e production
sc config Redmine start= auto

四、安装截图插件

这个插件只支持Webkit内核的浏览器,但貌似是唯一写明支持1.3.2版本的截图插件。地址:http://www.redmine.org/plugins/javasript_screenshot
下载Patch for Windows:http://gnuwin32.sourceforge.net/packages/patch.htm
执行patch.exe < _form.rhtml.patch
(当然,由于版本问题,更靠谱的方式是找到c:\devkit\redmine\app\views\attachments\下的文件手动patch)

五、安装lightbox插件(直接显示附件图片)

这个插件的遗憾是在Chrome下有bug,能显示缩略图,但不能以lightbox方式显示大图(里面用到的js库是压缩过的,还不好手改)。地址:http://www.redmine.org/plugins/redmine_lightbox
注意:放到插件目录后须手动将目录名改为redmine_lightbox,否则会出错。

参考链接:

http://www.redmine.org/projects/redmine/wiki/RedmineInstall
http://www.cnblogs.com/liuxiaori/archive/2011/07/09/2101781.html
http://wenku.baidu.com/view/20c95b0bf78a6529647d5337.html

亚马逊弹力云(EC2)之LAMP部署备忘

2012 年 01 月 29 日 IT No comments

出于某些不可告人的目的,假期折腾了一把传说中的亚马逊“弹力云”(Amazon Elastic Compute Cloud,Amazon EC2)。与国内一般的“虚拟主机”或云平台不同的是,EC2提供的是基于Xen的一个全功能的虚拟机,你可以任意选装操作系统和配置服务,搭建你想要的任何服务,甚至VPN。

折腾过程中参考了以下文章:
Amazon EC2 Ubuntu折腾笔记
Amazon Web Service 雲端運算平台攻略
Building EC2 Amazon Linux with LAMP
Windows下如何用putty连接Amazon EC2实例图文教程

一、初始配置

  1. 注册、创建实例和选择系统镜像不再赘述。我选的是64位的 Amazon Linux 和 t1.micro 方案。
  2. 以上步骤完成后,可在Elastic IPs里添加一个独立IP,但注意要将这个ip挂到一个实例上,否则据说有0.1美元/小时的收费
  3. Security Groups 里开放以下端口:
    SSH:22 TCP
    HTTP:80 TCP
    HTTPS:443 TCP
    FTP:21 TCP
    62222-63333 用于支持FTP连接的被动模式(PASV),详见后文
  4. 这个时候,操起Putty,挂上转换好的ppk文件,就可以登录主机了。注意登录名为:ec2-user,不需要密码。

二、LAMP配置
1. 更新系統
# sudo yum update
2. 安裝apache, php,mysql和vsftpd。
# sudo yum install apache mysql php php-mysql mysql-server vsftpd

3. 具体配置备忘

  • sudo vi /etc/php.ini,将short_open_tag = Off改为On,再增加一行 date.timezone = “Asia/Chongqing”,保证环境的兼容。
  • sudo vi /etc/vsftpd/vsftpd.conf,把anonymous_enable=YES改为NO,在文件最后部分加上下面内容:
    pasv_enable=YES
    pasv_min_port=62222
    pasv_max_port=63333

    这样,就可以用通常的PASV方式连接ftp。

4.启动服务

# sudo service httpd start
# sudo service mysqld start
# sudo /etc/init.d/vsftpd start

这个时候,就可以sudo vi /var/www/html/index.php,写代码再:wq,用浏览器访问之前设定的Elastic IP,看看效果了。

从Outlook便笺导出到Evernote的脚本

2011 年 08 月 11 日 IT 1 comment

终于决定从Palm平台迁移到Android,memo中的数百条备忘遂成了难题。思前想后,看来只能走memo——Outlook便笺——Evernote的曲线救国战略。

而实际上Outlook转Evernote也不易找到现成的工具,几经选择关键词,才搜到如下的VB脚本:

http://www.fourteenminutes.com/code/outlook2evernote/

此脚本的最大问题是不支持中文。大约因为vbs不便直接转换为Unicode,便笺里非基本英文或数字的字符都被转成ASCII码表示,得到的enex文件以ANSI方式保存。此时如果内文里有中文,由于某些兼容不良的未知问题,会导致报错。

Evernote的enex格式其实是认UTF-8的。因此我修改了代码,除去了对字符的ASCII转换,排除了报错问题。这样生成的enex文件显然不能直接用,需要用Editplus之类的编辑器打开,手动另存成UTF-8编码,方可导入到Evernote

此外,原脚本不支持分类导出,所以顺便加了一项,将Outlook里的分类识别为Evernote里的标签。

修正版脚本下载地址:http://vdisk.weibo.com/s/wcTu ,解压后按原网站指示运行即可。

发一个小工具:WYM+

2007 年 07 月 07 日 IT No comments

个多月前写的一个小东西,因为笔记本硬盘崩溃打乱了生活节奏,现在才发上来。

WYMeditor 就是传说中的“所见即所想”之HTML编辑器。用来写东西很舒服,不用担心格式的问题,又不像LaTEX那样有上手门槛。俺深受吸引,一时兴起就给它写了一个增强——

WYM+: WYMeditor之PHP驱动兼功能增强“插件”

  • 程序名称:WYM+ (What You Mean Plus)
  • 版权许可:和WYMeditor一样
  • 使用方法:将所有文件拷入WYMeditor 0.2.* 之根目录
  • 功能与属性:
    1. 存储
      • PHP驱动,文本存储
      • 存储无刷新(类AJAX)
      • 支持快捷键CTRL+S
      • 定时自动保存(默认10秒钟)
    2. 增强快捷键(CTRL+)
      • B: 加粗
      • I: 斜体
      • U: 下划线
      • S: 保存
      • 1~6: 一号至六号heading(h1~h6)
    3. 兼容性
      • 可用于 WYMeditor 0.2.* 版本
      • 完美兼容Firefox 2.0.0.3
      • IE 6.0 下不能自动判断内容是否有更改,建议延长定时保存的时间
      • 其它环境尚未测试
  • 程序文件:
    • index.php 主界面
    • liuxun.js 存储驱动及功能增强之Javascript
    • liuxun.txt 存储所用文本文档
    • liuxun_save.php 存储驱动
    • liuxun_readme.txt 说明文档
  • 演示地址:http://liuxun.net/w/
  • WYMeditor下载地址:http://www.wymeditor.org/en/download/

下载:WYM+

发布wordpress插件:Grapheed

2007 年 05 月 04 日 IT No comments

我也不知道这算不算严格意义上的“插件”,因为它暂时没有办法用wordpress的“插件管理器”来管理:)

其实是N久以前在校内发过的老东西。现在改成的代码,略做细微修改就可以用于所有blog程序,只要空间支持php,而且有iconv和gd函数库。

Plugin Name: Grapheed
Plugin URI: http://blog.liuxun.net/?p=22
Description: 可以将http://your-blog-url/wp-grapheed.php当作图片引用,在论坛签名档或xiaonei.com涂鸦板上显示自己的最新网志
Version: 1.0
Date: 2007/05/04
Author: 刘寻
Author URI: http://liuxun.net

=== 安装步骤 ===
1.从 http://www.ugia.cn/?p=82 下载点阵字库包(fontfun.rar),将包里的simsun12.fon上传至wordpress根目录(simsun是非自由字体,请自行解决版权问题)
2.将 wp-grapheed.php 上传至wordpress根目录。即可使用。

=== 版权声明 ===
本程序部分代码(详见注释)参考自ugia.cn,版权属于ugia.cn

其余部分,放弃所有版权,可以自由使用

点这里下载

发布wordpress主题:cathayan-style

2007 年 04 月 11 日 IT No comments

由来:
一直想找一个看起来最最没有个性,而且干净,而且单屏信息量充足、节约滚屏时间的主题。久觅不得,遂看上了cathayan的blog,起了将其移植到wordpress平台的念头。

下载:
本地下载,或者到Theme viewer下载

安装:

  1. 下载解压到wp-content/themes/ 。
  2. 打开解压后目录里的压缩包 random-quotes-chinese.zip,解压里面的random-quotes-chinese.php到wp-content/plugins/ (然后可以删掉random-quotes-chinese.zip)。
  3. 去wordpress后台启用模板”Cathayan Style”和插件”Random Quotes (Chinese)”。

两个问题:

  • 字体大小:被迫使用px
    本来觉得用像素值(px)设定字体大小,使IE用户没法调整字号,实在不够人性化。但在谷歌N遍,看完N篇文章之后,终于被迫放弃其它所有支持IE调整大小的设定方法,原因如下:

    1. firefox和IE的默认字体大小不一样,然而用相对单位时,字体大小的差距会被放大,没有办法保证界面的大概的一致
    2. 用normal,small,large,x-small…的定义方法,差距同样相当大(参考http://blog.cathayan.org在firefox和IE下的效果)
    3. 在国内,绝大多数网站在IE下是不可调整字体大小的,因此绝大多数人已经事实上地失去了调整字体的习惯;只有对浏览体验比较敏感的人才会注意到字体调整功能;而——
    4. 我相信,这样的朋友一定不会错过极度优秀、开放源码的Firefox浏览器:)。(我一直使用,强烈推荐)

    目前看到唯一不使用绝对字体大小而还过得去的模式是像Web4C一样,直接使用默认大小,在两种浏览器中分别显示为15和16像素–可惜这个大小显然不适合现在的cathayan-style。

  • 用表格实现多行文字在容器里上下居中。本来cathayan 在Email里介绍了个非常牛的div实现方法
    http://realazy.org/lab/div-valign/),可惜我人品有限,调试时冒出了一些短时间内搞不定的诡异问题,只好作罢。

版权:
设计是cathayan的(其授权是“Public domain都行吧”),里面的插件“Random Quotes (Chinese)”是(修改自)xinple同学的(其授权是“没关系,随便发布 :) 加不加链接也无所谓的,能方便其他用户就好。”),呵呵,所以本Theme的版权是——Public Domain(“公共财产”)。

spam留言如火如荼,难道我只有出绝招了?

2006 年 09 月 29 日 IT 5 comments

1355comments,一月断网回来,洋鬼子的机器人已经把我这当乐园了。
现在我连留名框内容框都没有设为必填(我考虑这样的话,不是特别聪明的动物界朋友也许会偶然碰到Enter键,告诉我它们的光临),显然是不可能因此加图片验证或小学算术之类的障碍。这儿能来一两个自然生物,已经很难得了。

现有一绝招,能够在对留言界面和过程99.7%无影响的情况下基本禁绝这些spammer机器。过两天用上。

update9.30 13:32:绝招已启用,需要提醒的是,如果您待人如此地细致,心性如此地舒宁,以至于从您打开blog的单独显示页到提交一条优雅的留言,时针已经两次划过12点的位置,那么在提交之前您最好对页面做一下刷新。(而如果中间太阳已经两次从东方升起,这将意味着如果不刷新页面,留言将肯定不能抵达数据库)

发布RaN – 基于XUL的阅读/书写工具

2006 年 06 月 25 日 IT No comments

历经两个多月的碎打零敲,现在终于隆重发布 RaN 0.1beta版。

详细文档在此

演示在此

功能已经完整,可以投入社会主义知识生产、为劳动人民造福了。lx同学2006年度对国际先进技术 XUL(以及JavaScript、XML……AJAX) 的广泛、细致、深入的研究工作就此告于段落。

喜爱阅读的人有福了;喜爱书写的人有福了;感受得到命令行温情的人,如今有福了。

RaN,我的孩子,今天为父就带你上路,把一切故事说与你听。

firefox中,javascript的行为先后问题

2006 年 04 月 15 日 IT No comments

在firefox中,Ctrl-S的功能是“网页另存为”。而我一直很想给blog实现这个功能:写日志时按Ctrl+S即可提交表单内容,同时(最关键的是)不弹出网页另存为的对话框。
要阻止“另存为”对话框,自然只能是在javascript中使用return false。而要实现提交表单功能,又必须捕获键盘事件Ctrl-S,使其有所执行。
我第一版的代码是:

<body onkeydown=”submitForm(event);return false;”>结果发现文本框不能输入英文字符。显然的,它把所有的键盘输入都return false了。另据实际经验,return false写在函数判断里面是无用的。我想到在submitform函数里做一个“转发器”,专事将键盘输入的东西还原为字符写入到文本框内。先做测试,有第二版代码:
<body onkeydown=”test(‘我发送了表单,还把其它键盘输入转发了,耶。’);return false;”>结果发现,“Ctrl-S调出另存为对话框”这个行为几乎是优先于所有js函数调用和输出的。也就是说,只要return false前面有函数调用和输出,那对话框必然先被调出;而把函数调用和输出写在后面又显然无效。问题相当严重。幸好没有着急写“转发器”。
谷歌”了一下,看到有人曰(http://www.codingforums.com/showthread.php?t=69761):

Any key combinations with special meanings to either the operating system or the browser are NOT passed to the web page and therefore cannot be handled using Javascript. To be able to process Ctrl-G in Javascript you would have to disable that option in your browser first. For it to work for your visitors they would have to disable it in their browser.

顿觉心灰意冷。但又确实知道writely已经实现了对Ctrl-S的“劫持”。遂坚定信心,多次尝试,终于得到正解:

<body onkeydown=”if(event.ctrlKey &#038;& event.keyCode==83){document.forms[‘write’].submit();return false;}”>原来唯独表单提交这一动作可以赶在“另存为”框弹出之前完成。至此问题暂时解决。
方法缺陷是——如果把正解中onkeydown的值包装成一个函数调用,则return false无效。因此无法实现代码结构化,难以扩展快捷键操作的功能。

(不知道这篇帖子怎么会招来那么多 online poker 的spam留言,被迫关掉回复: if(!empty($p_logid) && $p_logid!=185){//提交留言})