How To Get Blob Key with Python? - python

I am having difficulties in storing and then retrieving the blobstore key. It looks like I am able to get the database row key # instead of the blob key#....
1) I am not sure how to store the key
2) Also, I am not sure how the data currently gets stored into the UserPhoto datastructure
set up
3) How do I retrieve the Blob's key related to the current user, so I can display a link to i?
any help would be greatly appreciated.
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext import db
import urllib
class UserPhoto(db.Model):
user = db.StringProperty()
user1 = db.EmailProperty()
blob_prop = blobstore.BlobKey
blob_key = blobstore.BlobReferenceProperty()
class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
upload_url = blobstore.create_upload_url('/upload')
existing_data = "<br>"
if user:
data = UserPhoto.all()
#filter data by user e-mail
results = data.filter("user1 = ", user.email())
for dt in results:
existing_data +='<a href="/serve/%s' % dt.key() + '">'
existing_data += '%s' % dt.key() + '<br>'
self.response.out.write(
'<div align=center>Hello %s <a align="center" href="%s">Sign out</a><br>Is administrator: %s' %
(user.nickname(), users.create_logout_url("/"), users.is_current_user_admin())
+'<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url+
"""<br>Upload File: <input type="file" name="file"><br> <input type="submit"
name="submit" value="Submit"> </form>
<br>"""+existing_data + "</div>"
)
#the code below is used for testing...purposes only...
for b in blobstore.BlobInfo.all():
self.response.out.write('<li>' + str(b.filename) + '')
else:
self.redirect(users.create_login_url(self.request.uri))
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file') # 'file' is file upload field in the form
blob_info = upload_files[0]
user = users.get_current_user()
if user:
data = UserPhoto()
data.user1 = users.get_current_user().email()
data.blob_key = str(blob_info.key())
# data.user2[0] = self.get_uploads()
data.blob_prop = blob_info.key()
data.put()
#self.redirect('/serve/%s' % blob_info.key())
self.redirect('/')
class ViewPhotoHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, photo_key):
blob_key = str(urllib.unquote(photo_key))
if not blobstore.get(photo_key):
self.error(404)
else:
#self.send_blob(photo_key)
#self.send_blob('/serve/%s' % photo_key)
self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
application = webapp.WSGIApplication([('/', MainPage),
('/upload', UploadHandler),
('/serve/([^/]+)?', ServeHandler),
('/view_photo/([^/]+)?', ViewPhotoHandler)
],debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()

You're asking for the UserPhoto entity key when you construct the output, not the blobstore reference within that entity. It should be:
existing_data +='<a href="/serve/%s">' % dt.blob_key

Related

Blobstore Python API Download URL using Django HTML template

I'm creating a dropbox service using BlobStore, however I can't find a good way to implement the file download option from my Django HTML template.
Here is my app.yaml
application: my_application
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: /favicon\.ico
- url: (/.*)*
script: main.app
libraries:
- name: django
version: latest
Here is the main.py
#!/usr/bin/env python
from django.core.management import setup_environ
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext import blobstore
from google.appengine.ext.blobstore import BlobInfo
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import util
import django
import webapp2
import wsgiref.handlers
class UserUpload(db.Model):
blob_key = blobstore.BlobReferenceProperty(required=True)
user = db.UserProperty(required=True)
user_id = db.StringProperty(required=True)
creation = db.DateTimeProperty(required=True, auto_now_add=True)
filename = db.StringProperty()
content_type = db.StringProperty()
size = db.IntegerProperty()
MD5 = db.StringProperty()
# Start Dumpbox login
class MainPage(webapp2.RequestHandler):
#util.login_required
def get(self):
logout_url = users.create_logout_url('/')
upload_url = blobstore.create_upload_url('/upload')
user = users.get_current_user()
q = UserUpload.all()
q.filter('user_id =', users.get_current_user().user_id())
q.order('-creation')
if user:
html = template.render('templates/header.html', {'title': 'Dumpbox', 'nickname': user.nickname(), 'url': upload_url})
html = html + template.render('templates/table.html', { 'file_name': 'File Name',
'content_type': 'Content Type',
'size': 'Size',
'timestamp': 'Creation Date',
'q': q
})
html = html + template.render('templates/footer.html', {'logout_link': logout_url})
self.response.out.write(html)
else:
self.redirect(users.create_login_url(self.request.uri))
class LogoutHandler(webapp2.RequestHandler):
def get(self):
self.auth.unset_session()
self.redirect(self.uri_for('home'))
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file') # 'file' is file upload field in the form
blob_info = upload_files[0]
user_upload = UserUpload( user=users.get_current_user(),
user_id=users.get_current_user().user_id(),
blob_key=blob_info.key(),
filename=blob_info.filename,
content_type=blob_info.content_type,
size=blob_info.size,
creation=blob_info.creation,
MD5=blob_info.md5_hash
)
db.put(user_upload)
self.redirect('/')
class DownloadHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
app = webapp2.WSGIApplication([('/', MainPage),('/upload', UploadHandler),('/download([^/]+)?', DownloadHandler)],debug=True)
wsgiref.handlers.CGIHandler().run(app)
def main():
run_wsgi_app(app)
if __name__ == '__main__':
main()
The Django template uses a table with a checkbox to select file to be downloaded, but I can't find a good way to implement it.
How can tick the checkbox and submit a form to download a blobstore file?
<form method="GET" action="">
<div id="table-wrapper">
<div id="table-scroll">
<table id="file_table" class="display" style="width:100%">
<tr>
<th style="width:10px"><input type="checkbox" onclick="checkAll(this)"/></th>
<th>{{file_name}}</th>
<th>{{content_type}}</th>
<th>{{size}}</th>
<th>{{timestamp}}</th>
</tr>
{% for file in q %}
{% if file.size > 0 %}
<tr>
<td><input id="{{file.blob_key}}" type="checkbox"/></td>
<td>{{file.filename}}</td>
<td>{{file.content_type}}</td>
<td>{{file.size}} Bytes</td>
<td>{{file.creation}}</td>
</tr>
{% endif %}
{% endfor %}
</table>
</div>
</div>
<p><input type="submit" value="Download"></p>
</form>
Appreciate any help.
Here's my solution:
In your template change to line
<td>{{file.filename}}</td>
into
<td>{{file.filename}}</td>
In your views add two method:
def download(request,client):
if 'key' in request.GET:
blob_key_str = request.GET['key']
if not blob_key_str:
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
blob_key = str(urllib.unquote(blob_key_str))
blob = blobstore.BlobInfo.get(blob_key)
try:
return send_blob(blob, save_as=True)
except ValueError, error:
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
and
import cgi
import logging
import urllib
def send_blob(blob_key_or_info, content_type=None, save_as=None):
CONTENT_DISPOSITION_FORMAT = 'attachment; filename="%s"'
if isinstance(blob_key_or_info, blobstore.BlobInfo):
blob_key = blob_key_or_info.key()
blob_info = blob_key_or_info
else:
blob_key = blob_key_or_info
blob_info = None
logging.debug(blob_info)
response = HttpResponse()
response[blobstore.BLOB_KEY_HEADER] = str(blob_key)
if content_type:
if isinstance(content_type, unicode):
content_type = content_type.encode('utf-8')
response['Content-Type'] = content_type
else:
del response['Content-Type']
def send_attachment(filename):
if isinstance(filename, unicode):
filename = filename.encode('utf-8')
response['Content-Disposition'] = (CONTENT_DISPOSITION_FORMAT % filename)
if save_as:
if isinstance(save_as, basestring):
send_attachment(save_as)
elif blob_info and save_as is True:
send_attachment(blob_info.filename)
else:
if not blob_info:
raise ValueError('The specified file is not found.')
else:
raise ValueError(
'Unexpected value for the name in which file is '
'expected to be downloaded')
return response
Change this code according to your needs :)

Retrieving Submitted Greetings in the Tutorial

I'm working though the GAE Tutorial and I'm getting the following error.
File "/Users/cparrish/bin/guestbook/guestbook.py", line 62, in get
for greeting in greetings:
NameError: global name 'greetings' is not defined
So I think the problem is here somewhere.
greetings_query = Greeting.query(
ancestor = guestbook_key(guestbook_name)).order(-Greeting.date)
greeetings = greetings_query.fetch(10)
for greeting in greetings:
if greeting.author:
self.response.write(
'<b>%s</b> wrote:' % greeting.author.nickname())
Which are lines 58 - 66
So I'm wondering if anyone else can see what I'm apparently missing here.
Full code base below.
import cgi
import urllib
from google.appengine.api import users
from google.appengine.ext import ndb
import webapp2
MAIN_PAGE_FOOTER_TEMPLATE = """\
<form action="/sign?%s" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<hr>
<form>Guestbook name:
<input value="%s" name="guestbook_name">
<input type="submit" value="switch">
</from>
%s
</body>
</html>
"""
DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
# We set a parent key on the 'Greetings' to ensure that they are all in the same
# entity group. Queries across the signle entity group will be consistent.
# However, the write rate should be limited to -1/second.
def guestbook_key(guestbook_name="DEFAULT_GUESTBOOK_NAME"):
""" Constructs a Datastore key for a Guestbook entity with guestbook_name. """
return ndb.Key('Guestbook', guestbook_name)
class Greeting(ndb.Model):
"""Models an individual Guestbook entry with author, content, and date. """
author = ndb.UserProperty()
content = ndb.StringProperty( indexed = False )
date = ndb.DateTimeProperty( auto_now_add = True )
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.write('<html><body>')
guestbook_name = self.request.get('guestbook_name', DEFAULT_GUESTBOOK_NAME)
# Ancestor Queries, as shown here, are strongly consisten with the High
# Replication Datastore. Queries that span entity groups are eventually
# consisten. If we omitted the ancestor from this query there would be
# a slight chance that Greetings that had just been written would not
# show up in a query.
greetings_query = Greeting.query(
ancestor = guestbook_key(guestbook_name)).order(-Greeting.date)
greeetings = greetings_query.fetch(10)
for greeting in greetings:
if greeting.author:
self.response.write(
'<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.write('An anonymous person wrote:')
self.response.write('<blockquote>%s</blockquote' %
cgi.escape(greeting.content))
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
# Write the submission form and the footer of the page
sign_query_parms = urllib.urlencode({'guestbook_name': guestbook_name})
self.response.write(MAIN_PAGE_FOOTER_TEMPLATE % (sign_query_parms, cgi.escape(guestbook_name), url, url_linktext))
class Guestbook(webapp2.RequestHandler):
def post(self):
# We set the same parent key on the 'Greeting' to ensure each getting
# is in the same entity group. Queries across the single entity group
# will be consistent. However, the write reate to a sing entity groupo
# should be limited to ~1/second.
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
greeting = Greeting(parent=guestbook_key(guestbook_name))
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
query_params = {'guestbook_name': guestbook_name}
self.redirect('/?' + urllib.urlencode(query_params))
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', Guestbook),
], debug=True)
There are three e's in your assignment of greeetings.
greeetings = greetings_query.fetch(10)
for greeting in greetings:
One of these es is not like the others, one of these es just doesn't belong...

Get data from webpages with Python

Looking to get data from a specific website with Python to upload onto Google App Engine. The idea is to create a database data to store the information on the server to retrieve and display in an web app.
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
import os
import datetime
from google.appengine.ext.webapp import template
# A class which creates all the pokemon on the server
class Pokemondata(db.Model):
number = db.IntegerProperty()
pokemonname = db.StringProperty()
description = db.StringProperty()
newpoke = Pokemondata(number="001",pokemonname="Balbasuar",description="The grass pokemon")
newpoke = Pokemondata(number="002",pokemonname="Ivysaur",description="The seed pokemon")
newpoke = Pokemondata(number="003",pokemonname="Venasaur",description="Another grass pokemon")
newpoke.put()
# A class to put new pokemon in to the server ?
class ApplyHandler(webapp.RequestHandler):
def post(self):
self.session = Session()
pnumber = self.request.get('number')
pname = self.request.get('pokemonname')
pdescription = self.request.get('description')
newpoke = Pokemondata(number=pnumber,pokemonname=pname,description=pdescription)
newpoke.put()
self.session['pokemon'] = pname
doRender(self,"board.htm",{})
# Construct a google table for this data
# to display
class JSONInterface(webapp.RequestHandler):
def get(self):
que = db.Query(Pokemondata)
listing = que.fetch(limit = 12)
doRender(self,'http://pokedexapp.appspot.com/?user=cater54321#gmail.com#input',
{'listing':listing})
application = webapp.WSGIApplication([('/(.*html)?', ApplyHandler),
('/json', JSONInterface)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
When I do deploy the app to test I am getting server error. Can anyone tell me if this is a step in the right direction and what needs amending?
The yaml file currently is
application: pokedexapp
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: main.py
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
# A class which creates all the pokemon on the server
class Pokemondata(db.Model):
number = db.IntegerProperty()
pokemonname = db.StringProperty()
description = db.StringProperty()
def post(self):
self.session = Session()
pnumber = self.request.get('number')
pname = self.request.get('pokemonname')
pdescription = self.request.get('description')
newpoke = Pokemondata(number=pnumber,pokemonname=pname,description=pdescription)
newpoke.put()
self.session['pokemon'] = pname
doRender(self,"board.htm",{})
Page = """
<html manifest="my.manifest">
<head>
<!-- All the js and css header links go here -->
</head>
<body>
<!-- all the needed HTML markup -->
<!-- if there is a place you would need to embed values (e.g. a user name), just use %s in its place, e.g. -->
<h1>%s's App Engine App</h>
<!-- you can now do a string substitution for the each %s (in order) - see end…
</body>
</html>
"""
# A class to get / put pokemon in to the server ?
class ApplyHandler(webapp.RequestHandler):
def post(self):
self.session = Session()
pnumber = self.request.get('number')
pname = self.request.get('pokemonname')
pdescription = self.request.get('description')
newpoke = Pokemondata(number=pnumber,pokemonname=pname,description=pdescription)
newpoke.put()
self.session['pokemon'] = pname
doRender(self,"board.htm",{})
# Construct a google big ass table for this data
# to display
def get(self):
que = db.Query(Pokemondata)
listing = que.fetch(limit = 12)
doRender(self,'http://pokedexapp.appspot.com/?user=cater54321#gmail.com#input',
{'listing':listing})
#self.response.out.write( page % "Fred Bloggs")
# This is standard Google App Engine stuff - create a WSGI application
# framework and set up the routing between URIs and Handlers...
application = webapp.WSGIApplication([('/', Pokemondata),
('/json', JSONInterface)], debug=True)
def Addlist():
run_wsgi_app(application)
if __name__ == "__Addlist__":
main()
code here
from google.appengine.ext import db
# A class which creates all the pokemon on the server
class Pokemondata(db.Model):
pokemonname = db.StringProperty()
newpoke = Pokemondata(pokemonname="Balbasuar")
newpoke.put()
class JSONInterface(webapp.RequestHandler):
def post(self):
pkmname = self.request.get('pokemonname')
callback = self.request.get('callback')
# This line makes the Message object...
pkmname = Pokemondata(pokemonname=pkmname)
# This one pushes it to the database (a Big-Table)...
pkmname.put()
self.response.out.write(getJSONMessages(callback))
def get(self):
callback = self.request.get('callback')
self.response.out.write(getJSONMessages(callback))
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
import os
import datetime
from google.appengine.ext.webapp import template
# A class which creates all the pokemon on the server
class Pokemondata(db.Model):
def get(self):
pokemonname = db.StringProperty()
newpoke = Pokemondata(pokemonname="Balbasuar")
newpoke.put()
class JSONInterface(webapp.RequestHandler):
def post(self):
pkmname = self.request.get('pokemonname')
callback = self.request.get('callback')
# This line makes the Message object...
pkmname = Pokemondata(pokemonname=pkmname)
# This one pushes it to the database (a Big-Table)...
pkmname.put()
self.response.out.write(getJSONMessages(callback))
def get(self):
callback = self.request.get('callback')
self.response.out.write(getJSONMessages(callback))

Using djangoTemplate and db.Model in Google App Engine

I have a small app that has a form that grabs data about a new hire, emails people about it, and stores the data for future use. Everything is working fine, but I can't seem to find info on using djangoforms and check boxes. These are obviously a boolean value, but if I add a db.Boolean value to my db.Model class, and then had it to djangoforms.ModelForm class to generate it, nothing appears. I added it to my db>model, it creates a record default to false, but there is no way to modify from the form. Also,db.Text doesn't produce a fiel either. I am probably not being clear enough here, due to the fact this is my first GAE and Django project. Code is below
import cgi
import wsgiref.handlers
from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import mail
from google.appengine.ext.db import djangoforms
class Item(db.Model):
first_name = db.StringProperty()
last_name = db.StringProperty()
goes_by = db.StringProperty()
Studio = db.StringProperty()
Discipline = db.StringProperty()
position = db.StringProperty()
level = db.StringProperty(default='choice', choices=['choice', 'choice',
'choice', 'choice', 'choice', 'choice'])
start_date = db.DateTimeProperty()
buddy_name = db.StringProperty()
past_employee = bool()
email = db.EmailProperty()
cell_phone = db.PhoneNumberProperty()
phone = db.PhoneNumberProperty()
hire_type = db.StringProperty(default='Full Time',choices=[
'Temp', 'Intern', 'Contract', 'Full Time'])
seating_location = db.StringProperty()
additional_comments = db.Text()
entry_time = db.DateTimeProperty(auto_now_add=True)
added_by = db.UserProperty()
class ItemForm(djangoforms.ModelForm):
class Meta:
model = Item
exclude = ['added_by']
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body><head><link type="text/css" rel="stylesheet" href="/stylesheets/form.css"></head>'
'<div id=header><div id="logo><img src="/img/placeimg.gif"></div><div id ="headertxt"><h2>Place New Hire Portal</h2>'
'<p>Please filll out this form as accurately as possible, this information is used to create employee files and to setup IS equipment</div> '
'</div><div id="contain">'
'<form method="POST" '
'action="/">'
'<table>')
# This generates our fields and writes it in the response
self.response.out.write(ItemForm())
self.response.out.write('</table>'
'<input type="submit">'
'</form></div></body></html>')
def post(self):
data = ItemForm(data=self.request.POST)
if data.is_valid():
# Save the data, and redirect to the view page
entity = data.save(commit=False)
entity.added_by = users.get_current_user()
entity.put()
self.redirect('/items.html')
mailing_address = ("person#place.com")
sender_address = ("person#place.com")
subject = "A new hire has been made - Please begin Process"
body = ("""
The Following Person is scheduled to start at place on :
%s %s - %s \ %s - %s - %s
Please find the orientation template attached. In order to be sure all employees are oriented in the same way
please be sure to cover the items listed under your name.
In addition, afer the completion of your session, please escort the new hire to the next session and makle introductions. This will
ensure that the schedule continues in order.
Buddy, thank you very much for being a buddy to %s, Your time and lunch expenses should be charged to your Studio Operations number. Thank you
very much for helping %s with their transiton to Place."""
%(entity.first_name, entity.last_name, entity.Studio, entity.Discipline, entity.seating_location,
entity.buddy_name, entity.first_name, entity.first_name))
mail.send_mail(sender_address, mailing_address, subject, body)
else:
# Reprint the form
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/">'
'<table>')
self.response.out.write(data)
self.response.out.write('</table>'
'<input type="submit">'
'</form></body></html>')
class ItemPage(webapp.RequestHandler):
def get(self):
self.response.out.write('</br></br>Return to Form Entry</br></br>')
query = db.GqlQuery("SELECT * FROM Item ORDER BY first_name")
for item in query:
self.response.out.write('Edit - ' %
item.key().id())
self.response.out.write("%s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s | %s </br>"%
(item.first_name, item.last_name, item.goes_by, item.Studio, item.Discipline, item.position,
item.level, item.start_date, item.past_employee, item.cell_phone, item.seating_location,
item.additional_comments, item.email, item.phone, item.hire_type))
class EditPage(webapp.RequestHandler):
def get(self):
id = int(self.request.get('id'))
item = Item.get(db.Key.from_path('Item', id))
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/edit">'
'<table>')
self.response.out.write(ItemForm(instance=item))
self.response.out.write('</table>'
'<input type="hidden" name="_id" value="%s">'
'<input type="submit">'
'</form></body></html>' % id)
def post(self):
id = int(self.request.get('_id'))
item = Item.get(db.Key.from_path('Item', id))
data = ItemForm(data=self.request.POST, instance=item)
if data.is_valid():
# Save the data, and redirect to the view page
entity = data.save(commit=False)
entity.added_by = users.get_current_user()
entity.put()
self.redirect('/items.html')
else:
# Reprint the form
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/edit">'
'<table>')
self.response.out.write(data)
self.response.out.write('</table>'
'<input type="hidden" name="_id" value="%s">'
'<input type="submit">'
'</form></body></html>' % id)
def main():
application = webapp.WSGIApplication(
[('/', MainPage),
('/edit', EditPage),
('/items.html', ItemPage),
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__=="__main__":
main()
Wobble answered it for me
should be TextProperty and BooleanProperty. db.Text is just an alias to datastore_types.Text, not a Property subclass, and db.Boolean should raise an exception as far as I can see

How to display an image in GAE datastore?

I read the tutorial and all the sources I could find about displaying an image saved in datastore and still I could not make it work. I appreciate any help. This is my previous question.
The code below, for /displayimage shows broken link for the image; and for /image it gives BadKeyError: Invalid string key . According to Nick Johnson reply here I must be passing an empty string for img_id but logging.info in /display image shows this key: (((result.key():)))) agpkZXZ-dGluZy0xcg8LEghIb21lUGFnZRjOCAw. Thanks for your help.
class HomePage(db.Model):
thumbnail = db.BlobProperty()
firm_name = db.StringProperty()
class ImageUpload(webapp.RequestHandler):
def get(self):
...
self.response.out.write("""
<form action="/imagesave" enctype="multipart/form-data" method="post">
<div><label>firm name:</label> <input type="text" name="firm_name" size=40></div>
<div><input type="file" name="img" /></div>
<div><input type="submit" value="Upload image"></div>
</form>
""")
class ImageSave(webapp.RequestHandler):
def post(self):
homepage = HomePage()
thumbnail = self.request.get("img")
firm_name = self.request.get("firm_name")
homepage.thumbnail = db.Blob(thumbnail)
homepage.firm_name = firm_name
homepage.put()
self.redirect("/imageupload")
class ImageResize(webapp.RequestHandler):
def post(self):
q = HomepageImage.all()
q.filter("firm_name", "mta")
qTable = q.get()
if qTable:
qTable.thumbnail = db.Blob(images.resize(self.request.get("img"), 32, 32))
db.put(qTable)
else:
self.response.out.write("""firm not found""")
self.redirect("/imageupload")
class DisplayImage(webapp.RequestHandler):
def get(self):
...
query = HomePage.all()
query.filter("firm_name", "mta")
result = query.get()
self.response.out.write("""firm name: %s""" % result.firm_name)
#self.response.out.write("""<img src="img?img_id=%s"></img>""" %
#chenged this line as systempuntoout's comment to:
self.response.out.write("""<img src="/image?img_id=%s"></img>""" %
result.key())
#but I still get the same error
class Image(webapp.RequestHandler):
def get(self):
...
#I am adding the next line to show that "img_id" is an empty string.
#why "img_id" empty here?
img_id = self.request.get("img_id")
logging.info("""**************************img_id: %s**************************""" % img_id)
#**************************img_id: **************************
homepage = db.get(self.request.get("img_id"))
if homepage.thumbnail:
self.response.headers['Content-Type'] = "image/jpg"
self.response.out.write(homepage.thumbnail)
else:
self.response.out.write("no image")
application = webapp.WSGIApplication(
[
("/imageresize",ImageResize),
("/imageupload", ImageUpload),
("/displayimage", DisplayImage),
("/imagesave", ImageSave),
("/image", Image),
],
debug=True
)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
You are pointing the image source to a not defined wrong img route .
The correct link should point to /image like this:
<img src="/image?img_id=%s"></img>
I've tested your code with my correction and it works nicely:
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import logging
class HomePage(db.Model):
thumbnail = db.BlobProperty()
firm_name = db.StringProperty()
class ImageUpload(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<form action="/imagesave" enctype="multipart/form-data" method="post">
<div><label>firm name:</label> <input type="text" name="firm_name" size=40></div>
<div><input type="file" name="img" /></div>
<div><input type="submit" value="Upload image"></div>
</form>
""")
class ImageSave(webapp.RequestHandler):
def post(self):
homepage = HomePage()
thumbnail = self.request.get("img")
firm_name = self.request.get("firm_name")
homepage.thumbnail = db.Blob(thumbnail)
homepage.firm_name = firm_name
homepage.put()
self.redirect("/imageupload")
class ImageResize(webapp.RequestHandler):
def post(self):
q = HomepageImage.all()
q.filter("firm_name", "mta")
qTable = q.get()
if qTable:
qTable.thumbnail = db.Blob(images.resize(self.request.get("img"), 32, 32))
db.put(qTable)
else:
self.response.out.write("""firm not found""")
self.redirect("/imageupload")
class DisplayImage(webapp.RequestHandler):
def get(self):
query = HomePage.all()
query.filter("firm_name", "mta")
result = query.get()
self.response.out.write("""firm name: %s""" % result.firm_name)
self.response.out.write("""<img src="/image?img_id=%s"></img>""" %
result.key())
class Image(webapp.RequestHandler):
def get(self):
img_id = self.request.get("img_id")
logging.info("""**************************img_id: %s**************************""" % img_id)
homepage = db.get(self.request.get("img_id"))
if homepage.thumbnail:
self.response.headers['Content-Type'] = "image/jpg"
self.response.out.write(homepage.thumbnail)
else:
self.response.out.write("no image")
application = webapp.WSGIApplication(
[
("/imageresize",ImageResize),
("/imageupload", ImageUpload),
("/displayimage", DisplayImage),
("/imagesave", ImageSave),
("/image", Image),
],
debug=True
)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()

Categories

Resources