小子 发布的文章

获取wav时长

duration = filesize / byterate

获取wav文件的byterate

wav-sound-format.gif

图片来自:WAVE PCM soundfile format

<?php

function ascii2hex($ascii) {
    $ascii = strrev($ascii);
    $hex = '';
    for ($i = 0; $i < strlen($ascii); $i++) {
        $byte = dechex(ord($ascii{$i}));
        $byte = str_pad($byte, 2, '0', STR_PAD_LEFT);
        $hex .= $byte;
    }
    return $hex;
}

$file = fopen('test.wav', 'rb');
fseek($file, 28);
$byterate = fread($file, 4);
fclose($file);

$byterate = hexdec(ascii2hex($byterate));

echo filesize('test.wav') / $byterate / 60 . PHP_EOL;

postfix自动回复配置

增加hook

修改/etc/postfix/master.cf

myhook unix - n n - - pipe
  flags=F user=nobody argv=/usr/bin/python /path/to/script.py ${sender} ${size} ${recipient}
# 第二行前面一定要有空格

修改/etc/postfix/transport

example.com myhook:
# 最后是冒号

执行命令postmap /etc/postfix/transport

修改/etc/postfix/main.cf

transport_maps = hash:/etc/postfix/transport

自动回复脚本

这里我用的是python

#!/usr/bin/env python

import sys, smtplib, re

content = sys.stdin.read()
# 如果postfix设置了virtual,${sender}将不是我们所需要的,所以这里从mail的内容中获取
froms = re.findall('^From:\s+(.*?)\n', content, re.I | re.M)
tos = re.findall('^To:\s+(.*?)\n', content, re.I | re.M)
subjects = re.findall('^Subject:\s+(.*?)\n', content, re.I | re.M)

msg = 'From: %s\r\nTo: %s\r\nReply-To:%s\r\n\r\n' % (tos[0], froms[0], froms[0])

msg += 'this is a test reply.'

mail = smtplib.SMTP('localhost')
mail.sendmail(tos[0], froms[0], msg)
mail.quit()

自定义url scheme

就是实现类似thunder://svn://tencent://的链接,然后点击链接的时候,会弹出询问是否要启动应用程序。

windows下的实现

google搜索到,windows下只需要修改注册表就可以了,以下是导出的svn的

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\svn]
@="URL:SVN Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\svn\DefaultIcon]
@="C:\\Program Files\\TortoiseSVN\\bin\\TortoiseProc.exe"

[HKEY_CLASSES_ROOT\svn\shell]

[HKEY_CLASSES_ROOT\svn\shell\open]

[HKEY_CLASSES_ROOT\svn\shell\open\command]
@="C:\\Program Files\\TortoiseSVN\\bin\\TortoiseProc.exe /command:repobrowser /path:\"%1\""

php拾遗

php中的三目运算

// 可省略第一个,写了这么长时间的php,还真不知道,以前只知道C#的双问号,还特地搜过php是否有类似的操作符的
// laravel uri.php 56行
trim($uri, '/') ?: '/';

array_diff

两个单元仅在 (string) $elem1 === (string) $elem2 时被认为是相同的。

不直接使用 array_filter,是因为它默认根据元素的bool值来的

<?php
if(0) {
    var_dump((string)true); // "1"
    var_dump((string)false); // ""
}
// laravel uri.php 102行
array_diff($segments, array(''));</code></pre><h3>php对象链</h3><pre class="prettyprint"><code class="language-php">// php5.3会出错, 5.4正常:(new A())->a();
// laravel helpers.php 499行
function with($object) {
    return $object;
}

with(new A()) -> a();

svn的authz配置

设置svn目录

/project
├── trunk
├── tags
├── branches

  • super 最大级别的比如boss,不需要开发,所有的给读的权限
  • manager 项目的管理员,有读写权限,有打tag的权限
  • developer 开发人员,有读写权限,没打tag的权限
  • packer 打包人员,只有读tag的权限

[groups]
g_super = aaa
g_manager = bbb
g_developer = ccc,ddd
g_packer = eee


[project:/]
@g_super = r
@g_manager = rw
* =

[project:/trunk]
@g_super = r
@g_manager = rw
@g_developer = rw
* =

[project:/branches]
@g_super = r
@g_manager = rw
@g_developer = rw
* =

[project:/tags]
@g_super = r
@g_manager = rw
@g_developer = r
@g_packer = r
* =

php中正确获取程序路径

首先说说$_SERVER['DOCUMENT_ROOT']这个变量,这个变量是由apache的配置文件里面的documentroot决定的(当然你要是用的不是apache,那就是由其他服务器决定的),一般情况之下还是可靠的,近日,用到了apache中的alias,然后alias的目录不在virtualhost的documentroot中,于是alias的目录中用$_SERVER['DOCUMENT_ROOT']来计算文件的引入路径就出错了。

看看几个较流行的框架

Slim

public function root() {
        return rtrim($_SERVER['DOCUMENT_ROOT'], '/') . rtrim($this->request->getRootUri(), '/') . '/';
    }

Laravel

if ( ! defined('DS')) {
	define('DS', DIRECTORY_SEPARATOR);
}

$GLOBALS['laravel_paths']['base'] = __DIR__.DS;

于是slim嗝屁之,laravel依然风骚。由于laravel要求最低是php5.3,而__DIR__是5.3才有的,那在php之前的版本下使用dirname(__FILE__)就好了。

expect的使用

expect可以自动化执行需要交互的命令。

安装

yum -y install expect

使用

创建一个文件test.exp

#!/usr/bin/env expect
spawn php go-pear.phar
expect ":"
send "\n"
interact
expect test.exp

python版本

pip install pexpect
#!/usr/bin/env python
# encoding: utf-8
import pexpect

cmd = 'php go-pear.phar'
child = pexpect.spawn(cmd, timeout=None)
child.expect(':')
child.sendline('')
# child.interact()
child.close()

cocoa项目中嵌入python

添加链接库:
A5C731A1-10A4-46B3-AF78-A32AB4AF9CA2.png

文件结构:
QQ20130107-1.png

代码

main.m

#import 
#import 

int main(int argc, char *argv[]) {
    Py_Initialize();
    // 这里面自己定义一个hello函数(python的)好了
    PyRun_SimpleString("import hmac, binascii\n"
                       "from itertools import izip, cycle\n");
    int result = NSApplicationMain(argc, (const char **)argv);
    Py_Finalize();
    return result;
}

控制器里面直接使用就好了

- (IBAction)runpy:(id)sender {
    PyObject *m, *f, *a, *k;

    m = PyImport_ImportModule("__main__");
    f = PyObject_GetAttrString(m, "hello");
    a = PyTuple_Pack(1, PyString_FromString([[_email stringValue] UTF8String]));
    k = PyObject_CallObject(f, a);
    
    // NSLog(@"%@", [NSString stringWithUTF8String:PyString_AsString(k)]);
    [_keycode setStringValue:[NSString stringWithUTF8String:PyString_AsString(k)]];
    
    Py_DECREF(k);
    Py_DECREF(a);
    Py_DECREF(f);
    Py_DECREF(m);
}

JSONKit杂记

记录

写程序时遇到的几个问题,记录一下。

  • 加到project里面的时候不能加在子目录下
  • 编译的时候需要指定JSONKit.m的compiler flags "-fno-objc-arc"

吐槽

object-c的函数长度真心是伤不起的,截图留念!

sublime text2 svn sftp plugin keygen

第一次写object-c程序,写了好几个小时才写出来这么个小东西。

  1. 反编译pyc文件,查看算法
  2. 写出key生成的算法
  3. 将python嵌入Object-C,得到最终的程序

将email和生成的key写入插件目录下的sublime-setting文件。

"email": "your email",
"product_key": "the key",

下载地址:svn-sftp-keygen.app.zip

2013-03-19 增加 邮件获取注册码

发送任何邮件到 bot[at]tool.lu, 系统会自动生成注册码,并回复到你的发件邮箱

2013-04-24 增加 osx10.7支持,优化算法机

QQ20130424-1.png
下载地址:svn-keygen.app.zip

mac chrome下input submit样式

input submit指定样式不起作用

QQ20121209-1.png

There will be three new appearance constants for buttons. They are push-button, bevel-button and button. input will be using push-button by default. This constant maps to the Aqua system button. When this appearance constant is specified, the only way to disable the Aqua look will be by setting the appearance constant to none (which will give you a completely blank slate on which to build your own button look) or by specifying your own background and border properties. Specifying the background/border will result in the Aqua appearance being disabled and a more platform-neutral look being used.

来自:https://www.webkit.org/blog/28/buttons/

解决办法

/* 指定border或者background就可以了 */
input[type=submit] {
	border: 1px solid #CCC;
	/* background: red; */
}

自动禁用连接数高的IP

python代码

由于最近服务器受到大流量的攻击,于是写了该脚本。

#! /usr/bin/env python
# encoding: utf-8

import os, time

command = "/bin/netstat -antp|grep :80|awk ' ''{print $5}'|awk -F: '{print $1}'|sort -r|uniq -c|sort -n -k1 -r"
maxconn = 150

handle = os.popen(command)
for line in handle:
	fields = line.strip().split(' ')
	if len(fields) != 2:
		continue
	conn, ip = fields
	# 由于我们使用的是nginx作为反向代理,访问apache,所以这里要加上127.0.0.1
	if int(conn) > maxconn and ip != '127.0.0.1':
		print(time.strftime('%Y-%m-%d %X'), conn, ip)
		# 这里只会临时将ip拒绝,当重新启动iptables服务的时候失效
		os.system('/sbin/iptables -I INPUT -s %s/24 -j DROP' % ip)
handle.close()

定时执行

将python文件加入crontab中即可。

SimpleIni修改my.cnf

为了实现自动化修改mysql的配置文件,使用C++程序对改ini样式的文件进行修改

#include "SimpleIni.h"
int main(int argc, char* argv[]) {
	CSimpleIniA ini;
	const char* filename = "/etc/my.cnf";
	ini.SetUnicode();
	ini.LoadFile(filename);
	ini.SetValue("mysqld", "server-id", "1");
	ini.SetValue("mysqld", "binlog-do-db", "mydb");
	ini.SaveFile(filename, false);

	return 0;
}