コード例 #1
0
ファイル: ScheduleTools.py プロジェクト: mmccarty/nell
    def shiftPeriodBoundaries(self
                            , period
                            , start_boundary
                            , time
                            , neighbor
                            , reason
                            , desc):
        """
        Shifts the boundary between a given period and it's neighbors:
           * period_id - the period obj. whose boundary we first adjust
           * start_boundary - boolean, true for start, false for end
           * time - new time for that boundary
           * neighbor - period affected (can't be None)
           * reason - other_session_weather, *_rfi, or *_other
           * desc - the description to put into time accounting
        After periods are adjusted, time accounting is adjusted appropriately
        """
       
        # if there isn't a neighbor, then this change should be done by hand
        if neighbor is None:
            return (False, "Cannot shift period boundary if there is a neighboring gap in the schedule.")

        if period.state.abbreviation != 'S' or \
           neighbor.state.abbreviation != 'S':
            return (False, "Affected Periods should be in the Scheduled State")   
        # get the time range affected
        original_time = period.start if start_boundary else period.end()
        diff_hrs = TimeAgent.dtDiffHrs(original_time, time) #self.get_time_diff_hours(original_time, time)

        # check for the no-op
        if original_time == time:
            return (False, "Time given did not change Periods duration")

        # create the tag used for all descriptions in time accounting
        nowStr = datetime.now().strftime("%Y-%m-%d %H:%M")    
        descHead = " [Shift Period Bnd. (%s) " % nowStr 
        # dictionary of who gave and who got, where:
        # descDct[gave/got] = [(desc. of original period, time, period id)]
        descDct = {}

        # figure out the stuff that depends on which boundary we're moving
        if start_boundary:
            if time >= period.end():
                return (False, "Cannot start this period after it ends.")
            period_growing = True if time < original_time else False
        else:
            if time <= period.start:
                return (False, "Cannot shrink period past its start time.")
            period_growing = True if time > original_time else False

        if period_growing:
            # what to do with the period?
            # give time!
            # take notes for later    
            descDct["got_time"] = [(period.__str__(), diff_hrs, period.id)]
            descDct["gave_time"] = []
            period.accounting.short_notice += diff_hrs
            period.accounting.scheduled += diff_hrs
            period.duration += diff_hrs
            if start_boundary:
                period.start = time
            # what to do w/ the other periods    
            # what are the other periods affected (can be many when growing) 
            # (ignore original period causing affect) 
            range_time = time if start_boundary else original_time
            affected_periods = [p for p in \
                Period.get_periods(range_time, diff_hrs * 60.0) \
                    if p.id != period.id]
            for p in affected_periods:
                if p.start >= period.start and p.end() <= period.end():
                    # remove this period; 
                    descDct["gave_time"].append((p.__str__(), p.duration, p.id))
                    value = p.accounting.get_time(reason)
                    p.accounting.set_changed_time(reason, value + p.duration)
                    p.delete() # The Deleted state!
                else:
                    # give part of this periods time to the affecting period
                    other_time_point = p.end() if start_boundary else p.start
                    other_time = TimeAgent.dtDiffHrs(other_time_point, time)
                    descDct["gave_time"].append((p.__str__(), other_time, p.id))
                    value = p.accounting.get_time(reason)
                    p.accounting.set_changed_time(reason, value + other_time)
                    p.duration -= other_time 
                    if not start_boundary:
                        p.start = time
                    self.reinitScore(p)
                p.accounting.save()
                p.save()
        else: 
            # period is shrinking
            # what to do w/ the period?
            # take time!
            # take notes for later    
            descDct["gave_time"]  = [(period.__str__(), diff_hrs, period.id)]   
            value = period.accounting.get_time(reason)
            period.accounting.set_changed_time(reason, value + diff_hrs)
            period.duration -= diff_hrs
            if start_boundary:
                period.start = time
            # what to do w/ the other affected period (just one!)?
            # give it time!
            # take notes for later
            descDct["got_time"] = [(neighbor.__str__(), diff_hrs, neighbor.id)]
            neighbor.accounting.short_notice += diff_hrs
            neighbor.accounting.scheduled += diff_hrs
            neighbor.accounting.save()
            neighbor.duration += diff_hrs
            if not start_boundary:
                neighbor.start = time
            self.reinitScore(neighbor)
            neighbor.save()    
        
        # in all cases:
        self.reinitScore(period)
        period.accounting.save()
        period.save()
        
        # in all cases, give the description of entire event:
        self.assignDescriptions(descDct, descHead, desc)

        return (True, None)