Added tidal as a service
This commit is contained in:
@@ -1,2 +1,8 @@
|
||||
[main]
|
||||
volume = integer(default=50)
|
||||
|
||||
[services]
|
||||
[[tidal]]
|
||||
username = string(default="")
|
||||
password = string(default="")
|
||||
quality=string(default="lossless")
|
@@ -96,7 +96,7 @@ class Controller(object):
|
||||
|
||||
# Event functions. These functions will call other functions in a thread and are bound to widget events.
|
||||
def on_search(self, *args, **kwargs):
|
||||
utils.call_threaded(self.search)
|
||||
wx.CallAfter(self.search)
|
||||
|
||||
def on_activated(self, *args, **kwargs):
|
||||
self.on_play()
|
||||
|
@@ -1,3 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: UTF-8 -*-
|
||||
from . import mailru, youtube, zaycev
|
||||
import config
|
||||
from . import mailru, youtube, zaycev
|
||||
# conditional imports
|
||||
if config.app["services"]["tidal"]["username"] != "" and config.app["services"]["tidal"]["password"] != "":
|
||||
from . import tidal
|
76
src/extractors/tidal.py
Normal file
76
src/extractors/tidal.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import tidalapi
|
||||
import config
|
||||
from .import baseFile
|
||||
from update.utils import seconds_to_string
|
||||
log = logging.getLogger("extractors.tidal.com")
|
||||
|
||||
class interface(object):
|
||||
name = "tidal"
|
||||
|
||||
def __init__(self):
|
||||
self.results = []
|
||||
self.needs_transcode = False
|
||||
log.debug("started extraction service for {0}".format(self.name,))
|
||||
if hasattr(tidalapi.Quality, config.app["services"]["tidal"]["quality"]):
|
||||
quality = getattr(tidalapi.Quality, config.app["services"]["tidal"]["quality"])
|
||||
else:
|
||||
quality = tidalapi.Quality.high
|
||||
_config = tidalapi.Config(quality=quality)
|
||||
username = config.app["services"]["tidal"]["username"]
|
||||
password = config.app["services"]["tidal"]["password"]
|
||||
log.debug("Using quality: %s" % (quality,))
|
||||
self.session = tidalapi.Session(config=_config)
|
||||
self.session.login(username=username, password=password)
|
||||
|
||||
def search(self, text, page=1):
|
||||
if text == "" or text == None:
|
||||
raise ValueError("Text must be passed and should not be blank.")
|
||||
log.debug("Retrieving data from Tidal...")
|
||||
fieldtypes = ["artist", "album", "playlist"]
|
||||
for i in fieldtypes:
|
||||
if text.startswith(i+"://"):
|
||||
field = i
|
||||
text = text.replace(i+"://", "")
|
||||
log.debug("Searching for %s..." % (field))
|
||||
search_response = self.session.search(value=text, field=field)
|
||||
self.results = []
|
||||
if field == "tracks":
|
||||
data = search_response.tracks
|
||||
elif field == "artist":
|
||||
data = []
|
||||
artist = search_response.artists[0].id
|
||||
albums = self.session.get_artist_albums(artist)
|
||||
for album in albums:
|
||||
tracks = self.session.get_album_tracks(album.id)
|
||||
for track in tracks:
|
||||
data.append(track)
|
||||
compilations = self.session.get_artist_albums_other(artist)
|
||||
for album in compilations:
|
||||
tracks = self.session.get_album_tracks(album.id)
|
||||
for track in tracks:
|
||||
data.append(track)
|
||||
singles = self.session.get_artist_albums_ep_singles(artist)
|
||||
for album in singles:
|
||||
tracks = self.session.get_album_tracks(album.id)
|
||||
for track in tracks:
|
||||
data.append(track)
|
||||
for search_result in data:
|
||||
s = baseFile.song(self)
|
||||
s.title = search_result.name
|
||||
s.artist = search_result.artist.name
|
||||
s.duration = seconds_to_string(search_result.duration)
|
||||
s.url = search_result.id
|
||||
self.results.append(s)
|
||||
|
||||
log.debug("{0} results found.".format(len(self.results)))
|
||||
|
||||
def get_download_url(self, url):
|
||||
url = self.session.get_media_url(url)
|
||||
if url.startswith("https://") or url.startswith("http://") == False:
|
||||
url = "rtmp://"+url
|
||||
return url
|
||||
|
||||
def format_track(self, item):
|
||||
return "{title}. {artist}. {duration}".format(title=item.title, duration=item.duration, artist=item.artist)
|
@@ -45,7 +45,7 @@ class mainWindow(wx.Frame):
|
||||
box.Add(lbl2, 0, wx.GROW)
|
||||
box.Add(self.text, 1, wx.GROW)
|
||||
box.Add(wx.StaticText(self.panel, wx.NewId(), _(u"Search in")), 0, wx.GROW)
|
||||
self.extractor = wx.ComboBox(self.panel, wx.NewId(), choices=["youtube", "mail.ru", "zaycev.net"], value="youtube", style=wx.CB_READONLY)
|
||||
self.extractor = wx.ComboBox(self.panel, wx.NewId(), choices=["youtube", "tidal", "mail.ru", "zaycev.net"], value="youtube", style=wx.CB_READONLY)
|
||||
box.Add(self.extractor, 1, wx.GROW)
|
||||
self.search = wx.Button(self.panel, wx.NewId(), _(u"Search"))
|
||||
self.search.SetDefault()
|
||||
|
Reference in New Issue
Block a user