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
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])
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)
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()
def logout(self): engine = harkfm.Engine() engine.lfm_logout()
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)
def emit_updated(props): engine = harkfm.Engine() if props and props['artist'] and props['track']: engine.current = harkfm.Track(props) else: engine.current = None