diff options
Diffstat (limited to 'misc/dashboard/godashboard/package.py')
-rw-r--r-- | misc/dashboard/godashboard/package.py | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/misc/dashboard/godashboard/package.py b/misc/dashboard/godashboard/package.py index 351a1fadc..6c3bd9995 100644 --- a/misc/dashboard/godashboard/package.py +++ b/misc/dashboard/godashboard/package.py @@ -5,12 +5,18 @@ # This is the server part of the package dashboard. # It must be run by App Engine. +mail_to = "adg@golang.org" +mail_from = "Go Dashboard <adg@golang.org>" +mail_subject = "New Project Submitted" + from google.appengine.api import memcache from google.appengine.runtime import DeadlineExceededError from google.appengine.ext import db from google.appengine.ext import webapp from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app +from google.appengine.api import users +from google.appengine.api import mail import binascii import datetime import hashlib @@ -21,6 +27,7 @@ import re import struct import time import urllib2 +import sets # Storage model for package info recorded on server. # Just path, count, and time of last install. @@ -30,6 +37,15 @@ class Package(db.Model): count = db.IntegerProperty() last_install = db.DateTimeProperty() +class Project(db.Model): + name = db.StringProperty(indexed=True) + descr = db.StringProperty() + web_url = db.StringProperty() + package = db.ReferenceProperty(Package) + category = db.StringProperty(indexed=True) + tags = db.ListProperty(str) + approved = db.BooleanProperty(indexed=True) + re_bitbucket = re.compile(r'^bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$') re_googlecode = re.compile(r'^[a-z0-9\-]+\.googlecode\.com/(svn|hg)$') re_github = re.compile(r'^github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+$') @@ -124,8 +140,118 @@ class PackagePage(webapp.RequestHandler): self.response.set_status(500) self.response.out.write('not ok') +class ProjectPage(webapp.RequestHandler): + + def get(self): + admin = users.is_current_user_admin() + if self.request.path == "/project/login": + self.redirect(users.create_login_url("/project")) + elif self.request.path == "/project/logout": + self.redirect(users.create_logout_url("/project")) + elif self.request.path == "/project/edit" and admin: + self.edit() + else: + self.list() + + def post(self): + if self.request.path == "/project/edit": + self.edit(True) + else: + data = dict(map(lambda x: (x, self.request.get(x)), ["name","descr","web_url"])) + if reduce(lambda x, y: x or not y, data.values(), False): + data["submitMsg"] = "You must complete all the fields." + self.list(data) + return + p = Project.get_by_key_name("proj-"+data["name"]) + if p is not None: + data["submitMsg"] = "A project by this name already exists." + self.list(data) + return + p = Project(key_name="proj-"+data["name"], **data) + p.put() + + path = os.path.join(os.path.dirname(__file__), 'project-notify.txt') + mail.send_mail( + sender=mail_from, to=mail_to, subject=mail_subject, + body=template.render(path, {'project': p})) + + self.list({"submitMsg": "Your project has been submitted."}) + + def list(self, data={}): + projects = Project.all().order('category').order('name') + + admin = users.is_current_user_admin() + if not admin: + projects = projects.filter('approved =', True) + + projects = list(projects) + + tags = sets.Set() + for p in projects: + for t in p.tags: + tags.add(t) + + tag = self.request.get("tag", None) + if tag: + projects = filter(lambda x: tag in x.tags, projects) + + self.response.headers['Content-Type'] = 'text/html; charset=utf-8' + path = os.path.join(os.path.dirname(__file__), 'project.html') + data["tag"] = tag + data["tags"] = tags + data["projects"] = projects + data["admin"] = admin + self.response.out.write(template.render(path, data)) + + def edit(self, save=False): + if save: + name = self.request.get("orig_name") + else: + name = self.request.get("name") + + p = Project.get_by_key_name("proj-"+name) + if not p: + self.response.out.write("Couldn't find that Project.") + return + + if save: + if self.request.get("do") == "Delete": + p.delete() + else: + pkg_name = self.request.get("package", None) + if pkg_name: + pkg = Package.get_by_key_name("pkg-"+pkg_name) + if pkg: + p.package = pkg.key() + for f in ['name', 'descr', 'web_url', 'category']: + setattr(p, f, self.request.get(f, None)) + p.approved = self.request.get("approved") == "1" + p.tags = filter(lambda x: x, self.request.get("tags", "").split(",")) + p.put() + self.redirect("/project") + return + + # get all project categories and tags + cats, tags = sets.Set(), sets.Set() + for r in Project.all(): + cats.add(r.category) + for t in r.tags: + tags.add(t) + + self.response.headers['Content-Type'] = 'text/html; charset=utf-8' + path = os.path.join(os.path.dirname(__file__), 'project-edit.html') + self.response.out.write(template.render(path, { + "taglist": tags, "catlist": cats, "p": p, "tags": ",".join(p.tags) })) + + def redirect(self, url): + self.response.set_status(302) + self.response.headers.add_header("Location", url) + def main(): - app = webapp.WSGIApplication([('/package', PackagePage)], debug=True) + app = webapp.WSGIApplication([ + ('/package', PackagePage), + ('/project.*', ProjectPage), + ], debug=True) run_wsgi_app(app) if __name__ == '__main__': |