我使用Bottle框架创建了一个小型Web服务器来提供一个网页。这是通过我的python脚本“hello.py”完成的。从“hello.py”生成的网页,我可以编辑名为“data.txt”的文件的内容。当我从终端(python hello.py)运行“hello.py”时,这一切都很好。
但是当我使用PyInstaller创建可执行文件时遇到了问题。 我无法写入我的“data.txt”文件。我得到的错误消息是“权限被拒绝”。除此之外,可执行文件中的其他所有内容都可以使用!
在创建可执行文件之前,我将“data.txt”权限设置为777.这没有帮助。我也试过一个我在这里找到的潜在解决方案 - 但没有运气。它看起来像这样:
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
def fix_ownership(path):
"""Change the owner of the file to SUDO_UID"""
uid = os.environ.get('SUDO_UID')
gid = os.environ.get('SUDO_GID')
if uid is not None:
os.chown(resource_path(path), int(uid), int(gid))
@post('/data<dataValue>') # or @route('/login')
def data(dataValue):
thePostRequest = str(request.query_string)
newPostRequest = string.replace(thePostRequest, '%22', '\"')
fix_ownership("data.txt")
with open("data.txt","w") as fo:
fo.write('data = '+newPostRequest)
return
我寄予厚望,但那也没有用。这是我现在的代码(我是Python的新手,所以让我知道任何明显的错误):
from bottle import route, run, static_file, get, post, request, response, redirect
import os
import string
import sys
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
@get('/Count<deviceNumber>') # or @route('/login')
def Count(deviceNumber):
return
def fix_ownership(path):
"""Change the owner of the file to SUDO_UID"""
uid = os.environ.get('SUDO_UID')
gid = os.environ.get('SUDO_GID')
if uid is not None:
os.chown(resource_path(path), int(uid), int(gid))
@post('/data<dataValue>') # or @route('/login')
def data(dataValue):
thePostRequest = str(request.query_string)
newPostRequest = string.replace(thePostRequest, '%22', '\"')
newPostRequest = newPostRequest.replace('%27', '\'')
# THIS DOES NOT WORK AFTER EXECUTABLE IS CREATED BY PYINSTALLER - PERMISSION DENIED :(
with open("data.txt","w") as fo:
fo.write('data = '+newPostRequest)
return
@get('/ajax<noCache>') # or @route('/login')
def ajax(noCache):
return
@get('/<filename:re:.*\.(jpg|png|gif|ico)>')
def send_image(filename):
print "getting image..."
return static_file(filename, root=resource_path('./'))
@get('/<filename:path>')
def send_static(filename):
return static_file(filename, root=resource_path('./'))
# return static_file(filename, root=os.path.join(sys._MEIPASS, './'))
@route('/formSubmit', method='POST')
def formSubmit():
redirect("/hello", 303)
return
@route('/hello')
@route('/hello', method='GET')
def hello():
return '''
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-->
<script type="text/javascript" src="data.txt"></script>
<script type="text/javascript" src="myJavascript.js"></script>
<link rel="stylesheet" type="text/css" href="style.css"></script>
<title>CANARI JR. | Home</title>
</head>
<body onload="preparePage()">
<div id="spinner"></div>
<div id="container">
<div id="headerDiv">
<div id="logoDiv"><a href="/" onclick="showHome(); return false;">
<img src="cLogo.png" alt="Canari Jr. Logo">
</a>
</div>
<div id="navDiv">
<a href="/" onclick="showHome(); return false;"><p id="homeBtn" style="color:black;background-color:white">Home</p></a>
<a href="/" onclick="showSetup(); return false;"><p id="settingsBtn">Settings</p></a>
</div>
</div>
<div id="contentDiv">
</div>
<div id="addDiv" style="text-align:center;display:none;">
<h2>Add New Device</h2>
<form method="POST" id="deviceForm" action="/formSubmit" onsubmit="writeTxt('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P');">
<p style="background-color:#f5f5f5;" id="deviceDropdown">Monitor Type:<select name="" id="deviceList" onchange="loadContentA(this.value)">
<option value="default">Choose one...</option>
<option value="temp">Temperature</option>
<option value="humidity">Humidity</option>
<option value="analog">Analog</option>
<option value="digital">Digital</option>
<option value="counter">Counter</option>
</select></p>
<div id="clearDiv" style="clear:both"></div>
<a href="/" id="cancelBtn" onclick="hideAddDiv(); return false;">Cancel</a>
</form>
</div>
<div id="editDiv" style="display:none">
</div>
<div id="setupDiv" style="display:none">
<h2 style="margin-bottom:35px; border:3px solid #8C8C8C; width:40%; margin:0 auto; padding:10px">Change IP Address</h2>
<form method="POST" onsubmit="submitIP('ipAddress'); return false;">
<p>New IP Address: <input type="text" name="ipAddress" id="ipAddress"><input type="submit" value="Submit" style="padding:5px 10px 5px 10px">
</p>
<p>Make sure to <span style="color:red">write down this IP Address</span> as you will need it to complete setup.</p><br>
</form>
<h2 style="margin-bottom:35px; border:3px solid #8C8C8C; width:40%; margin:0 auto; padding:10px;margin-top:45px;">Binding Mode</h2>
<p>Binding Mode is currently:</p>
<a href="/" id="bindBtn" onclick="bindOn(); return false;" class="btn">OFF</a>
<p>(Click to change)</p>
</div>
</div>
</body>
</html>
'''
run(host='0.0.0.0', port=8080, debug=True)
我正在使用Mac OSX。
答案 0 :(得分:1)
我明白了!首先,我必须参考我的&#34; data.txt&#34;使用此功能的文件:
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
我这样使用它:
theDataFile = resource_path('./data.txt')
然后当我去写我的文件时,它工作了!像这样:
def data(dataValue):
thePostRequest = str(request.query_string)
newPostRequest = string.replace(thePostRequest, '%22', '\"')
newPostRequest = newPostRequest.replace('%27', '\'')
newPostRequest = newPostRequest.replace('%20', ' ')
newPostRequest = newPostRequest.replace('%7B', '{')
newPostRequest = newPostRequest.replace('%7D', '}')
print "This is the data value: " + newPostRequest
theDataFile = resource_path('./data.txt')
with open(theDataFile,"w") as fo:
fo.write('data = '+newPostRequest)
return