Compress folders by 7z

@ECHO OFF
ECHO.
ECHO Folder Compress and Organization
ECHO version: 0.1	2011-11-20

:: Number latest folders to be reserved.
SET RESERVED_COUNT=4

SETLOCAL ENABLEDELAYEDEXPANSION
SET /A COUNT=0
FOR /F %%i IN ('DIR /B /A:D /O:-D') DO (
    SET /A COUNT=COUNT+1
    IF !COUNT! GTR %RESERVED_COUNT% (
        ECHO Delete: %%i
        RMDIR /S %%i
        ECHO.
    ) ELSE (
        ECHO.
        ECHO ^<^<^< Compressing %%i
        "C:\Program Files\7-Zip\7z.exe" a %%i.7z .\%%i\*
        IF NOT "%ERRORLEVEL%" == "0" (
            CALL:reportError %%i
            GOTO:EOF
        )
    )
)
ENDLOCAL

ECHO.
ECHO Complete Success.
GOTO:EOF

:reportError
ECHO.
ECHO Error occur when compressing %~1
GOTO:EOF

保存此脚本为pack.bat,设定需要保留的最新目录数(RESERVED_COUNT),放在需要压缩的文件夹目录下。

UCenter: Fix Page Not Found Error on Linux

安装了Discuz! X1.5版本后打开UCenter tab的时候出现如下错误:

网上有些论坛管理员说有两种解决方法:
1. 修改/config/config_ucenter.php文件中的UC_APPID参数为2
2. 同样修改以上文件中的UC_IP参数为空,即改为”

我这里的情况和他们的不一样,错误显示的地址为/comsenz/discuzx/uc_server/admin.php,但是实际上地址为/comsenz/DiscuzX/uc_server/admin.php,我把/uc_server/admin.php文件中的:

define('UC_API', strtolower((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http')
.'://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'))));

改为

define('UC_API', (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http')
.'://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')));

就可以了。

Dive into downloads blocked by script

在Yahoo的一篇文章里看到如下描述:

The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specificationsuggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won’t start any other downloads, even on different hostnames.

In some situations it’s not easy to move scripts to the bottom. If, for example, the script usesdocument.write to insert part of the page’s content, it can’t be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.

An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn’t support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.

看到上述加粗的一句话,说明浏览器下载script的过程一定是单线程的,如果某个script的下载需要一段比较长的时间,那么整个页面的加载可能就会被大大拖慢。为什么不能并行下载呢?其中一个原因可能是如果后一个script需要使用前一个script的结果的话,那么最简单的解决方法是硬性规定下载顺序。

除了这点外,原文还说到一个要点,就是可以在JavaScript中加一个叫DEFER的属性。使用这个属性的前提有两点:

  1. 这个script里不能包含有立即改变网页内容的语句,例如document.write
  2. 不要script中包括任何立即执行脚本要使用的全局变量或者函数

defer型script具体写法是这样的:

<script language="javascript" type="text/javascript" defer>

<script type="text/javascript" defer="defer">

遗憾的是Firefox不支持此属性,而且IE在里也不是如你想象中解析这个属性,我在另一篇文章中看到如下描述:

Explorer 4+ on Windows has slightly changed the meaning ofdefer. Any code inside deferred script tags is only executed when the page has been parsed entirely.

那么在IE里就相当于window.onload了,也可能是这个原因,这个鸡肋的属性没有被广泛地应用。

到目前为止,我搜索到的普片适用的解决方法只有两个,一个是使用HTML5的asyncs属性,另一个是如Yahoo那篇文章所说,直接把script放在文档尾部

一个成功的在支持HTML5浏览器上实现并行下载script的例子是:

(function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'http://yourdomain.com/script.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
})();

关于script三种加载方式的时间顺序图:普通方式,使用defer属性,使用HTML5的async属性

普通方式:          也就是单线程方式
defer属性方式:简单地把执行时间推迟到HTML Parser完毕
async属性:      下载的同时可以进行HTML Parser的工作,而且当script下载完毕以后不用等待便可以立即执行

UPDATE: 在Firefox 3.6.13和IE8上只验证了不能从同一个IP中同时下载两个文件,但可以从不同IP中同时下载不同的scripts.

参考文章:
http://developer.yahoo.com/performance/rules.html
http://www.itlearner.com/article/4313
http://www.quirksmode.org/js/placejs.html
http://techie-buzz.com/webmaster-tips/load-banner-ads-after-page-loads.html
http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

在Ubuntu 10.10 maverick上安装TortoiseHg graphical tool

Step 1: Adding two Personal Package Archives(PPA) to your Ubuntu system

sudo add-apt-repository ppa:mercurial-ppa/releases
sudo add-apt-repository ppa:tortoisehg-ppa/releases

Your system will fetch the PPA’s key. This enables your Ubuntu system to verify that the packages in the PPA have not been interfered with since they were built.

Step 2: Now, you should tell your system to pull down the latest list of software from each archive it knows about, including the PPAs you just added

sudo apt-get update

Step 3: you’re ready to start installing software from the PPAs

sudo apt-get install mercurial
sudo apt-get install tortoisehg-nautilus

My mercurial and tortoisehg version info:

hg --version

分布式软件配置管理工具 – 水银 (版本 1.7.3)
(see http://mercurial.selenic.com for more information)

Copyright (C) 2005-2010 Matt Mackall and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Add Exception class for PHP 4

异常处理模块仅限于PHP 5或以上,对于PHP 4如果想模拟这样的效果的话可以尝试编写以下Exception类,在网上看到这样的代码,记一下笔记。

if(!class_exists('Exception')){
	class Exception{
		var $_message = '';
		var $_code = 0;
		var $_line = 0;
		var $_file = '';
		var $_trace = null;

		function Exception($message = 'Unknown exception', $code = 0){
			$this->_message = $message;
			$this->_code = $code;
			$this->_trace = debug_backtrace();
			$x = array_shift($this->_trace);
			$this->_file = $x['file'];
			$this->_line = $x['line'];
		}

		function __construct($message = 'Unknown exception', $code = 0){
			$this->Exception($message, $code);
		}

		function getMessage(){
			return $this->_message;
		}
		function getCode(){
			return $this->_code;
		}
		function getFile(){
			return $this->_file;
		}
		function getLine(){
			return $this->_line;
		}
		function getTrace(){
			return $this->_trace;
		}
		function getTraceAsString(){
			$s = '';
			foreach($this->_trace as $i=>$item){
				foreach($item['args'] as $j=>$arg)
					$item['args'][$j] = print_r($arg, true);
				$s .= "#$i " . (isset($item['class']) ? $item['class'] . $item['type'] : '') . $item['function']
				. '(' . implode(', ', $item['args']) . ") at [$item[file]:$item[line]]\n";
			}
			return $s;
		}
		function printStackTace(){
			echo $this->getTraceAsString();
		}
		function toString(){
			return $this->getMessage();
		}
		function __toString(){
			return $this->toString();
		}
	}
}