CMSimple Drupal Yii 內容管理系統三方案 - 提升台灣中小企業競爭力

目前位置:   首頁 > Program Talk > 網際英英字典專案

網際英英字典專案

1. 下載開放的英英字典檔案資料.

http://www.gutenberg.org/ebooks/search/?query=29765

將英英字典檔案存為 WebsterUnabridgedDictionary.txt

2. 利用 Python3 程式解譯系統, 執行下列程式:

#coding: utf-8
# 檔案內容讀取範例
檔案 = open("WebsterUnabridgedDictionary.txt",encoding="UTF-8")
count = 0
# 一次讀取所有檔案內容資料
所有資料 = 檔案.readlines()
print("這個檔案共有:"+str(len(所有資料))+"行")
# 利用重複迴圈逐行讀取, 由於單字以大寫字母列出, 因此透過大寫單字來判定檔案中的總字數
for 行數 in range(len(所有資料)):
    # 若該行的所有字母都是大寫, 表示為單字開頭
    行資料 = 所有資料[行數].rstrip()
    if(行資料.isupper()):
        # 列出單字
        #print(行資料.encode("UTF-8"))
        count += 1
    else:
        # 列出單字的所屬解釋
        #print("解釋", end="")
        #print(行資料.encode("UTF-8"))
        continue
print("單字數共有:"+str(count)+"個")
檔案.close() # 關閉檔案

 執行結束後, 可以得知此一字典檔案有 974265 行, 而單字數則共有 113794 個.

3. 為了方便擷取檔案中的單字與單字定義, 設法在每一個單字區段前加入分隔記號.

#coding: utf-8
# 這個程式主要在各單字上方置入分隔符號, 然後存為新檔案
from pybean import Store, SQLiteWriter
# 利用 Store  建立資料庫檔案對應物件, 並且設定 frozen=False 表示要開放動態資料表的建立
#vocabulary = Store(SQLiteWriter("webster_vocabulary.sqlite", frozen=False))
# 檔案內容讀取範例
檔案 = open("WebsterUnabridgedDictionary.txt",encoding="UTF-8")
新檔案 = open("WebsterUnabridgedDictionary_new.txt","w",encoding="UTF-8")
count = 0
所有資料 = 檔案.readlines()
print("這個檔案共有:"+str(len(所有資料))+"行")
for 行數 in range(len(所有資料)):
    # 若該行的所有字母都是大寫, 表示為單字開頭
    行資料 = 所有資料[行數].rstrip()
    # 新行資料保留跳行符號
    新行資料 = 所有資料[行數]
    #word = vocabulary.new("word")
    if(行資料.isupper()):
        # 在 word 資料表中建立 word 單字欄位
        # 列出單字
        #print("$-------$")
        新檔案.write("$-------$\n")
        新檔案.write(新行資料)
        #print(行資料.encode("UTF-8"))
        count += 1
    else:
        # 指向 word 資料表
        # 在 word 資料表中建立 definition 單字定義欄位
        #word.word = 單字
        #word.definition = 行資料
        # 列出單字的所屬解釋
        #print("解釋", end="")
        新檔案.write(新行資料)
        #print(行資料.encode("UTF-8"))
print("單字數共有:"+str(count)+"個")
檔案.close() # 關閉檔案
新檔案.close() # 關閉檔案

 4. 接下來希望利用 SQLite 資料庫檔案來儲存英文單字與對應的單字定義.

from pybean import Store, SQLiteWriter
# 利用 Store  建立資料庫檔案對應物件, 並且設定 frozen=False 表示要開放動態資料表的建立
vocabulary = Store(SQLiteWriter("webster_vocabulary.sqlite", frozen=False))
新檔案 = open("WebsterUnabridgedDictionary_new.txt",encoding="UTF-8")
所有資料 = 新檔案.readlines()
print("這個檔案共有:"+str(len(所有資料))+"行")
#原始檔案 = 所有資料.split("$-------$\n")
資料 = ""
for 行數 in range(len(所有資料)):
    # 若該行的所有字母都是大寫, 表示為單字開頭
    #行資料 = 所有資料[行數].rstrip()
    資料 += 所有資料[行數]
單字 = 資料.split("$-------$\n")
# 去掉第一個空白行單字
單字 = 單字[1:]
for 索引 in range(len(單字)):
    word = 單字[索引].split("\n")
    單字部分 = ""
    解釋部分 = ""
    for 次索引 in range(len(word)):
        if (次索引 == 0):
            #print("單字:",word[次索引].encode("UTF-8"))
            單字部分 = word[次索引]
        else:
            #print(word[次索引].encode("UTF-8"))
            解釋部分 += word[次索引]+"\n"
    '''
    print("單字部分:", 單字部分.encode("UTF-8"))
    print("解釋部分:", 解釋部分.encode("UTF-8"))
    print("")
    '''
    dbword = vocabulary.new("word")
    dbword.word = 單字部分
    dbword.defn = 解釋部分
    vocabulary.save(dbword)
    vocabulary.commit()
    #print(單字[索引].encode("UTF-8"))
新檔案.close() # 關閉檔案

 5. 接下來, 為了要讓英英字典的資料查詢更具彈性, 利用 CherryPy 與 Pybean 將資料庫查詢程式轉為網際程式.

#coding: utf-8
 
import cherrypy
# 執行指令但是不要開啟 Windows shell 用
import subprocess
# 導入 pybean 模組與所要使用的 Store 及 SQLiteWriter 方法
from pybean import Store, SQLiteWriter
# 利用 Store  建立資料庫檔案對應物件, 並且設定 frozen=False 表示要開放動態資料表的建立
 
class MyCheck(object):
    _cp_config = {
        'tools.sessions.on': True
    }
    def nl2br(self, string, is_xhtml= True ):
        if is_xhtml:
            return string.replace('\n','<br />\n')
        else :
            return string.replace('\n','<br>\n')
    def doCheck(self, word=None):
        vocabulary = Store(SQLiteWriter("webster_vocabulary.sqlite", frozen=True))
        if (vocabulary.count("word","lower(word) like ?", [word]) == 0):
            return "找不到與 "+ word.title() + "有關的資料!"
        else:
            result = vocabulary.find("word","lower(word) like ?", [word])
            for item in result:
                output = word.title()+"<br /><br />"+str(self.nl2br(item.defn,True))+"<br />"
            output += "<br /><a href=\"/\">重新查詢</a>"
            return output
 
    doCheck.exposed = True
 
    def index(self):
        return '''<html>
<head>
  <title>查字典</title>
</head>
<body>
  <form action="doCheck" method="post">
    請輸入要查詢的單字:<input type="text" name="word" value="" 
        size="15" maxlength="40"/>
    <p><input type="submit" value="查詢"/></p>
    <p><input type="reset" value="清除"/></p>
  </form>
</body>
</html>'''		
 
    index.exposed = True
 
 # 由於 url 帶有 &, 無法直接使用 os.system() 開啟網頁同時派送變數, 因此改用 subprocess
url = 'http://localhost:8088/index'
chrome = "V:/apps/GoogleChromePortable/GoogleChromePortable.exe"
retcode = subprocess.call([chrome, url])
# 指定程式執行的連接埠號, 內定為 8080
cherrypy.server.socket_port = 8088
# 指定程式執行所對應的伺服器 IP 位址, 內定為 127.0.0.1
cherrypy.server.socket_host = '127.0.0.1'
cherrypy.quickstart(MyCheck())

 6. 上述 CherryPy 英英字典查詢程式雖然可以在任何支援 Python3 的電腦上執行, 但是更好的作法是將這個程式配置在免費的雲端空間, 這裡選擇將 Python3 網際程式配置在 OpenShift 雲端主機上.

OpenShift CherryPy 程式配置步驟:

6-1. 建立 OpenShift 上的 Python 3.3 應用程式環境, 在命名空間下指定應用程式的名稱, 並選用 Python 3.3 Community Cartridge, 就可建立 Python 3.3 網際程式環境.

6-2. 利用 git clone 將 OpenShift 上的應用程式由 remote 端下載到 local 端.

6-3. 在 local 端修改 setup.py, 指定要求在啟動 wsgi 伺服之前安裝 CherryPy 與 Pybean 套件.

from setuptools import setup
 
setup(name='YourAppName', version='1.0',
      description='OpenShift Python-3.3 Community Cartridge based application',
      author='Your Name', author_email='your_email@your_domain_name',
      url='http://www.python.org/sigs/distutils-sig/',
 
      #  Uncomment one or more lines below in the install_requires section
      #  for the specific client drivers/modules your application needs.
      install_requires=['WebOb', 'cherrypy', 'pybean',
                        #  'mysql-connector-python',
                        #  'pymongo',
                        #  'psycopg2',
      ],
     )

 6-4. 完成上述 setup.py 編輯後, 修改 wsgi 目錄下的 application 檔案, 改為:

#coding: utf-8
 
import cherrypy
# 執行指令但是不要開啟 Windows shell 用
import subprocess
# 導入 pybean 模組與所要使用的 Store 及 SQLiteWriter 方法
from pybean import Store, SQLiteWriter
# 利用 Store  建立資料庫檔案對應物件, 並且設定 frozen=False 表示要開放動態資料表的建立
 
class MyCheck(object):
    _cp_config = {
        'tools.sessions.on': True
    }
    def nl2br(self, string, is_xhtml= True ):
        if is_xhtml:
            return string.replace('\n','<br />\n')
        else :
            return string.replace('\n','<br>\n')
    def doCheck(self, word=None):
        vocabulary = Store(SQLiteWriter("webster_vocabulary.sqlite", frozen=True))
        if (vocabulary.count("word","lower(word) like ?", [word]) == 0):
            return "找不到與 "+ word.title() + "有關的資料!"
        else:
            result = vocabulary.find("word","lower(word) like ?", [word])
            for item in result:
                output = word.title()+"<br /><br />"+str(self.nl2br(item.defn,True))+"<br />"
            output += "<br /><a href=\"/\">重新查詢</a>"
            return output
 
    doCheck.exposed = True
 
    def index(self):
        return '''<html>
<head>
  <title>查字典</title>
</head>
<body>
  <form action="doCheck" method="post">
    請輸入要查詢的單字:<input type="text" name="word" value="" 
        size="15" maxlength="40"/>
    <p><input type="submit" value="查詢"/></p>
    <p><input type="reset" value="清除"/></p>
  </form>
</body>
</html>'''		
 
    index.exposed = True
 
 # 由於 url 帶有 &, 無法直接使用 os.system() 開啟網頁同時派送變數, 因此改用 subprocess
url = 'http://localhost:8088/index'
chrome = "V:/apps/GoogleChromePortable/GoogleChromePortable.exe"
retcode = subprocess.call([chrome, url])
# 指定程式執行的連接埠號, 內定為 8080
cherrypy.server.socket_port = 8088
# 指定程式執行所對應的伺服器 IP 位址, 內定為 127.0.0.1
cherrypy.server.socket_host = '127.0.0.1'
# for localhost site start
#cherrypy.quickstart(MyCheck())
# for OpenShift deployment
application = cherrypy.Application(MyCheck())

 6-5. 接著將 local 端的程式碼, 以下列 git 指令送到 OpenShift 對應的網際空間中.

git add .
git commit -m "deploy cherrypy program"
git push

6-6. 由於 OpenShift 空間上的應用程式, 在每次更新程式碼時, 都會以 local 端特定版本的內容為準, 唯一不會配合 local 端更動的就是 os.environ['OPENSHIFT_DATA_DIR'] 所屬的資料目錄, 因此對於直接在網際環境中新增或修改的資料就必須設法置入這個 persistent 目錄 (OpenShift 環境變數), 才能在各版次內容更新後, 仍然維持原先的內容(若需要更新, 可以透過 SFTP 完成), 其中包括 SQLite 資料庫檔案與使用者上傳的資料檔, 或者其他可能在各程式碼版次更新後仍然要予以保留的網站設定檔案.

6-7. 若以 Pybean 的 SQLite 為例, 可以設為:

library = Store(SQLiteWriter(os.environ['OPENSHIFT_DATA_DIR']+"/database.sqlite", frozen=False))

 表示要將 database.sqlite 資料庫檔案存入程式碼更新後仍然維持不變的對應資料目錄中.

至於上傳檔案目錄與靜態資料目錄的設定則類似:

# 靜態檔案的目錄對應設定
myconfig = {'/downloads':{
    'tools.staticdir.on': True,
    'tools.staticdir.root': os.environ['OPENSHIFT_DATA_DIR'],
    'tools.staticdir.dir': 'downloads',
    'tools.staticdir.index' : 'index.html'
    },
    # 設定靜態 templates 檔案目錄對應
    '/templates':{
    'tools.staticdir.on': True,
    'tools.staticdir.root': os.environ['OPENSHIFT_REPO_DIR']+"/wsgi/static",
    'tools.staticdir.dir': 'templates',
    'tools.staticdir.index' : 'index.html'
    }
}

其中 templates 對應的目錄直接放入 OpenShift 所規劃的 wsgi/static 目錄中, 並且透過 Cherrypy 的目錄設定與網際目錄對應.

而與上述設定配合的上傳檔案子目錄, 則需要在實際存檔前, 進行必要的目錄查驗或新增對應目錄:

if fileupload and (fileupload.file != None):
    資料檔案目錄 = os.environ['OPENSHIFT_DATA_DIR']
    上傳目錄 = 資料檔案目錄 + "/downloads"
    if not os.path.exists(上傳目錄):
        os.makedirs(上傳目錄)
    #目前所在目錄 = os.path.dirname(os.path.abspath(__file__))
    上傳檔案 = open(資料檔案目錄+"/downloads/"+fileupload.filename, 'wb')

6-8. 一旦上述的流程都能正確執行, 使用者就可以利用下列 rhc 指令, 下載目前 OpenShift 平台上 Cherrypy 應用程式的壓縮檔案:

rhc snapshot save -a 應用名稱

Powered by CMSimple_XH| Template: ge-webdesign.de| 登入