Permalink
Browse files

Initial version

  • Loading branch information...
0 parents commit 4ad633f289fa4c248970774c778cbc65e35dc6c5 @dhalperi committed Jun 7, 2011
Showing with 157 additions and 0 deletions.
  1. 0 README
  2. +8 −0 app.yaml
  3. +11 −0 index.yaml
  4. +138 −0 main.py
No changes.
@@ -0,0 +1,8 @@
+application: halperin-redir
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: .*
+ script: main.py
@@ -0,0 +1,11 @@
+indexes:
+
+# AUTOGENERATED
+
+# This index.yaml is automatically updated whenever the dev_appserver
+# detects that a new type of query is run. If you want to manage the
+# index.yaml file manually, remove the above marker line (the line
+# saying "# AUTOGENERATED"). If you want to manage some indexes
+# manually, move them above the marker line. The index.yaml file is
+# automatically uploaded to the admin console when you next deploy
+# your application using appcfg.py.
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 Daniel Halperin <daniel@halper.in>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+from google.appengine.api import users
+from google.appengine.ext import webapp
+from google.appengine.ext import db
+from google.appengine.ext.webapp import util
+from datetime import datetime
+import cgi
+
+class Redirection(db.Model):
+ url = db.LinkProperty()
+ added = db.DateTimeProperty(auto_now_add=True)
+ last = db.DateTimeProperty()
+ hitcount = db.IntegerProperty(default=0)
+
+ def update(self):
+ self.hitcount += 1
+ self.last = datetime.now()
+
+
+class RedirPage(webapp.RequestHandler):
+ def get(self):
+ path = self.request.path
+ path_k = db.Key.from_path('Redirection', path)
+ result = db.get(path_k)
+ if not result:
+ self.response.set_status(404)
+ return
+ result.update()
+ result.put()
+ self.redirect(result.url, permanent=False)
+
+
+class PrivPage(webapp.RequestHandler):
@CSEMike
CSEMike Jun 7, 2011

again, probably want to configure this in the yaml rather than code. See here:

http://code.google.com/appengine/docs/python/config/appconfig.html

e.g.:

- url: /admin/.*
  script: admin.py
  login: admin
@dhalperi
dhalperi Jun 8, 2011 Owner

Yep. makes sense. See 71e41c7

I'm confused about the Model object. Redirection objects are used in both main.py and admin.py, declaring the model in both seems to cause no problems. But surely this code duplication is the wrong answer -- what to do?

@CSEMike
CSEMike Jun 8, 2011

create model.py, then from model import * in both I think

+ def validate_admin(self):
+ user = users.get_current_user()
+ if not user:
+ self.redirect(users.create_login_url(self.request.uri))
+ return False
+
+ if not users.is_current_user_admin():
+ self.response.set_status(403)
+ return False
+
+ return True
+
+
+class AddPage(PrivPage):
+ def post(self):
+ if not self.validate_admin():
+ return
+
+ name = self.request.get('name')
+ url = self.request.get('url')
+ if len(name) == 0:
+ self.response.out.write('Bad name '+cgi.escape(name))
+ return
+ if name[0] != '/':
+ name = '/' + name
+ if name == '/admin' or name == '/add' or name == '/del':
+ self.response.out.write('Bad name '+cgi.escape(name))
+ return
+ r = Redirection(key_name=name)
+ try:
+ r.url = url
+ except db.BadValueError:
+ self.response.out.write('Bad URL '+cgi.escape(url))
+ return
+ r.put()
+ self.redirect('/admin', permanent=False)
+
+ def get(self):
+ self.post()
+
+
+class DelPage(PrivPage):
+ def post(self):
+ if not self.validate_admin():
+ return
+
+ name = self.request.get('name')
+ name_k = db.Key.from_path('Redirection', name)
+ result = db.get(name_k)
+ if not result:
+ self.response.out.write('name not found '+cgi.escape(name))
+ return
+ result.delete()
+ self.redirect('/admin', permanent=False)
+
+ def get(self):
+ self.post()
+
+
+class AdminPage(PrivPage):
+ def get(self):
+ if not self.validate_admin():
+ return
+
+ links = db.GqlQuery("SELECT * "
+ "FROM Redirection "
+ "ORDER BY added")
+
+ if links.count(1) == 0:
+ self.response.out.write("No links<BR>\n")
+
+ for link in links:
+ delurl = "/del?name=%s" %(link.key().name())
+ msg = "%s -> <a href='%s'>%s</a> : count=%d : added=%s : last=%s" %(link.key().name(), link.url, link.url, link.hitcount, str(link.added), str(link.last))
+ self.response.out.write( "<a href='" + delurl + "'>X</a> " + msg + '<br>\n')
+
+ self.response.out.write('<br>\n')
+ self.response.out.write("""
+ <form action="/add" method="post">
+ <div>name: <input name="name"> url: <input name="url" value="http://"> <input type="submit"></div>
+ </form>
+ """)
+
+def main():
+ application = webapp.WSGIApplication([('/admin', AdminPage), ('/add', AddPage), ('/del', DelPage), ('/.*', RedirPage)], debug=True)
+ util.run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+ main()

0 comments on commit 4ad633f

Please sign in to comment.