Python and Plone help - python

Im using the plone cms and am having trouble with a python script. I get a name error "the global name 'open' is not defined". When i put the code in a seperate python script it works fine and the information is being passed to the python script becuase i can print the query. Code is below:
#Import a standard function, and get the HTML request and response objects.
from Products.PythonScripts.standard import html_quote
request = container.REQUEST
RESPONSE = request.RESPONSE
# Insert data that was passed from the form
query=request.query
#print query
f = open("blast_query.txt","w")
for i in query:
f.write(i)
return printed
I also have a second question, can i tell python to open a file in in a certain directory for example, If the script is in a certain loaction i.e. home folder, but i want the script to open a file at home/some_directory/some_directory can it be done?

Python Scripts in Plone are restricted and have no access to the filesystem. The open call is thus not available. You'll have to use an External Method or full python module to have full access to the filesystem.

Related

"with open as f" won't open and It doesn't even say there's a problem

import requests
res = requests.get("https://google.com")
res.raise_for_status()
print(len(res.text))
print(res.text)
with open('mygoogle.html',"w",encoding=('utf-8')) as f :
f.write(res.text)
The with open as f part doesn't work.
If it does, it has to open new file, but it doesn't.
I have tested this code and it works properly - mygoogle.html gets written and contains the expected content. The issue is likely outside of the script then. Since it is using a relative path, the issue could be that the file is getting written somewhere where you don't expect it due to the working directory not being set how you expect - Windows often defaults to C:\Windows\system32 or your user profile directory (%userprofile% aka C:\users\<username>) for new cmd instances.

How to use the biblib parser with a bibtex file stored in a pyhon variable?

I have a bibtex file that I get from the frontend and I'm trying to parse this file with biblib (a python library to parse bibtex files). Because I get the file from the frontend its not stored in a file on my computer. The file gets passed through a variable from the frontend to python and is then stored in the python variable fileFromFrontend. So I can use for example:
bibtexFile = fileFromFrontend.read()
to read the file.
now I'm trying to do something like the following to print the parsed file in the python terminal:
from pybtex.database.input import bibtex
parser = bibtex.Parser()
bibtexFile= parser.parse_file(fileFromFrontend)
print (bibtexFile.entries)
but then I get this error:
-->bibtexFile = parser.parse_file(filesFromFrontend)
-->with open_file(filename, encoding=self.encoding) as f:
-->AttributeError: __enter__
This is probably because the parser tries to open the file but he doesn't have to open this file, he just needs to read this file. I don't know what function of the biblib library to use for parsing the file from a variable and haven't found anything so far to solve my problem.
Hopefully somebody can help
thanks
According to documentation ( https://docs.pybtex.org/api/parsing.html ) there is methods
parse_string and parse_bytes which could work.
so like this
from pybtex.database.input import bibtex
parser = bibtex.Parser()
bibtexFile= parser.parse_bytes(fileFromFrontend.read())
print (bibtexFile.entries)
I don't have pybtex installed, so I couldn't try it myself. But try those methods. Parse_bytes and parse_string needs bib-format as second parameter. In examples that is bibtex, so I tried it here.

Passing to SOAP arguments from the command line

I have a python script that successfully sends SOAP to insert a record into a system. The values are static in the test. I need to make the value dynamic/argument that is passed through the command line or other stored value.
execute: python myscript.py
<d4p1:Address>MainStreet</d4p1:Address> ....this works to add hard coded "MainStreet"
execute: python myscript.py MainStreet
...this is now trying to pass the argument MainStreet
<d4p1:Address>sys.argv[1]</d4p1:Address> ....this does not work
It saves the literal text address as "sys.argv[1]" ... I have imported sys ..I have tried %, {}, etc from web searches, what syntax am I missing??
You need to read a little about how to create strings in Python, below is how it could look like in your code. Sorry it's hard to say more without seeing your actual code. And you actually shouldn't create XMLs like that, you should use for instance xml module from standard library.
test = "<d4p1:Address>" + sys.argv[1] + "</d4p1:Address>"

Microsoft Ajax Minifier output path access error when called from Python

I'm calling Microsoft Ajax Minifier from Python like so:
minifyArguments = ["C:\Program Files (x86)\Microsoft\Microsoft Ajax Minifier\AjaxMin.exe"]
for f in filesToMinify:
minifyArguments.append(f)
minifyArguments.append("–out")
minifyArguments.append("C:\\Users\\XXX\\Desktop\\TestFolder") #minifyJSDestinationPath
minifyArguments.append("–clobber")
ajaxMinProcess = subprocess.Popen(minifyArguments, shell=False)
stdout, stderr = ajaxMinProcess.communicate()
This works fine, and I see that it's starting etc. but when it wants to write the output file it gives an error:
AjaxMinifier.exe: error AM-AUTH: Access to the path 'C:\Users\XXX\Desktop\TestFolder' is denied.
I have tried different folders, the issue is not exclusive to the one in the code. It can't write to any folder.
When I don't call it from Python but directly from the commandline it works without problems.
Why does this happen and how can I fix it?
Thanks.
I found the solution to my problem:
This line:
minifyArguments.append("C:\\Users\\XXX\\Desktop\\TestFolder")
Should include the filename, like this:
minifyArguments.append("C:\\Users\\XXX\\Desktop\\TestFolder\\script.min.js")

Setting apache server wide variables with python

I would like to be able to call a python script that checks to see if the variables passed to it have already been passed to it and if not then spit out a KML file for google earth to read. I've looked at environment variables to no avail. But essentially I need to store a string so that the next time the script is called I can reference it. I'll post what I have below. Thanks and any help is greatly appreciated.
EDIT: I suppose I didn't clearly state the issue, I'm attempting to call a python script on an Apache server with KML passing URL variables to the script. One of the URL variables contains a time string, I would like to store that time and be able to reference it to the next "Time" that is passed to the script, IF the times don't match then print out certain KML, If they DO match then print empty script so that Google Earth doesn't duplicate a placemark. In essence I am filtering the KML files so that I can avoid duplicates. I've also updated the code below.
import cgi
import os
url = cgi.FieldStorage()
bbox = url['test'].value
bbox = bbox.split(',')
lat = float(bbox[0])
lon = float(bbox[1])
alt = float(bbox[2])
when = str(bbox[3])
if when == os.environ['TEMP']:
kml = ('<?xml version="1.0" encoding="UTF-8"?>\n'
'<kml xmlns="http://www.opengis.net/kml/2.2">\n'
'</kml>')
else:
kml = ('<?xml version="1.0" encoding="UTF-8"?>\n'
'<kml xmlns="http://www.opengis.net/kml/2.2">\n'
'<NetworkLinkControl>\n'
'<Update>\n'
'<targetHref>http://localhost/GE/Placemark.kml</targetHref>\n'
'<Create>\n'
'<Folder targetId="fld1">\n'
'<Placemark>\n'
'<name>View-centered placemark</name>\n'
'<TimeStamp>\n'
'<when>%s</when>\n'
'</TimeStamp>\n'
'<Point>\n'
'<coordinates>%.6f,%.6f,%.6f</coordinates>\n'
'</Point>\n'
'</Placemark>\n'
'</Folder>\n'
'</Create>\n'
'</Update>\n'
'</NetworkLinkControl>\n'
'</kml>'
) % (when, lat, lon, alt)
os.environ['TEMP'] = when
print('Content-Type: application/vnd.google-earth.kml+xml\n')
print(kml)
It seems like you have a few options here to share a state:
Use a db.
file system based persistence
a separate daemon process that you can connect to via sockets
Use memcache or some other service to store in memory
You can share states via python: https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes)
You can also create a manager and have proxy objects:

Categories