Ejemplo n.º 1
0
def __downloadTrack__(conf, track, album=None, playlist=None):
    msg, stream = API.getStreamUrl(track.id, conf.audioQuality)
    if not isNull(msg):
        Printf.err(track.title + "." + msg)
        return
    path = __getTrackPath__(conf, track, stream, album, playlist)

    # Printf.info("Download \"" + track.title + "\" Codec: " + stream.codec)
    check, err = downloadFileRetErr(stream.url,
                                    path + '.part',
                                    showprogress=True,
                                    stimeout=20)
    if not check:
        Printf.err("\n Download failed!" + getFileName(path))
        return
    # encrypted -> decrypt and remove encrypted file
    if isNull(stream.encryptionKey):
        os.replace(path + '.part', path)
    else:
        key, nonce = decrypt_security_token(stream.encryptionKey)
        decrypt_file(path + '.part', path, key, nonce)
        os.remove(path + '.part')

    path = __convertToM4a__(path, stream.codec)
    __setMetaData__(track, album, path)
    Printf.success(getFileName(path))
Ejemplo n.º 2
0
def searchTrack(user, lang, field, song, conf):
    __loadAPI__(user)

    msg, obj = API.searchSong(field, song, limit=10)

    for item in obj:
        if field == 'track':
            print(
                green(f"Enter [{obj.index(item)}]: ") +
                f"{item.title} - {item.artist.name} - {item.album.title}")
        elif field == 'album':
            print(
                green(f"Enter [{obj.index(item)}]: ") +
                f"{item.title} - {item.artist.name}")
        else:
            print(
                green(f"Enter [{obj.index(item)}]: ") +
                f"{item.title} - {item.numberOfTracks} Songs")

    try:
        choice = int(Printf.enter(lang))
        if (choice >= 0 and choice < len(obj)):
            if field == 'track':
                __track__(conf, obj[choice])
            elif field == 'album':
                __album__(conf, obj[choice])
            else:
                __playlist__(conf, obj[choice])
        else:
            os.system('clear')
            Printf.err("Invalid option!")
    except ValueError:
        os.system('clear')
        Printf.err("Invalid option!")
Ejemplo n.º 3
0
def start(user, conf, string):
    __loadAPI__(user)
    if aigpy.string.isNull(string):
        Printf.err('Please enter something.')
        return

    strings = string.split(" ")
    for item in strings:
        if aigpy.string.isNull(item):
            continue
        if os.path.exists(item):
            __file__(user, conf, item)
            return

        msg, etype, obj = API.getByString(item)
        if etype == Type.Null or not aigpy.string.isNull(msg):
            Printf.err(msg + " [" + item + "]")
            return

        if etype == Type.Album:
            __album__(conf, obj)
        if etype == Type.Track:
            __track__(conf, obj)
        if etype == Type.Video:
            __loadVideoAPI__(user)
            __video__(conf, obj)
        if etype == Type.Artist:
            __artist__(conf, obj)
        if etype == Type.Playlist:
            __playlist__(conf, obj)
Ejemplo n.º 4
0
def checkLogin():
    if not isNull(TOKEN.accessToken):
        #print('Checking Access Token...') #add to translations
        msg, check = API.verifyAccessToken(TOKEN.accessToken)
        if check == True:
            Printf.info(
                LANG.MSG_VALID_ACCESSTOKEN.format(
                    displayTime(int(TOKEN.expiresAfter - time.time()))))
            return
        else:
            Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
            msg, check = API.refreshAccessToken(TOKEN.refreshToken)
            if check == True:
                Printf.success(
                    LANG.MSG_VALID_ACCESSTOKEN.format(
                        displayTime(int(API.key.expiresIn))))
                TOKEN.userid = API.key.userId
                TOKEN.countryCode = API.key.countryCode
                TOKEN.accessToken = API.key.accessToken
                TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
                TokenSettings.save(TOKEN)
                return
            else:
                Printf.err(msg)
                tmp = TokenSettings()  #clears saved tokens
                TokenSettings.save(tmp)
    login()
    return
Ejemplo n.º 5
0
def __artist__(conf, obj):
    msg, albums = API.getArtistAlbums(obj.id, conf.includeEP)
    Printf.artist(obj, len(albums))
    if not isNull(msg):
        Printf.err(msg)
        return
    for item in albums:
        __album__(conf, item)
Ejemplo n.º 6
0
def __downloadVideo__(conf, video, album=None, playlist=None):
    msg, stream = API.getVideoStreamUrl(video.id, conf.videoQuality)
    if not isNull(msg):
        Printf.err(video.title + "." + msg)
        return
    path = __getVideoPath__(conf, video, album, playlist)
    if m3u8Helper.download(stream.m3u8Url, path):
        Printf.success(getFileName(path))
    else:
        Printf.err("\nDownload failed!" + getFileName(path))
Ejemplo n.º 7
0
def checkLogin():
    if not isNull(USER.assesstoken):
        mag, check = API.loginByAccessToken(USER.assesstoken)
        if check == False:
            Printf.err(LANG.MSG_INVAILD_ACCESSTOKEN)
    if not isNull(USER.sessionid1) and not API.isValidSessionID(USER.userid, USER.sessionid1):
        USER.sessionid1 = ""
    if not isNull(USER.sessionid2) and API.isValidSessionID(USER.userid, USER.sessionid2):
        USER.sessionid2 = ""
    if isNull(USER.sessionid1) or isNull(USER.sessionid2):
        login(USER.username, USER.password)
Ejemplo n.º 8
0
def __album__(conf, obj):
    Printf.album(obj)
    msg, tracks, videos = API.getItems(obj.id, Type.Album)
    if not isNull(msg):
        Printf.err(msg)
        return
    if conf.saveCovers:
        __downloadCover__(conf, obj)
    for item in tracks:
        __downloadTrack__(conf, item, obj)
    for item in videos:
        __downloadVideo__(conf, item, obj)
Ejemplo n.º 9
0
def __playlist__(conf, obj):
    Printf.playlist(obj)
    msg, tracks, videos = API.getItems(obj.id, Type.Playlist)
    if not isNull(msg):
        Printf.err(msg)
        return

    for item in tracks:
        mag, album = API.getAlbum(item.album.id)
        __downloadTrack__(conf, item, album)
    for item in videos:
        __downloadVideo__(conf, item, None)
def login():
    print(LANG.AUTH_START_LOGIN)
    msg, check = API.getDeviceCode()
    if not check:
        Printf.err(msg)
        return

    # print(LANG.AUTH_LOGIN_CODE.format(green(API.key.userCode)))
    print(LANG.AUTH_NEXT_STEP.format(green("http://" + API.key.verificationUrl + "/" + API.key.userCode), yellow(displayTime(API.key.authCheckTimeout))))
    print(LANG.AUTH_WAITING)
    loginByWeb()
    return
Ejemplo n.º 11
0
def main():
    if len(sys.argv) > 1:
        mainCommand()
        return

    Printf.logo()
    Printf.settings(CONF)

    checkLogin()

    onlineVer = getLastVersion('tidal-dl')
    if not isNull(onlineVer):
        icmp = cmpVersion(onlineVer, VERSION)
        if icmp > 0:
            Printf.info(LANG.PRINT_LATEST_VERSION + ' ' + onlineVer)

    while True:
        Printf.choices()
        raw = Printf.enter(LANG.PRINT_ENTER_CHOICE).strip()

        choice = int(re.sub('[^0-9]', '', raw))
        if choice == 0:
            return
        elif choice == 1:
            checkLogin()
        elif choice == 2:
            changeSettings()
        elif choice == 3:
            checkLogout()
        elif choice == 4:
            Printf.searchTypes()

            searchRaw = Printf.enter(LANG.PRINT_ENTER_CHOICE).strip()

            searchType = int(re.sub('[^0-9]', '', searchRaw))

            if (searchType == 3):
                searchRaw = Printf.enter("Enter a url or id: ").strip()
                start(TOKEN, CONF, searchRaw)
                return

            field = "track" if searchType == 0 else 'album' if searchType == 1 else 'playlist'

            if searchType >= 0 and searchType <= 2:
                song = Printf.enter("Enter the song name: ")
                searchTrack(TOKEN, LANG.PRINT_ENTER_CHOICE, field, song, CONF)
            else:
                os.system('clear')
                Printf.err("Invalid option!")
        else:
            os.system('clear')
            Printf.err("Invalid option!")
Ejemplo n.º 12
0
def __playlist__(conf, obj):
    Printf.playlist(obj)
    msg, tracks, videos = API.getItems(obj.uuid, Type.Playlist)
    if not isNull(msg):
        Printf.err(msg)
        return

    for index, item in enumerate(tracks):
        mag, album = API.getAlbum(item.album.id)
        item.trackNumberOnPlaylist = index + 1
        __downloadTrack__(conf, item, album, obj)
    for item in videos:
        __downloadVideo__(conf, item, None)
Ejemplo n.º 13
0
def __downloadVideo__(conf, video, album=None, playlist=None):
    msg, stream = API.getVideoStreamUrl(video.id, conf.videoQuality)
    if not aigpy.string.isNull(msg):
        Printf.err(video.title + "." + msg)
        return
    path = __getVideoPath__(conf, video, album, playlist)

    logging.info("[DL Video] name=" + aigpy.path.getFileName(path) + "\nurl=" +
                 stream.m3u8Url)
    if aigpy.m3u8.download(stream.m3u8Url, path):
        Printf.success(aigpy.path.getFileName(path))
    else:
        Printf.err("\nDownload failed!" + aigpy.path.getFileName(path))
Ejemplo n.º 14
0
def __album__(conf, obj):
    Printf.album(obj)
    msg, tracks, videos = API.getItems(obj.id, Type.Album)
    if not isNull(msg):
        Printf.err(msg)
        return
    # if conf.saveCovers:
    #    __downloadCover__(conf, obj)
    for item in tracks:
        if (Blueberry.should_break()):
            Blueberry.set_break_status(False)
            break
        __downloadTrack__(conf, item, obj)
Ejemplo n.º 15
0
def __album__(conf, obj):
    Printf.album(obj)
    msg, tracks, videos = API.getItems(obj.id, Type.Album)
    if not aigpy.string.isNull(msg):
        Printf.err(msg)
        return
    if conf.saveAlbumInfo:
        __saveAlbumInfo__(conf, obj, tracks)
    if conf.saveCovers:
        __downloadCover__(conf, obj)
    for item in tracks:
        downloadTrack(item, obj)
    for item in videos:
        downloadVideo(item, obj)
Ejemplo n.º 16
0
def setAccessToken():
    while True:
        print("-------------AccessToken---------------")
        token = Printf.enter("accessToken('0' go back):")
        if token == '0':
            return
        msg, check = API.loginByAccessToken(token, USER.userid)
        if check == False:
            Printf.err(msg)
            continue
        break

    USER.assesstoken = token
    UserSettings.save(USER)
Ejemplo n.º 17
0
def __playlist__(conf, obj):
    Printf.playlist(obj)
    msg, tracks, videos = API.getItems(obj.uuid, Type.Playlist)
    if not isNull(msg):
        Printf.err(msg)
        return

    for index, item in enumerate(tracks):
        if (Blueberry.should_break()):
            Blueberry.set_break_status(False)
            break
        mag, album = API.getAlbum(item.album.id)
        item.trackNumberOnPlaylist = index + 1
        __downloadTrack__(conf, item, album, obj)
Ejemplo n.º 18
0
def __file__(user, conf, string):
    txt = getFileContent(string)
    if isNull(txt):
        Printf.err("Nothing can read!")
        return
    array = txt.split('\n')
    for item in array:
        if isNull(item):
            continue
        if item[0] == '#':
            continue
        if item[0] == '[':
            continue
        start(user, conf, item)
Ejemplo n.º 19
0
def downloadVideo(video: Video, album=None, playlist=None):
    msg, stream = API.getVideoStreamUrl(video.id, CONF.videoQuality)
    Printf.video(video, stream)
    if not aigpy.string.isNull(msg):
        Printf.err(video.title + "." + msg)
        return False, msg
    path = getVideoPath(CONF, video, album, playlist)

    logging.info("[DL Video] name=" + aigpy.path.getFileName(path) + "\nurl=" +
                 stream.m3u8Url)
    m3u8content = requests.get(stream.m3u8Url).content
    if m3u8content is None:
        Printf.err(video.title + ' get m3u8 content failed.')
        return False, "Get m3u8 content failed"

    urls = aigpy.m3u8.parseTsUrls(m3u8content)
    if len(urls) <= 0:
        Printf.err(video.title + ' parse ts urls failed.')
        logging.info("[DL Video] title=" + video.title + "\m3u8Content=" +
                     str(m3u8content))
        return False, 'Parse ts urls failed.'

    check, msg = aigpy.m3u8.downloadByTsUrls(urls, path)
    # check, msg = aigpy.m3u8.download(stream.m3u8Url, path)
    if check is True:
        Printf.success(aigpy.path.getFileName(path))
        return True, ''
    else:
        Printf.err("\nDownload failed!" + msg + '(' +
                   aigpy.path.getFileName(path) + ')')
        return False, msg
Ejemplo n.º 20
0
def file(user, conf, string):
    txt = aigpy.file.getContent(string)
    if aigpy.string.isNull(txt):
        Printf.err("Nothing can read!")
        return
    array = txt.split('\n')
    for item in array:
        if aigpy.string.isNull(item):
            continue
        if item[0] == '#':
            continue
        if item[0] == '[':
            continue
        start(user, conf, item)
Ejemplo n.º 21
0
def __playlist__(conf, obj):
    Printf.playlist(obj)
    msg, tracks, videos = API.getItems(obj.uuid, Type.Playlist)
    if not aigpy.string.isNull(msg):
        Printf.err(msg)
        return

    for index, item in enumerate(tracks):
        mag, album = API.getAlbum(item.album.id)
        item.trackNumberOnPlaylist = index + 1
        downloadTrack(item, album, obj)
        if conf.saveCovers and not conf.usePlaylistFolder:
            __downloadCover__(conf, album)
    for item in videos:
        downloadVideo(item, None)
Ejemplo n.º 22
0
def start(user, conf, string):
    __loadAPI__(user)

    msg, etype, obj = API.getByString(string)
    if etype == Type.Null or not isNull(msg):
        Printf.err(msg)
        return

    if etype == Type.Album:
        __album__(conf, obj)
    if etype == Type.Track:
        __track__(conf, obj)
    if etype == Type.Video:
        __loadVideoAPI__(user)
        __video__(conf, obj)
    if etype == Type.Artist:
        __artist__(conf, obj)
    if etype == Type.Playlist:
        __playlist__(conf, obj)
Ejemplo n.º 23
0
def mainCommand():
    try:
        opts, args = getopt.getopt(
            sys.argv[1:], "hvl:o:q:r:",
            ["help", "version", "link=", "output=", "quality", "resolution"])
    except getopt.GetoptError as errmsg:
        Printf.err(vars(errmsg)['msg'] + ". Use 'tidal-dl -h' for useage.")
        return

    link = None
    for opt, val in opts:
        if opt in ('-h', '--help'):
            Printf.usage()
            continue
        if opt in ('-v', '--version'):
            Printf.logo()
            continue
        if opt in ('-l', '--link'):
            checkLogin()
            link = val
            continue
        if opt in ('-o', '--output'):
            CONF.downloadPath = val
            Settings.save(CONF)
            continue
        if opt in ('-q', '--quality'):
            CONF.audioQuality = Settings.getAudioQuality(val)
            Settings.save(CONF)
            continue
        if opt in ('-r', '--resolution'):
            CONF.videoQuality = Settings.getVideoQuality(val)
            Settings.save(CONF)
            continue

    if not mkdirs(CONF.downloadPath):
        Printf.err(LANG.MSG_PATH_ERR + CONF.downloadPath)
        return

    if link is not None:
        Printf.info(LANG.SETTING_DOWNLOAD_PATH + ':' + CONF.downloadPath)
        start(TOKEN, CONF, link)
Ejemplo n.º 24
0
def setAccessToken():
    while True:
        print("-------------AccessToken---------------")
        token = Printf.enter("accessToken('0' go back):")
        if token == '0':
            return
        msg, check = API.loginByAccessToken(token, TOKEN.userid)
        if check == False:
            Printf.err(msg)
            continue
        break

    print("-------------RefreshToken---------------")
    refreshToken = Printf.enter("refreshToken('0' to skip):")
    if refreshToken == '0':
        refreshToken = TOKEN.refreshToken

    TOKEN.assesstoken = token
    TOKEN.refreshToken = refreshToken
    TOKEN.expiresAfter = 0
    TokenSettings.save(TOKEN)
Ejemplo n.º 25
0
def changeSettings():
    Printf.settings(CONF)
    choice = Printf.enter(LANG.CHANGE_START_SETTINGS)
    if choice == '0':
        return

    while True:
        choice = Printf.enter(LANG.CHANGE_DOWNLOAD_PATH)
        if choice == '0':
            choice = CONF.downloadPath
        elif not os.path.isdir(choice):
            if not mkdirs(choice):
                Printf.err(LANG.MSG_PATH_ERR)
                continue
        CONF.downloadPath = choice
        break
    while True:
        choice = Printf.enter(LANG.CHANGE_AUDIO_QUALITY)
        if choice != '1' and choice != '2' and choice != '3' and choice != '0':
            Printf.err(LANG.MSG_INPUT_ERR)
            continue
        if choice == '0':
            CONF.audioQuality = AudioQuality.Normal
        if choice == '1':
            CONF.audioQuality = AudioQuality.High
        if choice == '2':
            CONF.audioQuality = AudioQuality.HiFi
        if choice == '3':
            CONF.audioQuality = AudioQuality.Master
        break
    while True:
        choice = Printf.enter(LANG.CHANGE_VIDEO_QUALITY)
        if choice != '1' and choice != '2' and choice != '3' and choice != '0':
            Printf.err(LANG.MSG_INPUT_ERR)
            continue
        if choice == '0':
            CONF.videoQuality = VideoQuality.P1080
        if choice == '1':
            CONF.videoQuality = VideoQuality.P720
        if choice == '2':
            CONF.videoQuality = VideoQuality.P480
        if choice == '3':
            CONF.videoQuality = VideoQuality.P360
        break
    CONF.onlyM4a = Printf.enter(LANG.CHANGE_ONLYM4A) == '1'
    CONF.addExplicitTag = Printf.enter(LANG.CHANGE_ADD_EXPLICIT_TAG) == '1'
    CONF.addHyphen = Printf.enter(LANG.CHANGE_ADD_HYPHEN) == '1'
    CONF.addYear = Printf.enter(LANG.CHANGE_ADD_YEAR) == '1'
    CONF.useTrackNumber = Printf.enter(LANG.CHANGE_USE_TRACK_NUM) == '1'
    CONF.checkExist = Printf.enter(LANG.CHANGE_CHECK_EXIST) == '1'
    CONF.artistBeforeTitle = Printf.enter(
        LANG.CHANGE_ARTIST_BEFORE_TITLE) == '1'
    CONF.includeEP = Printf.enter(LANG.CHANGE_INCLUDE_EP) == '1'
    CONF.addAlbumIDBeforeFolder = Printf.enter(
        LANG.CHANGE_ALBUMID_BEFORE_FOLDER) == '1'
    CONF.saveCovers = Printf.enter(LANG.CHANGE_SAVE_COVERS) == '1'
    CONF.language = Printf.enter(LANG.CHANGE_LANGUAGE)

    LANG = setLang(CONF.language)
    Settings.save(CONF)
Ejemplo n.º 26
0
def login():
    print(LANG.AUTH_START_LOGIN)
    msg, check = API.getDeviceCode()
    if check == False:
        Printf.err(msg)
        return

    print(LANG.AUTH_LOGIN_CODE.format(green(API.key.userCode)))
    print(LANG.AUTH_NEXT_STEP.format(green(API.key.verificationUrl), yellow(displayTime(API.key.authCheckTimeout))))
    print(LANG.AUTH_WAITING)
    start = time.time()
    elapsed = 0
    while elapsed < API.key.authCheckTimeout:
        elapsed = time.time() - start
        # print("Check auth status...")
        msg, check = API.checkAuthStatus()
        if check == False:
            if msg == "pending":
                time.sleep(API.key.authCheckInterval + 1)
                continue
            Printf.err(msg)
            break
        if check == True:
            Printf.success(LANG.MSG_VALID_ACCESSTOKEN.format(displayTime(int(API.key.expiresIn))))
            TOKEN.userid = API.key.userId
            TOKEN.countryCode = API.key.countryCode
            TOKEN.accessToken = API.key.accessToken
            TOKEN.refreshToken = API.key.refreshToken
            TOKEN.expiresAfter = time.time() + int(API.key.expiresIn)
            TokenSettings.save(TOKEN)
            break
    if elapsed >= API.key.authCheckTimeout:
        Printf.err(LANG.AUTH_TIMEOUT)
    return
Ejemplo n.º 27
0
def mainCommand():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:l:v",
                                   ["help", "output=", "link=", "version"])
        link = None
        for opt, val in opts:
            if opt in ('-h', '--help'):
                Printf.usage()
                return
            if opt in ('-v', '--version'):
                Printf.logo()
                return
            if opt in ('-l', '--link'):
                link = val
            if opt in ('-o', '--output'):
                CONF.downloadPath = val
        if link is None:
            Printf.err(
                "Please enter the link(url/id/path)! Enter 'tidal-dl -h' for help!"
            )
            return
        if not mkdirs(CONF.downloadPath):
            Printf.err(LANG.MSG_PATH_ERR + CONF.downloadPath)
            return

        checkLogin()
        start(USER, CONF, link)
        return
    except getopt.GetoptError:
        Printf.err("Argv error! Enter 'tidal -h' for help!")
Ejemplo n.º 28
0
def __downloadTrack__(conf: Settings, track: Track, album=None, playlist=None):
    try:
        if track.allowStreaming is False:
            Printf.err("Download failed! " + track.title +
                       ' not allow streaming.')
            return

        msg, stream = API.getStreamUrl(track.id, conf.audioQuality)
        Printf.track(track, stream)
        if not aigpy.string.isNull(msg) or stream is None:
            Printf.err(track.title + "." + msg)
            return
        path = __getTrackPath__(conf, track, stream, album, playlist)

        # check exist
        if conf.checkExist and __isNeedDownload__(path, stream.url) == False:
            Printf.success(
                aigpy.path.getFileName(path) + " (skip:already exists!)")
            return
        logging.info("[DL Track] name=" + aigpy.path.getFileName(path) +
                     "\nurl=" + stream.url)
        tool = aigpy.download.DownloadTool(path + '.part', [stream.url])
        check, err = tool.start(conf.showProgress)

        if not check:
            Printf.err("Download failed! " + aigpy.path.getFileName(path) +
                       ' (' + str(err) + ')')
            return
        # encrypted -> decrypt and remove encrypted file
        if aigpy.string.isNull(stream.encryptionKey):
            os.replace(path + '.part', path)
        else:
            key, nonce = decrypt_security_token(stream.encryptionKey)
            decrypt_file(path + '.part', path, key, nonce)
            os.remove(path + '.part')

        path = __convertToM4a__(path, stream.codec)

        # contributors
        contributors = API.getTrackContributors(track.id)
        lyrics = ''
        if conf.addLyrics:
            lyrics = __getLyrics__(track.title, track.artists[0].name,
                                   conf.lyricsServerProxy)

        __setMetaData__(track, album, path, contributors, lyrics)
        Printf.success(aigpy.path.getFileName(path))
    except Exception as e:
        Printf.err("Download failed! " + track.title + ' (' + str(e) + ')')
Ejemplo n.º 29
0
def downloadTrack(track: Track,
                  album=None,
                  playlist=None,
                  userProgress=None,
                  partSize=1048576):
    try:
        msg, stream = API.getStreamUrl(track.id, CONF.audioQuality)
        if not aigpy.string.isNull(msg) or stream is None:
            Printf.err(track.title + "." + msg)
            return False, msg
        if CONF.showTrackInfo:
            Printf.track(track, stream)
        if userProgress is not None:
            userProgress.updateStream(stream)
        path = getTrackPath(CONF, track, stream, album, playlist)

        # check exist
        if skip(path, stream.url):
            Printf.success(
                aigpy.path.getFileName(path) + " (skip:already exists!)")
            return True, ""

        # download
        logging.info("[DL Track] name=" + aigpy.path.getFileName(path) +
                     "\nurl=" + stream.url)
        tool = aigpy.download.DownloadTool(path + '.part', [stream.url])
        tool.setUserProgress(userProgress)
        tool.setPartSize(partSize)
        check, err = tool.start(CONF.showProgress)
        if not check:
            Printf.err("Download failed! " + aigpy.path.getFileName(path) +
                       ' (' + str(err) + ')')
            return False, str(err)

        # encrypted -> decrypt and remove encrypted file
        encrypted(stream, path + '.part', path)

        # convert
        path = convert(path, stream)

        # contributors
        msg, contributors = API.getTrackContributors(track.id)
        msg, tidalLyrics = API.getLyrics(track.id)

        lyrics = '' if tidalLyrics is None else tidalLyrics.subtitles
        if CONF.lyricFile:
            if tidalLyrics is None:
                Printf.info(f'Failed to get lyrics from tidal!"{track.title}"')
            else:
                lrcPath = path.rsplit(".", 1)[0] + '.lrc'
                aigpy.fileHelper.write(lrcPath, tidalLyrics.subtitles, 'w')

        setMetaData(track, album, path, contributors, lyrics)
        Printf.success(aigpy.path.getFileName(path))
        return True, ""
    except Exception as e:
        Printf.err("Download failed! " + track.title + ' (' + str(e) + ')')
        return False, str(e)
Ejemplo n.º 30
0
def login(username="", password=""):
    while True:
        if isNull(username) or isNull(password):
            print("---------------" + LANG.CHOICE_LOGIN + "-----------------")
            username = Printf.enter(LANG.PRINT_USERNAME)
            password = Printf.enter(LANG.PRINT_PASSWORD)
        msg, check = API.login(username, password, TOKEN1)
        if check == False:
            Printf.err(msg)
            username = ""
            password = ""
            continue
        api2 = TidalAPI()
        msg, check = api2.login(username, password, TOKEN2)
        break

    USER.username = username
    USER.password = password
    USER.userid = API.key.userId
    USER.countryCode = API.key.countryCode
    USER.sessionid1 = API.key.sessionId
    USER.sessionid2 = api2.key.sessionId
    UserSettings.save(USER)