Beispiel #1
0
    def __init__(self, searchTerm, naked=False):
        self.__ClassName = "Beatport.ResultPage"
        self.__ReleaseList = []

        # strip whitespaces on the edges
        searchTerm = searchTerm.strip()

        # replace white spaces
        searchTerm = searchTerm.replace(" ", "+")

        # remove ampersand from searchTerm
        searchTerm = searchTerm.replace("&", "")

        #
        # get the web data
        #
        ePrint(2, self.__ClassName, "Searching for term: " + searchTerm)

        if naked:
            return

        # maka request
        base = 'https://pro.beatport.com/search/releases?q={0}'
        base = base.format(searchTerm)

        r = requests.get(base)

        html = r.text

        self.__ReleaseList = self._get_releases(html, base)
Beispiel #2
0
    def RenameQuery(self, dest):
        dest = path.join(path.dirname(self.Path), dest + "." + self.Type)
        ePrint(1, ":", "Rename: " + path.basename(self.Path) + " --> " + path.basename(dest), end=" ? ")
        choice = "k"
        while choice != "y" and choice != "n":
            choice = input("(y/n): ")

        if choice == "y":
            rename(self.Path, dest)
Beispiel #3
0
def Remeta():


    # create an settings object and, which parses
    # arguemnts and sets default options
    ePrint(0, Remeta.__name__, "parsing arguments")
    settings = Settings(sys.argv[1:])

    # create a main instance and run it
    main = Main(settings)

    main.Run()
Beispiel #4
0
    def __init__(self, searchTerm):
        self.__ClassName = "Chemical.ResultPage"
        self.__ReleaseList = []

        # set the base link for searching
        self.__BaseLink = r'http://www.chemical-records.co.uk/sc/search?SRI=true&inandout=true&ND=-1&Type=Music&must='

        # strip whitespaces on the edges
        searchTerm = searchTerm.strip()

        # replace white spaces
        searchTerm = searchTerm.replace(" ", "+")

        # remove ampersand from searchTerm
        searchTerm = searchTerm.replace("&", "")

        #
        # get the web page source
        #
        ePrint(2, self.__ClassName, "Searching for term: " + searchTerm)
        response = urllib.request.urlopen(self.__BaseLink + searchTerm)

        # get page-source to str
        page = response.read()
        
        # return None if we have no source
        if len(page) == 0:
            return None

        # convert the string to a raw-string
        page = page.decode('Latin1')


        #
        # build the parser stream, we use minidom, after that parse the source
        #
        ePrint(2, self.__ClassName, "Parsing web source")
        p = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("dom"))
        dom_tree = p.parse(page)
        walker = treewalkers.getTreeWalker("dom")
        stream = walker(dom_tree)

        self.__CreateReleaseList__(stream)
Beispiel #5
0
    def _get_releases(self, html, query_link):
        # see if we hav multiple pages
        soup = BeautifulSoup(html, "lxml")

        page_numbers = soup.find_all(True, class_='pagination-number')

        if len(page_numbers) == 0:
            return self._get_releases_paginated(html)
        else:
            releases = []
            page_count = len(page_numbers)
            ePrint(1, self.__ClassName, "Found " + str(page_count) + " pages")

            for c in range(1, page_count + 1):
                r = requests.get(query_link + '&page=' + str(c))
                html = r.text

                releases = releases + self._get_releases_paginated(html)

            return releases
Beispiel #6
0
    def __init__(self, rel):
        
        # copy inherited object
        super().__init__()
        self.Name = rel.Name
        self.Catid = rel.Catid
        self.LabelName = rel.LabelName
        self.InfoPageLink = rel.InfoPageLink
        self.TrackList = deepcopy(rel.TrackList)

        # own members
        self.__ClassName = "ReleasePage"

        #
        # get the web page source
        #
        response = urllib.request.urlopen(self.InfoPageLink)

        # get page-source to str
        page = response.read()
        
        # return None if we have no source
        if len(page) == 0:
            return None

        # convert the string to a raw-string
        page = page.decode('Latin1')


        #
        # build the parser stream, we use minidom, after that parse the source
        #
        ePrint(2, self.__ClassName, "Parsing web source")
        p = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("dom"))
        dom_tree = p.parse(page)
        walker = treewalkers.getTreeWalker("dom")
        stream = walker(dom_tree)

        self.Parse(stream)
Beispiel #7
0
    def __init__(self, searchTerm):
        self.__ClassName = "Beatport.ResultPage"
        self.__ReleaseList = []


        # strip whitespaces on the edges
        searchTerm = searchTerm.strip()

        # replace white spaces
        searchTerm = searchTerm.replace(" ", "+")

        # remove ampersand from searchTerm
        searchTerm = searchTerm.replace("&", "")

        #
        # get the web data
        #
        ePrint(2, self.__ClassName, "Searching for term: " + searchTerm)

        # make a socket connection to the beatport api
        conn = http.client.HTTPConnection("api.beatport.com")
        conn.request("GET", "/catalog/3/search?query=" + searchTerm + "&facets[]=fieldType:release&perPage=500")
        r1 = conn.getresponse()
        #print(r1.status, r1.reason)
        
        mydict = json.loads(r1.read().decode())
        # print(json.dumps(mydict["results"], sort_keys=True, indent=4))

        #for entry in mydict["results"]:
        #    print(entry["name"])

        #print(len(mydict["results"]))
        
        # Check for nothing found
        if len(mydict["results"]) == 0:
            return None

        self.__CreateReleaseList__(mydict["results"])
Beispiel #8
0
    def __init__(self, filePath):
        self.__ClassName = "File"
        # set default Type
        self.Type = "mp3"
        self.Path = filePath
        self.Basename = path.basename(filePath)
        t, b = self.GetSuffix()

        self.RelDir = ""
        self.RelDirIdx = 0

        # set type
        if t:
            self.Type = t

        # set namebody, aka basename without extension
        self.NameBody = path.basename(b)

        # check if we find tag header and set the default if not
        self.TagHeader = None
        try:
            self.TagHeader = TagHeader(self.Path)
        except NoTagError:
            ePrint(1, self.__ClassName, "No Tag found in file: " + self.Basename)
Beispiel #9
0
    def IdentifyTrack(self, term):
        sFktname = "search_track"
        
        # build search term. so connect artist and
        # title, delete some characters and split on
        # white spaces
        search_term_list = term.strip()

        search_term_list = search_term_list.replace("(","").replace(")","").lower()

        search_term_list = search_term_list.split()

        ePrint(2, sFktname, "looking for term: {}".format(search_term_list))

        # to find the track, we constuct a ranking, with the term on the highest rank, wich
        # made the most hits 
        max_hits = 0
    
        match_list = []

        for item in self.TrackList:

            item_hits = 0

            # create target term
            search_target_list = item.Artist.lower() + " " + item.Title.lower()
            search_target_list = ReplaceChars("/_()-.:,", " ", search_target_list)
            search_target_list = search_target_list.split()
            ePrint(2, sFktname, "Matching against: "+ str(search_target_list))

            # match
            for s in search_term_list:
                if s in search_target_list:
                    item_hits += 1

            # calculate a value wich is relative to the length of the search_term_list
            item_hits = item_hits / len(search_term_list)
            ePrint(2, sFktname, "Ranking points: " + str(item_hits))
            
            # create a matchcount, item tupel
            match_list.append((item_hits, item))

        if len(match_list) == 0:
            return None


        # sort matchlist
        match_list = sorted(match_list, key = lambda tup: tup[0], reverse = True)
        
        
        return match_list[0][1]
Beispiel #10
0
 def Rename(self, dest):
     dest = path.join(path.dirname(self.Path), dest + "." + self.Type)
     ePrint(1, ":", "Renameing: " + path.basename(self.Path) + " --> " + path.basename(dest))
     
     rename(self.Path, dest)
Beispiel #11
0
    def __init__(self, arguments):
        self.__ClassName = "Settings"

        # 
        # at first parse options
        #
        usage = "usage: %prog [options] filnames or searchpatterns"
        parser = OptionParser(usage = usage)

        parser.add_option("-c", "--copy", action = "store_true",
                          help = "make a copy of original files before copying")
        parser.set_defaults(copy = False)

        parser.add_option("-w", "--cemelot", action = "store_true",
                          help = "use Cemelot format for keys")

        parser.add_option("-a", "--ask", action = "store_true",
                          help = "ask user if files are renamed")

        parser.add_option("-v", "--verb-level", action = "store", type= "int",
                          dest = "verblevel", help = "specify a verbosity level")

        parser.add_option("-p", "--pattern", action = "store", type= "string",
                          help = "specify a verbosity level")

        parser.add_option("-i", "--get-image", action = "store_true", dest = "getimage",
                          help = "download release artwork if release search is invoked")

        parser.set_defaults(copy = False)
        parser.set_defaults(cemelot = False)
        parser.set_defaults(verblevel = 1)
        parser.set_defaults(pattern = "")
        parser.set_defaults(ask = False)
        parser.set_defaults(getimage = False)

        (options, args) = parser.parse_args(arguments)

        #
        # set options 
        #

        # if a pattern was given initialize a Pattern object with
        # given string
        if options.pattern:
            self.Pattern = Pattern(options.pattern)
        else:
            self.Pattern = Pattern()

        # toggle copy mode on or of
        self.MakeCopy = options.copy

        # toggle use of crappy chemelot notation
        self.UseChemelot = options.cemelot

        # ask or not ask user
        self.Ask = options.ask

        # get image flag
        self.GetImage = options.getimage

        # set verbosity level
        # TODO: remove messi global variable
        self.VerbLevel = options.verblevel
        Helpers.G_VerbLevel = self.VerbLevel

        ePrint(2, self.__ClassName, "Pattern used: " + self.Pattern.Entry)
        ePrint(2, self.__ClassName, "Use copy mode: " + str(self.MakeCopy))
        ePrint(2, self.__ClassName, "Use chemelot notation: " + str(self.UseChemelot))


        #
        # create filelist and searchterm list
        #
        self.FileList = []
        self.DirList = []
        self.SearchTermList = []

        for entry in args:
            if path.isdir(entry):
                self.DirList.append(entry)
            elif path.isfile(entry):
                # create a file object
                self.FileList.append(File(entry))
            else:
                self.SearchTermList.append(entry)

        ePrint(3, self.__ClassName, "Search terms given:" + str(self.SearchTermList))
        ePrint(3, self.__ClassName, "Files given:")
        
        for f in self.FileList:
            ePrint(3, self.__ClassName, str(f.GetDict()))
Beispiel #12
0
    def Run(self):

        print()

        filled_tracks = []
        unfilled_tracks = []

        ##
        ## Handle Directories (Release Search)
        ##
        if self.Settings.HasDirs():

            # here we only link the files to specific dirs
            # the next loop then cares about and first makes
            # a search in a release cache

            idx = 0

            for folder in self.Settings.DirList:

                #
                # figure out the directory entries
                #
                file_list = os.listdir(folder)
                

                if not file_list:
                    ePrint(1, self.__ClassName, "Skipping directory " + folder)
                    continue

                ePrint(2, folder, "<-- Linking files")
                ePrint(2, "Containing: ", str(file_list) + "\n")

                # append them to the FileList
                for file_path in file_list:
                    f = File(os.path.join(folder, file_path))
                    f.RelDir = folder

                    f.RelDirIdx = idx
                    #ePrint(2, "Fileending: ", str(file_list) + "\n")
                    if f.Type in ["mp3", "flac", "wav", "wave", "ogg"]:
                        self.Settings.FileList.append(f)

                idx += 1


        ##
        ## Handle the FileList if existent
        ##
        if self.Settings.HasFiles():
            track_list = []
            
            for f in self.Settings.FileList:
                
                #
                # at first try to gather some data from the tags, so
                # create a track object
                #

                new_track = Track()
                
                # associate the track with its file and try to read
                # some info from the tags
                new_track.FileInstance = f
                new_track.FillFromFile()

                ePrint(1, ColorString(str(new_track.FileInstance.NameBody), "green"), "<-- Try to determine info")

                # if a track is fully filled continue with the next
                if (new_track.FilledEnough(self.Settings.Pattern)):
                    ePrint(1, self.__ClassName, "Track is filled enough: " + str(new_track) + "\n")
                    filled_tracks.append(new_track)
                    continue

                #
                # Look in the cache
                #
                rel_page = None

                for t in filled_tracks:
                    if new_track.FileInstance.RelDir != "" and \
                       new_track.FileInstance.RelDir == t.FileInstance.RelDir and \
                       t.Release:
                           ePrint(2, self.__ClassName, "Using cache")
                           rel_page = t.Release
                           break

                if not rel_page:
                    #
                    # look at chemical if nothing is found in tags or cache
                    #

                    # first we check for an explicit searchterm
                    idx = new_track.FileInstance.RelDirIdx
                    
                    if idx < len(self.Settings.SearchTermList):
                        search_term = self.Settings.SearchTermList[idx]
                    else:
                        # if we have artist and filename availible set this as searchterm
                        if new_track.Artist and new_track.Title:
                            search_term = new_track.Artist + " " + new_track.Title
                        else:
                            # otherwise create search_term from filename
                            search_term = new_track.FileInstance.NameBody
                            ePrint(2, self.__ClassName, "Setting searchterm: " + search_term)



                    # link it up on BeatportWeb
                    res_page = BeatportWeb.ResultPage(search_term)

                    # if we found nothing, we cut the searchterm
                    if not res_page.GetReleaseList():
                        # at first remove signs symbols and retry
                        search_term = ReplaceChars("/_()-.:,&?", " ", search_term)
                        # strip "feat" terms
                        p = re.compile(" feat ", re.IGNORECASE)
                        search_term = p.sub("", search_term)

                        res_page = BeatportWeb.ResultPage(search_term)

                        if not res_page.GetReleaseList():
                            # second remove numbers
                            search_term = ReplaceChars("0123456789", " ", search_term)
                            res_page = BeatportWeb.ResultPage(search_term)

                            # now strip words from the term
                            if not res_page.GetReleaseList():
                                search_term_word_list = search_term.split()
                                while len(search_term_word_list) > 1:
                                    search_term_word_list.pop()
                                    search_term = " ".join(search_term_word_list)
                                    res_page = BeatportWeb.ResultPage(search_term)
                                    if res_page.GetReleaseList():
                                        break
                                
                    
                    
                    # if we finally found nothing, skip
                    if not res_page.GetReleaseList():
                        ePrint(1, self.__ClassName, "Could not determine all fields for: " +
                               new_track.FileInstance.Basename + "\n")
                        unfilled_tracks.append(new_track)
                        continue
                    
                    #
                    # now we process the result list
                    #
                    release_list = res_page.GetReleaseList()
                    
                    # invoke the user if we have found more than one results
                    if len(release_list) > 1:
                        ePrint(1, self.__ClassName,
                               "Multiple possilble releases found for: " + new_track.FileInstance.Basename +
                               "Please type number. 0 to skip.")

                        # TODO print sorted
                        release_list = res_page.GetReleaseList()
                        
                        # sort the release list for better choosing
                        release_list = sorted(release_list, key = lambda rel: str(rel), reverse = False)

                        c = 1
                        for r in release_list:
                            print("{:4d} : {!s:.150}".format(c, r))
                            c += 1

                        choice = -1
                        while choice < 0 or choice > len(release_list):
                            choice = int(input(" <-- "))

                        if choice == 0:
                            ePrint(1, self.__ClassName, "Skipping: " + new_track.FileInstance.Basename + "\n")
                            unfilled_tracks.append(new_track)
                            continue

                        # choose result, pay attention on index
                        release_candidate = release_list[choice - 1]
                    else:
                        release_candidate = release_list[0]

                    # create a ReleasePage, from the release candidate . This determines all relevant 
                    # information for the release
                    rel_page = BeatportWeb.ReleasePage(release_candidate)


                #
                # identify the track in the release
                #

                # create a search term
                if new_track.Artist and new_track.Title:
                    search_term = new_track.Artist + " " + new_track.Title
                else:
                    search_term = new_track.FileInstance.NameBody
                
                search_term = ReplaceChars("/_()-.:,", " ", search_term)

                cor_track = rel_page.IdentifyTrack(search_term)
                ePrint(1, self.__ClassName, "corresponding track: " + ColorString(str(cor_track), 'green'))

                # since we only have a corresponding track copy on demand
                if not new_track.Artist:
                    new_track.Artist = cor_track.Artist
                if not new_track.Title:
                    new_track.Title = cor_track.Title
                if not new_track.Key:
                    new_track.Key = cor_track.Key
                if not new_track.Number:
                    new_track.Number = cor_track.Number

                if new_track.FilledEnough(self.Settings.Pattern):
                    ePrint(1, self.__ClassName, "Track is filled enough: " + str(new_track))
                    # link to the found release
                    new_track.Release = rel_page
                    filled_tracks.append(new_track)
                else:
                    ePrint(1, self.__ClassName, "Could not determine all fields for: " + new_track.FileInstance.Basename)
                    unfilled_tracks.append(new_track)

                print()

        #
        # Rename files
        #
        for track in filled_tracks:
            dest_name = self.Settings.Pattern.GetResolvedString(artist=track.Artist, title=track.Title,
                                                                number=track.Number, key=track.Key)

            # function only needs the basename without extension
            if self.Settings.MakeCopy:
                #track.FileInstance.Copy(dest_name)
                pass
            else:
                if self.Settings.Ask == True:
                    track.FileInstance.RenameQuery(dest_name)
                else:
                    track.FileInstance.Rename(dest_name)


        #
        # handle dir renaming
        #
        handled_dirs = []
        for track in filled_tracks:
            if track.FileInstance.RelDir and track.FileInstance.RelDir not in handled_dirs:
                #TODO remove code here
                # build a artist string, maximum 2
                #artists = ""
                #c = 0
                #for t in track.Release.TrackList:
                #    artists += t.Artist + " "
                #    if c >= 1:
                #        break
                #    c += 1

                #print("Artist name: " + artists)
                #
                ## create destination string
                #artists = artists.strip()
                #artists = ReplaceChars(" ", ".", artists)
                #artists = artists.lower()

                rel_name = track.Release.Name.strip()
                rel_name = ReplaceChars("/'", "", rel_name)
                rel_name = ReplaceChars(" ", ".", rel_name)
                rel_name = rel_name.lower()
                
                dest = track.Release.Catid.lower() + ".-." + rel_name
                ePrint(2, self.__ClassName, track.FileInstance.RelDir)
                ePrint(2, self.__ClassName, dest)

                # download artwork if necessary
                if self.Settings.GetImage == True:
                    image_path = os.path.join(track.FileInstance.RelDir, "artwork.jpg")
                    if os.path.exists(image_path):
                        ePrint(1, self.__ClassName, "Artwork already in release folder")
                    else:
                        ePrint(1, self.__ClassName, "Downloading Artwork")
                        DownloadFile(track.Release.PictureLink, image_path)


                RenameDirQuery(track.FileInstance.RelDir, dest)

                handled_dirs.append(track.FileInstance.RelDir)
Beispiel #13
0
 def __init__(self, settings):
     self.__ClassName = "Main"
     ePrint(2, self.__ClassName, "Entering")
     self.Settings = settings
Beispiel #14
0
    def __init__(self, filePath):
        self.__ClassName = "TagHeader"

        ePrint(2, self.__ClassName, "Try to create stagger tag for: " + filePath)

        self.Tag = stagger.read_tag(filePath)