Reverted back to crypted streams

This commit is contained in:
RemixDev 2021-07-20 14:44:20 +02:00
parent d80702e949
commit c007d39e15
No known key found for this signature in database
GPG Key ID: B33962B465BDB51C
3 changed files with 11 additions and 64 deletions

View File

@ -43,6 +43,7 @@ def streamTrack(outputStream, track, start=0, downloadObject=None, listener=None
if downloadObject.isCanceled: raise DownloadCanceled if downloadObject.isCanceled: raise DownloadCanceled
headers= {'User-Agent': USER_AGENT_HEADER} headers= {'User-Agent': USER_AGENT_HEADER}
chunkLength = start chunkLength = start
isCryptedStream = "/mobile/" in track.downloadUrl
itemData = { itemData = {
'id': track.id, 'id': track.id,
@ -53,6 +54,8 @@ def streamTrack(outputStream, track, start=0, downloadObject=None, listener=None
try: try:
with get(track.downloadUrl, headers=headers, stream=True, timeout=10) as request: with get(track.downloadUrl, headers=headers, stream=True, timeout=10) as request:
request.raise_for_status() request.raise_for_status()
if isCryptedStream:
blowfish_key = generateBlowfishKey(str(track.id))
complete = int(request.headers["Content-Length"]) complete = int(request.headers["Content-Length"])
if complete == 0: raise DownloadEmpty if complete == 0: raise DownloadEmpty
@ -77,6 +80,10 @@ def streamTrack(outputStream, track, start=0, downloadObject=None, listener=None
}) })
for chunk in request.iter_content(2048 * 3): for chunk in request.iter_content(2048 * 3):
if isCryptedStream:
if len(chunk) >= 2048:
chunk = decryptChunk(blowfish_key, chunk[0:2048]) + chunk[2048:]
outputStream.write(chunk) outputStream.write(chunk)
chunkLength += len(chunk) chunkLength += len(chunk)
@ -95,66 +102,6 @@ def streamTrack(outputStream, track, start=0, downloadObject=None, listener=None
sleep(2) sleep(2)
streamTrack(outputStream, track, start, downloadObject, listener) streamTrack(outputStream, track, start, downloadObject, listener)
def streamCryptedTrack(outputStream, track, start=0, downloadObject=None, listener=None):
if downloadObject.isCanceled: raise DownloadCanceled
headers= {'User-Agent': USER_AGENT_HEADER}
chunkLength = start
itemData = {
'id': track.id,
'title': track.title,
'artist': track.mainArtist.name
}
try:
with get(track.downloadUrl, headers=headers, stream=True, timeout=10) as request:
request.raise_for_status()
blowfish_key = str.encode(generateBlowfishKey(str(track.id)))
complete = int(request.headers["Content-Length"])
if complete == 0: raise DownloadEmpty
if start != 0:
responseRange = request.headers["Content-Range"]
if listener:
listener.send('downloadInfo', {
'uuid': downloadObject.uuid,
'data': itemData,
'state': "downloading",
'alreadyStarted': True,
'value': responseRange
})
else:
if listener:
listener.send('downloadInfo', {
'uuid': downloadObject.uuid,
'data': itemData,
'state': "downloading",
'alreadyStarted': False,
'value': complete
})
for chunk in request.iter_content(2048 * 3):
if len(chunk) >= 2048:
chunk = decryptChunk(blowfish_key, chunk[0:2048]) + chunk[2048:]
outputStream.write(chunk)
chunkLength += len(chunk)
if downloadObject:
if isinstance(downloadObject, Single):
chunkProgres = (chunkLength / (complete + start)) * 100
downloadObject.progressNext = chunkProgres
else:
chunkProgres = (len(chunk) / (complete + start)) / downloadObject.size * 100
downloadObject.progressNext += chunkProgres
downloadObject.updateProgress(listener)
except (SSLError, u3SSLError):
streamCryptedTrack(outputStream, track, chunkLength, downloadObject, listener)
except (RequestsConnectionError, ReadTimeout, ChunkedEncodingError):
sleep(2)
streamCryptedTrack(outputStream, track, start, downloadObject, listener)
class DownloadCanceled(Exception): class DownloadCanceled(Exception):
pass pass

View File

@ -24,7 +24,7 @@ from deemix.types.Picture import StaticPicture
from deemix.utils import USER_AGENT_HEADER from deemix.utils import USER_AGENT_HEADER
from deemix.utils.pathtemplates import generatePath, generateAlbumName, generateArtistName, generateDownloadObjectName from deemix.utils.pathtemplates import generatePath, generateAlbumName, generateArtistName, generateDownloadObjectName
from deemix.tagger import tagID3, tagFLAC from deemix.tagger import tagID3, tagFLAC
from deemix.decryption import generateStreamURL, streamTrack, DownloadCanceled from deemix.decryption import generateCryptedStreamURL, streamTrack, DownloadCanceled
from deemix.settings import OverwriteOption from deemix.settings import OverwriteOption
logger = logging.getLogger('deemix') logger = logging.getLogger('deemix')
@ -99,7 +99,7 @@ def getPreferredBitrate(track, bitrate, shouldFallback, uuid=None, listener=None
def testBitrate(track, formatNumber, formatName): def testBitrate(track, formatNumber, formatName):
request = requests.head( request = requests.head(
generateStreamURL(track.id, track.MD5, track.mediaVersion, formatNumber), generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, formatNumber),
headers={'User-Agent': USER_AGENT_HEADER}, headers={'User-Agent': USER_AGENT_HEADER},
timeout=30 timeout=30
) )
@ -342,7 +342,7 @@ class Downloader:
writepath = Path(currentFilename) writepath = Path(currentFilename)
if not trackAlreadyDownloaded or self.settings['overwriteFile'] == OverwriteOption.OVERWRITE: if not trackAlreadyDownloaded or self.settings['overwriteFile'] == OverwriteOption.OVERWRITE:
track.downloadUrl = generateStreamURL(track.id, track.MD5, track.mediaVersion, track.bitrate) track.downloadUrl = generateCryptedStreamURL(track.id, track.MD5, track.mediaVersion, track.bitrate)
try: try:
with open(writepath, 'wb') as stream: with open(writepath, 'wb') as stream:

View File

@ -20,7 +20,7 @@ def generateBlowfishKey(trackId):
bfKey = "" bfKey = ""
for i in range(16): for i in range(16):
bfKey += chr(ord(idMd5[i]) ^ ord(idMd5[i + 16]) ^ ord(SECRET[i])) bfKey += chr(ord(idMd5[i]) ^ ord(idMd5[i + 16]) ^ ord(SECRET[i]))
return bfKey return str.encode(bfKey)
def decryptChunk(key, data): def decryptChunk(key, data):
return Blowfish.new(key, Blowfish.MODE_CBC, b"\x00\x01\x02\x03\x04\x05\x06\x07").decrypt(data) return Blowfish.new(key, Blowfish.MODE_CBC, b"\x00\x01\x02\x03\x04\x05\x06\x07").decrypt(data)