Пример #1
0
 def __render(self, file):
     engine = harkfm.Engine()
     template = self.__class__.loader.load(file)
     search_path = 'file:///' + self.__class__.loader.search_path[0].replace('\\', '/') + '/'
     html = template.generate(
         current=engine.current,
         lastfm=engine.lfm_props(),
         config=harkfm.Storage.config
     ).render('html', doctype='html')
     self.QWebEngineView.setHtml(html, QUrl(search_path))
     self.__class__._last_page = file
Пример #2
0
    def __init__(self, props=None):
        if props is None:
            props = {}

        if self.__class__.storage is None:
            self.__class__.storage = harkfm.Storage()
        if self.__class__.engine is None:
            self.__class__.engine = harkfm.Engine()
        if self.__class__.interface is None:
            self.__class__.interface = harkfm.Interface()
        if self.__class__.logger is None:
            self.__class__.logger = logging.getLogger('root')

        self.app = None

        self._artist = None
        self._artist_corrected = None
        self.artist_img = None
        self.artist_url = None
        self.artist_wiki = None
        self.artist_listeners = 0
        self.artist_plays_global = 0
        self.artist_plays = 0
        self.artist_tags = []
        self.artist_similar = []
        self.artist_gender = None
        self.artist_country = None

        self._track = None
        self._track_corrected = None
        self.track_url = None
        self.track_wiki = None
        self.track_duration = 3 * 60  # default tracks to 3 minutes
        self.track_plays = 0
        self.track_tags = []
        self.track_loved = None

        self._album = None
        self._album_corrected = None
        self.album_img = None
        self.album_url = None
        self.album_wiki = None
        self.album_year = 0

        self.start = 0
        self.listened = 0
        self.queued = 0

        self._corrected_gn = False
        self._corrected_lfm = False

        for prop in props.keys():
            setattr(self, prop, props[prop])
Пример #3
0
import harkfm

formatter = logging.Formatter(
    fmt=
    '[%(asctime)s] [%(levelname).4s] [%(filename)s:%(lineno)03d]  %(message)s',
    datefmt='%H:%M:%S')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger = logging.getLogger('root')
logger.setLevel(logging.INFO)
logger.addHandler(handler)

app = QApplication(sys.argv)
window = QMainWindow(flags=Qt.Window)
ui = PyQt5.uic.loadUi(
    os.path.join(os.path.dirname(sys.argv[0]), 'harkfm/interface.ui'), window)

# Init the interface
interface = harkfm.Interface(window, ui)
# Start track scanner
scanner = harkfm.Scanner()

window.show()
exit_code = app.exec_()
if exit_code == 0:
    engine = harkfm.Engine()
    engine.scrobble()
    while engine.scrobbling:
        time.sleep(0.1)
sys.exit(exit_code)
Пример #4
0
    def __init__(self, qMainWindow=None, qtDesigner=None):
        if self.__class__.logger is None:
            self.__class__.logger = logging.getLogger('root')

        if self.__class__.loader is None:
            self.__class__.loader = genshi.template.TemplateLoader(
                os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), 'www')),
                auto_reload=True
            )

        if self.__class__.qMainWindow is None and qMainWindow is not None:
            self.__class__.qMainWindow = qMainWindow

        if self.__class__.qtDesigner is None and qtDesigner is not None:
            self.__class__.qtDesigner = qtDesigner

            class WebEnginePage(QWebEnginePage):
                updated = pyqtSignal(str, float, str)

                def javaScriptConsoleMessage(self, level, msg, line, source):
                    harkfm.Interface.logger.debug('%s:%s  %s', source, line, msg)

                def acceptNavigationRequest(self, url, type, is_main_frame):
                    if type == QWebEnginePage.NavigationTypeLinkClicked:
                        webbrowser.open(url.toString())
                        return False
                    return True

                # Turn a jQuery.serialize() query into a dict
                def _deserialize(self, query):
                    form = {}
                    query = query.split('&')
                    for val in query:
                        val = val.split('=')
                        form[urllib.parse.unquote(val[0])] = urllib.parse.unquote(val[1])
                    return form

                @pyqtSlot()
                def update(self):
                    if engine.current is not None:
                        self.updated.emit(engine.current.elapsed, engine.current.percent, engine.current.remaining)

                @pyqtSlot()
                def queued(self):
                    queued = 0
                    if engine.current is not None:
                        queued = engine.current.queued
                    self.updated.emit(sys._getframe().f_code.co_name, queued)

                @pyqtSlot()
                def love(self):
                    engine.current.love()
                    interface = harkfm.Interface()
                    interface.index()

                @pyqtSlot()
                def unlove(self):
                    engine.current.unlove()
                    interface = harkfm.Interface()
                    interface.index()

                @pyqtSlot(str)
                def login(self, query):
                    form = self._deserialize(query)
                    storage = harkfm.Storage()
                    api_key = harkfm.Engine.config['apis']['last.fm']['key']
                    api_secret = harkfm.Engine.config['apis']['last.fm']['secret']
                    try:
                        network = pylast.get_lastfm_network(api_key, api_secret)
                        session_key = pylast.SessionKeyGenerator(network).get_session_key(form['username'],  pylast.md5(form['password']))
                        storage.config_set('apis/last.fm/session_key', session_key)
                        interface = harkfm.Interface()
                        interface.index()
                    except Exception as e:
                        harkfm.Interface.logger.error('%s  %s', type(e), e)

                @pyqtSlot()
                def logout(self):
                    engine = harkfm.Engine()
                    engine.lfm_logout()

                @pyqtSlot(str)
                def save_settings(self, form):
                    form = json.loads(form)
                    storage = harkfm.Storage()
                    for key in form:
                        if type(form[key]) is str and form[key].isdigit():
                            form[key] = int(form[key])
                        storage.config_set('settings/' + key, form[key])
                    interface = harkfm.Interface()
                    interface.index()

            # Set custom page
            page = WebEnginePage(self.QWebEngineView)
            page.profile().setHttpCacheType(QWebEngineProfile.NoCache)
            self.QWebEngineView.setPage(page)

            # Set custom channel
            channel = QWebChannel(page)
            channel.registerObject('py', page)
            page.setWebChannel(channel)

            engine = harkfm.Engine()  # init harkfm.Engine
            lfm_network = engine.lfm_login()
            if lfm_network is None:
                self.login()
            else:
                self.index()
Пример #5
0
 def logout(self):
     engine = harkfm.Engine()
     engine.lfm_logout()
Пример #6
0
            def run(self):
                engine = harkfm.Engine()
                firefox = harkfm.Firefox()

                windows = []
                while True:
                    # Scan for a new window
                    while len(windows) == 0:
                        if 'windows' in self.scanner._config and len(self.scanner._config['windows']) > 0:
                            if os.name == 'nt':
                                import win32gui

                                def win_search(hwnd, lParam):
                                    if win32gui.IsWindowVisible(hwnd):
                                        # Get window properties
                                        try:
                                            w_class = win32gui.GetClassName(hwnd)
                                            w_text = win32gui.GetWindowText(hwnd)
                                        except Exception as e:
                                            self.scanner.logger.error('%s  %s', type(e), e)
                                            return
                                        # Ignore some default windows
                                        if w_class in [
                                            'IME',
                                            'MSCTFIME UI',
                                            'tooltips_class32'
                                        ]:
                                            return
                                        # Look for match in self.scanner._config['windows']
                                        try:
                                            for idx, window in enumerate(self.scanner._config['windows']):
                                                if (
                                                    ('class' not in window['window'] or (w_class and re.search(window['window']['class'], w_class))) and
                                                    ('title' not in window['window'] or (w_text and re.search(window['window']['title'], w_text)))
                                                ):
                                                    windows.append((idx, hwnd, w_class, win32gui.GetWindowText))
                                                    break
                                        except Exception as e:
                                            self.scanner.logger.error('%s  %s', type(e), e)

                                win32gui.EnumWindows(win_search, None)

                                if firefox.pids():
                                    for hwnd in firefox.hwnd():
                                        if win32gui.IsWindow(hwnd):
                                            w_class = win32gui.GetClassName(hwnd) if hwnd is not None else ''
                                            for tab in firefox.tabs():
                                                w_text = tab['title'] if 'title' in tab else ''
                                                for idx, window in enumerate(self.scanner._config['windows']):
                                                    if (
                                                        ('class' not in window['window'] or re.search(window['window']['class'], w_class)) and
                                                        ('title' not in window['window'] or re.search(window['window']['title'], w_text))
                                                    ):
                                                        windows.append((idx, tab, w_class, firefox.tab_title))
                                                        break

                        time.sleep(0.5)

                    # Get info from window
                    if len(windows) > 0:
                        if os.name == 'nt':
                            import win32gui

                            # Get window properties
                            window = self.scanner._config['windows'][windows[0][0]]
                            if type(windows[0][1]) is int and not win32gui.IsWindow(windows[0][1]):
                                windows = []
                                self.updated.emit({})
                                continue
                            w_class = windows[0][2](windows[0][1]) if hasattr(windows[0][2], '__call__') else windows[0][2]
                            w_text = windows[0][3](windows[0][1]) if hasattr(windows[0][3], '__call__') else windows[0][3]

                            # Check if we lost window match
                            if (
                                not w_text or
                                ('class' in window['window'] and not re.search(window['window']['class'], w_class)) or
                                ('title' in window['window'] and not re.search(window['window']['title'], w_text))
                            ):
                                windows = []
                                self.updated.emit({})
                                continue

                            # Parse window title (if changed)
                            if not hasattr(engine.current, 'w_text') or w_text != engine.current.w_text:
                                props = {'w_text': w_text, 'app': window}
                                if 'title' in window['window']:
                                    w_text = harkfm.Util.regex(window['window']['title'], w_text)
                                for prop in window['regex']:
                                    props[prop] = harkfm.Util.regex(window['regex'][prop], w_text)
                                    if props[prop] is None: props[prop] = ''
                                    # Do replacements
                                    if self.scanner.storage.config_get('settings/correct/scanner'):
                                        for replace in self.scanner._config['replace']['all']:
                                            props[prop] = re.sub(replace[0], replace[1], props[prop])
                                        for replace in self.scanner._config['replace'][prop]:
                                            props[prop] = re.sub(replace[0], replace[1], props[prop])

                                self.updated.emit(props)

                    time.sleep(0.1)
Пример #7
0
 def emit_updated(props):
     engine = harkfm.Engine()
     if props and props['artist'] and props['track']:
         engine.current = harkfm.Track(props)
     else:
         engine.current = None