2017年3月29日 星期三

解決 geany 與新酷音輸入法相衝

Geany 在 linux mint 中文版與新酷音輸入法的 Ctrl + Space 相衝,只要修改快速鍵定義就可以了:
1. 求助(H) -> 快速鍵(K)
往下拉到 "補完字詞" , 它的設定正好是 Ctrl + Space
2. 點選 Edit
    往下拉到 "補完字詞" , 點選並修正此快速鍵的定義
3. 重新開啟 Geany


另外透過安裝完 js-beautify可以啟用 javascript 的美化功能, 先安裝好 js-beautify
     sudo npm -g install js-beautify
再來開啟 Geany  自訂命令, 透過滑鼠右鍵叫出選單:
      格式(F) -> 發送選取區域到(S) -> 設定自訂命令 -> Add
命令欄填入 js-beautify
按 OK 完成設定,
之後將所選的文字並透過滑鼠右鍵叫出選單傳給自訂命令:
      格式(F) -> 發送選取區域到(S) -> js-beautify
也可以用它所定義的快速鍵(Ctrl+1 ...等等)直接美化所選的文字區域

另外也可以 uglify-js 來醜化或美化, 若要支援 ES6, 可以安裝 harmony版本的 Uglifyjs2
   sudo npm install uglify-js@github:mishoo/UglifyJS2#harmony -g
若不加任何參數,它內定會將 javascript 醜化,加上參數 -b 或 --beautify 可以改成美化的功能, 因此命令列若改用:
  uglifyjs -b

  uglifyjs --beautify
就相當於
  js-beautify
的功能
但 ulifyjs --beautify 功能比不上  js-beautify 來的好用, 習慣上還是直接用 js-beautify 就好

2017年3月28日 星期二

linux mint 18 安裝 brackets

1. 到  http://brackets.io/ 下載 brackets binary
    sudo wget https://github.com/adobe/brackets/releases/download/release-1.9/Brackets.Release.1.9.64-bit.deb
2. 安裝遺失的library: libgcrypt11 及 libcurl3
    sudo wget https://launchpad.net/~ubuntu-security-proposed/+archive/ubuntu/ppa/+build/7110687/+files/libgcrypt11_1.5.4-2ubuntu1.1_amd64.deb
    sudo apt deb libgcrypt11_1.5.4-2ubuntu1.1_amd64.deb
    sudo apt-get install libcurl3
3. 最後安裝所下載的 brackets
    sudo apt deb Brackets.Release.1.9.64-bit.deb
4. 喜愛的插件(extensions):
    Autoprefixer
    Beautify
    Bracket Color Picker
    Bracket Git
    Emmet
    Inline Regex Editor
    Integrated Development
    Markdown Preview
    Match Highloghter
5.喜愛的佈景主題:
    DarkSoda

升級 nodejs


為了使用 nodejs 6.10.1 升級指令:
1. curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
2. sudo apt-get install -y nodejs

// javascript 程式使用 class
class ClassA {
    constructor(name) {
        this.aliasName = name;      
    }
    get name() {
        return this.aliasName.toUpperCase();
    }
    set name(name){
        if(name){ 
            this.aliasName = name;
        }
    }   
}
class ClassB extends ClassA {
constructor(name) {
super(name);// super needs to be called first
this.newp = function(){console.log("Hi"); }
}
}
let a = new ClassB("first"); // invoke constructor
console.log(a.aliasName+' : '+a.name); // invoke getter
a.name = "second"; // invoke setter
console.log(a.aliasName+' : '+a.name);// invoke getter
a.newp();

2017年3月23日 星期四

node js 使用 events 及 child_process

// 內建的 events,  產生 events.EventEmitter() 後,就可以定義/註冊(附帶一提: .on() 或 .addListener() 兩者功能相同只是名稱不同而已)事件監聽器(event listenter), 之後透過 .emit() 來觸發該條件, 同時將參數傳遞給 event_Listener(callback function)讓它動起來

// events.js
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('bing', console.log);//  .on(event_Pattern, event_Listenter)
emitter.emit('bing','go');          //  .emit(event_Pattern, parameters_to_Listener)

// 內建的 child_process,  裡面的 .exec(), .spawn(), .fork()  可以讓指令平行處理, 如果要做自動化程序它是一個很好用的模組
//          .exec()  --> 開啟環境執行另一條系統指令, 可以攜帶 error,stdout.stderr,如有需要, 可以自行處理 callback function
//          .spawn() --> 開啟環境執行另一條系統指令, 使用 events 來處理指令所帶進來的資料
//          .fork()  --> 開啟環境執行另一份 javascript, 並使用 events 來處理指令所帶進來的資料, 其實等同用 .spawn() 開啟環境執行指令前面加上 js 來執行 javascript

// test.js
const process = require('child_process');
for(var i=0; i<2 i="" p="">   var exec = process.exec('js events.js',function(err, stdout, stderr) {    
      if (err)  console.log('stderr: ' + stderr);
      else      console.log(stdout);
   });

   exec.on('exit', function (code) {
      console.log('process exist code='+code);
   });
}

2017年3月21日 星期二

node js 使用 redis 資料庫

1. 先安裝好 redis-server:
      sudo apt-get install redis-server
2. 編輯修改 redis 的設定: /etc/redis/redis.conf, 將 requirepass 這個註解取消, 並填上自行設定的密碼, 剛開始可以用  '123456' 來測試看是否運作正常, .之後記得要改掉.
3. 重新啟動 redis server:
     sudo /etc/init.d/redis-server stop
     sudo /etc/init.d/redis-server start
4. node js 是使用 createClient(port, host, auth_pass)  api 來連線
5. 為了避免非同步程式出現callback hell(輪迴地獄), 並讓程式看起來簡潔比較好理解一點,可以使用 bluebird 這隻 Promise 模組, 用 npm 就可以直接安裝, 用 require('bluebird') 導進程式後就可以使用了:
    npm install bluebird --save
6. 經過 promisifyAll 的 redis API 會帶有 Async 的尾綴詞,  是因為它都是非同步的API,  因此 .on() 須改為 .onAsync(), .get() 須改用 .getAsync(), .set() 須改用 .setAsync(), 當然原先 API 還是可以使用, 只不過程式寫起來會很累綴. 對於像是 , .on('error', console.log) 就可以直接顯示錯誤訊息,其實並不需要使用經 promisify 過的 API:

// redisTest.js
var Promise = require("bluebird");
var redis=Promise.promisifyAll(require("redis"));
var port=6379;
var host='127.0.0.1';
var auth_pass={auth_pass:'123456'};
var service=redis.createClient(port, host, auth_pass);

service.onAsync('ready').then( function() { // console.log('ready');
    service.getAsync('version').then(function(reply) {
        if( reply !== null ) { console.log(reply); return ; }
        service.setAsync('version','1.0.0.0').then(function(reply) {
            console.log(reply); // should be 'OK'
        })
    })
})

service.on("error",console.log);

2017年3月19日 星期日

用 node js 及 express 寫個簡單的 https server

// 參考文章:
//  https://nodejs.org/api/https.html
//  http://stackoverflow.com/questions/11744975/enabling-https-on-express-js
// npm install express

// exps.js
var https   = require("https");
var fs      = require("fs");
var url     = require("url");
var path    = require("path");
var express = require("express");
var options = {
    key:  fs.readFileSync('mypass.key'),
    cert: fs.readFileSync('mypass.crt')
};

function getDOC(req,res) {
    var uri = url.parse(req.url).pathname;
    var filename = path.join(process.cwd()+"/www", uri);                    // add doc root: /www
    fs.access(filename, function(accessErr) {
        if(accessErr) {   res.send("File not found");  return; }
        if (fs.statSync(filename).isDirectory()) filename +='/mybaby.htm';  // default html document
        fs.readFile(filename, "binary", function(err, file) {
            if(err) { res.send(err); return; }        
            res.writeHead(200);
            res.write(file, "binary");
            res.end();
        });      
    })
}
 
var app = express();
    app.get('/*',getDOC);

var server=https.createServer(options, app);
server.listen(4443, function() {
console.log("HTTPS sever started at port %s",server.address().port);
});

// 再寫個 Makefilet 產生 ssl 所需要的檔案及目錄,方便使用及執行.
// Makefile
run: genkey exps.js
@js exps.js

genkey: mypass.crt www

mypass.key:
openssl genrsa -out mypass.key 2048
mypass.csr: mypass.key
openssl req -new -key mypass.key -out mypass.csr
mypass.crt:  mypass.csr mypass.key
openssl x509 -req -in mypass.csr -signkey mypass.key -out mypass.crt
www:
mkdir www

clean:
rm -f mypass.*

2017年3月18日 星期六

nodejs 中關於 exports 及 module.exports

參考文章: http://stackoverflow.com/questions/16383795/difference-between-module-exports-and-exports-in-the-commonjs-module-system
當使用 require() 載入模組時, 它回傳回一個物件{}, 該物件由 module.exports 所參考. 而 exports 實際上也指向 module.exports, 實體是同一個.如果沒意外,兩者都可以用來傳回想要使用的函數或特性.這個例外就是將 exports 重新指向新的實體, 因為 require 實際上是 return module.exports 裡面的物件,而module.exports 剛開始預設是一個空的實體, 如果將 exports 重新指向新的實體(例如 exports={a:'a', b:'b'}),它會導致exports 與 module.exports 分別指向不同個體. 但如果是使用句點添加成員的方式,在exports上添加新成員(例如 exports.name='name'),實際上等同在原先的實體(module.exports)上去添加新成員(等同module.exports.name='name'),那兩者用法就無分別. 如果因此會混淆,那就不要管 exports. 直接用 module.exports 就不會錯了.


2017年3月4日 星期六

複習sketchup畫房屋的技巧

1. 滑鼠中鍵按住不放可以旋轉視角,若再搭配鍵盤 shift 鍵可以平移視角,滑動滑鼠中鍵可以放大或縮放視角, 附帶一提的是在 Librecad 裡,按住滑鼠中鍵不放是直接平移視角.兩者是不同的

2. 先畫俯視平面圖,牆面先用左邊工具欄"長方形"及"筆"勾勒好輪廓.畫線條時搭配鍵盤 shift 鍵可以鎖住要畫線的方向,方便勾勒出垂直軸線的直線

3. 將各個房間及牆面線條先分類放在不同層(layer),層面設定可透過上方表單列: 視窗(W) -> 預設面板 -> 顯示面板, 將它打開, 在層面視窗 '+' 號可添加層面, '-' 號可刪除層面.中文版可以用中文替層面命名,

4. 從 3D warehouse (視窗(W) ->  3D warehouse) 抓出的元件,先放好在一個固定的層面,並將它定位到俯視圖面上,當所有要用的3D元件放置完,再將該層面關閉,避免影響製圖及電腦的運算速度.

5. 左邊工具欄旋轉工具可以對任何元件以任何可抓取到的點為圓心再設定旋轉軸及角度旋轉就可旋轉物件,若再搭配鍵盤Ctrl鍵可以將元件複製一份, 直接輸入尺寸可以精準控制所要旋轉的角度.

6. 左邊工具欄移動工具可以對任何元件以任何可抓取到的點為參考點,再設定移動距離就可將元件重新定位,若再搭配鍵盤Ctrl鍵可以將元件複製一份, 直接輸入尺寸可以精準控制所要移動距離.

7. 搭配Ctrl鍵複製元件時,定位後再輸入 ’*’符號緊跟著數字,可以複製出想要的數量,所輸入的距離將成為’相對距離',若是使用旋轉工具,所輸入的旋轉角度將成為’相對角度'

8. 若是使用滑動滑鼠中鍵放太大,結果失焦時,左邊工具欄一個含有’方向箭頭的放大器’按一下,就可讓所有元件都重回視線內

p.s.
1. 若是Sketchup pro 版可以import dxf 檔當背景作為描繪底稿, dxf 可以用 Librecad 當畫平面圖的工具,還蠻好用的, 當然直接用 Sketchup 也可以, 只是因為在 3D 世界裡要畫出平面圖並不是很容易

2. Librecad 抓取自製元件(View -> ToolBars -> Block List 先打開視窗顯示, 接著使用 File -> Import -> Block 引入檔案裡面來使用), 層面最好不要使用中文命名, 以免 dxf 檔案相容會有問題.

3.  在 Librecad裡面, 層面透果 view -> Toolbars -> Layer List 可以將它打開