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 (不可公開)
原因是....文章一開頭有說了:擁有.....吧拉吧拉吧拉。

2013年1月20日 星期日

高架橋下的相遇

寒冬的夜晚
沒有路燈的陸橋下
我又餓又累己經再也沒有力氣
我慢慢的躺下
只想好好的睡上一覺
才閉上眼睛沒多久
就聽到一個轟隆隆的聲音
聲音越來越近越來越近
吵得我無法乎視
不得不睜開眼坐起身來
是一個騎著打檔車的人類停在我的面前
到底是想幹麻阿
這麼晚了快回去你的家阿
人類催動油門在我身旁騎了一圈
我是犯著你了嗎
走開好嗎
突然  他衝向我
shit 我只好馬上起身往旁邊閃
是想撞我嗎 
吃飽太閒阿
人類怎麼都這麼混帳
但我知道我無力對抗
只好慢慢走到路旁的草叢中
從草叢裡看著外面那個發神經的人類
不要再過來了拜託
還好
他真的沒過來了
轉動機車把手慢慢騎走了
這世界到底怎麼了
當一只流浪狗就一定要這樣被欺負嗎
閉上含著不干心而淚濕著雙眼
我沉沉的睡著了

老婆阿跟你說
今天我在回來的路上
看到一隻白痴的黑狗
大半夜的就直接躺在大馬路中間睡覺
還好我有去趕走他
不然阿牠今晚就昇天了吧

有些人對你不好
卻是為你好


2011年10月6日 星期四

debian 上的 android sdk 安裝BUG

這是 Debian-based 的 Linux 特有的 bug...
事情發生在安裝好 sun-java6-jdk, eclipse, ADT 之後,打開 Window -> Android SDK and AVD manager 時,Eclipse 的 Console 視窗會開始一直跳出下面這樣的訊息
[2010-03-04 23:04:42 - ddms]Failed to reopen debug port for Selected Client to: 8700
[2010-03-04 23:04:42 - ddms]不適用的引數
java.net.SocketException: 不適用的引數
at sun.nio.ch.Net.bind(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:119)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:52)
at com.android.ddmlib.MonitorThread.reopenDebugSelectedPort(Unknown Source)
at com.android.ddmlib.MonitorThread.run(Unknown Source)

[2010-03-04 23:04:42 - DeviceMonitor]Connection attempts: 1
[2010-03-04 23:04:43 - DeviceMonitor]Connection attempts: 2
[2010-03-04 23:04:45 - DeviceMonitor]Connection attempts: 3

拜過谷歌大神後,得到解法如下
sudo sysctl -w net.ipv6.bindv6only=0

重開機後也要保持設定值,則修改 /etc/sysctl.d/bindv6only.conf 裡的的設定值為
net.ipv6.bindv6only = 0

2011年3月14日 星期一

星海二-自由之翼遊戲界面缺字問題解法

To add nopat to grub, open a console and edit /etc/default/grub

> sudo nano /etc/default/grub

Change the line:
> GRUB_CMDLINE_LINUX=""

to
> GRUB_CMDLINE_LINUX="nopat"

Save and exit, then run:
> sudo update-grub

再重開機就好了,雖然level不到不知道為何會這樣。