piplongrun.github.io icon indicating copy to clipboard operation
piplongrun.github.io copied to clipboard

Update bookmarklet.js

Open fkick opened this issue 2 years ago • 108 comments

Bypasses the 403 Error Introduced with the latest Plex Media Server update.

fkick avatar Aug 02 '21 22:08 fkick

:+1: for this change.

The thing I've noticed is that the name of the file that is downloaded is always "file.mkv". In the past it was the same as the filename on the server.

isuelt avatar Aug 03 '21 12:08 isuelt

Would anyone be able to let me know how to implement @fkik's change to the bookmarklet?

I came across the 403 error today, but am not au fait with coding etc. Thanks!

trodscudgeon avatar Aug 05 '21 12:08 trodscudgeon

@trodscudgeon

Figured out myself through some exploring.

So to start... Right click the bookmark, hit edit. It will show you some javascript, you will see it in the URL area. Switch out the bookmarklet.js URL found in the code with this: https%3A%2F%2Fgithub.com%2Ffkick%2Fpiplongrun.github.io%2Fblob%2F09fb91a603c825cd2e2adc1f08c962ca258a3223%2Fplxdwnld%2Fbookmarklet.js%3Fts%3D That will link it to the updated file found here. Haven't fully tested it yet so there's a chance it might not work.

Suffice avatar Aug 06 '21 05:08 Suffice

@Suffice Hmmm. Tried according to your instructions, but not working. Thanks for replying and let me know if you figure it out!

trodscudgeon avatar Aug 07 '21 19:08 trodscudgeon

@Suffice Hmmm. Tried according to your instructions, but not working. Thanks for replying and let me know if you figure it out!

Paste this inside your bookmarklet

javascript:(function()%7B%2F***%20Download%20original%20files%20from%20the%20Plex%20web%20interface**%20This%20project%20is%20licensed%20under%20the%20terms%20of%20the%20MIT%20license%2C%20see%20https%3A%2F%2Fpiplongrun.github.io%2Fplxdwnld%2FLICENSE.txt**%20%40author%20%20%20%20%20%20Pip%20Longrun%20%3Cpip.longrun%40protonmail.com%3E*%20%40version%20%20%20%20%200.3*%20%40see%20%20%20%20%20%20%20%20%20https%3A%2F%2Fpiplongrun.github.io%2Fplxdwnld%2F**%2F%22use%20strict%22%3Bif%20(typeof%20plxDwnld%20%3D%3D%3D%20%22undefined%22)%20%7Bwindow.plxDwnld%20%3D%20(function()%20%7Bconst%20self%20%3D%20%7B%7D%3Bconst%20clientIdRegex%20%3D%20new%20RegExp(%22server%5C%2F(%5Ba-f0-9%5D%7B40%7D)%5C%2F%22)%3Bconst%20metadataIdRegex%20%3D%20new%20RegExp(%22key%3D%252Flibrary%252Fmetadata%252F(%5C%5Cd%2B)%22)%3Bconst%20apiResourceUrl%20%3D%20%22https%3A%2F%2Fplex.tv%2Fapi%2Fresources%3FincludeHttps%3D1%26X-Plex-Token%3D%7Btoken%7D%22%3Bconst%20apiLibraryUrl%20%3D%20%22%7Bbaseuri%7D%2Flibrary%2Fmetadata%2F%7Bid%7D%3FX-Plex-Token%3D%7Btoken%7D%22%3Bconst%20downloadUrl%20%3D%20%22%7Bbaseuri%7D%7Bpartkey%7D%3Fdownload%3D0%26X-Plex-Token%3D%7Btoken%7D%22%3Bconst%20accessTokenXpath%20%3D%20%22%2F%2FDevice%5B%40clientIdentifier%3D'%7Bclientid%7D'%5D%2F%40accessToken%22%3Bconst%20baseUriXpath%20%3D%20%22%2F%2FDevice%5B%40clientIdentifier%3D'%7Bclientid%7D'%5D%2FConnection%5B%40local%3D'0'%5D%2F%40uri%22%3Bconst%20partKeyXpath%20%3D%20%22%2F%2FMedia%2FPart%5B1%5D%2F%40key%22%3Blet%20accessToken%20%3D%20null%3Blet%20baseUri%20%3D%20null%3Bconst%20getXml%20%3D%20function(url%2C%20callback)%20%7Bconst%20request%20%3D%20new%20XMLHttpRequest()%3Brequest.onreadystatechange%20%3D%20function()%20%7Bif%20(request.readyState%20%3D%3D%204%20%26%26%20request.status%20%3D%3D%20200)%20%7Bcallback(request.responseXML)%3B%7D%7D%3Brequest.open(%22GET%22%2C%20url)%3Brequest.send()%3B%7D%3Bconst%20getMetadata%20%3D%20function(xml)%20%7Bconst%20clientId%20%3D%20clientIdRegex.exec(window.location.href)%3Bif%20(clientId%20%26%26%20clientId.length%20%3D%3D%202)%20%7Bconst%20accessTokenNode%20%3D%20xml.evaluate(accessTokenXpath.replace('%7Bclientid%7D'%2C%20clientId%5B1%5D)%2C%20xml%2C%20null%2C%20XPathResult.FIRST_ORDERED_NODE_TYPE%2C%20null)%3Bconst%20baseUriNode%20%3D%20xml.evaluate(baseUriXpath.replace('%7Bclientid%7D'%2C%20clientId%5B1%5D)%2C%20xml%2C%20null%2C%20XPathResult.FIRST_ORDERED_NODE_TYPE%2C%20null)%3Bif%20(accessTokenNode.singleNodeValue%20%26%26%20baseUriNode.singleNodeValue)%20%7BaccessToken%20%3D%20accessTokenNode.singleNodeValue.textContent%3BbaseUri%20%3D%20baseUriNode.singleNodeValue.textContent%3Bconst%20metadataId%20%3D%20metadataIdRegex.exec(window.location.href)%3Bif%20(metadataId%20%26%26%20metadataId.length%20%3D%3D%202)%20%7BgetXml(apiLibraryUrl.replace('%7Bbaseuri%7D'%2C%20baseUri).replace('%7Bid%7D'%2C%20metadataId%5B1%5D).replace('%7Btoken%7D'%2C%20accessToken)%2C%20getDownloadUrl)%3B%7D%20else%20%7Balert(%22You%20are%20currently%20not%20viewing%20a%20media%20item.%22)%3B%7D%7D%20else%20%7Balert(%22Cannot%20find%20a%20valid%20accessToken.%22)%3B%7D%7D%20else%20%7Balert(%22You%20are%20currently%20not%20viewing%20a%20media%20item.%22)%3B%7D%7D%3Bconst%20getDownloadUrl%20%3D%20function(xml)%20%7Bconst%20partKeyNode%20%3D%20xml.evaluate(partKeyXpath%2C%20xml%2C%20null%2C%20XPathResult.FIRST_ORDERED_NODE_TYPE%2C%20null)%3Bif%20(partKeyNode.singleNodeValue)%20%7Bwindow.location.href%20%3D%20downloadUrl.replace('%7Bbaseuri%7D'%2C%20baseUri).replace('%7Bpartkey%7D'%2C%20partKeyNode.singleNodeValue.textContent).replace('%7Btoken%7D'%2C%20accessToken)%3B%7D%20else%20%7Balert(%22You%20are%20currently%20not%20viewing%20a%20media%20item.%22)%3B%7D%7D%3Bself.init%20%3D%20function()%20%7Bif%20(typeof%20localStorage.myPlexAccessToken%20!%3D%20%22undefined%22)%20%7BgetXml(apiResourceUrl.replace('%7Btoken%7D'%2C%20localStorage.myPlexAccessToken)%2C%20getMetadata)%3B%7D%20else%20%7Balert(%22You%20are%20currently%20not%20browsing%20or%20logged%20into%20a%20Plex%20web%20environment.%22)%3B%7D%7D%3Breturn%20self%3B%7D)()%3B%7DplxDwnld.init()%7D)()

LampPrinter avatar Aug 09 '21 11:08 LampPrinter

👍 for this change.

The thing I've noticed is that the name of the file that is downloaded is always "file.mkv". In the past it was the same as the filename on the server.

Have you found out how to get it working correctly with naming?

Also it looks like the site where the javascript is located is down... It doesn't work at all now...

KasperSvendsenGit avatar Aug 28 '21 13:08 KasperSvendsenGit

I tried this locally and the change results in a response of "400 Bad Request" rather than a "403 Forbidden" so it seems that another way to download needs to be discovered

edit: it dawned on me that the 400 may be because i was hosting locally as http instead of https. so that may have something to do with it.

twillis avatar Aug 28 '21 18:08 twillis

Hopefully this all gets resolved soon, my friend has shared their library with me so I can become a wannabe datahoarder lol

@piplongrun The website is down atm. please bring it back up!!!

KasperSvendsenGit avatar Aug 28 '21 19:08 KasperSvendsenGit

Also it looks like the site where the javascript is located is down... It doesn't work at all now...

Use the code in @LampPrinter 's post for the download - no need for an external server.

Have you found out how to get it working correctly with naming?

As far as the filename issue, I've been thinking about coding a Tampermonkey / GreaseMoney script in the browser that scrapes the Plex media page and copies the name into the clipboard. I've procrastinated doing it because I don't use this download method much. Maybe I'll get some time over the next weekend or two and see what I could slap together.

isuelt avatar Aug 30 '21 18:08 isuelt

Hopefully this all gets resolved soon, my friend has shared their library with me so I can become a wannabe datahoarder lol

@piplongrun The website is down atm. please bring it back up!!!

Use the code in @LampPrinter 's post for the download - no need for an external server.

isuelt avatar Aug 30 '21 18:08 isuelt

@isuelt @LampPrinter Is it possible that the new web layout screwed with the script?

It's not working on my end :/

Bockiii avatar Sep 13 '21 11:09 Bockiii

Oh... ignore half of that. It works one one server but doesnt on the other. So maybe the other server is behind 7 proxies.

Bockiii avatar Sep 13 '21 11:09 Bockiii

It's more likely to be due to this change in Plex Media Server 1.23.6.4881 and later:

NEW:

  • (Downloads) Download access now enforced on the server via shared user settings (#12859)

ticky avatar Sep 13 '21 18:09 ticky

its not working because the piplong.run site is down, the bookmarklet relies on the site to work so until then you can use this code instead (you can change it in chrome by right clicking it and pressing edit and changing the URL field to:

javascript:(function()%7B%2F**%0A * Download original files from the Plex web interface%0A *%0A * This project is licensed under the terms of the MIT license%2C see https%3A%2F%2Fpiplongrun.github.io%2Fplxdwnld%2FLICENSE.txt%0A *%0A * %40author Pip Longrun <pip.longrun%40protonmail.com>%0A * %40version 0.3%0A * %40see https%3A%2F%2Fpiplongrun.github.io%2Fplxdwnld%2F%0A *%0A *%2F%0A"use strict"%3B%0A%0Aif (typeof plxDwnld %3D%3D%3D "undefined") %7B%0A%0A window.plxDwnld %3D (function() %7B%0A%0A const self %3D %7B%7D%3B%0A const clientIdRegex %3D new RegExp("server%5C%2F(%5Ba-f0-9%5D%7B40%7D)%5C%2F")%3B%0A const metadataIdRegex %3D new RegExp("key%3D%252Flibrary%252Fmetadata%252F(%5C%5Cd%2B)")%3B%0A const apiResourceUrl %3D "https%3A%2F%2Fplex.tv%2Fapi%2Fresources%3FincludeHttps%3D1%26X-Plex-Token%3D%7Btoken%7D"%3B%0A const apiLibraryUrl %3D "%7Bbaseuri%7D%2Flibrary%2Fmetadata%2F%7Bid%7D%3FX-Plex-Token%3D%7Btoken%7D"%3B%0A const downloadUrl %3D "%7Bbaseuri%7D%7Bpartkey%7D%3Fdownload%3D1%26X-Plex-Token%3D%7Btoken%7D"%3B%0A const accessTokenXpath %3D "%2F%2FDevice%5B%40clientIdentifier%3D'%7Bclientid%7D'%5D%2F%40accessToken"%3B%0A const baseUriXpath %3D "%2F%2FDevice%5B%40clientIdentifier%3D'%7Bclientid%7D'%5D%2FConnection%5B%40local%3D'0'%5D%2F%40uri"%3B%0A const partKeyXpath %3D "%2F%2FMedia%2FPart%5B1%5D%2F%40key"%3B%0A let accessToken %3D null%3B%0A let baseUri %3D null%3B%0A%0A const getXml %3D function(url%2C callback) %7B%0A const request %3D new XMLHttpRequest()%3B%0A request.onreadystatechange %3D function() %7B%0A if (request.readyState %3D%3D 4 %26%26 request.status %3D%3D 200) %7B%0A callback(request.responseXML)%3B%0A %7D%0A %7D%3B%0A request.open("GET"%2C url)%3B%0A request.send()%3B%0A %7D%3B%0A%0A const getMetadata %3D function(xml) %7B%0A const clientId %3D clientIdRegex.exec(window.location.href)%3B%0A%0A if (clientId %26%26 clientId.length %3D%3D 2) %7B%0A const accessTokenNode %3D xml.evaluate(accessTokenXpath.replace('%7Bclientid%7D'%2C clientId%5B1%5D)%2C xml%2C null%2C XPathResult.FIRST_ORDERED_NODE_TYPE%2C null)%3B%0A const baseUriNode %3D xml.evaluate(baseUriXpath.replace('%7Bclientid%7D'%2C clientId%5B1%5D)%2C xml%2C null%2C XPathResult.FIRST_ORDERED_NODE_TYPE%2C null)%3B%0A%0A if (accessTokenNode.singleNodeValue %26%26 baseUriNode.singleNodeValue) %7B%0A accessToken %3D accessTokenNode.singleNodeValue.textContent%3B%0A baseUri %3D baseUriNode.singleNodeValue.textContent%3B%0A const metadataId %3D metadataIdRegex.exec(window.location.href)%3B%0A%0A if (metadataId %26%26 metadataId.length %3D%3D 2) %7B%0A getXml(apiLibraryUrl.replace('%7Bbaseuri%7D'%2C baseUri).replace('%7Bid%7D'%2C metadataId%5B1%5D).replace('%7Btoken%7D'%2C accessToken)%2C getDownloadUrl)%3B%0A %7D else %7B%0A alert("You are currently not viewing a media item.")%3B%0A %7D%0A %7D else %7B%0A alert("Cannot find a valid accessToken.")%3B%0A %7D%0A %7D else %7B%0A alert("You are currently not viewing a media item.")%3B%0A %7D%0A %7D%3B%0A%0A const getDownloadUrl %3D function(xml) %7B%0A const partKeyNode %3D xml.evaluate(partKeyXpath%2C xml%2C null%2C XPathResult.FIRST_ORDERED_NODE_TYPE%2C null)%3B%0A%0A if (partKeyNode.singleNodeValue) %7B%0A window.location.href %3D downloadUrl.replace('%7Bbaseuri%7D'%2C baseUri).replace('%7Bpartkey%7D'%2C partKeyNode.singleNodeValue.textContent).replace('%7Btoken%7D'%2C accessToken)%3B%0A %7D else %7B%0A alert("You are currently not viewing a media item.")%3B%0A %7D%0A %7D%3B%0A%0A self.init %3D function() %7B%0A if (typeof localStorage.myPlexAccessToken !%3D "undefined") %7B%0A getXml(apiResourceUrl.replace('%7Btoken%7D'%2C localStorage.myPlexAccessToken)%2C getMetadata)%3B%0A %7D else %7B%0A alert("You are currently not browsing or logged into a Plex web environment.")%3B%0A %7D%0A %7D%3B%0A%0A return self%3B%0A %7D)()%3B%0A%7D%0A%0AplxDwnld.init()%3B%7D)()%3B

nmcc1212 avatar Sep 13 '21 18:09 nmcc1212

Hello! Why does it work on one server but not the other?

mateussaa avatar Sep 23 '21 21:09 mateussaa

It's more likely to be due to this change in Plex Media Server 1.23.6.4881 and later:

NEW:

  • (Downloads) Download access now enforced on the server via shared user settings (#12859)

Again, it sometimes doesn't work even if you correct the source because some servers will have updated to this version where Plex blocked it.

ticky avatar Sep 23 '21 22:09 ticky

It's more likely to be due to this change in Plex Media Server 1.23.6.4881 and later:

NEW:

  • (Downloads) Download access now enforced on the server via shared user settings (#12859)

Again, it sometimes doesn't work even if you correct the source because some servers will have updated to this version where Plex blocked it.

Thanks for the reply! Do you think Plex will get a new update where it will let users do this as before?

mateussaa avatar Sep 23 '21 22:09 mateussaa

I doubt it, you're probably going to have to talk to the administrators of the Plex instances you want to download from about permitting downloads.

ticky avatar Sep 23 '21 22:09 ticky

You mean talking to the person that's sharing the server? I got them to enable the ''Allow Downloads'' option, but still nothing. And with another server that the person didn't enabled this option, the code works. Really weird.

mateussaa avatar Sep 23 '21 22:09 mateussaa

It's not weird. The code used a bug with the software, enabling you to download from servers who specifically did not enable downloading. The new update fixed that bug, now you need the admin to enable downloads and use the plex functionality

Bockiii avatar Sep 23 '21 22:09 Bockiii

I got the option to download enabled from the server owner! But the button does not appear to me. Is it a Plex Pass only thing? Or with a regular account I could still download and watch it offline on the Plex app/browser page.

mateussaa avatar Sep 23 '21 23:09 mateussaa

Any chance the website could be recovered? Would be great :) this script has always been great, the script above is good too but it doesn't name the file.

Juzzotec avatar Oct 01 '21 23:10 Juzzotec

@Juzzotec use the code from my earlier comment, it still works

nmcc1212 avatar Oct 02 '21 12:10 nmcc1212

@Juzzotec use the code from my earlier comment, it still works

Man, to call you a legend would be an understatement. I love this script and you brought it back to life. Thank you x100... keep plxdwnld alive ❤️

Juzzotec avatar Oct 02 '21 23:10 Juzzotec

@Juzzotec use the code from my earlier comment, it still works

'403 Forbidden' error for me.

mateussaa avatar Oct 03 '21 00:10 mateussaa

if you copy the code and put it in the dev console (f12 on chrome) does that work?

nmcc1212 avatar Oct 03 '21 00:10 nmcc1212

if you copy the code and put it in the dev console (f12 on chrome) does that work?

I did not tried that way. I just edit the bookmark code and press on it with a movie opened on Plex.

How do I do it?

mateussaa avatar Oct 03 '21 00:10 mateussaa

@mateussaa copy the all code from plxdwnld/bookmarklet.js and paste it into the dev console

nmcc1212 avatar Oct 03 '21 16:10 nmcc1212

@nmcc1212 It doesn't work. I tried on Mozilla by editing the bookmarklet and I get a '403 Forbidden'. And it doesn't work by copying and pasting too.

mateussaa avatar Oct 04 '21 13:10 mateussaa

@mateussaa try using this: http://nmcc1212.github.io/ it is a backup of the old site, if it doesn't work ill try the code from this PR

nmcc1212 avatar Oct 04 '21 14:10 nmcc1212