Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 443 lines (387 sloc) 13.16 kB
ddf6382 @visnup we're not proud :(
visnup authored
1 # this entire application is pretty gross, by our own judgement. we'd love to
2 # clean it up, but we'd probably just rewrite the whole thing anyway. you have
3 # been warned.
4
15360a2 @gerad wip
gerad authored
5 sys = require 'sys'
6 connect = require 'connect'
7 express = require 'express'
ac6a3a6 @gerad mongodb
gerad authored
8
15360a2 @gerad wip
gerad authored
9 models = require './models/models'
9e6fa62 @gerad wip create and view votes
gerad authored
10 [Team, Person, Vote] = [models.Team, models.Person, models.Vote]
c6fce2a @gerad resend invitation, confirm delete
gerad authored
11
c593a7c @visnup add coffee to compiler support for static public assets
visnup authored
12 pub = __dirname + '/public'
c67844f @gerad wip
gerad authored
13 app = express.createServer(
c593a7c @visnup add coffee to compiler support for static public assets
visnup authored
14 connect.compiler({ src: pub, enable: ['sass', 'coffee'] }),
c67844f @gerad wip
gerad authored
15 connect.staticProvider(pub)
16 )
b77ee23 @gerad edit person
gerad authored
17
d926e4d @gerad work on teams create
gerad authored
18 app.use connect.logger()
19 app.use connect.bodyDecoder()
0594309 @gerad working method override, order matters. fuck.
gerad authored
20 app.use connect.methodOverride()
d926e4d @gerad work on teams create
gerad authored
21 app.use connect.cookieDecoder()
b977208 @gerad use encrypted password
gerad authored
22
3649ee7 @gerad hoptoad working
gerad authored
23 Hoptoad = require('./lib/hoptoad-notifier/lib/hoptoad-notifier').Hoptoad
24 Hoptoad.key = 'b76b10945d476da44a0eac6bfe1aeabd'
25 process.on 'uncaughtException', (e) ->
26 Hoptoad.notify e
27
d926e4d @gerad work on teams create
gerad authored
28 request = (type) ->
29 (path, fn) ->
3649ee7 @gerad hoptoad working
gerad authored
30 app[type] path, (req, res, next) ->
58550ff @gerad edit person
gerad authored
31 Person.firstByAuthKey req.cookies.authkey, (error, person) =>
a1d957a @gerad close registration
gerad authored
32 ctx = {
33 sys: sys
34 req: req
35 res: res
36 next: next
37 redirect: __bind(res.redirect, res),
38 cookie: (key, value, options) ->
39 value ||= ''
40 options ||= {}
0953dc8 @gerad login with new email address
gerad authored
41 options.path ||= '/'
a1d957a @gerad close registration
gerad authored
42 cookie = "#{key}=#{value}"
43 for k, v of options
44 cookie += "; #{k}=#{v}"
45 res.header('Set-Cookie', cookie)
4b27e0b @visnup send back proper text/javascript content-type for application.js.coffee
visnup authored
46 render: (file, opts, fn) ->
a1d957a @gerad close registration
gerad authored
47 opts ||= {}
48 opts.locals ||= {}
49 opts.locals.view = file.replace(/\..*$/,'').replace(/\//,'-')
50 opts.locals.ctx = ctx
4b27e0b @visnup send back proper text/javascript content-type for application.js.coffee
visnup authored
51 res.render file, opts, fn
a1d957a @gerad close registration
gerad authored
52 currentPerson: person
231f81d @visnup hide votes under an admin check for now
visnup authored
53 isAdmin: person? && person.admin()
c977d34 @gerad open up voting to judges
gerad authored
54 isJudge: person? && person.type is 'Judge'
a1d957a @gerad close registration
gerad authored
55 setCurrentPerson: (person, options) ->
56 @cookie 'authKey', person?.authKey(), options
6d2ab22 @visnup /team goes to a logged in version of your team page
visnup authored
57 redirectToTeam: (person, alternate) ->
a1d957a @gerad close registration
gerad authored
58 Team.first { 'members._id': person._id }, (error, team) =>
59 if team?
44c2784 @visnup missed some toParams
visnup authored
60 @redirect '/teams/' + team.toParam()
6d2ab22 @visnup /team goes to a logged in version of your team page
visnup authored
61 else if alternate
62 alternate()
a54244d @gerad teams/edit
gerad authored
63 else
6d2ab22 @visnup /team goes to a logged in version of your team page
visnup authored
64 @redirect '/'
a1d957a @gerad close registration
gerad authored
65 redirectToLogin: ->
66 @redirect "/login?return_to=#{@req.url}"
67 logout: (fn) ->
10e6bcb @gerad more view helpers, simplified
gerad authored
68 if @currentPerson?
69 @currentPerson.logout (error, resp) =>
70 @setCurrentPerson null
71 fn()
72 else fn()
a1d957a @gerad close registration
gerad authored
73 canEditTeam: (team) ->
74 req.cookies.teamauthkey is team.authKey() or
231f81d @visnup hide votes under an admin check for now
visnup authored
75 team.hasMember(@currentPerson) or @isAdmin
a1d957a @gerad close registration
gerad authored
76 ensurePermitted: (other, fn) ->
6d9953a @gerad wip
gerad authored
77 permitted = @isAdmin
78 if other.hasMember?
79 permitted ||= @canEditTeam(other)
80 else if other.person?
81 permitted ||= (@currentPerson? and other.person.id() is @currentPerson.id())
a1d957a @gerad close registration
gerad authored
82 else
6d9953a @gerad wip
gerad authored
83 permitted ||= (@currentPerson? and other.id() is @currentPerson.id())
84 if permitted then fn()
85 else @redirectToLogin()}
a1d957a @gerad close registration
gerad authored
86 try
87 __bind(fn, ctx)()
88 catch e
89 e.action = e.url = req.url
90 Hoptoad.notify e
91 next e
d926e4d @gerad work on teams create
gerad authored
92 get = request 'get'
93 post = request 'post'
ef2dd99 @gerad wip teams update
gerad authored
94 put = request 'put'
2b2a930 @gerad delete working
gerad authored
95 del = request 'del'
31e8199 @gerad pass through context, view name
gerad authored
96
97 get /.*/, ->
98 [host, path] = [@req.header('host'), @req.url]
15360a2 @gerad wip
gerad authored
99 if host == 'www.nodeknockout.com' or host == 'nodeknockout.heroku.com'
c991680 @gerad more bug fixes
gerad authored
100 @redirect "http://nodeknockout.com#{path}", 301
15360a2 @gerad wip
gerad authored
101 else
31e8199 @gerad pass through context, view name
gerad authored
102 @next()
dadf031 @gerad permissions
gerad authored
103
31e8199 @gerad pass through context, view name
gerad authored
104 get '/', ->
83be906 @gerad move recently deployed to the home page
gerad authored
105 Team.count (error, teamCount) =>
106 Team.all {}, { sort: [['lastDeployedAt', -1]], limit: 10 }, (error, teams) =>
107 @teams = teams
108 @teamCount = teamCount
109 @render 'index.html.haml'
dadf031 @gerad permissions
gerad authored
110
501adfc @gerad /me redirects to edit for the current person (or login if necessary)
gerad authored
111 get '/me', ->
112 if @currentPerson?
44c2784 @visnup missed some toParams
visnup authored
113 @redirect "/people/#{@currentPerson.toParam()}/edit"
501adfc @gerad /me redirects to edit for the current person (or login if necessary)
gerad authored
114 else
115 @redirectToLogin()
116
6d2ab22 @visnup /team goes to a logged in version of your team page
visnup authored
117 get '/team', ->
118 if @currentPerson?
119 @redirectToTeam @currentPerson, __bind(@redirectToLogin, this)
120 else
121 @redirectToLogin()
122
9666788 @gerad /register /teams
gerad authored
123 get '/register', ->
1efc0ea @visnup count teams rather than grabbing them all, on all pages
visnup authored
124 if @currentPerson?
6d2ab22 @visnup /team goes to a logged in version of your team page
visnup authored
125 @redirectToTeam @currentPerson
1efc0ea @visnup count teams rather than grabbing them all, on all pages
visnup authored
126 else
a1d957a @gerad close registration
gerad authored
127 @redirect "/login?return_to=#{@req.url}"
c991680 @gerad more bug fixes
gerad authored
128
b391a93 @gerad try to get hoptoad working
gerad authored
129 get '/error', ->
130 throw new Error('Foo')
131
9666788 @gerad /register /teams
gerad authored
132 # list teams
133 get '/teams', ->
f66293b @visnup sort the teams by last deployed
visnup authored
134 Team.all {}, { 'sort': [['lastDeployedAt', -1]] }, (error, teams) =>
4f5acf0 @visnup vote buttons and filter out unverified now
visnup authored
135 @teams = teams.filter (t) -> t.members.length != t.invited.length
9666788 @gerad /register /teams
gerad authored
136 @yourTeams = if @currentPerson?
137 _.select teams, (team) =>
138 # TODO this is gross
139 _ids = _.pluck(team.members, '_id')
140 _.include _.pluck(_ids, 'id'), @currentPerson._id.id
141 else []
142 @render 'teams/index.html.haml'
c798a63 @gerad teams/new
gerad authored
143
144 # new team
145 get '/teams/new', ->
231f81d @visnup hide votes under an admin check for now
visnup authored
146 return @redirect '/' unless @isAdmin
147
148 @team = new Team {}, =>
149 @render 'teams/new.html.haml'
d926e4d @gerad work on teams create
gerad authored
150
151 # create team
152 post '/teams', ->
231f81d @visnup hide votes under an admin check for now
visnup authored
153 return @redirect '/' unless @isAdmin
154
155 @team = new Team @req.body, =>
156 @team.save (errors, res) =>
157 if errors?
158 @errors = errors
159 @render 'teams/new.html.haml'
160 else
161 @cookie 'teamAuthKey', @team.authKey()
162 @redirect '/teams/' + @team.toParam()
74dd45e @gerad teams/show
gerad authored
163
164 # show team
165 get '/teams/:id', ->
d6e1764 @visnup some vote heuristic stuff
visnup authored
166 @requestAt = Date.now()
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
167 Team.fromParam @req.param('id'), (error, team) =>
1efc0ea @visnup count teams rather than grabbing them all, on all pages
visnup authored
168 if team?
6803d08 @visnup add votes to the team page
visnup authored
169 @team = team
dc5a59f @visnup the easier application description stuff
visnup authored
170 @title = @team.name
6803d08 @visnup add votes to the team page
visnup authored
171 @editAllowed = @canEditTeam team
172
1f84d62 @gerad set @vote to your current vote if you've already voted on a team
gerad authored
173 people = team.members or []
174 @members = _.select people, (person) -> person.name
175 @invites = _.without people, @members...
176
177 renderVotes = =>
178 Vote.all { 'team._id': team._id }, { 'sort': [['createdAt', -1]], limit: 50 }, (error, votes) =>
179 @votes = votes
180 @render 'teams/show.html.haml'
181
182 if @currentPerson
fb836d4 @gerad one vote per person per team
gerad authored
183 Vote.firstByTeamAndPerson team, @currentPerson, (error, vote) =>
cc4a61f @visnup show that we're collecting ip address
visnup authored
184 @vote = vote or new Vote(null, @req)
1f84d62 @gerad set @vote to your current vote if you've already voted on a team
gerad authored
185 @vote.person = @currentPerson
186 @vote.email = @vote.person.email
187 renderVotes()
188 else
cc4a61f @visnup show that we're collecting ip address
visnup authored
189 @vote = new Vote(null, @req)
1f84d62 @gerad set @vote to your current vote if you've already voted on a team
gerad authored
190 renderVotes()
1efc0ea @visnup count teams rather than grabbing them all, on all pages
visnup authored
191 else
192 # TODO make this a 404
193 @redirect '/'
a54244d @gerad teams/edit
gerad authored
194
195 # edit team
196 get '/teams/:id/edit', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
197 Team.fromParam @req.param('id'), (error, team) =>
b3367b7 @visnup no more joyent totalling
visnup authored
198 @ensurePermitted team, =>
199 @team = team
200 @render 'teams/edit.html.haml'
a54244d @gerad teams/edit
gerad authored
201
ef2dd99 @gerad wip teams update
gerad authored
202 # update team
203 put '/teams/:id', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
204 Team.fromParam @req.param('id'), (error, team) =>
ef2dd99 @gerad wip teams update
gerad authored
205 @ensurePermitted team, =>
206 team.update @req.body
207 save = =>
208 team.save (errors, result) =>
209 if errors?
210 @errors = errors
211 @team = team
40a00e2 @gerad 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 wip teams update
gerad authored
216 else
40a00e2 @gerad handle errors in joyent count
gerad authored
217 if @req.xhr
218 @res.send 'OK', 200
219 else
44c2784 @visnup missed some toParams
visnup authored
220 @redirect '/teams/' + team.toParam()
ef2dd99 @gerad 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 delete working
gerad authored
225
226 # delete team
227 del '/teams/:id', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
228 Team.fromParam @req.param('id'), (error, team) =>
2b2a930 @gerad delete working
gerad authored
229 @ensurePermitted team, =>
230 team.remove (error, result) =>
231 @redirect '/'
232
5444ade @gerad reinvite
gerad authored
233 # resend invitation
234 get '/teams/:teamId/invite/:personId', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
235 Team.fromParam @req.param('teamId'), (error, team) =>
5444ade @gerad reinvite
gerad authored
236 @ensurePermitted team, =>
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
237 Person.fromParam @req.param('personId'), (error, person) =>
5444ade @gerad 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 @visnup missed some toParams
visnup authored
243 @redirect '/teams/' + team.toParam()
5444ade @gerad reinvite
gerad authored
244
6d9953a @gerad wip
gerad authored
245 saveVote = ->
246 @vote.save (errors, res) =>
247 if errors?
248 if errors[0] is 'Unauthorized'
249 # TODO flash "You must login to vote as #{@vote.email}."
250 @res.send 'Unauthorized', 403
251 else
252 @res.send JSON.stringify(errors), 400
253 else
254 # TODO flash "You are now logged into Node Knockout as #{@vote.email}."
255 @setCurrentPerson @vote.person if @vote.person? and !@currentPerson?
256 @votes = [@vote]
257 @render 'partials/votes/index.html.jade', { layout: false }
258
9e6fa62 @gerad wip create and view votes
gerad authored
259 # create vote
d5b1eff @visnup 1-5 validation
visnup authored
260 post '/teams/:teamId/votes', ->
b171bdc @gerad actually allow the votes to go through
gerad authored
261 return @redirect '/teams/' + @req.param('teamId') unless @isJudge
231f81d @visnup hide votes under an admin check for now
visnup authored
262
d5b1eff @visnup 1-5 validation
visnup authored
263 Team.fromParam @req.param('teamId'), (error, team) =>
264 # TODO: handle error
e66fac9 @visnup store remote ip, user-agent, etc.
visnup authored
265 @vote = new Vote @req.body, @req
d5b1eff @visnup 1-5 validation
visnup authored
266 @vote.team = @team = team
fb836d4 @gerad one vote per person per team
gerad authored
267 @vote.person = @currentPerson
d6e1764 @visnup some vote heuristic stuff
visnup authored
268 @vote.responseAt = Date.now()
6d9953a @gerad wip
gerad authored
269 saveVote.call(this)
4efad37 @gerad ajax submit the vote form
gerad authored
270
6d9953a @gerad wip
gerad authored
271 put '/teams/:teamId/votes/:voteId', ->
272 Team.fromParam @req.param('teamId'), (error, team) =>
273 Vote.fromParam @req.param('voteId'), (error, vote) =>
274 @ensurePermitted vote, =>
4efad37 @gerad ajax submit the vote form
gerad authored
275 @noHeader = true
6d9953a @gerad wip
gerad authored
276 @vote = vote
75d21b9 @gerad votes actually save
gerad authored
277 vote.update @req.body
6d9953a @gerad wip
gerad authored
278 saveVote.call(this)
9e6fa62 @gerad wip create and view votes
gerad authored
279
09f30a5 @gerad list votes redirects to team page
gerad authored
280 # list votes
281 get '/teams/:teamId/votes', ->
231f81d @visnup hide votes under an admin check for now
visnup authored
282 @redirect '/teams/' + @req.param('teamId')
09f30a5 @gerad list votes redirects to team page
gerad authored
283
d337452 @gerad render the paged results under the index.js route
gerad authored
284 get '/teams/:teamId/votes.js', ->
ce389f2 @visnup route to get a page of votes
visnup authored
285 skip = 50 * ((@req.query['page'] || 1)-1)
286 Team.fromParam @req.param('teamId'), (error, team) =>
287 # TODO: handle error
288 Vote.all { 'team._id': team._id }, { 'sort': [['createdAt', -1]], skip: skip, limit: 50 }, (error, votes) =>
289 @votes = votes
48a1d76 @visnup headers every page of votes
visnup authored
290 @render 'partials/votes/index.html.jade', { layout: false }
9e6fa62 @gerad wip create and view votes
gerad authored
291
19470be @gerad reset password, login page, start on people/edit
gerad authored
292 # sign in
293 get '/login', ->
294 @person = new Person()
295 @render 'login.html.haml'
296
bdefc7a @gerad login
gerad authored
297 post '/login', ->
298 Person.login @req.body, (error, person) =>
299 if person?
300 if @req.param 'remember'
301 d = new Date()
302 d.setTime(d.getTime() + 1000 * 60 * 60 * 24 * 180)
303 options = { expires: d }
304 @setCurrentPerson person, options
305 if person.name
306 if returnTo = @req.param('return_to')
307 @redirect returnTo
308 else @redirectToTeam person
309 else
44c2784 @visnup missed some toParams
visnup authored
310 @redirect '/people/' + person.toParam() + '/edit'
bdefc7a @gerad login
gerad authored
311 else
312 @errors = error
313 @person = new Person(@req.body)
314 @render 'login.html.haml'
19470be @gerad reset password, login page, start on people/edit
gerad authored
315
58550ff @gerad edit person
gerad authored
316 get '/logout', ->
cabd379 @visnup try to go back to where you came from on logout
visnup authored
317 @logout => @redirect(@req.param('return_to') || @req.headers.referer || '/')
58550ff @gerad edit person
gerad authored
318
319 # reset password
320 post '/reset_password', ->
321 Person.first { email: @req.param('email') }, (error, person) =>
322 # TODO assumes xhr
323 unless person?
324 @res.send 'Email not found', 404
325 else
326 person.resetPassword =>
327 @res.send 'OK', 200
328
d7c292f @gerad add judges to the database, and add views creating and editing them, …
gerad authored
329 # new judge
330 get '/judges/new', ->
331 @person = new Person({ type: 'Judge' })
332 @ensurePermitted @person, =>
333 @render 'judges/new.html.haml'
334
9f37814 @visnup pull judges from db
visnup authored
335 get '/judges|/judging', ->
5b1b654 @visnup randomize teams and judges
visnup authored
336 Person.all { type: 'Judge' }, (error, judges) =>
337 @judges = _.shuffle judges
9f37814 @visnup pull judges from db
visnup authored
338 @render 'judges/index.html.jade', { layout: 'layout.haml' }
339
d7c292f @gerad add judges to the database, and add views creating and editing them, …
gerad authored
340 # create person
341 post '/people', ->
342 @person = new Person @req.body
343 @ensurePermitted @person, =>
344 @person.save (error, res) =>
345 # TODO send confirmation email
44c2784 @visnup missed some toParams
visnup authored
346 @redirect '/people/' + @person.toParam() + '/edit'
d7c292f @gerad add judges to the database, and add views creating and editing them, …
gerad authored
347
58550ff @gerad edit person
gerad authored
348 # edit person
349 get '/people/:id/edit', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
350 Person.fromParam @req.param('id'), (error, person) =>
58550ff @gerad edit person
gerad authored
351 @ensurePermitted person, =>
352 @person = person
353 @render 'people/edit.html.haml'
354
355 # update person
356 put '/people/:id', ->
467bcb7 @visnup use fromParam to do finds from param('id') to setup for slugs
visnup authored
357 Person.fromParam @req.param('id'), (error, person) =>
58550ff @gerad edit person
gerad authored
358 @ensurePermitted person, =>
359 attributes = @req.body
360
361 # TODO this shouldn't be necessary
362 person.setPassword attributes.password if attributes.password
363 delete attributes.password
364
365 attributes.link = '' unless /^https?:\/\/.+\./.test attributes.link
bd39104 @gerad store whether the email address is has been confirmed (right now, onl…
gerad authored
366
adae341 @gerad remove gerads@gmail.com from being an admin, fix bug where confirmed …
gerad authored
367 if attributes.email? && attributes.email != person.email
368 person.confirmed = attributes.confimed = false
bd39104 @gerad store whether the email address is has been confirmed (right now, onl…
gerad authored
369
aabaea0 @gerad allow you to set github even if it's not in the hash
gerad authored
370 person.github ||= ''
58550ff @gerad edit person
gerad authored
371 person.update attributes
372 person.save (error, resp) =>
373 @redirectToTeam person
374
c56a3ab @gerad delete person
gerad authored
375 # delete person
376 del '/people/:id', ->
377 Person.fromParam @req.param('id'), (error, person) =>
378 @ensurePermitted person, =>
379 person.remove (error, result) =>
380 @redirect '/'
381
e2abb07 @visnup save head_long too
visnup authored
382 # TODO security
1a904ce @visnup get a debugging deploys post hook out there
visnup authored
383 post '/deploys', ->
f721cbd @visnup working deploy hook for heroku
visnup authored
384 # user: 'visnupx@gmail.com'
385 # head: '87eaeb6'
386 # app: 'visnup-nko'
387 # url: 'http://visnup-nko.heroku.com'
388 # git_log: ''
389 # prev_head: ''
390 # head_long: '87eaeb69d726593de6a47a5f38ff6126fd3920fa'
391 query = {}
392 deployedTo = if /\.no\.de$/.test(@req.param('url')) then 'joyent' else 'heroku'
393 query[deployedTo + 'Slug'] = @req.param('app')
394 Team.first query, (error, team) =>
b37da11 @visnup post receive hook & route for deploys
visnup authored
395 if team
396 team.url = @req.param('url')
397 team.lastDeployedTo = deployedTo
398 team.lastDeployedAt = new Date()
160b9e4 @visnup grab the sha1 of the last commit too
visnup authored
399 team.lastDeployedHead = @req.param('head')
e2abb07 @visnup save head_long too
visnup authored
400 team.lastDeployedHeadLong = @req.param('head_long')
a306866 @gerad save deploys shas
gerad authored
401 team.deployHeads.push team.lastDeployedHeadLong
b37da11 @visnup post receive hook & route for deploys
visnup authored
402 team.save(->)
84e7a7c @visnup say ok on the deploy hook
visnup authored
403 @render 'deploys/ok.html.haml', { layout: false }
1a904ce @visnup get a debugging deploys post hook out there
visnup authored
404
11853b8 @gerad prizes
gerad authored
405 get '/prizes', ->
406 @render 'prizes.html.jade', { layout: 'layout.haml' }
407
75ea889 @visnup try to find a view at the end
visnup authored
408 get '/*', ->
d78ce6c @gerad get rid of debugging information
gerad authored
409 try
410 @render "#{@req.params[0]}.html.haml"
411 catch e
412 throw e if e.errno != 2
413 @next()
75ea889 @visnup try to find a view at the end
visnup authored
414
e311be4 @visnup segregate the teams by verified or not
visnup authored
415 app.helpers {
416 pluralize: (n, str) ->
417 if n == 1
418 n + ' ' + str
419 else
420 n + ' ' + str + 's'
9f37814 @visnup pull judges from db
visnup authored
421
10e6bcb @gerad more view helpers, simplified
gerad authored
422 escapeURL: require('querystring').escape
423 markdown: require('markdown').toHTML
5b1b654 @visnup randomize teams and judges
visnup authored
424
4359404 @visnup replace team members with descriptions
visnup authored
425 firstParagraph: (md) ->
426 require('markdown').toHTML(md).match(/<p>.*?<\/p>/)?[0] || ''
427
5b1b654 @visnup randomize teams and judges
visnup authored
428 gravatar: (p, s) ->
429 "<img src=\"http://www.gravatar.com/avatar/#{p.emailHash}?s=#{s || 40}&d=monsterid\" />"
e311be4 @visnup segregate the teams by verified or not
visnup authored
430 }
431
5b1b654 @visnup randomize teams and judges
visnup authored
432 _.shuffle = (a) ->
433 r = _.clone a
434 for i in [r.length-1 .. 0]
435 j = parseInt(Math.random() * i)
436 [r[i], r[j]] = [r[j], r[i]]
437 r
438
3649ee7 @gerad hoptoad working
gerad authored
439 # has to be last
440 app.use '/', express.errorHandler({ dumpExceptions: true, showStack: true })
b391a93 @gerad try to get hoptoad working
gerad authored
441
ea75a0b @visnup pass the url to hoptoad
visnup authored
442 server = app.listen parseInt(process.env.PORT || 8000), null
Something went wrong with that request. Please try again.