+++ /dev/null
-<html>
-<head>
-<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
-<script type="text/javascript" src="http://www.google.com/jsapi"></script>
-<script>
-google.load("jquery", "1");
-google.load("jqueryui", "1.8.2");
-</script>
-</head>
-<body>
-<form action="/project/edit?orig_name={{p.name}}" method="POST">
-Name:<br/>
-<input type="text" name="name" value="{{p.name|escape}}"><br/>
-Description:<br/>
-<input type="text" name="descr" value="{{p.descr|escape}}"><br/>
-Category:<br/>
-<input type="text" id="cats" name="category" value="{{p.category|escape}}"><br/>
-Tags: (comma-separated)<br/>
-<input type="text" id="tags" name="tags" value="{{tags}}"><br/>
-Web URL:<br/>
-<input type="text" name="web_url" value="{{p.web_url|escape}}"><br/>
-Approved: <input type="checkbox" name="approved" value="1" {% if p.approved %}checked{% endif %}><br/>
-<br/>
-<input type="submit" name="do" value="Save">
-<input type="submit" name="do" value="Delete" onClick="javascript:return confirm('Delete this?');">
-</form>
-<script>
-var tags = [
-{% for t in taglist %}
- "{{t}}"{% if not forloop.last %},{% endif %}
-{% endfor %}
-];
-var cats = [
-{% for c in catlist %}
- "{{c}}"{% if not forloop.last %},{% endif %}
-{% endfor %}
-];
-
-google.setOnLoadCallback(function() {
- $('#tags').autocomplete({source:tags});
- $('#cats').autocomplete({source:cats});
-});
-</script>
-</body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Go Projects</title>
- <link rel="stylesheet" type="text/css" href="static/style.css">
- </head>
-
- <body>
- <ul class="menu"><li><a href="http://golang.org/">golang.org</a></li></ul>
- <h1>Go Projects</h1>
-
- <p>
- These are external projects and not endorsed or supported by the Go project.
- </p>
-
- <h2>Projects</h2>
-
- <div class="submit">
- <h3>Submit a Project</h3>
- <p>
- Using this form you can submit a project to be included in the list.
- </p>
- <form action="/project" method="POST">
- <table>
- <tr><td>Name:<td><input type="text" name="name">
- <tr><td>Description:<td><input type="text" name="descr">
- <tr><td>URL:<td><input type="text" name="web_url">
- <tr><td> <td><input type="submit" value="Send">
- {% if submitMsg %}
- <tr><td class="msg" colspan="2">{{ submitMsg }}</td></tr>
- {% endif %}
- </table>
- </form>
- </div>
-
- <p>
- Filter by tag:
- {% if tag %}
- <a href="/project">all</a>
- {% else %}
- <b>all</b>
- {% endif %}
- {% for t in tags %}
- {% ifequal t tag %}
- <b>{{t}}</b>
- {% else %}
- <a href="?tag={{t}}">{{t}}</a>
- {% endifequal %}
- {% endfor %}
- </p>
-
- {% for r in projects %}
- {% ifchanged r.category %}
- {% if not forloop.first %}
- </ul>
- {% endif %}
- <h3>{{r.category}}</h3>
- <ul>
- {% endifchanged %}
- <li{% if not r.approved %} class="unapproved"{% endif %}>
- {% if admin %}[<a href="/project/edit?name={{r.name}}">edit</a>]{% endif %}
- <a class="name" href="{{r.web_url}}">{{r.name}}</a> - {{r.descr}}
- {% for tag in r.tags %}
- <span class="tag">{{tag}}</span>
- {% endfor %}
- </li>
- {% if forloop.last %}
- </ul>
- {% endif %}
- {% endfor %}
- </ul>
-
- </body>
-</html>
+++ /dev/null
-# Copyright 2010 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-from google.appengine.api import mail
-from google.appengine.api import memcache
-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.ext.webapp.util import run_wsgi_app
-import os
-import sets
-
-# local imports
-import toutf8
-import const
-
-template.register_template_library('toutf8')
-
-class Project(db.Model):
- name = db.StringProperty(indexed=True)
- descr = db.StringProperty()
- web_url = db.StringProperty()
- category = db.StringProperty(indexed=True)
- tags = db.ListProperty(str)
- approved = db.BooleanProperty(indexed=True)
-
-CacheTimeout = 3600
-
-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/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=const.mail_from,
- to=const.mail_submit_to,
- subject=const.mail_submit_subject,
- body=template.render(path, {'project': p}))
-
- self.list({"submitMsg": "Your project has been submitted."})
-
- def list(self, additional_data={}):
- cache_key = 'view-project-data'
- tag = self.request.get('tag', None)
- if tag:
- cache_key += '-'+tag
- data = memcache.get(cache_key)
- admin = users.is_current_user_admin()
- if admin or not data:
- projects = Project.all().order('category').order('name')
- 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)
-
- if tag:
- projects = filter(lambda x: tag in x.tags, projects)
-
- data = {}
- data['tag'] = tag
- data['tags'] = tags
- data['projects'] = projects
- data['admin']= admin
- if not admin:
- memcache.set(cache_key, data, time=CacheTimeout)
-
- for k, v in additional_data.items():
- data[k] = v
-
- self.response.headers['Content-Type'] = 'text/html; charset=utf-8'
- path = os.path.join(os.path.dirname(__file__), 'project.html')
- 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:
- 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()
- memcache.delete('view-project-data')
- 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([
- ('/.*', ProjectPage),
- ], debug=True)
- run_wsgi_app(app)
-
-if __name__ == '__main__':
- main()