blob: 411cb210dcfc5bae7ce445737f564e60ce015059 [file] [log] [blame]
<html>
<head>
<script type="text/javascript" src="base64.js"></script>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="chrome_ex_oauthsimple.js"></script>
<script type="text/javascript" src="chrome_ex_oauth.js"></script>
<script type="text/javascript" src="Crypto.js"></script>
<script type="text/javascript" src="SHA1.js"></script>
<script type="text/javascript" charset="utf-8">
var OAUTH = ChromeExOAuth.initBackgroundPage({
'request_url' : 'https://www.google.com/accounts/OAuthGetRequestToken',
'authorize_url' : 'https://www.google.com/accounts/OAuthAuthorizeToken',
'access_url' : 'https://www.google.com/accounts/OAuthGetAccessToken',
'consumer_key' : 'anonymous',
'consumer_secret' : 'anonymous',
'scope' : 'http://picasaweb.google.com/data/',
'app_name' : 'Clip It Good: Chrome Extension'
});
// Constants for various album types.
var PICASA = 'picasa';
var CAMLISTORE = 'camlistore';
var ALBUM_TYPE_STRING = {
picasa: 'Picasa Web Albums',
camlistore: 'Camlistore'
};
// Preferences
var ALBUM_CONFIG = {}; // 'type' -> ('id' -> 'name')
var ALBUM_OPTIONS = {}; // 'type' -> ('id' -> optionsDict)
function loadAlbumConfig() {
var newAlbumConfig = localStorage.getItem('config:albums');
if (newAlbumConfig) {
ALBUM_CONFIG = $.parseJSON(newAlbumConfig);
}
var newAlbumOptions = localStorage.getItem('config:albumOptions');
if (newAlbumOptions) {
ALBUM_OPTIONS = $.parseJSON(newAlbumOptions);
}
}
function saveAlbumConfig() {
localStorage.setItem('config:albums', JSON.stringify(ALBUM_CONFIG));
localStorage.setItem('config:albumOptions', JSON.stringify(ALBUM_OPTIONS));
}
// Sort albums by name.
function getSortedAlbums(albumIdNameDict) {
var albumIdNameArray = [];
$.each(albumIdNameDict, function(id, name) {
albumIdNameArray.push({'id': id, 'name': name});
});
albumIdNameArray.sort(function(a, b) {
if (a['name'] < b['name']) {
return -1;
} else if (a['name'] > b['name']) {
return 1;
} else {
return 0;
}
});
return albumIdNameArray;
}
function setupMenus() {
loadAlbumConfig();
chrome.contextMenus.removeAll(function() {
$.each(ALBUM_CONFIG, function(albumType, albumIdNameDict) {
chrome.contextMenus.create({
title: ALBUM_TYPE_STRING[albumType],
contexts: ['image']
});
chrome.contextMenus.create({
type: 'separator',
contexts: ['image']
});
$.each(getSortedAlbums(albumIdNameDict), function(index, albumDict) {
chrome.contextMenus.create({
title: albumDict.name,
contexts: ['image'],
onclick: function(data, tab) {
return handleMenuClick(
albumType, albumDict.name, albumDict.id, data, tab);
}
});
});
});
});
}
// Upload actions
var ALBUM_TYPE_UPLOAD_FUNC = {
picasa: function(albumId, albumName, dataSrcUrl, dataBuffer, uploadDone) {
var builder = new BlobBuilder();
builder.append(dataBuffer);
function complete(resp, xhr) {
if (!(xhr.status >= 200 && xhr.status <= 299)) {
alert('Error: Response status = ' + xhr.status +
', response body = "' + xhr.responseText + '"');
} else {
uploadDone();
}
}
OAUTH.authorize(function() {
OAUTH.sendSignedRequest(
'http://picasaweb.google.com/data/feed/api/' +
'user/default/albumid/' + albumId,
complete,
{
method: 'POST',
headers: {
'Content-Type': 'image/png',
'Slug': dataSrcUrl
},
parameters: {
alt: 'json'
},
body: builder.getBlob('image/png')
}
);
});
},
camlistore: function(albumId, albumName, dataSrcUrl,
dataBuffer, uploadDone) {
var hash = Crypto.SHA1(new Uint8Array(dataBuffer, 0));
var blobRef = 'sha1-' + hash;
var options = ALBUM_OPTIONS[CAMLISTORE][albumId];
function doUpload(uploadUrl) {
// XXX Use real random boundary.
var boundary = 'randomboundaryXYZ';
var contentType = 'multipart/form-data; boundary=' + boundary;
var header =
'--' + boundary + '\r\n' +
'Content-Type: application/octet-stream\r\n' +
'Content-Disposition: form-data; name="' + blobRef +
'"; filename="1"\r\n\r\n'
var footer = '\r\n--' + boundary + '--\r\n';
var builder = new BlobBuilder();
builder.append(header);
builder.append(dataBuffer);
builder.append(footer);
var payload = builder.getBlob(contentType);
var uploadXhr = new XMLHttpRequest();
uploadXhr.open('POST', uploadUrl, true,
options.username, options.password);
uploadXhr.onreadystatechange = function() {
if (uploadXhr.readyState == XMLHttpRequest.DONE &&
uploadXhr.status == 200) {
// XXX Check for bad response format (not JSON).
var responseJson = $.parseJSON(uploadXhr.responseText)
if (responseJson.received &&
responseJson.received.length == 1 &&
responseJson.received[0].blobRef == blobRef) {
console.log('Successful upload: ' + blobRef);
uploadDone();
return;
}
alert('Camlistore upload response did not verify blob "' +
blobRef + '": ' + uploadXhr.responseText);
}
// XXX: Handle request errors
}
uploadXhr.setRequestHeader('Content-Type', contentType);
uploadXhr.send(payload);
}
var statXhr = new XMLHttpRequest();
statXhr.open('POST', albumId + '/camli/stat', true,
options.username, options.password);
statXhr.onreadystatechange = function() {
if (statXhr.readyState == XMLHttpRequest.DONE &&
statXhr.status == 200) {
// XXX Check for bad response format (not JSON).
var responseJson = $.parseJSON(statXhr.responseText);
if (responseJson.stat &&
responseJson.stat.length == 1 &&
responseJson.stat[0].blobRef == blobRef) {
console.log('Blob already present: ' + blobRef);
uploadDone();
return;
}
var uploadUrl = responseJson.uploadUrl;
if (!uploadUrl) {
alert('Camlistore stat response missing "uploadUrl": ' +
statXhr.responseText);
return;
}
doUpload(uploadUrl);
}
// XXX: Handle request errors
}
statXhr.setRequestHeader(
'Content-Type', 'application/x-www-form-urlencoded');
statXhr.send('camliversion=1&blob1=' + blobRef);
}
};
function handleMenuClick(albumType, albumName, albumId, data, tab) {
chrome.pageAction.setTitle({
tabId: tab.id,
title: 'Clip It Good: Uploading (' + data.srcUrl.substr(0, 100) + ')'
});
chrome.pageAction.show(tab.id);
var img = document.createElement('img');
img.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
var dataUrl = canvas.toDataURL();
var dataUrlAdjusted = dataUrl.replace('data:image/png;base64,', '');
var arrayBuffer = Base64.decode(dataUrlAdjusted).buffer;
function uploadDone() {
chrome.pageAction.hide(tab.id);
}
var uploadFunc = ALBUM_TYPE_UPLOAD_FUNC[albumType];
uploadFunc(albumId, albumName, data.srcUrl, arrayBuffer, uploadDone);
} // end onload
img.src = data.srcUrl;
}
$(document).ready( function() {
setupMenus();
});
</script>
</head>
<body>
</body>
</html>