Skip to content

Commit

Permalink
Merge pull request #1 from jonassterud/v1.0.1
Browse files Browse the repository at this point in the history
v1.0.1
  • Loading branch information
jonassterud committed Nov 17, 2020
2 parents d5d6ca5 + 8af3a71 commit f025f80
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 21 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
</p>

## About
**MSD** (Musescore Downloader) is a chrome extension, published [here](https://chrome.google.com/webstore/detail/musescore-downloader/bglnniclnbhchenijehpcihdobcmedol), that lets you download PDFs from https://musescore.com/. Previously, this tool also supported the option to download MIDI and MP3 files, but that is no longer working. MSD uses three external libraries to function. It uses the pre-built browser version of [PDFKit](https://github.com/foliojs/pdfkit) to create PDF files, the [blob-stream](https://github.com/devongovett/blob-stream) module to turn the PDFKit generated stream into a HTML5 [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object and finally [SVG-to-PDFKit](https://github.com/alafr/SVG-to-PDFKit) to add SVG support to PDFKit.
**MSD** (Musescore Downloader) is a chrome extension, published [here](https://chrome.google.com/webstore/detail/musescore-downloader/bglnniclnbhchenijehpcihdobcmedol), that lets you download PDFs from https://musescore.com/. Previously, this extension also supported the option to download MIDI and MP3 files, but that is no longer working. MSD uses three external libraries to work. It uses the pre-built browser version of [PDFKit](https://github.com/foliojs/pdfkit) to create PDF files, the [blob-stream](https://github.com/devongovett/blob-stream) module to turn the PDFKit generated stream into a [HTML5 Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object and finally [SVG-to-PDFKit](https://github.com/alafr/SVG-to-PDFKit) to add SVG support to PDFKit.

## Issues
Musescore often updates their website, and there is a good chance that this tool might then temporarily break. I often get many error reports on the actual chrome extension, but posting them here is preferred. When reporting a issue, try to include as much information as possible (operating system, browser, extension version, etc.), and try your best to describe the issue in detail.
Musescore often updates their website, and there is a chance that this extension might then temporarily break. I often get many error reports on the actual chrome extension, but posting them here is preferred. When reporting a issue, try to include as much information as possible (operating system, browser, extension version, etc.), and try your best to describe the issue in detail.

## Contributing
If you solved a bug, cleaned up some code, or anything else, feel free to send a pull request.
If you solved a bug, cleaned up some code, or anything else, feel free to send a pull request in the branch for the next release.

## License
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) for details.
13 changes: 10 additions & 3 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.pageAction.show(sender.tab.id);
break;
case "msd-fetch":
// Check for errors with URL
// Check URL for errors
if(!data?.url?.length) {
return sendResponse({
detail: JSON.stringify({
Expand All @@ -17,12 +17,13 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
});
};

// Send XML request and send data as response
// Open and send XML request
let xhr = new XMLHttpRequest();
xhr.open("GET", data.url);
xhr.responseType = (data.isPNG ? "arraybuffer" : "");
xhr.send();

// Send data as response
xhr.addEventListener("load", () => {
if(data.isPNG) {
return sendResponse({
Expand All @@ -42,7 +43,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
});
break;
case "msd-download":
// Check for errors with URL
// Check URL for errors
if(!data?.url) {
return sendResponse({
detail: JSON.stringify({
Expand All @@ -60,6 +61,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
saveAs: true
}, () => {
chrome.runtime.sendMessage({id: "msd-finished"});
return sendResponse({
detail: JSON.stringify({
state: "success",
data: ""
})
})
});
break;
}
Expand Down
19 changes: 13 additions & 6 deletions injected.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,36 @@

(function() {
// Check for errors
if(!/musescore.com\/.+\/.+/.test(document.location.href)) return alert("This doesn't look like a score page");
if(screen.availWidth - window.innerWidth != 0) {
if(!/musescore.com\/.+\/.+/.test(document.location.href)) {
return alert("This doesn't look like a score page");
}
else if(screen.availWidth - window.innerWidth != 0) {
if(confirm("Please maximize, and then reload, the window before using this extension")) {
return location.reload();
}
}

// Get data
// Gather data
let scoreContainer = document.querySelector("img[src*=score_]")?.parentElement?.parentElement;
let pageCount = scoreContainer?.querySelectorAll(".gXB83")?.length;
let urls = [];

// Check data for errors
if(!scoreContainer) return alert("Wasn't able to find score");
if(!pageCount) {
if(!scoreContainer) {
return alert("Wasn't able to find score");
}
else if(!pageCount) {
pageCount = parseInt(prompt("Wasn't able to find page count, please set manually:"), 10);
}

// Scroll down page and load images
(function loop(i=0) {
if(i >= 200) return;
const MAX_PAGE_COUNT = 200;
if(i >= MAX_PAGE_COUNT) return;

scoreContainer.scrollTo(0, i * (scoreContainer.scrollHeight / pageCount));
setTimeout(() => {
// Find correct image
let loadedImages = [...scoreContainer.querySelectorAll("img")].map(e => e?.src);
let image = loadedImages.find(e => e.includes("score_" + i));

Expand Down
18 changes: 10 additions & 8 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* CONTENT SCRIPT */

// Ask background script to activate popup
// Activate popup
chrome.runtime.sendMessage({id: "msd-popup"});

// Inject script on button press from popup
Expand All @@ -13,22 +13,22 @@ chrome.runtime.onMessage.addListener(async request => {
}
});

// Start downloading PDF after data has finished loading from injected script
// Download PDF after injected script has gathered data
document.addEventListener("msd-ready", async e => {
let data = JSON.parse(e?.detail || "null");
let pageCount = data?.pageCount;
let urls = data?.urls;
let isPNG = /score_\d+.png/.test(data?.urls?.[0]);

// Error checking
// Check data for errors
if(!data || !pageCount || !urls?.length) {
if(confirm("Wasn't able to fetch data, please reload the page")) {
location.reload();
}
return;
}

// Create document and pipe it to a blob stream
// Create PDF document and pipe to blob stream
let doc = new PDFDocument({
autoFirstPage: false,
bufferPages: true,
Expand All @@ -37,7 +37,7 @@ document.addEventListener("msd-ready", async e => {
let stream = doc.pipe(blobStream());
let resCount = 0; // Keep track of current page count

// Loop trough urls, fetch images and add them to the document
// Loop URLs, fetch images, and add to document
for(let i=0; i<pageCount && i<urls.length; i++) {
chrome.runtime.sendMessage({
id: "msd-fetch",
Expand All @@ -46,21 +46,22 @@ document.addEventListener("msd-ready", async e => {
isPNG: isPNG
})
}, raw_fetchRes => {
// Check if an error occured
let fetchRes = JSON.parse(raw_fetchRes?.detail || "null");
if(!fetchRes || fetchRes.state === "error") {
return alert(fetchRes?.data);
}

// Add pages, and make sure they are in the right order
// Add page(s)
while(i >= doc.bufferedPageRange().count) doc.addPage();
doc.switchToPage(i);
resCount++;

// Handle image type
if(isPNG) doc.image(new Uint8Array(fetchRes.data).buffer, 0, 0, {fit: [595, 842]});
else SVGtoPDF(doc, fetchRes.data, 0, 0, {preserveAspectRatio: "16:9"});
resCount++;

// Send download request to background page
// Send download request to background script
if(resCount >= pageCount) {
doc.end();
stream.on("finish", () => {
Expand All @@ -70,6 +71,7 @@ document.addEventListener("msd-ready", async e => {
url: stream.toBlobURL("application/pdf")
})
}, raw_downloadRes => {
// Check if an error occured
let downloadRes = JSON.parse(raw_downloadRes?.detail || "null");
if(!downloadRes && downloadRes.state === "error") {
return alert(downloadRes?.data);
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Musescore Downloader",
"version": "1.0.0",
"version": "1.0.1",
"description": "Download PDFs from Musescore.",
"permissions": ["*://musescore.com/*", "*://s3.ultimate-guitar.com/*", "downloads"],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
Expand Down
1 change: 1 addition & 0 deletions popup/popup.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* POPUP SCRIPT */

window.onload = () => {
// Send message on button press
chrome.tabs.query({active: true, currentWindow: true}, tabs => {
let pdf = document.getElementById("pdf");
pdf.addEventListener("click", () => {
Expand Down

0 comments on commit f025f80

Please sign in to comment.