Tuesday, April 28, 2015

你若是獅子,何須炫耀 ? 如果你夠強,想藏都藏不住,還怕人家不知道嗎

純種藏獒遇上一隻毛都掉光的狗...

有個壯小伙牽了一隻價值百萬的純種藏獒出來遛彎。

逢人便炫耀狗好,

人要是沒個四五百斤力量的拽都拽不住。

這時候看路邊一禿頂老頭,

身邊還坐一只毛都快要掉光了的狗。

他的藏獒對那狗一頓嚎叫,那老狗理都沒理藏獒。

小伙子正想要藏獒欺負一下這 老頭和 老狗,

但接下來發生的事,讓小伙下巴都掉下來了...

趕緊來看看吧...

鬥狗,竟然純種藏獒輸了...

小伙不樂意了。

說道:老頭,你那狗那麼大,是什麼狗啊?

咱倆的狗斗一下?

你的狗輸了給我500,我的藏獒輸了給你2000。

老頭說:我正愁我的老伙計下個月伙食呢!

要不賭大點?

我的狗輸了給你五萬,你輸了給我三萬。

小伙馬上火了:我這是純種藏獒。

別說我沒告訴你。賭了!

倆狗交鋒沒兩分鐘,藏獒敗下來,再也不敢嚎叫。

沒掉毛以前...它叫獅子!

小伙拿了三萬塊錢,郁悶至極:

大爺,你那是什麼狗?

怎麼能這麼猛?

老頭邊點錢邊說:

我也不知道現在它算啥狗,沒掉毛以前是叫獅子!

小伙哭笑不得!

Reference:

http://www.cmoney.tw/notes/note-detail.aspx?nid=29694

clear cache programatically on Magento

Method 1:

$typeArr = Mage::app()->useCache();

foreach ($typeArr as $k => $v) {
  Mage::app()->getCacheInstance()->cleanType($k);
}

Method 2:

$typeArr = Mage::app()->getCacheInstance()->getTypes();

foreach ($typeArr as $k => $v) {
  Mage::app()->getCacheInstance()->cleanType($k);
}

Method 3:

Mage::app()->getCacheInstance()->flush();

Method 4:

Mage::app()->getCache()->clean();

Install Munin 2.0.25 on CentOS 7

Munin will not be found in base repositories, hence we add EPEL repository to install Munin.

Install EPEL and additional repositories on CentOS and Red Hat:

# yum install wget
# yum install epel-release

Note: for more information https://fedoraproject.org/wiki/EPEL

# yum install munin munin-node

Uncomment the following lines:

# vim /etc/munin/munin.conf

dbdir /var/lib/munin
htmldir /var/www/html/munin
logdir /var/log/munin
rundir  /var/run/munin

# a simple host tree
[localhost]
    address 127.0.0.1
    use_node_name yes

Comment out all lines in /etc/httpd/conf.d/munin.conf:

# vim /etc/httpd/conf.d/munin.conf

Note: the reason why we comment out all the lines in munin.conf file is because we are going to move these lines under the VirtualHost block in httpd-vhosts.conf file.

Edit httpd-vhosts.conf, and add your IP address to the Allow from line:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot "/var/www/html/munin"
    ServerName munin.mydomain.com

    <directory /var/www/html/munin>
        AuthUserFile /etc/munin/munin-htpasswd
        AuthName "Munin"
        AuthType Basic
        require valid-user

        # This next part requires mod_expires to be enabled.
        #
        # We could use <IfModule mod_expires> around here, but I want it to be
        # as evident as possible that you either have to load mod_expires _or_
        # you coment out/remove these lines.

        # Set the default expiery time for files 5 minutes 10 seconds from
        # their creation (modification) time.  There are probably new files by
        # that time.

        ExpiresActive On
        ExpiresDefault M310

        Order Deny,Allow
        Deny from all
        Allow from 127.0.0.1 192.168.0.0/24
    </directory>

    ScriptAlias /munin-cgi/munin-cgi-graph /var/www/cgi-bin/munin-cgi-graph

    ErrorLog "/var/log/httpd/munin.mydomain.com-error_log"
    CustomLog "/var/log/httpd/munin.mydomain.com-access_log" common
</VirtualHost>

Make sure the permission:

# chown -R munin:munin /var/www/html/munin/

# ls -dlaZ /var/www/html/munin/

drwxr-xr-x. munin munin system_u:object_r:httpd_munin_content_t:s0 /var/www/html/munin/

To verify the Apache configuration file:

# httpd -t

Syntax OK

Create the munin admin account:

# htpasswd -c /etc/munin/munin-htpasswd Munin

Note: you don't have to use -c parameter if you want to add additional users.

Make sure the permission:

# chown root:apache /etc/munin/munin-htpasswd
# chmod 640 /etc/munin/munin-htpasswd

If you would like to change the admin's name, edit:

# vim /etc/httpd/conf.d/munin.conf

AuthName "Munin"

Enable munin on system boot:

# systemctl enable munin-node

or

# chkconfig --add munin-node
# chkconfig munin-node on

Start munin:

# systemctl restart munin-node

Restart Apache:

# systemctl restart httpd

Wait for a couple of minutes or reboot your system to allow munin to create necessary files/folders automatically on your apache root folder.

http://munin.mydomain.com

Reference:

http://www.unixmen.com/install-munin-monitoring-tool-centos-rhel-scientific-linux-6-56-46-3/

Monday, April 27, 2015

To Install Nagios 4.0.8 on CentOS 7

To Install Nagios 4.0.8 on CentOS 7

It all depends what you mean by "monitor"!

1. Is it (system or service) available? We use nagios.
2. What is it doing? We use munin for linux servers, and cacti for just about everything else, even though it is a pain to configure sometimes...
3. What has it done? We use syslog-ng to concentrate syslogs in one place and then run a customized logcheck script daily to send reports via email. We are looking for something similar for Windows servers.

Install the required packages:

# yum install gcc glibc glibc-common gd gd-devel make net-snmp openssl-devel

Install mailx:

# yum install mailx

Note: the reason why we install mailx is because Nagios use /bin/mail to send the notification mails out.
Note: Postfix is the default mta for Centos 7.

# which mail

/bin/mail

Send a simple testing email:

# echo "Your message" | mail -s "Message Subject" email@address.com

Send a testing email with an attachment:

# echo "Message" | mail -s "Subject" -a /loc/to/attachment.txt email@address.com

Reading the message body from a file:

# echo | mail -s "Subject" -r from@address.com -q /loc/to/body.txt email@address.com

Add the Nagios user:

# useradd nagios

Note: do not intend to create the user with /sbin/nologin or with the -r (system account) parameter. Because if the Nagios user can't send email then Nagios running as the nagios user won't be able to send mail either. You have to be able to send mail via a console terminal as the nagios user before you do any additional debugging.

Add the Nagios group:

# groupadd nagcmd

Add the nagios user and apache user to the Nagios group:

# usermod -a -G nagcmd nagios
# usermod -a -G nagcmd apache

Downloading and install Nagios:

# cd ~/tmp

# curl -L -O http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-4.0.8.tar.gz

# tar xvf nagios-*.tar.gz

# cd nagios-*

# ./configure --with-command-group=nagcmd

# make all

# make install
# make install-commandmode
# make install-init
# make install-config
# make install-webconf

Downloading and install Nagios Plugins:

# cd ~/tmp
# curl -L -O http://nagios-plugins.org/download/nagios-plugins-2.0.3.tar.gz
# tar xvf nagios-plugins-*.tar.gz

# cd nagios-plugins-*
# ./configure --with-nagios-user=nagios --with-nagios-group=nagios --with-openssl

# make
# make install

Configure Nagios:

# vim /usr/local/nagios/etc/nagios.cfg

cfg_dir=/usr/local/nagios/etc/servers

admin_email=me@example.com
admin_pager=me@example.com

Note: regarding the admin_email and admin_pager, Nagios never uses these values itself, but you can access them by using the $ADMINEMAIL$ and $ADMINPAGER$ macros in your notification commands.

# mkdir /usr/local/nagios/etc/servers

Verify the Nagios configuration file:

# /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg

Configure Nagios contacts:

# vim /usr/local/nagios/etc/objects/contacts.cfg

email                           nagios@localhost        ;

Set up the Nagios admin account:

# htpasswd -c /usr/local/nagios/etc/htpasswd.users nagiosadmin

Note: you don't have to use -c parameter if you want to add additional users.

# chmod 440 /usr/local/nagios/etc/htpasswd.users
# chown root:apache /usr/local/nagios/etc/htpasswd.users

Comment out all lines /etc/httpd/conf.d/nagios.conf:

# vim /etc/httpd/conf.d/nagios.conf

Move all of lines in /etc/httpd/conf.d/nagios.conf to your VirtualHost block, since we are using PHP-FPM to process php scripts:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

<VirtualHost *:80>
    ServerAdmin webmaster@dummy-host.example.com
    DocumentRoot "/usr/local/nagios/share"
    ServerName nagios.mydomain.com

    DirectoryIndex /index.php index.php index.html index.htm
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/usr/local/nagios/share/$1

    ErrorLog "/var/log/httpd/nagios.mydomain.com-error_log"
    CustomLog "/var/log/httpd/nagios.mydomain.com-access_log" common

    ScriptAlias /nagios/cgi-bin "/usr/local/nagios/sbin"

    <Directory "/usr/local/nagios/sbin">
    #  SSLRequireSSL
       Options ExecCGI
       AllowOverride None
       #Order allow,deny
       #Allow from all
       Order deny,allow
       Deny from all
       Allow from 127.0.0.1 192.168.0.5/24
       AuthName "Nagios Access"
       AuthType Basic
       AuthUserFile /usr/local/nagios/etc/htpasswd.users
       Require valid-user
    </Directory>

    Alias /nagios "/usr/local/nagios/share"

    <Directory "/usr/local/nagios/share">
    #  SSLRequireSSL
       Options None
       AllowOverride None
       #Order allow,deny
       #Allow from all
       Order deny,allow
       Deny from all
       Allow from 127.0.0.1 192.168.0.5/24
       AuthName "Nagios Access"
       AuthType Basic
       AuthUserFile /usr/local/nagios/etc/htpasswd.users
       Require valid-user
    </Directory>
</VirtualHost>

Verify the Apache configuration files:

# httpd -t

Syntax OK

If you have enabled SELinux, set the correct security context:

# chcon -R --reference=/var/www/html /usr/local/nagios/share
# chcon -R --reference=/var/www/html /usr/local/nagios/var
# chcon -R --reference=/var/www/cgi-bin /usr/local/nagios/sbin
# chcon -R -t httpd_sys_rw_content_t /usr/local/nagios/var/rw

Or do:

# chcon -R -t httpd_sys_content_t /usr/local/nagios/share
# chcon -R -t httpd_sys_content_t /usr/local/nagios/var
# chcon -R -t httpd_sys_script_exec_t /usr/local/nagios/sbin
# chcon -R -t httpd_sys_rw_content_t /usr/local/nagios/var/rw

Enable and Run services:

# systemctl enable nagios.service

or

# chkconfig --add nagios
# chkconfig nagios on

# systemctl start nagios.service

# systemctl restart httpd.service

Check http process:

# /usr/local/nagios/libexec/check_http -H 127.0.0.1

If you see the following message:

HTTP WARNING: HTTP/1.1 403 Forbidden - 5194 bytes in 0.001 second response time |time=0.000542s;;;0.000000 size=5194B;;;0

Try to touch index.html file in your root directory.

# cat /usr/local/nagios/var/nagios.log

# cat /var/log/maillog

postfix/sendmail[24452]: fatal: open /etc/postfix/main.cf: Permission denied

# setsebool -P httpd_can_network_connect 1
# setsebool -P httpd_can_sendmail 1

Note: -P in the above command means Persistent (across reboots).

# getsebool -a | grep -i httpd_can
# sestatus -b | grep httpd_can

httpd_can_network_connect on
httpd_can_sendmail on

# ll -Z /etc/postfix/main.cf

-rw-r--r--. root root system_u:object_r:postfix_etc_t:s0 /etc/postfix/main.cf

If you did not get the nofitication email, please check to see if the mail client path has been set correctly:

# vim /usr/local/nagios/etc/objects/commands.cfg

Note: the default setting is set to /bin/mail.
Note: postfix is the default mta for Centos 7.

To see the visual graphics:

PNP4Nagios is an addon to Nagios which analyzes performance data provided by plugins visually and stores them automatically into RRD-databases.

Reference:

https://www.digitalocean.com/community/tutorials/how-to-install-nagios-4-and-monitor-your-servers-on-centos-7
http://www.unixmen.com/install-configure-nagios-4-centos-7/
http://tecadmin.net/install-nagios-core-service-on-centos-rhel/
http://serverfault.com/questions/44/what-tool-do-you-use-to-monitor-your-servers

Add Swap to a Amazon EC2 instance with an EBS (Elastic Block Store) volume

The Amazon EC2 instance does not come with the swap partition by default. You will need to add the swap or paging space manually.

Swap space are useful for systems having less memory (RAM). If your system facing problem of lack of memory continuously and you don’t want to increase memory on server, Then it can be helpful to enable swap in your system. Swap is comparatively much slower than physical memory but operating system uses swap space in case system goes out of memory. To know more about working of swap visit here.

Creating a swap file in current file system:

# dd if=/dev/zero of=/myswap bs=1M count=2048

Note: if - input file.
Note: of - output file.
Note: bs - block size.

# mkswap /myswap
# chown root:root /myswap
# chmod 0600 /myswap

# swapon /myswap

# free -h

             total       used       free     shared    buffers     cached
Mem:          1.8G       1.6G       208M        80M         0B       674M
-/+ buffers/cache:       957M       882M
Swap:         2.0G         0B       2.0G

# swapon -s

Filename                                Type            Size    Used    Priority
/myswap                                 file    2097148 0       -1

To make the swap enable on system boot, run the following command:

# sh -c "echo /myswap swap swap defaults 0 0 >> /etc/fstab"

Or edit the /etc/fstab:

# vim /etc/fstab

/myswap   swap   swap   defaults  0 0

To verify the swap:

# cat /etc/fstab | grep -i swap

/myswap swap swap defaults 0 0

# cat /proc/meminfo | grep -i swap

SwapCached:            0 kB
SwapTotal:       2097148 kB
SwapFree:        2097148 kB

To check the current system's swappiness:

Swappiness is a ratio of how often the system will write to the swapfile: if set to zero, the system will only swap to avoid running out of memory (the error above); if set to 100, the system will attempt to swap all the time. The default is set at 60. Since we want to utilize the swap only when necessary.

The Linux kernel provides a tweakable setting that controls how often the swap file is used, called swappiness.

A swappiness setting of zero means that the disk will be avoided unless absolutely necessary (you run out of memory), while a swappiness setting of 100 means that programs will be swapped to disk almost instantly.

Ubuntu system comes with a default of 60, meaning that the swap file will be used fairly often if the memory usage is around half of my RAM.

# cat /proc/sys/vm/swappiness

30

To configure swappiness:

# sh -c "echo vm.swappiness = 0 >> /etc/sysctl.conf && sysctl -p"

Add the swap space to a second disk instead of the current disk:

If you would like to add the swap space to a second disk, first we need to add extra disk in our system first. In my case new disk mounted as /dev/xvdd (It may change in your case). Then, run the following commands:

# mkswap -f /dev/xvdd
# swapon /dev/xvdd

# vim /etc/fstab

dev/xvdd   swap   swap   defaults  0 0

If at all possible, I'd advise not to use swap on EC2 unless you're 99% certain you won't have to use it (I.E. it's only there for emergency). When we disabled swap on some of our EC2 instances our monthly EBS IO costs probably halved.

You are right, the Ubuntu EC2 EBS images don't come with swap space configured (for 11.04 at least). The "regular" instance-type images do have a swap partition, albeit only 896 MB on the one I tested.

If some process blows up and you don't have swap space, your server could come to a crawling halt for a good while before the OOM killer kicks in, whereas with swap, it merely gets slow. For that reason, I always like to have swap space around, even with enough RAM. Here's your options:

Create an EBS volume (2-4 times the size of your RAM), attach it to your instance (I like calling it /dev/xvdm for "memory"), sudo mkswap /dev/xvdm, add it to fstab, sudo swapon -a, and you're good to go. I have done this before and it works fine, and it is probably a bit faster than using a swap file, but for a server that doesn't normally depend on swap performance, I personally think the minor performance improvement is not worth the added complexity of having to attach a volume. (Update: It's probably not faster than a swap file on instance storage, since EBS has become known for lousy and unpredictable performance.)

Or you might be able to repartition your disk to add a swap partition, though this might require creating a new AMI. I have not been able to do this in a running instance, because I cannot unmount the root file system, and I do not even have access to the disk device (/dev/xvda), only the partition (xvda1).

Or you can create a swap file. This is my preferred solution right now.

# dd if=/dev/zero of=/var/swapfile bs=1M count=2048 &&
# chmod 600 /var/swapfile &&
# mkswap /var/swapfile &&
# echo /var/swapfile none swap defaults 0 0 | tee -a /etc/fstab &&
# swapon -a

Done. :) I know a lot of people feel icky about using files instead of partitions, but it certainly works well enough as emergency swap space.

Reference:

http://tecadmin.net/add-swap-partition-on-ec2-linux-instance/
http://stackoverflow.com/questions/17173972/how-do-you-add-swap-to-an-ec2-instance
http://askubuntu.com/questions/103915/how-do-i-configure-swappiness
http://serverfault.com/questions/218750/why-dont-ec2-ubuntu-images-have-swap
http://danielgriff.in/2014/add-swap-space-to-ec2-to-increase-performance-and-mitigate-failure/

To prevent vim from auto-wrapping at column 80, try:

:set tw=0
:set textwidth=0

or

:set wrapmargin=0

'textwidth' 'tw'        number  (default 0)
                        local to buffer
                        {not in Vi}
        Maximum width of text that is being inserted.  A longer line will be
        broken after white space to get this width.  A zero value disables
        this.  'textwidth' is set to 0 when the 'paste' option is set.  When
        'textwidth' is zero, 'wrapmargin' may be used.  See also
        'formatoptions' and |ins-textwidth|.
        When 'formatexpr' is set it will be used to break the line.
        NOTE: This option is set to 0 when 'compatible' is set.


'wrapmargin' 'wm'       number  (default 0) 
                        local to buffer
        Number of characters from the right window border where wrapping
        starts.  When typing text beyond this limit, an <EOL> will be inserted
        and inserting continues on the next line.
        Options that add a margin, such as 'number' and 'foldcolumn', cause
        the text width to be further reduced.  This is Vi compatible.
        When 'textwidth' is non-zero, this option is not used. 
        See also 'formatoptions' and |ins-textwidth|.  {Vi: works differently
        and less usefully}

Reference:

http://stackoverflow.com/questions/1290285/why-cant-i-stop-vim-from-wrapping-my-code
http://stackoverflow.com/questions/15724919/how-do-i-prevent-vim-from-auto-wrapping-at-column-80

Saturday, April 25, 2015

How can I find which version of libmysqlclient is installed in Centos?

# repoquery --whatprovides *libmysqlclient*

# repoquery -l mysql-libs-0:5.1.71-1.el6.x86_64 | head -9

# yum whatprovides "*libmysqlclient*"

# yum info mysql-devel

Reference:

http://unix.stackexchange.com/questions/114004/how-can-i-find-which-version-of-libmysqlclient-is-installed-in-centos

Friday, April 24, 2015

Apache configuration for Django

Install mod_wsgi:

# yum install mod_wsgi

Edit httpd-vhosts.conf:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

<VirtualHost *:80>
    ServerName myproj.cent-dev.local
    ServerAdmin webmaster@example.com

    DocumentRoot "/var/www/html/django/myproj"

    Alias /media/ /var/www/html/django/myproj/media/
    Alias /static/ /var/www/html/django/myproj/static/

    <Directory "/var/www/html/django/myproj">
        #<Files wsgi.py>
        #Require all granted
        #</Files>
    </Directory>

    WSGIDaemonProcess myproj.cent-dev.local python-path=/var/www/html/django/myproj:/usr/lib64/python2.7/site-packages  processes=2 threads=15 display-name=%{GROUP}
    #WSGIDaemonProcess myproj.cent-dev.local python-path=/var/www/html/django/myproj:/usr/lib64/python2.7/site-packages
    #WSGIDaemonProcess myproj.cent-dev.local python-path=/var/www/html/django/myproj

    WSGIProcessGroup myproj.cent-dev.local

    ### use the following on the production server.
    #WSGIScriptAlias / /var/www/html/django/myproj/myproj/wsgi.py process-group=myproj.cent-dev.local

    ### use the following two lines on the development server.
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/

    #SetEnv DJANGO_SETTINGS_MODULE myproj.settings

    ErrorLog "/var/log/httpd/myproj-cent-dev.local-error_log"
    CustomLog "/var/log/httpd/myproj-cent-dev.local-access_log" common
</VirtualHost>

Install pip:

# wget https://bootstrap.pypa.io/get-pip.py

# python get-pip.py

Install django:

# pip install django==1.7.6

To verify that Django can be seen by Python:

# python -c "import django; print(django.get_version())"

1.7.6

To listens on local interface on port 8000:

# python manage.py runserver

0 errors found
March 15, 2015 - 19:56:59
Django version 1.6.2, using settings 'myproj.settings'
Starting development server at http://127.0.0.1:8000/

To listens on every interface on port 8000:

# python manage.py runserver 0.0.0.0:8000

Store PHP sessions in Memcached

Install Memcached:

If Memcached is installed, storing PHP session files in RAM can be much more efficient than storing on disk and can also save some IO. To configure this, you should modify the main php.ini file and change session.save_handler to memcached.

# yum install memcached

# vim /etc/sysconfig/memcached

PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1"

# systemctl enable memcached.service

# systemctl restart memcached.service

# memcached-tool 127.0.0.1:11211 stats

# yum install php-pecl-memcached

# vim /etc/php.ini

session.save_handler = memcached

#session.save_path = unix:/tmp/memcached.sock
session.save_path = "127.0.0.1:11211"

# systemctl restart php-fpm.service

# php -r 'echo phpinfo();' | grep memcached

memcached support => enabled
Registered save handlers => files user redis memcached
session.save_handler => memcached => memcached

Wednesday, April 22, 2015

Show memory usage in Magento

To turn on memory usage and script execution time:

1. go to Admin->System->Configuration->Developer, find the ‘Profiler’ option in the ‘Debug’ section and enable it (set to ‘Yes’).

2. edit index.php and uncomment out the following line:

Varien_Profiler::enable();

The proper way to disable a module:

Go to app/etc/modules. Here you can find the list of *.xml files.

Each of them is corresponding to some extension. If you open some of the files with a text editor, you will see the following line there:

<active>true</active>

To disable the extension just change the parameter inside the ‘active’ node to FALSE in the following manner:

<active>false</active>

Remember, that’s the correct universal way to disable an extension. Do not use Admin->System->Configuration->Advanced admin page to turn off the extensions. It’s a common mistake since this tool does not disable an extension – it only disables the extension’s output. It might cause a lot of problems on your store.

Reference:

http://www.atwix.com/magento/finding-bottlenecks/

Tuesday, April 21, 2015

MariaDB log file location directory path

SHOW VARIABLES LIKE '%error%'

/var/log/mariadb/mariadb.log

Sunday, April 19, 2015

夜光石發光的原理?

物體在黑暗中會發光, 原理主要有兩大類...

1. 含有微量放射性物質: 這也是最早的夜光材料, 但有傷害人體的疑慮, 現已較少被採用. 不過仍有軍用手表使用. 其特性是自身發光, 不必經過吸光-發光週期, 其發光時間視衰變而定, 數十年至數千年甚至更長...

2. 含有蓄光材質: 這類材質, 當受到外界光或熱激發, 其電子會由基態進入激態, 當外界能量消失, 在由激態回到基態, 其能量則以光的方式釋放出來. 其特性為無幅射, 但在黑暗中發光會逐漸衰退, 必需重新照射光線蓄光.

古代所謂夜明珠, 夜光石, 大抵是含有這兩種成份, 天然者固然珍貴, 但要瞭解其原理其實很簡單, 不必聽販售者吹捧, 還需自行判斷是否物有所值... 而夜明珠在古代是稀世珍寶, 現在到處買得到, 怎麼來的? 自己想...

Reference:

https://tw.knowledge.yahoo.com/question/question?qid=1105070202000

夜光棒的原理是什么?

荧光棒中的化学物质主要由三种物质组成:过氧化物、酯类化合物和荧光染料。简单地说,荧光棒发光的原理就是过氧化物和酯类化合物发生反应,将反应后的能量传递给荧光染料,再由染料发出荧光。目前市场上常见的荧光棒中通常放置了一个玻璃管夹层,夹层内外隔离了过氧化物和酯类化合物,经过揉搓,两种化合物反应使得荧光染料发光。 由于荧光棒中的液体化学物质被聚乙烯(塑料)包装,所以不会对人体造成太大伤害。因为荧光棒所发出的光是靠化学反应激发染料发出的非放射性光,而不是由放射线激发染料发出的光,不会伤害人体。但赵福群也对时下有些人为追赶时髦,将荧光棒弄破,把里面的液体涂抹在身上的做法表示反对,因为荧光棒中的化学物质直接接触皮肤会对人体造成一定的损害。尤其注意不要让儿童误食。 之所以有观点认为荧光物质会伤害人体,是因为在有些夜光手表、矿井应急信号灯等中用的都是放射性物质,使染料在黑暗处发光,所以人们误认为荧光棒中也是运用了放射性物质,形成认识上的误差。消费者鉴别某夜光产品是否为放射性发光的办法是,放射性发光持续的时间比较长,并且光强度弱些;而非放射光持续的时间比较短。

补充:

在黑暗中能发出各色荧光的物质,称为夜光材料。人类使用夜光材料,已经有相当悠久的历史,比如用在手表的盘面上,就制成了一种夜光表。 夜光材料分为自发光型和蓄光型两种。自发光型夜光材料的基本成分为放射性材料,不需要从外部吸收能量,可持续发光,不仅黑夜,白天也是如此。正是因为含有放射性物质,所以在使用时受到较大的限制,废弃后的处理也是一大问题。蓄光型夜光材料很少含有放射性物质,没有使用方面的限制,但它们要靠吸收外部的光能才能发光,而且要储备足够的光能才能保证一直发光。蓄光型夜光材料的另个缺陷是辉度不够。例如,以前一直使用硫化锌作为余辉型荧光体,但发光时间太短,辉度也不够。于是后来就掺和了一种放射性同位素钜147,发光的效果是理想了,但放射性同位素的介入。不符合环境保护的要求。 对人体有害,虽然很小

补充:

 荧光棒通常是由内外两层管组成:外层管由塑料制成,内层管由易断裂的玻璃制成;两层管中分别充满不同液体的化学药品。

  当荧光棒被屈曲时,内层的玻璃管会破裂,使内层管中的化学药品与外层管中的化学药品混合一起,两种化学药品混合后,会导致化学反应,而产生新的化合物。新生成的化合物处于高能量状态,然后以光的形式将能量释放出来,这就是我们看见的荧光。

  荧光的颜色可以通过不同的化学反应而改变,不同的化学药品产生光的颜色会不同。但通常荧光棒都不会用这种方法制造颜色,而是简单地加入不同颜料造成。荧光的亮度与化学药品浓度有关,开始时化学药品浓度较高,看到的光会较亮;当管中化学药品的化学反应停止时,荧光棒就不再发光了。常见的荧光棒可以发光5~10小时

Reference:

http://wenwen.sogou.com/z/q148438158.htm

夜光材料的原理是什麽

熒光粉(俗稱夜光粉),通常分爲光致儲能夜光粉和帶有放射性的夜光粉兩類。光致儲能夜光粉是熒光粉在受到自然光、日光燈光、紫外光等照射後,把光能儲存起來,在停止光照射後,在緩慢地以熒光的方式釋放出來,所以在夜間或者黑暗處,仍能看到發光,持續時間長達幾小時至十幾小時。帶有放射性的夜光粉,是在熒光粉中摻入放射性物質,利用放射性物質不斷發出的射線激發熒光粉發光,這類夜光粉發光時間很長,但有毒有害和環境汙染等應用範圍小。

  人們在實際生活中利用夜光粉長時間發光的特性,制成弱照明光源,在軍事部門有特殊的用處,把這種材料塗在航空儀表、鍾表、窗戶、機器上各種開關標志,門的把手等處,也可用各種透光塑料一起壓制成各種符號、部件、用品(如電源開關、插座、釣魚鈎等)。這些發光部件經光照射後,夜間或意外停電、閃電後起床等它仍在持續發光,使人們可辨別周圍方向,爲工作和生活帶來方便。把夜光材料超細粒子摻入紡織品中,使顔色更鮮豔,小孩子穿上有夜光的紡織品,可減少交通事故。

  目前國內外夜光材料主要是以ZnS,SrS和CaS制成的,發出綠光和黃光。SrS,CaS材料易潮解,給廣泛應用帶來困難。所以市場上主要是以ZnS爲基質的夜光材料。但它的余輝時間只有1~3小時,同時在強光(如太陽光)、紫外光和潮濕空氣中容易變質發黑,所以在許多領域中應用受到限制。添加鑽、銅共激活的ZnS夜光粉雖然有很長的余輝時間,但它有紅外淬滅現象,在電燈光(包含較多的紅光)照射下,余輝很快熄滅。

Reference:

http://tc.wangchao.net.cn/xinxi/detail_131380.html

Django translation in views

myapp/views.py:

from django.utils.translation import ugettext

def getOptDict():
    optArr = {
        1: ugettext('Test 1'),
        2: ugettext('Test 2'),
    }
    return optArr

Thursday, April 16, 2015

Internet Explorer Adds Twice the Quantity to Cart

IE 8 (Internet Explorer 8) will add the product twice and cause the quantity of that product in the cart to double up (two quantities).

Change:
<button onclick="productAddToCartForm.submit(this)"><?php echo $this->__('Add to Cart') ?></button>

To
<button onclick="productAddToCartForm.submit(this); return false;"><?php echo $this->__('Add to Cart') ?></button>

Reference:

http://stackoverflow.com/questions/9021040/magento-theme-adds-product-2x-to-cart-in-ie-javascript
http://optimiseblog.co.uk/magento-fix-internet-explorer-adds-twice-doubl-quantity-to-cart/

Wednesday, April 15, 2015

WSGI vs uWSGi

Ok, guys this confusion is because of lack of detail from several sources, and the naming of these protocols, and what WSGI actually is.

Summary:

1. WSGI and uwsgi both are protocols, not servers. It is used to communicate with web servers for load balancing and especially to take advantage of extra features that pure HTTP can not provide. So far Nginx and Cherokee have implemented this protocol.

2. uWSGI is a server and one of the protocols it implements is WSGI. WSGI is a Python specification. There are several implementations of the WSGI specification and it's intended to be used for more than just application servers/web servers, but there are quite a few WSGI application servers (ie. CherryPy, which also happens to have a production ready WSGI compliant web server, if you weren't confused enough already!).

3. Comparing uwsgi to WSGI is comparing oranges to apples.

Reference:

http://stackoverflow.com/questions/7739810/wsgi-vs-uwsgi-with-nginx
http://flask.pocoo.org/docs/deploying/uwsgi/
http://nichol.as/benchmark-of-python-web-servers

disable remove default css style sheet on Drupal 6

/www/drupal6/sites/all/themes/zen_test/template.php:

function zen_test_preprocess_page(&$vars, $hook) {
  foreach ($vars['css']['all']['module'] as $_k => $_v) {
    if (in_array($_k, array('not_yet'))) {
      continue;
    }

    unset($vars['css']['all']['module'][$_k]);

    $vars['styles'] = drupal_get_css($vars['css']);
  }
}

Monday, April 13, 2015

check if Apache compression is working

# curl -i -H 'accept-encoding:gzip, deflate, sdch' http://example.com | head -n 13

or

# curl -i --compressed http://example.com | head -n 13

Content-Encoding: gzip

Thursday, April 9, 2015

Jquery UI Autocomplete with vertical scrollbar

scrollable dropdown instead of a plain dropdown list

bindDealerNameAC('#idDealer');

function bindDealerNameAC(idToBind) {
  $(idToBind).autocomplete({
    minLength: 1,
    create: function( event, ui ) {
      $('.ui-autocomplete').css({
        'max-height': '300px',
        'overflow-y': 'auto',
        'overflow-x': 'hidden',
      });
    },
    //source: ["choice 1", "choice"],
    source: function( request, response ) {
      $.get('/bg/crm/js_dealerarr', request, function(dataObj) {
        if (dataObj.status == true) {
          response(dataObj.dealerNameArr);
        }
        else {
          response([]);
        }
      }, 'json');
    },
  });
}

Django taxonomy category

# pip install django-taggit

# python manage.py schemamigration taggit --auto

# python manage.py migrate taggit

If you are using South you’ll have to add the following setting, since taggit uses Django migrations by default:

SOUTH_MIGRATION_MODULES = {
    'taggit': 'taggit.south_migrations',
}

And then to any model you want tagging on do the following:

models.py:

from django.db import models

from taggit.managers import TaggableManager

class News(models.Model):
    # ... fields here

    tags = TaggableManager()

If, when saving a form, you use the commit=False option you’ll need to call save_m2m() on the form after you save the object, just as you would for a form with normal many to many fields on it:

if request.method == "POST":
    form = MyFormClass(request.POST)
    if form.is_valid():
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        # Without this next line the tags won't be saved.
        form.save_m2m()

forms:

from taggit.forms import TagField, TagWidget

class NewsForm(ModelForm):
    tags = TagField(label=_('Tags'), widget=TagWidget(attrs={'size': 80}), help_text='A comma-separated list of tags')
    title = forms.CharField(label=_('Title'), widget=forms.TextInput(attrs={'size': 80}))
    class Meta:
        model = News
        fields = ['tags', 'title']
        #widgets = {
        #    'tags': TagWidget(),
        #}

views.py:

def ls_news(request):
    news_list = News.objects.order_by('-update_date')
    return render(request, 'administrator/news/index.html', locals())

template/administrator/news/index.html:

{% for n in news_list %}
    <!-- method 1 -->
    {{ n.tags.all|join:", " }}

    <!-- method 2 -->
    {% for t in n.tags.all %}
       {{ t.name }}
    {% endfor %}
{% endfor %}

To show all available tags:

from taggit.models import Tag

def add_news(request):
    tagsall = Tag.objects.all()
    return render(request, 'administrator/news/add.html', locals())
add_news = login_required(add_news)

{{ tagsall|join:', ' }}

Reference:

https://github.com/alex/django-taggit
https://github.com/fizista/django-taggit-templatetags2

https://django-taggit.readthedocs.org/en/latest/getting_started.html
http://stackoverflow.com/questions/16091940/django-taggit-in-edit-form
http://stackoverflow.com/questions/5359714/django-django-taggit-form
http://stackoverflow.com/questions/5742856/django-tagging-or-django-taggit-or-something-else
http://stackoverflow.com/questions/12894154/get-all-tags-from-taggit

Monday, April 6, 2015

JavaScript ZLIB Decompression

Download Pako: https://github.com/nodeca/pako

<html>
<head>
  <script src="pako-master/dist/pako.min.js"></script>
</head>
<body>

<?php
  $str = 'Hello, World!';
  $strGZCompressedBase64Encoded = base64_encode(gzcompress($str));
?>

<script>
  var strGZCompressedBase64Encoded = '<?php echo $strGZCompressedBase64Encoded; ?>';
  var str = uncompress_base64decode(strGZCompressedBase64Encoded);
  console.log(str);

  function uncompress_base64decode(strGZCompressedBase64Encoded) {
    // Decode base64 (convert ascii to binary)
    var strData = atob(strGZCompressedBase64Encoded);

    // Convert binary string to character-number array
    var charData = strData.split('').map(function(x){return x.charCodeAt(0);});

    // Turn number array into byte-array
    var binData = new Uint8Array(charData);

    // Pako magic
    var data = pako.inflate(binData);

    // Convert gunzipped byteArray back to ascii string:
    return String.fromCharCode.apply(null, new Uint16Array(data));
  }
</script>

</body>
</html>

Reference:

http://stackoverflow.com/questions/4507316/zlib-decompression-client-side
http://stackoverflow.com/questions/14620769/decompress-gzip-and-zlib-string-in-javascript

Saturday, April 4, 2015

jQuery text input change event

$('#test').on('input', function(e){
  console.log('test');
});

$('#test').on('keydown', function(e){
  console.log('test');
});

JavaScript events

This is when the different event are triggered:
  • change
    This will be called when the blur event is triggered if the value of the  has been changed. In other words it will trigger when the input loses focus the value is different to what it was.
  • input
    The input event is basically everything you are looking for, it captures the event on any input change and most likely came about due to the headaches causes when developing something that watches every keystroke. The input event even manages to catch the case where the mouse pastes in content.
    Unfortunately the input event is relatively new and only available to modern browsers (IE9+).
  • keydown
    The keydown event is pretty simple, it triggers when the user pushes the key down..
  • keypress
    The keypress event is supposed to represent a character being typed. Because of this is does not capture backspace or delete which immediately dismisses it for use over keydown.
  • keyup
    Much like keydown, it triggers whenever the user releases a key.
  • paste
    This handy event triggers when data is pasted into the element.

Modifier keys

Note that keydownkeypress and keyup carr with them information about the modifier keys ctrl shift and alt in the properties ctrlKeyshiftKey and altKey respectively.

The cases

Here is a list of the cases you need to consider:
  • Entering input with keyboard (includes holding down a key)
    Triggers: keydownkeypressinputkeyup
  • Deleting input (backspace/delete)
    Triggers: keydowninputkeyup
  • Pasting using ctrl+v
    Triggers: keydownpasteinputkeyup
  • Using mouse to paste
    Triggers: pasteinput
  • Select an item from the autocomplete (/)
    Triggers: keydownkeyup

Implementation

Given the above, you could implement your autocomplete box handling the input event for all changes to the input, and then keydown event to handling up and down. This would really separate everything nicely and lead to some pretty clean code.
If you want to support IE8, you will need to throw everything except pasting into the keydown event and then handle paste. The paste event is quite widely supported now and has been in IE since v5.5).

Reference:

http://stackoverflow.com/questions/15727324/for-a-javascript-autocomplete-search-box-must-we-use-the-input-event-handler

Creating a JSON response using Django and Python

Pre-Django 1.7:

import json
from django.http import HttpResponse

def testjson(request):
  response_data = {}
  response_data['result'] = 'failed'
  response_data['message'] = 'You messed up'
  return HttpResponse(json.dumps(response_data), content_type="application/json")

Django 1.7+:

from django.http import JsonResponse

def testjson(request):
  response_data = {}
  response_data['result'] = 'failed'
  response_data['message'] = 'You messed up'
  return JsonResponse(json.dumps(response_data))

Reference:

http://stackoverflow.com/questions/2428092/creating-a-json-response-using-django-and-python

Get selected element's outer HTML

<div id="test">
  <p><span>test 1</span></p>
  <p><span>test 2</span></p>
  <p><span>test 3</span></p>
  <p><span>test 4</span></p>
</div>

<script>
  var test1 = $('#test p:nth-last-child(2)')[0].outerHTML;
  var test2 = $('#test p:nth-last-child(1)')[0].outerHTML;

  console.log(test1);
  console.log(test2);
</script>

Reference:

http://stackoverflow.com/questions/2419749/get-selected-elements-outer-html

Friday, April 3, 2015

Django duplicate key value violates unique constraint "taggit_tag_name_key"

Solution:

ALTER TABLE taggit_tag CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

Reference:

https://github.com/alex/django-taggit/issues/162