SlideShare una empresa de Scribd logo
1 de 26
………
WECO Seminar Part II
How to build a personal portal on
Google App Engine with Django

                   Speaker : Jimmy Lu
                   Advisor : Hsing Mei

               Web Computing Laboratory
 Computer Science and Information Engineering Department
                Fu Jen Catholic University
Outline
• Design your personal portal
• Environment settings
       main.py
       settings.py
       app.yaml
• Implementation
• Demo
• Q&A
                      WECO Lab, CSIE dept., FJU
March 2, 2010                                     2
                        http://www.weco.net
Design your personal portal
• What elements should a personal portal
  have?
    Text: a simple blog
      - An editor
      - Posts archive
       Photos: upload and resize a profile picture
       Videos: fetch latest video you upload to your
          Youtube channel by Youtube API and embed
          it
       Widgets: embed Google Calendar and
                       WECO Lab, CSIE dept., FJU
March 2, 2010                                         3
          Google Map     http://www.weco.net
Environment settings                                     (1/5)



       main.py
      1. import os
      2. # point to seetings.py, then django knows how to configure the en
         vironment
      3. os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
      4.
      5. from google.appengine.ext.webapp.util import run_wsgi_app
      6. from google.appengine.dist import use_library
      7.
      8. # use_library('library_name', 'version'), impot django library
      9. use_library('django', '1.1')




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            4
                               http://www.weco.net
Environment settings                                       (2/5)


      10.
      11.   # django has implemented WSGI
      12.   import django.core.handlers.wsgi
      13.
      14.   def main():
      15.       # Create a Django application for WSGI.
      16.       application = django.core.handlers.wsgi.WSGIHandler()
      17.
      18.       # Run the WSGI CGI handler with that application.
      19.       run_wsgi_app(application)
      20.
      21.
      22.   if __name__ == '__main__':
      23.       main()



                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                           5
                                 http://www.weco.net
Environment settings                                     (3/5)



       settings.py
      import os

      # Because the django database mapping is not work on Google App
         Engine, we need to leave the database settings empty.
      DATABASE_ENGINE = ''
      DATABASE_NAME = ''
      DATABASE_USER = ''
      DATABASE_PASSWORD = ''
      DATABASE_HOST = ''
      DATABASE_PORT = '‘

      # localization
      TIME_ZONE = 'Asia/Taipei’
      LANGUAGE_CODE = 'zh-TW '

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                           6
                               http://www.weco.net
Environment settings                                     (4/5)


      # The path of the project root directory.
      ROOT_PATH = os.path.dirname(__file__)

      # Set the path where your templates locate.
      TEMPLATE_DIRS = (
          ROOT_PATH + '/templates',
      )

      INSTALLED_APPS = (
      #    'django.contrib.contenttypes',
      #    'django.contrib.sessions',
      )

      # Leave the others default.



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                    7
                               http://www.weco.net
Environment settings                                      (5/5)



• app.yaml
       Define the mapping of path to directory of
        static files(stylesheets, images, etc.) and the
        url.
         handlers:
         - url: /stylesheets
           static_dir: static/stylesheets

         - url: .*
           script: main.py



                              WECO Lab, CSIE dept., FJU
March 2, 2010                                                     8
                                http://www.weco.net
Implementation – models                                              (1/2)



• models.py
     We define three classes to store posts and
      pictures.
      1. class BlogPost(db.Model):
      2.      author = db.StringProperty()
      3.      title = db.StringProperty()
      4.      body = db.TextProperty()
      5.      # add the current time automatically.
      6.      timestamp = db.DateTimeProperty(auto_now_add = True)
      7.
      8. # a django form related to BlogPost.
      9. class BlogPostForm(djangoforms.ModelForm):
      10.     class Meta:
March 11.         model = BlogPost Lab, CSIE dept., FJU
                               WECO
      2, 2010                                                                9
                               http://www.weco.net
Implementation – models                                             (2/2)


      12.
      13.class Picture(db.Model):
      14.    # use BlobProperty to store a photo.
      15.    profilePicture = db.BlobProperty()
      16.    timestamp = db.DateTimeProperty(auto_now_add = True)




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                               10
                               http://www.weco.net
Implementation – views                                         (1/8)



• views.py
       Define a function to have an ability to edit a
        blog post and save it to the database.
      1. def edit(request):
      2.     # Use django form API, we can build a form object and display
          a form easily.
      3.     blogPostForm = BlogPostForm(data = request.POST or None)
      4.     t = loader.get_template("edit.html")
      5.     c = Context({ 'blogPostForm': blogPostForm })
      6.     blogPost = None
      7.     if blogPostForm.is_valid():



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            11
                               http://www.weco.net
Implementation – views                                           (2/8)


      8.           # Save the BlogPost object without save it to the databas
          e(commit = False).
      9.          blogPost = blogPostForm.save(commit = False)
      10.     if blogPost:
      11.         # Save it to the database.
      12.         blogPost.put()
      13.     if request.POST:
      14.         # Redirect to the main page.
      15.         return http.HttpResponseRedirect('/')
      16.
      17.     return HttpResponse(t.render(c))




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                             12
                               http://www.weco.net
Implementation – views                                           (3/8)



     Define a function to upload profile pictures.
      Notice that we use images API to resize the
      uploaded images.
      1. def upload(request):
      2.       if request.method == 'POST':
      3.           picture = Picture()
      4.           # Resize the picture by images API provided by Google App
            engine.
      5.           profile_picture = images.resize(request.FILES['img'].read
          (), 196, 196)
      6.           picture.profilePicture = db.Blob(profile_picture)
      7.           picture.put()
      8.           return http.HttpResponseRedirect('/')
      9.
                                WECO Lab, CSIE dept., FJU
March 10.
      2, 2010  return render_to_response('upload.html')                    13
                                http://www.weco.net
Implementation – views                                         (4/8)



       When a browser renders main.html, it will
        send request to the image source. By using
        url mapping, we map the url request to this
        function.
      1. def image(request):
      2.     # Get the picture by the key from database.
      3.     picture = Picture.get(request.GET['img_id'])
      4.     # Build your response
      5.     response = HttpResponse(picture.profilePicture)
      6.     # Set the content type to png because that's what the Google
         images api stores modified images as by default
      7.     response['Content-Type'] = 'image/png'
      8.
      9.     return response WECO Lab, CSIE dept., FJU
March 2, 2010                                                               14
                                http://www.weco.net
Implementation – views                                         (5/8)



       Use urlfetch API to fetch the response(XML
        format) from Youtube API and parse it to a
        DOM object. Then we can get the video id
        under “entry” elements.
      1. def video(request):
      2.     # From Youtube API document, you can get the url for getting
         your uploaded video.
      3.     url = "http://gdata.youtube.com/feeds/api/users/gn00023040/up
         loads"
      4.     # Fetch the result from url by urlfetch API provided by Googl
         e App engine.
      5.     result = urlfetch.fetch(url)
      6.     id = ''


                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            15
                               http://www.weco.net
Implementation – views                                          (6/8)


      7.      if result.status_code == 200:
      8.         # Parse the XML format by minidom which is a python build-
         in library.
      9.         xmldoc = minidom.parseString(result.content)
      10.         # An entry represents a video.
      11.         videos = xmldoc.getElementsByTagName('entry')
      12.         if videos:
      13.             # Get the first(latest) entry.
      14.             latest_video = videos[0]
      15.             id = latest_video.childNodes[0].childNodes[0].data[42:]

      16.
      17.       return id




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            16
                               http://www.weco.net
Implementation – views                                         (7/8)



• Send parameters to the templates to
  display post archive, profile picture, latest
  video and widgets.
      1. def main(request):
      2.     # Get all the posts chronologically.
      3.     posts = BlogPost.all().order('-timestamp')
      4.     # Store some parameters by Context dictionary.
      5.     c = Context()
      6.     c['posts'] = posts
      7.     c.push()
      8.     # Get the latest picture.
      9.     pictures = Picture.all().order('-timestamp').fetch(1)

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                          17
                               http://www.weco.net
Implementation – views                                         (8/8)


      1.        if pictures:
      2.            picture = pictures[0]
      3.            c['image_key'] = picture.key()
      4.            c.push()
      5.        # Request to the video function.
      6.        video_id = video(request)
      7.        if video_id != '':
      8.            c['id'] = video_id
      9.            c.push()
      10.       # Load the template.
      11.       t = loader.get_template("main.html")
      12.
      13.    # Send the parameters to the template, then the template will
          process the result.
      14.    return HttpResponse(t.render(c))


                                WECO Lab, CSIE dept., FJU
March 2, 2010                                                           18
                                  http://www.weco.net
Implementation –
templates                  (1/6)

• edit.html
       {{blogPostForm}} display a form for editing a
        blog post.
      1. <form action="{%url views.edit%}" method="post">
      2.     <table>
      3.         <!-- Display the form by django's form API -->
      4.         {{blogPostForm}}
      5.         <tr>
      6.             <td><input type="submit" value="Post"></td>
      7.         </tr>
      8.     </table>
      9. </form>



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                      19
                               http://www.weco.net
Implementation –
templates                  (2/6)

• upload.html
       Make sure the enctype attribute should be
        multipart/from-data
      1. <!--
          Remember the enctype attribute of the form shold by multipart/fr
         om-data or request.FILES will receive nothing. -->
      2. <form action="{%url views.upload%}" method="post" enctype="multip
         art/form-data">
      3.     <input type="file" name="img" />
      4.     <input type="submit" value="Upload" />
      5. </form>



                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            20
                               http://www.weco.net
Implementation –
templates                  (3/6)

• main.html
       Extend base.html and display post archive.
      1. {% extends "base.html" %}
      2. {% block content %}
      3.     <!-- Display all the posts iteratively -->
      4.     {% for post in posts %}
      5.         <h2>{{ post.title }}</h2>
      6.         <p>{{ post.timestamp|date:"l, F jS" }}</p>
      7.         <p>{{ post.body }}</p>
      8.     {% endfor %}
      9. {% endblock %}




                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                 21
                               http://www.weco.net
Implementation –
templates                    (4/6)

• base.html
       Map the src=“image?img_id=…” to the image
        function and get the image id by
        request.GET[„image_id‟]
      1.   <h2>My Picture</h2>
      2.   <!-- If there is no profile picture, we will ask for one. -->
      3.   {% if image_key %}
      4.   <!--
            Django will map the url, 'image?img_id=...', to the image functi
           on and get the image_key by requets.GET -->
      5.   <img src="image?img_id={{ image_key }}"></img>
      6.   {% else %}
      7.   Click <a href="upload">here</a> to upload your profile picture!
      8.   {% endif %}
                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                              22
                                 http://www.weco.net
Implementation –
templates                  (5/6)

       Embed your latest video by change the video
        id, {{id}}, to the embedded code provide by
        Youtube.
      1. <object width="425" height="344">
      2. <param name="movie" value="http://www.youtube.com/v/{{ id }}&hl=z
         h_TW&fs=1&"></param>
      3. <param name="allowFullScreen" value="true"></param>
      4. <param name="allowscriptaccess" value="always"></param>
      5. <embed src="http://www.youtube.com/v/{{ id }}&hl=zh_TW&fs=1&" typ
         e="application/x-shockwave-
         flash" allowscriptaccess="always" allowfullscreen="true" width="4
         25" height="344"></embed>
      6. </object>

                             WECO Lab, CSIE dept., FJU
March 2, 2010                                                            23
                               http://www.weco.net
Implementation –
templates                  (6/6)

       Where the result of main.html diplay.
      1. {% block content %}
      2. {% endblock %}


       We can also add some widgets here. Like
        Google Calendar or Google Map
      1. <h2>My Schedule</h2>
      2. <iframe src="http://www.google.com/calendar/embed?showTitle=0&sho
         wNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&mode=AGE
         NDA&height=400&wkst=1&bgcolor=%23453&src=weco.net_fm86efcblmn4qle
         bh9kometb6o%40group.calendar.google.com&color=%232952A3&ctz=Asia%
         2FTaipei" style=" border-
         width:0 " width="290" height="400" frameborder="0" scrolling="no"
         ></iframe>


                               WECO Lab, CSIE dept., FJU
March 2, 2010                                                            24
                                 http://www.weco.net
demo




                WECO Lab, CSIE dept., FJU
March 2, 2010                               25
                  http://www.weco.net
Q&A



Thanks for listening!

                WECO Lab, CSIE dept., FJU
March 2, 2010                               26
                  http://www.weco.net

Más contenido relacionado

Destacado

Learn More About Cyber Crime Investigation
Learn More About Cyber Crime Investigation Learn More About Cyber Crime Investigation
Learn More About Cyber Crime Investigation
Skills Academy
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorial
alexjones89
 

Destacado (12)

Cyber security and Hacking
Cyber security and HackingCyber security and Hacking
Cyber security and Hacking
 
Innovation at Microsoft
Innovation at MicrosoftInnovation at Microsoft
Innovation at Microsoft
 
The Art of Cyber War: Cyber Security Strategies in a Rapidly Evolving Theatre
The Art of Cyber War:  Cyber Security Strategies in a Rapidly Evolving TheatreThe Art of Cyber War:  Cyber Security Strategies in a Rapidly Evolving Theatre
The Art of Cyber War: Cyber Security Strategies in a Rapidly Evolving Theatre
 
Learn More About Cyber Crime Investigation
Learn More About Cyber Crime Investigation Learn More About Cyber Crime Investigation
Learn More About Cyber Crime Investigation
 
How to install Java and how to set the path
How to install Java and how to set the pathHow to install Java and how to set the path
How to install Java and how to set the path
 
WordPress Tutorial
WordPress TutorialWordPress Tutorial
WordPress Tutorial
 
Cyber security 07
Cyber security 07Cyber security 07
Cyber security 07
 
Area 51
Area 51Area 51
Area 51
 
Cybercrime investigation
Cybercrime investigationCybercrime investigation
Cybercrime investigation
 
cyber terrorism
cyber terrorismcyber terrorism
cyber terrorism
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorial
 
Area-51
Area-51Area-51
Area-51
 

Similar a How To Build A Personal Portal On Google App Engine With Django

iOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful BackendiOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful Backend
Stefano Zanetti
 
HTML5 Who what where when why how
HTML5 Who what where when why howHTML5 Who what where when why how
HTML5 Who what where when why how
brucelawson
 
把鐵路開進視窗裡
把鐵路開進視窗裡把鐵路開進視窗裡
把鐵路開進視窗裡
Wei Jen Lu
 

Similar a How To Build A Personal Portal On Google App Engine With Django (20)

Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Play framework
Play frameworkPlay framework
Play framework
 
Using RequireJS with CakePHP
Using RequireJS with CakePHPUsing RequireJS with CakePHP
Using RequireJS with CakePHP
 
iOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful BackendiOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful Backend
 
Django Seminar
Django SeminarDjango Seminar
Django Seminar
 
HTML5 Who what where when why how
HTML5 Who what where when why howHTML5 Who what where when why how
HTML5 Who what where when why how
 
Approaches to mobile site development
Approaches to mobile site developmentApproaches to mobile site development
Approaches to mobile site development
 
Developing iPhone and iPad apps that leverage Windows Azure
Developing iPhone and iPad apps that leverage Windows AzureDeveloping iPhone and iPad apps that leverage Windows Azure
Developing iPhone and iPad apps that leverage Windows Azure
 
Pyramid Framework
Pyramid FrameworkPyramid Framework
Pyramid Framework
 
Spring Performance Gains
Spring Performance GainsSpring Performance Gains
Spring Performance Gains
 
jRecruiter - The AJUG Job Posting Service
jRecruiter - The AJUG Job Posting ServicejRecruiter - The AJUG Job Posting Service
jRecruiter - The AJUG Job Posting Service
 
把鐵路開進視窗裡
把鐵路開進視窗裡把鐵路開進視窗裡
把鐵路開進視窗裡
 
Using MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB DayUsing MongoDB and a Relational Database at MongoDB Day
Using MongoDB and a Relational Database at MongoDB Day
 
JavaScript Coding with Class
JavaScript Coding with ClassJavaScript Coding with Class
JavaScript Coding with Class
 
Initiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App EngineInitiation the Java web application project in the Google App Engine
Initiation the Java web application project in the Google App Engine
 
J2 Ee Overview
J2 Ee OverviewJ2 Ee Overview
J2 Ee Overview
 
Intro to Joomla Development
Intro to Joomla DevelopmentIntro to Joomla Development
Intro to Joomla Development
 
Heroku pycon
Heroku pyconHeroku pycon
Heroku pycon
 
Building Dojo in the Cloud
Building Dojo in the CloudBuilding Dojo in the Cloud
Building Dojo in the Cloud
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 

Más de Jimmy Lu

Más de Jimmy Lu (20)

All the troubles you get into when setting up a production ready Kubernetes c...
All the troubles you get into when setting up a production ready Kubernetes c...All the troubles you get into when setting up a production ready Kubernetes c...
All the troubles you get into when setting up a production ready Kubernetes c...
 
A Million ways of Deploying a Kubernetes Cluster
A Million ways of Deploying a Kubernetes ClusterA Million ways of Deploying a Kubernetes Cluster
A Million ways of Deploying a Kubernetes Cluster
 
Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5Renaissance of JUnit - Introduction to JUnit 5
Renaissance of JUnit - Introduction to JUnit 5
 
Event sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachineEvent sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachine
 
Bootify your spring application
Bootify your spring applicationBootify your spring application
Bootify your spring application
 
A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...
A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...
A Prototype of Brain Network Simulator for Spatiotemporal Dynamics of Alzheim...
 
The Model of Spatiotemporal Dynamics of Alzheimer’s Disease
The Model of Spatiotemporal Dynamics of Alzheimer’s DiseaseThe Model of Spatiotemporal Dynamics of Alzheimer’s Disease
The Model of Spatiotemporal Dynamics of Alzheimer’s Disease
 
The Models of Alzheimer's Disease Part II
The Models of Alzheimer's Disease Part IIThe Models of Alzheimer's Disease Part II
The Models of Alzheimer's Disease Part II
 
The Models of Alzheimer's Disease Part I
The Models of Alzheimer's Disease Part IThe Models of Alzheimer's Disease Part I
The Models of Alzheimer's Disease Part I
 
The Models of Alzheimer's Disease Part III
The Models of Alzheimer's Disease Part IIIThe Models of Alzheimer's Disease Part III
The Models of Alzheimer's Disease Part III
 
On the Development of a Brain Simulator
On the Development of a Brain SimulatorOn the Development of a Brain Simulator
On the Development of a Brain Simulator
 
Design the Brain Simulator
Design the Brain SimulatorDesign the Brain Simulator
Design the Brain Simulator
 
Research Proposal and Milestone
Research Proposal and MilestoneResearch Proposal and Milestone
Research Proposal and Milestone
 
Reward
RewardReward
Reward
 
On the Development of a Brain Simulator
On the Development of a Brain SimulatorOn the Development of a Brain Simulator
On the Development of a Brain Simulator
 
Mining the Parkinson's Telemonitoring Data Set
Mining the Parkinson's Telemonitoring Data SetMining the Parkinson's Telemonitoring Data Set
Mining the Parkinson's Telemonitoring Data Set
 
Brian Simulator (a draft)
Brian Simulator (a draft)Brian Simulator (a draft)
Brian Simulator (a draft)
 
Exploring Complex Networks
Exploring Complex NetworksExploring Complex Networks
Exploring Complex Networks
 
Brain Network - Thalamocortical Motif
Brain Network - Thalamocortical MotifBrain Network - Thalamocortical Motif
Brain Network - Thalamocortical Motif
 
Brain Networks
Brain NetworksBrain Networks
Brain Networks
 

Último

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Último (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 

How To Build A Personal Portal On Google App Engine With Django

  • 1. ……… WECO Seminar Part II How to build a personal portal on Google App Engine with Django Speaker : Jimmy Lu Advisor : Hsing Mei Web Computing Laboratory Computer Science and Information Engineering Department Fu Jen Catholic University
  • 2. Outline • Design your personal portal • Environment settings  main.py  settings.py  app.yaml • Implementation • Demo • Q&A WECO Lab, CSIE dept., FJU March 2, 2010 2 http://www.weco.net
  • 3. Design your personal portal • What elements should a personal portal have?  Text: a simple blog - An editor - Posts archive  Photos: upload and resize a profile picture  Videos: fetch latest video you upload to your Youtube channel by Youtube API and embed it  Widgets: embed Google Calendar and WECO Lab, CSIE dept., FJU March 2, 2010 3 Google Map http://www.weco.net
  • 4. Environment settings (1/5)  main.py 1. import os 2. # point to seetings.py, then django knows how to configure the en vironment 3. os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' 4. 5. from google.appengine.ext.webapp.util import run_wsgi_app 6. from google.appengine.dist import use_library 7. 8. # use_library('library_name', 'version'), impot django library 9. use_library('django', '1.1') WECO Lab, CSIE dept., FJU March 2, 2010 4 http://www.weco.net
  • 5. Environment settings (2/5) 10. 11. # django has implemented WSGI 12. import django.core.handlers.wsgi 13. 14. def main(): 15. # Create a Django application for WSGI. 16. application = django.core.handlers.wsgi.WSGIHandler() 17. 18. # Run the WSGI CGI handler with that application. 19. run_wsgi_app(application) 20. 21. 22. if __name__ == '__main__': 23. main() WECO Lab, CSIE dept., FJU March 2, 2010 5 http://www.weco.net
  • 6. Environment settings (3/5)  settings.py import os # Because the django database mapping is not work on Google App Engine, we need to leave the database settings empty. DATABASE_ENGINE = '' DATABASE_NAME = '' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_HOST = '' DATABASE_PORT = '‘ # localization TIME_ZONE = 'Asia/Taipei’ LANGUAGE_CODE = 'zh-TW ' WECO Lab, CSIE dept., FJU March 2, 2010 6 http://www.weco.net
  • 7. Environment settings (4/5) # The path of the project root directory. ROOT_PATH = os.path.dirname(__file__) # Set the path where your templates locate. TEMPLATE_DIRS = ( ROOT_PATH + '/templates', ) INSTALLED_APPS = ( # 'django.contrib.contenttypes', # 'django.contrib.sessions', ) # Leave the others default. WECO Lab, CSIE dept., FJU March 2, 2010 7 http://www.weco.net
  • 8. Environment settings (5/5) • app.yaml  Define the mapping of path to directory of static files(stylesheets, images, etc.) and the url.  handlers:  - url: /stylesheets  static_dir: static/stylesheets  - url: .*  script: main.py WECO Lab, CSIE dept., FJU March 2, 2010 8 http://www.weco.net
  • 9. Implementation – models (1/2) • models.py  We define three classes to store posts and pictures. 1. class BlogPost(db.Model): 2. author = db.StringProperty() 3. title = db.StringProperty() 4. body = db.TextProperty() 5. # add the current time automatically. 6. timestamp = db.DateTimeProperty(auto_now_add = True) 7. 8. # a django form related to BlogPost. 9. class BlogPostForm(djangoforms.ModelForm): 10. class Meta: March 11. model = BlogPost Lab, CSIE dept., FJU WECO 2, 2010 9 http://www.weco.net
  • 10. Implementation – models (2/2) 12. 13.class Picture(db.Model): 14. # use BlobProperty to store a photo. 15. profilePicture = db.BlobProperty() 16. timestamp = db.DateTimeProperty(auto_now_add = True) WECO Lab, CSIE dept., FJU March 2, 2010 10 http://www.weco.net
  • 11. Implementation – views (1/8) • views.py  Define a function to have an ability to edit a blog post and save it to the database. 1. def edit(request): 2. # Use django form API, we can build a form object and display a form easily. 3. blogPostForm = BlogPostForm(data = request.POST or None) 4. t = loader.get_template("edit.html") 5. c = Context({ 'blogPostForm': blogPostForm }) 6. blogPost = None 7. if blogPostForm.is_valid(): WECO Lab, CSIE dept., FJU March 2, 2010 11 http://www.weco.net
  • 12. Implementation – views (2/8) 8. # Save the BlogPost object without save it to the databas e(commit = False). 9. blogPost = blogPostForm.save(commit = False) 10. if blogPost: 11. # Save it to the database. 12. blogPost.put() 13. if request.POST: 14. # Redirect to the main page. 15. return http.HttpResponseRedirect('/') 16. 17. return HttpResponse(t.render(c)) WECO Lab, CSIE dept., FJU March 2, 2010 12 http://www.weco.net
  • 13. Implementation – views (3/8)  Define a function to upload profile pictures. Notice that we use images API to resize the uploaded images. 1. def upload(request): 2. if request.method == 'POST': 3. picture = Picture() 4. # Resize the picture by images API provided by Google App engine. 5. profile_picture = images.resize(request.FILES['img'].read (), 196, 196) 6. picture.profilePicture = db.Blob(profile_picture) 7. picture.put() 8. return http.HttpResponseRedirect('/') 9. WECO Lab, CSIE dept., FJU March 10. 2, 2010 return render_to_response('upload.html') 13 http://www.weco.net
  • 14. Implementation – views (4/8)  When a browser renders main.html, it will send request to the image source. By using url mapping, we map the url request to this function. 1. def image(request): 2. # Get the picture by the key from database. 3. picture = Picture.get(request.GET['img_id']) 4. # Build your response 5. response = HttpResponse(picture.profilePicture) 6. # Set the content type to png because that's what the Google images api stores modified images as by default 7. response['Content-Type'] = 'image/png' 8. 9. return response WECO Lab, CSIE dept., FJU March 2, 2010 14 http://www.weco.net
  • 15. Implementation – views (5/8)  Use urlfetch API to fetch the response(XML format) from Youtube API and parse it to a DOM object. Then we can get the video id under “entry” elements. 1. def video(request): 2. # From Youtube API document, you can get the url for getting your uploaded video. 3. url = "http://gdata.youtube.com/feeds/api/users/gn00023040/up loads" 4. # Fetch the result from url by urlfetch API provided by Googl e App engine. 5. result = urlfetch.fetch(url) 6. id = '' WECO Lab, CSIE dept., FJU March 2, 2010 15 http://www.weco.net
  • 16. Implementation – views (6/8) 7. if result.status_code == 200: 8. # Parse the XML format by minidom which is a python build- in library. 9. xmldoc = minidom.parseString(result.content) 10. # An entry represents a video. 11. videos = xmldoc.getElementsByTagName('entry') 12. if videos: 13. # Get the first(latest) entry. 14. latest_video = videos[0] 15. id = latest_video.childNodes[0].childNodes[0].data[42:] 16. 17. return id WECO Lab, CSIE dept., FJU March 2, 2010 16 http://www.weco.net
  • 17. Implementation – views (7/8) • Send parameters to the templates to display post archive, profile picture, latest video and widgets. 1. def main(request): 2. # Get all the posts chronologically. 3. posts = BlogPost.all().order('-timestamp') 4. # Store some parameters by Context dictionary. 5. c = Context() 6. c['posts'] = posts 7. c.push() 8. # Get the latest picture. 9. pictures = Picture.all().order('-timestamp').fetch(1) WECO Lab, CSIE dept., FJU March 2, 2010 17 http://www.weco.net
  • 18. Implementation – views (8/8) 1. if pictures: 2. picture = pictures[0] 3. c['image_key'] = picture.key() 4. c.push() 5. # Request to the video function. 6. video_id = video(request) 7. if video_id != '': 8. c['id'] = video_id 9. c.push() 10. # Load the template. 11. t = loader.get_template("main.html") 12. 13. # Send the parameters to the template, then the template will process the result. 14. return HttpResponse(t.render(c)) WECO Lab, CSIE dept., FJU March 2, 2010 18 http://www.weco.net
  • 19. Implementation – templates (1/6) • edit.html  {{blogPostForm}} display a form for editing a blog post. 1. <form action="{%url views.edit%}" method="post"> 2. <table> 3. <!-- Display the form by django's form API --> 4. {{blogPostForm}} 5. <tr> 6. <td><input type="submit" value="Post"></td> 7. </tr> 8. </table> 9. </form> WECO Lab, CSIE dept., FJU March 2, 2010 19 http://www.weco.net
  • 20. Implementation – templates (2/6) • upload.html  Make sure the enctype attribute should be multipart/from-data 1. <!-- Remember the enctype attribute of the form shold by multipart/fr om-data or request.FILES will receive nothing. --> 2. <form action="{%url views.upload%}" method="post" enctype="multip art/form-data"> 3. <input type="file" name="img" /> 4. <input type="submit" value="Upload" /> 5. </form> WECO Lab, CSIE dept., FJU March 2, 2010 20 http://www.weco.net
  • 21. Implementation – templates (3/6) • main.html  Extend base.html and display post archive. 1. {% extends "base.html" %} 2. {% block content %} 3. <!-- Display all the posts iteratively --> 4. {% for post in posts %} 5. <h2>{{ post.title }}</h2> 6. <p>{{ post.timestamp|date:"l, F jS" }}</p> 7. <p>{{ post.body }}</p> 8. {% endfor %} 9. {% endblock %} WECO Lab, CSIE dept., FJU March 2, 2010 21 http://www.weco.net
  • 22. Implementation – templates (4/6) • base.html  Map the src=“image?img_id=…” to the image function and get the image id by request.GET[„image_id‟] 1. <h2>My Picture</h2> 2. <!-- If there is no profile picture, we will ask for one. --> 3. {% if image_key %} 4. <!-- Django will map the url, 'image?img_id=...', to the image functi on and get the image_key by requets.GET --> 5. <img src="image?img_id={{ image_key }}"></img> 6. {% else %} 7. Click <a href="upload">here</a> to upload your profile picture! 8. {% endif %} WECO Lab, CSIE dept., FJU March 2, 2010 22 http://www.weco.net
  • 23. Implementation – templates (5/6)  Embed your latest video by change the video id, {{id}}, to the embedded code provide by Youtube. 1. <object width="425" height="344"> 2. <param name="movie" value="http://www.youtube.com/v/{{ id }}&hl=z h_TW&fs=1&"></param> 3. <param name="allowFullScreen" value="true"></param> 4. <param name="allowscriptaccess" value="always"></param> 5. <embed src="http://www.youtube.com/v/{{ id }}&hl=zh_TW&fs=1&" typ e="application/x-shockwave- flash" allowscriptaccess="always" allowfullscreen="true" width="4 25" height="344"></embed> 6. </object> WECO Lab, CSIE dept., FJU March 2, 2010 23 http://www.weco.net
  • 24. Implementation – templates (6/6)  Where the result of main.html diplay. 1. {% block content %} 2. {% endblock %}  We can also add some widgets here. Like Google Calendar or Google Map 1. <h2>My Schedule</h2> 2. <iframe src="http://www.google.com/calendar/embed?showTitle=0&sho wNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&mode=AGE NDA&height=400&wkst=1&bgcolor=%23453&src=weco.net_fm86efcblmn4qle bh9kometb6o%40group.calendar.google.com&color=%232952A3&ctz=Asia% 2FTaipei" style=" border- width:0 " width="290" height="400" frameborder="0" scrolling="no" ></iframe> WECO Lab, CSIE dept., FJU March 2, 2010 24 http://www.weco.net
  • 25. demo WECO Lab, CSIE dept., FJU March 2, 2010 25 http://www.weco.net
  • 26. Q&A Thanks for listening! WECO Lab, CSIE dept., FJU March 2, 2010 26 http://www.weco.net