小子 发布的文章

uploadify的使用

html

Upload photos

Uploading…
Empty the list

javascript

$(function() {
	var fileRemoved = false;
	function reset() {
		$("#fileInputQueue, #upload-tools").hide();
		$("#status").empty().hide();
		$("#doc-loading").hide();
	}
	$('#fileInput').uploadify({
		uploader: 'static/js/uploadify/uploadify.swf',
		script: 'uploadify.php',
		buttonImg: 'static/image/button.png',
		// rollover: true,
		width: 100,
		height: 30,
		cancelImg: 'static/image/cancel.png',
		// auto: false,
		multi: true,
		// method: 'POST',
		fileDesc: 'Photo(*.jpg; *.jpeg; *.gif; *.png)',
		fileExt: '*.jpg; *.jpeg; *.gif; *.png',
		sizeLimit: 31457280,
		// displayData: 'percentage',
		scriptAccess: 'always',
		scriptData: {
		},
		onSelect: function(event, queueID, fileObj) {
			if (parseInt(fileObj.size) > parseInt(31457280)) {
				size_limit = Math.round(31457280 / 1048576 * 100000) / 100000;
				//上传文件大小超出限制
				fileRemoved = true;
				return false;
			}
			$("#fileInputQueue, #upload-tools").fadeIn();
			if (!fileRemoved) {
				//成功选择文件
			} else {
				//...
			}
		},
		onCancel: function() {
			if ($('.uploadifyQueueItem').size() === 1) {
				reset();
			}
		},
		onClearQueue: function() {
			reset();
		},
		onComplete: function(evt, queueID, fileObj, response, data) {
			//console.log(eval('(' + response + ')').pid);
			//$.parseJSON
			$("#fileInput" + queueID + " .uploadifyProgressBar").css("background", "#6AE16A");
			$("#fileInput" + queueID + " .cancel").hide();
			return false;
		},
		onAllComplete: function(evt, queueID, fileObj, response, data) {
			//全部上传成功
			$("#upload-tools, #doc-loading").hide();
		}
	});
	$('#upload-button').click(function() {
		$('#fileInput').uploadifyUpload();
		$('#upload-tools').hide();
		$("#fileInputQueue").before($("#doc-loading").show());
	});
});

css

.uploadifyQueue{border:1px solid #CCC;display:none;max-height:300px;margin:16px 0 24px 0;overflow:auto;zoom:1;}
.uploadifyQueueItem{border-bottom:1px solid #E2E2E2;font-weight:bold;padding:8px;}.uploadifyQueueItem .cancel{float:right;}
.uploadifyQueueItem:last-child{border-bottom:0;}
.uploadifyError{background-color:#eeacac !important;color:#cc0000 !important;}
.uploadifyProgress{background:#EEE;height:6px;margin-top:8px;overflow:hidden;width:100%;zoom:1;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);-webkit-box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 0 1px rgba(0, 0, 0, 0.05);}
.uploadifyProgressBar{background:#333;height:6px;margin-left:-1px;width:1px;}
a.delete-item{background:url('static/images/icons/delete.png') center left no-repeat;padding-left:18px;line-height:18px;}

google地图overlay

就是添加一个自定义的层,使用方法(初始化一个):
new FastMarker();

function FastMarker(latlng, options) {
	this.latlng = latlng;
	this.options = options || {};
}
FastMarker.prototype = new google.maps.OverlayView();
FastMarker.prototype.onAdd = function(map) {
	var div = document.createElement('div');
	if (this.options.className) div.className = this.options.className;
	if (this.options.html) div.innerHTML = this.options.html;
	if (this.options.dom) div.appendChild(this.options.dom);
	if (this.options.id) div.id = this.options.id;
	div.style.position = 'absolute';
	this.map = map;
	this.div = div;
	var events = ['click', 'dblclick', 'contextmenu', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'mousewheel', 'DOMMouseScroll'];
	for (var i = 0; i < events.length; i++)
	 google.maps.event.addDomListener(div, events[i], this.stop, false);
	var panes = this.getPanes();
	panes.overlayLayer.appendChild(div);
};
FastMarker.prototype.draw = function(force) {
	var point = this.getProjection().fromLatLngToDivPixel(this.latlng);
	this.div.style.top = (point.y) + 'px';
	this.div.style.left = (point.x) + 'px';
};
FastMarker.prototype.onRemove = function() {
	google.maps.event.clearInstanceListeners(this.div);
	this.div.parentNode.removeChild(this.div);
	this.div = null;
};
FastMarker.prototype.getPosition = function() {
	return this.latlng;
};
FastMarker.prototype.stop = function(e) {
	if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	} else {
		e.stopPropagation();
	}
};

重置mysql root密码

这里要说的是忘记root密码之后怎么去改密码。

killall -TERM mysqld #关闭mysql进程
/usr/local/mysql/bin/mysqld_safe --skip-grant-tables  --skip-networking & #安全模式启动mysql
mysql #直接mysql命令进去

注意该模式下进去是没有grant权限的,我们只能直接对表进行操作,下面是sql语句

USE mysql;
UPDATE user set password=password('new password') WHERE user='root';
FLUSH PRIVILEGES; #刷新权限

但是遇到徐老师这样的草泥马,把表清空了,N多的字段啊,果断从本地mysql的表里面搞出sql语句,插进去:

USE mysql;
INSERT INTO `user` VALUES ('%', 'root', PASSWORD('your password'), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
INSERT INTO `user` VALUES ('localhost', 'root', PASSWORD('your password'), 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', '', '', '', '', 0, 0, 0, 0);
FLUSH PRIVILEGES; #刷新权限

svn杂记

chmod +x hooks/pre-commit

svn强制要求填写注释

./hooks/pre-commit

REPOS="$1"
TXN="$2"

SVNLOOK=/usr/bin/svnlook

LOGMSG=`$SVNLOOK log -t $TXN $REPOS | wc -m`
if [ "$LOGMSG" -lt 48 ]
then
	echo "\n至少输入4个汉字" >&2
	exit 1
fi
exit 0

svn自动加版本号

enable-auto-props = yes
[auto-props]
*.php = svn:keywords=Date Author Id Revision HeadURL
*.css = svn:keywords=Date Author Id Revision HeadURL
*.html = svn:keywords=Date Author Id Revision HeadURL
*.js = svn:keywords=Date Author Id Revision HeadURL

svn同步到web目录

svn co file:///var/www/svn/sandbox /var/www/html/
#./hooks/pre-commit
svn up /var/www/html/

javascript判断数据类型

js的一切皆对象,constructor(构造函数)

alert([].constructor == Array);
alert({}.constructor == Object);
alert("string".constructor == String);
alert((123).constructor == Number);
alert(true.constructor == Boolean);

python多线程读取文件

网上只有多进程,有木有?理解和书写代码花了一天的时间,有木有?

多线程分块读取

# -*- coding: utf-8 -*-
import os,time
import threading

rlock = threading.RLock()
curPosition = 0

class Reader(threading.Thread):
    def __init__(self, res):
        self.res = res
        super(Reader, self).__init__()
    def run(self):
        global curPosition
        fstream = open(self.res.fileName, 'r')
        while True:
            #锁定共享资源
            rlock.acquire()
            startPosition = curPosition
            curPosition = endPosition = (startPosition + self.res.blockSize) if (startPosition + self.res.blockSize) < self.res.fileSize else self.res.fileSize
            #释放共享资源
            rlock.release()
            if startPosition == self.res.fileSize:
                break
            elif startPosition != 0:
                fstream.seek(startPosition)
                fstream.readline()
            pos = fstream.tell()
            while pos < endPosition:
                line = fstream.readline()
                #处理line
                #print(line.strip())
                pos = fstream.tell()
        fstream.close()

class Resource(object):
    def __init__(self, fileName):
        self.fileName = fileName
        #分块大小
        self.blockSize = 100000000
        self.getFileSize()
    #计算文件大小
    def getFileSize(self):
        fstream = open(self.fileName, 'r')
        fstream.seek(0, os.SEEK_END)
        self.fileSize = fstream.tell()
        fstream.close()

if __name__ == '__main__':
    starttime = time.clock()
    #线程数
    threadNum = 4
    #文件
    fileName = 'IPData.txt';
    res = Resource(fileName)
    threads = []
    #初始化线程
    for i in range(threadNum):
        rdr = Reader(res)
        threads.append(rdr)
    #开始线程
    for i in range(threadNum):
        threads[i].start()
    #结束线程
    for i in range(threadNum):
        threads[i].join()

    print(time.clock() - starttime)

多线程按行读取

#在上面的代码中使用open(file, 'r')产生的句柄每次在线程锁里面pop()就好了。

python之排序算法

快速排序

取一个元素,剩余元素与这个元素比较,小的放左边,大的放右边,依此循环嵌套,以下是实现的代码:

lis = [18,2,4,54,64,56,77]
def quicksort(lis):
	return [] if lis == [] else quicksort([x for x in lis[1:] if x < lis[0]]) + [lis[0]] + quicksort([x for x in lis[1:] if x >= lis[0]])
print(quicksort(lis))

Oracle sql杂记

一些注意点

-- || 连接字符串和字段
-- 所有数据区分大小写
-- IN 语句的范围内存在NULL对结果无影响
-- NOT IN 语句中范围内存在NULL,则不返回任何数据
-- NULL计算后的值还是NULL
-- 日期 - 数字 = 日期
-- 日期 - 日期 = 数字

一些函数

DECODE(a, 1, '男', 2, '女') -- 你懂的
NVL(a, 0) -- 字段为NULL的值
MONTHS_BETWEEN(a, b) -- a,b两个日期之间相差的月数
ADD_MONTHS(sysdate, 2) -- 在日期上加上指定的月数
NEXT_DAY(sysdate, '星期一') -- 下一个星期一
LAST_DAY(sysdate) -- 一个月的最后一天
WITH sql1 as (SELECT * FROM test) SELECT * FROM sql1 WHERE  -- with语句

select lpad('tech', 2) from dual -- te
select lpad('tech', 8, '0') from dual -- 0000tech

TRUNC(TO_DATE('24-Nov-1999 08:00 pm', 'dd-mon-yyyy hh:mi am')) -- '24-Nov-1999 12:00:00 am' 
TRUNC(TO_DATE('24-Nov-1999 08:37 pm', 'dd-mon-yyyy hh:mi am','hh')) -- '24-Nov-1999 08:00:00 am'

TRUNC(89.985, 2) -- 89.98
TRUNC(89.985) -- 89
TRUNC(89.985, -1) -- 80

select t.Name, case t.id when 1 then 'zhao' when 2 then 'qian' when 3 then 'sun' else 'li' end "fname" from T t

WMSYS.WM_CONCAT -- 行转列

一些常见的报错

未明确定义列

这一般只有在有子查询的sql语句中才会出现的错误,以为子查询的结果中有同名的列。如:

select to_char(dateline, 'yyyy-mm-dd') as dateline from test_table

这样的sql语句作为子句的时候,ORACLE会认为有两个同名的dateline列。解决办法就是将as后面的dateline改为其他的,如:fdateline

php杂记

逻辑运算

对于整个表达式来说:

或(|| or)两个同时为真则为真
与(&& and)有一个为真则为真
#这里可以用三目运算实现,这里只是为了说明逻辑关系。
$data = array(
    array('a'=>'a','b'=>''),
    array('a'=>'','b'=>'b'),
    array('a'=>'a','b'=>'b')
);
while(list(,$item) = each($data)) {
    ($item['a'] and $item['b']) and ($result = $item['a'] . $item['b']) or ($item['a'] and ($result = $item['a'])) or ($item['b'] and ($result = $item['b']));
    var_dump($result);
}
// string(1) "a"
// string(1) "b"
// string(2) "ab"

位运算

位的偏移运算,2进制

//   1
// 100 化成十进制 2的平方 = 4
echo 1<<2;

类型自动转换

可悲啊,在公司的群里面,发了下面的一道,居然没有一个人去尝试执行结果。

var_dump(0 == 'string'); // true
var_dump(true == 'string'); // true
var_dump(0 == false); //true

都是true?相信后两个的执行结果都能理解,为什么第一个也是true呢?
intval('string'); //0 看到木有,当字符串跟数字比较的时候,php会自动转换字符串为数字,啊哈。再来看看这个 intval('2string'); //2

创建多级目录

mkdir('/test1/test2', 0777, true); //最后一个参数设为true就可以了

正则杂记

验证手机号码

中国移动号段 1340-1348 135 136 137 138 139 150 151 152 157 158 159 187 188 147
中国联通号段 130 131 132 155 156 185 186 145
中国电信号段 133 1349 153 180 189
其他 181 182 183 184
^(13[0-9]|15[0-9]|14[0-9]|18[0-9])\d{8}$
^(1[3-5][0-9]|18[0-9])\d{8}$
^(1[3-58])\d{9}$

验证邮箱

^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,4}$

验证日期

^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$

验证时间

格式:时:分:秒

^([01]?\d|2[0-3]):[0-5]?\d:[0-5]?\d$

验证url

^\b(((https?|ftp):\/\/)?[-a-z0-9]+(\.[-a-z0-9]+)*\.(?:com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|[a-z][a-z]|((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d))\b(\/[-a-z0-9_:\@&?=+,.!\/~%\$]*)?)$

环视

以前一直没明白正则的环视的使用环境,网上的那些例子不用环视也能写出来,而且更容易理解。其实,在需要匹配的字符串有长度限制的时候,而且有其他的特殊要求的时候,用环视能很好的解决问题。这样说,还太抽象了,下面看例子:

#有待更新

一些注册表单会用到的正则

用户名(允许字母、数字、下划线、减号、中文)

^[A-Za-z0-9_\-\u4e00-\u9fa5]+$
^[A-Za-z0-9_\-\x{4e00}-\x{9fa5}]+$

真实姓名(允许字母、中文)

^[A-Za-z\u4e00-\u9fa5]+$    // js
^[A-Za-z\x{4e00}-\x{9fa5}]+$    // php

http及https的url

^http[s]?:\/\/([\w-]+\.)+[\w-]+([\w-./?%&=]*)?$

IP v4,下面把四个展开写是为了看起来比较直观,其实可以写的更短一点。

^(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)$

验证子网掩码

^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$

flush这个函数

这个函数呢,在每个浏览器下的作用结果是不一样的:

  • IE下,接受到256个字节之后才开始显示
  • Chrome下,接受到2048个字节之后才开始显示

$my_string_var = 'test...';
echo '';
for($i = 1, $i <7, $i++) {
	echo str_pad($my_string_var, 2048, ' ');
	@ob_flush();
	flush();
	sleep(1);
}

file_get_contents这个函数

当要获取的URL资源不存在的时候,这个函数在linux和windows下返回的结果是不一样的。

在windows下,当访问的页面返回404的时候,file_get_contents不会去获取response的body的值,会返回false

而在linux下他会去获取404的HTML页面的内容。

上述情况和网络环境有关。

所以去判断一个远程文件是否存在的时候,不能使用file_get_contents($url,0,null,0,1),而应当去获取response的头状态。

css杂记

css margin重叠的问题

是不是经常有的时候子标签的margin变成了父标签的margin了,嗯哼,试试下面的。


/*任选一个*/
overflow:hidden;
zoom:1;
border-top: 1px solid #ccc;

css baseline

是不是a标签下的img标签下方都是有嗲空隙的?那是因为img标签是内联元素,默认是按照baseline对齐的,犹如那英文四线格中的第三根线。解决办法:

  1. 设置成块级元素
  2. 设置垂直对齐方式

clearfix

/*清除浮动的良药啊*/
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
.clearfix{*zoom:1;}

IE6,7下z-index失效

...

lxml 加 beautifulsoup with 多线程(Snail)

抓取的时候,去获取网页中指定的内容,最基本的办法就是使用正则获取,但要是要处理的网站多了,写正则岂不写死。于是哥就写了个类,看代码:

蜗牛号基类

# -*- coding: utf-8 -*-
import threading, Queue
import urllib2, cookielib
from lxml.html.soupparser import fromstring

class Snail(threading.Thread):
	def __init__(self , *argv):
		self.buildBrowser(*argv)
		super(Snail, self).__init__()
	def buildBrowser(self, *argv):
		self.cookie = cookielib.CookieJar()
		opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))
		opener.addheaders = []
		opener.addheaders.append(('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.904.0 Safari/535.7'))
		opener.addheaders.append(('Accept', '*/*'))
		opener.addheaders = opener.addheaders + [t for t in argv]
		urllib2.install_opener(opener)
	def parse(self, link, data = None):
		content = self.handle(link, data).read()
		tree = fromstring(content)
		return tree
	def handle(self, link, data = None):
		return urllib2.urlopen(urllib2.Request(link, data))
	def save(self):
		pass
snail = Snail(('Cookie','这边可以自己填写'))

需要lxml模块支持,可以到 http://lxml.de/ 下载,centos下的安装方法:

yum -y install libxml2-dev libxslt-devel
cd /usr/local/src
wget http://lxml.de/files/lxml-2.3.2.tgz
tar vzxf lxml-2.3.2.tgz
cd lxml-2.3.2
python setup.py install

cd ../
wget http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.2.0.tar.gz
tar vzxf BeautifulSoup-3.2.0.tar.gz
cd BeautifulSoup-3.2.0
python setup.py install

基类的使用实例

线程锁rlock

# -*- coding: utf-8 -*-
from Snail import Snail
import threading

rlock = threading.RLock()
class Mphone(Snail):
	def __init__(self):
		super(Snail, self).__init__()
	def process(self, numhead):
		#做点实际处理的事情
		pass
	def run(self):
		while True:
			rlock.acquire()
			#线程锁锁定资源的时候,取值
			rlock.release()
			#可以在某个特定条件下 break 掉循环
			self.process(numhead)
if __name__ == '__main__':
	threadnum = 4
	threads = []
	for i in range(threadnum):
		mphone = Mphone()
		threads.append(mphone)
	for i in range(threadnum):
		threads[i].start()
	for i in range(threadnum):
		threads[i].join()

可能会遇到的一些问题

TypeError: cannot concatenate 'str' and 'NoneType' objects
#解决办法
unicode('这边是要解析的字符串', 'utf-8', errors='ignore')