Пример #1
0
def urlopen(_url, use_cache=True, retries=RETRIES):
    # set host port from 81 to 80, to fix image problem
    url = _url.replace(':81', '')
    if use_cache and ldb_imported:
        key = hash_byte(url)
        try:
            content = ldb_get(key)
            if content and len(content) > 10:
                try:
                    timestamp = int(content[:10].decode())
                    if (time.time() - timestamp) < CACHE_TIMEOUT:
                        return content[10:]
                except (ValueError, UnicodeDecodeError):
                    logger.debug(traceback.format_exc())
        except KeyError:
            logger.debug(traceback.format_exc())
    for i in range(retries):
        try:
            req = request.urlopen(url, timeout=TIMEOUT)
            req_content = req.read()
            if use_cache and ldb_imported:
                ldb_put(key, str(int(time.time())).encode() + req_content)
            return req_content
        except URLError:
            logger.warn(traceback.format_exc())
            logger.warn('Net.urlopen, url: %s' % url)
    return None
Пример #2
0
def urlopen(_url, use_cache=True, retries=RETRIES):
    # set host port from 81 to 80, to fix image problem
    url = _url.replace(':81', '')
    if use_cache and ldb_imported:
        key = hash_byte(url)
        try:
            content = ldb_get(key)
            if content and len(content) > 10:
                try:
                    timestamp = int(content[:10].decode())
                    if (time.time() - timestamp) < CACHE_TIMEOUT:
                        return content[10:]
                except (ValueError, UnicodeDecodeError):
                    logger.debug(traceback.format_exc())
        except KeyError:
            logger.debug(traceback.format_exc())
    for i in range(retries):
        try:
            req = request.urlopen(url, timeout=TIMEOUT)
            req_content = req.read()
            if use_cache and ldb_imported:
                ldb_put(key, str(int(time.time())).encode() + req_content)
            return req_content
        except URLError:
            logger.warn(traceback.format_exc())
            logger.warn('Net.urlopen, url: %s' % url)
    return None
Пример #3
0
def get_image(url, filepath=None):
    if not url or len(url) < 10:
        logger.error('Net.get_image: url is invalid, %s' % url)
        return None
    if not filepath:
        filename = os.path.split(url)[1]
        filepath = os.path.join(Config.IMG_DIR, filename)
    if os.path.exists(filepath):
        return filepath

    image = urlopen(url, use_cache=False)
    if not image:
        logger.debug('Net.get_image: failed to get image, %s' % image)
        return None

    with open(filepath, 'wb') as fh:
        fh.write(image)
    # Now, check its mime type
    file_ = Gio.File.new_for_path(filepath)
    file_info = file_.query_info(Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                                 Gio.FileQueryInfoFlags.NONE)
    content_type = file_info.get_content_type()
    if 'image' in content_type:
        return filepath
    else:
        os.remove(filepath)
        return None
Пример #4
0
def parse_lrc(lrc_txt):
    '''解析歌词'''
    try:
        return parser_lex(lrc_txt)
    except (lex.LrcError, NameError):
        logger.error(traceback.format_exc())
        logger.debug('LrcParser: fallback to regexp parser')
        return parser_re(lrc_txt)
Пример #5
0
def parse_lrc(lrc_txt):
    '''解析歌词'''
    try:
        return parser_lex(lrc_txt)
    except (lex.LrcError, NameError):
        logger.error(traceback.format_exc())
        logger.debug('LrcParser: fallback to regexp parser')
        return parser_re(lrc_txt)
Пример #6
0
    def do_cache_song_pool(self):
        def _remove_song():
            try:
                liststore.remove(liststore[path].iter)
            except IndexError:
                logger.error(traceback.format_exc())
            Gdk.Window.process_all_updates()

        def _on_disk_error(widget, song_path, eror=None):
            self.stop_caching_daemon()
            GLib.idle_add(Widgets.filesystem_error, self.app.window, song_path)

        def _on_network_error(widget, song_link, error=None):
            self.stop_caching_daemon()
            GLib.idle_add(Widgets.network_error, self.app.window,
                          _('Failed to cache song'))

        def _on_chunk_received(widget, percent):
            GLib.idle_add(do_on_chunk_received, percent)

        def do_on_chunk_received(percent):
            self.cache_local_count += 1
            self.cache_speed_label.set_text('{0} %'.format(int(percent * 100)))

        def _on_downloaded(widget, song_path, error=None):
            if song_path:
                GLib.idle_add(_remove_song)
            if self.cache_enabled:
                GLib.idle_add(self.do_cache_song_pool)

        if not self.cache_enabled:
            return
        self.cache_local_count = 0
        self.cache_global_count = 0
        self.cache_speed_label.set_text('0 %')
        list_name = 'Caching'
        liststore = self.tabs[list_name].liststore
        path = 0
        if len(liststore) == 0:
            logger.info('Caching playlist is empty, please add some songs')
            self.stop_caching_daemon()
            Notify.init('kwplayer-cache')
            notify = Notify.Notification.new('Kwplayer',
                    _('All songs in caching list have been downloaded.'),
                    'kwplayer')
            notify.show()
            return
        song = Widgets.song_row_to_dict(liststore[path], start=0)
        logger.debug('will download: %s' % song)
        self.cache_job = Net.AsyncSong(self.app)
        self.cache_job.connect('chunk-received', _on_chunk_received)
        self.cache_job.connect('downloaded', _on_downloaded)
        self.cache_job.connect('disk-error', _on_disk_error)
        self.cache_job.connect('network-error', _on_network_error)
        self.cache_job.get_song(song)
Пример #7
0
def get_image(url, filepath=None):
    if not url or len(url) < 10:
        logger.error('Net.get_image: url is invalid, %s' % url)
        return None
    if not filepath:
        filename = os.path.split(url)[1]
        filepath = os.path.join(Config.IMG_DIR, filename)
    if os.path.exists(filepath):
        return filepath

    image = urlopen(url, use_cache=False)
    if not image:
        logger.debug('Net.get_image: failed to get image, %s' % image)
        return None

    with open(filepath, 'wb') as fh:
        fh.write(image)
    return filepath
Пример #8
0
def get_image(url, filepath=None):
    if not url or len(url) < 10:
        logger.error('Net.get_image: url is invalid, %s' % url)
        return None
    if not filepath:
        filename = os.path.split(url)[1]
        filepath = os.path.join(Config.IMG_DIR, filename)
    if os.path.exists(filepath):
        return filepath

    image = urlopen(url, use_cache=False)
    if not image:
        logger.debug('Net.get_image: failed to get image, %s' % image)
        return None

    with open(filepath, 'wb') as fh:
        fh.write(image)
    return filepath
Пример #9
0
    def do_cache_song_pool(self):
        def _remove_song():
            try:
                liststore.remove(liststore.get_iter(path))
            except IndexError:
                logger.error(traceback.format_exc())
            Gdk.Window.process_all_updates()

        def _on_disk_error(widget, song_path, eror=None):
            def on_disk_error():
                logger.warn('Playlist.on_disk_error: %s, %s' %
                            (song_path, error))
                self.stop_caching_daemon()
                Widgets.filesystem_error(self.app.window, song_path)

            GLib.idle_add(on_disk_error)

        def _on_network_error(widget, song_link, error=None):
            def on_network_error():
                logger.warn('Playlist.on_network_error: %s, %s' %
                            (song_link, error))
                self.stop_caching_daemon()
                Widgets.network_error(self.app.window,
                                      _('Failed to cache song'))

            GLib.idle_add(on_network_error)

        def _on_chunk_received(widget, percent):
            def on_chunk_received():
                self.cache_local_count += 1
                self.cache_speed_label.set_text('{0} %'.format(
                    int(percent * 100)))

            GLib.idle_add(on_chunk_received)

        def _on_downloaded(widget, song_path, error=None):
            def on_downloaded():
                if song_path:
                    _remove_song()
                if self.cache_enabled:
                    self.do_cache_song_pool()

            GLib.idle_add(on_downloaded)

        if not self.cache_enabled:
            return
        self.cache_local_count = 0
        self.cache_global_count = 0
        self.cache_speed_label.set_text('0 %')
        list_name = 'Caching'
        liststore = self.tabs[list_name].liststore
        path = 0
        if len(liststore) == 0:
            logger.info('Caching playlist is empty, please add some songs')
            self.stop_caching_daemon()
            Notify.init('kwplayer-cache')
            notify = Notify.Notification.new(
                'Kwplayer',
                _('All songs in caching list have been downloaded.'),
                'kwplayer')
            notify.show()
            return
        song = Widgets.song_row_to_dict(liststore[path], start=0)
        logger.debug('will download: %s' % song)
        self.cache_job = Net.AsyncSong(self.app)
        self.cache_job.connect('chunk-received', _on_chunk_received)
        self.cache_job.connect('downloaded', _on_downloaded)
        self.cache_job.connect('disk-error', _on_disk_error)
        self.cache_job.connect('network-error', _on_network_error)
        self.cache_job.get_song(song)
Пример #10
0
from kuwo.MV import MV
from kuwo.OSDLrc import OSDLrc
from kuwo.Player import Player
from kuwo.PlayList import PlayList
from kuwo.Radio import Radio
from kuwo.Search import Search
from kuwo.Shortcut import Shortcut
from kuwo.Themes import Themes
from kuwo.TopCategories import TopCategories
from kuwo.TopList import TopList
try:
    # Ubuntu Unity uses AppIndicator instead of Gtk.StatusIcon
    gi.require_version('AppIndicator3', '0.1')
    from gi.repository import AppIndicator3 as AppIndicator
except ImportError:
    logger.debug(traceback.format_exc())

if Gtk.MAJOR_VERSION <= 3 and Gtk.MINOR_VERSION < 10:
    GObject.threads_init()
DBUS_APP_NAME = 'org.liulang.kwplayer'


class App:

    def __init__(self):
        self.app = Gtk.Application.new(DBUS_APP_NAME, 0)
        self.app.connect('startup', self.on_app_startup)
        self.app.connect('activate', self.on_app_activate)
        self.app.connect('shutdown', self.on_app_shutdown)

    def on_app_startup(self, app):
Пример #11
0
from kuwo.MV import MV
from kuwo.OSDLrc import OSDLrc
from kuwo.Player import Player
from kuwo.PlayList import PlayList
from kuwo.Radio import Radio
from kuwo.Search import Search
from kuwo.Shortcut import Shortcut
from kuwo.Themes import Themes
from kuwo.TopCategories import TopCategories
from kuwo.TopList import TopList
try:
    # Ubuntu Unity uses AppIndicator instead of Gtk.StatusIcon
    from gi.repository import AppIndicator3 as AppIndicator
except ImportError:
    print("importing indicator gets wrong")
    logger.debug(traceback.format_exc())

if Gtk.MAJOR_VERSION <= 3 and Gtk.MINOR_VERSION < 10:
    GObject.threads_init()
DBUS_APP_NAME = 'org.liulang.kwplayer'


class App:
    def __init__(self):
        self.app = Gtk.Application.new(DBUS_APP_NAME, 0)
        self.app.connect('startup', self.on_app_startup)
        self.app.connect('activate', self.on_app_activate)
        self.app.connect('shutdown', self.on_app_shutdown)

    def on_app_startup(self, app):
        self.conf = Config.load_conf()
Пример #12
0
    def _download_song(self, song, use_mv):
        cached, song_link, song_path = get_song_link(song, self.app.conf,
                                                     use_mv=use_mv)
        # temp file to store data
        tmp_song_path = '{0}-{1}.part'.format(song_path, int(time.time()))

        # check song already cached 
        if cached:
            self.emit('can-play', song_path)
            self.emit('downloaded', song_path)
            return

        # this song has no link to download
        if not song_link:
            logger.debug('download_song(): %s.' % song)
            self.emit('network-error', song_link)
            return

        if use_mv:
            chunk_to_play = CHUNK_MV_TO_PLAY
        else:
            chunk_to_play = CHUNK_TO_PLAY

        for retried in range(RETRIES):
            try:
                req = request.urlopen(song_link, timeout=TIMEOUT)
                received_size = 0
                can_play_emited = False
                content_length = int(req.headers.get('Content-Length'))
                fh = open(tmp_song_path, 'wb')

                while True:
                    if self.force_quit:
                        if not fh.closed:
                            fh.close()
                        if os.path.exists(song_path):
                            os.remove(song_path)
                        return
                    chunk = req.read(CHUNK)
                    received_size += len(chunk)
                    percent = received_size / content_length
                    if int(percent * 100) % 5 == 0:
                        self.emit('chunk-received', percent)
                    # this signal only emit once.
                    if ((received_size > chunk_to_play or percent > 0.4) and
                            not can_play_emited):
                        self.emit('can-play', tmp_song_path)
                        can_play_emited = True
                    if not chunk:
                        break
                    fh.write(chunk)

                fh.close()
                # download successfully
                if received_size == content_length:
                    os.rename(tmp_song_path, song_path)
                    self.emit('downloaded', song_path)
                    Utils.iconvtag(song_path, song)
                    return
                else:
                    logger.warn('Net.received_size: %s, content_length: %s' %
                                (received_size, content_length))
                    self.emit('network-error', song_link)
                # remove temp file
                if os.path.exists(tmp_song_path):
                    os.remove(tmp_song_path)
                break

            except URLError:
                logger.error(traceback.format_exc())
            except FileNotFoundError:
                logger.error(traceback.format_exc())
                self.emit('disk-error', song_path)
                if os.path.exists(tmp_song_path):
                    os.remove(tmp_song_path)
                return

        if os.path.exists(tmp_song_path):
            os.remove(tmp_song_path)
        self.emit('network-error', song_link)
Пример #13
0
 def _on_list_received(imgs, error=None):
     if error or not imgs or len(imgs) < 10:
         logger.debug('get_recommend_lists(): %s, %s' % (imgs, error))
         self.recommend_imgs = None
     else:
         self.recommend_imgs = imgs.strip().splitlines()
Пример #14
0
    def _download_song(self, song, use_mv):
        cached, song_link, song_path = get_song_link(song,
                                                     self.app.conf,
                                                     use_mv=use_mv)
        # temp file to store data
        tmp_song_path = '{0}-{1}.part'.format(song_path, int(time.time()))

        # check song already cached
        if cached:
            self.emit('can-play', song_path)
            self.emit('downloaded', song_path)
            return

        # this song has no link to download
        if not song_link:
            logger.debug('download_song(): %s.' % song)
            self.emit('network-error', song_link)
            return

        if use_mv:
            chunk_to_play = CHUNK_MV_TO_PLAY
        else:
            chunk_to_play = CHUNK_TO_PLAY

        for retried in range(RETRIES):
            try:
                req = request.urlopen(song_link, timeout=TIMEOUT)
                received_size = 0
                can_play_emited = False
                content_length = int(req.headers.get('Content-Length'))
                fh = open(tmp_song_path, 'wb')

                while True:
                    if self.force_quit:
                        if not fh.closed:
                            fh.close()
                        if os.path.exists(song_path):
                            os.remove(song_path)
                        return
                    chunk = req.read(CHUNK)
                    received_size += len(chunk)
                    percent = received_size / content_length
                    if int(percent * 100) % 5 == 0:
                        self.emit('chunk-received', percent)
                    # this signal only emit once.
                    if ((received_size > chunk_to_play or percent > 0.4)
                            and not can_play_emited):
                        self.emit('can-play', tmp_song_path)
                        can_play_emited = True
                    if not chunk:
                        break
                    fh.write(chunk)

                fh.close()
                # download successfully
                if received_size == content_length:
                    os.rename(tmp_song_path, song_path)
                    self.emit('downloaded', song_path)
                    Utils.iconvtag(song_path, song)
                    return
                else:
                    logger.warn('Net.received_size: %s, content_length: %s' %
                                (received_size, content_length))
                    self.emit('network-error', song_link)
                # remove temp file
                if os.path.exists(tmp_song_path):
                    os.remove(tmp_song_path)
                break

            except URLError:
                logger.error(traceback.format_exc())
            except FileNotFoundError:
                logger.error(traceback.format_exc())
                self.emit('disk-error', song_path)
                if os.path.exists(tmp_song_path):
                    os.remove(tmp_song_path)
                return

        if os.path.exists(tmp_song_path):
            os.remove(tmp_song_path)
        self.emit('network-error', song_link)
Пример #15
0
 def _on_list_received(imgs, error=None):
     if error or not imgs or len(imgs) < 10:
         logger.debug('get_recommend_lists(): %s, %s' % (imgs, error))
         self.recommend_imgs = None
     else:
         self.recommend_imgs = imgs.strip().splitlines()