在 Windows 下安裝官方預編譯 Boost 1.66.0

本篇 ShengYu 將介紹如何在 Windows 下安裝 Boost 1.66.0,
這版 boost 1.66.0 釋出日期是 2017/12/18,開始動手安裝 Boost 吧!

以下為我的系統環境:
作業系統:Windows 10
Visual Studio 2017 (msvc-14.1)
Visual Studio 2015 (msvc-14.0)
使用版本:boost 1.66.0

為了方便,這邊使用Prebuilt windows binaries
Visual Studio 2017 下載 boost_1_66_0-msvc-14.1-32.exe / boost_1_66_0-msvc-14.1-64.exe
Visual Studio 2015 下載 boost_1_66_0-msvc-14.0-32.exe / boost_1_66_0-msvc-14.0-64.exe
所有的版本下載boost_1_66_0-bin-msvc-all-32-64.7z

在 Windows 下使用 dirent.h

Dirent 是 C/C++ 程式在 linux 下讀取檔案與目錄資訊的函式庫,程式移植到 windows 下是沒有 dirent.h,解決方式為改寫成 win32 api 或使用 Dirent 這個專案的 dirent.h,它其實就是幫你轉換成 win32 api,為求快速開發我們通常選後者的方式。

官網:https://github.com/tronkko/dirent
到這裡下載

使用方法:在 windows 下由於 dirent.h,所以下載 Dirent 專案程式碼後,直接 include Dirent 專案裡的 dirent.h 即可,程式碼不須更改。

參考
[1] windows下MSVC兼容的dirent.h_10km的专栏-CSDN博客
https://blog.csdn.net/10km/article/details/51004888

Linux wget 下載檔案用法與範例

本篇記錄如何使用 Linux wget 指令來下載檔案。

Linux wget 指令下載檔案

以下載 wget 原始程式碼為例,wget 後面直接接上 URL 即可,

1
$ wget http://ftp.gnu.org/gnu/wget/wget-1.21.tar.gz

Linux wget 指令下載檔案並重新命名

承上例,如果下載的檔案想要另外重新命名的話,可以加上 -O 的參數,例如:wget <URL> -O <filename>,實際的指令如下所示,

1
$ wget http://ftp.gnu.org/gnu/wget/wget-1.21.tar.gz -O wget.tar.gz

Linux wget 指令擷取整個網站

wget 也可以用來擷取整個網站,範例如下,

1
2
3
4
5
6
7
8
# 擷取整個網站
$ wget --recursive --page-requisites --html-extension --convert-links http://xxxxxx.com/

# --recursive:遞迴下載,如果網址的部份為網站首頁的話,將會一層一層地將首頁所能連結到的所有頁面下載回來。
# --page-requisites:下載顯示網頁時所需的素材,像是圖片或是CSS。
# --html-extension:將檔名改為html,這樣才不會抓php網站而產生php檔案或是抓asp網站而產生asp檔案。
# --convert-links:將原本網站內所有站內的連結全都改為Local連結,這樣下載網站後才可以離線使用。
# --domains:只接受哪些網域下的網頁,可以多個網域,以逗號分隔。通常只會填入該網站的網域。

參考
[1] How to Rename File While Downloading with Wget in Linux
https://www.tecmint.com/rename-downloaded-file-with-wget-in-linux/
[2] How to rename the downloaded file with wget? - Stack Overflow
https://stackoverflow.com/questions/14306382/how-to-rename-the-downloaded-file-with-wget
[3] How to rename a downloaded file with Wget in Linux - Quora
https://www.quora.com/How-do-you-rename-a-downloaded-file-with-Wget-in-Linux

其它相關文章推薦
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux sed 字串取代用法與範例
Linux find 尋找檔案/尋找資料夾用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例
Linux tee 同時螢幕標準輸出和輸出到檔案用法與範例
Linux xargs 參數列表轉換用法與範例
Linux tail 持續監看檔案輸出用法與範例

Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例

本篇記錄如何使用 Linux 下的 du 指令來查詢硬碟剩餘空間。

查詢當下目錄的每個資料夾總共佔用硬碟多少(-d1 代表深度為1)

1
du -d1 -h

相關方法
使用 ubuntu 桌面版也可使用 disk 工具 來查詢硬碟剩餘空間。

其它相關文章推薦
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux sed 字串取代用法與範例
Linux find 尋找檔案/尋找資料夾用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux tee 同時螢幕標準輸出和輸出到檔案用法與範例
Linux xargs 參數列表轉換用法與範例
Linux tail 持續監看檔案輸出用法與範例
Linux wget 下載檔案用法與範例

Git 開新分支 branch

有時候 ShengYu 想要開新的分支作開發, 或者想要備份這個分支, 都可以透過下列方式完成唷!

根據現在的 HEAD 建立一個分支 branch

1
git checout HEAD -b <new branch name>

Git 修改上次的 commit

有時候 ShengYu 想加入某些檔案的修改在前一筆 commit 紀錄裡, 都是透過下面幾個指令就快速搞定囉!

將你想要加入的檔案用 git add 加一加, 最後在 git commit 後面加上 --amend
指令操作如下:

1
2
git add <filename>
git commit --amend

其他參考
git - How to modify existing, unpushed commit messages? - Stack Overflow
https://stackoverflow.com/questions/179123/how-to-modify-existing-unpushed-commit-messages
【狀況題】追加檔案到最近一次的 Commit - 為你自己學 Git | 高見龍
https://gitbook.tw/chapters/using-git/amend-commit2.html
【狀況題】修改 Commit 紀錄 - 為你自己學 Git | 高見龍
https://gitbook.tw/chapters/using-git/amend-commit1.html
Commit –amend【教學3 改寫提交】 | 連猴子都能懂的Git入門指南 | 貝格樂(Backlog)
https://backlog.com/git-tutorial/tw/stepup/stepup7_1.html

Python 寫藍芽 Service Discovery Protocol 通訊程式

到目前為止介紹了如何偵測鄰近的藍芽裝置,且建立兩種傳輸類型的連線,都是用固定的 Bluetooth address 和 port numbers,在實務上我們不推薦這麼做。

在 PyBluez 裡, 使用 服務發現協定 Service Discovery Protocol (SDP) 來動態地配置 port number 進行尋找是很簡單的。get_available_port 函式用來查找可用的 L2CAP 或 RFCOMM 的 port。advertise_service 函式用來廣播這個本地端 SDP 伺服器的服務,find_service 函式用來搜尋指定名稱的藍芽裝置。

1
bluetooth.get_available_port( protocol )

get_available_port 回傳指定 protocol 第一個可用的 port number。目前只有支援 RFCOMM 和 L2CAP protocols。get_available_port 只是回傳一個 port number,並沒有實際預定使用任何資源,所以有可能當你要 bind 時,這 port 已經被別人 bind 走了,如果發生的話 bind 會拋出一個BluetoothException 例外。

1
2
3
bluetooth.advertise_service( sock, name, uuid )
bluetooth.stop_advertising( sock )
bluetooth.find_service( name = None, uuid = None, bdaddr = None )

以上這三種函式用來廣撥服務,advertise_service 函式參數分別為 socket, service name 服務名稱, UUID,
這廣撥服務直到呼叫 stop_advertising 函式來關閉該 socket。

find_service可以搜尋單個或者所有附近特定裝置。透過匹配 name 和 UUID 進行 service 尋找(必須至少指定其中一個)。如果 bdaddr 是 None,那麼所有附近的設備都會進行尋找。如果提供了 localhost 作為 bdaddr 參數,那麼會對本地的 SDP 進行尋找。否則,就會指定的 bdaddr 藍芽裝置進行尋找。

server 端程式

rfcomm-server-sdp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import bluetooth

server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )

port = bluetooth.get_available_port( bluetooth.RFCOMM )
server_sock.bind(("",port))
server_sock.listen(1)
print "listening on port %d" % port

uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
bluetooth.advertise_service( server_sock, "FooBar Service", uuid )

client_sock,address = server_sock.accept()
print "Accepted connection from ",address

data = client_sock.recv(1024)
print "received [%s]" % data

client_sock.close()
server_sock.close()

client 端程式

rfcomm-client-sdp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sys
import bluetooth

uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
service_matches = bluetooth.find_service( uuid = uuid )

if len(service_matches) == 0:
print "couldn't find the FooBar service"
sys.exit(0)

first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]

print "connecting to \"%s\" on %s" % (name, host)

sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((host, port))
sock.send("hello!!")
sock.close()

參考
https://people.csail.mit.edu/albert/bluez-intro/x290.html

相關主題
Python 的第一支藍芽程式
Python 寫藍芽 RFCOMM 通訊程式
Python 寫藍芽 L2CAP 通訊程式

Hexo 本機測試時如何關閉 Google Analytics

ShengYu 最近在使用 Hexo 進行 hexo s 本機測試的文章時,發現這些瀏覽行為也會被 Google Analytics 給紀錄回傳出去,
但是這時候的行為大多數都是點擊測試看看連結有沒有作用, 然後關閉,
不然就是瀏覽整個版面有沒有正常文章有無順暢, 然後關閉,
這些不太像是正常使用者的行為,我想看的數據是真實使用者的數據阿!!不想紀錄這愚蠢的數據XD

如果不想讓以上這些本機開發測試的這些行為被 Google Analytics 給紀錄進去,
最好的方式就是在本機測試 hexo s 時, 先把 Google Analytics 拿掉,

位置在 themes/landscape/_config.yml,把裡面的 google_analytics: UA-xxxxxxxx-x 拿掉即可,
但每次前都要去拿掉,發布前要加回來,這動作一直重複且容易忘記,
這時可以寫成一個 script,ShengYu 自己的習慣是寫成 Makefile,

Makefile 範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server: remove_google_analytics generate
@hexo s -p $(PORT) --drafts

server_without_drafts: remove_google_analytics generate
@hexo s -p $(PORT)

deploy: add_google_analytics generate
@echo "Start deploy ..." && \
hexo d

generate: clean
@echo "Generate ..." && \
hexo g
clean:
@echo "Clean ..." && \
hexo clean

# 把 google analytics 移除, 避免用本機測試時上傳不真實數據
remove_google_analytics:
sed -i 's/'google_analytics:\ UA-xxxxxxxx-x'/'google_analytics:'/g' themes/landscape/_config.yml

# 發布前把 google analytics 加回來
add_google_analytics:
sed -i 's/'google_analytics:'/'google_analytics:\ UA-xxxxxxxx-x'/g' themes/landscape/_config.yml

這腳本包含了7個規則 (rule),那這個腳本要怎麼使用呢?
make server - 啟動本機網頁伺服器
(會先執行它的依賴規則,remove_google_analytics 和 generate)
也就是說,輸入make srever,會幫我們先執行 remove_google_analytics 這個規則,
再執行 generate 這個規則,最後執行 server 本身這個規則。
輸入一個指令就幫我們執行了三個規則了,好膩害!

make server_without_drafts - 啟動本機網頁伺服器,無草稿模式
make deploy - 發布
會先去執行它的依賴規則,先執行 add_google_analytics 這個規則,
再執行 generate 這個規則,最後執行 deploy 本身的規則。

make clean - 清除
make generate - 產生靜態網頁資料
make remove_google_analytics - 移除 google analytics id
make add_google_analytics - 加入 google analytics id
如果對 Makefile 規則不熟悉的話可以 Google 一下。

以上就是 ShengYu 目前在使用的腳本,是不是方便多了呢!哈哈!

相關文章
Hexo 使用 Google Analytics 進行網站流量分析
Hexo codeblock 插入程式碼區塊與各種程式語言預覽
升級更新 Hexo upgrade
Hexo 熱門主題列表
Ubuntu 安裝 Hexo
Mac OS 安裝 Hexo

Python 的第一支藍芽程式

ShengYu 會在本篇會介紹 Python 的擴充模組(PyBluez),可以讓你用幾行程式碼就很快速簡單地實現藍芽 bluetooth 相關功能。

Python 是一個多功能且強而有力的動態語言,支援物件導向,簡潔的語法,提供垃圾回收,自動管理記憶體使用,已至於程式設計師可以專注在演算法,而不用擔心記憶體洩漏或者其他阿雜事。

Python 雖然有很巨大很廣泛全面的內建標準函式庫,但內建標準函式庫卻還不包含藍芽的功能。PyBluez 是用 C 寫成的 Python 擴充模組,提供介面來去存取作業系統裡的藍芽裝置,支援 Windows, MacOS, Linux 和 Raspberry Pi。

第一支藍芽小程式

範例 findmyphone.py 演示了使用一個 Python 小程式去尋找附近名稱為 My Phone 的藍芽裝置。範例如下所示,請自行修改 target_name 成你要尋找的藍芽裝置名稱即可,

findmyphone.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import bluetooth

target_name = "My Phone"
target_address = None

nearby_devices = bluetooth.discover_devices()

for bdaddr in nearby_devices:
if target_name == bluetooth.lookup_name( bdaddr ):
target_address = bdaddr
break

if target_address is not None:
print "found target bluetooth device with address ", target_address
else:
print "could not find target bluetooth device nearby"

藍芽位址是由 xx:xx:xx:xx:xx:xx 的形式所組成,xx 為十六進制,怎麼查詢藍芽位址請看這篇,每個藍芽裝置都有個獨一無二的藍芽位址。但是如果我們要找”某個名稱”的藍芽裝置,而不是用藍芽位址去找,那會分成兩步驟:

以上述 findmyphone.py 為例,首先程式會先掃描附近的藍芽裝置,呼叫 discover_devices() 尋找附近的裝置(大概10秒),然後回傳一個列表,

再來,使用 lookup_name() 去連接上每個已偵測到的裝置,請求它們的裝置名稱,並且順便判斷名稱是不是我們要尋找的 My Phone target name,是的話會顯示找到並印出藍芽位址。

在區域內掃描藍芽裝置和查找裝置名稱這過程有時可能會失敗(空氣中其他的干擾等等不定因素,裝置很多,裝置在移動?!),discover_devices() 有會回傳 None,意味著無法用裝置名稱來進行後續的匹配,這時最好的解決方式就是多試幾次看看XD。

以上就是 ShengYu 為你介紹的第一支 Python 藍芽小程式,下一篇將會介紹 如何用Python的藍芽 RFCOMM 協定來通訊

參考
https://people.csail.mit.edu/albert/bluez-intro/c212.html

相關主題
Python 寫藍芽 L2CAP 通訊程式
Python 寫藍芽 Service Discovery Protocol 通訊程式