django.conf.settings.TIME_ZONE

Here are the examples of the python api django.conf.settings.TIME_ZONE taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

93 Examples 7

3 Source : check.py
with MIT License
from 510908220

    def process_at_service(self, service):
        """
        当 当前时间 > at时,看[at, at + grace]之间是否有上报的数据
        """
        latest_ping = self.get_last_ping(service)
        if not latest_ping:
            return

        at = pendulum.parse(service.value, tz=settings.TIME_ZONE).in_timezone('UTC')
        last_created = pendulum.instance(latest_ping.created)
        now = pendulum.now(tz='UTC')

        if now   <   at.add(minutes=int(service.grace)):
            return
        if last_created  <  at:
            self.notify(service, now)

    def process_every_service(self, service):

3 Source : timezone.py
with GNU General Public License v3.0
from Aghoreshwar

def get_default_timezone():
    """
    Return the default time zone as a tzinfo instance.

    This is the time zone defined by settings.TIME_ZONE.
    """
    return pytz.timezone(settings.TIME_ZONE)


# This function exists for consistency with get_current_timezone_name
def get_default_timezone_name():

3 Source : time_utils.py
with MIT License
from aileenproject

def get_timezone():
    """Get a timezone to be used"""
    return pytz.timezone(settings.TIME_ZONE)


def as_aileen_time(dt: datetime) -> datetime:

3 Source : date.py
with MIT License
from ambient-innovation

def datetime_format(target_datetime: datetime.datetime, dt_format: str) -> str:
    """
    Uses strftime, but considers timezone (only for datetime objects)
    """
    try:
        dt_format = target_datetime.astimezone(tz=pytz.timezone(settings.TIME_ZONE)).strftime(dt_format)
    except UnknownTimeZoneError:
        dt_format = target_datetime.strftime(dt_format)
    return dt_format


def get_start_and_end_date_from_calendar_week(year: int, calendar_week: int) -> (datetime.date, datetime.date):

3 Source : test_views_api.py
with MIT License
from bihealth

    def get_drf_datetime(cls, obj_dt):
        """
        Return datetime in DRF compatible format.

        :param obj_dt: Object DateTime field
        :return: String
        """
        return timezone.localtime(
            obj_dt, pytz.timezone(settings.TIME_ZONE)
        ).isoformat()

    @classmethod

3 Source : views.py
with MIT License
from cds-snc

    def post_notification(self, date_entry, severity, location_id, user):
        # Ensure that the datetime is aware (might not be if unit testing or something)
        tz = pytz.timezone(settings.TIME_ZONE or "UTC")
        start_dt = datetime.fromtimestamp(date_entry["start_ts"]).replace(tzinfo=tz)
        end_dt = datetime.fromtimestamp(date_entry["end_ts"]).replace(tzinfo=tz)

        # Create the notification
        notification = Notification(
            severity=severity,
            start_date=start_dt,
            end_date=end_dt,
            location_id=location_id,
            created_by=user,
        )
        notification.save()
        return notification

    def notify_server(self, notification):

3 Source : timezone.py
with MIT License
from chunky2808

def get_default_timezone():
    """
    Returns the default time zone as a tzinfo instance.

    This is the time zone defined by settings.TIME_ZONE.
    """
    return pytz.timezone(settings.TIME_ZONE)


# This function exists for consistency with get_current_timezone_name
def get_default_timezone_name():

3 Source : schedule_item_attendance.py
with GNU General Public License v2.0
from costasiella

    def resolve_cancellation_possible(self, info):
        local_tz = pytz.timezone(settings.TIME_ZONE)

        now = timezone.localtime(timezone.now())
        cancel_before = self.get_cancel_before()

        if now   <   cancel_before and self.booking_status == 'BOOKED':
            return True
        else:
            return False


class ScheduleItemAttendanceQuery(graphene.ObjectType):

3 Source : snippet.py
with Apache License 2.0
from dockerizeme

    def fetch(cls, sql, params_list):
        with psycopg2.connect(cls.db_dsn, cursor_factory=DictCursor) as conn:
            with conn.cursor() as c:
                c.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
            # you must have psycopg2 >= 2.6 to get proper exec handling for cursor context manager
            # see https://github.com/psycopg/psycopg2/issues/262
            with conn.cursor(cls.ss_cursor_name) as c:
                c.itersize = 100  # 100 to 1000 should be reasonable
                c.execute(sql, params_list)
                for row in c:
                    yield row

    @classproperty

3 Source : feeds.py
with GNU General Public License v3.0
from esrg-knights

    def timezone(self):
        return settings.TIME_ZONE

    #######################################################
    # Timezone information (Daylight-saving time, etc.)
    def vtimezone(self):

3 Source : feeds.py
with GNU General Public License v3.0
from esrg-knights

    def vtimezone(self):
        tz_info = util.generate_vtimezone(settings.TIME_ZONE, datetime(2020, 1, 1))
        tz_info.add('x-lic-location', settings.TIME_ZONE)
        return tz_info

    #######################################################
    # Activities

    def items(self):

3 Source : utils.py
with GNU General Public License v3.0
from ffplayout

    def settings(self):
        return {
            'timezone': settings.TIME_ZONE,
            'multi_channel': settings.MULTI_CHANNEL
        }

    def cpu(self):

3 Source : babel.py
with Apache License 2.0
from gethue

def _get_format():
    locale = get_current_locale()
    if not locale:
        locale = babel_core.Locale.parse(to_locale(get_language()))
    if timezone:
        tzinfo = timezone(settings.TIME_ZONE)
    else:
        tzinfo = None
    return babel_support.Format(locale, tzinfo)


@register.filter

3 Source : json.py
with Apache License 2.0
from gethue

    def default(self, obj):
        if isinstance(obj, Decimal):
            return str(obj)
        elif isinstance(obj, datetime.datetime):
            assert settings.TIME_ZONE == 'UTC'
            return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
        return json.JSONEncoder.default(self, obj)


def dumps(value):

3 Source : views.py
with BSD 3-Clause "New" or "Revised" License
from GhostManager

    def get(self, request, *args, **kwargs):
        context = {
            "timezone": settings.TIME_ZONE,
        }
        return render(request, "home/management.html", context=context)


class TestAWSConnection(LoginRequiredMixin, UserPassesTestMixin, View):

3 Source : mail.py
with BSD 3-Clause "New" or "Revised" License
from ietf-tools

def show_that_mail_was_sent(request,leadline,msg,bcc):
        if request and request.user:
            from ietf.ietfauth.utils import has_role
            if has_role(request.user,['Area Director','Secretariat','IANA','RFC Editor','ISE','IAD','IRTF Chair','WG Chair','RG Chair','WG Secretary','RG Secretary']):
                info =  "%s at %s %s\n" % (leadline,datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE)
                info += "Subject: %s\n" % force_text(msg.get('Subject','[no subject]'))
                info += "To: %s\n" % msg.get('To','[no to]')
                if msg.get('Cc'):
                    info += "Cc: %s\n" % msg.get('Cc')
                if bcc:
                    info += "Bcc: %s\n" % bcc
                messages.info(request,info,extra_tags='preformatted',fail_silently=True)

def save_as_message(request, msg, bcc):

3 Source : timezone.py
with BSD 3-Clause "New" or "Revised" License
from ietf-tools

def local_timezone_to_utc(d):
    """Takes a naive datetime in the local timezone and returns a
    naive datetime with the corresponding UTC time."""
    local_timezone = pytz.timezone(settings.TIME_ZONE)

    d = local_timezone.localize(d).astimezone(pytz.utc)

    return d.replace(tzinfo=None)

def utc_to_local_timezone(d):

3 Source : timezone.py
with BSD 3-Clause "New" or "Revised" License
from ietf-tools

def utc_to_local_timezone(d):
    """Takes a naive datetime UTC and returns a naive datetime in the
    local time zone."""
    local_timezone = pytz.timezone(settings.TIME_ZONE)

    d = local_timezone.normalize(d.replace(tzinfo=pytz.utc).astimezone(local_timezone))

    return d.replace(tzinfo=None)

def email_time_to_local_timezone(date_string):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_date_format_4(self):
        text = "lorem ipsum 13.02.2018 lorem ipsum"
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(
                2018, 2, 13, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

    def test_date_format_5(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_date_format_5(self):
        text = (
            "lorem ipsum 130218, 2018, 20180213 and lorem 13.02.2018 lorem "
            "ipsum"
        )
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(
                2018, 2, 13, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

    def test_date_format_6(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_date_format_7(self):
        text = (
            "lorem ipsum\n"
            "März 2019\n"
            "lorem ipsum"
        )
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(
                2019, 3, 1, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

    def test_date_format_8(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_date_format_9(self):
        text = (
            "lorem ipsum\n"
            "27. Nullmonth 2020\n"
            "März 2020\n"
            "lorem ipsum"
        )
        self.assertEqual(
            parse_date("", text),
            datetime.datetime(
                2020, 3, 1, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

    def test_crazy_date_past(self, *args):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_ignored_dates(self, *args):
        text = (
            "lorem ipsum 110319, 20200117 and lorem 13.02.2018 lorem "
            "ipsum"
        )
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(
                2018, 2, 13, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

3 Source : timezone.py
with Apache License 2.0
from lumanjiao

def get_default_timezone():
    """
    Returns the default time zone as a tzinfo instance.

    This is the time zone defined by settings.TIME_ZONE.

    See also :func:`get_current_timezone`.
    """
    global _localtime
    if _localtime is None:
        if isinstance(settings.TIME_ZONE, six.string_types) and pytz is not None:
            _localtime = pytz.timezone(settings.TIME_ZONE)
        else:
            # This relies on os.environ['TZ'] being set to settings.TIME_ZONE.
            _localtime = LocalTimezone()
    return _localtime

# This function exists for consistency with get_current_timezone_name
def get_default_timezone_name():

3 Source : json.py
with Apache License 2.0
from lumanjiao

    def default(self, obj):
        if isinstance(obj, Decimal):
            return str(obj)
        elif isinstance(obj, datetime.datetime):
            assert settings.TIME_ZONE == 'UTC'
            return obj.strftime('%Y-%m-%dT%H:%M:%SZ')
        return simplejson.JSONEncoder.default(self, obj)


def dumps(value):

3 Source : tests.py
with Apache License 2.0
from MeGustas-5427

def convert_local_timezone(time_in: datetime) -> datetime:
    """
    用来将输入的datetime格式的本地时间转化为utc时区时间
    :param time_in: datetime.datetime格式的本地时间
    :return:输出仍旧是datetime.datetime格式,但已经转换为utc时间
    """
    local = pytz.timezone(settings.TIME_ZONE)
    local_dt = local.localize(time_in, is_dst=None)
    time_utc = local_dt.astimezone(pytz.utc)
    return time_utc


def read_file(part: str) -> list:

3 Source : functions.py
with Apache License 2.0
from MeGustas-5427

def convert_timezone(time_in: datetime.datetime) -> datetime.datetime:
    """
    用来将系统自动生成的datetime格式的utc时区时间转化为本地时间
    :param time_in: datetime.datetime格式的utc时间
    :return:输出仍旧是datetime.datetime格式,但已经转换为本地时间
    """
    time_utc = time_in.replace(tzinfo=pytz.timezone("UTC"))
    time_local = time_utc.astimezone(pytz.timezone(settings.TIME_ZONE))
    return time_local


def dictfetchall(cursor):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_date_format_4(self):
        text = "lorem ipsum 13.02.2018 lorem ipsum"
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(2018, 2, 13, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

    def test_date_format_5(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_date_format_5(self):
        text = "lorem ipsum 130218, 2018, 20180213 and lorem 13.02.2018 lorem " "ipsum"
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(2018, 2, 13, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

    def test_date_format_6(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_date_format_7(self):
        text = "lorem ipsum\n" "März 2019\n" "lorem ipsum"
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(2019, 3, 1, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

    def test_date_format_8(self):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_date_format_8(self):
        text = (
            "lorem ipsum\n"
            "Wohnort\n"
            "3100\n"
            "IBAN\n"
            "AT87 4534\n"
            "1234\n"
            "1234 5678\n"
            "BIC\n"
            "lorem ipsum\n"
            "März 2020"
        )
        self.assertEqual(
            parse_date("", text),
            datetime.datetime(2020, 3, 1, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

    @override_settings(SCRATCH_DIR=SCRATCH)

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_date_format_9(self):
        text = "lorem ipsum\n" "27. Nullmonth 2020\n" "März 2020\n" "lorem ipsum"
        self.assertEqual(
            parse_date("", text),
            datetime.datetime(2020, 3, 1, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

    def test_crazy_date_past(self, *args):

3 Source : test_date_parsing.py
with GNU General Public License v3.0
from paperless-ngx

    def test_ignored_dates(self, *args):
        text = "lorem ipsum 110319, 20200117 and lorem 13.02.2018 lorem " "ipsum"
        date = parse_date("", text)
        self.assertEqual(
            date,
            datetime.datetime(2018, 2, 13, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)),
        )

3 Source : db.py
with MIT License
from pgeu

    def __init__(self, conference):
        if conference is None:
            self.tzname = settings.TIME_ZONE
        else:
            self.tzname = conference.tzname

    def __enter__(self):

3 Source : views.py
with MIT License
from transportkollektiv

def gbfsSystemInformation(request):
    if request.method == "GET":
        bsp = preferences.BikeSharePreferences
        data = {
            "system_id": bsp.gbfs_system_id,
            "license_url": "https://creativecommons.org/publicdomain/zero/1.0/",
            "language": languageCode(),
            "name": bsp.system_name,
            "short_name": bsp.system_short_name,
            "timezone": settings.TIME_ZONE,
        }
        return JsonResponse(getGbfsWithData(data), safe=False)


@permission_classes([AllowAny])

3 Source : __init__.py
with MIT License
from yuemiao-web

    def __init__(self) -> None:
        tz = timezone(settings.TIME_ZONE)
        jobstores = {
            'default': DjangoJobStore()
        }
        executors = {
            'default': ThreadPoolExecutor(20)
        }
        job_defaults = {
            'coalesce': True,
            'max_instances': 3
        }

        super().__init__(jobstores=jobstores, executors=executors,
                         job_defaults=job_defaults, timezone=tz)
        
        self._init_event()
        
    def _init_event(self):

0 Source : check.py
with MIT License
from 510908220

    def notify(self, service, now):
        msg = '{service.name}({service.value},{service.grace}) not send heartbeat at {now}'.format(
            service=service,
            now=now.in_timezone(settings.TIME_ZONE).to_datetime_string()
        )
        logger.warning(msg)

        if not service.notify_to.strip():
            logger.warning('service %s notify_to is empty', service.name)
            return

        notify_async(service.notify_to.strip().split(";"),
                     service.name,
                     service.tp,
                     service.value,
                     service.grace,
                     msg
                     )

    def get_last_ping(self, service):

0 Source : monitor_tmux.py
with MIT License
from aileenproject

def monitor_tmux_windows(tmux_session):
    """Monitor if tmux windows are doing fine. For now, only the sensor, can add others later."""
    box_id = BoxSettings.objects.last().box_id
    timezone = pytz.timezone(settings.TIME_ZONE)

    status = True  # start optimistic

    tmux_window = tmux_session.find_where({"window_name": "sensor"})
    if tmux_window is None:
        status = False
        logger.info(
            'Cannot find the "sensor" tmux window. Assuming sensor is not running...'
        )

    tmux_pane = tmux_window.list_panes()[0]
    last_message = tmux_pane.cmd("capture-pane", "-p").stdout[-1]

    if last_message == "sleeping a bit...":
        status = False
        logger.info(
            "The sensor seems to be off (process is sleeping and will try again) ..."
        )

    TmuxStatus.objects.update_or_create(
        box_id=box_id,
        sensor_status=status,
        time_stamp=timezone.localize(datetime.now()),
    )


class Command(BaseCommand):

0 Source : record_events_to_db.py
with MIT License
from aileenproject

def update_database_with_new_and_updated_observables(sensor_events_df: pd.DataFrame):
    """
    From known observables and latest sensor input, we compute what should go to the database:

    We are interested in the most recent events, which we do not yet know about.
    There is some set computing involved to single these out.

    Based on this information, we also update the observables table (this includes adding new ones seen
    for the first time). Every observable gets time_last_seen set to what the sensor reported just now.
    """
    logger.info(f"Length of sensor df: {len(sensor_events_df)}")

    # Load a df of observables, with a compatible timezone
    known_observables_df = Observables.to_df()
    if len(known_observables_df.index) > 0:
        known_observables_df.time_last_seen = known_observables_df.time_last_seen.dt.tz_convert(
            settings.TIME_ZONE
        )

    # Create a dataframe of observables which were just discovered for the first time
    new_observables_events_df = sensor_events_df[
        ~sensor_events_df.observable_id.isin(known_observables_df.index)
    ]

    # Append the new observables to the known ones, as well
    known_observables_df = known_observables_df.append(
        new_observables_events_df[["observable_id", "time_seen"]]
        .rename(columns={"time_seen": "time_last_seen"})
        .set_index("observable_id"),
        sort=False,
    )

    # Join the events which the sensor just recorded with information about known observables.
    # The joined df has both time_seen and time_last_seen.
    old_dt = datetime(1970, 1, 1, 1, 1, 1, tzinfo=pytz.timezone(settings.TIME_ZONE))
    events_plus_observable_data_df = (
        sensor_events_df.set_index("observable_id")
        .join(known_observables_df)
        .replace(np.NaN, old_dt)
    )

    # Now we can distill which updated events actually matter to us
    # (sensors might report already known events to us):
    # the ones where last_seen > time_last_seen. This excludes both old entries in the sensor data, where both
    # time_seen and time_last_seen are longer ago and new observables, which have both time_seen and time_last_seen
    # set to just now. Thus, we add the latter here.
    updated_events_df = (
        events_plus_observable_data_df[
            events_plus_observable_data_df.time_seen
            > events_plus_observable_data_df.time_last_seen
        ]
        .drop(columns=["time_last_seen"])
        .append(new_observables_events_df.set_index("observable_id"))
    )

    # do custom value adjustments if wanted
    sensor = get_sensor()
    if hasattr(sensor, "adjust_event_value"):

        def adjust_event(event_df):
            observable: Observables = Observables.find_observable_by_id(
                event_df.name  # observable_id
            )
            last_event_value = None
            try:
                last_event_df = Events.find_by_observable_id(observable.id).iloc[-1]
                last_event_value = last_event_df["value"]
            except:
                pass
            event_df["value"], event_df["observations"] = sensor.adjust_event_value(
                event_df["value"],
                last_event_value,
                event_df["observations"],
                last_event_df["observations"],
                observable,
            )
            return event_df

        updated_events_df = updated_events_df.apply(adjust_event, axis=1)

    # To store updates to the observables table,
    # format the updated events as observables.
    observables_with_recent_updates_df = updated_events_df[["time_seen"]].rename(
        columns={"time_seen": "time_last_seen"}
    )

    # And now it is time to let the database know about all of this.
    # First the observables, then events, so that the FK relation from events to observables works.
    with transaction.atomic():
        created = Observables.save_from_df(observables_with_recent_updates_df)
        logger.info(
            f"Finished saving {len(observables_with_recent_updates_df.index)} observables, {created} were new."
        )

        box_settings = BoxSettings.objects.first()
        if box_settings is None:
            raise Exception(
                "No box settings yet. Please create some in the admin panel."
            )
        created = Events.save_from_df(updated_events_df, box_settings.box_id)
        logger.info(
            f"Finished saving {len(updated_events_df.index)} updated observable events, {created} were new."
        )


def sensor_data_to_db(tmp_path: str):

0 Source : queries.py
with MIT License
from aileenproject

def prepare_df_datetime_index(
    df: pd.DataFrame, time_column="time_seen"
) -> pd.DataFrame:
    """
    Utility function which prepares an event dataframe to become time series data
    """
    df.astype(str, inplace=True)  # needed to have the json send easily
    df.rename(columns={time_column: "time"}, inplace=True)
    df.index = df["time"]
    del df["time"]
    if not df.index.empty:
        if df.index.tzinfo is not None:
            df.index = df.index.tz_convert(settings.TIME_ZONE)
        else:
            df.index = df.index.tz_localize(settings.TIME_ZONE)
    for field_name in (
        "id",
        "box_id",
        "total_packets",
    ):  # TODO: not the job of this function
        if field_name in df.columns:
            df.drop(field_name, 1, inplace=True)
    return df


def unique_observables_per_bin_size(df: pd.DataFrame, bin_size: str) -> List:

0 Source : runapscheduler.py
with BSD 2-Clause "Simplified" License
from atkinson

    def handle(self, *args, **options):
        scheduler = BlockingScheduler(timezone=settings.TIME_ZONE)
        scheduler.add_jobstore(DjangoJobStore(), "default")

        scheduler.add_job(
            my_job,
            trigger=CronTrigger(second="*/10"),  # Every 10 seconds
            id="my_job",  # The `id` assigned to each job MUST be unique
            max_instances=1,
            replace_existing=True,
        )
        logger.info("Added job 'my_job'.")

        scheduler.add_job(
            delete_old_job_executions,
            trigger=CronTrigger(
                day_of_week="mon", hour="00", minute="00"
            ),  # Midnight on Monday, before start of the next work week.
            id="delete_old_job_executions",
            max_instances=1,
            replace_existing=True,
        )
        logger.info("Added weekly job: 'delete_old_job_executions'.")

        try:
            logger.info("Starting scheduler...")
            scheduler.start()
        except KeyboardInterrupt:
            logger.info("Stopping scheduler...")
            scheduler.shutdown()
            logger.info("Scheduler shut down successfully!")

0 Source : schedule_class.py
with GNU General Public License v2.0
from costasiella

def get_booking_status(schedule_item, date, booking_open_on, available_online_spaces):
    """
        :param schedule_item: schedule_item object
        :return: String: booking status
    """
    ## Start test for class booking status

    # https://docs.djangoproject.com/en/3.1/topics/i18n/timezones/#usage
    local_tz = pytz.timezone(settings.TIME_ZONE)
    # print(local_tz)

    now = timezone.localtime(timezone.now())
    # print("#### now ########")
    # print(now)
    # print(now.date())

    dt_start = datetime.datetime(date.year,
                                 date.month,
                                 date.day,
                                 int(schedule_item.time_start.hour),
                                 int(schedule_item.time_start.minute))
    # print(dt_start)
    dt_start = local_tz.localize(dt_start)
    # print(dt_start)

    dt_end = datetime.datetime(date.year,
                               date.month,
                               date.day,
                               int(schedule_item.time_end.hour),
                               int(schedule_item.time_end.minute))
    # print(dt_end)
    dt_end = local_tz.localize(dt_end)
    # print(dt_end)

    status = "FINISHED"
    if schedule_item.organization_holiday_id:
        status = 'HOLIDAY'
    elif schedule_item.status == "CANCELLED":
        status = 'CANCELLED'
    elif dt_start   <  = now and dt_end >= now:
        # check start time
        status = 'ONGOING'
    elif dt_start >= now:
        if now.date()  <  booking_open_on:
            status = 'NOT_YET_OPEN'
        else:
            # check spaces for online bookings
            if available_online_spaces  <  1:
                status = 'FULL'
            else:
                status = 'OK'

    return status

    # dt_end = datetime.datetime(self.date.year,
    #                            self.date.month,
    #                            self.date.day,
    #                            int(row.classes.Endtime.hour),
    #                            int(row.classes.Endtime.minute))
    # dt_end = local_tz.localize(dt_end)

    ## End test for class booking status

    # Everything below here in this fn is OpenStudio code to be ported
    # pytz = current.globalenv['pytz']
    # TIMEZONE = current.TIMEZONE
    # NOW_LOCAL = current.NOW_LOCAL
    # TODAY_LOCAL = current.TODAY_LOCAL
    #
    # local_tz = pytz.timezone(TIMEZONE)
    #
    # dt_start = datetime.datetime(self.date.year,
    #                              self.date.month,
    #                              self.date.day,
    #                              int(row.classes.Starttime.hour),
    #                              int(row.classes.Starttime.minute))
    # dt_start = local_tz.localize(dt_start)
    # dt_end = datetime.datetime(self.date.year,
    #                            self.date.month,
    #                            self.date.day,
    #                            int(row.classes.Endtime.hour),
    #                            int(row.classes.Endtime.minute))
    # dt_end = local_tz.localize(dt_end)
    #
    # status = 'finished'
    # if row.classes_otc.Status == 'cancelled' or row.school_holidays.id:
    #     status = 'cancelled'
    # elif dt_start  < = NOW_LOCAL and dt_end >= NOW_LOCAL:
    #     # check start time
    #     status = 'ongoing'
    # elif dt_start >= NOW_LOCAL:
    #     if not self.bookings_open == False and TODAY_LOCAL  <  self.bookings_open:
    #         status = 'not_yet_open'
    #     else:
    #         # check spaces for online bookings
    #         spaces = self._get_day_list_booking_spaces(row)
    #         if spaces  <  1:
    #             status = 'full'
    #         else:
    #             status = 'ok'
    #
    # return status


def calculate_booking_open_on(date):

0 Source : runapscheduler.py
with MIT License
from e-m-b-a

    def handle(self, *args, **options):
        """
        handler for runapscheduler command
        """
        scheduler = BlockingScheduler(timezone=settings.TIME_ZONE)
        scheduler.add_jobstore(DjangoJobStore(), "default")

        # configure CronTrigger
        if options['test']:
            # Every hour -> changed to 5 seconds
            resource_tracker_trigger = CronTrigger(second="*/5")
            # every 30 minutes
            delete_old_job_executions_tigger = CronTrigger(minute="*/30")
            delete_old_than = 900
        else:
            # Every hour
            resource_tracker_trigger = CronTrigger(minute="00")
            # everyday at midnight
            delete_old_job_executions_tigger = CronTrigger(hour="00", minute="00")
            delete_old_than = 1_209_600

        # start resource_tracker
        scheduler.add_job(
            resource_tracker,
            trigger=resource_tracker_trigger,
            id="resource_tracker",
            max_instances=1,
            replace_existing=True,
        )
        logger.info("Added CronTrigger job %s.", resource_tracker.__name__)
        logger.info("Added CronTrigger resource_tracker_trigger: %s.", resource_tracker_trigger)
        logger.info("Added CronTrigger delete_old_job_executions_trigger: %s.", delete_old_job_executions_tigger)

        # start cleanup jobresource_tracker
        scheduler.add_job(
            delete_old_job_executions,
            trigger=delete_old_job_executions_tigger,
            id="delete_old_job_executions",
            max_instances=1,
            replace_existing=True,
            args=(delete_old_than,)
        )
        logger.info("Added weekly job: 'delete_old_job_executions'.")

        try:
            logger.info("Starting scheduler for tracking...")
            scheduler.start()
        except KeyboardInterrupt:
            logger.info("Stopping scheduler for tracking...")
            scheduler.shutdown()
            logger.info("Scheduler for tracking shut down successfully!")

0 Source : tasks.py
with GNU Affero General Public License v3.0
from etnguyen03

def process_image(photo_id: str) -> None:
    """
    Process an image.

    :param photo_id: The UUID of a photo
    :return: None
    """
    photo = Photo.objects.get(id=photo_id)

    # Read this file
    READ_FILE_PATH = os.path.join(
        os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
        "utils/files/read_file.py",
    )
    # TODO: find a better way to do this
    file_path = "/data/" + str(photo.file).lstrip("/")
    file_read: dict = json.loads(
        subprocess.run(
            [
                "sudo",
                "pipenv",
                "run",
                "python3",
                READ_FILE_PATH,
                file_path,
            ],  # sudo required for chroot
            capture_output=True,
            text=True,
        ).stdout
    )

    if "error" in file_read.keys():
        if file_read["error"] == 404:
            raise Exception()
        elif file_read["error"] == 500:
            raise Exception()

    assert "image" in file_read[file_path]["mime"], "Not an image"

    image_data: bytes = base64.b64decode(file_read[file_path]["data"])

    m = magic.Magic(mime=True)
    assert "image" in m.from_buffer(image_data), "Not an image file"

    exif_image = exif_Image(image_data)

    # Update the photo's metadata

    if "datetime" in dir(exif_image):
        # EXIF does not include timezones (WHY?!?) in timestamps.
        # Therefore, we use the GPS location to find the timezone of the image,
        # and where there is no GPS location, we use server time (likely UTC).
        tf = TimezoneFinder()

        if "gps_longitude" in dir(exif_image) and "gps_latitude" in dir(exif_image):
            gps_point = []
            for pt, direction in [
                (exif_image.gps_latitude, exif_image.gps_latitude_ref),
                (exif_image.gps_longitude, exif_image.gps_longitude_ref),
            ]:
                deg, minutes, seconds = pt
                # https://stackoverflow.com/a/54294962
                point = (
                    float(deg) + float(minutes) / 60 + float(seconds) / (60 * 60)
                ) * (-1 if direction in ["W", "S"] else 1)
                gps_point.append(point)
            tz = tf.timezone_at(lat=gps_point[0], lng=gps_point[1])
        else:
            tz = settings.TIME_ZONE

        photo.photo_taken_time = datetime.strptime(
            exif_image.datetime, "%Y:%m:%d %H:%M:%S"
        ).replace(tzinfo=pytz.timezone(tz))

    # Height and width are a property of every image
    image_pillow = PIL_Image.open(io.BytesIO(image_data))
    image_pillow = ImageOps.exif_transpose(image_pillow)
    width, height = image_pillow.size
    photo.image_width = width
    photo.image_height = height
    photo.image_size = file_read[file_path]["size"]

    if "make" in dir(exif_image):
        photo.camera_make = exif_image.make
    if "model" in dir(exif_image):
        photo.camera_model = exif_image.model
    if "aperture_value" in dir(exif_image):
        photo.aperture_value = exif_image.aperture_value
    if "shutter_speed_value" in dir(exif_image):
        photo.shutter_speed_value = exif_image.shutter_speed_value
    if "focal_length" in dir(exif_image):
        photo.focal_length = exif_image.focal_length
    if "photographic_sensitivity" in dir(exif_image):
        photo.iso = exif_image.photographic_sensitivity
    if "flash" in dir(exif_image):
        photo.flash_fired = exif_image.flash.flash_fired
        photo.flash_mode = exif_image.flash.flash_mode

    if settings.ENABLE_TENSORFLOW_TAGGING:
        # We only want to run one tagging operation at a time since it is memory intensive
        with redis_lock("tensorflow-tag"):
            # We define get_predictions to allow for a timeout
            # The queue is created to grab the return value
            queue = multiprocessing.Queue()

            def get_predictions(img_pillow: PIL_Image):
                """
                Helper function to determine tags of an image
                :param img_pillow: Pillow.Image
                :return: None (results appended to queue)
                """
                model = NASNetLarge(weights="imagenet")
                image_tags = keras_image.img_to_array(
                    img_pillow.resize((331, 331), PIL_Image.NEAREST)
                )
                image_tags = np.expand_dims(image_tags, axis=0)
                image_tags = preprocess_input(image_tags)
                predictions = model.predict(image_tags)
                queue.put(decode_predictions(predictions)[0])

            process = billiard.context.Process(
                target=get_predictions, kwargs={"img_pillow": image_pillow}
            )
            process.daemon = True
            process.start()

            process.join(60)  # 60 second (arbitrary) timeout
            if process.is_alive():
                process.terminate()
                raise TimeoutError

            decoded_predictions = queue.get()

            for prediction in decoded_predictions:
                if (
                    prediction[2] > 0.20
                ):  # If score greater than 0.20 (chosen arbitrarily)
                    tag = PhotoTag.objects.get_or_create(tag=prediction[1])
                    if tag[1]:  # If an object was created
                        tag[0].is_auto_generated = True
                        tag[0].save()
                    photo.tags.add(tag[0])

    if settings.ENABLE_FACE_RECOGNITION:
        # We can only do one at a time to prevent duplicates
        with redis_lock("face-recognition"):
            # We now need to convert the image to a NumPy array in order to do anything with it
            np_array = np.array(image_pillow)

            # Now, get the face encodings for the face(s) in this image
            encodings = face_recognition.face_encodings(np_array, model="cnn")

            # Loop over all the encodings detected

            # First, we have to query the database
            faces = list(Face.objects.all())
            faces_data = [json.loads(s.face_data) for s in faces]
            for encoding in encodings:
                # Now, we compare to the list of faces in the database
                # TODO: This needs to be more efficient
                compare = face_recognition.compare_faces(faces_data, encoding)

                # If a face already exists, then it should have a True value in that array,
                # corresponding to the faces list
                # TODO: Deduplicate somehow?
                if any(compare):
                    # Find the indices that are True, and take the same index in the faces list
                    for i in range(len(compare)):
                        if compare[i]:
                            photo.faces.add(faces[i])

                # If no face exists, then add one
                face = Face.objects.create(face_data=json.dumps(encoding.tolist()))
                photo.faces.add(face)

    # We will need to make a thumbnail of this image
    image_pillow.thumbnail((1024, 1024))

    # Save the thumbnail in a directory
    # This directory is under settings.IMAGE_THUMBS_DIR, and
    # we use the first two characters of the photo's UUID as subdirectories
    # to save images under

    path = os.path.join(settings.IMAGE_THUMBS_DIR, photo_id[0], photo_id[1])
    Path(os.path.join(settings.IMAGE_THUMBS_DIR, photo_id[0], photo_id[1])).mkdir(
        parents=True, exist_ok=True
    )

    image_pillow.save(os.path.join(path, f"{photo_id}.thumb.jpeg"))

    photo.save()

0 Source : utils.py
with Apache License 2.0
from gethue

def field_values_from_separated_file(fh, delimiter, quote_character, fields=None):
  if fields is None:
    field_names = None
  else:
    field_names = [field['name'].strip() for field in fields]

  if fields is None:
    timestamp_fields = None
  else:
    timestamp_fields = [field['name'].strip() for field in fields if field['type'] in DATE_FIELD_TYPES]

  if fields is None:
    integer_fields = None
  else:
    integer_fields = [field['name'].strip() for field in fields if field['type'] in INTEGER_FIELD_TYPES]

  if fields is None:
    decimal_fields = None
  else:
    decimal_fields = [field['name'].strip() for field in fields if field['type'] in DECIMAL_FIELD_TYPES]

  if fields is None:
    boolean_fields = None
  else:
    boolean_fields = [field['name'].strip() for field in fields if field['type'] in BOOLEAN_FIELD_TYPES]

  content = fh.read()
  headers = None

  while content:
    last_newline = content.rfind('\n')
    if last_newline > -1:
      next_chunk = fh.read()
      # If new line is quoted, skip this iteration and try again.
      if content[last_newline - 1] == '"' and next_chunk:
        content += next_chunk
        continue
      else:
        if headers is None:
          csvfile = string_io(content[:last_newline])
        else:
          csvfile = string_io('\n' + content[:last_newline])
        content = content[last_newline + 1:] + next_chunk
    else:
      if headers is None:
        csvfile = string_io(content)
      else:
        csvfile = string_io('\n' + content)
      content = fh.read()

    # First line is headers
    if headers is None:
      headers = next(csv.reader(csvfile, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character)))
      headers = [name.strip() for name in headers]

    # User dict reader
    reader = csv.DictReader(csvfile, fieldnames=headers, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character))

    remove_keys = None
    for row in reader:
      row = dict([(force_unicode(k), force_unicode(v, errors='ignore')) for k, v in row.items()]) # Get rid of invalid binary chars and convert to unicode from DictReader

      # Remove keys that aren't in collection
      if remove_keys is None:
        if field_names is None:
          remove_keys = []
        else:
          remove_keys = set(row.keys()) - set(field_names)
      if remove_keys:
        for key in remove_keys:
          del row[key]

      # Parse dates
      if timestamp_fields:
        tzinfo = pytz.timezone(settings.TIME_ZONE)
        for key in timestamp_fields:
          if key in row:
            dt = parse(row[key])
            if not dt.tzinfo:
              dt = tzinfo.localize(dt)
            row[key] = dt.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')

      # Parse decimal
      if decimal_fields:
        for key in decimal_fields:
          if key in row:
            row[key] = float(row[key])

      # Parse integer
      if integer_fields:
        for key in integer_fields:
          if key in row:
            row[key] = int(row[key])

      # Parse boolean
      if boolean_fields:
        for key in boolean_fields:
          if key in row:
            row[key] = str(row[key]).lower() == "true"

      # Add mock id random value
      if 'id' not in row:
        row['id'] = str(uuid.uuid4())

      yield row


def field_values_from_log(fh, fields=[ {'name': 'message', 'type': 'text_general'}, {'name': 'tdate', 'type': 'timestamp'} ]):

0 Source : test_date_parsing.py
with GNU General Public License v3.0
from jonaswinkler

    def test_date_format_8(self):
        text = (
            "lorem ipsum\n"
            "Wohnort\n"
            "3100\n"
            "IBAN\n"
            "AT87 4534\n"
            "1234\n"
            "1234 5678\n"
            "BIC\n"
            "lorem ipsum\n"
            "März 2020"
        )
        self.assertEqual(
            parse_date("", text),
            datetime.datetime(
                2020, 3, 1, 0, 0,
                tzinfo=tz.gettz(settings.TIME_ZONE)
            )
        )

    @override_settings(SCRATCH_DIR=SCRATCH)

0 Source : signals.py
with Apache License 2.0
from lumanjiao

def update_connections_time_zone(**kwargs):
    if kwargs['setting'] == 'TIME_ZONE':
        # Reset process time zone
        if hasattr(time, 'tzset'):
            if kwargs['value']:
                os.environ['TZ'] = kwargs['value']
            else:
                os.environ.pop('TZ', None)
            time.tzset()

        # Reset local time zone cache
        timezone._localtime = None

    # Reset the database connections' time zone
    if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC':
        USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE
    elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ:
        USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value']
    else:
        # no need to change the database connnections' time zones
        return
    tz = 'UTC' if USE_TZ else TIME_ZONE
    for conn in connections.all():
        conn.settings_dict['TIME_ZONE'] = tz
        tz_sql = conn.ops.set_time_zone_sql()
        if tz_sql:
            conn.cursor().execute(tz_sql, [tz])


@receiver(setting_changed)

0 Source : utils.py
with Apache License 2.0
from lumanjiao

def field_values_from_separated_file(fh, delimiter, quote_character, fields=None):
  if fields is None:
    field_names = None
  else:
    field_names = [field['name'].strip() for field in fields]

  if fields is None:
    timestamp_fields = None
  else:
    timestamp_fields = [field['name'].strip() for field in fields if field['type'] in DATE_FIELD_TYPES]

  if fields is None:
    integer_fields = None
  else:
    integer_fields = [field['name'].strip() for field in fields if field['type'] in INTEGER_FIELD_TYPES]

  if fields is None:
    decimal_fields = None
  else:
    decimal_fields = [field['name'].strip() for field in fields if field['type'] in DECIMAL_FIELD_TYPES]

  if fields is None:
    boolean_fields = None
  else:
    boolean_fields = [field['name'].strip() for field in fields if field['type'] in BOOLEAN_FIELD_TYPES]

  content = fh.read()
  headers = None

  while content:
    last_newline = content.rfind('\n')
    if last_newline > -1:
      # If new line is quoted, skip this iteration and try again.
      if content[:last_newline].count('"') % 2 != 0:
        content += fh.read()
        continue
      else:
        if headers is None:
          csvfile = StringIO.StringIO(content[:last_newline])
        else:
          csvfile = StringIO.StringIO('\n' + content[:last_newline])
        content = content[last_newline + 1:] + fh.read()
    else:
      if headers is None:
        csvfile = StringIO.StringIO(content)
      else:
        csvfile = StringIO.StringIO('\n' + content)
      content = fh.read()

    # First line is headers
    if headers is None:
      headers = next(csv.reader(csvfile, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character)))
      headers = [name.strip() for name in headers]

    # User dict reader
    reader = csv.DictReader(csvfile, fieldnames=headers, delimiter=smart_str(delimiter), quotechar=smart_str(quote_character))

    remove_keys = None
    for row in reader:
      # Remove keys that aren't in collection
      if remove_keys is None:
        if field_names is None:
          remove_keys = []
        else:
          remove_keys = set(row.keys()) - set(field_names)
      if remove_keys:
        for key in remove_keys:
          del row[key]

      # Parse dates
      if timestamp_fields:
        tzinfo = pytz.timezone(settings.TIME_ZONE)
        for key in timestamp_fields:
          if key in row:
            dt = parse(row[key])
            if not dt.tzinfo:
              dt = tzinfo.localize(dt)
            row[key] = dt.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%SZ')

      # Parse decimal
      if decimal_fields:
        for key in decimal_fields:
          if key in row:
            row[key] = float(row[key])

      # Parse integer
      if integer_fields:
        for key in integer_fields:
          if key in row:
            row[key] = int(row[key])

      # Parse boolean
      if boolean_fields:
        for key in boolean_fields:
          if key in row:
            row[key] = str(row[key]).lower() == "true"

      # Add mock id random value
      if 'id' not in row:
        row['id'] = str(uuid.uuid4())

      yield row


def field_values_from_log(fh, fields=[ {'name': 'message', 'type': 'text_general'}, {'name': 'tdate', 'type': 'timestamp'} ]):

0 Source : test_emails.py
with MIT License
from moshthepitt

    def test_leave_emails(self):
        """Test Leave emails."""
        # apply for leave
        start = datetime(2017, 6, 5, 7, 0, 0, tzinfo=pytz.timezone(settings.TIME_ZONE))
        end = datetime(2017, 6, 10, 7, 0, 0, tzinfo=pytz.timezone(settings.TIME_ZONE))
        data = {
            "staff": self.staffprofile.id,
            "leave_type": Leave.REGULAR,
            "start": start,
            "end": end,
            "review_reason": "Need a break",
        }
        form = ApplyLeaveForm(data=data)
        self.assertTrue(form.is_valid())
        leave = form.save()

        obj_type = ContentType.objects.get_for_model(leave)
        # Hard code the pk for the snapshot test
        # empty the test outbox so that we don't deal with the old review's emails
        mail.outbox = []
        ModelReview.objects.get(content_type=obj_type, object_id=leave.id).delete()
        review = mommy.make(
            "model_reviews.ModelReview",
            content_type=obj_type,
            object_id=leave.id,
            id=1338,
        )
        reviewer = Reviewer.objects.get(review=review, user=self.boss)

        self.assertEqual(
            "Mosh Pitt requested time off on 05 Jun to 10 Jun", mail.outbox[0].subject
        )
        self.assertEqual(["Mother Hen   <  [email protected]>"], mail.outbox[0].to)
        self.assertMatchSnapshot(mail.outbox[0].body)
        self.assertMatchSnapshot(mail.outbox[0].alternatives[0][0])

        # approve the review
        data = {
            "review": review.pk,
            "reviewer": reviewer.pk,
            "review_status": ModelReview.APPROVED,
        }
        form = PerformReview(data=data)
        self.assertTrue(form.is_valid())
        form.save()
        self.assertEqual(
            "Your time off request of 05 Jun - 10 Jun has a response",
            mail.outbox[1].subject,
        )
        self.assertEqual(["Mosh Pitt  < [email protected]>"], mail.outbox[1].to)
        self.assertMatchSnapshot(mail.outbox[1].body)
        self.assertMatchSnapshot(mail.outbox[1].alternatives[0][0])

        # then reject it
        data = {
            "review": review.pk,
            "reviewer": reviewer.pk,
            "review_status": ModelReview.REJECTED,
        }
        form = PerformReview(data=data)
        self.assertTrue(form.is_valid())
        form.save()
        self.assertEqual(
            "Your time off request of 05 Jun - 10 Jun has a response",
            mail.outbox[2].subject,
        )
        self.assertEqual(["Mosh Pitt  < [email protected]>"], mail.outbox[2].to)
        self.assertMatchSnapshot(mail.outbox[2].body)
        self.assertMatchSnapshot(mail.outbox[2].alternatives[0][0])

    def test_overtime_emails(self):

0 Source : test_emails.py
with MIT License
from moshthepitt

    def test_overtime_emails(self):
        """Test Overtime emails."""
        # apply for overtime
        start = datetime(
            2017, 6, 5, 16, 45, 0, tzinfo=pytz.timezone(settings.TIME_ZONE)
        )
        end = datetime(2017, 6, 5, 21, 30, 0, tzinfo=pytz.timezone(settings.TIME_ZONE))

        data = {
            "staff": self.staffprofile.id,
            "date": start.date(),
            "start": start.time(),
            "end": end.time(),
            "review_reason": "Extra work",
        }

        form = ApplyOverTimeForm(data=data)
        self.assertTrue(form.is_valid())
        overtime = form.save()

        obj_type = ContentType.objects.get_for_model(overtime)
        # Hard code the pk for the snapshot test
        # empty the test outbox so that we don't deal with the old review's emails
        mail.outbox = []
        ModelReview.objects.get(content_type=obj_type, object_id=overtime.id).delete()
        review = mommy.make(
            "model_reviews.ModelReview",
            content_type=obj_type,
            object_id=overtime.id,
            id=1337,
        )
        reviewer = Reviewer.objects.get(review=review, user=self.boss)

        self.assertEqual(
            "Mosh Pitt requested overtime on 05 Jun", mail.outbox[0].subject
        )
        self.assertEqual(["Mother Hen   <  [email protected]>"], mail.outbox[0].to)
        self.assertMatchSnapshot(mail.outbox[0].body)
        self.assertMatchSnapshot(mail.outbox[0].alternatives[0][0])

        # approve the overtime
        data = {
            "review": review.pk,
            "reviewer": reviewer.pk,
            "review_status": ModelReview.APPROVED,
        }
        form = PerformReview(data=data)
        self.assertTrue(form.is_valid())
        form.save()
        self.assertEqual(
            "Your overtime request of 05 Jun has a response", mail.outbox[1].subject,
        )
        self.assertEqual(["Mosh Pitt  < [email protected]>"], mail.outbox[1].to)
        self.assertMatchSnapshot(mail.outbox[1].body)
        self.assertMatchSnapshot(mail.outbox[1].alternatives[0][0])

        # then reject it
        data = {
            "review": review.pk,
            "reviewer": reviewer.pk,
            "review_status": ModelReview.REJECTED,
        }
        form = PerformReview(data=data)
        self.assertTrue(form.is_valid())
        form.save()
        self.assertEqual(
            "Your overtime request of 05 Jun has a response", mail.outbox[2].subject,
        )
        self.assertEqual(["Mosh Pitt  < [email protected]>"], mail.outbox[2].to)
        self.assertMatchSnapshot(mail.outbox[2].body)
        self.assertMatchSnapshot(mail.outbox[2].alternatives[0][0])

See More Examples