Esempio n. 1
0
class ViewFavoritesItem(Item):
    def __init__(self, parent):
        _debug_('ViewFavoritesItem.__init__(parent=%r)' % (parent,), 2)
        Item.__init__(self, parent, skin_type='tv')
        self.name = _('View Favorites')
        self.menuw = None
        self.recordclient = RecordClient()


    def actions(self):
        _debug_('actions()', 2)
        return [ ( self.view_favorites , _('View Favorites') ) ]


    def view_favorites(self, arg=None, menuw=None):
        _debug_('view_favorites(arg=%r, menuw=%r)' % (arg, menuw), 2)
        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return

        items = self.get_items()
        if not len(items):
            AlertBox(_('No favorites.')).show()
            return

        favorite_menu = menu.Menu(_( 'View Favorites'), items, reload_func=self.reload, item_types='tv favorite menu')
        self.menuw = menuw
        rc.app(None)
        menuw.pushmenu(favorite_menu)
        menuw.refresh()


    def reload(self):
        _debug_('reload()', 2)
        menuw = self.menuw

        menu = menuw.menustack[-1]

        new_choices = self.get_items()
        if not menu.selected in new_choices and len(new_choices):
            sel = menu.choices.index(menu.selected)
            if len(new_choices) <= sel:
                menu.selected = new_choices[-1]
            else:
                menu.selected = new_choices[sel]

        menu.choices = new_choices

        return menu


    def get_items(self):
        _debug_('get_items()', 2)
        items = []

        (status, favorites) = self.recordclient.getFavoritesNow()
        if status:
            f = lambda a, b: cmp(a.priority, b.priority)
            favs = favorites.values()
            favs.sort(f)
            for fav in favs:
                items.append(FavoriteItem(self, fav))

        return items
class ScheduledRecordingsItem(Item):
    def __init__(self, parent):
        Item.__init__(self, parent, skin_type='tv')
        self.name = _('Scheduled Recordings')
        self.menuw = None
        self.recordclient = RecordClient()


    def actions(self):
        return [ ( self.display_schedule , _('Display Scheduled Recordings') ) ]


    def display_schedule(self, arg=None, menuw=None):
        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return

        items = self.get_items()
        if not len(items):
            AlertBox(_('Nothing scheduled.')).show()
            return

        schedule_menu = menu.Menu(_('Scheduled Recordings'), items,
            reload_func=self.reload, item_types='tv program menu')
        self.menuw = menuw
        menuw.pushmenu(schedule_menu)
        menuw.refresh()


    def reload(self):
        menuw = self.menuw

        menu = menuw.menustack[-1]

        new_choices = self.get_items()
        if not menu.selected in new_choices and len(new_choices):
            sel = menu.choices.index(menu.selected)
            if len(new_choices) <= sel:
                menu.selected = new_choices[-1]
            else:
                menu.selected = new_choices[sel]

        menu.choices = new_choices

        return menu


    def get_items(self):
        items = []

        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return []

        (status, progs) = self.recordclient.getScheduledRecordingsNow()
        if status:
            f = lambda a, b: cmp(a.start, b.start)
            progs.sort(f)
            for prog in progs:
                items.append(ProgramItem(self, prog, context='schedule'))
        else:
            AlertBox(_('Get scheduled recordings failed')+(':\n%s' % schedule)).show()
            return []

        return items
Esempio n. 3
0
class ManualRecordItem(Item):

    def __init__(self, parent):
        logger.log( 9, 'manual_record.ManualRecordItem.__init__(parent)')
        Item.__init__(self, parent, skin_type='video')

        self.name = _("Manual Record")

        self.recordclient = RecordClient()

        # maxinum number of days we can record
        self.MAXDAYS = 7

        # minimum amount of time it would take record_server.py
        # to pick us up in seconds by default it is one minute plus
        # a few seconds just in case
        self.MINPICKUP = 70

        self.months = [
            _('Jan'), _('Feb'), _('Mar'), _('Apr'), _('May'), _('Jun'),
            _('Jul'), _('Aug'), _('Sep'), _('Oct'), _('Nov'), _('Dec')
        ]

        now = time.time()
        now += 300
        self.startnow = now
        self.starttime = time.localtime(now)
        now += 1900
        self.stopnow = now
        self.stoptime = time.localtime(now)


    def make_newprog(self):
        logger.log( 9, 'make_newprog(self)')
        self.prog = TvProgram()

        self.disp_title = self.prog.title = self.name

        self.description = ''
        self.prog.desc = ''

        self.prog.channel_id = config.TV_CHANNELS[0][0]
        self.disp_channel = config.TV_CHANNELS[0][1]

        #self.start_year = self.starttime[0]
        self.start_month = self.starttime[1]
        self.disp_start_month = self.months[self.start_month - 1]
        self.start_day   = self.starttime[2]
        self.start_time  = time.strftime(config.TV_TIME_FORMAT, self.starttime)
        self.prog.start  = self.startnow
        self.disp_starttime = '%s %s %s' % (self.disp_start_month, self.start_day, self.start_time)

        #self.stop_year = self.stoptime[0]
        self.stop_month = self.stoptime[1]
        self.disp_stop_month = self.months[self.stop_month - 1]
        self.stop_day   = self.stoptime[2]
        self.stop_time  = time.strftime(config.TV_TIME_FORMAT, self.stoptime)
        self.prog.stop  = self.stopnow
        self.disp_stoptime = '%s %s %s' % (self.disp_stop_month, self.stop_day, self.stop_time)


    def actions(self):
        logger.log( 9, 'actions(self)')
        return [( self.display_recitem , _('Display record item') )]


    def display_recitem(self, arg=None, menuw=None):
        logger.log( 9, 'display_recitem(self, arg=None, menuw=None)')
        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return

        self.make_newprog()

        items = []

        items.append(menu.MenuItem(_('Modify name'), action=self.mod_name))
        items.append(menu.MenuItem(_('Modify channel'), action=self.mod_channel))
        items.append(menu.MenuItem(_('Modify start month'), action=self.mod_start_month))
        items.append(menu.MenuItem(_('Modify start day'), action=self.mod_start_day))
        items.append(menu.MenuItem(_('Modify start time'), action=self.mod_start_time))
        items.append(menu.MenuItem(_('Modify stop month'), action=self.mod_stop_month))
        items.append(menu.MenuItem(_('Modify stop day'), action=self.mod_stop_day))
        items.append(menu.MenuItem(_('Modify stop time'), action=self.mod_stop_time))
        items.append(menu.MenuItem(_('Save'), action=self.save_changes))

        manualrecord_menu = menu.Menu(_('Record Item Menu'), items, item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_name(self, arg=None, menuw=None):
        logger.log( 9, 'mod_name(self, arg=None, menuw=None)')
        self.menuw = menuw
        InputBox(text=_('Alter Name'), handler=self.alter_name).show()


    def mod_channel(self, arg=None, menuw=None):
        logger.log( 9, 'mod_channel(self, arg=None, menuw=None)')
        items = []

        for chanline in config.TV_CHANNELS:
            items.append(menu.MenuItem(chanline[1], action=self.alter_prop,
                         arg=('channel', (chanline[1],chanline[0]))))

        manualrecord_menu = menu.Menu(_('Modify Channel'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_start_month(self, arg=None, menuw=None):
        logger.log( 9, 'mod_start_month(self, arg=None, menuw=None)')
        items = []

        iter=0
        while iter < 12:
            month_name = self.months[(iter + self.starttime[1] - 1) % 12];
            month_num  = self.months.index(month_name) + 1;
            items.append(menu.MenuItem(month_name, action=self.alter_prop, arg=('startmonth', (month_name, month_num))))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_start_day(self, arg=None, menuw=None):
        logger.log( 9, 'mod_start_day(self, arg=None, menuw=None)')
        items = []

        numdays = calendar.monthrange(self.starttime[0], self.start_month)[1]
        daylimit = numdays + 1
        iter=1
        while iter < daylimit:
            newday = (iter + self.starttime[2] - 1)
            currday = newday % daylimit
            if newday >= daylimit:
                currday += 1
            items.append(menu.MenuItem(str(currday), action=self.alter_prop,
                         arg=('startday', currday)))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_start_time(self, arg=None, menuw=None):
        logger.log( 9, 'mod_start_time(self, arg=None, menuw=None)')
        items = []

        currminutes = self.starttime[3]*60 + self.starttime[4]
        minpadding = 5 - (currminutes % 5)
        if minpadding == 5:
            minpadding = 0
        for i in range(288):
            mod = (i * 5 + currminutes + minpadding) % 1440
            showtime = strftime(config.TV_TIME_FORMAT, gmtime(float(mod * 60)))
            items.append(menu.MenuItem(showtime,
                                       action=self.alter_prop,
                                       arg=('starttime', showtime)))

        manualrecord_menu = menu.Menu(_('Modify Time'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_stop_month(self, arg=None, menuw=None):
        logger.log( 9, 'mod_stop_month(self, arg=None, menuw=None)')
        items = []

        iter=0
        while iter < 12:
            month_name = self.months[(iter + self.stoptime[1] - 1) % 12];
            month_num  = self.months.index(month_name) + 1;
            items.append(menu.MenuItem(month_name, action=self.alter_prop, arg=('stopmonth', (month_name, month_num))))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_stop_day(self, arg=None, menuw=None):
        logger.log( 9, 'mod_stop_day(self, arg=None, menuw=None)')
        items = []

        numdays = calendar.monthrange(self.stoptime[0], self.stop_month)[1]
        daylimit = numdays + 1
        iter=1
        while iter < daylimit:
            newday = (iter + self.starttime[2] - 1)
            currday = newday % daylimit
            if newday >= daylimit:
                currday += 1
            items.append(menu.MenuItem(str(currday), action=self.alter_prop,
                         arg=('stopday', currday)))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def mod_stop_time(self, arg=None, menuw=None):
        logger.log( 9, 'mod_stop_time(self, arg=None, menuw=None)')
        items = []

        currminutes = self.starttime[3]*60 + self.starttime[4]
        minpadding = 5 - (currminutes % 5)
        if minpadding == 5:
            minpadding = 0
        for i in range(288):
            mod = (i * 5 + currminutes + minpadding) % 1440
            showtime = strftime(config.TV_TIME_FORMAT, gmtime(float(mod * 60)))
            items.append(menu.MenuItem(showtime,
                                       action=self.alter_prop,
                                       arg=('stoptime', showtime)))

        manualrecord_menu = menu.Menu(_('Modify Time'), items,
                                  item_types = 'tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()


    def alter_name(self, name):
        logger.log( 9, 'alter_name(self, name)')
        if name:
            self.disp_title = self.prog.title = name

        self.menuw.refresh()


    def alter_prop(self, arg=(None,None), menuw=None):
        logger.log( 9, 'alter_prop(self, arg=(None,None), menuw=None)')
        (prop, val) = arg

        if prop == 'channel':
            self.prog.channel_id = val[1]
            self.disp_channel = val[0]

        if prop == 'startday':
            self.start_day = val
            self.disp_starttime = '%s %s %s' % (self.disp_start_month, self.start_day, self.start_time)

        if prop == 'startmonth':
            self.start_month = val[1]
            self.disp_start_month = val[0]
            self.disp_starttime = '%s %s %s' % (self.disp_start_month, self.start_day, self.start_time)

        if prop == 'starttime':
            self.start_time = val
            self.disp_starttime = '%s %s %s' % (self.disp_start_month, self.start_day, self.start_time)

        if prop == 'stopday':
            self.stop_day = val
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month, self.stop_day, self.stop_time)

        if prop == 'stopmonth':
            self.stop_month = val[1]
            self.disp_stop_month = val[0]
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month, self.stop_day, self.stop_time)

        if prop == 'stoptime':
            self.stop_time = val
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month, self.stop_day, self.stop_time)

        if menuw:
            menuw.back_one_menu(arg='reload')


    def save_changes(self, arg=None, menuw=None):
        logger.log( 9, 'save_changes(self, arg=None, menuw=None)')
        result = self.check_prog()
        if result:
            (result, reason) = self.recordclient.scheduleRecordingNow(self.prog)

            if not result:
                AlertBox(text=_('Save Failed, recording was lost')+(':\n%s' % reason)).show()
            else:
                if menuw:
                    menuw.back_one_menu(arg='reload')


    def check_prog(self):
        logger.log( 9, 'check_prog(self)')
        isgood = True
        curtime_epoch = time.time()
        curtime = time.localtime(curtime_epoch)
        startyear = curtime[0]
        stopyear = curtime[0]
        currentmonth = curtime[1]

        # handle the year wraparound
        if int(self.stop_month) < currentmonth:
            stopyear = int(stopyear) + 1
        if int(self.start_month) < currentmonth:
            startyear = int(startyear) + 1
        # create utc second start time
        starttime_str = '%s %s %s %s:00' % (self.start_month, self.start_day, startyear, self.start_time)
        starttime = time.mktime(strptime(starttime_str, '%m %d %Y '+config.TV_TIME_FORMAT+':%S'))
        # create utc stop time
        stoptime_str = '%s %s %s %s:00' % (self.stop_month, self.stop_day, stopyear, self.stop_time)
        stoptime = time.mktime(strptime(stoptime_str, '%m %d %Y '+config.TV_TIME_FORMAT+':%S'))

        # so we don't record for more then maxdays (maxdays day * 24hr/day * 60 min/hr * 60 sec/min)
        if not abs(stoptime - starttime) < (self.MAXDAYS * 86400):
            if self.MAXDAYS > 1:
                isgood = False
                msg = _("Program would record for more than %d days!") % self.MAXDAYS
                AlertBox(text=_('Save Failed, recording was lost')+(':\n%s' % msg)).show()
            else:
                isgood = False
                msg = _("Program would record for more than 1 day!") % self.MAXDAYS
                AlertBox(text=_('Save Failed, recording was lost')+(':\n%s' % msg)).show()

        elif not starttime < stoptime:
            isgood = False
            msg = _("start time is not before stop time." )
            AlertBox(text=_('Save Failed, recording was lost')+(':\n%s' % msg)).show()
        elif stoptime < curtime_epoch + self.MINPICKUP:
            isgood = False
            msg = _("Sorry, the stop time does not give enough time for scheduler to pickup the change.  Please set it to record for a few minutes longer.")
            AlertBox(text=_('Save Failed, recording was lost')+(':\n%s' % msg)).show()
        else:
            self.prog.start = starttime
            self.prog.stop = stoptime

        return isgood
Esempio n. 4
0
class ProgramItem(Item):
    """
    Item class for program items

    This is used in the tv guide
    and in the list of schedules recordings.
    """
    def __init__(self, parent, prog, context='menu'):
        Item.__init__(self, parent, skin_type='video')
        logger.log(9, '__init__(parent=%r, prog=%r, context=%r)', parent, prog,
                   context)
        # prog is a TvProgram object as we get it from the recordserver
        self.prog = prog
        self.context = context

        if hasattr(prog, 'name'): self.name = self.title = prog.name
        if hasattr(prog, 'title'): self.title = self.name = Unicode(prog.title)
        if hasattr(prog, 'sub_title'): self.sub_title = prog.sub_title
        if hasattr(prog, 'desc'): self.description = prog.desc
        if hasattr(prog, 'categories'): self.categories = prog.categories
        if hasattr(prog, 'ratings'): self.ratings = prog.ratings
        if hasattr(prog, 'advisories'): self.advisories = prog.advisories

        self.channel = tv_util.get_chan_displayname(prog.channel_id)
        if hasattr(prog, 'scheduled'):
            self.scheduled = prog.scheduled
        else:
            self.scheduled = False

        self.favorite = False
        if hasattr(prog, 'allowDuplicates'):
            self.allowDuplicates = prog.allowDuplicates
        else:
            self.allowDuplicates = 1

        if hasattr(prog, 'onlyNew'):
            self.onlyNew = prog.onlyNew
        else:
            self.onlyNew = 0

        self.overlap = prog.overlap

        self.start = time.strftime(config.TV_DATETIME_FORMAT,
                                   time.localtime(prog.start))
        self.stop = time.strftime(config.TV_DATETIME_FORMAT,
                                  time.localtime(prog.stop))
        self.recordclient = RecordClient()

    def actions(self):
        """ List of actions """
        logger.log(9, 'actions()')
        #list of entries for the menu
        items = []

        #'Play', if this programm is currently running or starts soon
        if self.context == 'guide':
            items.append((self.play, _('Play')))
            #now = time.time()
            #if self.prog.start <= now+(7*60) and self.prog.stop > now:
            #    items.append((self.play, _('Play')))

        # 'Show full description'
        items.append((self.show_description, _('Full Description')))

        if self.recordclient.pingNow():

            # 'Schedule for recording' OR 'Remove from schedule'
            (status, reason) = self.recordclient.isProgScheduledNow(self.prog)
            self.scheduled = status
            if self.scheduled:
                items.append((self.remove_program, _('Remove from schedule')))
            else:
                items.append(
                    (self.schedule_program, _('Schedule for recording')))

            # 'Add to favorites' OR 'Remove from favorites'
            (status, reason) = self.recordclient.isProgAFavoriteNow(self.prog)
            self.favorite = status
            if self.favorite:
                items.append((self.edit_favorite, _('Edit favorite')))
            else:
                items.append((self.add_favorite, _('Add to favorites')))

        plugins_list = plugin.get('tv_program')
        for p in plugins_list:
            items += p.items(self)

        return items

    ### Actions:

    def play(self, arg=None, menuw=None):
        """ Start watching TV """
        logger.log(9, 'play(arg=%r, menuw=%r)', arg, menuw)
        # watching TV should only be possible from the guide
        if not self.context == 'guide':
            rc.post_event(MENU_SELECT)
            return
        now = time.time()
        if menuw: menuw.delete_submenu()
        # Check if the selected program is >7 min in the future
        if self.prog.start > now + (7 * 60):
            if menuw: menuw.show()
            # this program is in the future
            if self.scheduled:
                msgtext = _(
                    'Do you want to remove the Program from the record schedule?'
                )
                confirmbtn = _('Remove')
            else:
                msgtext = _(
                    'This Program is in the future. Do you want to record it?')
                confirmbtn = _('Record')
            dialog.show_confirmation(msgtext,
                                     lambda: self.toggle_rec(menuw=menuw),
                                     proceed_text=confirmbtn)
            return
        else:
            # check if the device is free
            fc = FreevoChannels()
            # for that we need the name of the lock file
            suffix = fc.getVideoGroup(self.prog.channel_id, True,
                                      CHANNEL_ID).vdev
            suffix = suffix.split('/')[-1]
            tvlockfile = config.FREEVO_CACHEDIR + '/record.' + suffix
            if os.path.exists(tvlockfile):
                if menuw: menuw.show()
                # XXX: In the future add the options to watch what we are
                #      recording or cancel it and watch TV.
                msgtext = _('Sorry, you cannot watch TV while recording. ')
                msgtext += _('If this is not true then remove ')
                msgtext += tvlockfile + '.'
                dialog.show_alert(msgtext)
            else:
                # everything is ok, we can start watching!
                self.parent.hide()
                self.parent.player('tv', self.prog.channel_id)

    def show_description(self, arg=None, menuw=None):
        """ View a full scrollable description of the program.  """
        logger.log(9, 'show_description(arg=%r, menuw=%r)', arg, menuw)
        ShowProgramDetails(menuw, self)

    def toggle_rec(self, arg=None, menuw=None):
        """ Schedule or unschedule this program, depending on its current status """
        logger.log(9, 'toggle_rec(arg=%r, menuw=%r)', arg, menuw)
        if self.scheduled:
            # remove this program from schedule it it is already scheduled
            self.remove_program(menuw=menuw)
        else:
            # otherwise add it to schedule without more questions
            self.schedule_program(menuw=menuw)

    def schedule_program(self, arg=None, menuw=None):
        """ Add a program to schedule """
        logger.log(9, 'schedule_program(arg=%r, menuw=%r)', arg, menuw)
        # schedule the program
        (status, reason) = self.recordclient.scheduleRecordingNow(self.prog)
        if status == 'ok':
            self.scheduled = True
            menuw.delete_submenu(refresh=False)
            if hasattr(self.parent, 'update'):
                self.parent.update(force=True)
            else:
                menuw.refresh(reload=True)
            msgtext = _('"%s" has been scheduled for recording') % self.name
        elif status == 'conflict':
            msgtext = _('Conflict detected!')
            self.resolve_conflict(menuw, reason)
            return
        else:
            # something went wrong
            msgtext = _('Scheduling failed: ') + _(reason)

        dialog.show_message(msgtext)

    def remove_program(self, arg=None, menuw=None):
        """ Remove a program from schedule """
        logger.log(9, 'remove_program(arg=%r, menuw=%r)', arg, menuw)
        # remove the program
        (status,
         reason) = self.recordclient.removeScheduledRecordingNow(self.prog)
        if status:
            self.scheduled = False
            menuw.delete_submenu(refresh=False)
            if hasattr(self.parent, 'update'):
                self.parent.update(force=True)
            else:
                menuw.refresh(reload=True)
            msgtext = _('"%s" has been removed from schedule') % self.name
        else:
            # something went wrong
            msgtext = _('Remove failed') + (':\n%s' % reason)
        dialog.show_message(msgtext)

    def add_favorite(self, arg=None, menuw=None):
        """ Add a program to favorites """
        logger.log(9, 'add_favorite(arg=%r, menuw=%r)', arg, menuw)
        if menuw:
            menuw.delete_submenu(refresh=False)
        # create a favorite
        fav = Favorite(self.title, self.prog, True, True, True, -1, True,
                       False)
        logger.log(9, 'self.title=%r, self.prog=%r, fav.__dict__=%r)',
                   self.title, self.prog, fav.__dict__)
        # and a favorite item which represents the submen
        fav_item = FavoriteItem(self, fav, fav_action='add')
        # and open that submenu
        fav_item.display_submenu(menuw=menuw)

    def edit_favorite(self, arg=None, menuw=None):
        """
        Edit the settings of a favorite
        """
        logger.log(9, 'edit_favorite(arg=%r, menuw=%r)', arg, menuw)
        if menuw:
            menuw.delete_submenu(refresh=False)

        # get the favorite from the record client
        (got_fav, fav) = self.recordclient.getFavoriteObjectNow(self.prog)
        if got_fav:
            # create a favorite item for the submenu
            fav_item = FavoriteItem(self, fav, fav_action='edit')
            # and open the submenu
            fav_item.display_submenu(menuw=menuw)
        else:
            dialog.show_alert(_('Cannot edit favorite %s') % self.name)

    def display_submenu(self, arg=None, menuw=None):
        """
        Open the submenu for this item
        """
        logger.log(9, 'display_submenu(arg=%r, menuw=%r)', arg, menuw)
        if not menuw:
            return
        # this tries to imitated freevo's internal way of creating submenus
        menuw.make_submenu(_('Program Menu'), self.actions(), self)
        menuw.show()

    def resolve_conflict(self, menuw, conflictingProgs):
        prog_text = self.prog.getattr('time') + u' ' + self.prog.title
        other_prog_text = u''
        menu_items = []
        for progs in conflictingProgs:
            remove_text = ''
            for cprog in progs:
                if other_prog_text:
                    other_prog_text += u'\n'
                other_prog_text += cprog.getattr('time') + u' ' + cprog.title
                if not remove_text:
                    remove_text = cprog.title
                else:
                    remove_text += u', ' + cprog.title
            other_prog_text += u'\n\n'
            menu_items.append(
                menu.MenuItem(
                    _('Remove ') + remove_text, self.remove_and_schedule,
                    progs))
        self.conflict_info = _(
            'How do you want to resolve the conflict?\n%s\nconflicts with\n%s'
        ) % (prog_text, other_prog_text)
        menu_items.append(
            menu.MenuItem(
                _('Cancel scheduling ') + self.prog.title,
                menuw.back_one_menu))

        conflict_menu = menu.Menu(_('Resovle Conflict'),
                                  menu_items,
                                  item_types='tv conflict menu')
        conflict_menu.infoitem = self
        menuw.delete_submenu(refresh=False)
        menuw.pushmenu(conflict_menu)
        menuw.refresh()

    def remove_and_schedule(self, arg=None, menuw=None):
        for prog in arg:
            self.recordclient.removeScheduledRecordingNow(prog)
        menuw.back_one_menu()
        self.schedule_program(menuw=menuw)
Esempio n. 5
0
class ProgramItem(Item):
    """
    Item class for program items

    This is used in the tv guide
    and in the list of schedules recordings.
    """
    def __init__(self, parent, prog, context='menu'):
        Item.__init__(self, parent, skin_type='video')
        logger.log( 9, '__init__(parent=%r, prog=%r, context=%r)', parent, prog, context)
        # prog is a TvProgram object as we get it from the recordserver
        self.prog = prog
        self.context= context

        if hasattr(prog, 'name'): self.name = self.title = prog.name
        if hasattr(prog, 'title'): self.title = self.name = Unicode(prog.title)
        if hasattr(prog, 'sub_title'): self.sub_title = prog.sub_title
        if hasattr(prog, 'desc'): self.description = prog.desc
        if hasattr(prog, 'categories'):self.categories = prog.categories
        if hasattr(prog, 'ratings'): self.ratings = prog.ratings
        if hasattr(prog, 'advisories'): self.advisories = prog.advisories

        self.channel = tv_util.get_chan_displayname(prog.channel_id)
        if hasattr(prog, 'scheduled'):
            self.scheduled = prog.scheduled
        else:
            self.scheduled = False

        self.favorite = False
        self.allowDuplicates = prog.allowDuplicates
        self.onlyNew = prog.onlyNew
        self.overlap = prog.overlap

        self.start = time.strftime(config.TV_DATETIME_FORMAT, time.localtime(prog.start))
        self.stop = time.strftime(config.TV_DATETIME_FORMAT, time.localtime(prog.stop))
        self.recordclient = RecordClient()


    def actions(self):
        """ List of actions """
        logger.log( 9, 'actions()')
        #list of entries for the menu
        items = []

        #'Play', if this programm is currently running or starts soon
        if self.context == 'guide':
            items.append((self.play, _('Play')))
            #now = time.time()
            #if self.prog.start <= now+(7*60) and self.prog.stop > now:
            #    items.append((self.play, _('Play')))

        # 'Show full description'
        items.append((self.show_description, _('Full Description')))

        if self.recordclient.pingNow():

            # 'Schedule for recording' OR 'Remove from schedule'
            (status, reason) = self.recordclient.isProgScheduledNow(self.prog)
            self.scheduled = status
            if self.scheduled:
                items.append((self.remove_program, _('Remove from schedule')))
            else:
                items.append((self.schedule_program, _('Schedule for recording')))

            # 'Add to favorites' OR 'Remove from favorites'
            (status, reason) = self.recordclient.isProgAFavoriteNow(self.prog)
            self.favorite = status
            if self.favorite:
                items.append((self.edit_favorite, _('Edit favorite')))
            else:
                items.append((self.add_favorite, _('Add to favorites')))

        plugins_list = plugin.get('tv_program')
        for p in plugins_list:
            items += p.items(self)

        return items


    ### Actions:

    def play(self, arg=None, menuw=None):
        """ Start watching TV """
        logger.log( 9, 'play(arg=%r, menuw=%r)', arg, menuw)
        # watching TV should only be possible from the guide
        if not self.context == 'guide':
            rc.post_event(MENU_SELECT)
            return
        now = time.time()
        if menuw: menuw.delete_submenu()
        # Check if the selected program is >7 min in the future
        if self.prog.start > now + (7*60):
            if menuw: menuw.show()
            # this program is in the future
            if self.scheduled:
                msgtext= _('Do you want to remove the Program from the record schedule?')
                confirmbtn = _('Remove')
            else:
                msgtext = _('This Program is in the future. Do you want to record it?')
                confirmbtn = _('Record')
            dialog.show_confirmation(msgtext, lambda: self.toggle_rec(menuw=menuw), proceed_text=confirmbtn)
            return
        else:
            # check if the device is free
            fc = FreevoChannels()
            # for that we need the name of the lock file
            suffix = fc.getVideoGroup(self.prog.channel_id, True, CHANNEL_ID).vdev
            suffix = suffix.split('/')[-1]
            tvlockfile = config.FREEVO_CACHEDIR + '/record.'+suffix
            if os.path.exists(tvlockfile):
                if menuw: menuw.show()
                # XXX: In the future add the options to watch what we are
                #      recording or cancel it and watch TV.
                msgtext = _('Sorry, you cannot watch TV while recording. ')
                msgtext += _('If this is not true then remove ')
                msgtext += tvlockfile + '.'
                dialog.show_alert(msgtext)
            else:
                # everything is ok, we can start watching!
                self.parent.hide()
                self.parent.player('tv', self.prog.channel_id)


    def show_description(self, arg=None, menuw=None):
        """ View a full scrollable description of the program.  """
        logger.log( 9, 'show_description(arg=%r, menuw=%r)', arg, menuw)
        ShowProgramDetails(menuw, self)


    def toggle_rec(self, arg=None, menuw=None):
        """ Schedule or unschedule this program, depending on its current status """
        logger.log( 9, 'toggle_rec(arg=%r, menuw=%r)', arg, menuw)
        if self.scheduled:
            # remove this program from schedule it it is already scheduled
            self.remove_program(menuw=menuw)
        else:
            # otherwise add it to schedule without more questions
            self.schedule_program(menuw=menuw)


    def schedule_program(self, arg=None, menuw=None):
        """ Add a program to schedule """
        logger.log( 9, 'schedule_program(arg=%r, menuw=%r)', arg, menuw)
        # schedule the program
        (status, reason) = self.recordclient.scheduleRecordingNow(self.prog)
        if status == 'ok':
            self.scheduled = True
            menuw.delete_submenu(refresh=False)
            if hasattr(self.parent, 'update'):
                self.parent.update(force=True)
            else:
                menuw.refresh(reload=True)
            msgtext= _('"%s" has been scheduled for recording') % self.name
        elif status == 'conflict':
            msgtext=_('Conflict detected!')
            self.resolve_conflict(menuw, reason)
            return
        else:
            # something went wrong
            msgtext = _('Scheduling failed: ')+ _(reason)

        dialog.show_message(msgtext)


    def remove_program(self, arg=None, menuw=None):
        """ Remove a program from schedule """
        logger.log( 9, 'remove_program(arg=%r, menuw=%r)', arg, menuw)
        # remove the program
        (status, reason) = self.recordclient.removeScheduledRecordingNow(self.prog)
        if status:
            self.scheduled = False
            menuw.delete_submenu(refresh=False)
            if hasattr(self.parent, 'update'):
                self.parent.update(force=True)
            else:
                menuw.refresh(reload=True)
            msgtext = _('"%s" has been removed from schedule') % self.name
        else:
            # something went wrong
            msgtext = _('Remove failed')+(':\n%s' % reason)
        dialog.show_message(msgtext)


    def add_favorite(self, arg=None, menuw=None):
        """ Add a program to favorites """
        logger.log( 9, 'add_favorite(arg=%r, menuw=%r)', arg, menuw)
        if menuw:
            menuw.delete_submenu(refresh=False)
        # create a favorite
        fav = Favorite(self.title, self.prog, True, True, True, -1, True, False)
        logger.log( 9, 'self.title=%r, self.prog=%r, fav.__dict__=%r)', self.title, self.prog, fav.__dict__)
        # and a favorite item which represents the submen
        fav_item = FavoriteItem(self, fav, fav_action='add')
        # and open that submenu
        fav_item.display_submenu(menuw=menuw)


    def edit_favorite(self, arg=None, menuw=None):
        """
        Edit the settings of a favorite
        """
        logger.log( 9, 'edit_favorite(arg=%r, menuw=%r)', arg, menuw)
        if menuw:
            menuw.delete_submenu(refresh=False)

        # get the favorite from the record client
        (got_fav, fav) = self.recordclient.getFavoriteObjectNow(self.prog)
        if got_fav:
            # create a favorite item for the submenu
            fav_item = FavoriteItem(self, fav, fav_action='edit')
            # and open the submenu
            fav_item.display_submenu(menuw=menuw)
        else:
            dialog.show_alert(_('Cannot edit favorite %s') % self.name)


    def display_submenu(self, arg=None, menuw=None):
        """
        Open the submenu for this item
        """
        logger.log( 9, 'display_submenu(arg=%r, menuw=%r)', arg, menuw)
        if not menuw:
            return
        # this tries to imitated freevo's internal way of creating submenus
        menuw.make_submenu(_('Program Menu'), self.actions(), self)
        menuw.show()

    def resolve_conflict(self, menuw, conflictingProgs):
        prog_text = self.prog.getattr('time') + u' ' + self.prog.title
        other_prog_text = u''
        menu_items = []
        for progs in conflictingProgs:
            remove_text = ''
            for cprog in progs:
                if other_prog_text:
                    other_prog_text += u'\n'
                other_prog_text += cprog.getattr('time') + u' ' + cprog.title
                if not remove_text:
                    remove_text = cprog.title
                else:
                    remove_text += u', ' + cprog.title
            other_prog_text += u'\n\n'
            menu_items.append(menu.MenuItem(_('Remove ') + remove_text, self.remove_and_schedule, progs))
        self.conflict_info = _('How do you want to resolve the conflict?\n%s\nconflicts with\n%s') % (prog_text, other_prog_text)
        menu_items.append(menu.MenuItem(_('Cancel scheduling ') + self.prog.title, menuw.back_one_menu))

        conflict_menu = menu.Menu(_('Resovle Conflict'), menu_items, item_types='tv conflict menu')
        conflict_menu.infoitem = self
        menuw.delete_submenu(refresh = False)
        menuw.pushmenu(conflict_menu)
        menuw.refresh()


    def remove_and_schedule(self, arg=None, menuw=None):
        for prog in arg:
            self.recordclient.removeScheduledRecordingNow(prog)
        menuw.back_one_menu()
        self.schedule_program(menuw=menuw)
Esempio n. 6
0
class ScheduledRecordingsItem(Item):
    def __init__(self, parent):
        Item.__init__(self, parent, skin_type='tv')
        self.name = _('Scheduled Recordings')
        self.menuw = None
        self.recordclient = RecordClient()


    def actions(self):
        return [ ( self.display_schedule , _('Display Scheduled Recordings') ) ]


    def display_schedule(self, arg=None, menuw=None):
        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return

        items = self.get_items()
        if not len(items):
            AlertBox(_('Nothing scheduled.')).show()
            return

        schedule_menu = menu.Menu(_('Scheduled Recordings'), items,
            reload_func=self.reload, item_types='tv program menu')
        self.menuw = menuw
        rc.app(None)
        menuw.pushmenu(schedule_menu)
        menuw.refresh()


    def reload(self):
        menuw = self.menuw

        menu = menuw.menustack[-1]

        new_choices = self.get_items()
        if not menu.selected in new_choices and len(new_choices):
            sel = menu.choices.index(menu.selected)
            if len(new_choices) <= sel:
                menu.selected = new_choices[-1]
            else:
                menu.selected = new_choices[sel]

        menu.choices = new_choices

        return menu


    def get_items(self):
        items = []

        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return []

        (status, schedule) = self.recordclient.getScheduledRecordingsNow()
        if status:
            progs = schedule.getProgramList()

            f = lambda a, b: cmp(a.start, b.start)
            progs = progs.values()
            progs.sort(f)
            for prog in progs:
                items.append(ProgramItem(self, prog, context='schedule'))
        else:
            AlertBox(_('Get scheduled recordings failed')+(':\n%s' % schedule)).show()
            return []

        return items
Esempio n. 7
0
class ViewFavoritesItem(Item):
    def __init__(self, parent):
        logger.log( 9, 'ViewFavoritesItem.__init__(parent=%r)', parent)
        Item.__init__(self, parent, skin_type='tv')
        self.name = _('View Favorites')
        self.menuw = None
        self.recordclient = RecordClient()


    def actions(self):
        logger.log( 9, 'actions()')
        return [ ( self.view_favorites , _('View Favorites') ),
                 ( self.reschedule_favorites, _('Reschedule Favorites'))]


    def view_favorites(self, arg=None, menuw=None):
        logger.log( 9, 'view_favorites(arg=%r, menuw=%r)', arg, menuw)
        if not self.recordclient.pingNow():
            dialog.show_alert(self.recordclient.recordserverdown)
            return

        items = self.get_items()
        if not len(items):
            dialog.show_alert(_('No favorites.'))
            return

        favorite_menu = menu.Menu(_( 'View Favorites'), items, reload_func=self.reload, item_types='tv favorite menu')
        self.menuw = menuw
        menuw.pushmenu(favorite_menu)
        menuw.refresh()


    def reschedule_favorites(self, arg=None, menuw=None):
        """
        Force rescheduling of favorites
        """
        logger.log( 9, 'resched_favs(arg=%r, menuw=%r)', arg, menuw)
        dialog.show_message(_('Rescheduling Favorites...'))
        self.recordclient.updateFavoritesScheduleCo().connect(self.reschedule_favorites_complete)
        if menuw:
            menuw.delete_submenu()

    def reschedule_favorites_complete(self, result):
        if result:
            dialog.show_message(_('Favorites rescheduled'))
        else:
            dialog.show_alert(_('Reschedule failed'))


    def reload(self):
        logger.log( 9, 'reload()')
        menuw = self.menuw

        menu = menuw.menustack[-1]

        new_choices = self.get_items()
        if not menu.selected in new_choices and len(new_choices):
            sel = menu.choices.index(menu.selected)
            if len(new_choices) <= sel:
                menu.selected = new_choices[-1]
            else:
                menu.selected = new_choices[sel]

        menu.choices = new_choices

        return menu


    def get_items(self):
        logger.log( 9, 'get_items()')
        items = []

        (status, favorites) = self.recordclient.getFavoritesNow()
        if status:
            f = lambda a, b: cmp(a.priority, b.priority)
            favs = favorites.values()
            favs.sort(f)
            for fav in favs:
                items.append(FavoriteItem(self, fav))

        return items
Esempio n. 8
0
class ViewFavoritesItem(Item):
    def __init__(self, parent):
        logger.log(9, 'ViewFavoritesItem.__init__(parent=%r)', parent)
        Item.__init__(self, parent, skin_type='tv')
        self.name = _('View Favorites')
        self.menuw = None
        self.recordclient = RecordClient()

    def actions(self):
        logger.log(9, 'actions()')
        return [(self.view_favorites, _('View Favorites')),
                (self.reschedule_favorites, _('Reschedule Favorites'))]

    def view_favorites(self, arg=None, menuw=None):
        logger.log(9, 'view_favorites(arg=%r, menuw=%r)', arg, menuw)
        if not self.recordclient.pingNow():
            dialog.show_alert(self.recordclient.recordserverdown)
            return

        items = self.get_items()
        if not len(items):
            dialog.show_alert(_('No favorites.'))
            return

        favorite_menu = menu.Menu(_('View Favorites'),
                                  items,
                                  reload_func=self.reload,
                                  item_types='tv favorite menu')
        self.menuw = menuw
        menuw.pushmenu(favorite_menu)
        menuw.refresh()

    def reschedule_favorites(self, arg=None, menuw=None):
        """
        Force rescheduling of favorites
        """
        logger.log(9, 'resched_favs(arg=%r, menuw=%r)', arg, menuw)
        dialog.show_message(_('Rescheduling Favorites...'))
        self.recordclient.updateFavoritesScheduleCo().connect(
            self.reschedule_favorites_complete)
        if menuw:
            menuw.delete_submenu()

    def reschedule_favorites_complete(self, result):
        if result:
            dialog.show_message(_('Favorites rescheduled'))
        else:
            dialog.show_alert(_('Reschedule failed'))

    def reload(self):
        logger.log(9, 'reload()')
        menuw = self.menuw

        menu = menuw.menustack[-1]

        new_choices = self.get_items()
        if not menu.selected in new_choices and len(new_choices):
            sel = menu.choices.index(menu.selected)
            if len(new_choices) <= sel:
                menu.selected = new_choices[-1]
            else:
                menu.selected = new_choices[sel]

        menu.choices = new_choices

        return menu

    def get_items(self):
        logger.log(9, 'get_items()')
        items = []

        (status, favorites) = self.recordclient.getFavoritesNow()
        if status:
            f = lambda a, b: cmp(a.priority, b.priority)
            favs = favorites.values()
            favs.sort(f)
            for fav in favs:
                items.append(FavoriteItem(self, fav))

        return items
Esempio n. 9
0
class ManualRecordItem(Item):
    def __init__(self, parent):
        _debug_('manual_record.ManualRecordItem.__init__(parent)', 2)
        Item.__init__(self, parent, skin_type='video')

        self.name = _("Manual Record")

        self.recordclient = RecordClient()

        # maxinum number of days we can record
        self.MAXDAYS = 7

        # minimum amount of time it would take record_server.py
        # to pick us up in seconds by default it is one minute plus
        # a few seconds just in case
        self.MINPICKUP = 70

        self.months = [
            _('Jan'),
            _('Feb'),
            _('Mar'),
            _('Apr'),
            _('May'),
            _('Jun'),
            _('Jul'),
            _('Aug'),
            _('Sep'),
            _('Oct'),
            _('Nov'),
            _('Dec')
        ]

        now = time.time()
        now += 300
        self.startnow = now
        self.starttime = time.localtime(now)
        now += 1900
        self.stopnow = now
        self.stoptime = time.localtime(now)

    def make_newprog(self):
        _debug_('make_newprog(self)', 2)
        self.prog = TvProgram()

        self.disp_title = self.prog.title = self.name

        self.description = ''
        self.prog.desc = ''

        self.prog.channel_id = config.TV_CHANNELS[0][0]
        self.disp_channel = config.TV_CHANNELS[0][1]

        #self.start_year = self.starttime[0]
        self.start_month = self.starttime[1]
        self.disp_start_month = self.months[self.start_month - 1]
        self.start_day = self.starttime[2]
        self.start_time = time.strftime(config.TV_TIME_FORMAT, self.starttime)
        self.prog.start = self.startnow
        self.disp_starttime = '%s %s %s' % (self.disp_start_month,
                                            self.start_day, self.start_time)

        #self.stop_year = self.stoptime[0]
        self.stop_month = self.stoptime[1]
        self.disp_stop_month = self.months[self.stop_month - 1]
        self.stop_day = self.stoptime[2]
        self.stop_time = time.strftime(config.TV_TIME_FORMAT, self.stoptime)
        self.prog.stop = self.stopnow
        self.disp_stoptime = '%s %s %s' % (self.disp_stop_month, self.stop_day,
                                           self.stop_time)

    def actions(self):
        _debug_('actions(self)', 2)
        return [(self.display_recitem, _('Display record item'))]

    def display_recitem(self, arg=None, menuw=None):
        _debug_('display_recitem(self, arg=None, menuw=None)', 2)
        if not self.recordclient.pingNow():
            AlertBox(self.recordclient.recordserverdown).show()
            return

        self.make_newprog()

        items = []

        items.append(menu.MenuItem(_('Modify name'), action=self.mod_name))
        items.append(
            menu.MenuItem(_('Modify channel'), action=self.mod_channel))
        items.append(
            menu.MenuItem(_('Modify start month'),
                          action=self.mod_start_month))
        items.append(
            menu.MenuItem(_('Modify start day'), action=self.mod_start_day))
        items.append(
            menu.MenuItem(_('Modify start time'), action=self.mod_start_time))
        items.append(
            menu.MenuItem(_('Modify stop month'), action=self.mod_stop_month))
        items.append(
            menu.MenuItem(_('Modify stop day'), action=self.mod_stop_day))
        items.append(
            menu.MenuItem(_('Modify stop time'), action=self.mod_stop_time))
        items.append(menu.MenuItem(_('Save'), action=self.save_changes))

        manualrecord_menu = menu.Menu(_('Record Item Menu'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_name(self, arg=None, menuw=None):
        _debug_('mod_name(self, arg=None, menuw=None)', 2)
        self.menuw = menuw
        InputBox(text=_('Alter Name'), handler=self.alter_name).show()

    def mod_channel(self, arg=None, menuw=None):
        _debug_('mod_channel(self, arg=None, menuw=None)', 2)
        items = []

        for chanline in config.TV_CHANNELS:
            items.append(
                menu.MenuItem(chanline[1],
                              action=self.alter_prop,
                              arg=('channel', (chanline[1], chanline[0]))))

        manualrecord_menu = menu.Menu(_('Modify Channel'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_start_month(self, arg=None, menuw=None):
        _debug_('mod_start_month(self, arg=None, menuw=None)', 2)
        items = []

        iter = 0
        while iter < 12:
            month_name = self.months[(iter + self.starttime[1] - 1) % 12]
            month_num = self.months.index(month_name) + 1
            items.append(
                menu.MenuItem(month_name,
                              action=self.alter_prop,
                              arg=('startmonth', (month_name, month_num))))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_start_day(self, arg=None, menuw=None):
        _debug_('mod_start_day(self, arg=None, menuw=None)', 2)
        items = []

        numdays = calendar.monthrange(self.starttime[0], self.start_month)[1]
        daylimit = numdays + 1
        iter = 1
        while iter < daylimit:
            newday = (iter + self.starttime[2] - 1)
            currday = newday % daylimit
            if newday >= daylimit:
                currday += 1
            items.append(
                menu.MenuItem(str(currday),
                              action=self.alter_prop,
                              arg=('startday', currday)))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_start_time(self, arg=None, menuw=None):
        _debug_('mod_start_time(self, arg=None, menuw=None)', 2)
        items = []

        currminutes = self.starttime[3] * 60 + self.starttime[4]
        minpadding = 5 - (currminutes % 5)
        if minpadding == 5:
            minpadding = 0
        for i in range(288):
            mod = (i * 5 + currminutes + minpadding) % 1440
            showtime = strftime(config.TV_TIME_FORMAT, gmtime(float(mod * 60)))
            items.append(
                menu.MenuItem(showtime,
                              action=self.alter_prop,
                              arg=('starttime', showtime)))

        manualrecord_menu = menu.Menu(_('Modify Time'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_stop_month(self, arg=None, menuw=None):
        _debug_('mod_stop_month(self, arg=None, menuw=None)', 2)
        items = []

        iter = 0
        while iter < 12:
            month_name = self.months[(iter + self.stoptime[1] - 1) % 12]
            month_num = self.months.index(month_name) + 1
            items.append(
                menu.MenuItem(month_name,
                              action=self.alter_prop,
                              arg=('stopmonth', (month_name, month_num))))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_stop_day(self, arg=None, menuw=None):
        _debug_('mod_stop_day(self, arg=None, menuw=None)', 2)
        items = []

        numdays = calendar.monthrange(self.stoptime[0], self.stop_month)[1]
        daylimit = numdays + 1
        iter = 1
        while iter < daylimit:
            newday = (iter + self.starttime[2] - 1)
            currday = newday % daylimit
            if newday >= daylimit:
                currday += 1
            items.append(
                menu.MenuItem(str(currday),
                              action=self.alter_prop,
                              arg=('stopday', currday)))
            iter = iter + 1

        manualrecord_menu = menu.Menu(_('Modify Day'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def mod_stop_time(self, arg=None, menuw=None):
        _debug_('mod_stop_time(self, arg=None, menuw=None)', 2)
        items = []

        currminutes = self.starttime[3] * 60 + self.starttime[4]
        minpadding = 5 - (currminutes % 5)
        if minpadding == 5:
            minpadding = 0
        for i in range(288):
            mod = (i * 5 + currminutes + minpadding) % 1440
            showtime = strftime(config.TV_TIME_FORMAT, gmtime(float(mod * 60)))
            items.append(
                menu.MenuItem(showtime,
                              action=self.alter_prop,
                              arg=('stoptime', showtime)))

        manualrecord_menu = menu.Menu(_('Modify Time'),
                                      items,
                                      item_types='tv manual record menu')
        manualrecord_menu.infoitem = self
        menuw.pushmenu(manualrecord_menu)
        menuw.refresh()

    def alter_name(self, name):
        _debug_('alter_name(self, name)', 2)
        if name:
            self.disp_title = self.prog.title = name

        self.menuw.refresh()

    def alter_prop(self, arg=(None, None), menuw=None):
        _debug_('alter_prop(self, arg=(None,None), menuw=None)', 2)
        (prop, val) = arg

        if prop == 'channel':
            self.prog.channel_id = val[1]
            self.disp_channel = val[0]

        if prop == 'startday':
            self.start_day = val
            self.disp_starttime = '%s %s %s' % (
                self.disp_start_month, self.start_day, self.start_time)

        if prop == 'startmonth':
            self.start_month = val[1]
            self.disp_start_month = val[0]
            self.disp_starttime = '%s %s %s' % (
                self.disp_start_month, self.start_day, self.start_time)

        if prop == 'starttime':
            self.start_time = val
            self.disp_starttime = '%s %s %s' % (
                self.disp_start_month, self.start_day, self.start_time)

        if prop == 'stopday':
            self.stop_day = val
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month,
                                               self.stop_day, self.stop_time)

        if prop == 'stopmonth':
            self.stop_month = val[1]
            self.disp_stop_month = val[0]
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month,
                                               self.stop_day, self.stop_time)

        if prop == 'stoptime':
            self.stop_time = val
            self.disp_stoptime = '%s %s %s' % (self.disp_stop_month,
                                               self.stop_day, self.stop_time)

        if menuw:
            menuw.back_one_menu(arg='reload')

    def save_changes(self, arg=None, menuw=None):
        _debug_('save_changes(self, arg=None, menuw=None)', 2)
        result = self.check_prog()
        if result:
            (result,
             reason) = self.recordclient.scheduleRecordingNow(self.prog)

            if not result:
                AlertBox(text=_('Save Failed, recording was lost') +
                         (':\n%s' % reason)).show()
            else:
                if menuw:
                    menuw.back_one_menu(arg='reload')

    def check_prog(self):
        _debug_('check_prog(self)', 2)
        isgood = True
        curtime_epoch = time.time()
        curtime = time.localtime(curtime_epoch)
        startyear = curtime[0]
        stopyear = curtime[0]
        currentmonth = curtime[1]

        # handle the year wraparound
        if int(self.stop_month) < currentmonth:
            stopyear = str(int(stopyear) + 1)
        if int(self.start_month) < currentmonth:
            startyear = str(int(startyear) + 1)
        # create utc second start time
        starttime = time.mktime(
            strptime.strptime(
                str(self.start_month) + " " + str(self.start_day) + " " +
                str(startyear) + " " + str(self.start_time) + ":00",
                '%m %d %Y ' + config.TV_TIME_FORMAT + ':%S'))
        # create utc stop time
        stoptime = time.mktime(
            strptime.strptime(
                str(self.stop_month) + " " + str(self.stop_day) + " " +
                str(stopyear) + " " + str(self.stop_time) + ":00",
                '%m %d %Y ' + config.TV_TIME_FORMAT + ':%S'))

        # so we don't record for more then maxdays (maxdays day * 24hr/day * 60 min/hr * 60 sec/min)
        if not abs(stoptime - starttime) < (self.MAXDAYS * 86400):
            if self.MAXDAYS > 1:
                isgood = False
                msg = _("Program would record for more than %d days!"
                        ) % self.MAXDAYS
                AlertBox(text=_('Save Failed, recording was lost') +
                         (':\n%s' % msg)).show()
            else:
                isgood = False
                msg = _(
                    "Program would record for more than 1 day!") % self.MAXDAYS
                AlertBox(text=_('Save Failed, recording was lost') +
                         (':\n%s' % msg)).show()

        elif not starttime < stoptime:
            isgood = False
            msg = _("start time is not before stop time.")
            AlertBox(text=_('Save Failed, recording was lost') +
                     (':\n%s' % msg)).show()
        elif stoptime < curtime_epoch + self.MINPICKUP:
            isgood = False
            msg = _(
                "Sorry, the stop time does not give enough time for scheduler to pickup the change.  Please set it to record for a few minutes longer."
            )
            AlertBox(text=_('Save Failed, recording was lost') +
                     (':\n%s' % msg)).show()
        else:
            self.prog.start = starttime
            self.prog.stop = stoptime

        return isgood