@@ -0,0 +1,1874 @@
+import re%0Aimport codecs%0Afrom os import path%0A%0Afrom jinja2 import Environment%0A%0Aclass Librarian:%0A    %22%22%22%0A    Keeps track of which songs have been downloaded (or are downloading) and decides where to store them.%0A    This implementation generates XBMC/Kodi style .nfo files.%0A    %22%22%22%0A%0A    nfo_template_str = %22%22%22%3Cmusicvideo%3E%0A  %3Ctitle%3E%7B%7Bsong.title%7D%7D%3C/title%3E%0A  %3Cartist%3E%7B%7Bsong.artist%7D%7D%3C/artist%3E%0A  %3Calbum%3E%7B%7Bsong.artist%7D%7D%3C/album%3E%0A  %3Cgenre%3EPop%3C/genre%3E%0A  %3Cdirector%3E%3C/director%3E%0A  %3Ccomposer%3E%3C/composer%3E%0A  %3Cstudio%3E%3C/studio%3E%0A  %3Cyear%3E%3C/year%3E%0A  %3Cruntime%3E%3C/runtime%3E%0A  %3Cmormuvid%3E%3Cstatus%3E%7B%7Bstatus%7D%7D%3C/status%3E%3C/mormuvid%3E%0A%3C/musicvideo%3E%0A%22%22%22%0A%0A    def want_song(self, song):%0A        nfo_filename = self._get_nfo_filepath(song)%0A        if path.isfile(nfo_filename):%0A            return False%0A        else:%0A            return True%0A%0A    def notify_download_queued(self, song, video_watch_url):%0A        self._write_nfo_file(song, 'QUEUED')%0A        return%0A%0A    def notify_download_completed(self, song):%0A        self._write_nfo_file(song, 'COMPLETED')%0A        return%0A%0A    def notify_download_failed(self, song):%0A        self._write_nfo_file(song, 'FAILED')%0A        return%0A%0A    def get_base_filepath(self, song):%0A        raw = song.artist + %22 - %22 + song.title%0A        # TODO: obviously, this won't work at all with non-latin-alphabet song names ...%0A        safe = re.sub(r%22%5B%5E0-9A-Za-z .,;()_%5C-%5D%22, %22_%22, raw)%0A        return safe%0A%0A    def _get_nfo_filepath(self, song):%0A        return self.get_base_filepath(song) + '.nfo'%0A%0A    def _write_nfo_file(self, song, status):%0A        nfo_filename = self._get_nfo_filepath(song)%0A        env = Environment(autoescape = True)%0A        template = env.from_string(self.nfo_template_str)%0A        nfo_xml = template.render(song = song, status = status)%0A        target = codecs.open(nfo_filename, 'w', 'utf-8')%0A        target.write(nfo_xml)%0A        target.close()%0A        return%0A

Add librarian to look after files