2017年10月30日 星期一

[Javascript] Chartjs Doughnut Center Text

Center register

 Chart.pluginService.register({  
      beforeDraw: function (chart) {  
           if (chart.config.options.elements.center) {  
                //Get ctx from string  
                var ctx = chart.chart.ctx;  
                          //Get options from the center object in options  
                var centerConfig = chart.config.options.elements.center;  
                var fontStyle = centerConfig.fontStyle || 'Arial';  
                          var txt = centerConfig.text;  
                var color = centerConfig.color || '#000';  
                var sidePadding = centerConfig.sidePadding || 20;  
                var sidePaddingCalculated = (sidePadding/100) * (chart.innerRadius * 2)  
                //Start with a base font of 30px  
                ctx.font = "30px " + fontStyle;  
                          //Get the width of the string and also the width of the element minus 10 to give it 5px side padding  
                var stringWidth = ctx.measureText(txt).width;  
                var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;  
                // Find out how much the font can grow in width.  
                var widthRatio = elementWidth / stringWidth;  
                var newFontSize = Math.floor(30 * widthRatio);  
                var elementHeight = (chart.innerRadius * 2);  
                // Pick a new font size so it will not be larger than the height of label.  
                var fontSizeToUse = Math.min(newFontSize, elementHeight);  
                          //Set font settings to draw it correctly.  
                ctx.textAlign = 'center';  
                ctx.textBaseline = 'middle';  
                var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);  
                var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);  
                ctx.font = fontSizeToUse+"px " + fontStyle;  
                ctx.fillStyle = color;  
                //Draw text in center  
                ctx.fillText(txt, centerX, centerY);  
           }  
      }  
 });  

use example

 options: {  
      responsive: true,  
      legend: {  
           display: false  
      },  
      elements: {  
           center: {  
                text: '$'+(cost_vm+cost_storage+cost_data_management).toFixed(3),  
                color: '#FF6384', // Default is #000000  
                fontStyle: 'Arial', // Default is Arial  
                sidePadding: 20 // Defualt is 20 (as a percentage)  
           }  
      }  
 },  

2017年10月29日 星期日

[Linux] 排程執行資料庫語法

首先要先學會Crontab,如果還不會的話請看我的上一篇文章,有介紹Crontab,在ubuntu跟centos中crontab用法是一樣的。

進入主題,如何安全的使用mysql command 語法。
mysql_config_editor是一個好用又安全的方式(加密)

mysql_config_editor set --login-path=remote
--host=remote.example.com --user=remoteuser --password
輸入完後他會叫你打密碼。

mysql_config_editor print --all 可以查看你的設定

之後你只要用
mysql --login-path=remote 就可以直接執行mysql command,可以避免密碼透漏在crontab file當中。

舉個範例
mysql --login-path=remote --database=your_database_name --execute="指令(更新、備份、刪除)"


如果是一班狀態的話會變成
mysql --user=[username] --password=[password] --database=[db name] --execute="指令"


是不是很簡單呢XD

2017年10月25日 星期三

[Linux] CentOS7.3 install wkhtmltopdf

yum install -y libpng
yum install -y libjpeg
yum install -y openssl

yum install -y libX11
yum install -y libXext
yum install -y libXrender
yum install -y xorg-x11-fonts-Type1
yum install -y xorg-x11-fonts-75dpi

wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
unxz wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
tar -xvf wkhtmltox-0.12.4_linux-generic-amd64.tar
mv wkhtmltox/bin/* /usr/local/bin/
rm -rf wkhtmltox
rm -f wkhtmltox-0.12.4_linux-generic-amd64.tar

中文顯示問題的話請安裝
yum install wqy-zenhei-fonts

2017年10月12日 星期四

[Linux] Crontab 指令(排程)

crontab 這個指令所設定的工作將會循環的一直進行下去! 可循環的時間為分鐘、小時、每週、每月或每年等。

簡單介紹常用指令:
crontab -e 編輯排程 (edit cron)
crontab -r 移除排程 (remove cron)
crontab -l 顯示目前排程 (list cron)

contab格式如下

分 時 日 月 星期 要執行的指令

例如:
如果您要每30分鐘執行某種指令,請使用以下程式碼。
*/30 * * * * 指令

如果您要每15分鐘執行某種指令,請使用以下程式碼。
*/15 * * * * 指令

每分鐘執行一次指令
* * * * * 指令

每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * 指令


參考:
http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html

2017年9月5日 星期二

[Python] windows PIP install mysqldb

如遇到這個問題
No module named MySQLdb


建議使用以下指令安裝

on windows
pip install mysqlclient==1.3.4


on linux
sudo apt-get install python2.7-mysqldb

2017年8月29日 星期二

[Apache] httponly 讓Javascript無法取得cookie

當今天網站不小心被發現有 XSS 漏洞時,攻擊者很可能會透過 javascript 盜取你的 cookie 中的 session id,來盜取帳號。

在 http(s) header 中其中有一個 header 為 Set-Cookie,將 Set-Cookie 設為 httpOnly(javascript 無法存取cookie)或 secure (http 連線無法存取 cookie)

我們可以簡單的透過 php_ini 設定,Set-Cookie: HttpOnly
session.cookie_httponly = 1

透過 apache2 設定 header (apahce 版本資訊, 可透過指令 sudo apache2 -v 得知)
vim /etc/apache2/conf-available/security.conf

若是 apache 版本 >=2.2.4
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
若是 apache 版本 < 2.2.4
Header set Set-Cookie HttpOnly;Secure

sudo service apache2 restart   #重啟 apache 載入設定
這樣就可以避免 javascript 與不安全的 http 連線存取 cookie

2017年8月19日 星期六

[Python] python google alert 爬蟲教學

目標網頁:Google Alert (https://www.google.com.tw/alerts?hl=zh-tw)
目標:透過爬蟲抓取google alert指定關鍵字,搜尋資料結果。

1.      分析目標網頁為靜態網頁還是動態網頁。靜態網頁是指資料就寫在一開始進入網頁的HTML原始碼裡,此種網頁比較好利用爬蟲去抓取,不用透過模擬瀏覽器的方式,就能取得網頁資料。但是google alert網頁是屬於動態網頁,就比較麻煩須先模擬網頁瀏覽器,執行至google alert畫面,將關鍵字輸入,才能取得結果資料。

2.      使用python套件Beautiful Soup來抓取網頁HTML DOM結構,Beautiful Soup是一個不錯的爬蟲工具,在網路上有很多人使用,其技術問題比較容易在網路上找到解答。Python2與Python3有不同的安裝方法(請自行參考其官方網站),在windows上面可以用pip install beautifulsoup4來安裝套件。

3.      透過python模擬chrome並開啟google alert網頁,範例程式碼。
driver = webdriver.Chrome()
driver.get("https://www.google.com.tw/alerts")

4.      自動在google alert頁面輸入關鍵字。query_div為google alert網頁input的id,send_keys為模擬輸入值,keyword為想要查詢的關鍵字。輸入完畢後,網頁會顯示搜尋結果。
sbox = driver.find_element_by_id("query_div")
input = sbox.find_element_by_xpath("//input[1]")
input.send_keys(keyword)

5.      分析結果資料,並輸入進資料庫。
soup = BeautifulSoup(driver.page_source, "html.parser")
for obj in soup.find_all("li", attrs={'class': 'result'}):
    content = BeautifulSoup(str(obj), "html.parser")
    result_title_link = content.find("a",attrs={'class': 'result_title_link'})

    print(re.sub(SPACE_RE, '',
          result_title_link.text.encode("utf8"))) #title
    print result_title_link["href"] #url

    result_source_data = ''
    result_source = content.find("div",attrs={'class':    'result_source'})
    if(result_source != None):
        print(re.sub(SPACE_RE, '', result_source.text)) #source
        result_source_data = re.sub(SPACE_RE, '', result_source.text)

    img_data = ''
    img = content.find('img')
    if(img != None):
        print(img["src"])
        img_data = img["src"]
        snippet = content.find("span",attrs={'class': 'snippet'})

    if(snippet != None):
        print(re.sub(SPACE_RE, '', snippet.text.encode("utf8") ))
        snippet = re.sub(SPACE_RE, '', snippet.text.encode("utf8") )

其上面程式碼會顯示每一個結果的標題、網頁連結、來源、圖片與簡介。
再將資料存入資料庫就完成了。

6.      Python mysql資料庫範例
import mysql.connector
config = {
  'user': 'db_user',
  'password': 'db_password',
  'host': 'host_url',
  'database': 'your_database',
  'charset': 'utf8',
  'use_unicode': True,
}
cnx = mysql.connector.connect(**config)
cursor = cnx.cursor(buffered=True)

cursor.execute("select name from google_alert_keywords")
for keywords_obj in cursoro:
    keyword = keywords_obj[0] #即可抓取出資料庫的資料


/* 抓取結果…(略) */
/* 以下為存入資料庫 */
data_obj = {
'keyword': keyword,
'title': re.sub(SPACE_RE, '',result_title_link.text.encode("utf8")),
'source': result_source_data,
'img': img_data,
'url': result_title_link["href"],
'detail': snippet,
'time': datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
}

try:
    cursor.execute(("INSERT INTO google_alert_keywords_crawler (keyword, title, source, img, url, detail, time) VALUES (%(keyword)s, %(title)s, %(source)s, %(img)s, %(url)s, %(detail)s, %(time)s)"), data_obj)
except:
    print(cursor.statement)
    raise


[CentOS] httpd port 9000 to 80

<VirtualHost *:80>     ServerName domain.name     ProxyRequests Off     ProxyVia Block     ProxyPreserveHost On     <Proxy *...