2010-07-20 17 views
7

這是我在這裏的第一個問題,所以我希望它會正確完成;)Web-ifing python命令行腳本?

我已經分配了任務給一些「自制」python腳本的Web界面。 該腳本用於通過curl命令檢查一些網站/應用程序的可用性。這個腳本的一個非常重要的方面是它實時給出結果,逐行寫入標準輸出。

通過給這個腳本提供一個web界面,主要目標是腳本可以很容易地從任何地方使用,例如通過智能手機。所以Web界面必須非常基本,並且「無插件」工作。

我的問題是,我認爲或發現在網絡上的大多數解決方案(ajax,Django,甚至是一個簡單的帖子)似乎需要整個一代的頁面,然後將其發送到瀏覽器,失去了這個重要的「時間「方面。

有關如何正確執行此操作的任何想法?

在此先感謝。

+0

謝謝您的回答,我目前正忙於處理其他任務,但我應該回去就這一聲;-) – Lenn 2010-07-22 12:34:17

回答

0

你的任務聽起來很有趣。 :-)是剛剛進入腦海一個場景:你時間可持續刮資源與您的家庭釀造的腳本,並推動成果轉化爲你的持久數據庫和緩存系統 - 像Redis的 - simultanously。服務客戶端請求時,緩存系統/層作爲主要數據源。 Redis f.e.是一款能夠處理每秒100k連接的高性能鍵值存儲。儘管只有n個最新的(比如說fk.5萬條目)這個緩存系統只包含這些條目,並且讓你專注於開發服務器端API(處理連接,處理請求,從Redis中讀取)和前端​​。前端和後端API之間的通信可以由WebSocket連接驅動。 HTML5規範的新部分。然而,儘管如此,這些日子已經被許多瀏覽器版本所支持。或者,你可以回退一些異步Flash Socket的東西。 Websockets基本上允許客戶端和服務器之間的持久連接;您可以註冊爲每個傳入數據/分組調用的事件偵聽器 - 不需要無盡的輪詢或其他內容。

3

一種解決方案草圖:

創建一個HTML文件,其中包含了你的網頁佈局,配有專用DIV爲腳本的輸出:

<html> 
<body> 
<div id="scriptoutput"></div> 
<script type="text/javascript" src="localhost:8000/runscript"/> 
</body> 
</html> 

這個HTML文件可使用任何你想要的服務器。

現在,寫它運行的腳本,每行轉換爲JavaScript命令(在python爲例)一個簡單的HTTP服務器:

import os 
f = os.popen('ping 127.0.0.1') 
for i in range(30): 
    ln = f.readline() 
    print "document.getElementById('scriptoutput').innerHTML += '<pre>%s</pre><br/>';" % ln 

您可以使用任何CGI/WSGI服務器的任務,或者如果性能並不重要,甚至可以使用Python自己的BaseHTTPServer類。

這會做的伎倆,因爲大多數瀏覽器解析和執行JavaScript腳本的,因爲他們收到(不只是完成請求時) - 注意,不需要輪詢或服務器端存儲!

+0

我證明python2.7 server.py腳本運行並修改爲不帶參數和HTML代碼作爲index.html的腳本目錄。 我運行Python代碼,並得到誤差: 文件 「d:/test/javascr.py」,第4行,在 LN = f.readline() AttributeError的: '元組' 對象沒有屬性 '的ReadLine' 而瀏覽器顯示空白頁面。有些東西必須丟失。例如,在哪裏放python腳本名稱,說簡單的打印「Hello world」? – 2010-07-20 13:17:20

+0

對不起,它應該是popen而不是popen2 - 固定的。 – adamk 2010-07-21 04:39:54

0

我希望我理解你需要正確的。

Ajax背後的想法是無需重新加載整個頁面來更新頁面的內容。我認爲它應該符合你的需要。如果您想對它們進行Web化,您可能必須修改您的命令。您可能需要「即時獲取」他們的打印日誌。

這裏有一些想法:

  1. 寫一個非常簡單的頁面,執行命令的可能性(菜單,表格...)

  2. 當用戶請求命令執行,發對執行該命令的服務器執行ajax查詢。

  3. 您的命令需要修改才能將sys.stdout重定向到將打印日誌存儲到數據庫中的東西。您可以通過將一個具有write函數的對象分配給sys.stdout來完成此操作。

    class MyDbLogger: 
        def __init__(self, ...): 
         """Some initialization""" 
         ... 
    
        def write(self, s): 
         """write into the database""" 
         ... 
    
    dbout = MyDbLogger(...) 
    sys.stdout = dbout 
    
  4. 客戶端將輪詢服務器regurlarly獲取內容到數據庫中,然後將其寫入到頁面。

  5. 彗星肯定是要進行調查以實現實時行爲的技術。這將避免客戶定期輪詢服務器。這可能是對#4的改進,但實施起來可能更難一些。

我希望它能幫助