Skip to content

Commit

Permalink
Update v0.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
pinbackit authored Dec 5, 2018
1 parent e542606 commit ffbf1e6
Showing 1 changed file with 95 additions and 125 deletions.
220 changes: 95 additions & 125 deletions pinback.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
(function(){

var version = '0.3.1'
var version = '0.4.0'
, boards = {}
, board = {}
, selected_board
, pins = []
, pin_count = 0
, delay = 1000
, timer;
, username;

// make sure user is logged in and on profile page
if (location.hostname.match(/pinterest.[a-z.]{2,5}$/i) && document.querySelector('.profileBoardsFeed')) {
// already on profile page
start();
// make sure user is on a profile page
if (match = location.href.match(/^https:\/\/www.pinterest.[a-z.]{2,5}\/([a-z0-9_]{1,30})/i)) {
username = match[1];
getResource('Boards', {username: username, field_set_key: 'detailed'}, start);
} else {
alert('Log in and visit your profile to start (pinterest.com/username)');
alert('Log in and visit your profile (pinterest.com/username) or board to start');
return false;
}

// show overlay
function start() {
function start(json) {

// check if overlay is already open
if (document.querySelector('#pboverlay')) return false;

// start at top of page
window.scrollTo(0,0);

// create overlay
var overlay = document.createElement('div');
overlay.id = 'pboverlay';
Expand Down Expand Up @@ -54,155 +49,130 @@

// add overlay to document
document.querySelector('body').appendChild(overlay);

// find boards
var select = document.querySelector('#pboverlay select');
var option = document.createElement('option');
option.text = ' - All public pins - ';
option.value = '/' + location.pathname.split('/')[1] + '/pins/';
option.dataset.name = 'all public pins';
option.value = 'all';
select.add(option);

Array.prototype.forEach.call(document.querySelectorAll('.cardWrapper a'), function(el, i) {
var name = el.innerText.trim().split('\n')[0]; // first line of text
// add dropdown options for each board
Array.prototype.forEach.call(json.resource_response.data, function(b, i) {
var option = document.createElement('option');
option.text = name;
option.value = el.getAttribute('href');
option.dataset.name = name;
option.selected = (selected_board == el.href);
option.text = b.name;
option.value = b.id;
option.selected = (location.pathname == b.url);
select.add(option);
});

// set export button
document.querySelector('#pboverlay button').onclick = function() {
document.querySelector('#pboverlay .controls').innerHTML = '<meter min="0" max="100"></meter>';
status('Exporting...');
var selected = select.querySelector('option:checked');
var name = selected.dataset.name;

if (select.selectedIndex == 0) {
document.querySelectorAll('.tabItem')[1].click()
if (selected.value == 'all') {
status('Exporting all pins...');
getResource('User', {username: username}, parseBoard);
} else {
var link = document.querySelector('a[href="'+selected.value+'"]');
link.href = selected.value+'?'+Date.now();
link.click();
status('Exporting ' + selected.text + '...');
getResource('Board', {board_id: selected.value}, parseBoard);
}

status('Exporting ' + name + '...');
document.querySelector('#pboverlay .controls').innerHTML = '<meter min="0" max="100"></meter>';

return false;
};

// set up close button
document.querySelector('#pboverlay .close').onclick = function() {
window.scrollTo(0,0);
location.href = location.pathname;
return false;
};

// watch for ajax
XMLHttpRequest.prototype.open = (function(orig){
return function(){
// always retrieve first page
if (pin_count == 0) arguments[1] = arguments[1].replace('-end-','')
return orig.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);

XMLHttpRequest.prototype.send = (function(orig){
return function(){

this.addEventListener('loadend', function(e){
if (e.target.getResponseHeader('content-type').match(/json/)) {
var json = JSON.parse(e.target.response);
// regular resources
if (json.resource && json.resource_response && json.resource_response.data) {
parse_resource(json.resource, json.resource_response.data);
}
// cached resources
else if (json.resource_data_cache) {
json.resource_data_cache.forEach(function(el, i) {
if (el.resource) parse_resource(el.resource, el.data);
});
}
}
}, false);

return orig.apply(this, arguments);
};
})(XMLHttpRequest.prototype.send);
}

// parse incoming ajax responses
function parse_resource(r, data) {
if (pin_count >= board.pin_count) return;

if (r.name == 'UserResource' || r.name == 'BoardResource') {
board = data;
pins = [];

// parse selected board
function parseBoard(json) {
board = json.resource_response.data;
getFeed();
}

// fetch pins
function getFeed(bookmarks) {
if (board.type == 'user') {
getResource('UserPins', {username: username, page_size: 25, bookmarks: bookmarks}, parseFeed);
} else {
getResource('BoardFeed', {board_id: board.id, page_size: 25, bookmarks: bookmarks}, parseFeed);
}
if (r.name == 'UserPinsResource' || r.name == 'BoardFeedResource') {
data.forEach(function(p, i) {
if (p.type == 'pin') {
// add board if not already
if (!boards[p.board.name]) boards[p.board.name] = {
id: p.board.id,
name: p.board.name,
url: "https://www.pinterest.com"+p.board.url,
privacy: p.board.privacy,
pins: []
}
// add pin to board
boards[p.board.name].pins.push({
id: p.id,
link: p.link,
description: p.description,
url: "https://www.pinterest.com/pin/"+p.id,
image: p.images.orig.url,
color: p.dominant_color,
longitude: (p.place && p.place.longitude) || null,
latitude: (p.place && p.place.latitude) || null,
pinner: p.pinner.username,
privacy: p.privacy,
date: Date.parse(p.created_at)
});
pin_count++;
}

// parse incoming pins from selected board
function parseFeed(json) {
json.resource_response.data.forEach(function(p, i) {
if (p.type == 'pin') {
// add board if not already
if (!boards[p.board.name]) boards[p.board.name] = {
id: p.board.id,
name: p.board.name,
url: "https://www.pinterest.com"+p.board.url,
privacy: p.board.privacy,
pins: []
}
});

progress(pin_count, board.pin_count);

// scroll page to find more pins
var next = (typeof(r.options.bookmarks) !== "undefined") ? r.options.bookmarks[0] : null;
if (timer) clearTimeout(timer);
if (pin_count >= board.pin_count || next == '-end-') {
// found the end
if (pin_count > 0) done();
} else {
// keep going
timer = setTimeout(function() {
window.scrollTo(0, document.body.scrollHeight);
}, delay);
// add pin to board
boards[p.board.name].pins.push({
id: p.id,
link: p.link,
description: p.description,
url: "https://www.pinterest.com/pin/"+p.id,
image: p.images.orig.url,
color: p.dominant_color,
longitude: (p.place && p.place.longitude) || null,
latitude: (p.place && p.place.latitude) || null,
pinner: p.pinner.username,
privacy: p.privacy,
date: Date.parse(p.created_at)
});
progress(pin_count++, board.pin_count);
}
})

var bookmarks = json.resource.options.bookmarks;
if (bookmarks[0] == '-end-') {
done();
} else {
getFeed(bookmarks);
}
}

// handle api calls
function getResource(resource, options, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
callback(JSON.parse(xhr.responseText));
} else {
alert('An error has occurred.')
console.log(JSON.parse(xhr.responseText));
}
};
xhr.open('GET', '/resource/'+resource+'Resource/get/?data='+encodeURIComponent(JSON.stringify({options: options})));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Accept', 'application/json, text/javascript, */*, q=0.01');
xhr.send();
}

// set export status
function status(s) {
document.querySelector('#pboverlay h1').innerText = s;
}

// set export progress
function progress(a, b) {
if (b) {
status('Exporting ' + a + " of " + b + '...');
document.querySelector('#pboverlay meter').value = (a/b)*100;
} else {
status('Exporting ' + a + '...');
document.querySelector('#pboverlay meter').value = a*100;
}
status('Exporting ' + a + ' of ' + b + '...');
document.querySelector('#pboverlay meter').value = (a/b)*100;
}

// borrowed PRIVATE attribute format from Delicious
function privacy(p) {
// borrowed PRIVATE attribute format from Delicious
return (p != 'public') ? 1 : 0;
}

// simple escape html
function escapeHtml(unsafe) {
return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}
Expand Down Expand Up @@ -237,7 +207,7 @@
data += '</DL><p>';

// create file
var filename = location.pathname.replace(/^\/|\/$/g, '').replace(/\//g,'-')+".html";
var filename = (board.url || username).replace(/^\/|\/$/g, '').replace(/\//g,'-')+".html";
var blob = new Blob([data], {type: 'text/html'});
var url = URL.createObjectURL(blob);

Expand Down

0 comments on commit ffbf1e6

Please sign in to comment.