Weitere ähnliche Inhalte Ähnlich wie CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal) (20) Mehr von Jian-Kai Wang (11) CKAN : 資料開放平台技術介紹 (CAKN : Technical Introduction to Open Data Portal)2. 1 技術背景
2 CKAN 架構
3 客製化模版與模組
4 客製化頁面與語言轉換
Ubuntu, Python, Jinja, Postgresql, RWD
Pyenv, sandbox, system, network, db
客製化模版與模組開發
Plotly, Openlayers, Mapbox, syntaxhighlighter ,
Leaflet, flot DSP 智庫驅動 (2016)
3. 技術背景:常用 Linux 指令
$ ssh maintainer@cdcopendatatest.cloudapp.net -p 22 # ssh 登入測試機伺服器
$ pwd # 查看目前目錄
$ ls [-al] /home/maintainer # 查看家目錄底下資料列表
$ cd /home/maintainer # 移動至家目錄底下
$ mkdir /home/maintainer/folder # 家目錄下創建資料夾
$ rm -rf /home/maintainer/folder # 遞迴式刪除資料夾
$ cp -r [A] [B] # 將 A 複製到 B
$ mv [A] [B] # 將 A 移動到 B,包含更名
$ cat /home/maintainer/data # 查看家目錄下的資料 data
$ head -n 10 /home/maintainer/data # 查看家目錄下的資料 data 前 10 行內容
$ tail -n 10 /home/maintainer/data # 查看家目錄下的資料 data 後 10 行內容
$ who # 查看誰登入 (登出 exit)
$ sudo adduser maintainer # 加入 maintainer 使用者
$ groups maintainer # 查看 maintainer 群組
$ sudo usermod -a -G sudo maintainer # 將 maintainer 入 sudo 群組
$ sudo chown -R user:group path # 將路徑 path 底下重新劃分擁有者
# :w(儲存), :q(離開), :q!(強制離開), /(下搜尋), ?(上搜尋), u(undo), Ctrl+R(redo), :s///g(取代)
$ vim /home/maintainer/data
drwxr-xr-- 3 jkw root 4096 2月 25 2016 .distlib
|- rwx : 擁有者權限,r-x : 同群組權限,r-- : 一般使用者權限,jkw : 擁有者名稱,root : 群組名稱
4. 技術背景:Python 初探
• 物件導向
• C 語言延伸
• 動態繫結
• 動態頗析語意樹 (直譯式)
• 相對弱資料型態
• 強數值基礎
• 版本頗析 : v.2.7.x 與 v.3.5.x
關於 Python num = 100 # 宣告整數
string = "hello world" # 宣告字串
fnum = (float)(100) # 宣告小數
tmpList = ["string",100,0.5] # 宣告串列
tmpDict = { "key" : "value" } # 宣告字典
# 宣告類別
class OBJ:
__pri_value = 0
def __init__(self, value):
self.__pri_value = value
def getValue(self):
return self.__pri_value
obj = OBJ(2)
print "Number is %d" % obj.getValue()
5. 技術背景:Python 再探
aList = [123,"A","the string"] # 宣告串列
aList.append("value") # push 一個元素
getEle = aList.pop() # pop 一個元素
aList.extend(["abc",123,0.8]) # 延伸串列
if element in aList: # 元素是否在串列中
aList.index("element") # 元素在串列中位置
len(aList) # 串列中元素的數目
d = { key1 : value1 } # 宣告字典
getKeys = d.keys() # 所有鍵値
getValues = d.values() # 所有値
print d["k1"] # 透過鍵找出値
if d.has_key("testKey"): # 是否有此鍵
len(d.keys()) # 有幾組鍵値
d.setdefault("nKey","nVal") # 加入一組鍵値
del d["newKey"] # 刪除一組鍵値
再探 list 與 dictionary 再探流程管控與迴圈
if Ture:
pass
elif Ture:
pass
else:
pass
for index in range(0,10,1):
print str(index)
6. 技術背景:Jinja 初探
• 支援原生 html5 架構
• Inline-based coding
• Python 為基礎網頁語法
• 模版系統
• Pyramid 框架套件
• helper 函式定義
關於 Jinja2 {# 註解 #}
{{ h.funbody() }}
{% set action = h.execBody(pkg.id) %}
<!-- inline-based coding example -->
{% block secondary_content %}
<title>{% block title %}{% endblock %}</title>
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
{% endblock %}
<!-- snippet example -->
{% block secondary_content %}
{% snippet 'show.html' %}
{% endblock %}
7. 技術背景:PostgreSQL 初探
• Index-based (B-tree) 檢索
1. Search : O(log n)
2. 部分索引
3. 點陣圖式索引
• 支援資料型態
• 任意精度的數值
• 無限制長度文字
• IP位址與IPv6位址
• 類 MAC 位址路由
• 陣列
關於 PostgreSQL {% block subtitle %}{{ c.group_dict.display_name }} -
{{ _('Organizations') }}{% endblock %}
{% block breadcrumb_content %}
{# customized #}
<li>{% link_for _('Organizations'), controller='organization',
action='index' %}</li>
<li class="active">{% link_for h.getLangLabel(c.group_dict.etitle,
c.group_dict.title)|truncate(35), controller='organization',
action='read', id=c.group_dict.name %}</li>
{% endblock %}
{% block content_action %}
{% if h.check_access('organization_update', {'id': c.group_dict.id}) %}
{% link_for _('Manage'), controller='organization', action='edit',
id=c.group_dict.name, class_='btn', icon='wrench' %}
{% endif %}
{% endblock %}
8. 技術背景:RWD 初探
• CSS 優先,JS 次之
• 善用 media query (CSS3)
• 相對性排版
• class 優先,id 次之
• 注意 DOM library 注入順序
關於 RWD 原則 @media screen and (min-width: 480px) {
body {
background-color: lightgreen;
}
}
// 關於 NIDSS RWD
$('#container1').highcharts({
chart:
{
type: 'column',
// ----------------------
// 無法 RWD
width: eval(cwidth),
// ----------------------
height: 250, backgroundColor: {linearGradient: {x1: 0,
y1: 0, x2: 0, y2: 1}, stops: [[0, '#FFFFFF'], [1,
'#F0F0F0']]},
9. 1 技術背景
2 CKAN 架構
3 客製化模版與模組
4 客製化頁面與語言轉換
Ubuntu, Python, Jinja, Postgresql, RWD
Pyenv, sandbox, system, network, db
客製化模版與模組開發
Plotly, Openlayers, Mapbox, syntaxhighlighter ,
Leaflet, flot DSP 智庫驅動 (2016)
10. CAKN 架構 : 虛擬環境 (Virtualenv) 與沙盒 (sandbox)
Ubuntu 16.04 kernel 4.2.0-27
python 2.7.6
python 2.7.6
sandbox
CKAN
• 基於沙盒的虛擬技術
• 創造虛擬(獨立) Python 環境
• 但能針對不同的虛擬標的
• 隔離函數庫,不互相影響
• 沒有權限下安裝新套件
• 版本與套件管控
關於 Virtualenv 與 sandbox
# 進入虛擬機
$ . /usr/lib/ckan/default/bin/activate
11. CAKN 架構 : CKAN 系統
Linux
Apache
PHP
MySQL / Mariadb
Java Virtual Machine
JBOSS / Tomcat
JSP
JDBC
Windows
IIS
ASP.NET
SQL Server
C#
Linux
Python
Jinja2
PostgreSQL
LAMP 架構 JAVA-VM 容器架構 微軟解決方案架構 CKAN 架構
Nginx
Inline-coding Inline-coding Code-behind/inline-coding Inline-coding
12. CAKN 架構 : CKAN 系統架構與實體路徑
Linux
Python
Jinja2
PostgreSQL
CKAN 架構
Nginx
Inline-coding
/etc/ckan/default/
|- development.ini # 測試環境組態
|- production.ini # 正式環境組態
paster serve /etc/ckan/default/development.ini # 執行測試環境, Port 5000
/usr/lib/ckan/default/ # 主要路徑
|- src/
|- ckanext-pages/ # pages 模組
|- ckan/
|- ckanext/ # 主要模組放置處
|- ckanext-basiccharts/
|- ckanext-geoview/
|- ckanext-scheming/
|- datapusher/
|- datastore/ # 包含 reclineview 模組
|- ckan/
|- lib/helper.py # 伺服器,資料庫與頁面管理
|- templates/ # jinja2 模版
|- public/ # 資源放置處,包含 images, js, css
13. CAKN 架構 : Server, Database 與 Page 的中介 helper.py
# 伺服器,資料庫與頁面管理
/usr/lib/ckan/default/src/ckan/ckan/lib/helper.py
• Python 環境
• 並非全支援 python 套件
• 伺服器狀態與執行環境
• 全廣域環境
• 資料庫管理
• Jinja2 模版內容
• 與 js 決定效能 (平衡點)
關於 helper.py
# example : customized function in helper.py
# desc : get chinese and english title
# return : specific title in chinese and english
def getLicenseLabel(getLicense, getColumn):
register = model.Package.get_license_register()
sorted_licenses = sorted(register.values(), key=lambda x: x.title)
getTitle = ""
for i in range(0, len(sorted_licenses), 1):
if sorted_licenses[i].title == getLicense[getColumn]:
getTitle = getLangLabel(sorted_licenses[i].etitle, sorted_licenses[i].title)
break
return getTitle
{# 必須用物件方式引用 h.getLicenseLabel() #}
{% if title == 'Licenses' %}
<span>{{ h.getLicenseLabel(item,"display_name") }} {{ count }}</span>
{% else %}
14. 1 技術背景
2 CKAN 架構
3 客製化模版與模組
4 客製化頁面與語言轉換
Ubuntu, Python, Jinja, Postgresql, RWD
Pyenv, sandbox, system, network, db
客製化模版與模組開發
Plotly, Openlayers, Mapbox, syntaxhighlighter ,
Leaflet, flot DSP 智庫驅動 (2016)
15. CAKN Jinja2 模版 : 高度單元化
organization/read.html
{% block organization_facets %}
{% for facet in c.facet_titles %}
{{ h.snippet('snippets/facet_list.html',
title=c.facet_titles[facet], name=facet,
extras={'id':c.group_dict.id}) }}
{% endfor %}
{% endblock %}
group/read.html
{% block secondary_content %}
{{ super() }}
{% for facet in c.facet_titles %}
{{ h.snippet('snippets/facet_list.html',
title=c.facet_titles[facet], name=facet,
extras={'id':c.group_dict.id}) }}
{% endfor %}
{% endblock %}
snippets/facet_list.html
{% with items = items or h.get_facet_items_dict(name) %}
{% if items or not hide_empty %}
{% if within_tertiary %}
{% set nav_class = 'nav nav-pills nav-stacked' %}
傳入變數方式
16. CAKN Jinja2 模版 : 高度單元化
header.html
footer.html
css
js
organization
block
group
facet_list.html
block
block
feed.html
block
router
snippet
block
router
17. CAKN plugin 模組 : 路由、資料庫與網頁的高度單元體
• 處理包含所有 POST,
GET 等 request
• 處理所有頁面傳送
• 定義在 plugin.py
關於路由
• 預設 PostgreSQL
• 可以介接其他資料庫
• 定義在 plugin.py 或
init.py
關於資料庫
• 支援全 html5
• 配合路由進行 request
• 以 jinja2 為主模版
• 實體路徑 template 放
置網頁
• 實體路徑 public 放置外
部資源
關於網頁
18. CAKN plugin 模組 : 再探路由
class SchemingOrganizationsPlugin(p.SingletonPlugin, _GroupOrganizationMixin,
DefaultOrganizationForm, _SchemingMixin):
p.implements(p.IConfigurer)
p.implements(p.ITemplateHelpers)
p.implements(p.IGroupForm, inherit=True)
p.implements(p.IActions)
p.implements(p.IValidators)
SCHEMA_OPTION = 'scheming.organization_schemas'
FALLBACK_OPTION = 'scheming.organization_fallback'
SCHEMA_TYPE_FIELD = 'organization_type'
UNSPECIFIED_GROUP_TYPE = 'organization'
@classmethod
def _store_instance(cls, self):
SchemingOrganizationsPlugin.instance = self
def about_template(self):
return 'scheming/organization/about.html'
def group_form(group_type=None):
return 'scheming/organization/group_form.html'
# use the correct controller (see ckan/ckan#2771)
def group_controller(self):
return 'organization'
def get_actions(self):
return {
'scheming_organization_schema_list':
scheming_organization_schema_list,
'scheming_organization_schema_show':
scheming_organization_schema_show,
}
19. 1 技術背景
2 CKAN 架構
3 客製化模版與模組
4 客製化頁面與語言轉換
Ubuntu, Python, Jinja, Postgresql, RWD
Pyenv, sandbox, system, network, db
客製化模版與模組開發
Plotly, Openlayers, Mapbox, syntaxhighlighter ,
Leaflet, flot DSP 智庫驅動 (2016)
20. CAKN 架構 : 整合 GIS (datastore + openlayers)
22. CAKN 架構 : 引用外部資源
/usr/lib/ckan/default/src/ckan/ckan/public/base/ # 外部 js, css 資源
|- javascript/ # 外部 javascript
|- resource.config # 定義引用資源
|- css/ # 外部 css
開源 CSS
font-awesome.css, bootstrap.css, geo-resource-styles.css (Openlayers)
medium-editor.css (ckeditor), …
自定義 CSS general.css
引用 CSS 方式 於 base.html 中加入 <link rel="stylesheet" href="/base/css/general.css" />
開源 js jquery, bootstrap, flot, ckeditor, leaflet. openlayers
自定義 js general.js
引用 js 方式
1. 定義 resource.config
custom/plotly.js
custom/Common.js
custom/general.js
2. 重啟服務
sudo restart ckan