Remove localhost link
This commit is contained in:
parent
d43f2c341c
commit
fb848a9f81
@ -1 +1 @@
|
||||
CACHE MANIFEST
# v33
CACHE:
index.html
css/bootstrap.css
css/jgrowl.css
css/main.css
js/async-runner.js
js/bootstrap.js
js/config.js
js/custo.github.js
js/dropbox.js
js/gdrive.js
js/jgrowl.js
js/jquery.js
js/jquery-ui.js
js/layout.js
js/main.js
js/Markdown.Converter.js
js/Markdown.Editor.js
js/Markdown.Sanitizer.js
js/require.js
js/synchronizer.js
img/ajax-loader.gif
.js
js/jquery.js
.js
js/jquery-ui.js
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/stackedit-16.png
img/stackedit-32.ico
NETWORK:
*
|
||||
CACHE MANIFEST
# v33
CACHE:
index.html
css/bootstrap.css
css/jgrowl.css
css/main.css
js/async-runner.js
js/bootstrap.js
js/config.js
js/custo.github.js
js/dropbox-helper.js
js/gdrive.js
.js
js/gdrive.js
js/gdrive.js
js/jgrowl.js
js/jquery.js
js/jquery-ui.js
js/layout.js
js/main.js
js/Markdown.Converter.js
js/Markdown.Editor.js
js/Markdown.Sanitizer.js
js/publisher.js
js/require.js
js/synchronizer.js
js/gdrive.js
js/jquery.js
.js
js/jgrowl.js
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
||||
|
45
css/main.css
45
css/main.css
@ -225,18 +225,53 @@ hr {
|
||||
background-position: -456px -168px;
|
||||
}
|
||||
|
||||
.icon-gdrive {
|
||||
background-image: url("../img/gdrive.png") !important;
|
||||
.icon-stackedit {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: 0 0;
|
||||
background-position: -1px 0;
|
||||
}
|
||||
|
||||
.icon-gdrive {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -19px 0;
|
||||
}
|
||||
|
||||
.icon-dropbox {
|
||||
background-image: url("../img/dropbox.png") !important;
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: 0 0;
|
||||
background-position: -37px 0;
|
||||
}
|
||||
|
||||
.icon-github {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -55px 0;
|
||||
}
|
||||
|
||||
.icon-blogger {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -73px 0;
|
||||
}
|
||||
|
||||
.icon-tumblr {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -91px 0;
|
||||
}
|
||||
|
||||
.icon-wordpress {
|
||||
background-image: url("../img/icons.png") !important;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-position: -109px 0;
|
||||
}
|
||||
|
||||
.icon-spinner {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="js/dropbox.min.js"></script>
|
||||
<script src="lib/dropbox.js"></script>
|
||||
<script type="text/javascript">
|
||||
Dropbox.Drivers.Popup.oauthReceiver();
|
||||
</script>
|
||||
|
BIN
img/dropbox.png
BIN
img/dropbox.png
Binary file not shown.
Before Width: | Height: | Size: 854 B |
BIN
img/gdrive.png
BIN
img/gdrive.png
Binary file not shown.
Before Width: | Height: | Size: 741 B |
BIN
img/icons.png
Normal file
BIN
img/icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
75
index.html
75
index.html
@ -23,7 +23,10 @@
|
||||
<li class="btn-group"><button class="btn action-force-sync"
|
||||
title="Synchronize">
|
||||
<i class="icon-refresh"></i>
|
||||
</button></li>
|
||||
</button><button class="btn action-publish"
|
||||
title="Publish">
|
||||
<i class="icon-share"></i>
|
||||
</button></li>
|
||||
<li class="btn-group"><button class="btn action-create-file"
|
||||
title="New local document">
|
||||
<i class="icon-file"></i>
|
||||
@ -39,8 +42,8 @@
|
||||
<ul id="file-selector" class="dropdown-menu">
|
||||
</ul></li>
|
||||
<li class="btn-group"><a class="btn dropdown-toggle"
|
||||
data-toggle="dropdown" href="#" title="Menu"><img
|
||||
src="img/stackedit-16.png" /> <b class="caret"></b></a>
|
||||
data-toggle="dropdown" href="#" title="Menu"><i
|
||||
class="icon-stackedit"></i> <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="action-download-md" href="#"><i
|
||||
class="icon-download-alt"></i> Save as MD</a></li>
|
||||
@ -67,6 +70,22 @@
|
||||
data-target="#modal-manage-sync"><i class="icon-refresh"></i>
|
||||
Manage synchronization</a></li>
|
||||
<li class="divider"></li>
|
||||
<li class="dropdown-submenu"><a href="#"><i
|
||||
class="icon-share"></i> Publish</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#" class="action-publish-github"><i
|
||||
class="icon-github"></i> GitHub</a></li>
|
||||
<li><a href="#" class="action-publish-blogger"><i
|
||||
class="icon-blogger"></i> Blogger</a></li>
|
||||
<li><a href="#" class="action-publish-wordpress"><i
|
||||
class="icon-wordpress"></i> WordPress</a></li>
|
||||
<li><a href="#" class="action-publish-tumblr"><i
|
||||
class="icon-tumblr"></i> Tumblr</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#" data-toggle="modal"
|
||||
data-target="#modal-manage-publication"><i class="icon-share"></i>
|
||||
Manage publication</a></li>
|
||||
<li class="divider"></li>
|
||||
<li><a href="#" data-toggle="modal"
|
||||
data-target="#modal-settings" class="action-load-settings"><i
|
||||
class="icon-cog"></i> Settings</a></li>
|
||||
@ -237,6 +256,56 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-publish-existing" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×</button>
|
||||
<h3>Publish</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Would you like to:</dt>
|
||||
<dd>
|
||||
<label class="radio"> <input type="radio"
|
||||
name="radio-publish-existing" value="new">
|
||||
Create a new Post
|
||||
</label> <label class="radio"> <input type="radio"
|
||||
name="radio-publish-existing" value="existing"> Edit an existing post
|
||||
</label>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||
data-dismiss="modal" class="btn btn-primary action-publish-next">Next</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-publish-format" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×</button>
|
||||
<h3>Publish</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Publish as:</dt>
|
||||
<dd>
|
||||
<label class="radio"> <input type="radio"
|
||||
name="radio-publish-format" value="markdown">
|
||||
Markdown format
|
||||
</label> <label class="radio"> <input type="radio"
|
||||
name="radio-publish-format" value="html"> HTML format
|
||||
</label>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||
data-dismiss="modal" class="btn btn-primary action-publish-finish">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-settings" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
|
103
js/core.js
103
js/core.js
@ -271,7 +271,110 @@ define(["jquery", "bootstrap", "jgrowl", "layout", "Markdown.Editor"], function(
|
||||
return x.join('');
|
||||
};
|
||||
|
||||
// CRC32 algorithm
|
||||
var mHash = [ 0, 1996959894, 3993919788, 2567524794, 124634137,
|
||||
1886057615, 3915621685, 2657392035, 249268274, 2044508324,
|
||||
3772115230, 2547177864, 162941995, 2125561021, 3887607047,
|
||||
2428444049, 498536548, 1789927666, 4089016648, 2227061214,
|
||||
450548861, 1843258603, 4107580753, 2211677639, 325883990,
|
||||
1684777152, 4251122042, 2321926636, 335633487, 1661365465,
|
||||
4195302755, 2366115317, 997073096, 1281953886, 3579855332,
|
||||
2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
|
||||
901097722, 1119000684, 3686517206, 2898065728, 853044451,
|
||||
1172266101, 3705015759, 2882616665, 651767980, 1373503546,
|
||||
3369554304, 3218104598, 565507253, 1454621731, 3485111705,
|
||||
3099436303, 671266974, 1594198024, 3322730930, 2970347812,
|
||||
795835527, 1483230225, 3244367275, 3060149565, 1994146192,
|
||||
31158534, 2563907772, 4023717930, 1907459465, 112637215,
|
||||
2680153253, 3904427059, 2013776290, 251722036, 2517215374,
|
||||
3775830040, 2137656763, 141376813, 2439277719, 3865271297,
|
||||
1802195444, 476864866, 2238001368, 4066508878, 1812370925,
|
||||
453092731, 2181625025, 4111451223, 1706088902, 314042704,
|
||||
2344532202, 4240017532, 1658658271, 366619977, 2362670323,
|
||||
4224994405, 1303535960, 984961486, 2747007092, 3569037538,
|
||||
1256170817, 1037604311, 2765210733, 3554079995, 1131014506,
|
||||
879679996, 2909243462, 3663771856, 1141124467, 855842277,
|
||||
2852801631, 3708648649, 1342533948, 654459306, 3188396048,
|
||||
3373015174, 1466479909, 544179635, 3110523913, 3462522015,
|
||||
1591671054, 702138776, 2966460450, 3352799412, 1504918807,
|
||||
783551873, 3082640443, 3233442989, 3988292384, 2596254646,
|
||||
62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
|
||||
3814918930, 2489596804, 225274430, 2053790376, 3826175755,
|
||||
2466906013, 167816743, 2097651377, 4027552580, 2265490386,
|
||||
503444072, 1762050814, 4150417245, 2154129355, 426522225,
|
||||
1852507879, 4275313526, 2312317920, 282753626, 1742555852,
|
||||
4189708143, 2394877945, 397917763, 1622183637, 3604390888,
|
||||
2714866558, 953729732, 1340076626, 3518719985, 2797360999,
|
||||
1068828381, 1219638859, 3624741850, 2936675148, 906185462,
|
||||
1090812512, 3747672003, 2825379669, 829329135, 1181335161,
|
||||
3412177804, 3160834842, 628085408, 1382605366, 3423369109,
|
||||
3138078467, 570562233, 1426400815, 3317316542, 2998733608,
|
||||
733239954, 1555261956, 3268935591, 3050360625, 752459403,
|
||||
1541320221, 2607071920, 3965973030, 1969922972, 40735498,
|
||||
2617837225, 3943577151, 1913087877, 83908371, 2512341634,
|
||||
3803740692, 2075208622, 213261112, 2463272603, 3855990285,
|
||||
2094854071, 198958881, 2262029012, 4057260610, 1759359992,
|
||||
534414190, 2176718541, 4139329115, 1873836001, 414664567,
|
||||
2282248934, 4279200368, 1711684554, 285281116, 2405801727,
|
||||
4167216745, 1634467795, 376229701, 2685067896, 3608007406,
|
||||
1308918612, 956543938, 2808555105, 3495958263, 1231636301,
|
||||
1047427035, 2932959818, 3654703836, 1088359270, 936918000,
|
||||
2847714899, 3736837829, 1202900863, 817233897, 3183342108,
|
||||
3401237130, 1404277552, 615818150, 3134207493, 3453421203,
|
||||
1423857449, 601450431, 3009837614, 3294710456, 1567103746,
|
||||
711928724, 3020668471, 3272380065, 1510334235, 755167117 ];
|
||||
core.crc32 = function(str) {
|
||||
var n = 0, crc = -1;
|
||||
for ( var i = 0; i < str.length; i++) {
|
||||
n = (crc ^ str.charCodeAt(i)) & 0xFF;
|
||||
crc = (crc >>> 8) ^ mHash[n];
|
||||
}
|
||||
crc = crc ^ (-1);
|
||||
if (crc < 0) {
|
||||
crc = 0xFFFFFFFF + crc + 1;
|
||||
}
|
||||
return crc.toString(16);
|
||||
};
|
||||
|
||||
// Used to setup an empty localStorage
|
||||
function setupLocalStorage() {
|
||||
if (localStorage["file.counter"] === undefined
|
||||
|| localStorage["file.list"] === undefined) {
|
||||
localStorage["file.counter"] = "0";
|
||||
localStorage["file.list"] = ";";
|
||||
}
|
||||
}
|
||||
|
||||
// Used to upgrade an existing localStorage
|
||||
function upgradeLocalStorage() {
|
||||
var version = localStorage["version"];
|
||||
|
||||
// from v0 to v1
|
||||
if(version === undefined) {
|
||||
var fileIndexList = localStorage["file.list"].split(";");
|
||||
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
||||
var fileIndex = fileIndexList[i];
|
||||
localStorage[fileIndex + ".publish"] = ";";
|
||||
var titleCRC = core.crc32(localStorage[fileIndex + ".title"]);
|
||||
var contentCRC = core.crc32(localStorage[fileIndex + ".content"]);
|
||||
var fileSyncIndexList = localStorage[fileIndex + ".sync"].split(";");
|
||||
for ( var j = 1; j < fileSyncIndexList.length - 1; j++) {
|
||||
var fileSyncIndex = fileSyncIndexList[j];
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
// We store title CRC only for Google Drive synchronization
|
||||
if(localStorage[fileSyncIndex + ".etag"] !== undefined) {
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
version = "v1";
|
||||
}
|
||||
localStorage["version"] = version;
|
||||
}
|
||||
|
||||
core.init = function() {
|
||||
setupLocalStorage();
|
||||
upgradeLocalStorage();
|
||||
|
||||
// jGrowl configuration
|
||||
$.jGrowl.defaults.life = 5000;
|
||||
|
@ -6,7 +6,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
var client = undefined;
|
||||
var authenticated = false;
|
||||
|
||||
var dropbox = {};
|
||||
var dropboxHelper = {};
|
||||
|
||||
// Try to connect dropbox by downloading client.js
|
||||
function connect(callback) {
|
||||
@ -24,7 +24,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url : "js/dropbox.min.js",
|
||||
url : "lib/dropbox.js",
|
||||
dataType : "script", timeout : AJAX_TIMEOUT
|
||||
}).done(function() {
|
||||
asyncTask.success();
|
||||
@ -96,7 +96,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
}
|
||||
|
||||
dropbox.upload = function(path, content, callback) {
|
||||
dropboxHelper.upload = function(path, content, callback) {
|
||||
callback = callback || core.doNothing;
|
||||
authenticate(function() {
|
||||
if (client === undefined) {
|
||||
@ -128,7 +128,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
dropbox.checkUpdates = function(lastChangeId, callback) {
|
||||
dropboxHelper.checkUpdates = function(lastChangeId, callback) {
|
||||
callback = callback || core.doNothing;
|
||||
authenticate(function() {
|
||||
if (client === undefined) {
|
||||
@ -177,7 +177,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
dropbox.downloadMetadata = function(paths, callback, result) {
|
||||
dropboxHelper.downloadMetadata = function(paths, callback, result) {
|
||||
callback = callback || core.doNothing;
|
||||
result = result || [];
|
||||
if(paths.length === 0) {
|
||||
@ -204,13 +204,13 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
asyncTask.onSuccess = function() {
|
||||
dropbox.downloadMetadata(paths, callback, result);
|
||||
dropboxHelper.downloadMetadata(paths, callback, result);
|
||||
};
|
||||
asyncTaskRunner.addTask(asyncTask);
|
||||
});
|
||||
};
|
||||
|
||||
dropbox.downloadContent = function(objects, callback, result) {
|
||||
dropboxHelper.downloadContent = function(objects, callback, result) {
|
||||
callback = callback || core.doNothing;
|
||||
result = result || [];
|
||||
if(objects.length === 0) {
|
||||
@ -252,7 +252,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
asyncTask.onSuccess = function() {
|
||||
dropbox.downloadContent(objects, callback, result);
|
||||
dropboxHelper.downloadContent(objects, callback, result);
|
||||
};
|
||||
asyncTaskRunner.addTask(asyncTask);
|
||||
});
|
||||
@ -322,7 +322,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
}
|
||||
|
||||
dropbox.picker = function(callback) {
|
||||
dropboxHelper.picker = function(callback) {
|
||||
callback = callback || core.doNothing;
|
||||
loadPicker(function() {
|
||||
if (pickerLoaded === false) {
|
||||
@ -349,12 +349,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
dropbox.importFiles = function(paths) {
|
||||
dropbox.downloadMetadata(paths, function(result) {
|
||||
dropboxHelper.importFiles = function(paths) {
|
||||
dropboxHelper.downloadMetadata(paths, function(result) {
|
||||
if(result === undefined) {
|
||||
return;
|
||||
}
|
||||
dropbox.downloadContent(result, function(result) {
|
||||
dropboxHelper.downloadContent(result, function(result) {
|
||||
if(result === undefined) {
|
||||
return;
|
||||
}
|
||||
@ -362,6 +362,8 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
var file = result[i];
|
||||
fileSyncIndex = SYNC_PROVIDER_DROPBOX + encodeURIComponent(file.path.toLowerCase());
|
||||
localStorage[fileSyncIndex + ".version"] = file.versionTag;
|
||||
var contentCRC = core.crc32(file.content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
var fileIndex = fileManager.createFile(file.name, file.content, [fileSyncIndex]);
|
||||
fileManager.selectFile(fileIndex);
|
||||
core.showMessage('"' + file.name + '" imported successfully from Dropbox.');
|
||||
@ -370,11 +372,11 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
dropbox.init = function(fileManagerModule) {
|
||||
dropboxHelper.init = function(fileManagerModule) {
|
||||
fileManager = fileManagerModule;
|
||||
};
|
||||
|
||||
dropbox.checkPath = function(path) {
|
||||
dropboxHelper.checkPath = function(path) {
|
||||
if(!path.match(/^[^\\<>:"\|?\*]+$/)) {
|
||||
core.showError('"' + path + '" contains invalid characters.');
|
||||
return undefined;
|
||||
@ -385,5 +387,5 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
return path;
|
||||
};
|
||||
|
||||
return dropbox;
|
||||
return dropboxHelper;
|
||||
});
|
5
js/dropbox.min.js
vendored
5
js/dropbox.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,11 +1,12 @@
|
||||
define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
function($, core, gdrive, dropbox, synchronizer, asyncTaskRunner) {
|
||||
define(["jquery", "core", "google-helper", "dropbox-helper", "synchronizer", "publisher", "async-runner"],
|
||||
function($, core, googleHelper, dropboxHelper, synchronizer, publisher, asyncTaskRunner) {
|
||||
|
||||
var fileManager = {};
|
||||
|
||||
fileManager.init = function() {
|
||||
gdrive.init(fileManager);
|
||||
dropbox.init(fileManager);
|
||||
googleHelper.init(fileManager);
|
||||
dropboxHelper.init(fileManager);
|
||||
publisher.init(fileManager);
|
||||
|
||||
var changeSyncButtonState = function() {
|
||||
if(synchronizer.isRunning() || synchronizer.isQueueEmpty() || core.isOffline) {
|
||||
@ -83,21 +84,21 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
$(".action-upload-gdrive-select").click(function() {
|
||||
// This action is not available because picker does not support
|
||||
// folder selection yet
|
||||
gdrive.picker(function(ids) {
|
||||
googleHelper.picker(function(ids) {
|
||||
if(ids !== undefined && ids.length !== 0) {
|
||||
uploadGdrive(ids[0]);
|
||||
uploadGdrive(undefined, ids[0]);
|
||||
}
|
||||
}, true);
|
||||
});
|
||||
$(".action-download-gdrive").click(function() {
|
||||
gdrive.picker(importGdrive);
|
||||
googleHelper.picker(importGdrive);
|
||||
});
|
||||
$(".action-manual-gdrive").click(function(event) {
|
||||
var fileId = core.getInputValue($("#manual-gdrive-fileid"), event);
|
||||
manualGdrive(fileId);
|
||||
});
|
||||
$(".action-download-dropbox").click(function() {
|
||||
dropbox.picker(importDropbox);
|
||||
dropboxHelper.picker(importDropbox);
|
||||
});
|
||||
$(".action-upload-dropbox").click(function(event) {
|
||||
var path = core.getInputValue($("#upload-dropbox-path"), event);
|
||||
@ -112,12 +113,6 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
// Caution: this function recreate the editor (reset undo operations)
|
||||
var fileDescList = [];
|
||||
fileManager.selectFile = function(fileIndex) {
|
||||
// If file system does not exist
|
||||
if (!localStorage["file.counter"] || !localStorage["file.list"]) {
|
||||
localStorage.clear();
|
||||
localStorage["file.counter"] = 0;
|
||||
localStorage["file.list"] = ";";
|
||||
}
|
||||
// If no file create one
|
||||
if (localStorage["file.list"].length === 1) {
|
||||
fileIndex = this.createFile();
|
||||
@ -169,6 +164,7 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
sync += syncIndexes[i] + ";";
|
||||
}
|
||||
localStorage[fileIndex + ".sync"] = sync;
|
||||
localStorage[fileIndex + ".publish"] = ";";
|
||||
localStorage["file.counter"] = fileCounter + 1;
|
||||
localStorage["file.list"] += fileIndex + ";";
|
||||
return fileIndex;
|
||||
@ -282,10 +278,11 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
refreshManageSync();
|
||||
}
|
||||
}
|
||||
// Remove Google Drive etag
|
||||
// Remove ETAG, version, CRCs (if any)
|
||||
localStorage.removeItem(fileSyncIndex + ".etag");
|
||||
// Remove Dropbox version
|
||||
localStorage.removeItem(fileSyncIndex + ".version");
|
||||
localStorage.removeItem(fileSyncIndex + ".contentCRC");
|
||||
localStorage.removeItem(fileSyncIndex + ".titleCRC");
|
||||
};
|
||||
|
||||
// Look for local file associated to a synchronized location
|
||||
@ -303,14 +300,18 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
return fileIndex;
|
||||
};
|
||||
|
||||
function uploadGdrive(folderId) {
|
||||
function uploadGdrive(fileId, folderId) {
|
||||
var fileIndex = localStorage["file.current"];
|
||||
var content = localStorage[fileIndex + ".content"];
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
gdrive.upload(undefined, folderId, title, content, function(fileSyncIndex) {
|
||||
googleHelper.upload(fileId, folderId, title, content, function(fileSyncIndex) {
|
||||
if (fileSyncIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
var contentCRC = core.crc32(content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
var titleCRC = core.crc32(title);
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
localStorage[fileIndex + ".sync"] += fileSyncIndex + ";";
|
||||
refreshManageSync();
|
||||
fileManager.updateFileTitles();
|
||||
@ -319,6 +320,21 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
});
|
||||
}
|
||||
|
||||
function manualGdrive(fileId) {
|
||||
if(!fileId) {
|
||||
return;
|
||||
}
|
||||
// Check that file is not synchronized with an other one
|
||||
var fileSyncIndex = SYNC_PROVIDER_GDRIVE + fileId;
|
||||
var fileIndex = fileManager.getFileIndexFromSync(fileSyncIndex);
|
||||
if(fileIndex !== undefined) {
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
core.showError('File ID is already synchronized with "' + title + '"');
|
||||
return;
|
||||
}
|
||||
uploadGdrive(fileId);
|
||||
}
|
||||
|
||||
function importGdrive(ids) {
|
||||
if(ids === undefined) {
|
||||
return;
|
||||
@ -335,44 +351,14 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
}
|
||||
importIds.push(fileId);
|
||||
}
|
||||
gdrive.importFiles(importIds);
|
||||
}
|
||||
|
||||
function manualGdrive(fileId) {
|
||||
if(!fileId) {
|
||||
return;
|
||||
}
|
||||
// Check that file is not synchronized with an other one
|
||||
var fileSyncIndex = SYNC_PROVIDER_GDRIVE + fileId;
|
||||
var fileIndex = fileManager.getFileIndexFromSync(fileSyncIndex);
|
||||
if(fileIndex !== undefined) {
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
core.showError('File ID is already synchronized with "' + title + '"');
|
||||
return;
|
||||
}
|
||||
var fileIndex = localStorage["file.current"];
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
gdrive.downloadMetadata([fileId], function(result) {
|
||||
if(result === undefined || result.length === 0) {
|
||||
return;
|
||||
}
|
||||
localStorage[fileSyncIndex + ".etag"] = result[0].etag;
|
||||
localStorage[fileIndex + ".sync"] += fileSyncIndex + ";";
|
||||
refreshManageSync();
|
||||
fileManager.updateFileTitles();
|
||||
core.showMessage('"' + title
|
||||
+ '" will now be synchronized on Google Drive.');
|
||||
// Force synchronization
|
||||
synchronizer.addFileForUpload(fileIndex);
|
||||
synchronizer.forceSync();
|
||||
});
|
||||
googleHelper.importFiles(importIds);
|
||||
}
|
||||
|
||||
function manualDropbox(path) {
|
||||
if(!path) {
|
||||
return;
|
||||
}
|
||||
path = dropbox.checkPath(path);
|
||||
path = dropboxHelper.checkPath(path);
|
||||
if(path === undefined) {
|
||||
return;
|
||||
}
|
||||
@ -387,10 +373,12 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
var fileIndex = localStorage["file.current"];
|
||||
var content = localStorage[fileIndex + ".content"];
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
dropbox.upload(path, content, function(fileSyncIndex) {
|
||||
dropboxHelper.upload(path, content, function(fileSyncIndex) {
|
||||
if (fileSyncIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
var contentCRC = core.crc32(content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
localStorage[fileIndex + ".sync"] += fileSyncIndex + ";";
|
||||
refreshManageSync();
|
||||
fileManager.updateFileTitles();
|
||||
@ -415,7 +403,7 @@ define(["jquery", "core", "gdrive", "dropbox", "synchronizer", "async-runner"],
|
||||
}
|
||||
importPaths.push(filePath);
|
||||
}
|
||||
dropbox.importFiles(importPaths);
|
||||
dropboxHelper.importFiles(importPaths);
|
||||
}
|
||||
|
||||
function refreshManageSync() {
|
||||
|
10
js/github.js
Normal file
10
js/github.js
Normal file
@ -0,0 +1,10 @@
|
||||
define(["jquery", "core", "async-runner", "underscore-min"], function($, core, asyncTaskRunner) {
|
||||
|
||||
var client = undefined;
|
||||
var authenticated = false;
|
||||
|
||||
var github = {};
|
||||
|
||||
|
||||
|
||||
});
|
@ -6,7 +6,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
var connected = false;
|
||||
var authenticated = false;
|
||||
|
||||
var gdrive = {};
|
||||
var googleHelper = {};
|
||||
|
||||
// Try to connect Gdrive by downloading client.js
|
||||
function connect(callback) {
|
||||
@ -97,7 +97,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
}
|
||||
|
||||
gdrive.upload = function(fileId, parentId, title, content, callback) {
|
||||
googleHelper.upload = function(fileId, parentId, title, content, callback) {
|
||||
callback = callback || core.doNothing;
|
||||
authenticate(function() {
|
||||
if (connected === false) {
|
||||
@ -151,17 +151,10 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
return;
|
||||
}
|
||||
var error = response.error;
|
||||
// If it's an update and file has been removed from Google Drive
|
||||
if(error !== undefined && fileId !== undefined && error.code === 404) {
|
||||
core.showMessage('"' + title + '" has been removed from Google Drive.');
|
||||
fileManager.removeSync(SYNC_PROVIDER_GDRIVE + fileId);
|
||||
fileManager.updateFileTitles();
|
||||
// We assume it's not error
|
||||
fileSyncIndex = null;
|
||||
asyncTask.success();
|
||||
return;
|
||||
}
|
||||
// Handle error
|
||||
if(error !== undefined && fileId !== undefined && error.code === 404) {
|
||||
error = 'File ID "' + fileId + '" does not exist on Google Drive.';
|
||||
}
|
||||
handleError(error, asyncTask, callback);
|
||||
});
|
||||
};
|
||||
@ -172,7 +165,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
gdrive.checkUpdates = function(lastChangeId, callback) {
|
||||
googleHelper.checkUpdates = function(lastChangeId, callback) {
|
||||
callback = callback || core.doNothing;
|
||||
authenticate(function() {
|
||||
if (connected === false) {
|
||||
@ -226,7 +219,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
gdrive.downloadMetadata = function(ids, callback, result) {
|
||||
googleHelper.downloadMetadata = function(ids, callback, result) {
|
||||
callback = callback || core.doNothing;
|
||||
result = result || [];
|
||||
if(ids.length === 0) {
|
||||
@ -268,13 +261,13 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
asyncTask.onSuccess = function() {
|
||||
gdrive.downloadMetadata(ids, callback, result);
|
||||
googleHelper.downloadMetadata(ids, callback, result);
|
||||
};
|
||||
asyncTaskRunner.addTask(asyncTask);
|
||||
});
|
||||
};
|
||||
|
||||
gdrive.downloadContent = function(objects, callback, result) {
|
||||
googleHelper.downloadContent = function(objects, callback, result) {
|
||||
callback = callback || core.doNothing;
|
||||
result = result || [];
|
||||
if(objects.length === 0) {
|
||||
@ -328,7 +321,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
asyncTask.onSuccess = function() {
|
||||
gdrive.downloadContent(objects, callback, result);
|
||||
googleHelper.downloadContent(objects, callback, result);
|
||||
};
|
||||
asyncTaskRunner.addTask(asyncTask);
|
||||
});
|
||||
@ -404,7 +397,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
}
|
||||
|
||||
gdrive.picker = function(callback) {
|
||||
googleHelper.picker = function(callback) {
|
||||
callback = callback || core.doNothing;
|
||||
loadPicker(function() {
|
||||
if (pickerLoaded === false) {
|
||||
@ -446,12 +439,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
gdrive.importFiles = function(ids) {
|
||||
gdrive.downloadMetadata(ids, function(result) {
|
||||
googleHelper.importFiles = function(ids) {
|
||||
googleHelper.downloadMetadata(ids, function(result) {
|
||||
if(result === undefined) {
|
||||
return;
|
||||
}
|
||||
gdrive.downloadContent(result, function(result) {
|
||||
googleHelper.downloadContent(result, function(result) {
|
||||
if(result === undefined) {
|
||||
return;
|
||||
}
|
||||
@ -459,6 +452,10 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
var file = result[i];
|
||||
fileSyncIndex = SYNC_PROVIDER_GDRIVE + file.id;
|
||||
localStorage[fileSyncIndex + ".etag"] = file.etag;
|
||||
var contentCRC = core.crc32(file.content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
var titleCRC = core.crc32(file.title);
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
var fileIndex = fileManager.createFile(file.title, file.content, [fileSyncIndex]);
|
||||
fileManager.selectFile(fileIndex);
|
||||
core.showMessage('"' + file.title + '" imported successfully from Google Drive.');
|
||||
@ -467,7 +464,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
});
|
||||
};
|
||||
|
||||
gdrive.init = function(fileManagerModule) {
|
||||
googleHelper.init = function(fileManagerModule) {
|
||||
fileManager = fileManagerModule;
|
||||
var state = localStorage["sync.gdrive.state"];
|
||||
if(state === undefined) {
|
||||
@ -476,11 +473,15 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
localStorage.removeItem("sync.gdrive.state");
|
||||
state = JSON.parse(state);
|
||||
if (state.action == "create") {
|
||||
gdrive.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE,
|
||||
googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE,
|
||||
"", function(fileSyncIndex) {
|
||||
if(fileSyncIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
var contentCRC = core.crc32("");
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
var titleCRC = core.crc32(GDRIVE_DEFAULT_FILE_TITLE);
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
var fileIndex = fileManager.createFile(GDRIVE_DEFAULT_FILE_TITLE, "", [fileSyncIndex]);
|
||||
fileManager.selectFile(fileIndex);
|
||||
core.showMessage('"' + GDRIVE_DEFAULT_FILE_TITLE + '" created successfully on Google Drive.');
|
||||
@ -498,9 +499,9 @@ define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
ids.push(id);
|
||||
}
|
||||
}
|
||||
gdrive.importFiles(ids);
|
||||
googleHelper.importFiles(ids);
|
||||
}
|
||||
};
|
||||
|
||||
return gdrive;
|
||||
return googleHelper;
|
||||
});
|
37
js/publisher.js
Normal file
37
js/publisher.js
Normal file
@ -0,0 +1,37 @@
|
||||
define(["jquery", "core", "async-runner"], function($, core, asyncTaskRunner) {
|
||||
|
||||
// Dependencies
|
||||
var fileManager = undefined;
|
||||
|
||||
var publisher = {};
|
||||
|
||||
var wizardProvider = undefined;
|
||||
|
||||
function initWizard(provider) {
|
||||
wizardProvider = provider;
|
||||
$("input:radio[name=radio-publish-existing][value=new]").prop("checked", true);
|
||||
$("input:radio[name=radio-publish-format][value=markdown]").prop("checked", true);
|
||||
}
|
||||
|
||||
publisher.init = function(fileManagerModule) {
|
||||
fileManager = fileManagerModule;
|
||||
$("#action-publish-github").click(function() {
|
||||
initWizard("github");
|
||||
});
|
||||
$("#action-publish-blogger").click(function() {
|
||||
initWizard("blogger");
|
||||
});
|
||||
$("#action-publish-wordpress").click(function() {
|
||||
initWizard("wordpress");
|
||||
});
|
||||
$("#action-publish-tumblr").click(function() {
|
||||
initWizard("tumblr");
|
||||
});
|
||||
};
|
||||
|
||||
publisher.initWizard = function() {
|
||||
|
||||
};
|
||||
|
||||
return publisher;
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbox) {
|
||||
define(["jquery", "core", "google-helper", "dropbox-helper"], function($, core, googleHelper, dropboxHelper) {
|
||||
var synchronizer = {};
|
||||
|
||||
// Dependencies
|
||||
@ -49,7 +49,7 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
};
|
||||
|
||||
// Recursive function to upload a single file on multiple locations
|
||||
function fileUp(fileSyncIndexList, content, title, callback) {
|
||||
function fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback) {
|
||||
if (fileSyncIndexList.length === 0) {
|
||||
localStorage.removeItem("sync.current");
|
||||
// run the next file synchronization
|
||||
@ -58,12 +58,22 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
}
|
||||
var fileSyncIndex = fileSyncIndexList.pop();
|
||||
|
||||
// Skip if CRC has not changed
|
||||
var syncContentCRC = localStorage[fileSyncIndex + ".contentCRC"];
|
||||
var syncTitleCRC = localStorage[fileSyncIndex + ".titleCRC"];
|
||||
if(contentCRC == syncContentCRC && (syncTitleCRC === undefined || titleCRC == syncTitleCRC)) {
|
||||
fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find the provider
|
||||
if (fileSyncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) {
|
||||
var id = fileSyncIndex.substring(SYNC_PROVIDER_GDRIVE.length);
|
||||
gdrive.upload(id, undefined, title, content, function(result) {
|
||||
googleHelper.upload(id, undefined, title, content, function(result) {
|
||||
if (result !== undefined) {
|
||||
fileUp(fileSyncIndexList, content, title, callback);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback);
|
||||
return;
|
||||
}
|
||||
// If error we put the fileIndex back in the queue
|
||||
@ -75,9 +85,10 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
} else if (fileSyncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) {
|
||||
var path = fileSyncIndex.substring(SYNC_PROVIDER_DROPBOX.length);
|
||||
path = decodeURIComponent(path);
|
||||
dropbox.upload(path, content, function(result) {
|
||||
dropboxHelper.upload(path, content, function(result) {
|
||||
if (result !== undefined) {
|
||||
fileUp(fileSyncIndexList, content, title, callback);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback);
|
||||
return;
|
||||
}
|
||||
// If error we put the fileIndex back in the queue
|
||||
@ -87,7 +98,7 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
return;
|
||||
});
|
||||
} else {
|
||||
fileUp(fileSyncIndexList, content, title, callback);
|
||||
fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,10 +119,12 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
|
||||
var content = localStorage[fileIndex + ".content"];
|
||||
var title = localStorage[fileIndex + ".title"];
|
||||
var contentCRC = core.crc32(content);
|
||||
var titleCRC = core.crc32(title);
|
||||
|
||||
// Parse the list of synchronized locations associated to the file
|
||||
var fileSyncIndexList = localStorage[fileIndex + ".sync"].split(";");
|
||||
fileUp(fileSyncIndexList, content, title, callback);
|
||||
fileUp(fileSyncIndexList, content, contentCRC, title, titleCRC, callback);
|
||||
};
|
||||
|
||||
function syncDownGdrive(callback) {
|
||||
@ -121,12 +134,12 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
}
|
||||
var lastChangeId = parseInt(localStorage[SYNC_PROVIDER_GDRIVE
|
||||
+ "lastChangeId"]);
|
||||
gdrive.checkUpdates(lastChangeId, function(changes, newChangeId) {
|
||||
googleHelper.checkUpdates(lastChangeId, function(changes, newChangeId) {
|
||||
if (changes === undefined) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
gdrive.downloadContent(changes, function(changes) {
|
||||
googleHelper.downloadContent(changes, function(changes) {
|
||||
if (changes === undefined) {
|
||||
callback();
|
||||
return;
|
||||
@ -175,9 +188,14 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
fileManager.selectFile(); // Refresh editor
|
||||
}
|
||||
}
|
||||
// Update file etag
|
||||
// Update file etag and CRCs
|
||||
localStorage[fileSyncIndex + ".etag"] = file.etag;
|
||||
// Synchronize file to others locations
|
||||
var contentCRC = core.crc32(file.content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
var titleCRC = core.crc32(file.title);
|
||||
localStorage[fileSyncIndex + ".titleCRC"] = titleCRC;
|
||||
|
||||
// Synchronize file with others locations
|
||||
synchronizer.addFileForUpload(fileIndex);
|
||||
}
|
||||
if(updateFileTitles) {
|
||||
@ -196,12 +214,12 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
return;
|
||||
}
|
||||
var lastChangeId = localStorage[SYNC_PROVIDER_DROPBOX + "lastChangeId"];
|
||||
dropbox.checkUpdates(lastChangeId, function(changes, newChangeId) {
|
||||
dropboxHelper.checkUpdates(lastChangeId, function(changes, newChangeId) {
|
||||
if (changes === undefined) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
dropbox.downloadContent(changes, function(changes) {
|
||||
dropboxHelper.downloadContent(changes, function(changes) {
|
||||
if (changes === undefined) {
|
||||
callback();
|
||||
return;
|
||||
@ -243,9 +261,12 @@ define(["jquery", "core", "gdrive", "dropbox"], function($, core, gdrive, dropbo
|
||||
fileManager.selectFile(); // Refresh editor
|
||||
}
|
||||
}
|
||||
// Update file version
|
||||
// Update file version and CRC
|
||||
localStorage[fileSyncIndex + ".version"] = file.versionTag;
|
||||
// Synchronize file to others locations
|
||||
var contentCRC = core.crc32(file.content);
|
||||
localStorage[fileSyncIndex + ".contentCRC"] = contentCRC;
|
||||
|
||||
// Synchronize file with others locations
|
||||
synchronizer.addFileForUpload(fileIndex);
|
||||
}
|
||||
if(updateFileTitles) {
|
||||
|
5
js/underscore-min.js
vendored
Normal file
5
js/underscore-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3399
lib/dropbox.js
Normal file
3399
lib/dropbox.js
Normal file
File diff suppressed because it is too large
Load Diff
499
lib/github.js
Normal file
499
lib/github.js
Normal file
@ -0,0 +1,499 @@
|
||||
// Github.js 0.7.0
|
||||
// (c) 2012 Michael Aufreiter, Development Seed
|
||||
// Github.js is freely distributable under the MIT license.
|
||||
// For all details and documentation:
|
||||
// http://substance.io/michael/github
|
||||
|
||||
(function() {
|
||||
var Github;
|
||||
var API_URL = 'https://api.github.com';
|
||||
|
||||
Github = window.Github = function(options) {
|
||||
|
||||
// HTTP Request Abstraction
|
||||
// =======
|
||||
//
|
||||
// I'm not proud of this and neither should you be if you were responsible for the XMLHttpRequest spec.
|
||||
|
||||
function _request(method, path, data, cb, raw) {
|
||||
function getURL() {
|
||||
var url = API_URL + path;
|
||||
return url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
if (!raw) {xhr.dataType = "json";}
|
||||
|
||||
xhr.open(method, getURL());
|
||||
xhr.onreadystatechange = function () {
|
||||
if (this.readyState == 4) {
|
||||
if (this.status >= 200 && this.status < 300 || this.status === 304) {
|
||||
cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true);
|
||||
} else {
|
||||
cb({request: this, error: this.status});
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.setRequestHeader('Accept','application/vnd.github.raw');
|
||||
xhr.setRequestHeader('Content-Type','application/json');
|
||||
if (
|
||||
(options.auth == 'oauth' && options.token) ||
|
||||
(options.auth == 'basic' && options.username && options.password)
|
||||
) {
|
||||
xhr.setRequestHeader('Authorization',options.auth == 'oauth'
|
||||
? 'token '+ options.token
|
||||
: 'Basic ' + Base64.encode(options.username + ':' + options.password)
|
||||
);
|
||||
}
|
||||
data ? xhr.send(JSON.stringify(data)) : xhr.send();
|
||||
}
|
||||
|
||||
// User API
|
||||
// =======
|
||||
|
||||
Github.User = function() {
|
||||
this.repos = function(cb) {
|
||||
_request("GET", "/user/repos?type=all&per_page=1000&sort=updated", null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List user organizations
|
||||
// -------
|
||||
|
||||
this.orgs = function(cb) {
|
||||
_request("GET", "/user/orgs", null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List authenticated user's gists
|
||||
// -------
|
||||
|
||||
this.gists = function(cb) {
|
||||
_request("GET", "/gists", null, function(err, res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Show user information
|
||||
// -------
|
||||
|
||||
this.show = function(username, cb) {
|
||||
var command = username ? "/users/"+username : "/user";
|
||||
|
||||
_request("GET", command, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List user repositories
|
||||
// -------
|
||||
|
||||
this.userRepos = function(username, cb) {
|
||||
_request("GET", "/users/"+username+"/repos?type=all&per_page=1000&sort=updated", null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List a user's gists
|
||||
// -------
|
||||
|
||||
this.userGists = function(username, cb) {
|
||||
_request("GET", "/users/"+username+"/gists", null, function(err, res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// List organization repositories
|
||||
// -------
|
||||
|
||||
this.orgRepos = function(orgname, cb) {
|
||||
_request("GET", "/orgs/"+orgname+"/repos?type=all&per_page=1000&sort=updated&direction=desc", null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// Follow user
|
||||
// -------
|
||||
|
||||
this.follow = function(username, cb) {
|
||||
_request("PUT", "/user/following/"+username, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// Unfollow user
|
||||
// -------
|
||||
|
||||
this.unfollow = function(username, cb) {
|
||||
_request("DELETE", "/user/following/"+username, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Repository API
|
||||
// =======
|
||||
|
||||
Github.Repository = function(options) {
|
||||
var repo = options.name;
|
||||
var user = options.user;
|
||||
|
||||
var that = this;
|
||||
var repoPath = "/repos/" + user + "/" + repo;
|
||||
|
||||
var currentTree = {
|
||||
"branch": null,
|
||||
"sha": null
|
||||
};
|
||||
|
||||
// Uses the cache if branch has not been changed
|
||||
// -------
|
||||
|
||||
function updateTree(branch, cb) {
|
||||
if (branch === currentTree.branch && currentTree.sha) return cb(null, currentTree.sha);
|
||||
that.getRef("heads/"+branch, function(err, sha) {
|
||||
currentTree.branch = branch;
|
||||
currentTree.sha = sha;
|
||||
cb(err, sha);
|
||||
});
|
||||
}
|
||||
|
||||
// Get a particular reference
|
||||
// -------
|
||||
|
||||
this.getRef = function(ref, cb) {
|
||||
_request("GET", repoPath + "/git/refs/" + ref, null, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.object.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Create a new reference
|
||||
// --------
|
||||
//
|
||||
// {
|
||||
// "ref": "refs/heads/my-new-branch-name",
|
||||
// "sha": "827efc6d56897b048c772eb4087f854f46256132"
|
||||
// }
|
||||
|
||||
this.createRef = function(options, cb) {
|
||||
_request("POST", repoPath + "/git/refs", options, cb);
|
||||
};
|
||||
|
||||
// Delete a reference
|
||||
// --------
|
||||
//
|
||||
// repo.deleteRef('heads/gh-pages')
|
||||
// repo.deleteRef('tags/v1.0')
|
||||
|
||||
this.deleteRef = function(ref, cb) {
|
||||
_request("DELETE", repoPath + "/git/refs/"+ref, options, cb);
|
||||
};
|
||||
|
||||
// List all branches of a repository
|
||||
// -------
|
||||
|
||||
this.listBranches = function(cb) {
|
||||
_request("GET", repoPath + "/git/refs/heads", null, function(err, heads) {
|
||||
if (err) return cb(err);
|
||||
cb(null, _.map(heads, function(head) { return _.last(head.ref.split('/')); }));
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the contents of a blob
|
||||
// -------
|
||||
|
||||
this.getBlob = function(sha, cb) {
|
||||
_request("GET", repoPath + "/git/blobs/" + sha, null, cb, 'raw');
|
||||
};
|
||||
|
||||
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
|
||||
// -------
|
||||
|
||||
this.getSha = function(branch, path, cb) {
|
||||
// Just use head if path is empty
|
||||
if (path === "") return that.getRef("heads/"+branch, cb);
|
||||
that.getTree(branch+"?recursive=true", function(err, tree) {
|
||||
var file = _.select(tree, function(file) {
|
||||
return file.path === path;
|
||||
})[0];
|
||||
cb(null, file ? file.sha : null);
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the tree a commit points to
|
||||
// -------
|
||||
|
||||
this.getTree = function(tree, cb) {
|
||||
_request("GET", repoPath + "/git/trees/"+tree, null, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.tree);
|
||||
});
|
||||
};
|
||||
|
||||
// Post a new blob object, getting a blob SHA back
|
||||
// -------
|
||||
|
||||
this.postBlob = function(content, cb) {
|
||||
if (typeof(content) === "string") {
|
||||
content = {
|
||||
"content": content,
|
||||
"encoding": "utf-8"
|
||||
};
|
||||
}
|
||||
|
||||
_request("POST", repoPath + "/git/blobs", content, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Update an existing tree adding a new blob object getting a tree SHA back
|
||||
// -------
|
||||
|
||||
this.updateTree = function(baseTree, path, blob, cb) {
|
||||
var data = {
|
||||
"base_tree": baseTree,
|
||||
"tree": [
|
||||
{
|
||||
"path": path,
|
||||
"mode": "100644",
|
||||
"type": "blob",
|
||||
"sha": blob
|
||||
}
|
||||
]
|
||||
};
|
||||
_request("POST", repoPath + "/git/trees", data, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Post a new tree object having a file path pointer replaced
|
||||
// with a new blob SHA getting a tree SHA back
|
||||
// -------
|
||||
|
||||
this.postTree = function(tree, cb) {
|
||||
_request("POST", repoPath + "/git/trees", { "tree": tree }, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Create a new commit object with the current commit SHA as the parent
|
||||
// and the new tree SHA, getting a commit SHA back
|
||||
// -------
|
||||
|
||||
this.commit = function(parent, tree, message, cb) {
|
||||
var data = {
|
||||
"message": message,
|
||||
"author": {
|
||||
"name": options.username
|
||||
},
|
||||
"parents": [
|
||||
parent
|
||||
],
|
||||
"tree": tree
|
||||
};
|
||||
|
||||
_request("POST", repoPath + "/git/commits", data, function(err, res) {
|
||||
currentTree.sha = res.sha; // update latest commit
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Update the reference of your head to point to the new commit SHA
|
||||
// -------
|
||||
|
||||
this.updateHead = function(head, commit, cb) {
|
||||
_request("PATCH", repoPath + "/git/refs/heads/" + head, { "sha": commit }, function(err, res) {
|
||||
cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
// Show repository information
|
||||
// -------
|
||||
|
||||
this.show = function(cb) {
|
||||
_request("GET", repoPath, null, cb);
|
||||
};
|
||||
|
||||
// Get contents
|
||||
// --------
|
||||
|
||||
this.contents = function(branch, path, cb) {
|
||||
_request("GET", repoPath + "/contents?ref=" + branch, { path: path }, cb);
|
||||
};
|
||||
|
||||
// Fork repository
|
||||
// -------
|
||||
|
||||
this.fork = function(cb) {
|
||||
_request("POST", repoPath + "/forks", null, cb);
|
||||
};
|
||||
|
||||
// Create pull request
|
||||
// --------
|
||||
|
||||
this.createPullRequest = function(options, cb) {
|
||||
_request("POST", repoPath + "/pulls", options, cb);
|
||||
};
|
||||
|
||||
// Read file at given path
|
||||
// -------
|
||||
|
||||
this.read = function(branch, path, cb) {
|
||||
that.getSha(branch, path, function(err, sha) {
|
||||
if (!sha) return cb("not found", null);
|
||||
that.getBlob(sha, function(err, content) {
|
||||
cb(err, content, sha);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Remove a file from the tree
|
||||
// -------
|
||||
|
||||
this.remove = function(branch, path, cb) {
|
||||
updateTree(branch, function(err, latestCommit) {
|
||||
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
|
||||
// Update Tree
|
||||
var newTree = _.reject(tree, function(ref) { return ref.path === path; });
|
||||
_.each(newTree, function(ref) {
|
||||
if (ref.type === "tree") delete ref.sha;
|
||||
});
|
||||
|
||||
that.postTree(newTree, function(err, rootTree) {
|
||||
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
|
||||
that.updateHead(branch, commit, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Move a file to a new location
|
||||
// -------
|
||||
|
||||
this.move = function(branch, path, newPath, cb) {
|
||||
updateTree(branch, function(err, latestCommit) {
|
||||
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
|
||||
// Update Tree
|
||||
_.each(tree, function(ref) {
|
||||
if (ref.path === path) ref.path = newPath;
|
||||
if (ref.type === "tree") delete ref.sha;
|
||||
});
|
||||
|
||||
that.postTree(tree, function(err, rootTree) {
|
||||
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
|
||||
that.updateHead(branch, commit, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Write file contents to a given branch and path
|
||||
// -------
|
||||
|
||||
this.write = function(branch, path, content, message, cb) {
|
||||
updateTree(branch, function(err, latestCommit) {
|
||||
if (err) return cb(err);
|
||||
that.postBlob(content, function(err, blob) {
|
||||
if (err) return cb(err);
|
||||
that.updateTree(latestCommit, path, blob, function(err, tree) {
|
||||
if (err) return cb(err);
|
||||
that.commit(latestCommit, tree, message, function(err, commit) {
|
||||
if (err) return cb(err);
|
||||
that.updateHead(branch, commit, cb);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Gists API
|
||||
// =======
|
||||
|
||||
Github.Gist = function(options) {
|
||||
var id = options.id;
|
||||
var gistPath = "/gists/"+id;
|
||||
|
||||
// Read the gist
|
||||
// --------
|
||||
|
||||
this.read = function(cb) {
|
||||
_request("GET", gistPath, null, function(err, gist) {
|
||||
cb(err, gist);
|
||||
});
|
||||
};
|
||||
|
||||
// Create the gist
|
||||
// --------
|
||||
// {
|
||||
// "description": "the description for this gist",
|
||||
// "public": true,
|
||||
// "files": {
|
||||
// "file1.txt": {
|
||||
// "content": "String file contents"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
this.create = function(options, cb){
|
||||
_request("POST","/gists", options, cb);
|
||||
};
|
||||
|
||||
// Delete the gist
|
||||
// --------
|
||||
|
||||
this.delete = function(cb) {
|
||||
_request("DELETE", gistPath, null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Fork a gist
|
||||
// --------
|
||||
|
||||
this.fork = function(cb) {
|
||||
_request("POST", gistPath+"/fork", null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Update a gist with the new stuff
|
||||
// --------
|
||||
|
||||
this.update = function(options, cb) {
|
||||
_request("PATCH", gistPath, options, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Top Level API
|
||||
// -------
|
||||
|
||||
this.getRepo = function(user, repo) {
|
||||
return new Github.Repository({user: user, name: repo});
|
||||
};
|
||||
|
||||
this.getUser = function() {
|
||||
return new Github.User();
|
||||
};
|
||||
|
||||
this.getGist = function(id) {
|
||||
return new Github.Gist({id: id});
|
||||
};
|
||||
};
|
||||
}).call(this);
|
Loading…
Reference in New Issue
Block a user