Beispiel #1
0
def normalizePeriodStartStop(period, dt):
    """
    Returns the start/stop time for a period ensuring it stays within the 
    given month.
    """
    start = TimeAgent.utc2est(period.start)
    if start.month != dt.month:
        start = datetime(dt.year, dt.month, 1, 0, 0, 0)

    stop = TimeAgent.utc2est(period.end())
    if stop.month != dt.month:
        _, day = calendar.monthrange(dt.year, dt.month)
        stop = datetime(dt.year, dt.month, day, 23, 59, 59)

    return start, stop
Beispiel #2
0
    def test_summary(self):
        # setup a period for a month before
        lastMonth = self.start - timedelta(days = 31)
        lastMonthEst = TimeAgent.utc2est(lastMonth)
        pa = Period_Accounting(scheduled = self.dur)
        pa.save()
        p = Period( session = self.s
                  , start = lastMonth 
                  , duration = self.dur
                  , state = Period_State.get_state("S")
                  , accounting = pa
                  )
        p.save()          
        
        # get - sets up the form
        response = self.get('/schedule/summary')
        self.failUnlessEqual(response.status_code, 200)
        startStr = datetime.strftime(lastMonthEst, "%H:%M")
        self.assertTrue(startStr in response.content)
        self.assertTrue("mikes awesome project" in response.content)

        # post - they've requested something
        # first, the schedule summary report
        # default to last month
        response = self.post('/schedule/summary', {'summary' : 'schedule'})
        self.failUnlessEqual(response.status_code, 200)        
        self.assertTrue(startStr in response.content)
        self.assertTrue("mikes awesome project" in response.content)

        # now do an earlier month, and our period should not show up
        response = self.post('/schedule/summary'
                          , {'summary' : 'schedule'
                           , 'month'   : 'December'
                           , 'year'    : '2000'}
                            )
        self.failUnlessEqual(response.status_code, 200)        
        self.assertTrue(startStr not in response.content)
        self.assertTrue("mikes awesome project" not in response.content)

        # okay, now test the project summary report
        pcode = self.s.project.pcode
        response = self.post('/schedule/summary'
                          , {'summary' : 'project'
                           , 'project' : pcode}
                            )
        self.failUnlessEqual(response.status_code, 200)        
        self.assertTrue("GBT Project Summary for" in response.content)
        self.assertTrue(pcode in response.content)
        self.assertTrue(str(self.dur) in response.content)

        # make sure we can handle all projects 
        response = self.post('/schedule/summary'
                          , {'summary' : 'project'
                           , 'project' : None}
                            )
        self.failUnlessEqual(response.status_code, 200)        
        self.assertTrue("GBT Project Summary for" in response.content)
        self.assertTrue(pcode in response.content)
        self.assertTrue(str(self.dur) in response.content)
Beispiel #3
0
    def getSessionTable(self, periods):
        table  = "Start (ET)   |      UT      |  LST  |  (hr) | T | S |    PI     | Rx        | Session\n"
        table += "--------------------------------------------------------------------------------------\n"
        for p in periods:
            if p.session.project.pcode == "Maintenance":
                pi = ""
            else:
                pi = p.session.project.principal_investigator().last_name[:9] if p.session.project.principal_investigator() else "Unknown"

            table += "%s | %s | %s | %5s | %s | %s | %-9s | %-9s | %s\n" % (
                TimeAgent.utc2est(p.start).strftime('%b %d %H:%M') # start (ET)
              , p.start.strftime('%b %d %H:%M') # start (UT)
              , TimeAgent.dt2tlst(p.start).strftime('%H:%M') # LST
              , "%2.2f" % p.duration # dur (Hrs)
              , p.session.session_type.type[0].upper() # sess type
              , p.state.abbreviation # state
              , pi
              , p.session.receiver_list_simple()[:9]
              , p.session.name
            )
        return table
Beispiel #4
0
def summary(request, *args, **kws):
    """
    Serves up a page that allows Operations to run reconcilation reports. There
    are two basic reports - schedule and project. Even though it is specifically
    for Operations, any logged in user may view it.
    """
    now        = datetime.now()
    psummary = []

    if request.method == 'POST':
        summary = request.POST.get('summary', 'schedule')

        project = project_search(request.POST.get('project', ''))
        if isinstance(project, list) and len(project) == 1:
            project = project[0].pcode
        else:
            project = ''

        month = request.POST.get('month', None)
        year  = request.POST.get('year', None)
        year  = int(year) if year else None
        if month and year:
            start = datetime(int(year)
                           , [m for m in calendar.month_name].index(month)
                           , 1)
        else: # Default to this month
            start = datetime(now.year, now.month, 1)
            month = calendar.month_name[start.month]
            year  = start.year
    else: # Default to this month
        summary    = 'schedule'
        project    = ''
        start      = datetime(now.year, now.month, 1)
        month      = calendar.month_name[start.month]
        year       = start.year

    end = datetime(start.year
                 , start.month
                 , calendar.monthrange(start.year, start.month)[1]) + \
          timedelta(days = 1)

    # View is in ET, database is in UTC. Only use scheduled periods.
    periods = Period.in_time_range(TimeAgent.est2utc(start)
                                 , TimeAgent.est2utc(end))
    if project:
        periods = [p for p in periods if p.isScheduled() and p.session.project.pcode == project]

    # Handle either schedule or project summaries.
    if summary == "schedule":
        schedule = get_gbt_schedule_events(start, end, "ET", True)
        url      = 'users/schedule_summary.html'
        projects = []
        receivers = {}
        days     = {}
        hours    = {}
        summary  = {}
    else:
        url      = 'users/project_summary.html'
        projects = list(set([p.session.project for p in periods]))
        projects.sort(lambda x, y: cmp(x.pcode, y.pcode))

        receivers = {}
        for p in periods:
            rxs = receivers.get(p.session.project.pcode, [])
            rxs.extend([r.abbreviation for r in p.receivers.all()])
            receivers[p.session.project.pcode] = rxs

        schedule = {}
        days     = dict([(p.pcode, []) for p in projects])
        hours    = dict([(p.pcode, 0) for p in projects])
        summary  = dict([(c, 0) for c in Sesshun.getCategories()])
        for p in periods:
            pstart = TimeAgent.utc2est(p.start)
            pend   = TimeAgent.utc2est(p.end())

            # Find the days this period ran within the month.
            day = pstart.day if pstart >= start else pend.day
            days[p.session.project.pcode].append(str(day))
            if day != pend.day: # For multi-day periods
                days[p.session.project.pcode].append(str(pend.day))

            # Find the duration of this period within the month.
            duration = min(pend, end) - max(pstart, start)
            hrs = duration.seconds / 3600. + duration.days * 24.
            hours[p.session.project.pcode] += hrs

            # Tally hours for various categories important to Operations.
            summary[p.session.getCategory()] += hrs

            # If just for one project, create a more detailed summary.
            if project:
                psummary.append((pstart, hrs, p.receiver_list))

    return render_to_response(
               url
             , {'calendar' : schedule
              , 'projects' : [(p
                             , sorted(list(set(receivers[p.pcode])))
                             , sorted(list(set(days[p.pcode]))
                                    , lambda x, y: cmp(int(x), int(y)))
                             , hours[p.pcode]) for p in projects]
              , 'start'    : start
              , 'months'   : calendar.month_name
              , 'month'    : month
              , 'years'    : [y for y in xrange(2009, now.year + 2, 1)]
              , 'year'     : year
              , 'summary'  : [(t, summary[t]) for t in sorted(summary)]
              , 'project'  : project
              , 'psummary' : psummary
              , 'is_logged_in': request.user.is_authenticated()})
Beispiel #5
0
 def utc2est(self, dt, frmt):
     return TimeAgent.utc2est(dt).strftime(frmt)
Beispiel #6
0
    def test_nsfReport(self):

        # Periods look like (UTC, EST subtract 5):
        # 1 One: 2010-01-01 00:00:00 for  2.00 Hrs
        # 3 Two: 2010-01-01 02:00:00 for  3.00 Hrs
        # 2 One: 2010-01-01 05:00:00 for  1.00 Hrs - this one start in Jan, EST
        # 4 Two: 2010-01-01 06:00:00 for  2.00 Hrs
       
        decStart = datetime(2009,12, 1, 0)
        janStart = datetime(2010, 1, 1, 0)
        ps = Period.objects.all().order_by('start')
        ps = list(ps)

       
        # what are the periods that lie in Dec (EST)?
        filterd = filterPeriodsByDate(decStart)
        self.assertEquals([1,3], [p.id for p in filterd])
        # what are the periods that lie in Jan (EST)?
        filterd = filterPeriodsByDate(janStart)
        self.assertEquals([2,4], [p.id for p in filterd])

        pids = [1,2,4]
        dts = [decStart, janStart, janStart]
        for pid, dt in zip(pids, dts):
            p = Period.objects.get(id = pid)
            start, stop = normalizePeriodStartStop(p, dt)
            self.assertEquals(start, TimeAgent.utc2est(p.start))
            self.assertEquals(stop, TimeAgent.utc2est(p.end()))
        # Period 3 is a special case
        p = Period.objects.get(id = 3)
        start, stop = normalizePeriodStartStop(p, decStart)
        self.assertEquals(start, TimeAgent.utc2est(p.start))
        self.assertEquals(stop, datetime(2009, 12, 31, 23, 59, 59))


        self.assertAlmostEquals(5.000, getTime(ps[:2], decStart), 2)    
        self.assertAlmostEquals(3.000, getTime(ps[2:], janStart), 2)    

        # tail of Q1
        dt = decStart
        fps = filterPeriodsByDate(dt)
        self.assertAlmostEquals(5.000, getScheduledTime(fps, dt), 2)    
        self.assertEquals(0.0, getDowntime(fps, dt))    
        self.assertEquals(0.0, getMaintenance(fps, dt))    
        self.assertEquals(0.0, getTesting(fps, dt))    

        # Start of Q2!
        dt = janStart
        fps = filterPeriodsByDate(dt)
        self.assertAlmostEquals(3.000, getScheduledTime(fps, dt), 2)    
        self.assertEquals(0.5, getDowntime(fps, dt))    
        self.assertEquals(0.0, getMaintenance(fps, dt))    
        self.assertEquals(0.0, getTesting(fps, dt))    

        argv = ["program", "1", "2010"]
        quarters = {
            1: [10, 11, 12]
          , 2: [1, 2, 3]
          , 3: [4, 5, 6]
          , 4: [7, 8, 9]
                   }

        quarter     = int(argv[1])
        fiscal_year = int(argv[2])
    
        months = quarters[quarter]
        year   = fiscal_year if quarter != 1 else fiscal_year - 1
   
        nsfReport('Q%dFY%d' % (quarter, fiscal_year)
                     , [datetime(year, m, 1) for m in months], year)


        # can we handle 24 hour periods?
        dur = 24.0
        scheduled = Period_State.get_state("S")
        pa = Period_Accounting(scheduled = dur)
        pa.save()
        p = Period(session = self.s1
                 , start = datetime(2010, 1, 1, 8)
                 , duration = dur
                 , state = scheduled
                 , accounting = pa
                  )
        p.save()

        L = (Receiver.get_rcvr('L'))
        pg = Period_Receiver(period = p, receiver = L)
        pg.save()

        start, stop = normalizePeriodStartStop(p, janStart)
        self.assertEquals(start, TimeAgent.utc2est(p.start))
        self.assertEquals(stop, TimeAgent.utc2est(p.end()))

        dt = janStart
        fps = filterPeriodsByDate(dt)
        self.assertAlmostEquals(27.000, getScheduledTime(fps, dt), 2)    
        self.assertEquals(0.5, getDowntime(fps, dt))    
        self.assertEquals(0.0, getMaintenance(fps, dt))    
        self.assertEquals(0.0, getTesting(fps, dt))