python和tkinter写了一个豆瓣音乐下载工具

前天自己的阿里妈妈账号再次被冻结了,好不容易有5000多收入,一下又没了。

没办法,还是拿自己的一点小手艺,赚点吃饭的钱,花一天时间写了这个小工具。

douban-music-downloader

可以下载豆瓣的红心兆赫、豆瓣小站大部分专辑。下载任意兆赫的功能没有写,时间有限。

douban-downloader-main

这个程序我希望能够收费提供,所以虽然公开代码,但并不希望你生成无限制的exe免费提供,请谅解。

Tkinter是single-threaded,记住这一点比较重要。 对于耗时的操作,比如下载,需要创建新的线程来完成。

我在程序启动时创建了5个daemon线程,用于下载MP3,一般,5个线程就足够达到较好的下载效率。

windows可执行文件 (请注意,文件夹名称中不能存在中文)

下载源代码 (如果你做了任何改进,欢迎提交给我。 :))

Python命名空间和作用域的基本认识和一点小魔法

作为初学者,简单总结自己对Python命名空间(namespace)和作用域(scope)的认识。

Python在名称空间搜寻变量和函数的顺序可以认为是:

函数内部 -> (嵌套)父函数内部 -> 模块内部 ->  built_in内置模块

1. 函数内部(local)

简单举例说明:

x = 123

def func():
    x = 456
    print 'inner x =', x

func()
print 'outer x =', x

输出:

inner x = 456
outer x = 123

模块级变量x的值是123,而在函数func内部,local变量x的值是456。可以看到,函数是没有改变外部x的值的。

2. 父函数内部 继续阅读Python命名空间和作用域的基本认识和一点小魔法

python sys.setdefaultencoding的一点小魔法

python中调用sys.setdefaultencoding方法可以修改默认编码。

但是这个方法调用有一些特别。在python解释器中执行:

>>> import sys
>>> dir(sys)

输出为:

['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__name__', '__p
ackage__', '__plen', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache
', '_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', 'builtin
_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayh
ook', 'dllhandle', 'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type', '
excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_
repr_style', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding',
'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace', 'getw
indowsversion', 'hexversion', 'long_info', 'maxint', 'maxsize', 'maxunicode', 'm
eta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', '
prefix', 'ps1', 'ps2', 'py3kwarning', 'setcheckinterval', 'setprofile', 'setrecu
rsionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', '
version_info', 'warnoptions', 'winver']

会看到实际上sys模块中并没有这个所谓的setdefaultencoding方法。

文档中描述为:这个方法是为site模块的调用而准备的,而一旦被调用之后,它将会被从sys的名称空间中抹掉。

This function is only intended to be used by the site module 
implementation and, where needed, by sitecustomize. Once used 
by the site module, it is removed from the sys module’s namespace.

而如果确实有需要调用这个方法,可以使用reload再次导入这个模块:

import sys  

print 'old encoding value:', sys.getdefaultencoding()
reload(sys)
sys.setdefaultencoding('utf8')
print 'new encoding value:', sys.getdefaultencoding()

输出为:

old encoding value: ascii
new encoding value: utf8

VPS迁移后重建MySQL ISAM全文索引

前文我简单总计了web应用的迁移过程,这里补充说明一下数据库迁移后的全文索引重建问题。

数据库导入到MySQL之后,如果有ISAM fulltext表,需要重建索引。

cd /var/lib/mysql/music

找到对应数据表的索引文件,这里music是我的数据库名称(db_name)。

对于较小的表,直接执行:

myisamchk –recover –ft_min_word_len=2 –ft_max_word_len=20 bt.MYI

为了让用户能搜索到较短的人名,比如“许巍”,我把单词的最短长度设定为2。

对于超大的表,直接执行上述命令就不行了,会得到一个错误提示:

myisamchk error: myisam_sort_buffer_size is too small

这时需要为myisamchk命令添加–force和–safe-recover两个参数。 比如,这里我为一个百万记录的表重建索引,则执行:

myisamchk –recover –force –safe-recover –ft_min_word_len=2 –ft_max_word_len=20 albums_fulltext.MYI

把自己的两个网站迁移部署到Linode VPS

手上买了3个VPS ,一个用来放网站,另外两个用来跑自己的程序(不是用于扫肉鸡之类… )。

最近yardVPS和photonVPS的廉价VPS抽风得厉害。 晚上9点到11点这个高峰期,慢得离奇。

无奈,买了新的Linode VPS。 日本机房,延迟小,内存和硬盘更大,一个月大约是24美元。

迁移网站到一个新服务器上,需要完成的几个步骤是:

1. 基本的环境配置

首先需要进行最基本的安全配置,比如进行必要的更新,修改ssh端口号,禁止root远程登录ssh。

接着可以安装apache2、php5、MySQL,因为我的网站http://www.fachun.net 使用了django框架,还需要安装django、以及它所要用到python-mysqldb、localurl等。

2. 转移web目录下的文件

假设你的web文件位于/var/www下,可以整体打包它,切换到/var/,执行类似:

tar czvf www.tar.gz www/*

等打包结束,再将这个www.tar.gz移动到某个站点目录下,比如放到博客https://www.lijiejie.com/www.tar.gz,然后在新的vps上下载它:

wget https://www.lijiejie.com/www.tar.gz

下载后解压即可。

3. 打包apache2和MySQL配置文件

操作与上面类似,把/etc/apache2/和/etc/mysql下面的文件打包并下载到新的VPS上,完成解压和覆盖。

4. 导出MySQL数据库

直接把数据库导出到站点web目录下:

mysqldump -uroot -p db_name > /var/www/web_folder/db_name.sql

在新的VPS上下载并导入这些数据。

5. 修改本地hosts,测试站点是否正常工作

在新的VPS上逐个启用站点:

a2ensite your_site_name

service apache2 reload

这个时候,虚拟主机已经生效了,但我们不要忙修改DNS,先修改本地hosts文件,把域名解析到这个新的VPS,查看站点能否正常工作。如果有问题,可以调试解决。

确认没有问题,就可以去修改DNS,把域名解析到这个新VPS的IP。

因为DNS生效需要一定的时间,这时候先不要忙暂停旧VPS上的网站。