2010-07-20 67 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的改进,但实施起来可能更难一些。

我希望它能帮助