Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit a533f0b82ea7ebd827f65a7b2ce2a1e092faf07d @dustball dustball committed Jan 20, 2012
Showing with 275 additions and 0 deletions.
  1. +13 −0 app.yaml
  2. +11 −0 index.yaml
  3. +108 −0 main.py
  4. BIN static/stripe.png
  5. BIN static/stripe2.png
  6. +62 −0 static/style.css
  7. +60 −0 templates/main.html
  8. +21 −0 templates/thanks.html
@@ -0,0 +1,13 @@
+application: hd-satisfaction
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /favicon\.ico
+ static_files: favicon.ico
+ upload: favicon\.ico
+- url: /static
+ static_dir: static
+- 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.
108 main.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+import hashlib, random
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import util
+from google.appengine.ext.webapp import template
+from google.appengine.ext import db
+from django.utils import simplejson
+from google.appengine.api import users
+from datetime import datetime
+
+METRICS = ["Overall","Cleanliness","Value","Community"]
+GRADES = {'A':100.0,'B':90.0,'C':80.0,'D':70.0,'F':60.0}
+REVSERSE_GRADES = dict((v,k) for k, v in GRADES.iteritems())
+
+class SatisfactionMetric(db.Model):
+ metric = db.StringProperty()
+ grade = db.FloatProperty()
+ who = db.UserProperty()
+ when = db.DateTimeProperty(auto_now=True)
+
+
+class MainHandler(webapp.RequestHandler):
+ def get(self):
+ user = users.get_current_user()
+ if not user:
+ self.redirect(users.create_login_url('/'))
+ else:
+ survey = []
+ for metric in METRICS:
+ survey_item = {}
+ survey_item['metric'] = metric
+ survey_item['grade'] = None
+ existing_metric = None
+ existing_metric_all_months = SatisfactionMetric.all().filter('who =', user).filter('metric =', metric).fetch(500)
+ for m in existing_metric_all_months:
+ if m.when.month == datetime.now().month and m.when.year == datetime.now().year:
+ existing_metric = m
+ if existing_metric:
+ survey_item['grade'] = REVSERSE_GRADES[existing_metric.grade]
+ survey.append(survey_item)
+ grades = sorted(GRADES.keys())
+ self.response.out.write(template.render('templates/main.html', locals()))
+
+ def post(self):
+ user = users.get_current_user()
+ if not user:
+ self.redirect(users.create_login_url('/'))
+ else:
+ for metric in METRICS:
+ try:
+ grade = GRADES[self.request.get(metric)]
+ sm = None
+ existing_metric_all_months = SatisfactionMetric.all().filter('who =', user).filter('metric =', metric).fetch(500)
+ for m in existing_metric_all_months:
+ if m.when.month == datetime.now().month and m.when.year == datetime.now().year:
+ sm = m
+ if not sm:
+ sm = SatisfactionMetric(metric=metric,who=user)
+ sm.grade = grade
+ sm.put()
+ except KeyError, e:
+ existing_metric_all_months = SatisfactionMetric.all().filter('who =', user).filter('metric =', metric).fetch(500)
+ for m in existing_metric_all_months:
+ if m.when.month == datetime.now().month and m.when.year == datetime.now().year:
+ m.delete()
+ self.response.out.write(template.render('templates/thanks.html', locals()))
+
+# Sample Output:
+#
+# [
+# {
+# "grade":90.0,
+# "metric":"General",
+# "who":"96f81e4886",
+# "exact_time":"01-20-2012 00:56:30",
+# "month":"2012-01"
+# },
+
+class AllDataHandler(webapp.RequestHandler):
+ def get(self):
+ seed = str(random.random())
+
+ def to_dict(data):
+ m = hashlib.md5()
+ m.update(data.who.email())
+ m.update(seed)
+
+ return dict(
+ metric=data.metric,
+ grade=data.grade,
+ who=m.hexdigest()[0:10],
+ month=datetime.now().strftime("%Y-%m"),
+ exact_time=datetime.now().strftime("%m-%d-%Y %H:%M:%S"),)
+
+ self.response.out.write(simplejson.dumps([to_dict(data) for data in SatisfactionMetric.all()]))
+
+
+def main():
+ application = webapp.WSGIApplication([
+ ('/', MainHandler),
+ ('/api/all', AllDataHandler),
+ ],debug=True)
+ util.run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+ main()
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,62 @@
+body {
+ background:#A6A6A6 url(stripe2.png) fixed
+}
+body, td {
+ font-family: Verdana, sans-serif;
+ font-size: 15px;
+}
+h1 {
+ font-size:30px;
+ border-bottom:1px solid #ccc;
+}
+h2 {
+ font-size:16px;
+}
+.card {
+ background:white;
+ width:600px;
+ margin:3em auto;
+ padding:18px;
+ border:3px solid #ff7800;
+ -webkit-box-shadow: 4px 4px 32px #666;
+ -webkit-border-radius: 12px;
+ -moz-border-radius: 12px;
+ border-radius: 12px;
+}
+input {
+ text-align:center
+}
+.submit {
+ margin:3em
+}
+.thanks {
+ margin:4em;
+ font-size:18px;
+}
+table.out {
+ margin:3em auto 1em auto;
+}
+
+.survey th,.survey td {
+ padding:7px;
+ border-top:1px solid #ccc;
+ border-left:1px solid #ccc;
+}
+table.survey {
+ border-right:1px solid #ccc;
+ border-bottom:1px solid #ccc;
+}
+div.legend {
+ padding:12px;
+ border: 1px dotted #ccc;
+ margin:0
+}
+
+.legendlabel {
+ margin:0 0 1em 0;
+ border-bottom:1px solid #ddd;
+}
+p.legend {
+ margin:.5em 0;
+ padding-left:1.5em;
+}
@@ -0,0 +1,60 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Member Satisfaction Index</title>
+ <link rel="stylesheet" href="static/style.css">
+</head>
+
+<body>
+
+<div class="card">
+<h1>Member Satisfaction Index</h1>
+<h2>{% now "F Y" %}</h2>
+
+<p>Please grade Hacker Dojo on the following metrics for this month ({% now "F" %}). You may leave an answer "<code>--</code>" if you do not have an opinion. Your answers are anonymous, but data will be made public in aggregate. You may change your grade at any time during the month by coming back to this page.</p>
+
+<form method=POST>
+<table class="out" cellspacing=0 cellpadding=0 border=0 align=center><tr><td>
+<table class="survey" cellspacing=0 cellpadding=0 border=0 align=center>
+<tr>
+<th>Metric</td>
+<th>Grade</th>
+</tr>
+
+{% for survey_item in survey %}
+ <tr>
+
+ <td>{{ survey_item.metric }}</td>
+ <td align=center><select name="{{survey_item.metric}}">
+ <option {% ifequal survey_item.grade None %}selected{% endifequal %}>--</option>
+ {% for grade in grades %}
+ <option {% ifequal survey_item.grade grade %}selected{% endifequal %}>{{grade}}</option>
+ {% endfor %}
+ </select></td>
+
+ </tr>
+
+{% endfor %}
+</table>
+</td>
+<td width=50>&nbsp;</td>
+<td>
+<div class="legend">
+<p class="legendlabel"><b>Legend:</b></p>
+<p class=legend>A - I'm very satisfied.</p>
+<p class=legend>B - I'm mostly satisfied.</p>
+<p class=legend>C - Improvement is needed.</p>
+<p class=legend>D - I'm not satisfied.</p>
+<p class=legend>F - Completely unhappy.</p>
+</div>
+</td></tr></table>
+
+<center><input class="submit" type="submit" value="Save" /></center>
+
+</form>
+</div>
+
+
+</body>
+</html>
@@ -0,0 +1,21 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <title>Member Satisfaction Index</title>
+ <link rel="stylesheet" href="static/style.css">
+</head>
+
+<body>
+
+<div class="card">
+<h1>Member Satisfaction Index</h1>
+<h2>{% now "F Y" %}</h2>
+
+<p class="thanks">Thank you! Please come back next month :)</p>
+
+</div>
+
+
+</body>
+</html>

0 comments on commit a533f0b

Please sign in to comment.