Exemplo n.º 1
0
class Calendar(FocusPanel, DateSelectedHandler):
    monthsOfYear = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    daysOfWeek = ['S', 'M', 'T', 'W', 'T', 'F', 'S']
    today = 'Today'
    tomorrow = 'Tomorrow'
    yesterday = 'Yesterday'
    cancel = 'Cancel'

    def __init__(self, **kwargs):
        FocusPanel.__init__(self, **kwargs)
        DateSelectedHandler.__init__(self)
        yr, mth, day = time.strftime("%Y-%m-%d").split("-")
        self.todayYear = int(yr)
        self.todayMonth = int(mth)  # change to offset 0 as per javascript
        self.todayDay = int(day)

        self.currentMonth = self.todayMonth
        self.currentYear = self.todayYear
        self.currentDay = self.todayDay


        self.defaultGrid = None # used later

        return


    def setDate(self, _date):
        """ _date - object of datetime.date class """
        self.currentMonth = _date.month
        self.currentYear = _date.year
        self.currentDay = _date.day

    def getMonthsOfYear(self):
        return self.monthsOfYear

    def getDaysOfWeek(self):
        return self.daysOfWeek

    def isLeapYear(self, year):
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            return True
        else:
            return False

    def getDaysInMonth(self, mth, year):
        days = 0
        if mth in [1, 3, 5, 7, 8, 10, 12]:
            days = 31
        elif mth in [4, 6, 9, 11]:
            days = 30
        elif (mth == 2 and self.isLeapYear(year)):
            days = 29
        else:
            days = 28
        return days

    def setPosition(self, left, top):
        element = self.getElement()
        DOM.setStyleAttribute(element, "left", "%dpx" % left)
        DOM.setStyleAttribute(element, "top", "%dpx" % top)

    def show(self, left, top):
        if left < 0:
            left = 0
        if top < 0:
            top = 0
        self.setPosition(left, top)
        self.drawCurrent()
        self.setVisible(True)

    def drawCurrent(self):
        yr, mth, day = self.currentYear, self.currentMonth, self.currentDay
        self.draw(int(mth), int(yr))


    def draw(self, month , year):
        tod = time.localtime()
        mm = tod.tm_mon
        yy = tod.tm_year
        # has today changed and thus changed month? cater to rare case
        # where widget in created on last day of month and
        # page left till next day
        hasChangeMonth = False
        if yy <> self.todayYear or mm <> self.todayMonth:
            hasChangeMonth = True
            self.todayYear = yy
            self.todayMonth = mm

        # check to see if we have drawn the full widget before
        if self.defaultGrid is None:
            self.drawFull(month, year)
        else:
            # ok means we are re-drawing, but first check if it is the same
            # as the defaultGrid, if yes, just use it
            if not hasChangeMonth and month == self.todayMonth and \
                   year == self.todayYear:
                self.middlePanel.setWidget(self.defaultGrid)
                self.currentMonth = self.todayMonth
                self.currentYear = self.todayYear
            else:
                # we have to redraw the grid -- bah
                g = self.drawGrid(month, year)

                if hasChangeMonth:
                    # reset the default grid as we have changed months
                    self.defaultGrid = grid

            #
            # what about the title panel?
            #
            txt = "<b>"
            txt += self.getMonthsOfYear()[month - 1] + " " + str(year)
            txt += "</b>"
            self.titlePanel.setWidget(HTML(txt))
            self.setVisible(True)

        return

    def drawFull(self, month, year):
        # should be called only once when we draw the calendar for
        # the first time
        self.vp = VerticalPanel()
        self.vp.setSpacing(2)
        self.vp.addStyleName("calendarbox calendar-module calendar")
        self.setWidget(self.vp)
        self.setVisible(False)
        #
        mth = int(month)
        yr = int(year)

        tp = HorizontalPanel()
        tp.addStyleName("calendar-top-panel")
        tp.setSpacing(5)

        h1 = Hyperlink('<<')
        h1.addClickListener(getattr(self, 'onPreviousYear'))
        h2 = Hyperlink('<')
        h2.addClickListener(getattr(self, 'onPreviousMonth'))
        h4 = Hyperlink('>')
        h4.addClickListener(getattr(self, 'onNextMonth'))
        h5 = Hyperlink('>>')
        h5.addClickListener(getattr(self, 'onNextYear'))

        tp.add(h1)
        tp.add(h2)

        # titlePanel can be changed, whenever we draw, so keep the reference
        txt = "<b>"
        txt += self.getMonthsOfYear()[mth - 1] + " " + str(yr)
        txt += "</b>"
        self.titlePanel = SimplePanel()
        self.titlePanel.setWidget(HTML(txt))
        self.titlePanel.setStyleName("calendar-center")

        tp.add(self.titlePanel)
        tp.add(h4)
        tp.add(h5)
        tvp = VerticalPanel()
        tvp.setSpacing(10)
        tvp.add(tp)

        self.vp.add(tvp)

        # done with top panel

        self.middlePanel = SimplePanel()
        grid = self.drawGrid(mth, yr)
        self.middlePanel.setWidget(grid)
        self.vp.add(self.middlePanel)
        self.defaultGrid = grid

        self._gridShortcutsLinks()
        self._gridCancelLink()
        #
        # add code to test another way of doing the layout
        #
        self.setVisible(True)
        return

    def _gridShortcutsLinks(self):

        #
        # some links & handlers
        #
        bh1 = Hyperlink(self.yesterday)
        bh1.addClickListener(getattr(self, 'onYesterday'))
        bh2 = Hyperlink(self.today)
        bh2.addClickListener(getattr(self, 'onToday'))
        bh3 = Hyperlink(self.tomorrow)
        bh3.addClickListener(getattr(self, 'onTomorrow'))

        b = HorizontalPanel()
        b.add(bh1)
        b.add(bh2)
        b.add(bh3)
        b.addStyleName("calendar-shortcuts")
        self.vp.add(b)

    def _gridCancelLink(self):
        bh4 = Hyperlink(self.cancel)
        bh4.addClickListener(getattr(self, 'onCancel'))

        b2 = SimplePanel()
        b2.add(bh4)
        b2.addStyleName("calendar-cancel")
        self.vp.add(b2)

    def drawGrid(self, month, year):
        # draw the grid in the middle of the calendar

        daysInMonth = self.getDaysInMonth(month, year)
        # first day of the month & year
        secs = time.mktime((year, month, 1, 0, 0, 0, 0, 0, -1))
        struct = time.localtime(secs)
        # 0 - sunday for our needs instead 0 = monday in tm_wday
        startPos = (struct.tm_wday + 1) % 7
        slots = startPos + daysInMonth - 1
        rows = int(slots / 7) + 1
        grid = Grid(rows + 1, 7) # extra row for the days in the week
        grid.setWidth("100%")
        grid.addTableListener(self)
        self.middlePanel.setWidget(grid)
        #
        # put some content into the grid cells
        #
        for i in range(7):
            grid.setText(0, i, self.getDaysOfWeek()[i])
            grid.cellFormatter.addStyleName(0, i, "calendar-header")
        #
        # draw cells which are empty first
        #
        day = 0
        pos = 0
        while pos < startPos:
            grid.setText(1, pos , " ")
            grid.cellFormatter.setStyleAttr(1, pos, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(1, pos, "calendar-blank-cell")
            pos += 1
        # now for days of the month
        row = 1
        day = 1
        col = startPos
        while day <= daysInMonth:
            if pos % 7 == 0 and day <> 1:
                row += 1
            col = pos % 7
            grid.setText(row, col, str(day))
            if self.currentYear == self.todayYear and \
               self.currentMonth == self.todayMonth and day == self.todayDay:
                grid.cellFormatter.addStyleName(row, col, "calendar-cell-today")
            else:
                grid.cellFormatter.addStyleName(row, col, "calendar-day-cell")
            day += 1
            pos += 1
        #
        # now blank lines on the last row
        #
        col += 1
        while col < 7:
            grid.setText(row, col, " ")
            grid.cellFormatter.setStyleAttr(row, col, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(row, col, "calendar-blank-cell")
            col += 1

        return grid

    def onCellClicked(self, grid, row, col):
        if row == 0:
            return
        text = grid.getText(row, col).strip()
        if text == "":
            return
        try:
            selectedDay = int(text)
        except ValueError, e:
            return

        self.fireDateSelectedEvent(date(
            self.currentYear,
            self.currentMonth,
            selectedDay,
            ))
        self.setVisible(False)
Exemplo n.º 2
0
class Calendar(FocusPanel):
    monthsOfYear = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    daysOfWeek = ['S', 'M', 'T', 'W', 'T', 'F', 'S']
    today = 'Today'
    tomorrow = 'Tomorrow'
    yesterday = 'Yesterday'
    cancel = 'Cancel'

    def __init__(self, **kwargs):
        FocusPanel.__init__(self, **kwargs)
        yr, mth, day = time.strftime("%Y-%m-%d").split("-")
        self.todayYear = int(yr)
        self.todayMonth = int(mth)  # change to offset 0 as per javascript
        self.todayDay = int(day)

        self.currentMonth = self.todayMonth
        self.currentYear = self.todayYear
        self.currentDay = self.todayDay

        self.selectedDateListeners = []

        self.defaultGrid = None # used later

        return


    def setDate(self,_date):
        """ _date - object of datetime.date class """
        self.currentMonth = _date.month
        self.currentYear = _date.year
        self.currentDay = _date.day

    def getMonthsOfYear(self):
        return self.monthsOfYear

    def getDaysOfWeek(self):
        return self.daysOfWeek

    def addSelectedDateListener(self, listener):
        self.selectedDateListeners.append(listener)

    def removeSelectedDateListener(self, listener):
        self.selectedDateListeners.remove(listener)

    def isLeapYear(self, year):
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            return True
        else:
            return False

    def getDaysInMonth(self, mth, year):
        days = 0
        if mth in [1, 3, 5, 7, 8, 10, 12]:
            days=31
        elif mth in [4, 6, 9, 11]:
            days = 30
        elif (mth==2 and self.isLeapYear(year)):
            days = 29
        else:
            days = 28
        return days

    def setPosition(self, left, top):
        element = self.getElement()
        DOM.setStyleAttribute(element, "left", "%dpx" % left)
        DOM.setStyleAttribute(element, "top", "%dpx" % top)

    def show(self, left, top):
        if left < 0:
            left = 0
        if top < 0:
            top = 0
        self.setPosition(left, top)
        self.drawCurrent()
        self.setVisible(True)

    def drawCurrent(self):
        yr, mth, day = self.currentYear, self.currentMonth, self.currentDay
        self.draw(int(mth), int(yr))


    def draw(self, month , year):
        tod = time.localtime()
        mm = tod.tm_mon
        yy = tod.tm_year
        # has today changed and thus changed month? cater to rare case
        # where widget in created on last day of month and
        # page left till next day
        hasChangeMonth = False
        if yy <> self.todayYear or mm <> self.todayMonth:
            hasChangeMonth = True
            self.todayYear = yy
            self.todayMonth = mm

        # check to see if we have drawn the full widget before
        if self.defaultGrid is None:
            self.drawFull(month, year)
        else:
            # ok means we are re-drawing, but first check if it is the same
            # as the defaultGrid, if yes, just use it
            if not hasChangeMonth and month == self.todayMonth and \
                   year == self.todayYear:
                self.middlePanel.setWidget(self.defaultGrid)
                self.currentMonth = self.todayMonth
                self.currentYear = self.todayYear
            else:
                # we have to redraw the grid -- bah
                g = self.drawGrid(month, year)

                if hasChangeMonth:
                    # reset the default grid as we have changed months
                    self.defaultGrid = grid

            #
            # what about the title panel?
            #
            txt = "<b>"
            txt += self.getMonthsOfYear()[month-1] + " " + str(year)
            txt += "</b>"
            self.titlePanel.setWidget(HTML(txt))
            self.setVisible(True)

        return

    def drawFull(self, month, year):
        # should be called only once when we draw the calendar for
        # the first time
        self.vp = VerticalPanel()
        self.vp.setSpacing(2)
        self.vp.addStyleName("calendarbox calendar-module calendar")
        self.setWidget(self.vp)
        self.setVisible(False)
        #
        mth = int(month)
        yr = int(year)

        tp = HorizontalPanel()
        tp.addStyleName("calendar-top-panel")
        tp.setSpacing(5)

        h1 = Hyperlink('<<')
        h1.addClickListener(getattr(self, 'onPreviousYear'))
        h2 = Hyperlink('<')
        h2.addClickListener(getattr(self, 'onPreviousMonth'))
        h4 = Hyperlink('>')
        h4.addClickListener(getattr(self, 'onNextMonth'))
        h5 = Hyperlink('>>')
        h5.addClickListener(getattr(self, 'onNextYear'))

        tp.add(h1)
        tp.add(h2)

        # titlePanel can be changed, whenever we draw, so keep the reference
        txt = "<b>"
        txt += self.getMonthsOfYear()[mth-1] + " " + str(yr)
        txt += "</b>"
        self.titlePanel = SimplePanel()
        self.titlePanel.setWidget(HTML(txt))
        self.titlePanel.setStyleName("calendar-center")

        tp.add(self.titlePanel)
        tp.add(h4)
        tp.add(h5)
        tvp = VerticalPanel()
        tvp.setSpacing(10)
        tvp.add(tp)

        self.vp.add(tvp)

        # done with top panel

        self.middlePanel = SimplePanel()
        grid = self.drawGrid(mth, yr)
        self.middlePanel.setWidget(grid)
        self.vp.add(self.middlePanel)
        self.defaultGrid = grid

        self._gridShortcutsLinks()
        self._gridCancelLink()
        #
        # add code to test another way of doing the layout
        #
        self.setVisible(True)
        return

    def _gridShortcutsLinks(self):

        #
        # some links & handlers
        #
        bh1 = Hyperlink(self.yesterday)
        bh1.addClickListener(getattr(self, 'onYesterday'))
        bh2 = Hyperlink(self.today)
        bh2.addClickListener(getattr(self, 'onToday'))
        bh3 = Hyperlink(self.tomorrow)
        bh3.addClickListener(getattr(self, 'onTomorrow'))

        b = HorizontalPanel()
        b.add(bh1)
        b.add(bh2)
        b.add(bh3)
        b.addStyleName("calendar-shortcuts")
        self.vp.add(b)

    def _gridCancelLink(self):
        bh4 = Hyperlink(self.cancel)
        bh4.addClickListener(getattr(self, 'onCancel'))

        b2 = SimplePanel()
        b2.add(bh4)
        b2.addStyleName("calendar-cancel")
        self.vp.add(b2)

    def drawGrid(self, month, year):
        # draw the grid in the middle of the calendar

        daysInMonth = self.getDaysInMonth(month, year)
        # first day of the month & year
        secs = time.mktime((year, month, 1, 0, 0, 0, 0, 0, -1))
        struct = time.localtime(secs)
        # 0 - sunday for our needs instead 0 = monday in tm_wday
        startPos = (struct.tm_wday + 1) % 7
        slots = startPos + daysInMonth - 1
        rows = int(slots/7) + 1
        grid = Grid(rows+1, 7) # extra row for the days in the week
        grid.setWidth("100%")
        grid.addTableListener(self)
        self.middlePanel.setWidget(grid)
        #
        # put some content into the grid cells
        #
        for i in range(7):
            grid.setText(0, i, self.getDaysOfWeek()[i])
            grid.cellFormatter.addStyleName(0, i, "calendar-header")
        #
        # draw cells which are empty first
        #
        day =0
        pos = 0
        while pos < startPos:
            grid.setText(1, pos , " ")
            grid.cellFormatter.setStyleAttr(1, pos, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(1, pos, "calendar-blank-cell")
            pos += 1
        # now for days of the month
        row = 1
        day = 1
        col = startPos
        while day <= daysInMonth:
            if pos % 7 == 0 and day <> 1:
                row += 1
            col = pos % 7
            grid.setText(row, col, str(day))
            if self.currentYear == self.todayYear and \
               self.currentMonth == self.todayMonth and day == self.todayDay:
                grid.cellFormatter.addStyleName(row, col, "calendar-cell-today")
            else:
                grid.cellFormatter.addStyleName(row, col, "calendar-day-cell")
            day += 1
            pos += 1
        #
        # now blank lines on the last row
        #
        col += 1
        while col < 7:
            grid.setText(row, col, " ")
            grid.cellFormatter.setStyleAttr(row, col, "background", "#f3f3f3")
            grid.cellFormatter.addStyleName(row, col, "calendar-blank-cell")
            col += 1

        return grid

    def onCellClicked(self, grid, row, col):
        if row == 0:
            return
        text = grid.getText(row, col).strip()
        if text == "":
            return
        try:
            selectedDay = int(text)
        except ValueError, e:
            return
        # well if anyone is listening to the listener, fire that event
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener.onDateSelected(self.currentYear, self.currentMonth,
                                        selectedDay)
            else:
                listener(self.currentYear, self.currentMonth, selectedDay)
        self.setVisible(False)
Exemplo n.º 3
0
class MovieRatings:
	def onModuleLoad(self):
        # Setup JSON RPC
		self.remote = DataService()

### Initialize member variables
		self.mainPanel = HorizontalPanel()
		self.rightPanel = VerticalPanel()
		self.moviesPanel = VerticalPanel()
		self.topRatedPanel = VerticalPanel()
		self.categoriesPanel = VerticalPanel()
        
		self.moviesFlexTable = FlexTable()
		self.topRatedMoviesFlexTable = FlexTable()
		self.topCategoryMoviesFlexTable = FlexTable()
        
		self.lessThanFiveLabel = Label('There are less than 5 movies. Add more movies!')
		self.moviesListLabel = Label('Movies List')
        
		self.addPanel = VerticalPanel()
		self.newMovieCategoryTextBox = TextBox()
		self.newMovieNameTextBox = TextBox()
		self.newMovieRatingListBox = ListBox(False)
		self.addMovieButton = Button('Add', self.addMovieButton_Click)
        
		self.movies = []
		self.topRatedMovies = []
		self.categories = {}
		
		self.MAX_RATING = 10
		
###	Add Movie Panel
		# Add ratings to list box
		for i in range(self.MAX_RATING + 1):
			self.newMovieRatingListBox.addItem(str(i))
		
		# Add label and textbox to horizontal panel
		self.labelPanel = HorizontalPanel()
		self.labelPanel.add(Label("Add a movie:"))
		self.categoryPanel = HorizontalPanel()
		self.categoryPanel.add(Label("Category: "))
		self.categoryPanel.add(self.newMovieCategoryTextBox)
		self.namePanel = HorizontalPanel()
		self.namePanel.add(Label("Movie Name: "))
		self.namePanel.add(self.newMovieNameTextBox)
		self.ratingPanel = HorizontalPanel()
		self.ratingPanel.add(Label("Movie Rating: "))
		self.ratingPanel.add(self.newMovieRatingListBox)

		self.labelPanel.addStyleName("addLabel")
		self.labelPanel.setSpacing(5)
		self.categoryPanel.addStyleName("addPanel")
		self.categoryPanel.setSpacing(5)
		self.namePanel.addStyleName("addPanel")
		self.namePanel.setSpacing(5)
		self.ratingPanel.addStyleName("addPanel")
		self.ratingPanel.setSpacing(5)
		self.newMovieCategoryTextBox.addStyleName("addPanel-input")
		self.newMovieNameTextBox.addStyleName("addPanel-input")
		self.newMovieRatingListBox.addStyleName("addPanel-input")
		
		self.addPanel.add(self.labelPanel)
		self.addPanel.add(self.categoryPanel)
		self.addPanel.add(self.namePanel)
		self.addPanel.add(self.ratingPanel)
		self.addPanel.add(self.addMovieButton)
		self.addPanel.addStyleName("addPanel")
		
		self.addMovieButton.addStyleName('addButton')
		self.addPanel.add(self.addMovieButton)
		self.addPanel.addStyleName('addPanel')
		
###	Movies table
		self.moviesFlexTable.setText(0, 1, "Category")
		self.moviesFlexTable.setText(0, 2, "Title")
		self.moviesFlexTable.setText(0, 3, "Rating")

		self.moviesFlexTable.addStyleName("movieList")
		self.moviesFlexTable.getRowFormatter().addStyleName(0, "listHeader")
		self.moviesFlexTable.setCellPadding(6)
		self.moviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn")
		self.moviesFlexTable.getCellFormatter().setStyleName(0, 2, "listHeaderColumn")
		self.moviesListLabel.addStyleName("listLabel")

		self.moviesPanel.add(self.moviesListLabel)
		self.moviesPanel.add(self.moviesFlexTable)
		self.moviesPanel.setStyleName("moviesPanel")
		
###	Top rated movies table
		self.topRatedMoviesFlexTable.setText(0, 0, "Category")
		self.topRatedMoviesFlexTable.setText(0, 1, "Title")
		self.topRatedMoviesFlexTable.setText(0, 2, "Rating")

		self.topRatedMoviesFlexTable.addStyleName("topMoviesList")
		self.topRatedMoviesFlexTable.getRowFormatter().addStyleName(0, "listHeader")
		self.topRatedMoviesFlexTable.setCellPadding(6)
		self.topRatedMoviesFlexTable.getCellFormatter().setStyleName(0, 0, "listHeaderColumn")
		self.topRatedMoviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn")

		self.topRatedLabel = Label("Top 5 Rated Movies")
		self.topRatedLabel.addStyleName("listLabel")
		self.lessThanFiveLabel.addStyleName("noticeLabel")

		self.topRatedPanel.add(self.topRatedLabel)
		self.topRatedPanel.add(self.topRatedMoviesFlexTable)
		self.topRatedPanel.add(self.lessThanFiveLabel)
		self.topRatedPanel.setStyleName("topRatedPanel")
		
###	Categories table
		self.topCategoryMoviesFlexTable.setText(0, 0, "Category")
		self.topCategoryMoviesFlexTable.setText(0, 1, "Top Movie")
		self.topCategoryMoviesFlexTable.setText(0, 2, "Average Rating")

		self.topCategoryMoviesFlexTable.addStyleName("topCategoryMoviesList")
		self.topCategoryMoviesFlexTable.getRowFormatter().addStyleName(0, "listHeader")
		self.topCategoryMoviesFlexTable.setCellPadding(6)
		self.topCategoryMoviesFlexTable.getCellFormatter().setStyleName(0, 0, "listHeaderColumn")
		self.topCategoryMoviesFlexTable.getCellFormatter().setStyleName(0, 1, "listHeaderColumn")

		self.categoriesLabel = Label("Movie Categories")
		self.categoriesLabel.addStyleName("listLabel")

		self.categoriesPanel.add(self.categoriesLabel)
		self.categoriesPanel.add(self.topCategoryMoviesFlexTable)
		self.categoriesPanel.setStyleName("categoriesPanel")
		
###	Assemble Main panel
		self.rightPanel.add(self.topRatedPanel)
		self.rightPanel.add(self.categoriesPanel)
		self.mainPanel.add(self.moviesPanel)
		self.mainPanel.add(self.rightPanel)

		self.mainPanel.setStyleName("mainPanel")
		self.mainPanel.setSpacing(25)
		
        # Associate panels with the HTML host page
		RootPanel('addPanel').add(self.addPanel)
		RootPanel('main').add(self.mainPanel)

        # Move cursor focus to the input box
		self.newMovieNameTextBox.setFocus(True)

        # Load the movies
		self.remote.getMovies(self)
	
	def verifyInputs(self, name, category):
		if len(name) == 0:
			Window.alert("Movie name cannot be empty.")
			return False
		if len(name) > 100:
			Window.alert("Movie name is too long. Maximum length is 100 characters.")
			return False
		if len(category) == 0:
			Window.alert("Category cannot be empty.")
			return False
		p = re.compile('^[0-9A-Za-z\\.\\-\\(\\) ]{1,100}$')
		if p.match(category) == None:
			Window.alert('"%s" is not a valid category.' % category)
			return False
		return True
	
	def addMovieButton_Click(self, event):		
		name = self.newMovieNameTextBox.getText().trim()
		cat = self.newMovieCategoryTextBox.getText().trim().lower()
		category = cat[0].upper() + cat[1:]
		rating = self.newMovieRatingListBox.getSelectedIndex()
		
		if not self.verifyInputs(name, category):
			return
			
		movie = Movie(name, category, rating)
			
		if movie in self.movies:
			Window.alert("'" + name + "' is already in table.")
			self.newMovieNameTextBox.selectAll()
			return
			
		self.remote.addMovie((name, category, rating), self)
		self.newMovieNameTextBox.setText('')
		
	def addMovie(self, sender, movie):						
		self.movies.append(movie)
		row = self.moviesFlexTable.getRowCount()
		
		self.moviesFlexTable.setText(row, 1, movie.category)
		self.moviesFlexTable.setText(row, 2, movie.name)
		self.moviesFlexTable.setText(row, 3, movie.rating)
					
		# Adds buttons for remove, edit, save and cancel
		removeMovieButton = Button("x")
		editMovieButton = Button("Edit")
		saveButton = Button("Save")
		cancelButton = Button("Cancel")	
			
		# Save and cancel are hidden by default
		saveButton.setVisible(False)
		cancelButton.setVisible(False)
		
		# Add buttons to row
		buttons = HorizontalPanel()
		buttons.add(removeMovieButton)
		buttons.add(editMovieButton)
		buttons.add(cancelButton)
		buttons.add(saveButton)
		self.moviesFlexTable.setWidget(row, 0, buttons)
		
		def removeMovieButton_Click(sender):
			self.remote.deleteMovie((movie.name, movie.category), self)
		removeMovieButton.addClickListener(removeMovieButton_Click)
		
		def editMovieButton_Click(sender):   		
    	    # Add textboxes and listbox
			editMovieButton.setVisible(False)
			cancelButton.setVisible(True)
			saveButton.setVisible(True)
			editCategory = TextBox()
			editName = TextBox()
			editRating = ListBox(False)
			for i in range(self.MAX_RATING + 1):
				editRating.addItem(str(i))
    		
    		# Variable width textboxes
			catlen = len(movie.category)
			namelen = len(movie.name)    		
			if (catlen > 8):
				editCategory.setWidth(str(catlen*10) + "px")
			else:
				editCategory.setWidth("80px")
			if (namelen > 8):
				editName.setWidth(str(namelen*10) + "px")
			else:
				editName.setWidth("80px")
    		
			self.moviesFlexTable.setWidget(row, 1, editCategory)
			self.moviesFlexTable.setWidget(row, 2, editName)
			self.moviesFlexTable.setWidget(row, 3, editRating)
			editCategory.setText(movie.category)
			editName.setText(movie.name)
			editRating.setSelectedIndex(movie.rating)			
		editMovieButton.addClickListener(editMovieButton_Click)
		
		def saveButton_Click(sender):
			catText = self.moviesFlexTable.getWidget(row, 1)
			nameText = self.moviesFlexTable.getWidget(row, 2)
			ratingList = self.moviesFlexTable.getWidget(row, 3)
			
			newCategory = catText.getText().trim().lower()
			newCategory = newCategory[0].upper() + newCategory[1:]
			newName = nameText.getText().trim()
			newRating = ratingList.getSelectedIndex()

			if not self.verifyInputs(newName, newCategory):
				return
			
			# Removes temporarily to check for duplicates
			self.movies.remove(movie)
			
			newMovie = Movie(newName, newCategory, newRating)			
			if newMovie in self.movies:
				Window.alert("'" + newName + "' is already in table.")
				nameText.selectAll()
				return
    		
			self.remote.editMovie((movie.name, movie.category), (newMovie.name, newMovie.category, newMovie.rating), self)
		saveButton.addClickListener(saveButton_Click)
		
		def cancelButton_Click(sender):			
			self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 1))
			self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 2))
			self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 3))

			# Reverts fields to old movie info
			self.moviesFlexTable.setText(row, 1, movie.category)
			self.moviesFlexTable.setText(row, 2, movie.name)
			self.moviesFlexTable.setText(row, 3, movie.rating)

			cancelButton.setVisible(False)
			saveButton.setVisible(False)
			editMovieButton.setVisible(True)
		cancelButton.addClickListener(cancelButton_Click)
		
	def updateTopRatedMovies(self):
		numTopRated = len(self.topRatedMovies)
				
		self.clearTable(self.topRatedMoviesFlexTable)
			
		for row in range(numTopRated):
			self.topRatedMoviesFlexTable.setText(row+1, 0, self.topRatedMovies[row].category)
			self.topRatedMoviesFlexTable.setText(row+1, 1, self.topRatedMovies[row].name)
			self.topRatedMoviesFlexTable.setText(row+1, 2, self.topRatedMovies[row].rating)
			
		# Label should only be visible if less than 5 movies
		self.lessThanFiveLabel.setVisible(numTopRated < 5)
		
	def updateCategories(self):
		self.clearTable(self.topCategoryMoviesFlexTable)
		
		for row, cat in enumerate(self.categories):
			self.topCategoryMoviesFlexTable.setText(row+1, 0, cat + " (" + str(self.categories[cat][2]) + ")")
			self.topCategoryMoviesFlexTable.setText(row+1, 1, self.categories[cat][0])
			self.topCategoryMoviesFlexTable.setText(row+1, 2, "%.1f" % float(self.categories[cat][1]))
			
	def clearTable(self, table):
		try:
			for i in range(table.getRowCount()):
				table.removeRow(1)
		except:
			pass

	# Called when a response is received from a RPC.
	def onRemoteResponse(self, response, request_info):
		if request_info.method in ['getMovies', 'addMovie', 'deleteMovie', 'editMovie']:
		    # Clear current and add all
			self.movies = []
			self.clearTable(self.moviesFlexTable)
			for m in response:
				movie = Movie(m[0], m[1], m[2])
				self.addMovie(None, movie)
			self.moviesListLabel.setText("Movies List (" + str(len(self.movies)) + ")")
			self.remote.getTopRated(self)
			self.remote.getCategories(self)
			
		if request_info.method == 'getTopRated':
		    # Update top rated
			self.topRatedMovies = []
			for m in response:
				movie = Movie(m[0], m[1], m[2])
				self.topRatedMovies.append(movie)
			self.updateTopRatedMovies()
			
		if request_info.method == 'getCategories':
		    # Update categories
			self.categories = response
			self.updateCategories()
Exemplo n.º 4
0
class PageVerify:
    # setup JSON RPC
    facebook_user = {}
    users = []
    new_user = {}
    get_data = {}
    app_info = {}
    verification_key = None
    verification_status = False

    def onModuleLoad(self):
        self.remote = DataService()

        # do JSON RPC calls
        self.remote.get_facebook_user(self)
        self.remote.get_app_info(self, "verify")

        # labels and banners
        self.html_verify_banner = HTML("<h1>Verify your NetID</h1>")
        self.html_confirm_banner = HTML("<h1>Confirming your NetID...</h1>")

        self.lbl_verify_text = Label("Please verify your account.")
        self.lbl_confirm_text = Label("Confirming Acount...")
        self.lbl_confirm_result = Label()

        # textboxes
        self.tb_verify_netid = TextBox()

        # hook up keyboard events
        send_confirmation_email = self.send_confirmation_email
        class Add_KeyboardHandler():
            def onKeyPress(self, sender, keycode, modifiers):
                if keycode == KEY_ENTER:
                    send_confirmation_email()
            def onKeyDown(self, sender, keycode, modifiers): return
            def onKeyUp(self, sender, keycode, modifiers): return
        self.kbh = Add_KeyboardHandler()
        self.tb_verify_netid.addKeyboardListener(self.kbh)

        # buttons
        self.btn_verify = Button("Verify!", self.send_confirmation_email)

        # NetID information form
        self.table_verify_netid = FlexTable()
        self.table_verify_netid.setText(0, 0, "NetID:")
        self.table_verify_netid.setWidget(0, 1, self.tb_verify_netid)
        self.table_verify_netid.setWidget(1, 1, self.btn_verify)

        # panels
        self.main_panel = VerticalPanel()

        # check get information, if present, verify, if not request form
        self.location = Window.getLocation().getHref()
        self.tmp = self.location.split('?')
        self.tmp = self.tmp[len(self.tmp) - 1].split("&")
        for e in self.tmp:
            get_var = e.split("=")
            if len(get_var) == 2:
                PageVerify.get_data[get_var[0]] = get_var[1]

        if "vk" in PageVerify.get_data:
            # we have request from verification email
            self.main_panel.add(self.html_confirm_banner)
            self.main_panel.add(self.lbl_confirm_text)
            self.main_panel.add(self.lbl_confirm_result)
            self.verify_user()
        else:
            self.main_panel.add(self.html_verify_banner)
            self.main_panel.add(self.lbl_verify_text)
            self.main_panel.add(self.table_verify_netid)
            
        self.main_panel.addStyleName("verify_panel")

        # add everything to root panel
        RootPanel("page_verify").add(self.main_panel)

    def send_confirmation_email(self, sender, netid = None):
        """ given a valid NetID, send a confirmation email
            with a link (using encrypted key) to validate
            the user's NetID
        """
        if netid == None:
            netid = self.tb_verify_netid.getText()

        # create a new user with netid and facebook id
        self.remote.create_user(self, PageVerify.facebook_user['facebook_id'], netid, PageVerify.facebook_user['full_name'])

        # create cryptogram based on email name
        self.remote.encrypt(self, netid)

        # subject line
        subject = "Hello from Textbook Connect!"

        class EmailTimer(Timer):
            def __init__(self, context):
                Timer.__init__(self)
                self.max_tries = 10
                self.tries = 0
                self.context = context

            def run(self):
                self.context.btn_verify.setEnabled(False)
                self.context.tb_verify_netid.setFocus(False)
                self.tries += 1

                # stop timer after a certain time
                if self.tries >= self.max_tries:
                    Window.alert("It looks like there's a connection problem. We're sorry about the inconvenience. Please try again later.")
                    self.context.btn_verify.setEnabled(True)
                    self.cancel()
                    return False

                if "error" in PageVerify.new_user:
                    Window.alert(PageVerify.new_user["error"])
                    return False

                if len(PageVerify.new_user) == 0 or PageVerify.verification_key == None:
                    return False

                # message body
                link = "%sverify?vk=%s" % (PageVerify.app_info['url'], PageVerify.verification_key)

                body = "Hello, %s.<br /><br />Thank you for verifying your netid with us! " % PageVerify.new_user['name']
                body += "Please click the link below or copy and paste the link into a web browser.<br /><br />"
                body += "<a href=\"%s\">%s</a><br /><br />" % (link, link)
                body += "Thanks,<br /> Textbook Connect Team"
                
                self.context.remote.send_email(self.context, netid + "@cornell.edu", subject, body)
                Window.alert("Thank you! An email from Textbook Connect should arrive shortly.")
                self.cancel()
                return True

        et = EmailTimer(self)
        et.scheduleRepeating(500)

    def verify_user(self):
        """ take get data input with verification key
            and attempt to verify a user in the database
        """
        class VerifyTimer(Timer):
            def __init__(self, context):
                Timer.__init__(self)
                self.max_tries = 10
                self.tries = 0
                self.context = context

            def run(self):
                self.tries += 1

                if self.context.facebook_user == None or "vk" not in self.context.get_data:
                    return False

                # stop timer after a certain time
                if self.tries >= self.max_tries:
                    Window.alert("It looks like there's a connection problem. We're sorry about the inconvenience. Please try again later.")
                    self.context.lbl_confirm_result.setText("User verification unsuccessful...")
                    self.cancel()
                    return False

                self.context.remote.verify_email(self.context, self.context.facebook_user['facebook_id'], self.context.get_data['vk'])
                
                if self.context.verification_status:
                    self.context.lbl_confirm_result.setText("User verification successful!")
                    self.cancel()
                    Window.open(self.context.app_info['url'], "_top", "")
                    return True

        vt = VerifyTimer(self)
        vt.scheduleRepeating(500)

    def onRemoteResponse(self, response, request_info):
        """ Called when a response is received from an RPC
        """
        if not request_info.method in DataService.methods:
            Window.alert('Unrecognized JSONRPC method.')
            return

        if request_info.method == "get_facebook_user":
            PageVerify.facebook_user = {}
            for k, v in response.items():
                PageVerify.facebook_user[k] = v
        elif request_info.method == "get_app_info":
            for k, v in response.items():
                PageVerify.app_info[k] = v
        elif request_info.method == "encrypt":
            PageVerify.verification_key = response['c']
        elif request_info.method == "verify_email":
            PageVerify.verification_status = response['result']
        elif request_info.method == "create_user":
            PageVerify.new_user = {}
            for k, v in response.items():
                PageVerify.new_user[k] = v

    def onRemoteError(self, code, message, request_info):
        """ Called when a returned response is invalid or Server Error
        """
        code = str(code)
        message = str(message)

        if len(code) > 200: code = code[0:200] + "..."
        if len(message) > 200: message = message[0:200] + "..."

        err_msg = Label("Server Error or invalid response: ERROR " + str(code) + " - " + str(message))
        err_msg.addStyleName("status")
        Window.alert(err_msg.getText())
Exemplo n.º 5
0
class Calendar(FocusPanel):
    monthsOfYear = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    daysOfWeek = ['M', 'T', 'W', 'T', 'F', 'S', 'S']
    daysOfWeek3 = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    today = 'Today'
    tomorrow = 'Tomorrow'
    yesterday = 'Yesterday'
    cancel = 'Cancel'

    def __init__(self, **kwargs):
        self.backyear = kwargs.pop('BackyearSymbol', '<<')
        self.backmonth = kwargs.pop('BackmonthSymbol', '<')
        self.fwdyear = kwargs.pop('FwdyearSymbol', '>>')
        self.fwdmonth = kwargs.pop('FwdmonthSymbol', '>')
        self.addbuttons = kwargs.pop('AddButtons', True)
        self.mindate = kwargs.pop('MinDate', None) # (yr, mnth, day)
        self.maxdate = kwargs.pop('MaxDate', None) # (yr, mnth, day)
        self.weekdaylength = kwargs.pop('WeekdayLength', 1) 
        self.dayoffset = kwargs.pop('DayOffset', 1) # 1 returns Mon, 0 for Sun
        self.daybuttons = kwargs.pop('DayButtons', False)
        if kwargs.pop('ArrowButtons', False):
            self.bkls = Button
        else:
            self.bkls = Hyperlink

        FocusPanel.__init__(self, **kwargs)

        self.setDate()

        self.todayYear = self.currentYear
        self.todayMonth = self.currentMonth
        self.todayDay = self.currentDay
        self.selectedDateListeners = []
        self.defaultGrid = None # used later

    def setDate(self, _date=None, m=None, d=None):
        """ _date - object of datetime.date class """
        if m is None and d is None:
            if _date is None:
                y, m, d = time.strftime("%Y-%m-%d").split("-")
            else:
                m = _date.month
                y = _date.year
                d = _date.day
        else:
            y = _date

        self.currentYear = int(y)
        self.currentMonth = int(m)
        self.currentDay = int(d)

    def getMonthsOfYear(self):
        return self.monthsOfYear

    def getDaysOfWeek(self):
        if self.weekdaylength == 1:
            dow = self.daysOfWeek
        else:
            dow = self.daysOfWeek3
        return dow[-self.dayoffset:] + \
               dow[:-self.dayoffset]

    def addSelectedDateListener(self, listener):
        self.selectedDateListeners.append(listener)

    def removeSelectedDateListener(self, listener):
        self.selectedDateListeners.remove(listener)

    def isLeapYear(self, year):
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            return True
        else:
            return False

    def _indaterange(self, year, mnth, day=None):

        if self.mindate is not None:
            if year < self.mindate[0]:
                return False
            if year == self.mindate[0]:
                if mnth < self.mindate[1]:
                    return False
                if day is not None:
                    if mnth == self.mindate[1] and day < self.mindate[2]:
                        return False

        if self.maxdate is not None:
            if year > self.maxdate[0]:
                return False
            if year == self.maxdate[0]:
                if mnth > self.maxdate[1]:
                    return False
                if day is not None:
                    if mnth == self.maxdate[1] and day > self.maxdate[2]:
                        return False

        return True

    def getDaysInMonth(self, mth, year):
        days = 0
        if mth in [1, 3, 5, 7, 8, 10, 12]:
            days=31
        elif mth in [4, 6, 9, 11]:
            days = 30
        elif (mth==2 and self.isLeapYear(year)):
            days = 29
        else:
            days = 28
        return days

    def setPosition(self, left, top):
        element = self.getElement()
        DOM.setStyleAttribute(element, "left", "%dpx" % left)
        DOM.setStyleAttribute(element, "top", "%dpx" % top)

    def show(self, left, top):
        if left < 0:
            left = 0
        if top < 0:
            top = 0
        self.setPosition(left, top)
        self.drawCurrent()
        self.setVisible(True)

    def drawCurrent(self):
        self.drawDate()

    def draw(self, month , year):
        tod = time.localtime()
        mm = tod.tm_mon
        yy = tod.tm_year
        # has today changed and thus changed month? cater to rare case
        # where widget in created on last day of month and
        # page left till next day
        hasChangeMonth = False
        if yy != self.todayYear or mm != self.todayMonth:
            hasChangeMonth = True
            self.todayYear = yy
            self.todayMonth = mm

        # check to see if we have drawn the full widget before
        if self.defaultGrid is None:
            self.drawFull(month, year)
        else:
            # ok means we are re-drawing, but first check if it is the same
            # as the defaultGrid, if yes, just use it
            if not hasChangeMonth and month == self.todayMonth and \
                   year == self.todayYear:
                self.middlePanel.setWidget(self.defaultGrid)
                self.currentMonth = self.todayMonth
                self.currentYear = self.todayYear
            else:
                # we have to redraw the grid -- bah
                g = self.drawGrid(month, year)

                if hasChangeMonth:
                    # reset the default grid as we have changed months
                    self.defaultGrid = grid

            #
            # what about the title panel?
            #
            txt = "<b>"
            txt += self.getMonthsOfYear()[month-1] + "&nbsp;" + str(year)
            txt += "</b>"
            self.titlePanel.setWidget(HTML(txt))
            self.setVisible(True)

    def drawFull(self, month, year):
        # should be called only once when we draw the calendar for
        # the first time
        self.vp = VerticalPanel()
        self.vp.setSpacing(0)
        self.vp.setPadding(0)
        self.vp.addStyleName("calendarbox calendar-module calendar")
        self.setWidget(self.vp)
        self.setVisible(False)
        #
        mth = int(month)
        yr = int(year)

        tp = HorizontalPanel(Width="100%")
        tp.addStyleName("calendar-top-panel")
        tp.setSpacing(0)
        tp.setPadding(0)

        self.h1 = None
        self.h2 = None
        self.h4 = None
        self.h5 = None
        if self.backyear:
            self.h1 = self.bkls(self.backyear, StyleName="calendar-arrows")
            self.h1.addClickListener(getattr(self, 'onPreviousYear'))
            tp.add(self.h1)
            tp.setCellHorizontalAlignment(self.h1, "left")
        if self.backmonth:
            self.h2 = self.bkls(self.backmonth, StyleName="calendar-arrows")
            self.h2.addClickListener(getattr(self, 'onPreviousMonth'))
            tp.add(self.h2)
            tp.setCellHorizontalAlignment(self.h2, "left")

        # titlePanel can be changed, whenever we draw, so keep the reference
        txt = "<b>"
        txt += self.getMonthsOfYear()[mth-1] + " " + str(yr)
        txt += "</b>"
        self.titlePanel = SimplePanel()
        self.titlePanel.setWidget(HTML(txt))
        self.titlePanel.setStyleName("calendar-center")

        tp.add(self.titlePanel)
        tp.setCellHorizontalAlignment(self.titlePanel, "center")
        tp.setCellWidth(self.titlePanel, "100%")

        if self.fwdmonth:
            self.h4 = self.bkls(self.fwdmonth, StyleName="calendar-arrows")
            self.h4.addClickListener(getattr(self, 'onNextMonth'))
            tp.add(self.h4)
            tp.setCellHorizontalAlignment(self.h4, "right")
            tp.setCellWidth(self.h4, "100%")
            self.h4.setWidth("100%")
        if self.fwdyear:
            self.h5 = self.bkls(self.fwdyear, StyleName="calendar-arrows")
            self.h5.addClickListener(getattr(self, 'onNextYear'))
            tp.add(self.h5)
            tp.setCellHorizontalAlignment(self.h5, "right")

        tvp = VerticalPanel(Width="100%")
        tvp.setSpacing(2)
        tvp.add(tp)

        self.vp.add(tvp)

        # done with top panel

        self.middlePanel = SimplePanel()
        grid = self.drawGrid(mth, yr)
        self.middlePanel.setWidget(grid)
        self.vp.add(self.middlePanel)
        self.defaultGrid = grid

        if self.addbuttons:
            #
            # some links & handlers
            #
            bh1 = Hyperlink(self.yesterday)
            bh1.addClickListener(getattr(self, 'onYesterday'))
            bh2 = Hyperlink(self.today)
            bh2.addClickListener(getattr(self, 'onToday'))
            bh3 = Hyperlink(self.tomorrow)
            bh3.addClickListener(getattr(self, 'onTomorrow'))
            bh4 = Hyperlink(self.cancel)
            bh4.addClickListener(getattr(self, 'onCancel'))

            #
            # add code to test another way of doing the layout
            #
            b = HorizontalPanel()
            b.add(bh1)
            b.add(bh2)
            b.add(bh3)
            b.addStyleName("calendar-shortcuts")
            self.vp.add(b)
            b2 = SimplePanel()
            b2.add(bh4)
            b2.addStyleName("calendar-cancel")
            self.vp.add(b2)

        self.checkLinks(mth, yr)
        self.setVisible(True)

    def checkLinks(self, month=None, year=None):
        if month is None:
            month = self.currentMonth
        if year is None:
            year = self.currentYear

        if self.backyear:
            ok = self._indaterange(year-1, month)
            self.h1.setEnabled(ok)
        if self.backmonth:
            py, pm = self._previousMonth(year, month)
            ok = self._indaterange(py, pm)
            print "prevmonth", month, year, py, pm, ok
            self.h2.setEnabled(ok)
        if self.fwdmonth:
            ny, nm = self._nextMonth(year, month)
            ok = self._indaterange(ny, nm)
            print "nextmonth", month, year, ny, nm, ok
            self.h4.setEnabled(ok)
        if self.fwdyear:
            ok = self._indaterange(year+1, month)
            self.h5.setEnabled(ok)

    def drawGrid(self, month, year):
        # draw the grid in the middle of the calendar

        self.checkLinks(month, year)

        daysInMonth = self.getDaysInMonth(month, year)
        # first day of the month & year
        secs = time.mktime((year, month, 1, 0, 0, 0, 0, 0, -1))
        struct = time.localtime(secs)
        startPos = (struct.tm_wday + self.dayoffset) % 7
        slots = startPos + daysInMonth - 1
        rows = int(slots/7) + 1
        grid = Grid(rows+1, 7, # extra row for the days in the week
                    StyleName="calendar-grid") 
        grid.setWidth("100%")
        grid.addTableListener(self)
        self.middlePanel.setWidget(grid)
        cf = grid.getCellFormatter()
        #
        # put some content into the grid cells
        #
        for i in range(7):
            grid.setText(0, i, self.getDaysOfWeek()[i])
            cf.addStyleName(0, i, "calendar-header")
        #
        # draw cells which are empty first
        #
        day = 0
        pos = 0
        while pos < startPos:
            self._setCell(grid, 1, pos, BLANKCELL, "calendar-blank-cell")
            pos += 1
        # now for days of the month
        row = 1
        day = 1
        col = startPos
        while day <= daysInMonth:
            if pos % 7 == 0 and day != 1:
                row += 1
            col = pos % 7
            if not self._indaterange(self.currentYear, self.currentMonth, day):
                self._setCell(grid, row, col, BLANKCELL, "calendar-blank-cell")
                day += 1
                pos += 1
                continue
            if self.currentYear == self.todayYear and \
               self.currentMonth == self.todayMonth and day == self.todayDay:
                style = "calendar-cell-today"
            else:
                style = "calendar-day-cell"
            self._setCell(grid, row, col, str(day), style)
            day += 1
            pos += 1
        #
        # now blank lines on the last row
        #
        col += 1
        while col < 7:
            self._setCell(grid, row, col, BLANKCELL, "calendar-blank-cell")
            col += 1

        return grid

    def _setCell(self, grid, row, col, txt, style):
        
        cf = grid.getCellFormatter()
        if self.daybuttons:
            if txt != BLANKCELL:
                listener = lambda x, col=col, row=row, grid=grid\
                            : self.onCellClicked(grid, row, col)
            else:
                listener = None
            b = Button(txt, listener=listener, StyleName="%s-button" % style)
            grid.setWidget(row, col, b)
            cf.setWidth(row, col, "100%")
        else:
            grid.setHTML(row, col, txt)
            cf.setStyleName(row, col, style)

    def onCellClicked(self, grid, row, col):
        if row == 0:
            return
        text = grid.getText(row, col).strip()
        if text == BLANKCELL:
            return
        try:
            selectedDay = int(text)
        except ValueError, e:
            return
        # fire event to all listeners
        for listener in self.selectedDateListeners:
            if hasattr(listener, "onDateSelected"):
                listener = listener.onDateSelected
            listener(self.currentYear, self.currentMonth, selectedDay)
        self.setVisible(False)
Exemplo n.º 6
0
class PageIndex:
    def onModuleLoad(self):
        # JSON RPC response containers
        self.facebook_user = {}
        self.app_info = {}
        self.wl_books = []
        self.sl_books = []
        self.events = []

        # setup JSON RPC
        self.remote = DataService()

        # make JSON RPC calls
        self.remote.get_app_info(self, "index")
        self.remote.get_wish_list(self)
        self.remote.get_sell_list(self)

        self.remote.get_events(self, 10)

        # panels
        self.main_panel = HorizontalPanel()
        self.feed_panel = VerticalPanel()
        self.list_panel = VerticalPanel()

        self.feed_panel.addStyleName("feed_panel")
        self.list_panel.addStyleName("list_panel")

        # labels
        self.html_feed_title = HTML("<h1>Recent Activity</h1>")
        self.html_wish_title = HTML("<h1>Your Wishlist</h1>")
        self.html_sell_title = HTML("<h1>Your Selllist</h1>")

        # user lists
        self.wish_list = UserList("wish", self)
        self.sell_list = UserList("sell", self)

        self.wish_list.addStyleName("userlist")
        self.sell_list.addStyleName("userlist")

        self.feed_panel.add(self.html_feed_title)

        self.list_panel.add(self.html_wish_title)
        self.list_panel.add(self.wish_list)

        self.list_panel.add(HTML("<br />"))
        self.list_panel.add(self.html_sell_title)
        self.list_panel.add(self.sell_list)

        # add everything together
        self.main_panel.add(self.feed_panel)
        self.main_panel.add(self.list_panel)
        self.main_panel.setWidth("100%")

        RootPanel("page_index").add(self.main_panel)

        show_events = self.show_events
        class EventTimer(Timer):
            def run(self):
                show_events()
        et = EventTimer()
        self.show_events()
        et.scheduleRepeating(5000)

    def populate_book_lists(self):
        """ check the JSON RPC containers and fill the UserLists if
            it finds them to be non-empty
        """
        for b in self.wl_books:
            Window.alert(str(b))
            self.wish_list.add_book(b)
            
        for b in self.sl_books:
            self.sell_list.add_book(b)
        return True

    def show_events(self):
        """ create events on the recent activity feed 
        """
        for e in self.events:
            self.add_event(e)
        self.events = []
	
    def add_event(self, event):
        """ add an event to the recent activity feed
        """
        event_panel = HorizontalPanel()
        mid_panel = VerticalPanel()
        book_panel = HorizontalPanel()

        # profile picture
        pic_url = "https://graph.facebook.com/" + event['fbid'] + "/picture"
        pic_html = HTML("<img src=\"%s\" />" % pic_url)

        # event string
        event_html = HTML("<span style=\"font-weight: bold\">%s</span>" % event['string'])
        url = self.app_info['url'] + "book?asin=" + event['book']['asin']

        cutoff = 40
        # book thumbnail
        img_url = event['book']['thumbnail']
        if event['book']["thumbnail"] == "N/A":
            img_url = self.app_info['url'] + "static/images/default_thumbnail.png"
        img_html = HTML("<a href=\"%s\" target=\"_top\"><img src=\"%s\" /></a>" % (url, img_url))

        # handle book information
        title = event['book']['title']
        author = event['book']['author']
        isbn = event['book']['isbn10']

        if len(title) > cutoff: title = title[0:cutoff] + "..."
        if len(author) > cutoff: author = author[0:cutoff] + "..."
        if len(isbn) > cutoff: isbn = isbn[0:cutoff] + "..."

        html = "<a href=\"%s\" target=\"_top\"><span style=\"font-weight: bold\">%s</span></a><br />" % (url, title)
        html += "<span style=\"font-weight: bold; color: #6C82AF;\">ISBN-10: %s</span><br />" % isbn
        html += "<span style=\"font-weight: bold; color: #7D7D7D;\">%s</span><br />" % author
        html_entry = HTML(html)

        book_panel.add(img_html)
        book_panel.add(html_entry)

        mid_panel.add(event_html)
        mid_panel.add(book_panel)
        
        event_panel.add(pic_html)
        event_panel.add(mid_panel)

#        html = "<span style=\"text-align: right; width: 100%; display: block;\">%s</span><hr />" % unicode(event['time'])
#        event_panel.add(HTML(html))
        self.feed_panel.add(event_panel)
	
    def onRemoteResponse(self, response, request_info):
        """ Called when a response is received from an RPC
        """
        if request_info.method == "get_facebook_user":
            for k, v in response.items():
                self.facebook_user[k] = v
        elif request_info.method == "get_app_info":
            for k, v in response.items():
                self.app_info[k] = v
        elif request_info.method == "get_wish_list":
            self.wl_books = response
            for b in self.wl_books:
                self.wish_list.add_book(b)
        elif request_info.method == "get_sell_list":
            self.sl_books = response
            for b in self.sl_books:
                self.sell_list.add_book(b)
        elif request_info.method == "add_event":
            self.events.append(response)
        elif request_info.method == "get_events":
            self.events = response

    def onRemoteError(self, code, message, request_info):
        """ Called when a returned response is invalid or Server Error
        """
        code = str(code)
        message = str(message)

        if len(code) > 200: code = code[0:200] + "..."
        if len(message) > 200: message = message[0:200] + "..."

        err_msg = Label("Server Error or invalid response: ERROR " + str(code) + " - " + str(message))
        err_msg.addStyleName("status")
        Window.alert(err_msg.getText())
Exemplo n.º 7
0
class PageBookComments:
    def onModuleLoad(self):
        # parse get data
        self.location = Window.getLocation().getHref()
        self.get_data = {}
        self.tmp = self.location.split('?')
        self.tmp = self.tmp[len(self.tmp) - 1].split("&")
        for e in self.tmp:
            get_var = e.split("=")
            if len(get_var) == 2:
                self.get_data[get_var[0]] = get_var[1]

        # JSON RPC response holders
        self.facebook_user = {}
        self.app_info = {}
        self.sellers = []
        self.book = {}
        self.has_book = "none"
        
        # setup JSON RPC
        self.remote = DataService()

        self.remote.get_facebook_user(self)
        self.remote.get_app_info(self, "book_detail")
        if "asin" in self.get_data:
            self.remote.get_book_details(self, self.get_data["asin"])
            self.remote.get_sellers(self, self.get_data["asin"])
            self.remote.user_has_book(self, self.get_data["asin"])

        # create panels
        self.main_panel = HorizontalPanel()
        self.info_panel = VerticalPanel()
        self.sell_btn_panel = VerticalPanel()
        self.wish_btn_panel = VerticalPanel()
        self.seller_panel = VerticalPanel()
        self.add_comment_panel = VerticalPanel()

        # images
        self.img_book_cover = Image()

        # html labels
        self.html_book_title = HTML()
        self.html_book_author = HTML()
        self.html_book_isbn10 = HTML()
        self.html_book_publisher = HTML()
        self.html_book_publish_date = HTML()
        self.html_book_edition = HTML()
        self.html_book_binding = HTML()

        self.html_btn_sell = HTML()
        self.html_btn_wish = HTML()
        
        self.html_seller_title = HTML()

        # check for no get data!
        if "asin" not in self.get_data:
            self.html_book_title.setHTML("<h1>Book not found!</h1>\n<p>The book you are looking for does not exist.</p>")
            self.info_panel.setWidth("100%")
            self.main_panel.setWidth("100%")
            self.info_panel.add(self.html_book_title)
            self.main_panel.add(self.info_panel)
            RootPanel("page_book_comments").add(self.main_panel)
            return

        # add to sellers panel
        self.seller_panel.add(self.html_seller_title)
        self.seller_panel.addStyleName("comments")

        self.info_panel.add(self.html_book_title)
        self.info_panel.add(self.html_book_author)
        self.info_panel.add(self.html_book_isbn10)
        self.info_panel.add(self.html_book_publisher)
        self.info_panel.add(self.html_book_publish_date)
        self.info_panel.add(self.html_book_edition)
        self.info_panel.add(self.html_book_binding)
        self.info_panel.add(self.add_comment_panel)
        self.info_panel.add(self.seller_panel)
        self.info_panel.addStyleName("info_panel")
        
        self.main_panel.add(self.info_panel)
        self.main_panel.add(self.img_book_cover)
        
        RootPanel("page_book_comments").add(self.main_panel)
        
        # spin until book info get here
        class SpinTimer(Timer):
            def __init__(self, max_tries = 10, interval = 500):
                Timer.__init__(self)
                self.interval = interval
                self.max_tries = max_tries
                self.tries = 0
                self.func = func
                self.params = params
                self.scheduleRepeating(self.interval)

            def run(self):
                self.tries += 1

                if self.tries >= self.max_tries:
                    Window.alert("It looks like there's a connection problem. We're sorry about the inconvenience. Please try again later.")
                    self.cancel()
                    return

                if populate_book_details():
                    self.cancel()
        
        populate_book_details = self.populate_book_details
        st = SpinTimer()

    def populate_book_details(self):
        """ fill in book information on this page
        """
        if len(self.facebook_user) == 0: return False
        if len(self.app_info) == 0: return False
        if len(self.book) == 0: return False
        if self.book['num_sellers'] != 0 and len(self.sellers) == 0: return False

        if 'title' not in self.book or 'binding' not in self.book: return False
        binding = "Hardcover"
        if self.book['binding'] != "Hardcover" and not self.book['binding']: binding = "Paperback"
        self.html_book_title.setHTML("<span class=\"title\">%s [%s]</span>" % (self.book['title'], binding))

        if 'author' not in self.book: return False
        self.html_book_author.setHTML("<span class=\"author\">%s</span>" % self.book['author'])

        if 'isbn10' not in self.book: return False
        self.html_book_isbn10.setHTML("<span class=\"isbn\">ISBN 10: %s</span>" % self.book['isbn10'])

        # add these in
        #self.html_book_publisher.setHTML("<span class=\"info\">Publisher: %s</span>" % self.book['publisher'])
        #self.html_book_publish_date.setHTML("<span class=\"info\">Published: %s</span>" % self.book['publish_date'])

        if 'edition' not in self.book: return False
        self.html_book_edition.setHTML("<span class=\"info\">Edition: %s</span>" % self.book['edition'])

        if 'thumbnail' not in self.book: return False
        if self.book['thumbnail'] == "N/A":
            self.book['thumbnail'] = self.app_info['url'] + "static/images/default_thumbnail.png"
        self.img_book_cover.setUrl(self.book['thumbnail'])

        if 'num_sellers' not in self.book: return False
        amount = "amount_low"
        if int(self.book['num_sellers']) > 3: amount = "amount_medium"
        elif int(self.book['num_sellers']) > 7: amount = "amount_high"
        self.html_btn_sell.setHTML("<span class=\"num_sellers\">Sellers: <span class=\"%s\">%d</span></span>" % (amount, self.book['num_sellers']))

        if 'num_watchers' not in self.book: return False
        amount = "amount_low"
        if int(self.book['num_watchers']) > 3: amount = "amount_medium"
        elif int(self.book['num_watchers']) > 7: amount = "amount_high"
        self.html_btn_wish.setHTML("<span class=\"num_watchers\">Watchers: <span class=\"%s\">%d</span></span>" % (amount, self.book['num_watchers']))

        self.html_seller_title.setHTML("<h1>%s's Seller Activity for %s</h1>" % (self.facebook_user['first_name'], self.book['title']))

        comments_url = self.app_info['url']
        comments_url += "fbcommentsplugin?asin=" + self.get_data['asin']
        comments_url += "&fbid=" + self.get_data['fbid']

        self.frame_seller_comments = HTML('<div data-height="600px" class="fb-comments" data-num-posts="3" data-width="600"></div>')

        self.seller_panel.add(self.html_seller_title)
        self.seller_panel.add(self.frame_seller_comments)
        return True

    def onRemoteResponse(self, response, request_info):
        """ Called when a response is received from an RPC
        """
        if not request_info.method in DataService.methods:
            Window.alert('Unrecognized JSONRPC method.')
            return

        if request_info.method == "get_facebook_user":
            self.facebook_user = {}
            for k, v in response.items():
                self.facebook_user[k] = v
        elif request_info.method == "get_book_details":
            self.book = {}
            for k, v in response.items():
                self.book[k] = v
        elif request_info.method == "get_app_info":
            self.app_info = {}
            for k, v in response.items():
                self.app_info[k] = v
        elif request_info.method == "get_sellers":
            self.sellers = response
        elif request_info.method == "user_has_book":
            self.has_book = response["result"]

    def onRemoteError(self, code, message, request_info):
        """ Called when a returned response is invalid for Server Error
        """
        code = str(code)
        message = str(message)

        if len(code) > 200: code = code[0:200] + "..."
        if len(message) > 200: message = message[0:200] + "..."

        err_msg = Label("Server Error or invalid response: ERROR " + str(code) + " - " + str(message))
        err_msg.addStyleName("status")
        Window.alert(err_msg.getText())