好吧,我设法让它按照我想要的方式工作(尽管有些/大多数人可能不同意这种方法)。我按照下面的建议使用了 Flask。可能被认为“错误”的部分是 404 检查循环。这是不正确的设计,如果持续时间过长,会导致某些浏览器出现“卡住脚本”错误。但是,我要运行的脚本不会持续足够长的时间,因此不会成为问题。
感谢您的帮助,如果您有任何其他建议,请告诉我。
flask 应用:
import threading
import subprocess
import os
import sys
from flask import Flask
from flask import render_template, abort
app = Flask(__name__)
app.debug = True
def run_script():
theproc = subprocess.Popen([sys.executable, "run_me.py"])
theproc.communicate()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/generate')
def generate():
threading.Thread(target=lambda: run_script()).start()
return render_template('processing.html')
@app.route('/is_done')
def is_done():
hfile = "templates\\itworked.html"
if os.path.isfile(hfile):
return render_template('itworked.html')
else:
abort(404)
if __name__ == "__main__":
app.run()
处理.html:
<!DOCTYPE html>
<html>
<head>
<script src="/static/jquery.min.js"></script>
</head>
<body>
<p>Processing...</p>
<script>
setInterval(function()
{
var http = new XMLHttpRequest();
http.open('HEAD', "is_done", false);
http.send();
if (http.status==200)
window.location.replace("is_done");
},2000);
</script>
</body>
</html>
原始问题:
我是初级/中级 Python 程序员和初级 Web 开发人员,所以请多多包涵。 我想要的是: 用户单击一个超链接并被带到一个中间网页,上面写着类似“处理中...”的内容。在后台(在服务器上)这个链接触发一个 python 脚本来处理一个文件并创建一个新的网页。脚本完成后,用户将被重定向到新创建的页面。 我有的: 我有一个脚本可以进行处理并吐出一个新页面。我还没有弄清楚的是如何触发 python 脚本,然后在脚本完成时触发重定向。我看过像 django 和 cgi 脚本这样的网络框架。但是我还没有找到任何我认为符合要求的东西。我很可能只是遗漏了一些非常明显的东西,所以我非常感谢任何帮助。 谢谢。
最佳答案
解决此问题的一种简单方法是使用像 Flask 这样的简单 Web 框架来构建系统的 Web 部件。在魔术链接的请求处理程序中,您需要生成脚本并跟踪它。查看脚本是否完成并将其转发给用户的一种简单方法是定期发送 ajax 请求以检查是否完成。
因此,例如 Flask 网站可能如下所示:
import threading
import subprocess
import uuid
from flask import Flask
from flask import render_template, url_for, abort, jsonify, request
app = Flask(__name__)
background_scripts = {}
def run_script(id):
subprocess.call(["/path/to/yourscript.py", "argument1", "argument2"])
background_scripts[id] = True
@app.route('/')
def index():
return render_template('index.html')
@app.route('/generate')
def generate():
id = str(uuid.uuid4())
background_scripts[id] = False
threading.Thread(target=lambda: run_script(id)).start()
return render_template('processing.html', id=id)
@app.route('/is_done')
def is_done():
id = request.args.get('id', None)
if id not in background_scripts:
abort(404)
return jsonify(done=background_scripts[id])
和 index.html:
<a href="{{ url_for('generate') }}">click me</a>
和processing.html:
<html>
<head>
<script src="/static/jquery.js"></script>
<script>
function ajaxCallback(data) {
if (data.done)
window.location.replace("http://YOUR_GENERATED_PAGE_URL");
else
window.setTimeout(function() {
$.getJSON('{{ url_for('is_done') }}', {id: {{ id }} }, ajaxCallback);
}, 3000);
}
$(document).ready(function(){
ajaxCallback({done=false});
});
</script>
</head>
<body>
Processing...
</body></html>
目前这些都是未经测试的代码,但我希望您对如何解决这个问题有所了解。另请记住,这仅在您从一个进程提供页面时才有效,因此如果您设置 Apache 和 mod_wsgi,请确保进程组中只有一个进程。
如果您需要更复杂的解决方案,您可能需要查看消息队列等。
关于javascript - 创建一个执行 python 脚本的超链接(或按钮),然后在脚本完成时重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10903615/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg