2016年12月13日 星期二

vmware workstation player 12 guest 3D 設定

假設建立了一個 guest 叫做 windows_7 必須在
該 windows_7 vm 目錄下 windows_7.vmx 加入以下兩行:

mks.enableD3DRenderer = TRUE

mks.enableDX11Renderer = FALSE

2016年12月10日 星期六

使用 complete 呼叫的 jquery ajax polling

(function poll(){
  $.ajax({
    url: "/poll",
    success: function (data) {
      do_something_with(data);
    },
    dataType: "json",
    complete: poll,
    timeout: 30000
  });
})();

2016年12月7日 星期三

進階 jquery polling 即使 request 失敗也不會停止

function doPoll(){
    $.post('ajax/test.html').done(function(data) {
        /* process */
    }).always(function() {
        setTimeout(doPoll, 5000);
    });
}

jquery 簡單 polling 範例

function doPoll()
    $.post('ajax/test.html', function(data) {
        alert(data); // process results here 
        setTimeout(doPoll,5000);     
    }); 
}

2016年12月3日 星期六

如何禁止Vmware同步時間



參考:http://trufflepenne.blogspot.tw/2014/02/vmware.html
如果你有時必須調整VM裡的時間,但重開VM後又恢復現在時間,請利用以下步驟來修改(以windows 2008 R2為例):


停止VMWare tools, Windows Time服務
進入你的VM作業系統,選服務,把VMWare tools, Windows Time停止,並改為手動
取消Internet同步時間
進入你的控制台找到日期時間,進入後將以下取消打勾





修改VMWare configuration檔 (vmx, 跟VM檔案同一目錄)
a. shutdown VM
b. 切到你的VM目錄
c. 打開xxx.vmx
d. 找到tools.syncTime = "XXX" 標籤,刪掉之
e. 在最結尾填入以下
tools.syncTime = "FALSE"
time.synchronize.continue = FALSE
time.synchronize.restore = FALSE
time.synchronize.resume.disk = FALSE
time.synchronize.shrink = FALSE
time.synchronize.tools.startup = FALSE
time.synchronize.resume.host = FALSE
重新進入VM,修改時間,重開機就會看到新設定時間沒被同步
如果要讓VM重開時,都定在固定時間
在xxx.vmx最後加上
rtc.startTime = 1335862800
後面數字是timesatmp, 上面是2012 09:00:00 ,可用以下計算
http://www.onlineconversion.com/unix_time.htm

2016年10月17日 星期一

mysql 與 django 設定 index 欄位注意事項

範例:
strOriginUrl = models.CharField(db_index=True, max_length=255, null=False)

注意:
1. 欄位需使用 CharField 型態
2. 最大長度為 255
3. 指定 db_index=True

2016年10月13日 星期四

[selenium] 讓 chrome 啟動時最大化視窗

chromeDriverExeFilePath = "path-to-executable/chromedriver.exe"
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(executable_path=chromeDriverExeFilePath, chrome_options=options)

2016年10月3日 星期一

windows 系統下的網頁另存新檔 html 與 _files 的連動關閉

在 windows 下,預設 xxx.html 與 xxx_files 是連動的,
刪除或移動 xxx.html xxx_files 也會跟著刪除或移動
如果需要關閉這一層連動關係,必需修改註冊表:

開始 - 執行, 輸入 regedit
HKEY_CURRENT_USER - Software - Microsoft - Windows - CurrentVersion - Explorer

建一個新的 DWORD 值
名稱:NoFileFolderConnection 
數值: 1

完成後,不需重新開機等動作即可生效。

2016年8月31日 星期三

python3 selenium 移動滑鼠到 element 範例 (hover)

使用 selenium 時,有點要被 click 的元件,可能要先將滑鼠 hover 到某個元件上才會顯示出來
可以這樣寫:
假設我們要切換幣別為 USD 但該網站設計,必需先移動到 #currency 元件上  #usd 選項才會出現。

from selenium.webdriver.common.action_chains import ActionChains
eleCurrency = self.driver.find_element_by_css_selector("#currency")
eleUsd = self.driver.find_element_by_css_selector("#usd")
actHoverThenClick = ActionChains(seleniumDriverInstance)
actHoverThenClick.move_to_element(eleCurrency).move_to_element(eleUsd).click().perform()

2016年8月13日 星期六

python3 在 ubuntu 下安裝 lxml 模組

sudo apt-get install libxml2-dev
sudo apt-get install libxslt1-dev
python3 -m pip install lxml

python3 zipfile 解壓縮 zip 檔

from zipfile import ZipFile

with ZipFile("z.zip", "r") as zipFile:
    zipFile.extract("file_path_in_zip.xml", "folder_path_to_extract")

python3 使用 urllib 執行登入範例

無法查看此摘要。請 按這裡查看文章。

2016年7月26日 星期二

python 使用 smtplib 透過 gmail 寄信

首先要將 google 帳號切換為
低安全性應用程式,設定網址:
https://www.google.com/settings/security/lesssecureapps
選擇開啟

程式碼範例:
import smtplib
from email.mime.text import MIMEText

DEFAULT_SMTP = "smtp.gmail.com:587"
DEFAULT_ACCOUNT = "xxxxx@gmail.com"
DEFAULT_PASSWORD = "******"

#帳號密碼
strSmtp = DEFAULT_SMTP
strAccount = DEFAULT_ACCOUNT
strPassword = DEFAULT_PASSWORD

#郵件內容
msg = MIMEText(strMsg)
msg["Subject"] = strSubject
msg["From"] = strFrom
msg["To"] = strTo

#傳送
server = smtplib.SMTP(strSmtp)
server.ehlo()
server.starttls()
server.login(strAccount, strPassword)
server.sendmail(strAccount, lstStrTarget, msg.as_string())
server.quit()

2016年7月21日 星期四

[python] 去除 list 裡重覆的資料

source_list = [1,2,3,4,5,6,1,2,3,4]
new_list = list(set(source_list))
print(new_list)

[1,2,3,4,5,6]

2016年7月16日 星期六

Ubuntu 下讓 mysql 綁定在 0.0.0.0 讓非 localhost 的電腦也能連接

修改 /etc/mysql/my.cnf
bind-address = 0.0.0.0

重啟 mysql
sudo service mysql restart

以 root 登入 mysql
mysql -u root -p

建立兩個同名的使用者 接受 localhost 及 % 連線
CREATE USER 'user_name'@'localhost' IDENTIFIED BY 'user_pwd';
CREATE USER 'user_name'@'%' IDENTIFIED BY 'user_pwd';

授權操作權限至 db
GRANT ALL ON db_name.* TO 'user_name'@'localhost'; 
GRANT ALL ON db_name.* TO 'user_name'@'%';

執行
FLUSH PRIVILEGES;

離開
EXIT;

2016年7月10日 星期日

python url encode/decode

環境是 python 2.7 下:

import urllib

#測試初始 unicode 字串物件
strUnicode = u"test data"

#字串型態為 UNICODE
type(strUnicode)
<type 'unicode'>

#開始 url encode,先將 unicode 編碼為 utf-8,再 url encode (quote),得到 utf-8 字串物件
strResult = urllib.quote(strUnicode.encode("utf-8"))
type(srtResult)
<type 'str'>

#開始 url decode,將上面的結果進行 url decode (unquote),再解碼回 unicode 字串物件
 strResult = urllib.unquote(urllib.quote(u_str.encode("utf-8"))).decode("utf-8")
type(srtResult)
<type 'unicode'>

python 之禪,中英文合圖


blogger 文章加入含有 <> 的文字而不會打亂排版

編寫文章時右方的選項打開
撰寫模式選擇 按照字面顯示HTML
即可:



測試
<html>
    <p>我是一個 html</p>
</html>

2016年7月9日 星期六

ubuntu 下改 mysql 編碼


查詢目前資料庫編碼
mysql> status;
...
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8

設定並重啟
$ sudo vi /etc/mysql/conf.d/charset.cnf

[client]
default-character-set=utf8

[mysqld]
character-set-server=utf8
collation-server=utf8_unicode_ci

$ sudo service mysql restart

再查詢一次
mysql> status;
...
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8

ubuntu 下查看 TCP port 被哪個程式使用

  • sudo netstat -tulpn

2016年7月8日 星期五

deploy django + mysql + ubuntu + apache

sudo apt-get update 
sudo apt-get upgrade

安裝 apache
sudo apt-get install apache2

安裝 Django less than 1.9
sudo apt-get install python3-pip
sudo python3 -m pip install "Django<1.9"

安裝 apache 模組 - wsgi
sudo apt-get install libapache2-mod-wsgi-py3

安裝 mysql 過程會設定 mysql root 密碼
sudo apt-get install mysql-server libapache2-mod-auth-mysql

安裝 mysql 官方 python-connector
到 mysql 下載 mysql-connector-python-py3_2.1.3-1ubuntu14.04_all.deb
sudo dpkg -i mysql-connector-python-py3_2.1.3-1ubuntu14.04_all.deb

測試登入 mysql
mysql -u root -p

mysql 設定檔 /etc/mysql/conf.d
修改資料庫編碼 文章連結

新增資料庫
mysql>create datebase db_name;

顯示所有資料庫
mysql>show datebases;

mysql 新增使用者與設定權限
以下為 mysql shell 內使用的命令
use mysql;
INSERT INTO user(host,user,password) VALUES('localhost','user_name',password('user_pwd'));
FLUSH PRIVILEGES;
GRANT ALL ON db_name.* TO 'user_name'@localhost IDENTIFIED BY 'user_pwd';
FLUSH PRIVILEGES;
以上為 mysql shell 內使用的命令

新增 django 專案
django-admin startproject my_proj

同步 django ORM model 到 mysql TABLE
cd my_proj
python3 manage.py makemigrations
python3 manage.py migrate

/etc/apache2/sites-available 下新增 my_proj.conf
<VirtualHost *:80>
 
    WSGIScriptAlias / /home/ubuntu/git_code/my_proj/my_proj/wsgi.py
    <Directory /home/ubuntu/git_code/my_proj/my_proj>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    Alias /static /home/ubuntu/git_code/my_proj/static
    <Directory /home/ubuntu/git_code/my_proj/static>
        Require all granted
    </Directory>
 
    WSGIDaemonProcess my_proj python-path=/home/ubuntu/git_code/my_proj:/usr/local/lib/python3.4/dist-packages
    WSGIProcessGroup my_proj
 
</VirtualHost>

套用 site 設定
sudo a2ensite my_proj.conf
sudo service apache2 reload

重啟 apache
sudo service apache2 restart

amazon web services 修改主機名稱

在 AWS 申請主機登入後,
bash 的提示符號很醜,ex:

ubuntu@ip-123-456-789-012:~

只要修改 hostname 就可以改為較順眼的顯示方式

sudo hostname bennu.com

重新登入後就變成

ubuntu@bennu.com:~

而如果需要更客製化的提示符
就要去修改 ~/.bashrc 的 PS1 變數了

2016年6月4日 星期六

用戶密碼加解密概念-client版

client........................network..................................server

step1
................................................................................create
input rawpwd
salt(fixed) + rawpwd ==sha256==> encode1
salt_encode1...  .....................https.........................save salt_encode1 to database

step2
.............................................................................. validate
input rawpwd
salt + rawpwd ==sha256==> encode2
salt_encode2... .... .....................https....................load salt_encode1 from database
...............................................................................test if  encode2 equals to encode1

用戶密碼加解密概念-server版

client..........network............................server

step1
.........................................................create
rawpwd.................https...................salt(random) + rawpwd ==sha256==> encode1
.........................................................save salt_encode1 to database

step2
.........................................................validate
rawpwd.................https.. ................load salt from salt_encode1 in database
.........................................................salt + rawpwd ==sha256==> encode2
.........................................................test if  encode2 equals to encode1

2016年5月23日 星期一

[Django] 設定 Django 使用 MySQL 做為資料庫

首先是版本

MySQL 我使用目前最新 社群版(免費版) 5.6.28
安裝時 附帶一起安裝 mysql-connector-python 2.1.3 模組
這是MySQL官方自己出的 connector 但與 Django 最新版 (1.9.x) 不完全相容
因此,我們必須捨棄最新版本的 Django,pip 安裝時加上:


python3 -m pip install "Django<1.9"


這樣就可以安裝 1.8.x 的最新版本 ,需注意後面的 "Django<1.9" 雙引號不可省略,
完成安裝後,在 Django 的 project 目錄下的 setting.py,資料庫設定的部分:


DATABASES = {
    'default': {
        'ENGINE': 'mysql.connector.django',
        'NAME': 'datebase_name',
        'USER': 'datebase_user_name',
        'PASSWORD': 'datebase_user_password',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
          'autocommit': True,
        },
    }
}
ENGINE 的部分是設定使用 MySQL 官方的 connector
完成後,執行 Django migrate 命令:

python3 manage.py migrate

若成功就會把 Django 的資料庫移轉到 MySQL 下了。

[python] regex 群組命名表示法

原本我只會

text = "123 is num"
re.match("^(\d+) is num$", text).group(1)

結果為 "123"

學了一下 Django 意外學到


text = "123 is num"
re.match("^(?P<num>\d+) is num$", text).group("num")
可以透過 ?P<variable_name>  為群組命名,程式碼可以更容易懂,還不錯。

2016年5月18日 星期三

[python] OAuth 取得 facebook 使用者的 id name email

1. 到 facebook developers頁面 建立一個 WWW APP ,可以得到一組 client id / client secret
下方填入自己的 WebService 網址。ex:


2.在系統的登入頁加入一個超連結,填入 上一步的 client id ,要向使用者索取的資源 scope, 以及使用者同意授權後,facebook 要將授權碼 redirect 的位址,我們填入自己的 WebService 位址。


href="https://www.facebook.com/dialog/oauth?
&client_id=1730077280596052
&scope=public_profile,email
&redirect_uri=http://bennu-aws.ddns.net:5000/fb_oauth"


3. 設計一個 WebService 接收 授權碼 code,使用 python Flask 框架。

@app.route("/fb_oauth", methods=["GET"])
def fbOauth():
    #接收授權碼
    strAuthCode = request.args.get("code", None, type=str)

4.將授權碼回傳給 facebook 換取 token,需要 client_id、client_secret、第3步得到的授權碼、以及第2步使用的 redircet_uri,facebook 就會回傳 token 回來

strAccessTokenUrlTemplate = "https://graph.facebook.com/oauth/access_token?
                                          &client_id=%s
                                          &redirect_uri=%s
                                          &client_secret=%s
                                          &code=%s"
strAccessTokenUrl = strAccessTokenUrlTemplate%
                                      (strFbClientId,
                                       "http://bennu-aws.ddns.net:5000/fb_oauth",
                                        strFbClientSecret,
                                        strAuthCode)
responseToken = urllib.request.urlopen(strAccessTokenUrl)
strToken =  responseToken.read().decode(responseToken.headers.get_content_charset())

5.使用 token 取得使用者的資料

responseUserData = urllib.request.urlopen("https://graph.facebook.com/me?
                                                                     &fields=id,name,email
                                                                     &" + strToken)
    strUserData = responseUserData.read().decode(responseToken.headers.get_content_charset())
    dicUserData = json.loads(strUserData)
    return (dicUserData["id"], dicUserData["name"], dicUserData["email"])

2016年5月15日 星期日

[python] unicode decode encode 的秘密

python 2.7
u"abc中文" == unicode 物件
"abc中文" == str 物件

python 3.x
u"abc中文" == unicode 物件
"abc中文" == unicode 物件

所以大多數問題出現在 python 2.7
以下使用 2.7 的觀點來看:

encode == 把 unicode 物件轉為 str 物件
strUTF8 = u"abc中文".encode("utf-8")  == str 物件
strBIG5 = u"abc中文".encode("big5")  == str 物件
strCP950 = u"abc中文".encode("cp950")  == str 物件

decode == 把 str 物件轉為 unicode 物件
strUTF8 .decode("utf-8") == unicode 物件
strBIG5.decode("big5") == unicode 物件
strCP950.decode("cp950") == unicode 物件

秘密:
如果 str 物件 執行 encode 相當於 "先 decode 為 unicode 再 encode", ex:

strBIG5.encode("cp950") == strBIG5.decode("ascii").encode("cp950")

重點在於 decode 過程會使用 python 的預設系統編碼 ascii 而不是使用 big5
造成 明明是呼叫 encode 卻報錯 "無法使用 ascii 進行 decode " 之類的奇怪結果


[python] 使用 pkg_resources 模組存取 package 裡面的檔案

import pkg_resources

strPkgFilePath = pkg_resources.resource_filename("package_name", "resource_file")

當資源存放在 package (含有 __init__.py 的資料夾)裡面時,
一但經過封裝上傳  pip install  之後,檔案路徑會與 os.path 取得的路徑不同,
os.path 是根據 "當前執行的目錄 (cwd)" 去做尋找,也就是說:

在 c:\ 下執行 會尋找 c:\package_name\resource_file
在 c:\dir\ 下執行會尋找 c:\dir\package_name\resource_file
不可能因為執行的 cwd 不同而到處搬移 resource_file 
於是會將 resource_file 存放在 package 下,pip install 後
resourc_file 會固定放在 C:\Python34\Lib\site-packages\package_name\resource_file
而要取得該位置,只要使用 pkg_resources.resource_filename 即可。

2016年5月14日 星期六

python 設定 setup.py 及 MANIFEST.in 封裝整個專案 並上傳至 pypi 的設定

setup.py

from setuptools import setup,find_packages

with open("README.txt") as file:
    long_description = file.read()

setup(
    name = "bennu",
    version = "0.3.2.dev2",
    keywords = ["bennu", "utility", "muchu"],
    description = "muchu's utility module",
    author = "MuChu Hsu",
    author_email = "muchu1983@gmail.com",
    license = "BSD 3-Clause License",
    url="https://github.com/muchu1983/bennu",
    long_description=long_description,
    packages = find_packages(),
    include_package_data = True,
    install_requires = ["Pillow>=3.0.0"],
    platforms = "python 3.3",
    entry_points = {"console_scripts":["bennu=bennu.launcher:entry_point"]},
    classifiers = [
        "Programming Language :: Python :: 3.3",
        ],
)

重點:
name 之後使用 pip install 要用到的名稱
version 每次上傳不得重覆,否則上傳會失敗,數字越大版本越新。
find_packages() 可以自動找出含有 __init__.py 的資料夾,省去一一指定。
install_requires 指定本專案相依的其他 pypi 專案,用 pip 安裝時也會被加入安裝。
entry_points 指定 專案的執行進入點 並建立 可執行檔 ["execuatable_name=package.package:function"]

MANIFEST.in

include LICENSE
recursive-include bennu_res *
recursive-exclude test *

搭配 MANIFEST.in 可以指定其他檔案是否要一起加入封裝

上傳

1. 登入,首次會問你 pypi 上的帳密,之後可以記錄
python setup.py register 
2. 包裝,將你的專案包裝成 zip (windows) 或 tar.gz (linux)
python setup.py sdist
3. 上傳至 pypi
python setup.py upload

成功的話,要先移除專案資料夾內生成的 dist/ 還有 .egg-info/
否則 pip 會以為你已經有最新版本了,若是其他電腦就沒差
之後就可以用
pip install name
來安裝專案
安裝後也可以直接執行 executable_name 來執行

ubuntu 下使用 headless browser PhantomJS

PhantomJS 是一個 無畫面 的 browser
非常適合用來與 selenium 配合進行 自動化測試或是爬蟲程式
例如:

#取得 selenium driver 物件
def getDriver(self):
    driver = None
    if os.name == "nt":
        #chromeDriverExeFilePath = os.sep.join(("bennu_res", "chromedriver.exe"))
        #driver = webdriver.Chrome(chromeDriverExeFilePath)
        phantomjsDriverExeFilePath = os.sep.join(("bennu_res", "phantomjs.exe"))
        driver = webdriver.PhantomJS(phantomjsDriverExeFilePath)
    if os.name == "posix":
        phantomjsDriverExeFilePath = os.sep.join(("bennu_res", "phantomjs"))
        driver = webdriver.PhantomJS(phantomjsDriverExeFilePath)
    return driver

selenium 用法 本篇暫不介紹

PhantomJS 下載之後只有一個執行檔,將他放在 selenium 可以讀取到的位置即可使用
在 ubuntu 環境下,有幾點要注意的是:
1. 必須 chmod 755 phantomjs 加入執行權限
2. 必須安裝 apt-get install fontconfig 套件

2016年5月11日 星期三

windows 下安裝 python scrapy 模組

目前 scrapy 僅支援 2.7 版本 python

安裝前準備:

0. 升級 pip
python2 -m pip install pip --upgrade
1. Visual C++ compiler for python 2.7
https://www.microsoft.com/en-us/download/details.aspx?id=44266
2. lxml 用 exe 安裝 (用 pip 直接裝有點問題)
https://pypi.python.org/pypi/lxml/3.6.0
3. pypiwin32 (用 pip 直接裝就可以了)
python2 -m pip install pypiwin32

準備完成:

python2 -m pip install scrapy

python 使用 global 時機

當 local 區域 要 assign 資料給 外部區域 的變數時,
就必須先在 local 區域 使用 global  宣告一個相同名稱的 區域變數:

g = 1

def  func():
global g
g = 2
若是單純取值,沒有 assign 的動作,則可以不宣告:
g = 1
def func():
print(g)

 

關閉 windows 休眠,釋放 C 槽大量容量

命令列
powercfg -h off

ssh key 備忘

ssh key 分為 公錀 與 私錀,成雙成對。
擁有私錀可以產生對應的公錀,但擁有公錀無法反推產生私錀。
公錀放在 server
私錀放在 client
linux 上 ssh-keygen  產生的 公錀 檔名為 id_rsa.pub
linux 上 ssh-keygen  產生的 私錀 檔名為 id_rsa
windows server 不支援 ssh 認証,故 公錀 一般只有 linux 格式
windows 由 puttygen 可將 id_rsa 轉為可在 windows 下 putty 使用的 .ppk 檔
也就是說 .ppk 檔 等於 windows 下使用的 私錀,與原本的 id_rsa 格式有些不同,
但功能相同,若要將 .ppk 檔 轉回 linux 下使用的 id_rsa

sudo apt-get install putty-tools
puttygen key.ppk -O private-openssh -o id_rsa

linux 公錀存放位置  ~/.ssh/authorized_keys (可同時放多組公錀)
linux 私錀存放位置 ~/.ssh/id_rsa
存取權限必須設定為
chmod 700 ~/.ssh
chmod 777 ~/.ssh/authorized_keys (可公開)
chmod 600 ~/.ssh/id_rsa (不可公開)
原因是....文章一開頭有說了:擁有.....吧拉吧拉吧拉。