yaml config

This commit is contained in:
Radek Stepan 2012-05-23 16:17:39 +01:00
parent 23d0cb4001
commit afec4bd24f
7 changed files with 96 additions and 33 deletions

33
README.md Normal file
View File

@ -0,0 +1,33 @@
Server for connect to GitHub Issues API and displaying a burndown chart for a current milestone.
## Requirements:
You can install all the following dependencies by running:
```bash
npm install -d
```
- [CoffeeScript](http://coffeescript.org/)
- [express](http://expressjs.com/)
- [eco](https://github.com/sstephenson/eco)
- [js-yaml](https://github.com/visionmedia/js-yaml)
## Configure:
The app is configured by pointing to a public GitHub user/project. Do so in `config.yml`:
```yaml
github_user: ̈́'intermine'
github_project: 'InterMine'
project_name: 'Core InterMine Project'
```
## Use:
1. Start a node server using `.webserver.sh`.
2. Visit [http://0.0.0.0:3000/](http://0.0.0.0:3000/)
## Example:
![image](https://raw.github.com/radekstepan/github-burndown-chart/master/example.png)

View File

@ -2,21 +2,41 @@ express = require 'express'
eco = require 'eco'
https = require 'https'
fs = require "fs"
yaml = require "js-yaml"
# Make HTTPS GET to GitHub API v3.
apiGet = (path, type, callback) ->
options =
host: "api.github.com"
method: "GET"
path: path
# Helper object for GitHub Issues.
Issues =
https.request(options, (response) ->
if response.statusCode is 200
json = ""
response.on "data", (chunk) -> json += chunk
response.on "end", -> callback JSON.parse(json), type
).end()
# Make HTTPS GET to GitHub API v3.
get: (path, type, callback) ->
options =
host: "api.github.com"
method: "GET"
path: path
https.request(options, (response) ->
if response.statusCode is 200
json = ""
response.on "data", (chunk) -> json += chunk
response.on "end", -> callback JSON.parse(json), type
).end()
# URLs to API.
getOpenIssues: (callback) -> Issues.get "/repos/#{Issues.config.github_user}/#{Issues.config.github_project}/issues?state=open", 'issues', callback
getClosedIssues: (callback) -> Issues.get "/repos/#{Issues.config.github_user}/#{Issues.config.github_project}/issues?state=closed", 'issues', callback
getMilestones: (callback) -> Issues.get "/repos/#{Issues.config.github_user}/#{Issues.config.github_project}/milestones", 'milestones', callback
# Convert GitHub ISO to JS ISO date and then time
dateToTime: (date) -> new Date(date[0...date.length - 1] + '.000' + date.charAt date.length-1).getTime()
# Format issues for display in a listing.
format: (issue) ->
# Format the timestamps.
if issue.created_at? then issue.created_at = new Date(Issues.dateToTime(issue.created_at)).toUTCString()
if issue.updated_at? then issue.updated_at = new Date(Issues.dateToTime(issue.updated_at)).toUTCString()
issue
# Express.
app = express.createServer()
@ -55,10 +75,7 @@ app.get '/burndown', (req, res) ->
when 'milestones' then store.milestones = store.milestones.concat data
# Are we done?
if resources is 0
# Convert GitHub ISO to JS ISO date and then time
dateToTime = (date) -> new Date(date[0...date.length - 1] + '.000' + date.charAt date.length-1).getTime()
if resources is 0
# Store the current milestone and its size.
current = { 'milestone': {}, 'diff': +Infinity, 'size': 0 }
@ -67,7 +84,7 @@ app.get '/burndown', (req, res) ->
for milestone in store.milestones
due = milestone['due_on']
# JS expects more accuracy.
due = dateToTime due
due = Issues.dateToTime due
# Is this the 'current' one?
diff = due - now
if diff > 0 and diff < current.diff
@ -75,7 +92,7 @@ app.get '/burndown', (req, res) ->
# Create n dict with all dates in the milestone span.
days = {} ; totalDays = 0
day = dateToTime current.milestone.created_at # TODO: shift this to the start of the day and deal with time shifts.
day = Issues.dateToTime current.milestone.created_at # TODO: shift this to the start of the day and deal with time shifts.
while day < current.due
# Save the day.
days[day] = { 'issue': {}, 'actual': 0, 'ideal': 0 }
@ -100,7 +117,7 @@ app.get '/burndown', (req, res) ->
current.size += issue.size
# Is it closed?
if issue.closed_at?
closed = dateToTime issue.closed_at
closed = Issues.dateToTime issue.closed_at
# Find when was it closed (will be made faster)
day = do () ->
for day, x of days
@ -124,22 +141,31 @@ app.get '/burndown', (req, res) ->
# Finally send to client.
res.render 'burndown',
'days': days
'days': days
'project': Issues.config.project_name
, (html) -> res.send html, 'Content-Type': 'text/html', 200
# Get Milestones, Opened and Closed Tickets.
apiGet "/repos/intermine/InterMine/milestones", 'milestones', done
apiGet "/repos/intermine/InterMine/issues?state=open", 'issues', done
apiGet "/repos/intermine/InterMine/issues?state=closed", 'issues', done
Issues.getMilestones done
Issues.getOpenIssues done
Issues.getClosedIssues done
# Show open issues.
app.get '/issues', (req, res) ->
apiGet "/repos/intermine/InterMine/issues?state=open", 'issues', (issues) ->
# Vanilla render.
Issues.getOpenIssues (issues) ->
# Replace the dates in issues with nice dates.
issues = ( Issues.format(issue) for issue in issues )
res.render 'issues',
'issues': issues
'issues': issues
'project': Issues.config.project_name
, (html) -> res.send html, 'Content-Type': 'text/html', 200
app.listen 3000
console.log "Express server listening to port 3000"
# Fetch config and start server.
fs.readFile "config.yml", "utf8", (err, data) ->
Issues.config = yaml.load data
app.listen 3000
console.log "Express server listening to port 3000"

3
config.yml Normal file
View File

@ -0,0 +1,3 @@
github_user: 'intermine'
github_project: 'InterMine'
project_name: 'Core InterMine Project'

BIN
example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

View File

@ -3,7 +3,8 @@
, "version": "0.0.0"
, "private": true
, "dependencies": {
"express": ">= 3.0",
"eco": "latest"
"express": ">= 3.0",
"eco": "latest",
"js-yaml": "latest"
}
}

View File

@ -22,7 +22,7 @@
<li><a><i class="icon-white icon-fire"></i> Burndown App</a></li>
</ul>
<ul class="nav pull-right">
<li><a><i class="icon-white icon-book"></i> Core InterMine Project</a></li>
<li><a><i class="icon-white icon-book"></i> <%= @project %></a></li>
</ul>
</div>
</div>

View File

@ -17,7 +17,7 @@
<li><a><i class="icon-white icon-fire"></i> Burndown App</a></li>
</ul>
<ul class="nav pull-right">
<li><a><i class="icon-white icon-book"></i> Core InterMine Project</a></li>
<li><a><i class="icon-white icon-book"></i> <%= @project %></a></li>
</ul>
</div>
</div>