<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Swarling Black Mable &#187; Django</title>
	<atom:link href="http://blainegarrett.com/category/programming/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://blainegarrett.com</link>
	<description>Blaine Garrett's Home on the Web - Art, Programming, Ideas, and more</description>
	<lastBuildDate>Tue, 02 Aug 2011 18:50:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Appengine Files Api &#8211; part 1: Storing/Fetching remote images in Blobstore using Django</title>
		<link>http://blainegarrett.com/2011/04/02/appengine-files-api-part-1-storingfetching-remote-images-in-blobstore-using-django/</link>
		<comments>http://blainegarrett.com/2011/04/02/appengine-files-api-part-1-storingfetching-remote-images-in-blobstore-using-django/#comments</comments>
		<pubDate>Sat, 02 Apr 2011 19:00:23 +0000</pubDate>
		<dc:creator>blainegarrett</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Google AppEngine]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blainegarrett.com/?p=1009</guid>
		<description><![CDATA[Here is a quick tutorial on how to fetch remote images with the new Files API on Google Appengine 1.4.3 released March 30th. These examples use Django. Before we begin, read up on how to write files to blobstore using the Files API. Prior to the 1.4.3 release of the SDK, the only way to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blainegarrett.com/2010/01/25/appengine-djangogql-ensuring-uniqueness-of-model-type-on-edit/saupload_google_appengine/" rel="attachment wp-att-840"><img src="http://blainegarrett.com/files/2010/01/saupload_google_appengine.png" alt="" width="150" height="150" class="alignleft size-full wp-image-840" /></a>Here is a quick tutorial on how to fetch remote images with the new Files API on Google Appengine 1.4.3 released March 30th. These examples use Django.</p>
<p>Before we begin, read <a href="http://code.google.com/appengine/docs/python/blobstore/overview.html#Writing_Files_to_the_Blobstore">up on how to write files to blobstore using the Files API</a>. Prior to the 1.4.3 release of the SDK, the only way to get files into the blobstore (and thus leverage things like BlobInfo) was to upload them via a POST request. To do what I am attempting below required a really confusing multistep process to fetch the file data and then generate a post request to the blobstore upload url. This was very error prone and awkward, but it worked. With 1.4.3, the solution is fairly straight forward. Also, note, the below example works with any file data, not just images. </p>
<p>First lets set up a simple url to handle the fetching and displaying.</p>
<pre class="brush: python">
# Put this in your /urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns(&#039;&#039;,
...
(r&#039;^remote_fetch_image/$&#039;, &#039;cdn.views.remote_fetch_image&#039;),
(r&#039;^remote_display_image/(?P[^/]+)/$&#039;, &#039;cdn.views.remote_display_image&#039;),
...
)
</pre>
<p>Next create a folder in your main application called &#8220;cdn&#8221;. Inside of it, add and empty <strong>__init__.py</strong> file as well as a <strong>views.py</strong>.<br />
You may also need to add to add &#8220;cdn&#8221; to your list of installed apps in <strong>settings.py</strong></p>
<pre class="brush: python">
INSTALLED_APPS = (
...
&#039;cdn&#039;,
...
)
</pre>
<p>Next, open up <strong>cdn/views.py</strong> and add the following code:</p>
<pre class="brush: python">
from __future__ import with_statement # Note this MUST go at the top of your views.py
from google.appengine.ext import blobstore
from django import http
from google.appengine.ext import db
def remote_fetch_image(request):
    from google.appengine.api import files, urlfetch
    from django.core import urlresolvers
    from django import http

    # Fetch image content
    image_url = request.GET.get(&#039;image_url&#039;, None)
    if not image_url:
        return http.HttpResponse(&#039;Please provide a query argument named &quot;image_url&quot; that is the full url to an image. &#039;)
    fetch_response = urlfetch.fetch(image_url)

    file_data = fetch_response.content
    content_type = fetch_response.headers.get(&#039;content-type&#039;, None)

    # Create the file
    file_name = files.blobstore.create(mime_type=content_type)

    # Open the file and write to it
    with files.open(file_name, &#039;a&#039;) as f:
      f.write(file_data)

    # Finalize the file. Do this before attempting to read it.
    files.finalize(file_name)

    # Get the file&#039;s blob key
    blob_key = files.blobstore.get_blob_key(file_name)
    # We&#039;re technically done, but lets redirect and display the image
    return http.HttpResponseRedirect(urlresolvers.reverse(remote_display_image, args=[blob_key]))

def remote_display_image(request, blob_key):
    # Fetch blob by key from blobstore
    blob_info = blobstore.BlobInfo.get(blob_key)
    if not blob_info:
        raise Exception(&#039;Blob Key does not exist&#039;)

    blob_file_size = blob_info.size
    blob_content_type = blob_info.content_type

    # Attempt to fetch the blob in one or more chunks depending on size and api limits
    blob_concat = &quot;&quot;
    start = 0
    end = blobstore.MAX_BLOB_FETCH_SIZE - 1
    step = blobstore.MAX_BLOB_FETCH_SIZE - 1

    while(start &amp;lt; blob_file_size):
        blob_concat += blobstore.fetch_data(blob_key, start, end)
        temp_end = end
        start = temp_end + 1
        end = temp_end + step
    return http.HttpResponse(blob_concat, mimetype=blob_content_type)
</pre>
<p>Finally, open your app in the browser with the url to a file. For me, my sdk is mapped to the domain garrettclan.org:<br />
example: 	<em>http://garrettclan.org/remote_fetch_image/?image_url=<a href="http://storyofdim.com/2010/03/23/neuroma-flare/" target="_new">http://blainegarrett.com/files/2010/01/birthmarks2.jpg</a></em></p>
<p>You should see the image at the url and it is now in the blobstore. This is an example usage of the new files api. Please note that this is experimental and may change as Appengine progresses. Also, not that the above processes is subject to the urlfetch quota, blobstore quota, and cpu quotas. See more details about the <a href="http://code.google.com/appengine/docs/python/blobstore/overview.html#Writing_Files_to_the_Blobstore" target="_new">files API here</a>.</p>
<p>Also, if interested, the image I used is a painting my <a href="http://storyofdim.com">collaborative art crew</a> did called <a href="http://storyofdim.com/2010/03/23/neuroma-flare/">&#8220;Nuroma Flare&#8221;</a>, part of the <a href="http://storyofdim.com/category/artwork/series/birthmarks/">Birthmarks</a> series.</p>
<p>The next steps:</p>
<ol>
<li>Part 2: Fetching the Facebook Profile Image and attaching it to a user</li>
<li>Part 3: Scale/crop down large uploaded images to a reasonable size before storing in blobstore to save on disk space quotas</li>
<li>Part 4: Utilizing existing blobstore features to dynamically generate thumbnails and sized images</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blainegarrett.com/2011/04/02/appengine-files-api-part-1-storingfetching-remote-images-in-blobstore-using-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django in-url paging and reverse, url, permalink, etc</title>
		<link>http://blainegarrett.com/2007/09/10/django-urls-with-inline-paging-and-reverse/</link>
		<comments>http://blainegarrett.com/2007/09/10/django-urls-with-inline-paging-and-reverse/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 16:54:23 +0000</pubDate>
		<dc:creator>blainegarrett</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blainegarrett.com/blog/?p=25</guid>
		<description><![CDATA[Here is a quick note that my coworker George discovered that I went around and changed in some of our development code&#8230; Django&#8217;s url structure allows you to do your paging inline (bla.com/view/3/ instead of bla.com/view?page=3) which is better for url based page cache retrieval (at least in rails) as well as search spider optimization&#8230; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blainegarrett.com.digibodies.com/files/2007/09/django01a.jpg" title="django01a.jpg"><img src="http://blainegarrett.com.digibodies.com/files/2007/09/django01a.jpg" alt="django01a.jpg" style="float: right" /></a></p>
<p>Here is a quick note that my coworker George discovered that I went around and changed in some of our development code&#8230;</p>
<p>Django&#8217;s url structure allows you to do your paging inline (bla.com/view/3/ instead of bla.com/view?page=3) which is better for url based page cache retrieval (at least in rails)  as well as search spider optimization&#8230; and it is just more visually pleasing for bookmarks and link sharing. However, reverse(), url(), permalink() get confused on complex url rule.</p>
<p><span id="more-25"></span></p>
<p>The below rule in urls.py matches bla.com/view, bla.com/view/, bla.com/view/2, and bla.com/2/ :<br />
<code><br />
(r'^view/(?P<br />
[\d]+)?/*$', 'some_view'),<br />
</code></p>
<p>This works great! However, this works great if you are constructing your own links. If you make use of django&#8217;s reverse() or similar &#8220;view to url&#8221; creation tools, then you get some funky issues.</p>
<p>The final solution after lots of reading was to create 2 url rules in urls.py<br />
<code><br />
(r'^view/$', 'some_view'),<br />
(r'^view/(?P<br />
[\d]+)?/$', 'some_view'),<br />
</code></p>
<p>This is somewhat touched on in the <a href="http://www.djangoproject.com/documentation/url_dispatch/#naming-url-patterns">django documentation</a>, but according to the docs the solution above, would get &#8220;confused&#8221; since two address point to the same view. However, in the above case, they have different argument lists.  Word.</p>
]]></content:encoded>
			<wfw:commentRss>http://blainegarrett.com/2007/09/10/django-urls-with-inline-paging-and-reverse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

