<commit_before>import traceback
import sys
import datetime

from elasticsearch_dsl import Search

from . import Reporter, runerror, get_configfile, get_template, coroutine

logfile = 'osgpersitereport.log'
default_templatefile = 'template_persite.html'
opp_vos = ['glow', 'gluex', 'hcc', 'osg', 'sbgrid']


# Helper Functions
def monthrange(date):
    """
    Takes a start date and finds out the start and end of the month that that
    input date is in

    :param list date: Pass in date list (as returned by TimeUtils.dateparse) or
    datetime.datetime object.
    :return tuple:datetime.datetime objects that span the month
    (2016-12-05 --> 2016-12-01, 2016-12-31)
    """
    # if isinstance(date, list):
    #     startdate = datetime.datetime(*date)
    if isinstance(date, datetime.datetime) or \
            isinstance(date, datetime.date):
        startdate = date
    else:
        print "monthrange will only work with a datetime.datetime object"
        sys.exit(1)
    start = startdate.replace(day=1)
    nextmonth_first = (startdate.replace(day=28) +
                       datetime.timedelta(days=4)).replace(day=1)
    end = nextmonth_first - datetime.timedelta(days=1)
    return start, end


def prev_month_shift(date):
    """
    Take the date passed in, go back a month, and return the range of that
    previous month
    (2016-12-05 --> 2016-11-01, 2016-11-30)

    :param datetime.datetime date: datetime.datetime object
    :return tuple: Consists of two datetime.datetime
    objects that span the range of the _previous_ month
    """
    sd = date.replace(day=1)-datetime.timedelta(days=1)
    return monthrange(sd)


def perc(num, den):
    """
    Converts fraction to percent

    :param float num: Numerator of fraction
    :param float den: Denominator of fraction
    :return float: Returns fraction converted to percentage
    """
    try:
        return float(num/den) * 100.
    except ZeroDivisionError:
        if num == 0:
            return 0.
        else:
            raise("Error: Tried to do division of {0}/{1}".format(num, den))


def perc_change(old, new):
    """Calculates the percentage change between two numbers

    :param float old: Baseline number
    :param float new: Changed number
    :return float: Percentage change from old to new
    """
    try:
        return perc(new - old, old)
    except:
        if new != 0:
            return 100.     # If we have something like (10-0) / 0, return 100%


@Reporter.init_reporter_parser
def parse_opts(parser):
    """
    Don't need to add any options to Reporter.parse_opts
    """
    pass


class VO(object):
    """
    Class to hold VO information

    :param str voname: Name of VO
    """
    def __init__(self, voname):
        self.name = voname
        self.sites = {}
        self.current = True
        self.pos = 0
        self.total = [0,0]  # Position 0 = Current, Position 1 = Past
        self.totalcalc = self.running_totalhours()

    def add_site(self, sitename, corehours):
        """Add a new site data to the VO.  Also updates the core hours of
         sitename and the total for the VO

         :param str sitename: Name of site a VO's job set ran on
         :param float corehours: Core hours in the summary record
         """
        if not self.current: self.pos = 1

        if sitename in self.sites:
            self.sites[sitename][self.pos] += corehours
        else:   # Initialize the site
            self.sites[sitename] = [0, 0]
            self.sites[sitename][self.pos] = corehours

        self.totalcalc.send(corehours)
        return

    def get_cur_sitehours(self, sitename):
        """Get the current value of core hours for a particular sitename for
        the VO"""
        return self.sites[sitename][0]

    def get_cur_totalhours(self):
        """Get the current value of total core hours for the VO"""
        return self.total[0]

    def get_old_sitehours(self, sitename):
        """Get the previous month's value of core hours for a particular
        sitename for the VO"""
        if sitename in self.sites:
            return self.sites[sitename][1]
        else:
            return 0

    def get_old_totalhours(self):
        """Get the previous month's value of total core hours for the VO"""
        return self.total[1]

    @coroutine
    def running_totalhours(self):
        """Keeps running total of core hours for the VO"""
        while True:
            newhrs = yield
            self.total[self.pos] += newhrs


class OSGPerSiteReporter(Reporter):
    """Class to store information and perform actions for the OSG Per Site
    Report

    :param str config: Report Configuration file
    :param str start: Start time of report range
    :param str end: End time of report range
    :param str template: Filename of HTML template to generate report
    :param bool verbose: Verbose flag
    :param bool is_test: Whether or not this is a test run.
    :param bool no_email: If true, don't actually send the email
    """
    def __init__(self, config, start, end, template=False, verbose=False,
                 is_test=False, no_email=False, ov_logfile=None):
        report = 'siteusage'

        if ov_logfile:
            rlogfile = ov_logfile
            logfile_override = True
        else:
            rlogfile = logfile
            logfile_override = False

        Reporter.__init__(self, report, config, start, end=end,
                          verbose=verbose, is_test=is_test, no_email=no_email,
                          template=template, logfile=rlogfile,
                          logfile_override=logfile_override)
        self.header = ["Site", "Total", "Opportunistic Total",
                       "Percent Opportunistic", "Prev. Month Opp. Total",
                       "Percentage Change Month-Month"]
        self.start_time, self.end_time = \
            monthrange(self.start_time)
        fmt = "%Y-%m-%d %H:%M"
        self.title = 'VOs Usage of OSG Sites: {0} - {1}'.format(
            self.start_time.strftime(fmt), self.end_time.strftime(fmt))
        self.current = True
        self.vodict = {}
        self.sitelist = []

    def run_report(self):
        """Method to run the OSG per site report"""
        self.generate()<commit_msg>Condensed code by replacing some if/else with ternary operator statements<commit_after>import traceback
import sys
import datetime

from elasticsearch_dsl import Search

from . import Reporter, runerror, get_configfile, get_template, coroutine

logfile = 'osgpersitereport.log'
default_templatefile = 'template_persite.html'
opp_vos = ['glow', 'gluex', 'hcc', 'osg', 'sbgrid']


# Helper Functions
def monthrange(date):
    """
    Takes a start date and finds out the start and end of the month that that
    input date is in

    :param list date: Pass in date list (as returned by TimeUtils.dateparse) or
    datetime.datetime object.
    :return tuple:datetime.datetime objects that span the month
    (2016-12-05 --> 2016-12-01, 2016-12-31)
    """
    # if isinstance(date, list):
    #     startdate = datetime.datetime(*date)
    if isinstance(date, datetime.datetime) or \
            isinstance(date, datetime.date):
        startdate = date
    else:
        print "monthrange will only work with a datetime.datetime object"
        sys.exit(1)
    start = startdate.replace(day=1)
    nextmonth_first = (startdate.replace(day=28) +
                       datetime.timedelta(days=4)).replace(day=1)
    end = nextmonth_first - datetime.timedelta(days=1)
    return start, end


def prev_month_shift(date):
    """
    Take the date passed in, go back a month, and return the range of that
    previous month
    (2016-12-05 --> 2016-11-01, 2016-11-30)

    :param datetime.datetime date: datetime.datetime object
    :return tuple: Consists of two datetime.datetime
    objects that span the range of the _previous_ month
    """
    sd = date.replace(day=1)-datetime.timedelta(days=1)
    return monthrange(sd)


def perc(num, den):
    """
    Converts fraction to percent

    :param float num: Numerator of fraction
    :param float den: Denominator of fraction
    :return float: Returns fraction converted to percentage
    """
    try:
        return float(num/den) * 100.
    except ZeroDivisionError:
        if num == 0:
            return 0.
        else:
            raise("Error: Tried to do division of {0}/{1}".format(num, den))


def perc_change(old, new):
    """Calculates the percentage change between two numbers

    :param float old: Baseline number
    :param float new: Changed number
    :return float: Percentage change from old to new
    """
    try:
        return perc(new - old, old)
    except:
        if new != 0:
            return 100.     # If we have something like (10-0) / 0, return 100%


@Reporter.init_reporter_parser
def parse_opts(parser):
    """
    Don't need to add any options to Reporter.parse_opts
    """
    pass


class VO(object):
    """
    Class to hold VO information

    :param str voname: Name of VO
    """
    def __init__(self, voname):
        self.name = voname
        self.sites = {}
        self.current = True
        self.pos = 0
        self.total = [0,0]  # Position 0 = Current, Position 1 = Past
        self.totalcalc = self.running_totalhours()

    def add_site(self, sitename, corehours):
        """Add a new site data to the VO.  Also updates the core hours of
         sitename and the total for the VO

         :param str sitename: Name of site a VO's job set ran on
         :param float corehours: Core hours in the summary record
         """
        if not self.current: self.pos = 1

        if sitename in self.sites:
            self.sites[sitename][self.pos] += corehours
        else:   # Initialize the site
            self.sites[sitename] = [0, 0]
            self.sites[sitename][self.pos] = corehours

        self.totalcalc.send(corehours)
        return

    def get_cur_sitehours(self, sitename):
        """Get the current value of core hours for a particular sitename for
        the VO"""
        return self.sites[sitename][0]

    def get_cur_totalhours(self):
        """Get the current value of total core hours for the VO"""
        return self.total[0]

    def get_old_sitehours(self, sitename):
        """Get the previous month's value of core hours for a particular
        sitename for the VO"""
        return self.sites[sitename][1] if sitename in self.sites else 0

    def get_old_totalhours(self):
        """Get the previous month's value of total core hours for the VO"""
        return self.total[1]

    @coroutine
    def running_totalhours(self):
        """Keeps running total of core hours for the VO"""
        while True:
            newhrs = yield
            self.total[self.pos] += newhrs


class OSGPerSiteReporter(Reporter):
    """Class to store information and perform actions for the OSG Per Site
    Report

    :param str config: Report Configuration file
    :param str start: Start time of report range
    :param str end: End time of report range
    :param str template: Filename of HTML template to generate report
    :param bool verbose: Verbose flag
    :param bool is_test: Whether or not this is a test run.
    :param bool no_email: If true, don't actually send the email
    """
    def __init__(self, config, start, end, template=False, verbose=False,
                 is_test=False, no_email=False, ov_logfile=None):
        report = 'siteusage'

        logfile_fname = ov_logfile if ov_logfile is not None else logfile
        logfile_override = True if ov_logfile is not None else Falsecat

        Reporter.__init__(self, report, config, start, end=end,
                          verbose=verbose, is_test=is_test, no_email=no_email,
                          template=template, logfile=logfile_fname,
                          logfile_override=logfile_override)
        self.header = ["Site", "Total", "Opportunistic Total",
                       "Percent Opportunistic", "Prev. Month Opp. Total",
                       "Percentage Change Month-Month"]
        self.start_time, self.end_time = \
            monthrange(self.start_time)
        fmt = "%Y-%m-%d %H:%M"
        self.title = 'VOs Usage of OSG Sites: {0} - {1}'.format(
            self.start_time.strftime(fmt), self.end_time.strftime(fmt))
        self.current = True
        self.vodict = {}
        self.sitelist = []

    def run_report(self):
        """Method to run the OSG per site report"""
        self.generate()
{'fraction_non_alphanumeric': 0.09175117783278768, 'fraction_numerical': 0.014373552663099896, 'mean_word_length': 2.400488732011947, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3101875', 'n_tokens_mistral': 3834, 'n_tokens_neox': 3557, 'n_words': 1234}