Permalink
Browse files

Merge branch 'release/20120419164457'

  • Loading branch information...
2 parents de62f91 + 7c1e1d8 commit b3a7a406aa611814b4a100fe37aed8e39df1bc9e @cybertoast cybertoast committed Apr 19, 2012
Showing with 2,733 additions and 142 deletions.
  1. +106 −1 controllers/admin.py
  2. +60 −0 controllers/calendar.py
  3. +16 −0 controllers/home.py
  4. +8 −5 controllers/join.py
  5. +30 −27 controllers/project.py
  6. +2 −1 controllers/rest.py
  7. +3 −2 controllers/search.py
  8. +8 −1 etc/config.yaml.tmpl
  9. +9 −0 etc/cron_table.tmpl
  10. +28 −0 etc/logrotate.d/lp-changebyus.tmpl
  11. +54 −0 etc/nginx/nginx.conf.tmpl
  12. +16 −0 etc/supervisor/supervisor.conf.tmpl
  13. +19 −12 fabfile.py
  14. +2 −2 framework/controller.py
  15. +1 −1 framework/emailer.py
  16. +5 −1 framework/log.py
  17. +1 −1 framework/orm_holder.py
  18. +36 −1 framework/util.py
  19. +17 −21 giveaminute/location.py
  20. +26 −16 giveaminute/project.py
  21. +10 −8 giveaminute/user.py
  22. +6 −5 main.py
  23. +4 −1 rcfile.sample
  24. +1,353 −0 scripts/daemonwatch.py
  25. +4 −12 scripts/digest_emailer.py
  26. +38 −0 scripts/monitor.py
  27. +1 −0 sql/migrations/0006_add_redirect_link_to_unauthenticated_user_table.sql
  28. +10 −0 sql/migrations/0007_create_homepage_question.sql
  29. +2 −0 sql/migrations/0008_add_is_project_creator.sql
  30. +19 −0 sql/models.sql
  31. +256 −4 static/css/tc.gam.admin.css
  32. +29 −0 static/css/tc.gam.main.css
  33. BIN static/images/control_manage_questions_star.png
  34. BIN static/images/footer-planyc.png
  35. +224 −0 static/js/pages/cms.questions.js
  36. +7 −3 static/js/pages/join.js
  37. +12 −5 static/js/pages/project.js
  38. +20 −0 static/js/pages/project.members.js
  39. +102 −0 templates/calendar.html
  40. +141 −0 templates/cms_homepage_questions.html
  41. +0 −7 templates/email/digest.html
  42. +1 −1 templates/home.html
  43. +1 −0 templates/join.html
  44. +5 −1 templates/partials/base.html
  45. +6 −1 templates/project/conversation_message.html
  46. +13 −1 templates/project/member_list.html
  47. +19 −1 templates/project/mission.html
  48. +3 −0 wsgi.py
View
@@ -27,6 +27,8 @@ def GET(self, action = None, param0 = None, param1 = None):
return self.showContent()
elif (action == 'users'):
return self.getAdminUsers()
+ elif (action == 'questions'):
+ return self.showHomepageQuestions()
elif (action == 'all'):
if (param0 == 'getflagged'):
if (param1 == 'counts'):
@@ -156,6 +158,17 @@ def POST(self, action = None, param0 = None, param1 = None):
return self.approveProjectResource()
else:
return self.not_found()
+ elif (action == 'questions'):
+ if (param0 == 'add'):
+ return self.addHomepageQuestion()
+ elif (param0 == 'delete'):
+ return self.deleteHomepageQuestion()
+ elif (param0 == 'feature'):
+ return self.featureHomepageQuestion()
+ elif (param0 == 'edit'):
+ return self.updateHomepageQuestion()
+ else:
+ return self.not_found()
else:
return self.not_found()
@@ -178,6 +191,14 @@ def showContent(self):
self.template_data['featured_projects'] = dict(data = featuredProjects, json = json.dumps(featuredProjects))
return self.render('cms_content')
+
+ def showHomepageQuestions(self):
+ questions = self.getHomepageQuestions()
+
+ self.template_data['questions'] = {'data': questions,
+ 'json': json.dumps(questions)}
+
+ return self.render('cms_homepage_questions')
def deleteProject(self):
projectId = self.request('project_id')
@@ -336,7 +357,92 @@ def getFlaggedItemCounts(self):
log.error(e)
return self.json(obj)
+
+ # BEGIN homepage question methods
+ def getHomepageQuestions(self):
+ data = []
+
+ sql = """select homepage_question_id,
+ question,
+ is_featured
+ from homepage_question
+ where is_active = 1"""
+
+ try:
+ data = list(self.db.query(sql))
+ except Exception, e:
+ log.info("*** couldn't get homepage questions")
+ log.error(e)
+
+ return data
+
+ def addHomepageQuestion(self):
+ q = self.request('question')
+
+ if (util.strNullOrEmpty(q)):
+ log.error("*** attempt to add question with no question content")
+ return False
+ else:
+ try:
+ self.db.insert('homepage_question', question = q, created_datetime = None)
+ return True
+ except Exception, e:
+ log.info("*** error inserting new question")
+ log.error(e)
+ return False
+
+ def deleteHomepageQuestion(self):
+ id = self.request('question_id')
+
+ log.debug("*** deleting homepage question %s" % id)
+ try:
+ self.db.update('homepage_question',
+ where = "homepage_question_id = $id",
+ is_active = 0,
+ vars = {'id': id})
+ return True
+ except Exception, e:
+ log.info("*** there was a problem deleting homepage question id = %s" % id)
+ log.error(e)
+
+ return False
+
+ def updateHomepageQuestion(self):
+ id = self.request('question_id')
+ q = self.request('question')
+
+ try:
+ self.db.update('homepage_question',
+ where = "homepage_question_id = $id",
+ question = q,
+ vars = {'id': id})
+ return True
+ except Exception, e:
+ log.info("*** there was a problem updating homepage question id = %s" % id)
+ log.error(e)
+
+ return False
+
+ def featureHomepageQuestion(self):
+ id = self.request('question_id')
+
+ try:
+ self.db.update('homepage_question',
+ where = "is_featured = 1",
+ is_featured = 0)
+ self.db.update('homepage_question',
+ where = "homepage_question_id = $id",
+ is_featured = 1,
+ vars = {'id': id})
+ return True
+ except Exception, e:
+ log.info("*** there was a problem featuring homepage question id = %s" % id)
+ log.error(e)
+
+ return False
+
+ # END homepage question methods
def getUnreviewedResources(self):
limit = util.try_f(int, self.request('n_limit'), 10)
@@ -599,4 +705,3 @@ def getBadwords(self):
log.error(e)
return words
-
View
@@ -0,0 +1,60 @@
+"""
+ :copyright: (c) 2011 Local Projects, all rights reserved
+ :license: Affero GNU GPL v3, see LICENSE for more details.
+"""
+
+from datetime import datetime, timedelta
+from framework.controller import *
+from framework.config import Config
+from sqlalchemy import and_
+
+class Calendar(Controller):
+ def GET(self, action=None, param0=None, param1=None, param2=None):
+ if (Config.get('features').get('is_calendar_enabled')):
+ if (action == 'show'):
+ return self.showCalendar(param0, param1)
+ elif (action == 'get'):
+ return self.getCalendar(param0, param1)
+ else:
+ return self.not_found()
+ else:
+ return self.not_found()
+
+ def showCalendar(self, unit, start):
+ if (not unit or not start):
+ unit = 'monthly'
+ d = datetime.now()
+ start = d.strftime('%Y-%m')
+
+ return self.redirect("/calendar/show/%(unit)s/%(start)s" % {'unit': 'monthly',
+ 'start': start})
+ elif (unit == 'monthly'):
+ d = datetime.strptime(start, '%Y-%m')
+ end = (d + timedelta(days = 32)).strftime('%Y-%m')
+
+ self.template_data['calendar'] = {}
+ self.template_data['calendar']['events'] = self.getEvents(start, end)
+ self.template_data['calendar']['next_month'] = end
+ self.template_data['calendar']['prev_month'] = (d + timedelta(days = -1)).strftime('%Y-%m')
+ self.template_data['calendar']['is_active_month'] = self.isActiveMonth(d)
+
+ return self.render('calendar')
+ else:
+ return self.not_found()
+
+ def getCalendar(self, unit, start):
+ if (unit == 'monthly'):
+ return start
+ else:
+ return self.not_found()
+
+
+ def getEvents(self, start, end):
+ events = self.orm.query(models.Event).filter(and_(models.Event.start_datetime > start,
+ models.Event.start_datetime < end))
+ return events
+
+ def isActiveMonth(self, d):
+ now = datetime.now()
+
+ return (d.year >= now.year and d.month >= now.month)
View
@@ -34,6 +34,7 @@ def GET(self, action=None, param0=None):
project_user = dict(is_member = True,
is_project_admin = True)
self.template_data['project_user'] = dict(data = project_user, json = json.dumps(project_user))
+ self.template_data['homepage_question'] = self.getHomepageQuestion()
if (not action or action == 'home'):
return self.showHome()
@@ -515,6 +516,21 @@ def getNewsItems(self):
log.error(e)
return data
+
+ def getHomepageQuestion(self):
+ q = None
+
+ if (Config.get('homepage').get('is_question_from_cms')):
+ sql = "select question from homepage_question where is_active = 1 and is_featured = 1"
+ data = list(self.db.query(sql))
+
+ if (len(data) == 1):
+ q = data[0].question
+
+ if (not q):
+ q = Config.get('homepage').get('question')
+
+ return q
def submitFeedback(self):
name = self.request('name')
View
@@ -121,8 +121,8 @@ def newUser(self):
def authenticateUser(self, authGuid):
# kill existing session
# self.session.kill()
-
- userId = mUser.createUserFromAuthGuid(self.db, authGuid)
+
+ userId, redirectLink = mUser.createUserFromAuthGuid(self.db, authGuid)
isSuccess = False
if (userId):
@@ -140,7 +140,9 @@ def authenticateUser(self, authGuid):
if (user.phone and len(user.phone) > 0):
mIdea.attachIdeasByPhone(self.db, user.phone)
- return self.render('join', {'is_email_auth_attempt':True, 'is_email_auth_attempt_successful': isSuccess})
+ return self.render('join', { 'is_email_auth_attempt':True,
+ 'is_email_auth_attempt_successful': isSuccess,
+ 'post_auth_redirect_link': redirectLink })
def newUnauthenticatedUser(self):
if (self.request('main_text')): return False
@@ -150,7 +152,8 @@ def newUnauthenticatedUser(self):
email = self.request('email')
password = self.request('password')
phone = util.cleanUSPhone(self.request('sms_phone'))
- code = self.request('beta_code')
+ code = self.request('beta_code')
+ redirectLink = self.request('redirect_link')
if (self.appMode == 'beta' and not self.verifyBetaCode(code)):
log.error("*** beta user attempted register w/ invalid code")
@@ -171,7 +174,7 @@ def newUnauthenticatedUser(self):
#create unauth data record and email user
authGuid = uuid.uuid4()
- if (mUser.createUnauthenticatedUser(self.db, authGuid, email, password, firstName, lastName, phone)):
+ if (mUser.createUnauthenticatedUser(self.db, authGuid, email, password, firstName, lastName, phone, redirectLink=redirectLink)):
return mMessaging.emailUnauthenticatedUser(email, authGuid)
else:
return False
View
@@ -16,7 +16,7 @@
import datetime
class Project(Controller):
- def GET(self, action=None, param0=None):
+ def GET(self, action=None, param0=None, param1=None):
if (action == 'resource'):
if (param0 == 'info'):
return self.getResourceInfo()
@@ -38,7 +38,7 @@ def GET(self, action=None, param0=None):
else:
return self.showProject(action)
- def POST(self, action=None, param0=None):
+ def POST(self, action=None, param0=None, param1=None):
if (action == 'join'):
return self.join()
elif (action == 'endorse'):
@@ -81,6 +81,13 @@ def POST(self, action=None, param0=None):
elif (action == 'user'):
if (param0 == 'remove'):
return self.removeUser()
+ elif (param0 == 'admin'):
+ if (param1 == 'add'):
+ return self.setAdmin(True)
+ elif (param1 == 'remove'):
+ return self.setAdmin(False)
+ else:
+ return self.not_found()
else:
return self.not_found()
elif (action == 'photo'):
@@ -173,41 +180,20 @@ def getProjectUser(self, projectId):
def join(self):
projectId = self.request('project_id')
- description = self.request('message')
if (not self.user):
log.error("*** join submitted w/o logged in user")
return False
elif (not projectId):
log.error("*** join submitted w/o logged project id")
return False
- elif (util.strNullOrEmpty(description)):
- log.error("*** join submitted w/o idea")
- return False
+
else:
isJoined = mProject.join(self.db, projectId, self.user.id)
if (isJoined):
project = mProject.Project(self.db, projectId)
-
- # create the user's "hello there" idea and add to project
- newIdeaId = mIdea.createIdea(self.db,
- description,
- project.data.location_id,
- 'web',
- self.user.id,
- self.user.email)
-
- if (newIdeaId):
- if (not mIdea.addIdeaToProject(self.db, newIdeaId, projectId)):
- log.error("*** new idea not created for user %s on joining project %s" % (self.user.id, projectId))
- else:
- log.error("*** new idea not created for user %s on joining project %s" % (self.user.id, projectId))
-
- # automatically insert any ideas attached to invites for this user and this project
- if (not mIdea.addInvitedIdeaToProject(self.db, projectId, self.user.id)):
- log.error("*** couldn't add invited idea to project for user %s on joining project %s" % (self.user.id, projectId))
-
+
# add a message to the queue about the join
message = 'New Member! Your project now has %s total!' % project.data.num_members
@@ -226,8 +212,7 @@ def join(self):
projectId,
message,
'join',
- self.user.id,
- newIdeaId)):
+ self.user.id)):
log.error("*** new message not created for user %s on joining project %s" % (self.user.id, projectId))
return isJoined
@@ -530,3 +515,21 @@ def updateTitle(self):
self.orm.commit()
return True
+
+ def setAdmin(self, b):
+ projectId = self.request('project_id')
+ userId = self.request('user_id')
+
+ projectUser = self.orm.query(models.ProjectMember).get((userId, projectId))
+
+ # TODO prevent last admin from being deleted
+ # TODO on delete of creator, make oldest admin creator
+
+ if projectUser:
+ projectUser.is_project_admin = b
+ self.orm.commit()
+
+ return True
+ else:
+ return False
+
View
@@ -427,7 +427,8 @@ def instance_to_dict(self, row):
for columnName in row.__mapper__.columns.keys():
d[columnName] = getattr(row, columnName)
try:
- if str(row.__mapper__.columns.get('name').type).startswith('VARCHAR'):
+ col = row.__mapper__.columns.get('name')
+ if col and str(col.type).startswith('VARCHAR'):
d[columnName] = jinja2.Markup(d[columnName]).unescape()
except Exception, e:
log.debug("Exception decoding field %s: %s" % (columnName, e))
Oops, something went wrong.

0 comments on commit b3a7a40

Please sign in to comment.