Closed Aden720 closed 3 weeks ago
using an intermediate function to grab track id first then feed into a different url to request api seems to do the job.
I modified the resolve
function and added a new get_track_id
function in the SoundCloudAPI
class
do note that I did it on the async side in asyncio.py
, if you want to use the normal class then change it in sync.py
below is the code I changed for asyncio.py
import aiohttp
from bs4 import BeautifulSoup
async def resolve(self, url): # pylint: disable=invalid-overridden-method
""" Resolve an api url to a soundcloud object """
if not self.client_id:
await self.get_credentials()
full_url = f"https://api-v2.soundcloud.com/tracks?ids={await self.get_track_id(url)}&client_id={self.client_id}"
obj = await get_obj_from(full_url)
if not obj:
raise ValueError('Could not resolve url')
obj = obj[0]
if obj['kind'] == 'track':
return Track(obj=obj, client=self)
if obj['kind'] in ('playlist', 'system-playlist'):
playlist = Playlist(obj=obj, client=self)
await playlist.clean_attributes()
return playlist
# Getting the track ID
async def get_track_id(self, url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.text()
soup = BeautifulSoup(content, "html.parser")
track_id = soup.find("meta", property="twitter:app:url:googleplay")["content"].split(":")[-1]
return track_id
for a non-async in sync.py
:
def resolve(self, url):
""" Resolve url """
if not self.client_id:
self.get_credentials()
url = f"https://api-v2.soundcloud.com/tracks?ids={self.get_track_id(url)}&client_id={self.client_id}"
obj = get_obj_from(url)[0]
if obj['kind'] == 'track':
return Track(obj=obj, client=self)
if obj['kind'] in ('playlist', 'system-playlist'):
playlist = Playlist(obj=obj, client=self)
playlist.clean_attributes()
return playlist
return None
def get_track_id(self, url):
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
track_id = soup.find("meta", property="twitter:app:url:googleplay")["content"].split(":")[-1]
return track_id
Thanks for your response, is this a change you will be implementing to handle these URLs?
I opened a pull request #45 with a better solution since my solution above broke playlist links it simply tries to get the redirect url (soundcloud.com) from on.soundcloud links then feeds into the resolve url
on soundcloud mobile you can share a track or playlist, tapping copy link will generate a link with some metadata in it e.g. https://soundcloud.com/shift-key/on-my-mind -> https://on.soundcloud.com/QnSJh
when you navigate to one of these links it will send a http 302 with the full soundcloud url in the location header. currently passing one of these links to resolve raises a 404 error which I didn't expect
returns an error