Sorry if this question is dumb. I converted a jqplot image to data-url and send it with a form. In the new page, I used cgi.FieldStorage() to get the submitted data-url, but got nothing. So could anyone give me some suggestions on my approach? Thanks!
I am using Python on Google App Engine
Input page Javascript
var imgData = $('#chart1').jqplotToImageStr({});
$('<tr style="display:none"><td><input type="hidden" name="extract1"></td></tr>')
.appendTo('.getpdf')
.find('input')
.data(imgData);
Output page:
def post(self):
form = cgi.FieldStorage()
extract1 = form.getvalue('extract1') #extract1 is empty
I tried to print the form and it looked as:MiniFieldStorage('extract1', '"data:image/png;base64,iVBORw0KGgoAAAANSUhE
If I assigned the data-url (data:image/png;base64,iVBORw0KGg...), it worked.
I have (working) code that does something similar.
def post(self):
img_data = self.request.get('extract1')
# then strip off the prefix and convert from base64
is what I'm doing. Poking into cgi.FieldStorage isn't something I normally see done in Python App Engine apps.
Related
I'm trying to automate some blog posting so that I can automatically post the contents of a text file onto a wordpress site I use for school. The site is wordpress version 4.1.1
So far I have tried using the wordpress_xmlrpc method and have been having some difficulties.
Here's an example of the code I've been trying to use:
from wordpress_xmlrpc import Client
from wordpress_xmlrpc.methods import posts
client = Client(...)
posts = client.call(posts.GetPosts())
page = WordPressPage()
page.title = 'About Me'
page.content = 'I am an aspiring WordPress and Python developer.'
page.post_status = 'publish'
page.id = client.call(posts.NewPost(page))
page.content = 'I am a WordPress and Python developer.'
client.call(posts.EditPost(page.id, page))
I don't particularly need anything complicated, I just want to get a simple python script working that creates a simple post on my school's blog.
Any help with why my examples aren't working, or any other examples that could work is greatly appreciated.
Thanks!
Your issue is with client.call(posts.getPosts())...Watch the case! It should be: client.call(posts.GetPosts()), with a capital G.
The error clues you into this:
AttributeError: 'module' object has no attribute 'getPosts'
This would be a reminder to check the methods of posts. A quick search will expose the simple typo.
I'm using Python to scrape data from a number of web pages that have simple HTML input forms, like the 'Username:' form at the bottom of this page:
http://www.w3schools.com/html/html_forms.asp (this is just a simple example to illustrate the problem)
Firefox Inspect Element indicates this form field has the following HTML structure:
<form name="input0" target="_blank" action="html_form_action.asp" method="get">
Username:
<input name="user" size="20" type="text"></input>
<input value="Submit" type="submit"></input>
</form>
All I want to do is fill out this form and get the resulting page:
http://www.w3schools.com/html/html_form_action.asp?user=ThisIsMyUserName
Which is what is produced in my browser by entering 'ThisIsMyUserName' in the 'Username' field and pressing 'Submit'. However, every method that I have tried (details below) returns the contents of the original page containing the unaltered form without any indication the form data I submitted was recognized, i.e. I get the content from the first link above in response to my request, when I expected to receive the content of the second link.
I suspect the problem has to do with action="html_form_action.asp" in the form above, or perhaps some kind of hidden field I'm missing (I don't know what to look for - I'm new to form submission). Any suggestions?
HERE IS WHAT I'VE TRIED SO FAR:
Using urllib.requests in Python 3:
import urllib.request
import urllib.parse
# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})
# Encode dict
example_data = example_data.encode('utf-8')
# Create request
example_url = 'http://www.w3schools.com/html/html_forms.asp'
request = urllib.request.Request(example_url, data=example_data)
# Create opener and install
my_url_opener = urllib.request.build_opener() # no handlers
urllib.request.install_opener(my_url_opener)
# Open the page and read content
web_page = urllib.request.urlopen(request)
content = web_page.read()
# Save content to file
my_html_file = open('my_html_file.html', 'wb')
my_html_file.write(content)
But what is returned to me and saved in 'my_html_file.html' is the original page containing
the unaltered form without any indication that my form data was recognized, i.e. I get this page in response: qqqhttp://www.w3schools.com/html/html_forms.asp
...which is the same thing I would have expected if I made this request without the
data parameter at all (which would change the request from a POST to a GET).
Naturally the first thing I did was check whether my request was being constructed properly:
# Just double-checking the request is set up correctly
print("GET or POST?", request.get_method())
print("DATA:", request.data)
print("HEADERS:", request.header_items())
Which produces the following output:
GET or POST? POST
DATA: b'user=ThisIsMyUserName'
HEADERS: [('Content-length', '21'), ('Content-type', 'application/x-www-form-urlencoded'), ('User-agent', 'Python-urllib/3.3'), ('Host', 'www.w3schools.com')]
So it appears the POST request has been structured correctly. After re-reading the
documentation and unsuccessfuly searching the web for an answer to this problem, I
moved on to a different tool: the requests module. I attempted to perform the same task:
import requests
example_url = 'http://www.w3schools.com/html/html_forms.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.post(example_url, params=data_to_send)
contents = response.content
And I get the same exact result. At this point I'm thinking maybe this is a Python 3
issue. So I fire up my trusty Python 2.7 and try the following:
import urllib, urllib2
data = urllib.urlencode({'user' : 'ThisIsMyUserName'})
resp = urllib2.urlopen('http://www.w3schools.com/html/html_forms.asp', data)
content = resp.read()
And I get the same result again! For thoroughness I figured I'd attempt to achieve the
same result by encoding the dictionary values into the url and attempting a GET request:
# Using Python 3
# Construct the url for the GET request
example_url = 'http://www.w3schools.com/html/html_forms.asp'
form_values = {'user': 'ThisIsMyUserName'}
example_data = urllib.parse.urlencode(form_values)
final_url = example_url + '?' + example_data
print(final_url)
This spits out the following value for final_url:
qqqhttp://www.w3schools.com/html/html_forms.asp?user=ThisIsMyUserName
I plug this into my browser and I see that this page is exactly the same as
the original page, which is exactly what my program is downloading.
I've also tried adding additional headers and cookie support to no avail.
I've tried everything I can think of. Any idea what could be going wrong?
The form states an action and a method; you are ignoring both. The method states the form uses GET, not POST, and the action tells you to send the form data to html_form_action.asp.
The action attribute acts like any other URL specifier in an HTML page; unless it starts with a scheme (so with http://..., https://..., etc.) it is relative to the current base URL of the page.
The GET HTTP method adds the URL-encoded form parameters to the target URL with a question mark:
import urllib.request
import urllib.parse
# Create dict of form values
example_data = urllib.parse.urlencode({'user': 'ThisIsMyUserName'})
# Create request
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
get_url = example_url + '?' + example_data
# Open the page and read content
web_page = urllib.request.urlopen(get_url)
print(web_page.read().decode(web_page.info().get_param('charset', 'utf8')))
or, using requests:
import requests
example_url = 'http://www.w3schools.com/html/html_form_action.asp'
data_to_send = {'user': 'ThisIsMyUserName'}
response = requests.get(example_url, params=data_to_send)
contents = response.text
print(contents)
In both examples I also decoded the response to Unicode text (something requests makes easier for me with the response.text attribute).
I am working with GAE and Python, I know python, but I don't know HTML, which seems to be what I need right now. I want to take in a text file write something in it then return it for download. I am using other people's examples, but far all I have is:
class MainPage(webapp.RequestHandler):
#http://bukhantsov.org/2011/12/python-google-app-engine-calculator/
def get(self):
self.response.out.write("""<html>
<body>
<form action='/' method='get' autocomplete='off'>
<input type='file' name='file'/><br/>
</form>
</body>
</html>""")
I imagine there is something I need to put in the file line so I can access what the user feeds it, but I don't know what or how to access it from the python code. So what should I do here?
If I understand your question correctly, you are trying to grab the text data being sent by the user via the GET call that is defined by the form action HTML line.
Concisely, you are looking for this call:
file = self.request.get('file')
This may also be useful:
filename = self.request.GET['file'].filename
These can be used in the same location and in conjunction with your "self.response.out".
More information can be found here:
https://developers.google.com/appengine/docs/python/tools/webapp/requestclass#Request_get
Alternatively, the BlobStore APIs may be easier.
https://developers.google.com/appengine/docs/python/blobstore/overview
Possibly related:
Upload files in Google App Engine,
Get original filename google app engine
Hope that helps!
Jess
I am having trouble getting a video entry which includes a link rel="edit". I need such an entry in order to be able to call DeleteVideoEntry(...) on it.
I am retrieving the video using GetYouTubeVideoEntry(youtube_id=XXXXXXX). My yt_service is initialized with a username, password, and a developer key. I use ProgrammaticLogin. This part seems to work fine. I use the same yt_service to upload said video earlier. Also, if I change the developer key to something bogus (during debugging) and try to authenticate, I get a 403 error. This leads me to believe that authentication works OK.
Needsless to say, the video entry retrieved with GetYouTubeVideoEntry(youtube_id=XXXXXXX) does not contain the edit link and I cannot use the entry in a DeleteVideoEntry(...) call.
Is there some special way to get a video entry which will contain a link element with a rel="edit"? Can anyone suggest some way to resolve my issue? Could this possibly be a bug?
Update:
For the records, when I tried getting the feed of all my uploads, and then looping through the video entries, the video entries do have an edit link. So using this works:
uri = 'http://gdata.youtube.com/feeds/api/users/%s/uploads' % username
feed = yt_service.GetYouTubeVideoFeed(uri)
for entry in feed.entry:
yt_service.DeleteVideoEntry(entry)
But this does not:
entry = yt_service.GetYouTubeVideoEntry(video_id = video.youtube_id)
yt_service.DeleteVideoEntry(entry)
Using the same yt_service.
I've just deleted youtube video using gdata and ProgrammaticLogin()
Here is some steps to reproduce:
import gdata.youtube.service
yt_service = gdata.youtube.service.YouTubeService()
yt_service.developer_key = 'developer_key'
yt_service.email = 'email'
yt_service.password = 'password'
yt_service.ProgrammaticLogin()
# video_id should looks like 'iu6Gq-tUsTc'
uri = 'https://gdata.youtube.com/feeds/api/users/%s/uploads/%s' % (username, video_id)
entry = yt_service.GetYouTubeUserEntry(uri=uri)
response = yt_service.DeleteVideoEntry(entry)
print response # True
yt_service.GetYouTubeVideoFeed(uri) works because GetYouTubeVideoFeed doesn't check uri and just calls self.Get(uri, ...) but originaly, I think, it expected 'https://gdata.youtube.com/feeds/api/videos' uri.
vice versa yt_service.GetYouTubeVideoEntry() use YOUTUBE_VIDEO_URI = 'https://gdata.youtube.com/feeds/api/videos' but this entry doesn't contains rel="edit"
Hope that helps you out
You can view the HTTP headers of the generated requests by setting the debug flag to true. This is as simple as:
yt_service = gdata.youtube.service.YouTubeService()
yt_service.debug = True
You can read about this in the documentation here.
I've created a HTML page with forms, which takes a name and password and passes it to a Python Script which is supposed to print the persons name with a welcome message. However, after i POST the values, i'm just getting the Python code displayed in the browser and not the welcome message. I have stored the html file and python file in the cgi-bin folder under Apache 2.2. If i just run a simple hello world python script in the browser, the "Hello World" message is being displayed. I'm using WinXP, Python 2.5, Apache 2.2. the code that i'm trying to run is the following:
#!c:\python25\python.exe
import cgi
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
reshtml = """Content-Type: text/html\n
<html>
<head><title>Security Precaution</title></head>
<body>
"""
print reshtml
User = form['UserName'].value
Pass = form['PassWord'].value
if User == 'Gold' and Pass == 'finger':
print '<big><big>Welcome'
print 'mr. Goldfinger !</big></big><br>'
print '<br>'
else:
print 'Sorry, incorrect user name or password'
print '</body>'
print '</html>'
The answer to it might be very obvious, but its completely escaping me. I'm very new to Python so any help would be greatly appreciated.
Thanks.
This
i'm just getting the Python code
displayed in the browser
sounds like CGI handling with Apache and Python is not configured correctly.
You can narrow the test case by passing UserName and PassWord as GET parameters:
http://example.com/cgi-bin/my-script.py?UserName=Foo&PassWord=bar
What happens if you do this?
You may have to extract the field values like this
User = form.getfirst('UserName')
Pass = form.getfirst('PassWord')
I know, it's strange.