Esempio n. 1
0
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)
Esempio n. 2
0
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_()
Esempio n. 3
0
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_()
Esempio n. 4
0
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)
Esempio n. 5
0
 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)
Esempio n. 6
0
 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)
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 9
0
 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)
Esempio n. 10
0
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