forked from OpenUserJS/OpenUserJS.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement OpenUserJS#81 - Sync Script Description from GitHub
* Unfocused md-editors no longer look disabled. * Add new panel in the scriptEditMetadataPage to with inputs to enter the filepath to a markdown file to use as the script description. * Refactored the webhook to wait on saving the script/description before sending an OK response with a list of the models changed (or an error). * Refactored the github import code to also handle importing markdown files. * New Properties: * Script.githubSyncDescription * Script.githubSyncSource * Script.githubSyncUserId * Script.githubSyncRepoName * Script.githubSyncDescriptionPath * Script.githubSyncSourcePath * Automatically fill out githubSyncUserId, githubSyncRepoName, and githubSyncSourcePath when when importing from github (eg: during the webhook). * Disable the Script.about markdown editor when set to sync with github.
- Loading branch information
Showing
17 changed files
with
703 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
var async = require('async'); | ||
var _ = require('underscore'); | ||
|
||
var User = require('../models/user').User; | ||
|
||
var github = require('../libs/githubClient'); | ||
var githubImporter = require('../libs/githubImporter'); | ||
|
||
// GitHub calls this on a push if a webhook is setup | ||
// This controller makes sure we have the latest version of a script | ||
module.exports = function (aReq, aRes, aNext) { | ||
if (!aReq.body.payload) | ||
return aRes.status(400).send('Payload required.'); | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
// Test for know GH webhook ips: https://api.github.com/meta | ||
var reqIP = aReq.headers['x-forwarded-for'] || aReq.connection.remoteAddress; | ||
if (!/192\.30\.25[2-5]\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])$/.test(reqIP)) | ||
return; | ||
} | ||
|
||
|
||
var payload = JSON.parse(aReq.body.payload); | ||
|
||
// Only accept commits to the master branch | ||
if (!payload || payload.ref !== 'refs/heads/master') | ||
return aRes.send(400, 'payload.ref !== refs/heads/master'); | ||
|
||
var githubUserName = payload.repository.owner.name; | ||
var githubRepoName = payload.repository.name; | ||
|
||
|
||
User.findOne({ | ||
ghUsername: githubUserName | ||
}, function (aErr, aUser) { | ||
if (!aUser) | ||
return aRes.status(400).send('No account linked to GitHub username ' + username); | ||
|
||
// Gather the modified user scripts | ||
var jsFilenames = {}; // Set (key == value) | ||
var mdFilenames = {}; // Set (key == value) | ||
payload.commits.forEach(function (aCommit) { | ||
aCommit.modified.forEach(function (aFilename) { | ||
switch (aFilename.substr(-3)) { | ||
case '.js': | ||
jsFilenames[aFilename] = aFilename; | ||
break; | ||
case '.md': | ||
mdFilenames[aFilename] = aFilename; | ||
break; | ||
} | ||
}); | ||
}); | ||
jsFilenames = Object.keys(jsFilenames); | ||
mdFilenames = Object.keys(mdFilenames); | ||
|
||
var githubRepoBlobs = null; | ||
|
||
// Update | ||
async.series([ | ||
// Fetch all blobs in the target repo. | ||
function(aCallback) { | ||
async.waterfall([ | ||
function(aCallback) { | ||
github.gitdata.getBlobs({ | ||
user: encodeURIComponent(githubUserName), | ||
repo: encodeURIComponent(githubRepoName) | ||
}, aCallback); | ||
}, | ||
|
||
function(aBlobs, aCallback) { | ||
githubRepoBlobs = aBlobs; | ||
aCallback(); | ||
}, | ||
], aCallback); | ||
}, | ||
|
||
// Update Javascript File Triggers | ||
function(aCallback) { | ||
async.map(jsFilenames, function(jsFilename, aCallback) { | ||
githubImporter.importJavascriptBlob({ | ||
user: aUser, | ||
githubUserId: githubUserName, | ||
githubRepoName: githubRepoName, | ||
githubBlobPath: jsFilename, | ||
updateOnly: false, | ||
blobs: githubRepoBlobs | ||
}, aCallback); | ||
}, aCallback); | ||
}, | ||
|
||
// Update Markdown File Triggers | ||
function(aCallback) { | ||
async.map(mdFilenames, function(mdFilename, aCallback) { | ||
githubImporter.importMarkdownBlob({ | ||
user: aUser, | ||
githubUserId: githubUserName, | ||
githubRepoName: githubRepoName, | ||
githubBlobPath: mdFilename, | ||
blobs: githubRepoBlobs | ||
}, aCallback); | ||
}, aCallback); | ||
} | ||
], function(aError, aResults) { | ||
if (aError) { | ||
console.error(aError); | ||
return aRes.status(500).send('Error while updating.'); | ||
} | ||
|
||
aRes.status(200).send(aResults); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
var githubImporter = require('../libs/githubImporter'); | ||
var modelParser = require('../libs/modelParser'); | ||
var statusCodePage = require('../libs/templateHelpers').statusCodePage; | ||
|
||
module.exports = function (aReq, aRes, aNext) { | ||
var authedUser = aReq.session.user; | ||
|
||
if (!authedUser) return aRes.redirect('/login'); | ||
|
||
// | ||
var options = {}; | ||
var tasks = []; | ||
|
||
// Session | ||
authedUser = options.authedUser = modelParser.parseUser(authedUser); | ||
options.isMod = authedUser && authedUser.isMod; | ||
options.isAdmin = authedUser && authedUser.isAdmin; | ||
|
||
// GitHub | ||
var githubUserId = options.githubUserId = aReq.body.user || aReq.query.user || authedUser.ghUsername || authedUser.githubUserId(); | ||
var githubRepoName = options.githubRepoName = aReq.body.repo || aReq.query.repo; | ||
var githubBlobPath = options.githubBlobPath = aReq.body.path || aReq.query.path; | ||
|
||
if (!(githubUserId && githubRepoName && githubBlobPath)) { | ||
return statusCodePage(aReq, aRes, aNext, { | ||
statusCode: 400, | ||
statusMessage: 'Bad Request. Require <code>user</code>, <code>repo</code>, and <code>path</code> to be set.' | ||
}); | ||
} | ||
|
||
githubImporter.importJavascriptBlob({ | ||
user: authedUser, | ||
githubUserId: githubUserId, | ||
githubRepoName: githubRepoName, | ||
githubBlobPath: githubBlobPath, | ||
updateOnly: false | ||
}, function (aErr, aData) { | ||
if (aErr) { | ||
console.error(aErr); | ||
console.error(githubUserId, githubRepoName, githubBlobPath); | ||
return statusCodePage(aReq, aRes, aNext, { | ||
statusCode: 400, | ||
statusMessage: aErr | ||
}); | ||
} | ||
|
||
var script = modelParser.parseScript(aData.script); | ||
aRes.redirect(script.scriptPageUrl); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.