class DebuggerTest(UsesQApplication): def setUp(self): UsesQApplication.setUp(self) self.engine = QScriptEngine() self.debugger = QScriptEngineDebugger() self.has_suspended = 0 self.has_resumed = 0 self.count = 3 def suspended(self): self.has_suspended += 1 # Will emit evaluationResumed until there are more instructions to be run QTimer.singleShot( 100, self.debugger.action(QScriptEngineDebugger.StepIntoAction).trigger) def resumed(self): # Will be called when debugger.state() change from Suspended to Running # except for the first time. self.has_resumed += 1 def testBasic(self): '''Interrupt and resume evaluation with QScriptEngineDebugger''' self.debugger.attachTo(self.engine) self.debugger.setAutoShowStandardWindow(False) self.debugger.connect(SIGNAL('evaluationSuspended()'), self.suspended) self.debugger.connect(SIGNAL('evaluationResumed()'), self.resumed) self.debugger.action(QScriptEngineDebugger.InterruptAction).trigger() self.engine.evaluate("3+4\n2+1\n5+1") self.assert_(self.has_resumed >= 1) self.assert_(self.has_suspended >= 1)
class DebuggerTest(UsesQApplication): def setUp(self): UsesQApplication.setUp(self) self.engine = QScriptEngine() self.debugger = QScriptEngineDebugger() self.has_suspended = 0 self.has_resumed = 0 self.count = 3 def suspended(self): self.has_suspended += 1 # Will emit evaluationResumed until there are more instructions to be run QTimer.singleShot(100, self.debugger.action(QScriptEngineDebugger.StepIntoAction).trigger) def resumed(self): # Will be called when debugger.state() change from Suspended to Running # except for the first time. self.has_resumed += 1 def testBasic(self): '''Interrupt and resume evaluation with QScriptEngineDebugger''' self.debugger.attachTo(self.engine) self.debugger.setAutoShowStandardWindow(False) self.debugger.connect(SIGNAL('evaluationSuspended()'), self.suspended) self.debugger.connect(SIGNAL('evaluationResumed()'), self.resumed) self.debugger.action(QScriptEngineDebugger.InterruptAction).trigger() self.engine.evaluate("3+4\n2+1\n5+1") self.assert_(self.has_resumed >= 1) self.assert_(self.has_suspended >= 1)
def setUp(self): UsesQApplication.setUp(self) self.engine = QScriptEngine() self.debugger = QScriptEngineDebugger() self.has_suspended = 0 self.has_resumed = 0 self.count = 3
def main(argv=None): if argv is None: argv = sys.argv app = QApplication(argv) engine = QScriptEngine() if HAS_DEBUGGER: debugger = QScriptEngineDebugger() debugger.attachTo(engine) debugWindow = debugger.standardWindow() debugWindow.resize(1024, 640) scriptFileName = './calculator.js' scriptFile = QFile(scriptFileName) scriptFile.open(QIODevice.ReadOnly) engine.evaluate(unicode(scriptFile.readAll()), scriptFileName) scriptFile.close() loader = QUiLoader() ui = loader.load(':/calculator.ui') ctor = engine.evaluate('Calculator') scriptUi = engine.newQObject(ui, QScriptEngine.ScriptOwnership) calc = ctor.construct([scriptUi]) if HAS_DEBUGGER: display = ui.findChild(QLineEdit, 'display') display.connect(display, SIGNAL('returnPressed()'), debugWindow, SLOT('show()')) ui.show() return app.exec_()
def testQScriptEngine(self): engine = QScriptEngine() obj = engine.evaluate( "({ unitName: 'Celsius', toKelvin: function(x) { return x + 273; } })" ) toKelvin = obj.property("toKelvin") result = toKelvin.call(obj, [100]) self.assertEqual(result.toNumber(), 373)
def __init__(self): if not self.ENGINE: self.ENGINE = QScriptEngine() if not self.DATA: self.DATA = JS if not self.COOKIE_JAR: self.COOKIE_JAR = cookielib.CookieJar() if not self.OPENER: self.OPENER = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.COOKIE_JAR))
def testScriptQProperty(self): qapp = QCoreApplication([]) myEngine = QScriptEngine() obj = MyObject() scriptObj = myEngine.newQObject(obj) myEngine.globalObject().setProperty("obj", scriptObj) myEngine.evaluate("obj.x = 42") self.assertEqual(scriptObj.property("x").toInt32(), 42) self.assertEqual(obj.property("x"), 42)
def __init__(self): self.app = QApplication.instance() if self.app is None: self.app = QCoreApplication([]) self.engine = QScriptEngine() self.globalObject = self.engine.globalObject() # There were some problems evalating javascript inside a function callback. QtSide's bindings for QScriptEngine # didn't seem prepared to handle it (it breaks in weird hard-to-debug ways) # It is however not a problem if you use a wrapped QObject for the callback instead of using engine.newFunction(). # The workaround here is to pass a wrapped QObject, and then evaluate javascript to create a function that calls # a method of the wrapped QObject. # Also note: Wrapped QObjects passed to QtSide are not refcounted in Python! To work around this, a reference to # "RequireObj" is stored in the JSEngine instance self.requireObj = JsEngineRequireClass(self.engine) self.addObject('RequireObj', self.requireObj) self.evaluate(""" function require(arg) { return RequireObj.require(arg); } """)
class JsEngine: def __init__(self): self.app = QApplication.instance() if self.app is None: self.app = QCoreApplication([]) self.engine = QScriptEngine() self.globalObject = self.engine.globalObject() # There were some problems evalating javascript inside a function callback. QtSide's bindings for QScriptEngine # didn't seem prepared to handle it (it breaks in weird hard-to-debug ways) # It is however not a problem if you use a wrapped QObject for the callback instead of using engine.newFunction(). # The workaround here is to pass a wrapped QObject, and then evaluate javascript to create a function that calls # a method of the wrapped QObject. # Also note: Wrapped QObjects passed to QtSide are not refcounted in Python! To work around this, a reference to # "RequireObj" is stored in the JSEngine instance self.requireObj = JsEngineRequireClass(self.engine) self.addObject('RequireObj', self.requireObj) self.evaluate(""" function require(arg) { return RequireObj.require(arg); } """) # Sets a variable in the global object def addObject(self, name, obj): wrappedObject = pyObjectToScriptValue(self.engine, obj) self.engine.globalObject().setProperty(name, wrappedObject) # Adds a python function to the global object, wrapping it def addFunction(self, name, func): f = lambda context,engine: pyObjectToScriptValue(engine, func(*_contextToArguments(context))) wrappedFunction = self.engine.newFunction(f) self.engine.globalObject().setProperty(name, wrappedFunction) # Adds a python function to the global object, not wrapping it (it gets passed raw context and engine arguments) def addRawFunction(self, name, func): wrappedFunction = self.engine.newFunction(func) self.engine.globalObject().setProperty(name, wrappedFunction) # Evaluate some javascript code def evaluate(self, code): result = self.engine.evaluate(code) if self.engine.hasUncaughtException(): raise JsEngineException(result, self.engine) return scriptValueToPyObject(result)
class JsEngine: def __init__(self): self.app = QApplication.instance() if self.app is None: self.app = QCoreApplication([]) self.engine = QScriptEngine() self.globalObject = self.engine.globalObject() # There were some problems evalating javascript inside a function callback. QtSide's bindings for QScriptEngine # didn't seem prepared to handle it (it breaks in weird hard-to-debug ways) # It is however not a problem if you use a wrapped QObject for the callback instead of using engine.newFunction(). # The workaround here is to pass a wrapped QObject, and then evaluate javascript to create a function that calls # a method of the wrapped QObject. # Also note: Wrapped QObjects passed to QtSide are not refcounted in Python! To work around this, a reference to # "RequireObj" is stored in the JSEngine instance self.requireObj = JsEngineRequireClass(self.engine) self.addObject('RequireObj', self.requireObj) self.evaluate(""" function require(arg) { return RequireObj.require(arg); } """) # Sets a variable in the global object def addObject(self, name, obj): wrappedObject = pyObjectToScriptValue(self.engine, obj) self.engine.globalObject().setProperty(name, wrappedObject) # Adds a python function to the global object, wrapping it def addFunction(self, name, func): f = lambda context, engine: pyObjectToScriptValue( engine, func(*_contextToArguments(context))) wrappedFunction = self.engine.newFunction(f) self.engine.globalObject().setProperty(name, wrappedFunction) # Adds a python function to the global object, not wrapping it (it gets passed raw context and engine arguments) def addRawFunction(self, name, func): wrappedFunction = self.engine.newFunction(func) self.engine.globalObject().setProperty(name, wrappedFunction) # Evaluate some javascript code def evaluate(self, code): result = self.engine.evaluate(code) if self.engine.hasUncaughtException(): raise JsEngineException(result, self.engine) return scriptValueToPyObject(result)
def engine(self): if not self._engine: self._engine = QScriptEngine() return self._engine
def testQScriptEngine(self): engine = QScriptEngine() obj = engine.evaluate("({ unitName: 'Celsius', toKelvin: function(x) { return x + 273; } })") toKelvin = obj.property("toKelvin") result = toKelvin.call(obj, [100]) self.assertEqual(result.toNumber(), 373)
class Search(object): """Main search class""" TYPE_TRACKS = 0 TYPE_ALBUMS = 1 TYPE_ARTISTS = 2 TYPES = { TYPE_TRACKS: 'tracks', TYPE_ALBUMS: 'albums', TYPE_ARTISTS: 'artists', } URL = 'http://music.yandex.ru/fragment/search?text=%(text)s&type=%(type)s&page=%(page)d' TRACKS_CACHE = {} ALBUMS_CACHE = {} ARTISTS_CACHE = {} DATA = None ENGINE = None OPENER = None COOKIE_JAR = None LOGIN = None PASSWORD = None AUTHENTICATED = False __instance = None def __init__(self): if not self.ENGINE: self.ENGINE = QScriptEngine() if not self.DATA: self.DATA = JS if not self.COOKIE_JAR: self.COOKIE_JAR = cookielib.CookieJar() if not self.OPENER: self.OPENER = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.COOKIE_JAR)) def open(self, url): """Open with cookies""" return self.OPENER.open(url) def get_key(self, key): """Get secret key for track loading""" base = QScriptProgram('var s="%s"; ' % (key,) + self.DATA) p = self.ENGINE.evaluate(base) return p.toString() def _class_filter(self, cls_name): """Create BeautifulSoup class filter""" return {'class': re.compile(r'\b%s\b' % cls_name)} def _remove_html(self, data): p = re.compile(r'<.*?>') try: return p.sub('', data) except TypeError: return data def _get_tracks(self, soup): for track in soup.findAll('div', self._class_filter('b-track')): track = json.loads(track['onclick'][7:]) # remove return yield Track.get( id=track['id'], title=track['title'], artist_id=track['artist_id'], artist_title=track['artist'], album_id=track['album_id'], album_title=track['album'], album_cover=track['cover'], storage_dir=track['storage_dir'] ) def _get_albums(self, soup): for album in soup.findAll('div', self._class_filter('b-albums')): cover_a = album.find('div', self._class_filter('b-albums__cover')).find('a') artist_a = album.find('a', self._class_filter('b-link_class_albums-title-link') ) yield Album.get( id=cover_a['href'].split('/')[-1], title=self._remove_html(album.find('a', self._class_filter('b-link_class_albums-title-link') ).__unicode__()), cover=cover_a.find('img')['src'], artist_id=artist_a['href'].split('/')[-1], artist_title=self._remove_html(artist_a.__unicode__()) ) def _get_artists(self, soup): for artist in imap( lambda obj: obj.find('a'), soup.findAll('div', self._class_filter('b-artist-group')) ): yield Artist.get( id=artist['href'].split('/')[-1], title=self._remove_html(artist.__unicode__()) ) def _get(self, type, soup): if type == self.TYPE_TRACKS: return self._get_tracks(soup) elif type == self.TYPE_ALBUMS: return self._get_albums(soup) elif type == self.TYPE_ARTISTS: return self._get_artists(soup) def _get_result(self, type, text): # start from 0! pages_count = 1 current_page = 0 while pages_count > current_page: result = self.open(self.URL % { 'text': text, 'type': self.TYPES[type], 'page': current_page, }).read() soup = BeautifulSoup(result) try: try: pages_count = int(soup.findAll('a', self._class_filter('b-pager__page'))[-1].text) # start form 1! except UnicodeEncodeError: # fix work with ... page pages_count = int(soup.findAll('a', self._class_filter('b-pager__page'))[-2].text) # start form 1! current_page = int(soup.find('b', self._class_filter('b-pager__current')).text) # start from 1! except IndexError: current_page += 1 # if only one page for obj in self._get(type, soup): yield obj def search(self, type, text, single=False): if type not in self.TYPES: raise AttributeError('Wrong type') result = self._get_result(type, text) if single: return next(islice(result, 0, None)) else: return result