GitHub Issues Exporter
Provides a simple UI for accessing a given users GitHub repository and exporting issues as a spreadsheet.
by jamesdh
HTML
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css">
<div id="wrap">
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container"> <a class="brand" href="#">GitHub Issue Exporter</a>
<div id="userView"
class="pull-right"></div>
<!-- UserView Templates -->
<script type="text/template" id="userlogin_template">
<div class="navbar-form"><input id="username" class="span2" type="text" placeholder="GitHub Username">
<input id="password" class="span2" type="password" placeholder="GitHub Password">
<button id="login" type="submit" class="btn">Go!</button>
</div >
</script>
<script type="text/template" id="loggedin_template">
<div>
<ul class="nav">
<li><a target="_blank" href="<%= html_url %>"><%= name %></a></li>
<li><a id="rate" target="_blank" href="http://developer.github.com/v3/#rate-limiting"></a></li>
</ul>
<button id="logout" type="submit" class="btn">Logout</button>
</div>
</script>
</div>
</div>
</div>
<div class="container">
<div id="errorView"></div>
<!-- ALERT MESSAGE TEMPLATES -->
<script type="text/template" id="error_template">
<div class="alert alert-error">
<button id="alert-close" type="button" class="close" data-dismiss="alert">×</button>
<strong>Error:...
CSS
/* Sticky footer styles
-------------------------------------------------- */
html, body {
height: 100%;
/* The html and body elements cannot have any padding or margin. */
}
/* Wrapper for page content to push down footer */
#wrap {
min-height: 100%;
height: auto !important;
height: 100%;
/* Negative indent footer by it's height */
margin: 0 auto -30px;
}
/* Set the fixed height of the footer here */
#push, #footer {
height: 50px;
}
#footer {
background-color: #eee/*#f5f5f5;*/
}
/* Lastly, apply responsive CSS fixes as necessary */
@media (max-width: 767px) {
#footer {
margin-left: -20px;
margin-right: -20px;
padding-left: 20px;
padding-right: 20px;
}
}
.container .credit {
margin: 15px 0;
text-align: center;
}
JavaScript
var apiRoot = "https://api.github.com"
// ############## MODELS ##############
var User = Backbone.Model.extend({
url: apiRoot + "/user",
initialize: function () {
this.on("change:username change:password", this.authEncode);
this.on("sync", this.extractRateLimit);
},
authEncode: function () {
var that = this;
$.ajaxSetup({
dataType: "jsonp",
beforeSend: function (xhr) {
var b64auth = window.btoa(that.get("username") + ":" + that.get("password"));
xhr.setRequestHeader('Authorization', "Basic " + b64auth);
}
});
},
extractRateLimit: function (model, resp, options) {
var rateLimit = options.xhr.getResponseHeader("X-RateLimit-Remaining");
this.set({rate_limit: rateLimit});
}
});
var Org = Backbone.Model.extend({
});
var Milestone = Backbone.Model.extend({
title: null,
number: null
});
var Repo = Backbone.Model.extend({
name: null
});
var Collaborator = Backbone.Model.extend({
login: null
});
var Label = Backbone.Model.extend({
name: null,
color: null
});
var Issue = Backbone.Model.extend({
html_url: null,
number: null,
title: null,
assignee: null, // User
labels: [], // Labels
milestone: null, // Milestone
createdAt: null, // "2011-04-22T13:33:48Z"
closedAt: null
});
// ############## COLLECTIONS ##############
var Orgs = Backbone.Collection.extend({
model: Org,
url: "/user/orgs"
});
var Milestones = Backbone.Collection.extend({
model: Milestone,
url: "/repos/:owner/:repo/milestones"
});
var Repos = Backbone.Collection.extend({
model: Repo,
url: "/user/repos"
});
var Collaborators = Backbone.Collection.extend({
model: Collaborator,
url: "/repos/:owner/:repo/collaborators"
});
var Labels = Backbone.Collection.extend({
model: Label,
url: "/repos/:owner/:repo/labels" // OR...