Exemplo n.º 1
0
def start(user, conf, string):
    __loadAPI__(user)
    if isNull(string):
        Printf.err('Please enter something.')
        return

    strings = string.split(" ")
    for item in strings:
        if 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 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)
Exemplo 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!")
Exemplo n.º 3
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()
        choice = Printf.enter(LANG.PRINT_ENTER_CHOICE)
        if choice == "0":
            return
        elif choice == "1":
            checkLogin()
        elif choice == "2":
            changeSettings()
        elif choice == "3":
            checkLogout()
        elif choice == "4":
            song = Printf.enter("Enter the song name: ")
            searchTrack(TOKEN, LANG.PRINT_ENTER_CHOICE, song, CONF)
        else:
            start(TOKEN, CONF, choice)
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!")
def loginByWeb():
    start = time.time()
    elapsed = 0
    while elapsed < API.key.authCheckTimeout:
        elapsed = time.time() - start
        msg, check = API.checkAuthStatus()
        if not check:
            if msg == "pending":
                time.sleep(API.key.authCheckInterval + 1)
                continue
            return False
        if check:
            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)
            return True

    Printf.err(LANG.AUTH_TIMEOUT)
    return False
Exemplo n.º 6
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)
Exemplo n.º 7
0
def __mix__(conf, obj: Mix):
    Printf.mix(obj)
    for index, item in enumerate(obj.tracks):
        mag, album = API.getAlbum(item.album.id)
        item.trackNumberOnPlaylist = index + 1
        downloadTrack(item, album)
        if conf.saveCovers and not conf.usePlaylistFolder:
            __downloadCover__(conf, album)
    for item in obj.videos:
        downloadVideo(item, None)
Exemplo n.º 8
0
def main():
    if len(sys.argv) > 1:
        mainCommand()
        return

    Printf.logo()
    Printf.settings(CONF)

    checkLogin()
    autoGetAccessToken()

    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()
        choice = Printf.enter(LANG.PRINT_ENTER_CHOICE)
        if choice == "0":
            return
        elif choice == "1":
            login()
        elif choice == "2":
            changeSettings()
        elif choice == "3":
            setAccessToken()
        else:
            start(USER, CONF, choice)
Exemplo n.º 9
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)
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
Exemplo n.º 11
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)
Exemplo n.º 12
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)
Exemplo n.º 13
0
def autoGetAccessToken():
    array = API.tryGetAccessToken(USER.userid)
    if len(array) <= 0:
        return
    for item in array:
        msg, check = API.loginByAccessToken(item, USER.userid)
        if check == False:
            continue
        if item != USER.assesstoken:
            USER.assesstoken = item
            UserSettings.save(USER)
            Printf.info("Auto get accesstoken from tidal cache success!")
            return
Exemplo 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)
Exemplo n.º 15
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)
def __downloadTrack__(conf, track, album=None, playlist=None):
    try:
        msg, stream = API.getStreamUrl(track.id, conf.audioQuality)
        if not isNull(msg) or stream is None:
            Printf.err(track.title + "." + msg)
            return
        path = __getTrackPath__(conf, track, stream, album, playlist)

        # Printf.info("Download \"" + track.title + "\" Codec: " + stream.codec)
        check, err = downloadFileMultiThread(stream.url,
                                             path + '.part',
                                             stimeout=20,
                                             showprogress=True)
        if not check:
            Printf.err("Download failed!" + getFileName(path) + ' (' +
                       str(err) + ')')
            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))
    except Exception as e:
        Printf.err("Download failed!" + track.title + ' (' + str(e) + ')')
Exemplo n.º 17
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
Exemplo n.º 18
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)
Exemplo n.º 19
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)
Exemplo 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)
Exemplo n.º 21
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)
def checkLogin():
    if not isNull(USER.accessToken):
        #print('Checking Access Token...') #add to translations
        msg, check = API.verifyAccessToken(USER.accessToken)
        if check == True:
            Printf.info(
                LANG.MSG_VALID_ACCESSTOKEN.format(
                    displayTime(int(USER.expiresAfter - time.time()))))
            return
        else:
            Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
            msg, check = API.refreshAccessToken(USER.refreshToken)
            if check == True:
                Printf.success(
                    LANG.MSG_VALID_ACCESSTOKEN.format(
                        displayTime(int(API.key.expiresIn))))
                USER.userid = API.key.userId
                USER.countryCode = API.key.countryCode
                USER.accessToken = API.key.accessToken
                USER.expiresAfter = time.time() + int(API.key.expiresIn)
                UserSettings.save(USER)
                return
            else:
                Printf.err(msg)
                tmp = UserSettings()  #clears saved tokens
                UserSettings.save(tmp)
    login()
    return
Exemplo n.º 23
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)
Exemplo n.º 24
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)
Exemplo n.º 25
0
def mainCommand():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:l:v:u:p:a:q:r", [
            "help", "output=", "link=", "version", "username", "password",
            "accessToken", "quality", "resolution"
        ])
        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 opt in ('-u', '--username'):
                USER.username = val
                UserSettings.save(USER)
            if opt in ('-p', '--password'):
                USER.password = val
                UserSettings.save(USER)
            if opt in ('-a', '--accessToken'):
                USER.assesstoken = val
                UserSettings.save(USER)
            if opt in ('-q', '--quality'):
                CONF.audioQuality = Settings.getAudioQuality(val)
            if opt in ('-r', '--resolution'):
                CONF.videoQuality = Settings.getVideoQuality(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!")
Exemplo n.º 26
0
def __downloadVideo__(conf, video:Video, album=None, playlist=None):
    if video.allowStreaming is False:
        Printf.err("Download failed! " + video.title + ' not allow streaming.')
        return

    msg, stream = API.getVideoStreamUrl(video.id, conf.videoQuality)
    Printf.video(video, stream)
    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)
    check, msg = aigpy.m3u8.download(stream.m3u8Url, path)
    if check is True:
        Printf.success(aigpy.path.getFileName(path))
    else:
        Printf.err("\nDownload failed!" + msg + '(' + aigpy.path.getFileName(path) + ')')
Exemplo n.º 27
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)
Exemplo n.º 28
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)
Exemplo n.º 29
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)
Exemplo n.º 30
0
def loginByConfig():
    if aigpy.stringHelper.isNull(TOKEN.accessToken):
        return False

    msg, check = API.verifyAccessToken(TOKEN.accessToken)
    if check:
        Printf.info(
            LANG.MSG_VALID_ACCESSTOKEN.format(
                displayTime(int(TOKEN.expiresAfter - time.time()))))
        API.key.countryCode = TOKEN.countryCode
        API.key.userId = TOKEN.userid
        API.key.accessToken = TOKEN.accessToken
        return True

    Printf.info(LANG.MSG_INVAILD_ACCESSTOKEN)
    msg, check = API.refreshAccessToken(TOKEN.refreshToken)
    if check:
        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 True
    else:
        tmp = TokenSettings()  # clears saved tokens
        TokenSettings.save(tmp)
        return False