Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 389 lines (342 sloc) 11.255 kb
15360a2 Gerad Suyderhoud wip
gerad authored
1 sys = require 'sys'
2 connect = require 'connect'
3 express = require 'express'
ac6a3a6 Gerad Suyderhoud mongodb
gerad authored
4
15360a2 Gerad Suyderhoud wip
gerad authored
5 models = require './models/models'
9e6fa62 Gerad Suyderhoud wip create and view votes
gerad authored
6 [Team, Person, Vote] = [models.Team, models.Person, models.Vote]
c6fce2a Gerad Suyderhoud resend invitation, confirm delete
gerad authored
7
c67844f Gerad Suyderhoud wip
gerad authored
8 pub = __dirname + '/public';
9 app = express.createServer(
10 connect.compiler({ src: pub, enable: ['sass'] }),
11 connect.staticProvider(pub)
12 )
b77ee23 Gerad Suyderhoud edit person
gerad authored
13
d926e4d Gerad Suyderhoud work on teams create
gerad authored
14 app.use connect.logger()
15 app.use connect.bodyDecoder()
0594309 Gerad Suyderhoud working method override, order matters. fuck.
gerad authored
16 app.use connect.methodOverride()
d926e4d Gerad Suyderhoud work on teams create
gerad authored
17 app.use connect.cookieDecoder()
b977208 Gerad Suyderhoud use encrypted password
gerad authored
18
3649ee7 Gerad Suyderhoud hoptoad working
gerad authored
19 Hoptoad = require('./lib/hoptoad-notifier/lib/hoptoad-notifier').Hoptoad
20 Hoptoad.key = 'b76b10945d476da44a0eac6bfe1aeabd'
21 process.on 'uncaughtException', (e) ->
22 Hoptoad.notify e
23
d926e4d Gerad Suyderhoud work on teams create
gerad authored
24 request = (type) ->
25 (path, fn) ->
3649ee7 Gerad Suyderhoud hoptoad working
gerad authored
26 app[type] path, (req, res, next) ->
58550ff Gerad Suyderhoud edit person
gerad authored
27 Person.firstByAuthKey req.cookies.authkey, (error, person) =>
a1d957a Gerad Suyderhoud close registration
gerad authored
28 ctx = {
29 sys: sys
30 req: req
31 res: res
32 next: next
33 redirect: __bind(res.redirect, res),
34 cookie: (key, value, options) ->
35 value ||= ''
36 options ||= {}
37 cookie = "#{key}=#{value}"
38 for k, v of options
39 cookie += "; #{k}=#{v}"
40 res.header('Set-Cookie', cookie)
41 render: (file, opts) ->
42 opts ||= {}
43 opts.locals ||= {}
44 opts.locals.view = file.replace(/\..*$/,'').replace(/\//,'-')
45 opts.locals.ctx = ctx
46 res.render file, opts
47 currentPerson: person
48 setCurrentPerson: (person, options) ->
49 @cookie 'authKey', person?.authKey(), options
50 redirectToTeam: (person, alternatePath) ->
51 Team.first { 'members._id': person._id }, (error, team) =>
52 if team?
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
53 @redirect '/teams/' + team.toParam()
a54244d Gerad Suyderhoud teams/edit
gerad authored
54 else
a1d957a Gerad Suyderhoud close registration
gerad authored
55 @redirect (alternatePath or '/')
56 redirectToLogin: ->
57 @redirect "/login?return_to=#{@req.url}"
58 logout: (fn) ->
59 @currentPerson.logout (error, resp) =>
60 @setCurrentPerson null
61 fn()
62 canEditTeam: (team) ->
63 req.cookies.teamauthkey is team.authKey() or
a6a0899 Visnu Pitiyanuvath admins can edit (and delete) teams
visnup authored
64 team.hasMember(@currentPerson) or
65 (@currentPerson? and @currentPerson.admin())
a1d957a Gerad Suyderhoud close registration
gerad authored
66 ensurePermitted: (other, fn) ->
67 permitted = (@currentPerson? and @currentPerson.admin() or
68 other.hasMember? and @canEditTeam(other) or
69 !other.hasMember? and @currentPerson? and other.id() is @currentPerson.id())
70 if permitted then fn()
71 else
72 unless @currentPerson?
73 @redirectToLogin()
74 else
75 # TODO flash "Oops! You don't have permissions to see that. Try logging in as somebody else."
76 @logout =>
77 @redirectToLogin()}
78 try
79 __bind(fn, ctx)()
80 catch e
81 e.action = e.url = req.url
82 Hoptoad.notify e
83 next e
d926e4d Gerad Suyderhoud work on teams create
gerad authored
84 get = request 'get'
85 post = request 'post'
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
86 put = request 'put'
2b2a930 Gerad Suyderhoud delete working
gerad authored
87 del = request 'del'
31e8199 Gerad Suyderhoud pass through context, view name
gerad authored
88
89 get /.*/, ->
90 [host, path] = [@req.header('host'), @req.url]
15360a2 Gerad Suyderhoud wip
gerad authored
91 if host == 'www.nodeknockout.com' or host == 'nodeknockout.heroku.com'
c991680 Gerad Suyderhoud more bug fixes
gerad authored
92 @redirect "http://nodeknockout.com#{path}", 301
15360a2 Gerad Suyderhoud wip
gerad authored
93 else
31e8199 Gerad Suyderhoud pass through context, view name
gerad authored
94 @next()
dadf031 Gerad Suyderhoud permissions
gerad authored
95
31e8199 Gerad Suyderhoud pass through context, view name
gerad authored
96 get '/', ->
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
97 @render 'index.html.haml'
dadf031 Gerad Suyderhoud permissions
gerad authored
98
501adfc Gerad Suyderhoud /me redirects to edit for the current person (or login if necessary)
gerad authored
99 get '/me', ->
100 if @currentPerson?
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
101 @redirect "/people/#{@currentPerson.toParam()}/edit"
501adfc Gerad Suyderhoud /me redirects to edit for the current person (or login if necessary)
gerad authored
102 else
103 @redirectToLogin()
104
31e8199 Gerad Suyderhoud pass through context, view name
gerad authored
105 get '/*.js', ->
69566c4 Gerad Suyderhoud wip application.js.coffee
gerad authored
106 try
c798a63 Gerad Suyderhoud teams/new
gerad authored
107 @render "#{@req.params[0]}.js.coffee", { layout: false }
69566c4 Gerad Suyderhoud wip application.js.coffee
gerad authored
108 catch e
31e8199 Gerad Suyderhoud pass through context, view name
gerad authored
109 @next()
c67844f Gerad Suyderhoud wip
gerad authored
110
9666788 Gerad Suyderhoud /register /teams
gerad authored
111 get '/register', ->
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
112 if @currentPerson?
a1d957a Gerad Suyderhoud close registration
gerad authored
113 @redirectToTeam @currentPerson, '/'
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
114 else
a1d957a Gerad Suyderhoud close registration
gerad authored
115 @redirect "/login?return_to=#{@req.url}"
c991680 Gerad Suyderhoud more bug fixes
gerad authored
116
b391a93 Gerad Suyderhoud try to get hoptoad working
gerad authored
117 get '/error', ->
118 throw new Error('Foo')
119
9666788 Gerad Suyderhoud /register /teams
gerad authored
120 # list teams
121 get '/teams', ->
122 Team.all (error, teams) =>
e311be4 Visnu Pitiyanuvath segregate the teams by verified or not
visnup authored
123 [@teams, @unverifiedTeams] = [[], []]
5b1b654 Visnu Pitiyanuvath randomize teams and judges
visnup authored
124 for team in _.shuffle(teams)
e311be4 Visnu Pitiyanuvath segregate the teams by verified or not
visnup authored
125 if team.members.length == team.invited.length
126 @unverifiedTeams.push team
127 else
128 @teams.push team
9666788 Gerad Suyderhoud /register /teams
gerad authored
129 @yourTeams = if @currentPerson?
130 _.select teams, (team) =>
131 # TODO this is gross
132 _ids = _.pluck(team.members, '_id')
133 _.include _.pluck(_ids, 'id'), @currentPerson._id.id
134 else []
135 @render 'teams/index.html.haml'
c798a63 Gerad Suyderhoud teams/new
gerad authored
136
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
137 get '/teams/attending', ->
138 Team.all (error, teams) =>
139 @joyentTotal = Team.joyentTotal teams
140 @teams = _.select teams, (team) ->
141 parseInt(team.joyent_count) > 0
142 @render 'teams/index.html.haml'
143
c798a63 Gerad Suyderhoud teams/new
gerad authored
144 # new team
145 get '/teams/new', ->
a1d957a Gerad Suyderhoud close registration
gerad authored
146 unless @currentPerson? and @currentPerson.admin()
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
147 @redirect '/'
148 else
149 Team.all (error, teams) =>
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
150 @joyentTotal = Team.joyentTotal teams
c798a63 Gerad Suyderhoud teams/new
gerad authored
151 @team = new Team {}, =>
152 @render 'teams/new.html.haml'
d926e4d Gerad Suyderhoud work on teams create
gerad authored
153
154 # create team
155 post '/teams', ->
a1d957a Gerad Suyderhoud close registration
gerad authored
156 unless @currentPerson? and @currentPerson.admin()
157 @redirect '/'
158 else
159 @req.body.joyent_count = parseInt(@req.body.joyent_count) || 0
160 @team = new Team @req.body, =>
161 @team.save (errors, res) =>
162 if errors?
163 @errors = errors
164 @render 'teams/new.html.haml'
165 else
166 @cookie 'teamAuthKey', @team.authKey()
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
167 @redirect '/teams/' + @team.toParam()
74dd45e Gerad Suyderhoud teams/show
gerad authored
168
169 # show team
170 get '/teams/:id', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
171 Team.fromParam @req.param('id'), (error, team) =>
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
172 if team?
6803d08 Visnu Pitiyanuvath add votes to the team page
visnup authored
173 @team = team
174 @editAllowed = @canEditTeam team
175
ce389f2 Visnu Pitiyanuvath route to get a page of votes
visnup authored
176 Vote.all { 'team._id': team._id }, { 'sort': [['createdAt', -1]], limit: 50 }, (error, votes) =>
6803d08 Visnu Pitiyanuvath add votes to the team page
visnup authored
177 @votes = votes
7c38abc Gerad Suyderhoud wip working on new vote in team show page
gerad authored
178 @vote = new Vote()
179 @vote.person = @currentPerson
180 @vote.email = @vote.person?.email
6803d08 Visnu Pitiyanuvath add votes to the team page
visnup authored
181
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
182 people = team.members or []
183 @members = _.select people, (person) -> person.name
184 @invites = _.without people, @members...
6803d08 Visnu Pitiyanuvath add votes to the team page
visnup authored
185
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
186 @render 'teams/show.html.haml'
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
187 else
188 # TODO make this a 404
189 @redirect '/'
a54244d Gerad Suyderhoud teams/edit
gerad authored
190
191 # edit team
192 get '/teams/:id/edit', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
193 Team.fromParam @req.param('id'), (error, team) =>
1efc0ea Visnu Pitiyanuvath count teams rather than grabbing them all, on all pages
visnup authored
194 Team.all (error, teams) =>
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
195 @ensurePermitted team, =>
196 @joyentTotal = Team.joyentTotal teams
197 @team = team
198 @render 'teams/edit.html.haml'
a54244d Gerad Suyderhoud teams/edit
gerad authored
199
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
200 # update team
201 put '/teams/:id', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
202 Team.fromParam @req.param('id'), (error, team) =>
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
203 @ensurePermitted team, =>
204 team.joyent_count ||= 0
6a1583b Gerad Suyderhoud handle joyent being full
gerad authored
205 @req.body.joyent_count = parseInt(@req.body.joyent_count) || 0
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
206 team.update @req.body
207 save = =>
208 team.save (errors, result) =>
209 if errors?
210 @errors = errors
211 @team = team
40a00e2 Gerad Suyderhoud handle errors in joyent count
gerad authored
212 if @req.xhr
213 @res.send 'ERROR', 500
214 else
215 @render 'teams/edit.html.haml'
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
216 else
40a00e2 Gerad Suyderhoud handle errors in joyent count
gerad authored
217 if @req.xhr
218 @res.send 'OK', 200
219 else
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
220 @redirect '/teams/' + team.toParam()
ef2dd99 Gerad Suyderhoud wip teams update
gerad authored
221 # TODO shouldn't need this
222 if @req.body.emails
223 team.setMembers @req.body.emails, save
224 else save()
2b2a930 Gerad Suyderhoud delete working
gerad authored
225
226 # delete team
227 del '/teams/:id', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
228 Team.fromParam @req.param('id'), (error, team) =>
2b2a930 Gerad Suyderhoud delete working
gerad authored
229 @ensurePermitted team, =>
230 team.remove (error, result) =>
231 @redirect '/'
232
5444ade Gerad Suyderhoud reinvite
gerad authored
233 # resend invitation
234 get '/teams/:teamId/invite/:personId', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
235 Team.fromParam @req.param('teamId'), (error, team) =>
5444ade Gerad Suyderhoud reinvite
gerad authored
236 @ensurePermitted team, =>
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
237 Person.fromParam @req.param('personId'), (error, person) =>
5444ade Gerad Suyderhoud reinvite
gerad authored
238 person.inviteTo team, =>
239 if @req.xhr
240 @res.send 'OK', 200
241 else
242 # TODO flash "Sent a new invitation to $@person.email"
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
243 @redirect '/teams/' + team.toParam()
5444ade Gerad Suyderhoud reinvite
gerad authored
244
9e6fa62 Gerad Suyderhoud wip create and view votes
gerad authored
245 # create vote
d5b1eff Visnu Pitiyanuvath 1-5 validation
visnup authored
246 post '/teams/:teamId/votes', ->
247 Team.fromParam @req.param('teamId'), (error, team) =>
248 # TODO: handle error
249 @vote = new Vote @req.body
250 @vote.team = @team = team
251 @vote.save (errors, res) =>
252 if errors?
253 @errors = errors
254 @email = @vote.email
255 @render 'votes/new.html.jade', { layout: 'layout.haml' }
256 else
ce389f2 Visnu Pitiyanuvath route to get a page of votes
visnup authored
257 @redirect '/teams/' + @team.toParam()
9e6fa62 Gerad Suyderhoud wip create and view votes
gerad authored
258
ce389f2 Visnu Pitiyanuvath route to get a page of votes
visnup authored
259 # list votes
260 get '/teams/:teamId/votes', ->
261 skip = 50 * ((@req.query['page'] || 1)-1)
262 Team.fromParam @req.param('teamId'), (error, team) =>
263 # TODO: handle error
264 Vote.all { 'team._id': team._id }, { 'sort': [['createdAt', -1]], skip: skip, limit: 50 }, (error, votes) =>
265 @votes = votes
48a1d76 Visnu Pitiyanuvath headers every page of votes
visnup authored
266 @render 'partials/votes/index.html.jade', { layout: false }
9e6fa62 Gerad Suyderhoud wip create and view votes
gerad authored
267
19470be Gerad Suyderhoud reset password, login page, start on people/edit
gerad authored
268 # sign in
269 get '/login', ->
270 @person = new Person()
271 @render 'login.html.haml'
272
bdefc7a Gerad Suyderhoud login
gerad authored
273 post '/login', ->
274 Person.login @req.body, (error, person) =>
275 if person?
276 if @req.param 'remember'
277 d = new Date()
278 d.setTime(d.getTime() + 1000 * 60 * 60 * 24 * 180)
279 options = { expires: d }
280 @setCurrentPerson person, options
281 if person.name
282 if returnTo = @req.param('return_to')
283 @redirect returnTo
284 else @redirectToTeam person
285 else
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
286 @redirect '/people/' + person.toParam() + '/edit'
bdefc7a Gerad Suyderhoud login
gerad authored
287 else
288 @errors = error
289 @person = new Person(@req.body)
290 @render 'login.html.haml'
19470be Gerad Suyderhoud reset password, login page, start on people/edit
gerad authored
291
58550ff Gerad Suyderhoud edit person
gerad authored
292 get '/logout', ->
293 @redirect '/' unless @currentPerson?
294 @logout =>
295 @redirect '/'
296
297 # reset password
298 post '/reset_password', ->
299 Person.first { email: @req.param('email') }, (error, person) =>
300 # TODO assumes xhr
301 unless person?
302 @res.send 'Email not found', 404
303 else
304 person.resetPassword =>
305 @res.send 'OK', 200
306
d7c292f Gerad Suyderhoud add judges to the database, and add views creating and editing them, onl...
gerad authored
307 # new judge
308 get '/judges/new', ->
309 @person = new Person({ type: 'Judge' })
310 @ensurePermitted @person, =>
311 @render 'judges/new.html.haml'
312
9f37814 Visnu Pitiyanuvath pull judges from db
visnup authored
313 get '/judges|/judging', ->
5b1b654 Visnu Pitiyanuvath randomize teams and judges
visnup authored
314 Person.all { type: 'Judge' }, (error, judges) =>
315 @judges = _.shuffle judges
9f37814 Visnu Pitiyanuvath pull judges from db
visnup authored
316 @render 'judges/index.html.jade', { layout: 'layout.haml' }
317
d7c292f Gerad Suyderhoud add judges to the database, and add views creating and editing them, onl...
gerad authored
318 # create person
319 post '/people', ->
320 @person = new Person @req.body
321 @ensurePermitted @person, =>
322 @person.save (error, res) =>
323 # TODO send confirmation email
44c2784 Visnu Pitiyanuvath missed some toParams
visnup authored
324 @redirect '/people/' + @person.toParam() + '/edit'
d7c292f Gerad Suyderhoud add judges to the database, and add views creating and editing them, onl...
gerad authored
325
58550ff Gerad Suyderhoud edit person
gerad authored
326 # edit person
327 get '/people/:id/edit', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
328 Person.fromParam @req.param('id'), (error, person) =>
58550ff Gerad Suyderhoud edit person
gerad authored
329 @ensurePermitted person, =>
330 @person = person
331 @render 'people/edit.html.haml'
332
333 # update person
334 put '/people/:id', ->
467bcb7 Visnu Pitiyanuvath use fromParam to do finds from param('id') to setup for slugs
visnup authored
335 Person.fromParam @req.param('id'), (error, person) =>
58550ff Gerad Suyderhoud edit person
gerad authored
336 @ensurePermitted person, =>
337 attributes = @req.body
338
339 # TODO this shouldn't be necessary
340 person.setPassword attributes.password if attributes.password
341 delete attributes.password
342
343 attributes.link = '' unless /^https?:\/\/.+\./.test attributes.link
bd39104 Gerad Suyderhoud store whether the email address is has been confirmed (right now, only a...
gerad authored
344
adae341 Gerad Suyderhoud remove gerads@gmail.com from being an admin, fix bug where confirmed was...
gerad authored
345 if attributes.email? && attributes.email != person.email
346 person.confirmed = attributes.confimed = false
bd39104 Gerad Suyderhoud store whether the email address is has been confirmed (right now, only a...
gerad authored
347
aabaea0 Gerad Suyderhoud allow you to set github even if it's not in the hash
gerad authored
348 person.github ||= ''
58550ff Gerad Suyderhoud edit person
gerad authored
349 person.update attributes
350 person.save (error, resp) =>
351 @redirectToTeam person
352
11853b8 Gerad Suyderhoud prizes
gerad authored
353 get '/prizes', ->
354 @render 'prizes.html.jade', { layout: 'layout.haml' }
355
75ea889 Visnu Pitiyanuvath try to find a view at the end
visnup authored
356 get '/*', ->
d78ce6c Gerad Suyderhoud get rid of debugging information
gerad authored
357 try
358 @render "#{@req.params[0]}.html.haml"
359 catch e
360 throw e if e.errno != 2
361 @next()
75ea889 Visnu Pitiyanuvath try to find a view at the end
visnup authored
362
9f37814 Visnu Pitiyanuvath pull judges from db
visnup authored
363 markdown = require 'markdown'
e311be4 Visnu Pitiyanuvath segregate the teams by verified or not
visnup authored
364 app.helpers {
365 pluralize: (n, str) ->
366 if n == 1
367 n + ' ' + str
368 else
369 n + ' ' + str + 's'
9f37814 Visnu Pitiyanuvath pull judges from db
visnup authored
370
371 markdown: (s) ->
372 markdown.toHTML s
5b1b654 Visnu Pitiyanuvath randomize teams and judges
visnup authored
373
374 gravatar: (p, s) ->
375 "<img src=\"http://www.gravatar.com/avatar/#{p.emailHash}?s=#{s || 40}&d=monsterid\" />"
e311be4 Visnu Pitiyanuvath segregate the teams by verified or not
visnup authored
376 }
377
5b1b654 Visnu Pitiyanuvath randomize teams and judges
visnup authored
378 _.shuffle = (a) ->
379 r = _.clone a
380 for i in [r.length-1 .. 0]
381 j = parseInt(Math.random() * i)
382 [r[i], r[j]] = [r[j], r[i]]
383 r
384
3649ee7 Gerad Suyderhoud hoptoad working
gerad authored
385 # has to be last
386 app.use '/', express.errorHandler({ dumpExceptions: true, showStack: true })
b391a93 Gerad Suyderhoud try to get hoptoad working
gerad authored
387
ea75a0b Visnu Pitiyanuvath pass the url to hoptoad
visnup authored
388 server = app.listen parseInt(process.env.PORT || 8000), null
Something went wrong with that request. Please try again.