mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
started on GithubService
This commit is contained in:
parent
5ded34e668
commit
93c0e8f50b
@ -123,6 +123,7 @@ TODO:
|
||||
- quantify verilog "graph iterations"
|
||||
- toolbar overlaps scope
|
||||
- CPU debugging
|
||||
- use $readmem for inline asm programs?
|
||||
- single-stepping vector games makes screen fade
|
||||
- break on stack overflow, bad op, bad access, etc
|
||||
- PPU/TIA register write visualization
|
||||
@ -132,6 +133,11 @@ TODO:
|
||||
- allow "include graphics.asm" instead of "include project/graphics.asm"
|
||||
- chrome looks blurry on vcs
|
||||
- don't have to include bootstrap-tourist each time?
|
||||
- don't have to include firebase always?
|
||||
- Github
|
||||
- write/read metadata w/ main file
|
||||
- push/pull changes
|
||||
- gh-pages branch with embedded
|
||||
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
66
index.html
66
index.html
@ -20,8 +20,24 @@ body {
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="css/ui.css">
|
||||
|
||||
<!-- google analytics -->
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
ga('create', 'UA-54497476-9', 'auto');
|
||||
ga('set', 'anonymizeIp', true);
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
</script>
|
||||
<script async src='https://www.google-analytics.com/analytics.js'></script>
|
||||
</head>
|
||||
|
||||
<!-- firebase libs -->
|
||||
<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-app.js"></script>
|
||||
<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-auth.js"></script>
|
||||
<script defer src="config.js"></script>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- for file upload -->
|
||||
@ -54,7 +70,7 @@ body {
|
||||
<li><a class="dropdown-item" href="/login.html">Login to GitHub...</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="#" id="item_github_import">Import Project from GitHub...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_github_connect">Publish Project on GitHub...</a></li>
|
||||
<li><a class="dropdown-item" href="#" id="item_github_publish">Publish Project on GitHub...</a></li>
|
||||
<hr>
|
||||
<li><a class="dropdown-item" href="#" id="item_github_push">Push Changes to Repository...</a></li>
|
||||
<hr>
|
||||
@ -234,6 +250,10 @@ body {
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
Please wait...
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-striped active" role="progressbar" id="pleaseWaitProgressBar">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -293,17 +313,29 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="connectGithubModal" class="modal fade">
|
||||
<div id="publishGithubModal" class="modal fade">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Publish Project on GitHub</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>This will migrate your existing files to a GitHub repository.</p>
|
||||
<p><input id="connectGithubURL" size="40" placeholder="Enter a project name"></input></p>
|
||||
<p><button type="button" class="btn btn-primary" id="connectGithubButton">Upload Project</button></p>
|
||||
<p>If the destination repository does not exist, it will be created.</p>
|
||||
<p>This will migrate your existing files to a new GitHub repository.</p>
|
||||
<p><input id="githubRepoName" size="50" placeholder="Enter a project name"></input></p>
|
||||
<p><input id="githubRepoDesc" size="50" placeholder="Enter a project description"></input></p>
|
||||
<p>Your repository will be <select id="githubRepoPrivate">
|
||||
<option value="public">Public</option>
|
||||
<option value="private">Private</option>
|
||||
</select></p>
|
||||
<p>License: <select id="githubRepoLicense">
|
||||
<option value="">Will decide later</option>
|
||||
<option value="cc0-1.0">CC Zero (public domain)</option>
|
||||
<option value="mit">MIT (public domain, must preserve notices)</option>
|
||||
<option value="cc-by-4.0">CC BY (must attribute)</option>
|
||||
<option value="cc-by-sa-4.0">CC BY-SA (must attribute, use same license)</option>
|
||||
<option value="gpl-3.0">GPL v3 (must publish source)</option>
|
||||
</select></p>
|
||||
<p><button type="button" class="btn btn-primary" id="publishGithubButton">Upload Project</button></p>
|
||||
<p>Your existing file will be moved to a new folder in the IDE.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@ -312,6 +344,22 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="pushGithubModal" class="modal fade">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">Push Project Changes to GitHub</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><input id="githubCommitMsg" size="50" placeholder="Enter a commit message"></input></p>
|
||||
<p><button type="button" class="btn btn-primary" id="pushGithubButton">Push Changes</button></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="jquery/jquery-3.4.1.min.js"></script>
|
||||
|
||||
@ -381,6 +429,7 @@ function require(modname) {
|
||||
<script src="gen/recorder.js"></script>
|
||||
<script src="gen/waveform.js"></script>
|
||||
<script src="gen/pixed/pixeleditor.js"></script>
|
||||
<script src="gen/services.js"></script>
|
||||
<script src="gen/ui.js"></script>
|
||||
<!-- <script src="src/audio/votrax.js"></script> -->
|
||||
<!-- <script src="local/lzg.js"></script> -->
|
||||
@ -405,10 +454,5 @@ $( ".dropdown-submenu" ).click(function(event) {
|
||||
*/
|
||||
</script>
|
||||
|
||||
<!-- firebase libs -->
|
||||
<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-app.js"></script>
|
||||
<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-auth.js"></script>
|
||||
<script defer src="config.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -14,6 +14,7 @@
|
||||
"jsdom": "^12.2.0",
|
||||
"lzg": "^1.0.x",
|
||||
"mocha": "^5.2.x",
|
||||
"octokat": "^0.10.0",
|
||||
"pngjs": "^3.3.3",
|
||||
"typescript": "^3.3.3",
|
||||
"wavedrom-cli": "^0.5.x"
|
||||
|
@ -330,9 +330,11 @@ export class CodeProject {
|
||||
}
|
||||
|
||||
stripLocalPath(path : string) : string {
|
||||
var folder = getFolderForPath(this.mainPath);
|
||||
if (folder != '' && path.startsWith(folder)) {
|
||||
path = path.substring(folder.length+1);
|
||||
if (this.mainPath) {
|
||||
var folder = getFolderForPath(this.mainPath);
|
||||
if (folder != '' && path.startsWith(folder)) {
|
||||
path = path.substring(folder.length+1);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
196
src/services.ts
Normal file
196
src/services.ts
Normal file
@ -0,0 +1,196 @@
|
||||
|
||||
import { getFolderForPath, isProbablyBinary, stringToByteArray } from "./util";
|
||||
import { FileData } from "./workertypes";
|
||||
import { CodeProject } from "./project";
|
||||
|
||||
// in index.html
|
||||
declare var exports;
|
||||
declare var firebase;
|
||||
|
||||
interface GHSession {
|
||||
url : string;
|
||||
user : string;
|
||||
reponame : string;
|
||||
repo : any;
|
||||
prefix : string;
|
||||
paths? : string[];
|
||||
}
|
||||
|
||||
export class GithubService {
|
||||
|
||||
github;
|
||||
store;
|
||||
project : CodeProject;
|
||||
branch : string = "master";
|
||||
|
||||
constructor(github, store, project : CodeProject) {
|
||||
this.github = github;
|
||||
this.store = store;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
isFileIgnored(s : string) : boolean {
|
||||
s = s.toUpperCase();
|
||||
if (s.startsWith("LICENSE")) return true;
|
||||
if (s.startsWith("README")) return true;
|
||||
if (s.startsWith(".")) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
parseGithubURL(ghurl:string) {
|
||||
var toks = ghurl.split('/');
|
||||
console.log(toks);
|
||||
if (toks.length < 5) return null;
|
||||
if (toks[0] != 'https:') return null;
|
||||
if (toks[2] != 'github.com') return null;
|
||||
return {user:toks[3], repo:toks[4]};
|
||||
}
|
||||
|
||||
getPrefix(user, reponame) : string {
|
||||
return 'shared/' + user + '-' + reponame + '/';
|
||||
}
|
||||
|
||||
getGithubRepo(ghurl:string) : Promise<GHSession> {
|
||||
return new Promise( (yes,no) => {
|
||||
var urlparse = this.parseGithubURL(ghurl);
|
||||
if (!urlparse) {
|
||||
no("Please enter a valid GitHub URL.");
|
||||
}
|
||||
var sess = {
|
||||
url: ghurl,
|
||||
user: urlparse.user,
|
||||
reponame: urlparse.repo,
|
||||
prefix: this.getPrefix(urlparse.user, urlparse.repo),
|
||||
repo: this.github.repos(urlparse.user, urlparse.repo)
|
||||
};
|
||||
yes(sess);
|
||||
});
|
||||
}
|
||||
|
||||
// bind a folder path to the Github URL in local storage
|
||||
bind(sess : GHSession, dobind : boolean) {
|
||||
var key = '__github_url_' + sess.prefix;
|
||||
// TODO: this doesn't work b/c it binds the entire root to a url
|
||||
if (!key.endsWith('/'))
|
||||
key = key + '/';
|
||||
console.log('bind', key, dobind);
|
||||
if (dobind)
|
||||
localStorage.setItem(key, sess.url);
|
||||
else
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
getBoundURL(path : string) : string {
|
||||
var p = getFolderForPath(path);
|
||||
var key = '__github_url_' + p + '/';
|
||||
console.log(key);
|
||||
return localStorage.getItem(key) as string; // TODO
|
||||
}
|
||||
|
||||
import(ghurl:string) : Promise<GHSession> {
|
||||
var sess : GHSession;
|
||||
return this.getGithubRepo(ghurl).then( (session) => {
|
||||
sess = session;
|
||||
return sess.repo.commits(this.branch).fetch();
|
||||
})
|
||||
.then( (sha) => {
|
||||
return sess.repo.git.trees(sha.sha).fetch();
|
||||
})
|
||||
.then( (tree) => {
|
||||
let blobreads = [];
|
||||
sess.paths = [];
|
||||
tree.tree.forEach( (item) => {
|
||||
console.log(item.path, item.type, item.size);
|
||||
sess.paths.push(item.path);
|
||||
if (item.type == 'blob' && !this.isFileIgnored(item.path)) {
|
||||
var read = sess.repo.git.blobs(item.sha).readBinary().then( (blob) => {
|
||||
var path = sess.prefix + item.path;
|
||||
var size = item.size;
|
||||
var isBinary = isProbablyBinary(blob);
|
||||
var data = isBinary ? stringToByteArray(blob) : blob; //byteArrayToUTF8(blob);
|
||||
return this.store.setItem(path, data);
|
||||
});
|
||||
blobreads.push(read);
|
||||
} else {
|
||||
console.log("ignoring " + item.path);
|
||||
}
|
||||
});
|
||||
return Promise.all(blobreads);
|
||||
})
|
||||
.then( (blobs) => {
|
||||
this.bind(sess, true);
|
||||
return sess;
|
||||
});
|
||||
}
|
||||
|
||||
publish(reponame:string, desc:string, license:string, isprivate:boolean) : Promise<GHSession> {
|
||||
return this.github.user.repos.create({
|
||||
name: reponame,
|
||||
description: desc,
|
||||
private: isprivate,
|
||||
auto_init: true,
|
||||
license_template: license
|
||||
})
|
||||
.then( (repo) => {
|
||||
let sess = {
|
||||
url: repo.htmlUrl,
|
||||
user: repo.owner.login,
|
||||
reponame: reponame,
|
||||
repo: repo,
|
||||
prefix : ''
|
||||
};
|
||||
this.bind(sess, true);
|
||||
return sess;
|
||||
});
|
||||
}
|
||||
|
||||
commitPush( ghurl:string, message:string, files:{path:string,data:FileData}[] ) : Promise<GHSession> {
|
||||
var sess : GHSession;
|
||||
var repo;
|
||||
var head;
|
||||
var tree;
|
||||
return this.getGithubRepo(ghurl).then( (session) => {
|
||||
sess = session;
|
||||
repo = sess.repo;
|
||||
return repo.git.refs.heads(this.branch).fetch();
|
||||
}).then( (_head) => {
|
||||
head = _head;
|
||||
return repo.git.trees(head.object.sha).fetch();
|
||||
}).then( (_tree) => {
|
||||
tree = _tree;
|
||||
return Promise.all(files.map( (file) => {
|
||||
return repo.git.blobs.create({
|
||||
content: file.data,
|
||||
encoding: 'utf-8'
|
||||
});
|
||||
}));
|
||||
}).then( (blobs) => {
|
||||
return repo.git.trees.create({
|
||||
tree: files.map( (file, index) => {
|
||||
return {
|
||||
path: file.path,
|
||||
mode: '100644',
|
||||
type: 'blob',
|
||||
sha: blobs[index]['sha']
|
||||
};
|
||||
}),
|
||||
base_tree: tree.sha
|
||||
});
|
||||
}).then( (tree) => {
|
||||
return repo.git.commits.create({
|
||||
message: message,
|
||||
tree: tree.sha,
|
||||
parents: [
|
||||
head.object.sha
|
||||
]
|
||||
});
|
||||
}).then( (commit) => {
|
||||
return repo.git.refs.heads(this.branch).update({
|
||||
sha: commit.sha
|
||||
});
|
||||
}).then( (update) => {
|
||||
return sess;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -43,6 +43,7 @@ function copyFromVer2xStorageFormat(platformid:string, newstore, callback:(store
|
||||
// no files to convert?
|
||||
if (keys.length == 0) {
|
||||
localStorage.setItem(alreadyMigratedKey, 'true');
|
||||
callback(newstore);
|
||||
return;
|
||||
}
|
||||
// convert function
|
||||
|
173
src/ui.ts
173
src/ui.ts
@ -12,11 +12,12 @@ import { PLATFORMS, EmuHalt, Toolbar } from "./emu";
|
||||
import * as Views from "./views";
|
||||
import { createNewPersistentStore } from "./store";
|
||||
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG,
|
||||
byteArrayToUTF8, isProbablyBinary, getWithBinary, stringToByteArray } from "./util";
|
||||
byteArrayToUTF8, isProbablyBinary, getWithBinary } from "./util";
|
||||
import { StateRecorderImpl } from "./recorder";
|
||||
import { GithubService } from "./services";
|
||||
|
||||
// external libs (TODO)
|
||||
declare var Tour, GIF, saveAs, JSZip, Mousetrap, Split, GitHub;
|
||||
declare var Tour, GIF, saveAs, JSZip, Mousetrap, Split, firebase;
|
||||
// in index.html
|
||||
declare var exports;
|
||||
|
||||
@ -366,84 +367,109 @@ function getCurrentEditorFilename() : string {
|
||||
|
||||
// GITHUB stuff (TODO: move)
|
||||
|
||||
var githubService : GithubService;
|
||||
|
||||
function getCookie(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getGithubService() {
|
||||
if (!githubService) {
|
||||
loadScript("lib/octokat.js", () => {
|
||||
// get github API key from cookie
|
||||
var ghkey = getCookie('__github_key');
|
||||
var ghopts = {token:ghkey};
|
||||
githubService = new GithubService(new exports['Octokat'](ghopts), store, current_project);
|
||||
});
|
||||
}
|
||||
return githubService;
|
||||
}
|
||||
|
||||
function _importProjectFromGithub(e) {
|
||||
var githuburl_ta = $("#importGithubURL");
|
||||
getGithubService(); // load it
|
||||
var modal = $("#importGithubModal");
|
||||
var btn = $("#importGithubButton");
|
||||
modal.modal('show');
|
||||
btn.off('click').on('click', () => {
|
||||
importFromGithub(githuburl_ta.val());
|
||||
});
|
||||
}
|
||||
|
||||
function _connectProjectToGithub(e) {
|
||||
var githuburl_ta = $("#connectGithubURL");
|
||||
var modal = $("#connectGithubModal");
|
||||
var btn = $("#connectGithubButton");
|
||||
modal.modal('show');
|
||||
btn.off('click').on('click', () => {
|
||||
connectToGithub(githuburl_ta.val());
|
||||
});
|
||||
}
|
||||
|
||||
function parseGithubURL(ghurl) {
|
||||
var toks = ghurl.split('/');
|
||||
console.log(toks)
|
||||
if (toks.length < 5) return null;
|
||||
if (toks[0] != 'https:') return null;
|
||||
if (toks[2] != 'github.com') return null;
|
||||
return {user:toks[3], repo:toks[4]};
|
||||
}
|
||||
|
||||
function getGithubRepo(ghurl, callback) {
|
||||
var urlparse = parseGithubURL(ghurl);
|
||||
if (!urlparse) {
|
||||
alert("Please enter a valid GitHub URL.");
|
||||
return;
|
||||
}
|
||||
loadScript("lib/octokat.js", () => {
|
||||
var github = new exports['Octokat']();
|
||||
var prefix = 'shared/' + urlparse.user + '-' + urlparse.repo + '/';
|
||||
var repo = github.repos(urlparse.user, urlparse.repo);
|
||||
callback(github, repo, prefix);
|
||||
});
|
||||
}
|
||||
|
||||
function importFromGithub(ghurl) {
|
||||
getGithubRepo(ghurl, (github, repo, prefix) => {
|
||||
repo.commits('master').fetch().then( (sha) => {
|
||||
repo.git.trees(sha.sha).fetch().then( (tree) => {
|
||||
tree.tree.forEach( (item) => {
|
||||
console.log(item);
|
||||
if (item.type == 'blob') {
|
||||
repo.git.blobs(item.sha).readBinary().then( (blob) => {
|
||||
var path = prefix + item.path;
|
||||
var size = item.size;
|
||||
var isBinary = isProbablyBinary(blob);
|
||||
var data = isBinary ? stringToByteArray(blob) : blob; //byteArrayToUTF8(blob);
|
||||
// TODO projectWindows.updateFile(path, data);
|
||||
store.setItem(path, data);
|
||||
// TODO; wait for set?
|
||||
console.log(path, size, isBinary, typeof blob);
|
||||
// TODO: redirect to main file?
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
var githuburl = $("#importGithubURL").val()+"";
|
||||
getGithubService().import(githuburl).then( (sess) => {
|
||||
// TODO : redirect to main file
|
||||
modal.modal('hide');
|
||||
}).catch( (e) => {
|
||||
modal.modal('hide');
|
||||
alert("Could not import " + githuburl + ": " + e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function connectToGithub(ghurl) {
|
||||
getGithubRepo(ghurl, (github, repo, prefix) => {
|
||||
// TODO
|
||||
function _publishProjectToGithub(e) {
|
||||
getGithubService(); // load it
|
||||
var modal = $("#publishGithubModal");
|
||||
var btn = $("#publishGithubButton");
|
||||
modal.modal('show');
|
||||
btn.off('click').on('click', () => {
|
||||
var name = $("#githubRepoName").val()+"";
|
||||
var desc = $("#githubRepoDesc").val()+"";
|
||||
var priv = $("#githubRepoPrivate").val() == 'private';
|
||||
var license = $("#githubRepoLicense").val()+"";
|
||||
getGithubService().publish(name, desc, license, priv).then( (sess) => {
|
||||
modal.modal('hide');
|
||||
// TODO: commit files
|
||||
// TODO: migrate project files
|
||||
console.log(sess);
|
||||
alert("Created repository at " + sess.url);
|
||||
pushChangesToGithub('initial import from 8bitworkshop.com');
|
||||
}).catch( (e) => {
|
||||
modal.modal('hide');
|
||||
alert("Could not create GitHub repository: " + e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _pushProjectToGithub(e) {
|
||||
getGithubService(); // load it
|
||||
var modal = $("#pushGithubModal");
|
||||
var btn = $("#pushGithubButton");
|
||||
modal.modal('show');
|
||||
btn.off('click').on('click', () => {
|
||||
var commitMsg = $("#githubCommitMsg").val()+"";
|
||||
modal.modal('hide');
|
||||
pushChangesToGithub(commitMsg);
|
||||
});
|
||||
}
|
||||
|
||||
function pushChangesToGithub(message:string) {
|
||||
var ghurl = getGithubService().getBoundURL(current_project.mainPath);
|
||||
console.log("Github URL: " + ghurl);
|
||||
if (!ghurl) {
|
||||
alert("This project is not bound to a GitHub project.");
|
||||
return;
|
||||
}
|
||||
// build file list for push
|
||||
var files = [];
|
||||
for (var path in current_project.filedata) {
|
||||
var newpath = current_project.stripLocalPath(path);
|
||||
files.push({path:newpath, data:current_project.filedata[path]});
|
||||
}
|
||||
// push files
|
||||
setWaitDialog(true);
|
||||
getGithubService().commitPush(ghurl, message, files).then( (sess) => {
|
||||
setWaitDialog(false);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: remove?
|
||||
function loadSharedGist(gistkey : string) {
|
||||
loadScript("lib/octokat.js", () => {
|
||||
var github = new exports['Octokat']();
|
||||
var gist = github.gists(gistkey);
|
||||
var gist = this.github.gists(gistkey);
|
||||
gist.fetch().done( (val) => {
|
||||
var filename;
|
||||
var newid;
|
||||
@ -983,12 +1009,17 @@ function updateDebugWindows() {
|
||||
|
||||
function setWaitDialog(b : boolean) {
|
||||
if (b) {
|
||||
$("#pleaseWaitProgressBar").hide();
|
||||
$("#pleaseWaitModal").modal('show');
|
||||
} else {
|
||||
$("#pleaseWaitModal").modal('hide');
|
||||
}
|
||||
}
|
||||
|
||||
function setWaitProgress(prog : number) {
|
||||
$("#pleaseWaitProgressBar").css('width', (prog*100)+'%').show();
|
||||
}
|
||||
|
||||
var recordingVideo = false;
|
||||
function _recordVideo() {
|
||||
if (recordingVideo) return;
|
||||
@ -1013,7 +1044,10 @@ function _recordVideo() {
|
||||
rotate: rotate
|
||||
});
|
||||
var img = $('#videoPreviewImage');
|
||||
gif.on('finished', function(blob) {
|
||||
gif.on('progress', (prog) => {
|
||||
setWaitProgress(prog);
|
||||
});
|
||||
gif.on('finished', (blob) => {
|
||||
img.attr('src', URL.createObjectURL(blob));
|
||||
setWaitDialog(false);
|
||||
_resume();
|
||||
@ -1198,7 +1232,8 @@ function setupDebugControls() {
|
||||
$("#item_new_file").click(_createNewFile);
|
||||
$("#item_upload_file").click(_uploadNewFile);
|
||||
$("#item_github_import").click(_importProjectFromGithub);
|
||||
$("#item_github_connect").click(_connectProjectToGithub);
|
||||
$("#item_github_publish").click(_publishProjectToGithub);
|
||||
$("#item_github_push").click(_pushProjectToGithub);
|
||||
$("#item_share_file").click(_shareEmbedLink);
|
||||
$("#item_reset_file").click(_revertFile);
|
||||
$("#item_rename_file").click(_renameFile);
|
||||
@ -1455,7 +1490,7 @@ function startPlatform() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function loadScript(scriptfn, onload, onerror?) {
|
||||
export function loadScript(scriptfn, onload, onerror?) {
|
||||
var script = document.createElement('script');
|
||||
script.onload = onload;
|
||||
script.onerror = onerror;
|
||||
@ -1539,7 +1574,7 @@ export function startUI(loadplatform : boolean) {
|
||||
store = createNewPersistentStore(platform_id, (store) => {
|
||||
// is this an importURL?
|
||||
if (qs['githubURL']) {
|
||||
importFromGithub(qs['githubURL']);
|
||||
getGithubService().import(qs['githubURL']);
|
||||
return;
|
||||
}
|
||||
// is this an importURL?
|
||||
|
69
test/cli/testgithub.js
Normal file
69
test/cli/testgithub.js
Normal file
@ -0,0 +1,69 @@
|
||||
"use strict";
|
||||
|
||||
var vm = require('vm');
|
||||
var fs = require('fs');
|
||||
var assert = require('assert');
|
||||
|
||||
var wtu = require('./workertestutils.js'); // loads localStorage
|
||||
global.localforage = require("localForage/dist/localforage.js");
|
||||
var util = require("gen/util.js");
|
||||
var mstore = require("gen/store.js");
|
||||
var prj = require("gen/project.js");
|
||||
var serv = require("gen/services.js");
|
||||
var Octokat = require('octokat');
|
||||
|
||||
var test_platform_id = "_TEST";
|
||||
|
||||
function newGH(store) {
|
||||
// pzpinfo user
|
||||
return new serv.GithubService(new Octokat({token:'ec64fdd81dedab8b7547388eabef09288e9243a9'}), store);
|
||||
}
|
||||
|
||||
describe('Store', function() {
|
||||
|
||||
it('Should import from Github', function(done) {
|
||||
var store = mstore.createNewPersistentStore(test_platform_id, function(store) {
|
||||
var gh = newGH(store);
|
||||
gh.import('https://github.com/sehugg/genemedic/extra/garbage').then( (sess) => {
|
||||
assert.equal(4, sess.paths.length);
|
||||
// TODO: test for presence in local storage, make sure returns keys
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should publish (fail) on Github', function(done) {
|
||||
var store = mstore.createNewPersistentStore(test_platform_id, function(store) {
|
||||
var gh = newGH(store);
|
||||
// should fail
|
||||
gh.publish('testrepo4').catch( (e) => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should commit/push to Github', function(done) {
|
||||
var store = mstore.createNewPersistentStore(test_platform_id, function(store) {
|
||||
var gh = newGH(store);
|
||||
var files = [
|
||||
{path:'text.txt', data:'hello world'}
|
||||
];
|
||||
gh.commitPush('https://github.com/pzpinfo/testrepo3', 'test commit', files).then( (sess) => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should bind paths to Github', function(done) {
|
||||
var store = mstore.createNewPersistentStore(test_platform_id, function(store) {
|
||||
var gh = newGH(store);
|
||||
var sess = {prefix:'prefix', url:'_'};
|
||||
gh.bind(sess, true);
|
||||
assert.equal(gh.getBoundURL('prefix', '_'));
|
||||
gh.bind(sess, false);
|
||||
assert.equal(gh.getBoundURL('prefix', null));
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -4,42 +4,7 @@ var vm = require('vm');
|
||||
var fs = require('fs');
|
||||
var assert = require('assert');
|
||||
|
||||
var localItems = {};
|
||||
var localMods = 0;
|
||||
|
||||
global.localStorage = {
|
||||
clear: function() {
|
||||
localItems = {};
|
||||
localMods = 0;
|
||||
this.length = 0;
|
||||
},
|
||||
getItem: function(k) {
|
||||
console.log('get',k);
|
||||
return localItems[k];
|
||||
},
|
||||
setItem: function(k,v) {
|
||||
console.log('set',k,v);
|
||||
if (!localItems[k]) this.length++;
|
||||
localItems[k] = v;
|
||||
localMods++;
|
||||
},
|
||||
removeItem: function(k) {
|
||||
if (localItems[k]) {
|
||||
this.length--;
|
||||
delete localItems[k];
|
||||
localMods++;
|
||||
}
|
||||
},
|
||||
length: 0,
|
||||
key: function(i) {
|
||||
var keys = [];
|
||||
for (var k in localItems)
|
||||
keys.push(k);
|
||||
console.log(i,keys[i]);
|
||||
return keys[i];
|
||||
}
|
||||
};
|
||||
|
||||
var wtu = require('./workertestutils.js'); // loads localStorage
|
||||
global.localforage = require("localForage/dist/localforage.js");
|
||||
var util = require("gen/util.js");
|
||||
var mstore = require("gen/store.js");
|
||||
@ -83,7 +48,7 @@ describe('Store', function() {
|
||||
project.loadFiles(['local/test','test'], function(err, result) {
|
||||
assert.equal(null, err);
|
||||
assert.deepEqual(["presets/_TEST/test"], remote);
|
||||
assert.deepEqual([ { path: 'local/test', filename: 'test', data: 'a', link:true } ], result);
|
||||
assert.deepEqual([ { path: 'local/test', filename: 'local/test', data: 'a', link:true } ], result);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -69,3 +69,40 @@ includeInThisContext("gen/worker/workermain.js");
|
||||
global.ab2str = function(buf) {
|
||||
return String.fromCharCode.apply(null, new Uint16Array(buf));
|
||||
}
|
||||
|
||||
global.localItems = {};
|
||||
global.localMods = 0;
|
||||
|
||||
global.localStorage = {
|
||||
clear: function() {
|
||||
localItems = {};
|
||||
localMods = 0;
|
||||
this.length = 0;
|
||||
},
|
||||
getItem: function(k) {
|
||||
console.log('get',k);
|
||||
return localItems[k];
|
||||
},
|
||||
setItem: function(k,v) {
|
||||
console.log('set',k,v.length<100?v:v.length);
|
||||
if (!localItems[k]) this.length++;
|
||||
localItems[k] = v;
|
||||
localMods++;
|
||||
},
|
||||
removeItem: function(k) {
|
||||
if (localItems[k]) {
|
||||
this.length--;
|
||||
delete localItems[k];
|
||||
localMods++;
|
||||
}
|
||||
},
|
||||
length: 0,
|
||||
key: function(i) {
|
||||
var keys = [];
|
||||
for (var k in localItems)
|
||||
keys.push(k);
|
||||
console.log(i,keys[i]);
|
||||
return keys[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user