Total Pageviews

2016/12/31

2016/12 高雄

高雄彩虹教堂
DSC00946

高雄風車公園
DSC00950

DSC00953


駁二藝術特區
DSC00978


紅毛港文化園區
DSC00980
DSC00983


武德殿
DSC00998
DSC01014


鳳儀書院
DSC01028
DSC01055





2016/12/13

[iPhone] 無法連上VPN ,錯誤 619 : 無法建立與遠端電腦的連線,因此已關閉用於此連線的連接埠

Problem
因為工作關係,需要透過 VPN 連上另外一個工作地點的伺服器作業,其採用 PPTP 此通信協定


我利用 iPhone (手機作業系統為 iOS 10) 做為我連外的網路,但在一直遇到 VPN 連線錯誤,錯誤訊息如下:「錯誤 619 : 無法建立與遠端電腦的連線,因此已關閉用於此連線的連接埠」


How-To
經過幾天的搜尋資料與更改設定,仍舊無法解決此怪異的問題,一直看到 apple 的官網的一段描述
如果您設定了 PPTP VPN 伺服器,iOS 10 和 macOS Sierra 使用者將無法連線到該伺服器。iOS 10 和 macOS Sierra 會在使用者升級裝置時,移除任何 VPN 描述檔的 PPTP 連線。(If you’ve set up a PPTP VPN server, iOS 10 and macOS Sierra users won't be able to connect to it. iOS 10 and macOS Sierra will remove PPTP connections from any VPN profile when a user upgrades their device.)
此時改用其他人的手機 (如 android 手機或 iOS 10 以前的手機),卻可以成功連上 VPN ,代表是 iOS 將 PPTP 的 VPN 連線拒絕了,此時只能改用非 iOS 10 的手機來連線,或是更改 VPN Server 的協定,改用更安全的 L2TP/IPSec、IKEv2/IPSec 或 Cisco IPSec 等 protocols


Reference
[1] https://support.apple.com/zh-tw/HT206844
[2] https://mrmad.com.tw/upgrade-ios10-macos-sierra-pptp
[3] https://discussions.apple.com/thread/7673183?start=0&tstart=0

2016/12/11

[Windows 7] 如何將遠端的電腦重開機

Problem
當我透過遠端桌面連線來連到遠端的電腦時,若因某些緣故要重開遠端的電腦,但是其只有三個選項:登出、中斷連線與鎖定,無法從遠端重開




How-to
可以透過指令的方式達到重開機的目的,如 10 秒鐘後自動重開機,指令如下:
shutdown -r -t 10

若要關機,可以透過指令的方式達到關機的目的,如 10 秒鐘後關機,指令如下:
shutdown -s -t 10


Reference 
[1] https://technet.microsoft.com/en-us/library/bb491003.aspx

2016/12/10

[Windows 7] 無法遠端連線

Problem
當我要從我的電腦透過遠端桌面連線到另外一台電腦時,發生無法連線的錯誤



How-to
解決步驟如下 (以下設定是在遠端的電腦)
步驟 1. 於搜尋視窗輸入 gpedit.msc

步驟 2. 開啟本機群組原則編輯器後,透過左方目錄樹,到電腦設定→系統管理範本→Windows元件→遠端桌面服務→遠端桌面工作階段主機→連線 資料夾

步驟 3.  啟用 "允許使用者使用遠端桌面服務從與端連線"、設定 "限制連線數目" 為 999999 表示無限制連線數目




2016/12/09

[iPhone] 電腦與 iPhone 中的 google map 的 my map 資訊不一致

Problem
當我們在自助旅行時,會利用google map來做行程規劃 (如 http://goo.gl/iTD6d8 ),但是在 iPhone 使用上遇到一個問題,當我在電腦版的 google map 做了變動以後,在 iPhone 上的 google map app,卻沒有更新

How-to
1. 打開 google map app
2. 點選 Settings


3. 點選 About, terms and privacy


4. 點選 Clear Application Data


5. 點選 OK後, app 就會自動抓到最新的 map 資訊



Reference
[1] https://goo.gl/A306g0

2016/12/08

[Chrome Extension] Background Pages

A common need for extensions is to have a single long-running script to manage some task or state. Background pages to the rescue.

Assume I have a simple requirement, I hope it will print current timestamp each 3 seconds in background.

Steps are as bellows:

1. Define background scripts in manifest.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "manifest_version": 2,
  "name": "Build Chrome Extension With AngularJS",
  "description": "利用 AngularJS 建置 Chrome Extension ",
  "version": "1.0",
  "permissions": [ "activeTab", "storage"],
  "browser_action": {
    "default_icon": "img/icon.png",
    "default_popup": "todo.html",
    "default_title": "Build Chrome Extension With AngularJS"
  },
   "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Alt+Shift+D"
      }
    }
  },
  "background": {
    "scripts": ["js/background.js"]
  },
  "options_page": "options.html"
}


2. Create background.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var myVar = setInterval(myTimer, 3000);

function myTimer() {
    var now = new Date();
    var year = now.getFullYear();
    var month = now.getMonth() + 1;
    var date = now.getDate();
    var hour = now.getHours();
    var minutes = now.getMinutes();
    var seconds = now.getSeconds();
    var time = year + '/' + month + '/' + date + ' ' + hour + ':' + minutes + ':' + seconds;
    console.log(time);
}


3. Reload extensions and open background page to test





2016/12/07

[Apache POI] java.lang.IllegalArgumentException: The maximum length of cell contents (text) is 32,767 characters

Problem
I am using Apache POI to write data into Microsoft Excel, but it throw this exception during the process:
java.lang.IllegalArgumentException: The maximum length of cell contents (text) is 32,767 characters


Here is the code snippet, this exception result from line 12:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
                                          List<ColumnIndex> customFieldDefinitions) {
        Cell cell = row.createCell(0);
        cell.setCellValue(issue.getId()); // 編號
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue(issue.getSubject()); // 主旨
        cell.setCellStyle(style);

        cell = row.createCell(2);
        cell.setCellValue(issue.getDescription()); // 敘述
        cell.setCellStyle(style);

    }



Solution
According to Apache POI's source code, it will check the maximum length of each cell cannot be larger than 32,767 characters.
https://github.com/apache/poi/blob/31f2b5fdd10c7442576cbed5d37507cb2cdf11cc/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java#L574-L576    


And it is also XLS's imitation, so we need to do substring or use XLSX format instead. We choose the former option. Therefore, my source code should be modified as following:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
    private void writeIssueDataForEachRow(Issue issue, Row row, CellStyle style,
                                          List<ColumnIndex> customFieldDefinitions) {
        Cell cell = row.createCell(0);
        cell.setCellValue(issue.getId()); // 編號
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue(issue.getSubject()); // 主旨
        cell.setCellStyle(style);

        // substring 的原因是要避開 The maximum length of cell contents (text) is 32,767 characters
        cell = row.createCell(2);
        cell.setCellValue(StringUtils.substring(issue.getDescription(), 0, 32767)); // 敘述
        cell.setCellStyle(style);

    }


Reference
[1] https://support.office.com/en-us/article/Excel-specifications-and-limits-16c69c74-3d6a-4aaf-ba35-e6eb276e8eaa?CorrelationId=c8dcbafe-51ff-447e-bd62-3c1ce0e1d05e&ui=en-US&rs=en-US&ad=US&ocmsassetID=HP010073849

2016/12/06

[Chrome Extension] Use the chrome.storage API to store, retrieve, and track changes to user data

Requirement
I would like to store user data for my chrome extension, I can use either storage.sync or storage.local. 
When using storage.sync, the stored data will automatically be synced to any Chrome browser that the user is logged into, provided the user has sync enabled.

In the following example, I will utilize storage.sync to fulfill this requirement


How-To
Steps are as bellows:
1. Add options_page and storage permissions in manifest.json 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
  "manifest_version": 2,
  "name": "Build Chrome Extension With AngularJS",
  "description": "利用 AngularJS 建置 Chrome Extension ",
  "version": "1.0",
  "permissions": [ "activeTab", "storage"],
  "browser_action": {
    "default_icon": "img/icon.png",
    "default_popup": "todo.html",
    "default_title": "Build Chrome Extension With AngularJS"
  },
   "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Alt+Shift+D"
      }
    }
  },
  "options_page": "options.html"
}


2. Add options.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
    <title>設定初始工作</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="js/angular.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
    <script src="js/options.js"></script>
</head>

<body>
    <div ng-app="optionsApp" ng-controller="optionController" class="container" >
        <div class="row">
            <label>inital task:</label>
            <input id="initialTask" name="initialTask" ng-model='initialTask' autofocus="true">
            <button id="save" class="btn btn-primary btn-md" ng-click="addInitialTask()">
                <i class="glyphicon glyphicon-pencil"></i>
            </button>
        </div>        
    </div>

</body>
</html>


3. Add options.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
angular.module('optionsApp', [])
    .controller('optionController', function($scope) {
      
      $scope.initialTask = '';

      $scope.addInitialTask = function () {
        var initialTask = $scope.initialTask;
        // Save data using the Chrome extension storage API.
        chrome.storage.sync.set({
          'initialTask' : initialTask
        }, 
        function () {
          alert("設定成功!");
        });
      }
});

function init(){
  // Get data using the Chrome extension storage API.
  chrome.storage.sync.get(
      'initialTask'
  , function(data) {
    document.getElementById('initialTask').value = data.initialTask;   
  });
}

// call init function as page loaded
document.addEventListener('DOMContentLoaded', init);


4. Reload extension and do test


Reference
[1] https://developer.chrome.com/extensions/storage

2016/12/05

[Chrome Extension] Create a simple chrome extenstion with AngularJS 1.X

The steps are as bellows:

1. Download AngularJS 1 from https://angularjs.org/

2. Download Bootstrap from https://getbootstrap.com/

3. Create manifest.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "manifest_version": 2,
  "name": "Build Chrome Extension With AngularJS",
  "description": "利用 AngularJS 建置 Chrome Extension ",
  "version": "1.0",
  "permissions": [ "activeTab" ],
  "browser_action": {
    "default_icon": "img/icon.png",
    "default_popup": "todo.html",
    "default_title": "Build Chrome Extension With AngularJS"
  }
}

4. Create popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html style="min-width:220px;">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Todo list Page</title>
        <script src="js/angular.min.js"></script>
        <script src="js/todo.js"></script>
        <script src="js/bootstrap.min.js"></script>
        <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
    </head>

    <body>
        <div ng-app="todoApp" ng-controller="todoController" class="container">
            <form id='myForm'>
                <div class="row">
                    <input type="text" ng-model="task">
                    <button class="btn btn-primary btn-xs" ng-click="addTask()">
                        <i class="glyphicon glyphicon-plus"></i>
                    </button>
                </div>               
            </form>

            <div class="row">
                <ul>
                    <li ng-repeat="t in tasks track by $index">{{ t }} 
                        <button class="btn btn-default btn-xs" ng-click="deleteTask()">
                            <i class="glyphicon glyphicon-minus"></i>
                        </button>
                    </li>
                </ul>
            </div>
            
        </div>
    </body>
</html>


5. Create a JS file for popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
angular.module('todoApp', [])
    .controller('todoController', function($scope) {

        $scope.tasks = [];
        
        $scope.addTask = function() {
            if(isNotEmptyOrUndefined($scope.task)){
                 $scope.tasks.push($scope.task);
                $scope.task = '';
            } else {
                alert('task name cannot be null');
            }           
        }
        
        $scope.deleteTask = function() {
            $scope.tasks.splice(this.$index, 1);
        }

});

// 檢查是串是否不為空值且不為undefined
function isNotEmptyOrUndefined(str) {
    return str != '' && !angular.isUndefined(str) && str != null;
}


6. Install to Chrome and do test


Source code: https://github.com/junyuo/ChromeExtensions/tree/master/ChromeExtensionWithAngular

2016/12/04

[Chrome Extension] Create a simple chrome extenstion to search picture in Flicker

Steps are as bellows:

1. Create manifest.json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "manifest_version": 2,
  "name": "搜尋Flicker照片",
  "description": "Flicker Search Extension",
  "version": "1.0",
  "permissions": [ "activeTab" ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "helloworld.html",
    "default_title": "搜尋Flicker照片"
  }
}


2. Get icons
icon for chrome extension: https://goo.gl/7x1ID8
icon for pupup window: https://goo.gl/YldO4J


3. Create pop up window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html style="min-width:210px;">
    <head>
        <meta charset="UTF-8">
        <title>Hello Page</title>
        <script src="helloWorld.js"></script>
    </head>

    <body>
        <form id='myForm'>
            <img src="magnifier.png" height="20" width="20">
            <input type="text" id="queryString" style="width:100px">
            <button type="submit" id="doSearch">Search</button>
        </form>
    </body>
</html>


4. Create a JS file for popup window
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* The DOMContentLoaded event is fired when the initial HTML document 
 * has been completely loaded and parsed, without waiting for stylesheets, 
 * images, and subframes to finish loading.
 */
document.addEventListener('DOMContentLoaded', function() {

    var searchBtn = document.getElementById('doSearch'); 

    // Execute the following steps as user click Search button       
    searchBtn.addEventListener('click', function(){      
        // Gets query string 
        var queryString = document.getElementById('queryString').value;

        // Create URL with query string
        var newUrl = 'https://www.flickr.com/search/?q='+queryString;

        // Creates a new tab.
        chrome.tabs.create({ url : newUrl});
    }, false);

}, false);   


5. Install to Chrome and do Test


Source code: https://goo.gl/sSRCz0

2016/12/03

[Git] fatal: LF would be replaced by CRLF

Problem
As I try to use the git add command adds a change in the working directory to the staging area. 

It show the fatal error message as bellows:
albert@albert-PC MINGW64 /d/git/ChromeExtensions (master)
$ git add --all
fatal: LF would be replaced by CRLF in HelloWorld/manifest.json



How-to
This fatal error message results from this command fail to pass crlf check.

Here has the solution to fix this file's crlf problem.
If you have Notepad++ installed in your computer, simply follow these steps.
[1] Open the file that is having the fatal issue.
[2] Click Edit -> EOL Conversion, then select Windows Format and save it.





2016/12/02

[閱讀筆記] The Unwritten Laws of Business (2/2)


  1. 有些人似乎永遠都會把水弄的更濁,或無法見樹又見林。能夠從看似複雜的情境裡,分析出最基本、最關鍵的要素,是一種智慧,而且通常必須從經驗累積而成。在這個能力上的差異,會使兩個在各方面都旗鼓相當的人分出高下
  2. 大多數危機在一開始看似很糟糕,但其實根本沒有這麼嚴重,所以要格外謹慎,不要把不好的情勢給誇大了
  3. 任何會議的重點,都在於面對問題和解決問題。人往往會有規避問題的傾向,不是會延遲行動,就是希望事情會自己自動解決。要是在散會前,與會者尚未明確了解工作任務的內容、負責人及時間表,這就是一場失敗的會議
  4. 養成決策明快俐落的習慣,有些主管甚至在決定非常小的問題上,都非常痛苦掙扎,主要是因為他們從來沒有克服對於犯錯的恐懼
  5. 不要讓犯錯的危險,把你的進取新壓抑到「無所冒險,無所得」的程度。預期自己有可能會犯錯,偶而冒一些風險,並且在失敗時承擔苦果是比較健康的。很少錯誤是找不出益處的,就算只有累積了經驗,也算是一種收獲
  6. 以下是執行專案的準則,也可以說是 SOP:
    1. 界定專案目標
    2. 規劃工作
      1. 列出帶完成的每一個步驟
      2. 界定所需的資源,包含人力、資金和設備
      3. 備妥明確的時間表
    3. 執行計畫
    4. 監督進度,並在偏離進度時做出回應
      1. 留意「瓶頸」、「進度停滯」及「中斷的環節」:挹注額外的時間、資金和人力,以追趕落後的工作項目
      2. 如果有必要,修正你的時間表
    5. 盡全力準時完成專案
  7. 過度專注追求安全感,很容易導致更大的危險。身處競爭激烈的世界,你必須冒點風險,放手一搏,因為你不這麼做,其他人也會去做,而他們通常是最後的贏家,他們會讓你為了趕上他們而跑的上氣不接下氣
  8. 積極大膽的計畫原本就會有風險,為了將風險降到最低,在實際可行的前提下,提供替代方案,或是確保有後路可退,避免徹底失敗
  9. 當員工根本不知道自己的工作內容,也不清楚該負責什麼任務時,將嚴重損及士氣和效率。如果指派的任務不明確,很容易就會產生沒完沒了的爭執、混淆和不好的感覺
  10.   如果你對於部屬的工作表現不滿意,應該在一發現這樣的情況時,就立即與他們展開會談,這是你責無旁貸的事情,但是,要做到這點通常不太容易,這需要許多圓融的智慧,以免使部屬感到受挫或被冒犯
  11. 如果你必須開除某個部屬,你必須回答兩個尖銳的問題:『為什麼你要花五年的時間,才發現我能力不足?』以及『你為什麼沒給過我公平的機會,去修正這些缺失?』切記,當你以能力不足開除某人時,不只是該名員工表現差勁,也表示你個人督導不周
  12. 成功的主管會清楚地說明它們對於部屬的要求、目標和期望,之後再予以督導,提供支援
  13. 主管自然而然地想直接行使他們的管理權限,以前迅速明快地解決事情,卻因此沒能顧慮到已經被指派該項工作的人,此舉會嚴重打擊該名部屬的工作士氣
  14. 在對部屬職責的各種粗糙對待中,僅次於職責未被賦予權限的,就是位能讓部屬獲得充分資訊。當員工被指派負責某項專案,如果他們對於專案的過往歷史、現況或未來,都尚未取得足夠的資訊之際,就要求他們展現出可信度,是非常不公平的
  15. 薪資的調整,無論是透過什麼形式,都是對於工作表現優異、承擔更大職責或是為公司增加價值,最恰當的獎勵或報酬
  16. 信心、團隊和人際溝通、工作動力、成就感、適應能力、領導潛力、求知慾、誠信和情緒控制這些技能和特質,才是區分稱職員工與卓越員工的決定條件
  17. 能與各式各樣人相處的能力,是最珍貴的人格特質之一
  18. 與人為善的具體原則
    1. 學會欣賞每個人的優點,而非挑剔他人的缺點
    2. 不要因為受到挑釁,就失去耐心和惱怒
    3. 因為真誠的意見分歧而發生爭論之後,千萬不要心懷怨恨
    4. 養成體貼他人感覺和利益的習慣
    5. 不要太過專注於自己的私利
    6. 養成一有機會就協助他人的習慣
    7. 格外留意,無論在任何場合都要公正無私
    8. 不要對自己太嚴苛,或是太嚴肅看待工作
    9. 多費一點心思,真誠地與人打招呼
    10. 如果你對於別人的動機有所懷疑,先假定他們是無辜的,尤其是當你能夠這麼做的時候
  19. 留心避免和他人爭吵,可是萬一爭端已起,就應該讓對方知道你不是可以輕侮的
  20. 太過刻意地要與每個人和睦相處,因而一味地討人喜歡、甚至是屈服順從,當然是錯誤的作法,遲早有人會利用你這點
  21. 將個人誠信視為你最重要的資產之一,如果你擁有高度的個人誠信,你就會誠實、有品德、值得信賴、負責而且真誠。不妥協和堅守誠信,必然會得到珍貴的報償:信心,亦即同事、部屬和外人對你的信心
  22. 不要低估專業職責和個人責任的範圍,遵循以下幾個簡單的指導原則:
    1. 以有系統的方式處理你所有的工作,尤其是在開發新產品、流程或設備的時候
    2. 找出所需的專業知識和技能,並將之應用到所有活動上
    3. 確實了解合適的規範與標準,並加以採用
    4. 盡可能採行既有的程序
    5. 記錄你自己和部門的活動
  23. 留意你的個人儀表對其他人所造成的影響,還有反過來對你自己的影響
  24. 你必須設法趕上自己領域的最新科技,因為如果你等待別人給你機會,就等於是等著自己被淘汰