-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1ddbc8e
commit 1671310
Showing
18 changed files
with
388 additions
and
500 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
from ak_requests import RequestsSession | ||
import brotli | ||
|
||
from jiosaavn.file_parser import Song | ||
import json | ||
|
||
from jiosaavn.utils import log | ||
|
||
class SaavnMe: | ||
BASEURL: str = 'https://saavn.me/' | ||
SESSION = RequestsSession() | ||
log.info('SaavnMe Instance Initialized') | ||
|
||
def __init__(self) -> None: | ||
self.SESSION.MIN_REQUEST_GAP = 1.5 #To prevent Ratelimit in free API | ||
|
||
def __str__(self) -> str: | ||
return 'Instance of SaavnMe class for saavn.me parser' | ||
|
||
def __repr__(self) -> str: | ||
return 'SaavnMe()' | ||
|
||
def playlist(self, id: int|str) -> list[Song]: | ||
"""Provides a list of Song dataclass from the playlist id""" | ||
log.info(f'Extracting Playlist Info with ID: {id}') | ||
url: str = f'{self.BASEURL}playlists?id={id}' | ||
_res = self.SESSION.get(url) | ||
try: | ||
data: dict = json.loads(_res.content)['data'] | ||
except Exception: | ||
data: dict = json.loads(brotli.decompress(_res.content))['data'] | ||
|
||
log.debug(f'Playlist: {data.get("name")}\nSongCount:{data.get("songCount")}\nFollowers:{data.get("followerCount")}\nURL:{data.get("url")}') | ||
|
||
return _parse_playlist_results( | ||
song_list=data['songs'] | ||
) | ||
|
||
def song(self, url: str) -> Song: | ||
"""Returns Song dataclass from provided jiosaavn url""" | ||
req_url: str = f'{self.BASEURL}songs?link={url}' | ||
log.info(f'Extracting Song from URL: {url}') | ||
data: dict = self.SESSION.get(req_url).json()['data'] | ||
return _parse_song_dict(song_dict=data) | ||
|
||
def _parse_song_dict(song_dict: dict) -> Song: | ||
# get media url | ||
download_urls: list[dict] = song_dict['downloadUrl'] | ||
_currentkbps: int = 0 | ||
media_url: str = '' | ||
|
||
for download_url in download_urls: | ||
__curr = int(download_url['quality'].replace('kbps','')) | ||
if __curr > _currentkbps: | ||
media_url = download_url['link'] | ||
_currentkbps = __curr | ||
|
||
#primary_artists | ||
primary_artists = song_dict['primaryArtists'].split(', ') | ||
|
||
# get image url | ||
urls: list[dict] = song_dict['image'] | ||
_currentkbps: int = 0 | ||
image_url: str = '' | ||
|
||
for url in urls: | ||
__curr = int(url['quality'].split('x')[0]) | ||
if __curr > _currentkbps: | ||
image_url = url['link'] | ||
_currentkbps = __curr | ||
|
||
return Song( | ||
song_id=song_dict['id'], | ||
name=song_dict['name'], | ||
album=song_dict['album']['name'], | ||
media_url=media_url, | ||
primary_artists=primary_artists, | ||
artists=primary_artists, | ||
year=int(song_dict['year']), | ||
image_url=image_url | ||
) | ||
|
||
def _parse_playlist_results(song_list: list[dict]) -> list[Song]: | ||
return [_parse_song_dict(song_dict) for song_dict in song_list] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .SaavnMe_Parser import SaavnMe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,101 @@ | ||
# Import WebClient from Python SDK (github.com/slackapi/python-slack-sdk) | ||
from slack_sdk import WebClient | ||
from slack_sdk.errors import SlackApiError | ||
from jiosaavn.credentials import getpwd | ||
|
||
class Slack_instance: | ||
from jiosaavn.utils import getpwd | ||
from jiosaavn.utils import log | ||
|
||
class Blocks: | ||
def __init__(self) -> None: | ||
self.DIVIDER = {"type": "divider"} | ||
|
||
def TEXT(self, text: str, img_url: str='', img_alt: str ='') -> dict: | ||
block = { | ||
"type": "section", | ||
"text": { "type": "mrkdwn", "text": text} | ||
} | ||
|
||
if img_url != '': | ||
block["accessory"] = { | ||
"type": "image", | ||
"image_url": img_url, | ||
"alt_text": img_alt | ||
} | ||
return block | ||
|
||
def IMAGE(self, img_url: str, alt_txt: str='', text: str='') -> dict: | ||
block: dict = { | ||
"type": "image", | ||
"image_url": img_url, | ||
"alt_text": alt_txt | ||
} | ||
|
||
if text != '': | ||
block['title'] = { | ||
"type": "plain_text", | ||
"text": text, | ||
"emoji": True | ||
} | ||
return block | ||
|
||
def HEADER(self, text: str) -> dict: | ||
return { | ||
"type": "header", | ||
"text": { | ||
"type": "plain_text", | ||
"text": text, | ||
"emoji": True | ||
} | ||
} | ||
|
||
class Slack: | ||
def __init__(self): | ||
#GetSlack | ||
self.client = WebClient(token=getpwd('Slack-pythonbot', 'token')) | ||
self.BLOCK = Blocks() | ||
log.info('Slack Instance Initialized') | ||
return | ||
|
||
# Destructor | ||
def __del__(self): | ||
return | ||
|
||
def do_actions(self): | ||
return 0 | ||
|
||
def __str__(self) -> str: | ||
return "SlackAPI Instance" | ||
|
||
def __repr__(self) -> str: | ||
return "Slack()" | ||
|
||
def channel_id(self, channel_name:str) -> str: | ||
"""Returns channel id for the specified channel name | ||
Args: | ||
channel_name (str): Name of the slack channel | ||
Returns: | ||
str: Channel ID | ||
""" | ||
return getpwd('Slack-pythonbot', channel_name) | ||
|
||
def init_block(self): | ||
self.block = [] | ||
return | ||
|
||
def msg(self, message:str, channel:str="python"): | ||
def msg(self, message:str, channel:str="python") -> int: | ||
"""Sends Slack message | ||
Args: | ||
message (str): Message to be sent | ||
channel (str, optional): Slack channel to send the message to. Defaults to "#python". | ||
""" | ||
err = 0 | ||
try: | ||
_ = self.client.chat_postMessage( | ||
channel=self.channel_id(channel), | ||
text=message) | ||
log.debug('Slack message sent') | ||
except SlackApiError as e: | ||
# You will get a SlackApiError if "ok" is False | ||
print(f'NG - Slack message not sent: {str(e)}') | ||
log.error(f'NG - Slack message not sent: {str(e)}') | ||
err = 1 | ||
return err | ||
|
||
|
||
def add_text(self, text, image_url=None,image_alt_text=""): | ||
"""Adds markdown element to block message | ||
Args: | ||
text (str): Text to display | ||
image_url (str, optional): Image to display. Defaults to None. | ||
image_alt_text (str, optional): Alt string for image. Defaults to "". | ||
""" | ||
if not image_url: | ||
self.block.append( | ||
{ | ||
"type": "section", | ||
"text": { "type": "mrkdwn", "text": text} | ||
}) | ||
else: | ||
self.block.append( | ||
{ | ||
"type": "section", | ||
"text": {"type": "mrkdwn", "text": text}, | ||
"accessory": { | ||
"type": "image", | ||
"image_url": image_url, | ||
"alt_text": image_alt_text | ||
} | ||
}) | ||
|
||
return | ||
|
||
def add_divider(self): | ||
"""Adds divider to the block message | ||
""" | ||
self.block.append({"type": "divider"}) | ||
return | ||
|
||
def post_block(self, channel): | ||
def post_block(self, channel: str, blocks: list[dict]): | ||
"""Posts the currently constructed block to slack chat | ||
Args: | ||
channel (str): Channel name | ||
""" | ||
err = 0 | ||
try: | ||
response = self.client.chat_postMessage(channel=self.channel_id(channel),blocks=self.block) | ||
_ = self.client.chat_postMessage(channel=self.channel_id(channel), | ||
blocks=blocks) | ||
log.debug('Slack block sent successfully') | ||
except SlackApiError as e: | ||
# You will get a SlackApiError if "ok" is False | ||
print(f'NG - Slack message not sent: {str(e)}') | ||
log.error(f'NG - Slack message not sent: {str(e)}') | ||
err = 1 | ||
return err |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,19 @@ | ||
"Placeholder module info" | ||
__version__ = "0.0.1" | ||
|
||
from jiosaavn.debugger import * | ||
from jiosaavn.utils import log, ic | ||
from jiosaavn.main import JiosaavnDownload | ||
|
||
|
||
log.info('Jiosaavn Module Initialized') | ||
|
||
ic.disable() | ||
ic.enable() # Comment this line out to enable debugger | ||
|
||
|
||
if ic.enabled: | ||
log.setLevel(10) #debug | ||
else: | ||
log.setLevel(20) #info | ||
|
||
log.debug(f'Icecream Debugger: {ic.enabled}') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.