コード例 #1
0
class LoggerPanel(DisclosurePanel):
    def __init__(self, maxhistory=100, maxloglinelength=200, headerStyleName=None, panelStyleName=None,
                 buttonStyleName=None, labelStyleName=None):
        super(LoggerPanel, self).__init__(self, header='BLAH', isOpen=False)
        self.labelStyleName = labelStyleName
        self.maxhistory = maxhistory
        self.maxloglinelength = maxloglinelength

        self.getHeader().setStyleName(headerStyleName)
        self.logpanel = VerticalPanel(StyleName=panelStyleName)
        self.setContent(self.logpanel)

        self.clearbutton = Button('Clear', listener=self.clear, StyleName=buttonStyleName)
        self.logpanel.add(self.clearbutton)
        self.updateHeaderText()
    def log(self, string):
        self.logpanel.add(Label(string[:self.maxloglinelength], StyleName=self.labelStyleName))
        widgcnt = self.logpanel.getWidgetCount()
        if widgcnt > self.maxhistory:
            for i in range(0, widgcnt - self.maxhistory):
                self.logpanel.remove(self.logpanel.getWidget(i))
        self.updateHeaderText()
    def __call__(self, string):
        self.log(string)
        return
    def updateHeaderText(self):
        self.getHeader().setText('Logging: %s items' % (self.logpanel.getWidgetCount() - 1))
    def clear(self):
        self.logpanel.clear()
        self.logpanel.add(self.clearbutton)
        self.updateHeaderText()
コード例 #2
0
class ContentPanel(HorizontalPanel):
    def __init__(self, onItemPublish, onItemLike, onItemDislike, onSort=None, onFilter=None):
        super(ContentPanel, self).__init__()
        self.newItemArgs = {'onPublish':onItemPublish, 'onLike':onItemLike, 'onDislike':onItemDislike}

        self.sidebar = SideVerticalToolbar(onSort=onSort, onFilter=onFilter)
        text = '<br>'.join(list('More Tools'))
        self.sidebarEdge = Button(text, listener=self.onSidebarEdgeClick, StyleName=Styles.TOOLBAR_VERTICALEDGE)
        self.add(self.sidebarEdge)

        self.contentpanel = VerticalPanel()
        self.add(self.contentpanel)
        self.allContentCells = []
        return
    def _getAllContentItemCells(self):
        for widg in self.contentpanel.getChildren():
            if isinstance(widg, ContentItemCell):
                yield widg
    def addItems(self, items):
        for item in items:
            widg = ContentItemCell(item, **self.newItemArgs)
            self.contentpanel.add(widg)
            self.allContentCells.append(widg)
    def itemCount(self):
        return len(self.allContentCells)
    def onSidebarEdgeClick(self):
        #If parent is set, hide it- otherwise, remove it
        if self.sidebar.parent:
            self.sidebar.removeFromParent()
        else:
            self.insert(self.sidebar, 0)
    def setItemsOpenState(self, state):
        for cell in self._getAllContentItemCells():
            cell.setOpen(state)
    def sortItems(self, keyselector, ascending):
        allchildren = list(self.contentpanel.getChildren())
        self.contentpanel.clear()
        sall = sorted(allchildren, key=keyselector)
        if not ascending:
            sall = reversed(sall)
        for child in sall:
            self.contentpanel.add(child)
    def filterItems(self, predicate):
        self.contentpanel.clear()
        cellsToShow = [cell for cell in self.allContentCells if predicate(cell)]
        for cell in cellsToShow:
            self.contentpanel.add(cell)
コード例 #3
0
ファイル: Chapter.py プロジェクト: Afey/pyjs
class Chapter(Sink):
    def __init__(self):

        Sink.__init__(self)

        self.vp = VerticalPanel()
        self.initWidget(self.vp)
        self.loaded = False

    def onShow(self):

        if self.loaded:
            return

        self.name = self.name.replace(" ", "_")
        self.name = self.name.lower()
        HTTPRequest().asyncGet("%s.txt" % self.name, ChapterLoader(self))

    def setChapter(self, text):
        self.loaded = True

        self.text = text + '\n'

        self.ul_stack1 = 0
        self.ul_stack2 = 0
        self.doing_code = 0
        self.custom_style = False
        self.txt = ''
        self.para = ''
        self.up_to = 0

        Timer(1, self)

    def onTimer(self, timer):

        count = 0
        while count < 10:
            count += 1
            idx = self.text.find("\n", self.up_to)
            if idx < 0:
                self.text = None
                break
            self.process_line(self.text[self.up_to:idx])
            self.up_to = idx+1

        if self.text:
            timer.schedule(1)


    def process_line(self, line):

        if self.doing_code:
            if line == "}}":
                self.doing_code = 0
                self.custom_style = False
                line = "</pre>"
                self.txt += line
                panel = sect_markup(self.txt, self.name)
                self.vp.add(panel)
                self.txt = ''
                return
            if line:
                if not self.custom_style:
                    self.txt += escape(line)
                else:
                    self.txt += line
            self.txt += "\n"
            return

        line = line.strip()
        ul_line = False
        ul_line2 = False
        addline = ''
        add = False
        addpara = False
        if not line:
            line = ""
            addpara = True
        elif line[:2] == "{{":
            self.doing_code = 1
            addpara = True
            if len(line) > 4 and line[2] == '-':
                addline = "<pre class='chapter_%s'>" % line[3:]
                self.custom_style = True
            elif len(line) > 2:
                addline = "<pre class='chapter_code'>%s" % line[2:]
            else:
                addline = "<pre class='chapter_code'>"
        elif line[:2] == '= ' and line[-2:] == ' =':
            addline = "<h1 class='chapter_heading1>%s</h1>" % qr(line[2:-2])
            add = True
            addpara = True
        elif line[:3] == '== ' and line[-3:] == ' ==':
            addline = "<h2 class='chapter_heading2>%s</h2>" % qr(line[3:-3])
            add = True
            addpara = True
        elif line[:2] == '* ':
            if not self.ul_stack1:
                self.txt += "<ul class='chapter_list1'>\n"
            addline = "<li class='chapter_listitem1'/>%s\n" % ts(line[2:], 0)
            self.ul_stack1 = True
            ul_line = True
            addpara = True
        elif line[:3] == '** ':
            if not self.ul_stack2:
                self.txt += "<ul class='chapter_list2'>\n"
            addline = "<li class='chapter_listitem2'/>%s\n" % ts(line[2:], 0)
            self.ul_stack2 = True
            ul_line2 = True
            ul_line = True
        if self.ul_stack2 and not ul_line2:
            self.ul_stack2 = False
            self.txt += "</ul>\n"
        if self.ul_stack1 and not ul_line:
            self.ul_stack1 = False
            self.txt += "</ul>\n"
        if addline:
            self.txt += addline + "\n"
        elif line:
            line = line.replace("%", "&#37;")
            self.para += line + "\n"
        if not self.ul_stack2 and not self.ul_stack1 and not self.doing_code :
            add = True
        if self.para and addpara:
            self.para = "<p class='chapter_para'>%s</p>" % urlmap(self.para, 0)
            panel = sect_markup(self.para, self.name)
            self.vp.add(panel)
            self.para = ''
        if add:
            panel = sect_markup(self.txt, self.name)
            self.vp.add(panel)
            self.txt = ''

    def onError(self, text, code):
        self.vp.clear()
        self.vp.add(HTML("TODO: Chapter '%s' not loaded" % self.name))
        self.vp.add(HTML(text))
        self.vp.add(HTML(code))
コード例 #4
0
class SWFUploadExample(SWFUploadInterface):
    def onModuleLoad(self):
        self.panel = VerticalPanel()
        self.panel.setSpacing(10)
        RootPanel().add(self.panel)

        self.swfUpload = self.getSWFUpload()
        self.panel.add(self.swfUpload)

        self.fileids = []
        self.queue = VerticalPanel()
        self.panel.add(self.queue)

        startButton = Button('Start Upload')
        startButton.addClickListener(getattr(self, 'onStartUpload'))
        self.panel.add(startButton)

        self.progress = Label()
        self.panel.add(self.progress)

    def getSWFUpload(self):
        swfUpload = SWFUpload()
        swfUpload.setSettings(self.getSettings())
        swfUpload.setID('SWFUploadPanel')
        return swfUpload

    def showQueue(self):
        self.queue.clear()
        for fileid in self.fileids:
            file = self.swfUpload.getFile(fileid)
            label = Label('%s (%s Bytes)' % (file.name, file.size))
            self.queue.add(label)

    def getSettings(self):
        settings = Settings()
        settings.setURL('upload.html')

        settings.setButtonHTML('<span class="uploadButton">add Files</span>')
        settings.setButtonCSS(
            '.uploadButton { font-size: 12; font-weight: bold; }')
        settings.setButtonWidth(60)
        settings.setButtonHeight(25)
        settings.setButtonTopPadding(10)
        settings.setButtonLeftPadding(5)

        settings.setEventListener(self)
        settings.setFlashURL('swf/swfupload.swf')

        return settings

    def onStartUpload(self):
        #log.writebr('Starting Upload')
        self.swfUpload.startUpload()

    """
    SWFUpload Events
    """

    def swfUploadLoaded(self):
        #log.writebr('swfUploadLoaded')
        pass

    def uploadProgress(self, file, bytesLoaded, totalBytes):
        self.progress.setText('%s - %s of %s uploaded' %
                              (file.name, bytesLoaded, totalBytes))

    def uploadError(self, file, errorCode, message):
        log.writebr('uploadError: %s, %s' % (errorCode, message))

    def uploadSuccess(self, file, receivedResponse, serverData):
        self.fileids.remove(file.id)
        self.showQueue()

    def uploadComplete(self, file):
        #log.writebr('uploadComplete: %s' % file.name)
        if len(self.fileids) > 0:
            self.swfUpload.startUpload()
        else:
            self.progress.setText('All files uploaded')

    def fileDialogStart(self):
        #log.writebr('fileDialogStart')
        pass

    def fileQueued(self, file):
        #log.writebr('fileQueued: %s' % file.name)
        self.fileids.append(file.id)

    def fileQueueError(self, file, errorCode, message):
        log.writebr('fileQueueError: %s, %s' % (errorCode, message))

    def fileDialogComplete(self, sel, qu, tqu):
        #log.writebr('fileDialogComplete: %s, %s, %s' % (sel, qu, tqu))
        self.showQueue()

    def uploadStart(self, file):
        #log.writebr('uploadStart')
        # Do something before the upload starts, and return True to start the upload
        return True
コード例 #5
0
ファイル: swfu.py プロジェクト: brodybits/pyjs
class SWFUploadExample(SWFUploadInterface):
    
    def onModuleLoad(self):
        self.panel = VerticalPanel()
        self.panel.setSpacing(10)
        RootPanel().add(self.panel)
        
        self.swfUpload = self.getSWFUpload()
        self.panel.add(self.swfUpload)
        
        self.fileids = []
        self.queue = VerticalPanel()
        self.panel.add(self.queue)
        
        startButton = Button('Start Upload')
        startButton.addClickListener(getattr(self, 'onStartUpload'))
        self.panel.add(startButton)
        
        self.progress = Label()
        self.panel.add(self.progress)
    
    def getSWFUpload(self):
        swfUpload = SWFUpload()
        swfUpload.setSettings(self.getSettings())
        swfUpload.setID('SWFUploadPanel')
        return swfUpload
        
    def showQueue(self):
        self.queue.clear()
        for fileid in self.fileids:
            file = self.swfUpload.getFile(fileid)
            label = Label('%s (%s Bytes)' % (file.name, file.size))
            self.queue.add(label)
        
    def getSettings(self):
        settings = Settings()
        settings.setURL('upload.html')
        
        settings.setButtonHTML('<span class="uploadButton">add Files</span>')
        settings.setButtonCSS('.uploadButton { font-size: 12; font-weight: bold; }')
        settings.setButtonWidth(60)
        settings.setButtonHeight(25)
        settings.setButtonTopPadding(10)
        settings.setButtonLeftPadding(5)
        
        settings.setEventListener(self)
        settings.setFlashURL('swf/swfupload.swf')
        
        return settings
    
    def onStartUpload(self):
        #log.debug('Starting Upload')
        self.swfUpload.startUpload()
        
    """
    SWFUpload Events
    """
    
    def swfUploadLoaded(self):
        #log.debug('swfUploadLoaded')
        pass
        
    def uploadProgress(self, file, bytesLoaded, totalBytes):
        self.progress.setText('%s - %s of %s uploaded' % (file.name, bytesLoaded, totalBytes))
        
    def uploadError(self, file, errorCode, message):
        log.debug('uploadError: %s, %s' % (errorCode, message))
    
    def uploadSuccess(self, file, receivedResponse, serverData):
        self.fileids.remove(file.id)
        self.showQueue()
        
    def uploadComplete(self, file):
        #log.debug('uploadComplete: %s' % file.name)
        if len(self.fileids) > 0:
            self.swfUpload.startUpload()
        else:
            self.progress.setText('All files uploaded')
        
    def fileDialogStart(self):
        #log.debug('fileDialogStart')
        pass
        
    def fileQueued(self, file):
        #log.debug('fileQueued: %s' % file.name)
        self.fileids.append(file.id)
        
    def fileQueueError(self, file, errorCode, message):
        log.debug('fileQueueError: %s, %s' % (errorCode, message))
        
    def fileDialogComplete(self, sel, qu, tqu):
        #log.debug('fileDialogComplete: %s, %s, %s' % (sel, qu, tqu))
        self.showQueue()
        
    def uploadStart(self, file):
        #log.debug('uploadStart')
        # Do something before the upload starts, and return True to start the upload
        return True
コード例 #6
0
ファイル: Chapter.py プロジェクト: pombredanne/pyjamas
class Chapter(Sink):
    def __init__(self):

        Sink.__init__(self)

        self.vp = VerticalPanel()
        self.initWidget(self.vp)
        self.loaded = False

    def onShow(self):

        if self.loaded:
            return 

        self.name = self.name.replace(" ", "_")
        self.name = self.name.lower()
        HTTPRequest().asyncGet("%s.txt" % self.name, ChapterLoader(self))

    def setChapter(self, text):
        self.loaded = True

        self.text = text + '\n'

        self.ul_stack1 = 0
        self.ul_stack2 = 0
        self.doing_code = 0
        self.custom_style = False
        self.txt = ''
        self.para = ''
        self.up_to = 0

        Timer(1, self)

    def onTimer(self, sender):

        count = 0
        while count < 10:
            count += 1
            idx = self.text.find("\n", self.up_to)
            if idx < 0:
                self.text = None
                break
            self.process_line(self.text[self.up_to:idx])
            self.up_to = idx+1

        if self.text:
            Timer(1, self)


    def process_line(self, line):

        if self.doing_code:
            if line == "}}":
                self.doing_code = 0
                self.custom_style = False
                line = "</pre>"
                self.txt += line
                panel = sect_markup(self.txt, self.name)
                self.vp.add(panel)
                self.txt = ''
                return
            if line:
                if not self.custom_style:
                    self.txt += escape(line)
                else:
                    self.txt += line
            self.txt += "\n"
            return
            
        line = line.strip()
        ul_line = False
        ul_line2 = False
        addline = ''
        add = False
        addpara = False
        if not line:
            line = ""
            addpara = True
        elif line[:2] == "{{":
            self.doing_code = 1
            addpara = True
            if len(line) > 4 and line[2] == '-':
                addline = "<pre class='chapter_%s'>" % line[3:]
                self.custom_style = True
            elif len(line) > 2:
                addline = "<pre class='chapter_code'>%s" % line[2:]
            else:
                addline = "<pre class='chapter_code'>"
        elif line[:2] == '= ' and line[-2:] == ' =':
            addline = "<h1 class='chapter_heading1>%s</h1>" % qr(line[2:-2])
            add = True
            addpara = True
        elif line[:3] == '== ' and line[-3:] == ' ==':
            addline = "<h2 class='chapter_heading2>%s</h2>" % qr(line[3:-3])
            add = True
            addpara = True
        elif line[:2] == '* ':
            if not self.ul_stack1:
                self.txt += "<ul class='chapter_list1'>\n"
            addline = "<li class='chapter_listitem1'/>%s\n" % ts(line[2:], 0)
            self.ul_stack1 = True
            ul_line = True
            addpara = True
        elif line[:3] == '** ':
            if not self.ul_stack2:
                self.txt += "<ul class='chapter_list2'>\n"
            addline = "<li class='chapter_listitem2'/>%s\n" % ts(line[2:], 0)
            self.ul_stack2 = True
            ul_line2 = True
            ul_line = True
        if self.ul_stack2 and not ul_line2:
            self.ul_stack2 = False
            self.txt += "</ul>\n"
        if self.ul_stack1 and not ul_line:
            self.ul_stack1 = False
            self.txt += "</ul>\n"
        if addline:
            self.txt += addline + "\n"
        elif line:
            line = line.replace("%", "&#37;")
            self.para += line + "\n"
        if not self.ul_stack2 and not self.ul_stack1 and not self.doing_code :
            add = True
        if self.para and addpara:
            self.para = "<p class='chapter_para'>%s</p>" % urlmap(self.para, 0)
            panel = sect_markup(self.para, self.name)
            self.vp.add(panel)
            self.para = ''
        if add:
            panel = sect_markup(self.txt, self.name)
            self.vp.add(panel)
            self.txt = ''

    def onError(self, text, code):
        self.vp.clear()
        self.vp.add(HTML("TODO: Chapter '%s' not loaded" % self.name))
        self.vp.add(HTML(text))
        self.vp.add(HTML(code))
コード例 #7
0
class Photos(Composite):
    def __init__(self):
        Composite.__init__(self)

        self.albums = []
        self.photos = []
        self.grid = Grid(4, 4, CellPadding=4, CellSpacing=4)
        self.grid.addTableListener(self)
        self.drill = 0
        self.pos = 0
        self.up = Button("Up", self)
        self.next = Button("Next", self)
        self.prev = Button("Prev", self)
        self.timer = Timer(notify=self)
        self.userid = "jameskhedley"
        self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb"
        self.doRESTQuery(self.album_url, self.timer)

        self.vp = VerticalPanel()
        self.disclosure = DisclosurePanel(
            "Click for boring technical details.")
        self.disclosure.add(
            HTML(
                '''<p>OK so you want to write client JS to do a RESTful HTTP query from picasa right?
				 Well you can't because of the Same Origin Policy. Basically this means that
				 because the domain of the query and the domain of the hosted site are different,
				 then that could well be a cross-site scripting (XSS) attack. So, the workaround is to
				 do the call from a script tag so the JSON we get back is part of the document.
				 But since we don't know what URL to hit yet, once we find out then we have to inject
				 a new script tag dynamically which the browser will run as soon as we append it.
				 To be honest I'm not 100% why Google use RESTful services and not JSON-RPC or somesuch,
				 which would be easier. Well, easier for me.'''))

        self.IDPanel = HorizontalPanel()
        self.IDPanel.add(Label("Enter google account:"))
        self.IDButton = Button("Go", self)

        self.IDBox = TextBox()
        self.IDBox.setText(self.userid)
        self.IDPanel.add(self.IDBox)
        self.IDPanel.add(self.IDButton)
        self.vp.add(self.IDPanel)
        self.vp.add(self.disclosure)
        self.vp.add(self.grid)

        self.initWidget(self.vp)

    def doRESTQuery(self, url, timer):
        """this is a totally different from an RPC call in that we have to
           dynamically add script tags to the DOM when we want to query the
           REST API. These rely on callbacks in the DOM so we can either add
           them dynamically or pre-define them in public/Main.html.
           Once we've done that have to wait for the response.
           Which means we need to provide a listener for the timer"""

        new_script = DOM.createElement("script")
        DOM.setElemAttribute(new_script, "src", url)
        DOM.setElemAttribute(new_script, "type", "text/javascript")
        doc().body.appendChild(new_script)
        self.timer.schedule(100)

    def onCellClicked(self, sender, row, col):
        if self.drill == 0:
            self.drill += 1
            self.vp.clear()
            self.grid.clear()
            self.vp.add(self.up)
            self.vp.add(self.grid)
            gridcols = self.grid.getColumnCount()
            album = self.albums[row + col + (row * (gridcols - 1))]
            url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "/albumid/" + album[
                "id"] + "?alt=json-in-script&kind=photo&hl=en_US&callback=restCb"
            self.doRESTQuery(url, self.timer)
        elif self.drill == 1:
            self.drill += 1
            gridcols = self.grid.getColumnCount()
            self.pos = row + col + (row * (gridcols - 1))
            photo = self.photos[self.pos]
            self.vp.clear()
            self.fullsize = HTML('<img src="' + photo["full"] + '"/>')
            hp = HorizontalPanel()
            hp.add(self.up)
            hp.add(self.prev)
            hp.add(self.next)
            hp.setSpacing(8)
            self.vp.add(hp)
            self.vp.add(self.fullsize)

    def onClick(self, sender):
        if sender == self.IDButton:
            self.userid = self.IDBox.getText()
            if self.userid == "" or self.userid.isdigit():
                return
            self.drill = 0
            self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb"
            self.grid.clear()
            self.doRESTQuery(self.album_url, self.timer)
        else:
            if self.drill == 2:
                if sender == self.up:
                    self.drill = 1
                    self.vp.clear()
                    self.vp.add(self.up)
                    self.vp.add(self.grid)
                    self.fillGrid(self.photos, "photos")
                else:
                    if sender == self.next:
                        if self.pos >= len(self.photos):
                            return
                        self.pos += 1
                    elif sender == self.prev:
                        if self.pos < 1:
                            return
                        self.pos -= 1
                    photo = self.photos[self.pos]
                    self.fullsize.setHTML('<img src="' + photo["full"] + '"/>')
            elif self.drill == 1:
                self.drill = 0
                self.vp.clear()
                self.vp.add(self.IDPanel)
                self.vp.add(self.disclosure)
                self.vp.add(self.grid)
                self.fillGrid(self.albums, "albums")

    def onTimer(self, timer):
        fd = doc().getElementById("__pygwt_hiddenData")
        receiver = fd.innerHTML

        if receiver == 'wait':
            self.timer.schedule(1000)
            return

        fd.innerHTML = 'wait'

        if self.drill == 0:
            self.parseAlbums(receiver)
            self.fillGrid(self.albums, "albums")
        elif self.drill == 1:
            self.parsePhotos(receiver)
            self.fillGrid(self.photos, "photos")

    def fillGrid(self, items, type):
        self.grid.clear()
        cols = self.grid.getColumnCount()
        self.grid.resizeRows((len(items) / cols) + 1)
        rows = self.grid.getRowCount()
        for i in range(len(items)):
            vp = VerticalPanel()
            if type == 'photos':
                vp.add(items[i]['thumb'])
            else:
                vp.add(items[i]['thumb'])
                vp.add(items[i]['title'])
            self.grid.setWidget(int(i / cols), i % cols, vp)

    def parsePhotos(self, items):
        photo_list = json.loads(items)
        self.photos = []
        for ph in photo_list:
            aphoto = {}
            aphoto['thumb'] = HTML(
                '<img src="' +
                ph[u"media$group"][u"media$thumbnail"][1][u"url"] + '"/>')
            aphoto['full'] = ph[u"media$group"][u"media$content"][0][u"url"]
            self.photos.append(aphoto)

    def parseAlbums(self, items):
        album_list = json.loads(items)
        self.albums = []
        for al in album_list:
            analbum = {}
            analbum['title'] = HTML(al[u"title"][u"$t"])
            analbum['thumb'] = HTML(
                '<img src="' +
                al[u"media$group"][u"media$thumbnail"][0][u"url"] + '"/>')
            url = al[u"id"][u"$t"]
            analbum['id'] = url.split(u'albumid/')[1].split(u'?alt')[0]
            self.albums.append(analbum)
コード例 #8
0
ファイル: Photos.py プロジェクト: anandology/pyjamas
class Photos(Composite):
    def __init__(self):
        Composite.__init__(self)

        self.albums = []
        self.photos = []
        self.grid = Grid(4, 4, CellPadding=4, CellSpacing=4)
        self.grid.addTableListener(self)
        self.drill = 0
        self.pos = 0
        self.up = Button("Up", self) 
        self.next = Button("Next", self) 
        self.prev = Button("Prev", self) 
        self.timer = Timer(notify=self)
        self.userid = "jameskhedley"
        self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb"
        self.doRESTQuery(self.album_url, self.timer)

        self.vp = VerticalPanel()
        self.disclosure = DisclosurePanel("Click for boring technical details.") 
        self.disclosure.add(HTML('''<p>OK so you want to write client JS to do a RESTful HTTP query from picasa right?
				 Well you can't because of the Same Origin Policy. Basically this means that
				 because the domain of the query and the domain of the hosted site are different,
				 then that could well be a cross-site scripting (XSS) attack. So, the workaround is to
				 do the call from a script tag so the JSON we get back is part of the document. 
				 But since we don't know what URL to hit yet, once we find out then we have to inject
				 a new script tag dynamically which the browser will run as soon as we append it.
				 To be honest I'm not 100% why Google use RESTful services and not JSON-RPC or somesuch,
				 which would be easier. Well, easier for me.'''))
        
        self.IDPanel = HorizontalPanel()
        self.IDPanel.add(Label("Enter google account:"))
        self.IDButton = Button("Go", self)
        
        self.IDBox = TextBox()
        self.IDBox.setText(self.userid)
        self.IDPanel.add(self.IDBox)
        self.IDPanel.add(self.IDButton)
        self.vp.add(self.IDPanel)
        self.vp.add(self.disclosure)
        self.vp.add(self.grid)

        self.initWidget(self.vp)

    def doRESTQuery(self, url, timer):
        """this is a totally different from an RPC call in that we have to
           dynamically add script tags to the DOM when we want to query the 
           REST API. These rely on callbacks in the DOM so we can either add 
           them dynamically or pre-define them in public/Main.html. 
           Once we've done that have to wait for the response.
           Which means we need to provide a listener for the timer"""

        JS("$wnd.receiver = 'wait'")
        new_script = DOM.createElement("script")
        DOM.setElemAttribute(new_script, "src", url)
        DOM.setElemAttribute(new_script, "type","text/javascript")
        JS("$wnd.document.body.appendChild(@{{new_script}})")
        self.timer.schedule(100)

    def onCellClicked(self, sender, row, col):
        if self.drill==0:
            self.drill += 1 
            self.vp.clear()
            self.grid.clear()
            self.vp.add(self.up)
            self.vp.add(self.grid)
            gridcols = self.grid.getColumnCount()
            album = self.albums[row+col+(row*(gridcols-1))]
            url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "/albumid/" + album["id"] + "?alt=json-in-script&kind=photo&hl=en_US&callback=restCb"
            self.doRESTQuery(url, self.timer)
        elif self.drill==1:
            self.drill += 1
            gridcols = self.grid.getColumnCount()
            self.pos =row+col+(row*(gridcols-1))
            photo = self.photos[self.pos]
            self.vp.clear()
            self.fullsize = HTML('<img src="' + photo["full"] + '"/>')
            hp = HorizontalPanel()
            hp.add(self.up)
            hp.add(self.prev)
            hp.add(self.next)
            hp.setSpacing(8)
            self.vp.add(hp)
            self.vp.add(self.fullsize)

    def onClick(self, sender):
        if sender == self.IDButton:
            self.userid = self.IDBox.getText()
            if self.userid == "" or self.userid.isdigit():
                return
            self.drill = 0
            self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb"
            self.grid.clear()
            self.doRESTQuery(self.album_url, self.timer)
        else:
            if self.drill == 2:
                if sender == self.up:
                    self.drill=1
                    self.vp.clear()
                    self.vp.add(self.up)
                    self.vp.add(self.grid)
                    self.fillGrid(self.photos, "photos")
                else:
                    if sender == self.next:
                        if self.pos >= len(self.photos):
                            return
                        self.pos +=1
                    elif sender == self.prev:
                        if self.pos < 1:
                            return
                        self.pos -=1
                    photo = self.photos[self.pos]
                    self.fullsize.setHTML('<img src="' + photo["full"] + '"/>')
            elif self.drill == 1:
                self.drill=0
                self.vp.clear()
                self.vp.add(self.IDPanel)
                self.vp.add(self.disclosure)
                self.vp.add(self.grid)
                self.fillGrid(self.albums, "albums")
            
    def onTimer(self, timer):
        receiver = JS("$wnd.receiver")

        if receiver == 'wait':
           self.timer.schedule(1000)
           return

        JS("$wnd.receiver = 'wait'")

        if self.drill == 0:
            self.parseAlbums(receiver)
            self.fillGrid(self.albums, "albums")
        elif self.drill == 1:
            self.parsePhotos(receiver)
            self.fillGrid(self.photos, "photos")

    def fillGrid(self, items, type):
        self.grid.clear()
        cols = self.grid.getColumnCount()
        self.grid.resizeRows((len(items)/cols)+1)
        rows = self.grid.getRowCount()
        for i in range(len(items)):
            vp = VerticalPanel()
            if type == 'photos':
                vp.add(items[i]['thumb'])
            else:
                vp.add(items[i]['thumb'])
                vp.add(items[i]['title'])
            self.grid.setWidget(int(i/cols), i%cols, vp)

    def parsePhotos(self, items):
        photo_list = JSONParser().jsObjectToPyObject(items)
        self.photos = []
        for i in range(len(photo_list)):
            index = "%s" % i
            aphoto = {}
            aphoto['thumb'] = HTML('<img src="' + photo_list[index]["media$group"]["media$thumbnail"]["1"]["url"] + '"/>')
            aphoto['full'] = photo_list[index]["media$group"]["media$content"]["0"]["url"] 
            self.photos.append(aphoto)

    def parseAlbums(self, items):
        album_list = JSONParser().jsObjectToPyObject(items)
        self.albums = []
        for i in range(len(album_list)):
            index = "%s" % i
            analbum = {}
            analbum['title'] = HTML(album_list[index]["title"]["$t"])
            analbum['thumb'] = HTML('<img src="' + album_list[index]["media$group"]["media$thumbnail"]["0"]["url"] + '"/>')
            url = album_list[index]["id"]["$t"]
            analbum['id'] = url.split('albumid/')[1].split('?alt')[0]
            self.albums.append(analbum)
コード例 #9
0
class CompaniesAppGUI(AbsolutePanel):
	def __init__(self):
		AbsolutePanel.__init__(self)
		
		self.app = CompaniesApp()
		
		self.history = []
		
		self.save = Button("save", self)
		self.selectDepartment = Button("select", self)
		self.selectEmployee = Button("select", self)
		self.edit = Button("edit", self)
		self.cut = Button("cut", self)
		self.back = Button("back", self)
		
		self.name = TextBox()
		self.address = TextBox()
		self.manager = TextBox()
		self.departments = ListBox(Size=("100%"), VisibleItemCount="5")
		self.employees = ListBox(Size=("100%"), VisibleItemCount="5")
		self.total = TextBox()

		self.errors = VerticalPanel()
		
		self.grid = Grid()
		self.allPanels = VerticalPanel()
		self.allPanels.add(self.grid)
		self.allPanels.add(self.errors)
		self.add(self.allPanels)
		
		self.initCompanyGUI()
		
	def onClick(self, sender):
                self.errors.clear()
		if sender == self.cut:
			self.current.cut()
			self.total.setText(self.current.total())
		if sender == self.save:
			if self.current.__class__.__name__ == "Employee":
                                if self.validateEmployee(self.current.id, self.name.getText(), self.address.getText(), self.total.getText()) == True:
                                        self.current.save(self.name.getText(), self.address.getText(), float(self.total.getText()))
			else:
                                if self.validateDepartment(self.current.id, self.name.getText()) == True:
                                        self.current.save(self.name.getText())
		if sender == self.selectDepartment:
			if (self.departments.getSelectedIndex() > -1):
				self.history.append(self.current)
				self.current = self.app.getDepartment(self.departments.getValue(self.departments.getSelectedIndex()))
				self.initDepartmentGUI()
		if sender == self.selectEmployee:
			if (self.employees.getSelectedIndex() > -1):
				self.history.append(self.current)
				self.current = self.app.getEmployee(self.employees.getValue(self.employees.getSelectedIndex()))
				self.initEmployeeGUI()
		if sender == self.edit:
			self.history.append(self.current)
			self.current = self.current.getManager()
			self.initEmployeeGUI()
		if sender == self.back:
			if len(self.history) > 0:
				self.current = self.history.pop()
				if self.current.__class__.__name__ == "Company":
					self.initCompanyGUI()
				else:
					self.initDepartmentGUI()

	def validateDepartment(self, index, name):
                valid = True

                if name == "":
                        self.errors.add(Label("- Enter a valid name, please."))
                        valid = False
                
                for item in self.app.departments:
                        if item.id != index and name == item.name:
                                self.errors.add(Label("- There is already a department with the same name. Enter a valid name, please."))
                                valid = False
                return valid

        def validateEmployee(self, index, name, address, salary):
                valid = True

                if name == "":
                        self.errors.add(Label("- Enter a valid name, please."))
                        valid = False

                if address == "":
                        self.errors.add(Label("- Enter a valid address, please."))
                        valid = False

                if salary == "":
                        self.errors.add(Label("- Enter a valid salary, please."))
                        valid = False

                try:
                        float(salary)
                except ValueError:
                        self.errors.add(Label("- The salary must be a number. Enter a valid salary, please."))
                        valid = False
                        
                
                for item in self.app.employees:
                        if item.id != index and name == item.name and item.address == address:
                                self.errors.add(Label("- There is already an employee with the same name and address combination. Enter a valid name and address, please."))
                                valid = False
                return valid
			
	def initCompanyGUI(self):
		self.current = self.app.company
	
		self.grid.clear()
		self.grid.resize(4, 3)
		
		# row 1
		self.grid.setWidget(0, 0, Label("Name:"))
		self.grid.setWidget(1, 0, Label("Department:"))
		self.grid.setWidget(2, 0, Label("Total:"))
		
		# row 2
		self.grid.setWidget(0, 1, self.name)
		self.grid.setWidget(1, 1, self.departments)
		self.grid.setWidget(2, 1, self.total)

		# row 3
		self.grid.setWidget(0, 2, self.save)
		self.grid.setWidget(1, 2, self.selectDepartment)
		self.grid.setWidget(2, 2, self.cut)
		
		self.name.setText(self.current.name)
		self.departments.clear()
		for item in self.current.departments:
			self.departments.addItem(item.name, item.id)
		if self.departments.getItemCount() > 0:
			self.departments.setSelectedIndex(0)
		self.total.setText(self.current.total())
		
	def initDepartmentGUI(self):	
		self.grid.clear()
		self.grid.resize(6, 3)
		
		# row 1
		self.grid.setWidget(0, 0, Label("Name:"))
		self.grid.setWidget(1, 0, Label("Manager:"))
		self.grid.setWidget(2, 0, Label("Department:"))
		self.grid.setWidget(3, 0, Label("Employee:"))
		self.grid.setWidget(4, 0, Label("Total:"))
		
		# row 2
		self.grid.setWidget(0, 1, self.name)
		self.grid.setWidget(1, 1, self.manager)
		self.grid.setWidget(2, 1, self.departments)
		self.grid.setWidget(3, 1, self.employees)
		self.grid.setWidget(4, 1, self.total)

		# row 3
		self.grid.setWidget(0, 2, self.save)
		self.grid.setWidget(1, 2, self.edit)
		self.grid.setWidget(2, 2, self.selectDepartment)
		self.grid.setWidget(3, 2, self.selectEmployee)
		self.grid.setWidget(4, 2, self.cut)
		
		# back
		self.grid.setWidget(5, 2, self.back)
		
		self.name.setText(self.current.name)
		self.departments.clear()
		self.employees.clear()
		for item in self.current.departments:
			self.departments.addItem(item.name, item.id)
		if self.departments.getItemCount() > 0:
			self.departments.setSelectedIndex(0)
		for item in self.current.employees:
			if item.manager == 0:
				self.employees.addItem(item.name, item.id)
			else:
				self.manager.setText(item.name)
		if self.employees.getItemCount() > 0:
			self.employees.setSelectedIndex(0)
		self.total.setText(self.current.total())
		
	def initEmployeeGUI(self):
		self.grid.clear()
		self.grid.resize(4, 3)
		
		# row 1
		self.grid.setWidget(0, 0, Label("Name:"))
		self.grid.setWidget(1, 0, Label("Address:"))
		self.grid.setWidget(2, 0, Label("Salary:"))
		
		# row 2
		self.grid.setWidget(0, 1, self.name)
		self.grid.setWidget(1, 1, self.address)
		self.grid.setWidget(2, 1, self.total)
		
		# row 3
		self.grid.setWidget(0, 2, self.save)
		self.grid.setWidget(2, 2, self.cut)
		self.grid.setWidget(3, 2, self.back)
		
		self.name.setText(self.current.name)
		self.address.setText(self.current.address)
		self.total.setText(self.current.salary)
コード例 #10
0
ファイル: Slide.py プロジェクト: minghuascode/pyj
class Slide(Sink):
    def __init__(self):

        Sink.__init__(self)

        text = "<div class='infoProse'>This is the Kitchen Sink sample.  "

        self.vp = VerticalPanel()
        self.initWidget(self.vp)
        self.loaded = False

    def onShow(self):

        if self.loaded:
            return

        name = self.name.replace(" ", "_")
        name = name.lower()
        HTTPRequest().asyncGet("%s.txt" % name, SlideLoader(self))

    def setSlide(self, text):
        self.loaded = True
        ul_stack1 = 0
        ul_stack2 = 0
        doing_code = 0
        txt = ''
        text += '\n'
        for line in text.split("\n"):
            if doing_code:
                if line == "}}":
                    doing_code = 0
                    line = "</pre>"
                    txt += line
                    self.vp.add(HTML(txt))
                    txt = ''
                    continue
                if line:
                    txt += line
                txt += "\n"
                continue

            line = line.strip()
            ul_line = False
            ul_line2 = False
            add = False
            if not line:
                line = "&nbsp;"
            elif line[:2] == "{{":
                doing_code = 1
                if len(line) > 2:
                    line = "<pre class='slide_code'>%s" % line[2:]
                else:
                    line = "<pre class='slide_code'>"
            elif line[:2] == '= ' and line[-2:] == ' =':
                line = "<h1 class='slide_heading1'>%s</h1>" % line[2:-2]
            elif line[:3] == '== ' and line[-3:] == ' ==':
                line = "<h2 class='slide_heading2>%s</h2>" % line[3:-3]
            elif line[:2] == '* ':
                if not ul_stack1:
                    txt += "<ul class='slide_list1'>\n"
                line = "<li class='slide_listitem1'/>%s\n" % ts(line[2:])
                ul_stack1 = True
                ul_line = True
            elif line[:3] == '** ':
                if not ul_stack2:
                    txt += "<ul class='slide_list2'>\n"
                line = "<li class='slide_listitem2'/>%s\n" % ts(line[2:])
                ul_stack2 = True
                ul_line2 = True
                ul_line = True
            else:
                if not doing_code:
                    line = "<p class='slide_para'>%s</p>" % line
            if ul_stack2 and not ul_line2:
                ul_stack2 = False
                txt += "</ul>\n"
            if ul_stack1 and not ul_line:
                ul_stack1 = False
                txt += "</ul>\n"
            if not ul_stack2 and not ul_stack1 and not doing_code:
                add = True
            txt += line
            if add:
                self.vp.add(HTML(txt))
                txt = ''

    def onError(self, text, code):
        self.vp.clear()
        self.vp.add(HTML("TODO: Slide '%s' not loaded" % self.name))
        self.vp.add(HTML(text))
        self.vp.add(HTML(code))

    def onProgress(self, event):
        self.vp.clear()
コード例 #11
0
ファイル: userlist.py プロジェクト: jdunck/Tickery
 def clear(self):
     VerticalPanel.clear(self)
     self.nSelected = 0
コード例 #12
0
ファイル: userlist.py プロジェクト: jdunck/Tickery
class UserListPanel(VerticalPanel):
    def __init__(self, tabPanel, topPanel, **kwargs):
        VerticalPanel.__init__(self, StyleName='user-list-panel', **kwargs)
        self.tabPanel = tabPanel
        self.topPanel = topPanel
        self.iconAdder = None
        self.iconPanel = None
        self.nSelected = 0
        self.leftPanelWidth = 340
        self.widthFudgeFactor = 25

    def clear(self):
        VerticalPanel.clear(self)
        self.nSelected = 0

    def updateResultLink(self):
        self.resultLink.setHTML('Results:&nbsp;<a href="%s">link</a>' %
                                self.tabPanel.resultsLink())
    
    def setUsers(self, title, users, kwargs):
        self.users = users
        self.nUsers = len(users)
        self.title = title
        self.resultPanel = HorizontalPanel(StyleName='result-panel')
        self.add(self.resultPanel)
        self.leftPanel = VerticalPanel(StyleName='results-left-panel',
                                       Width=self.leftPanelWidth)
        self.resultPanel.add(self.leftPanel)
        if not users:
            self.iconPanel = None
            self.leftPanel.add(HTML(title, StyleName='result-title'))
        else:
            # Set a display order that will show everything for now.
            self.displayOrder = range(self.nUsers)
            self.largeAvatar = LargeAvatar(self, self.tabPanel, self.topPanel)
            self.leftPanel.add(self.largeAvatar)

            resultPanelBottomLeft = VerticalPanel(
                StyleName='results-left-panel-bottom-left')

            self.resultLink = HTML(StyleName='result-detail')
            self.updateResultLink()
            resultPanelBottomLeft.add(self.resultLink)
            
            self.iconSizePanel = HorizontalPanel()
            self.iconSizePanel.add(
                HTML('Icons:&nbsp;', StyleName='result-detail'))

            self.iconSizeLb = lb = ListBox()
            i = 0
            for text, key in _iconData:
                lb.addItem(text, key)
                if key == _iconSize:
                    lb.setSelectedIndex(i)
                i += 1
            lb.addChangeListener(IconSizeChanger(self))
            self.iconSizePanel.add(lb)
            resultPanelBottomLeft.add(self.iconSizePanel)

            if self.nUsers > 1:
                self.sortPanel = HorizontalPanel()
                self.sortPanel.add(
                    HTML('Sort:&nbsp;', StyleName='result-detail'))

                self.lb = lb = ListBox()
                i = 0
                for text, key in _sortKeyData:
                    lb.addItem(text, key)
                    if key == _sortKey:
                        lb.setSelectedIndex(i)
                    i += 1
                lb.addChangeListener(self)
                self.sortPanel.add(lb)
                resultPanelBottomLeft.add(self.sortPanel)
                
            self.filterPanel = HorizontalPanel()
            resultPanelBottomLeft.add(self.filterPanel)
            self.addFilterWidgets()
            
            if self.topPanel.loggedIn():
                if 'screennames' in kwargs:
                    resultPanelBottomLeft.add(tweet.SimpleTweetPanel(
                        kwargs['screennames'], len(self.users), self.topPanel))
                elif 'query' in kwargs:
                    resultPanelBottomLeft.add(tweet.PrepareTweetButton(
                        kwargs['query'], len(self.users),
                        self.tabPanel.tabName, self.topPanel))

            self.leftPanel.add(resultPanelBottomLeft)

            self.iconPanel = VerticalPanel(StyleName='icon-outer-panel')
            self.resultPanel.add(self.iconPanel)
            self.images = []
            for u in users:
                url = u['profile_image_url']
                i = Image(url, StyleName='avatar-' + _iconSize)
                # Does calling prefetch actually help?
                i.prefetch(url)
                i._user = u
                i._selected = False
                i.addMouseListener(self)
                self.images.append(i)
            self.showUsers()

    def addFilterWidgets(self):
        """If we're logged in (and hence the friends list is available),
        create a filter listbox. If not, tell the loginPanel that we exist
        so it can call us when the login is complete."""
        if self.topPanel.loggedIn():
            # Window.alert('Logged in')
            self.filterPanel.add(
                HTML('Filter:&nbsp;', StyleName='result-detail'))
            self.filterChanger = FilterChanger(self, self.topPanel)
            self.filterBox = ListBox()
            self.filterBox.addItem('None', 0)
            self.filterBox.addItem(
                'Following (%d of %d)' %
                (self.filterChanger.nFriends, self.nUsers), 1)
            self.filterBox.addItem(
                "Not following (%d of %d)" %
                (self.nUsers - self.filterChanger.nFriends, self.nUsers), 2)
            self.filterBox.addChangeListener(self.filterChanger)
            self.filterPanel.add(self.filterBox)
        else:
            # Not yet logged in. Add ourselves to the list of UserListPanels
            # that the loginPanel will call when it's ready.
            self.topPanel.loginPanel.addUserListPanel(self)
                    
    def onChange(self, sender):
        global _sortKey
        _sortKey = self.lb.getValue(self.lb.getSelectedIndex())
        self.updateResultLink()
        self.showUsers()

    def showUsers(self):
        # Cancel any existing timed icon additions before changing
        # self.displayOrder.
        if self.iconAdder is not None:
            self.iconAdder.cancel()
            self.iconAdder = None
            
        self.iconPanel.clear()

        # Set a title above the icons.
        if hasattr(self, 'filterChanger'):
            order = self.filterChanger.currentOrder
            if order == 0:
                title = self.title
            else:
                if order == 1:
                    n = self.filterChanger.nFriends
                    detail = 'follow'
                else:
                    n = self.nUsers - self.filterChanger.nFriends
                    detail = "don't follow"
                if n == 0:
                    if detail == 'follow':
                        title = "You don't follow any of them!"
                    else:
                        title = "You already follow them all!"
                else:
                    if n > 1:
                        plural = 's'
                    else:
                        plural = ''
                    title = 'The %d user%s you %s:' % (n, plural, detail)
        else:
            title = self.title
        self.iconPanel.add(HTML(title, StyleName='result-title'))
        
        if not self.displayOrder:
            # There are no users to show.
            return
            
        decreasing = _sortKey in (
            'friends_count', 'followers_count', 'statuses_count')
        alpha = _sortKey in ('screen_name', 'name', 'location')
        def _keyFunc(n):
            value = self.users[n][_sortKey]
            if decreasing:
                return -1 * value
            elif alpha:
                if value:
                    return value.lower().strip()
                else:
                    # Uh, put this towards the end (of ASCII at least)
                    return '~~~'
            else:
                return value

        # Don't use sorted here, as it replaces the display order list
        # (which is actually being maintained for us by our FilterChanger
        # instance).
        self.displayOrder.sort(key=_keyFunc)
        self.icons = FlowPanel(StyleName='icon-panel')
        self.adjustWidths()
        self.iconPanel.add(self.icons)
        self.iconAdder = IconAdder(self)
        Timer.Timer(1, self.iconAdder)
        if self.nSelected == 0:
            self.largeAvatar.setUser(self.users[self.displayOrder[0]])

    def onMouseEnter(self, img):
        if not self.nSelected:
            self.largeAvatar.setUser(img._user)

    def onMouseMove(self, img, x, y):
        pass

    def onMouseLeave(self, img):
        pass

    def onMouseDown(self, img, x, y):
        self.largeAvatar.setUser(img._user)
        if not img._selected and self.nSelected:
            self._unselectAll()
        self._toggleSelect(img)

    def onMouseUp(self, img, x, y):
        pass

    def _toggleSelect(self, img):
        if img._selected:
            self._unselect(img)
        else:
            self._select(img)
        
    def _unselect(self, img):
        if img._selected:
            img.removeStyleDependentName('selected')
            self.nSelected -= 1
            img._selected = False

    def _select(self, img):
        if not img._selected:
            img.addStyleDependentName('selected')
            self.nSelected += 1
            img._selected = True

    def _unselectAll(self):
        for img in self.images:
            self._unselect(img)

    def unselectNotFollowed(self):
        for img in self.images:
            if not img._user['following'] and img._selected:
                self._unselect(img)

    def unselectFollowed(self):
        for img in self.images:
            if img._user['following'] and img._selected:
                self._unselect(img)

    def setIconSizes(self):
        for img in self.images:
            selected = img._selected
            if selected:
                self._unselect(img)
            img.setStyleName('avatar-' + _iconSize)
            if selected:
                self._select(img)

    def adjustWidths(self, windowWidth=None):
        if windowWidth is None:
            windowWidth = Window.getClientWidth()
        width = windowWidth - self.leftPanelWidth - self.widthFudgeFactor
        if self.iconPanel is not None:
            self.icons.setWidth(width)

    def adjustSize(self, width, height):
        self.adjustWidths(width)
コード例 #13
0
ファイル: Slide.py プロジェクト: FreakTheMighty/pyjamas
class Slide(Sink):
    def __init__(self):

        Sink.__init__(self)

        text="<div class='infoProse'>This is the Kitchen Sink sample.  "

        self.vp = VerticalPanel()
        self.initWidget(self.vp)
        self.loaded = False

    def onShow(self):

        if self.loaded:
            return 

        name = self.name.replace(" ", "_")
        name = name.lower()
        HTTPRequest().asyncGet("%s.txt" % name, SlideLoader(self))

    def setSlide(self, text):
        self.loaded = True
        ul_stack1 = 0
        ul_stack2 = 0
        doing_code = 0
        txt = ''
        text += '\n'
        for line in text.split("\n"):
            if doing_code:
                if line == "}}":
                    doing_code = 0
                    line = "</pre>"
                    txt += line
                    self.vp.add(HTML(txt))
                    txt = ''
                    continue
                if line:
                    txt += line
                txt += "\n"
                continue
                
            line = line.strip()
            ul_line = False
            ul_line2 = False
            add = False
            if not line:
                line = "&nbsp;"
            elif line[:2] == "{{":
                doing_code = 1
                if len(line) > 2:
                    line = "<pre class='slide_code'>%s" % line[2:]
                else:
                    line = "<pre class='slide_code'>"
            elif line[:2] == '= ' and line[-2:] == ' =':
                line = "<h1 class='slide_heading1'>%s</h1>" % line[2:-2]
            elif line[:3] == '== ' and line[-3:] == ' ==':
                line = "<h2 class='slide_heading2>%s</h2>" % line[3:-3]
            elif line[:2] == '* ':
                if not ul_stack1:
                    txt += "<ul class='slide_list1'>\n"
                line = "<li class='slide_listitem1'/>%s\n" % ts(line[2:])
                ul_stack1 = True
                ul_line = True
            elif line[:3] == '** ':
                if not ul_stack2:
                    txt += "<ul class='slide_list2'>\n"
                line = "<li class='slide_listitem2'/>%s\n" % ts(line[2:])
                ul_stack2 = True
                ul_line2 = True
                ul_line = True
            else:
                if not doing_code:
                    line = "<p class='slide_para'>%s</p>" % line
            if ul_stack2 and not ul_line2:
                ul_stack2 = False
                txt += "</ul>\n"
            if ul_stack1 and not ul_line:
                ul_stack1 = False
                txt += "</ul>\n"
            if not ul_stack2 and not ul_stack1 and not doing_code:
                add = True
            txt += line
            if add:
                self.vp.add(HTML(txt))
                txt = ''

    def onError(self, text, code):
        self.vp.clear()
        self.vp.add(HTML("TODO: Slide '%s' not loaded" % self.name))
        self.vp.add(HTML(text))
        self.vp.add(HTML(code))