Ejemplo n.º 1
0
def test_init_is_today(init_args):
    """If passed an object without a timetuple method, use today."""

    today = datetime.date.today().timetuple()
    if init_args is not None:
        ddate_obj = DDate(init_args).date.timetuple()
    else:
        ddate_obj = DDate().date.timetuple()
    assert today.tm_yday == ddate_obj.tm_yday
    assert today.tm_mon == ddate_obj.tm_mon
Ejemplo n.º 2
0
def test_discordian_holiday(dateobj, holidayexp, strexp):
    """Ensure the holidays are correctly accounted for."""

    hday = DDate(dateobj)
    assert hday.holiday == holidayexp
    # have to use endswith just in case today is the test day
    assert str(hday).endswith("{0} Celebrate {1}!".format(strexp, holidayexp))
Ejemplo n.º 3
0
def when(inp, say=None):
    #"Shows the countdown to the new episode of My Little Pony: Friendship is Magic!"

    try:
        ep = ponyapi.newest()
        now, then, td = get_time(ep)
        seasonep = ""

        if inp == "discord":
            return "%s will air on %s" % (ep[u"name"], DDate(then))

        if ep[u"is_movie"]:
            seasonep = "(a movie)"
        else:
            seasonep = "(season %d episode %d)" % (ep[u"season"],
                                                   ep[u"episode"])

        reply = "%s %s will air on %s in %d days!" % (
            ep[u"name"], seasonep, then.strftime("%a, %d %b %Y %H:%M:%S"),
            td.days)

        return reply

    except:
        return "404! We're on hiatus!"
Ejemplo n.º 4
0
    def __init__(self,
                 discordian=False,
                 eve_real=False,
                 eve_game=False,
                 date=None):
        self.discordian = discordian
        self.eve_real = eve_real
        self.eve_game = eve_game

        if self.discordian:
            self.max_width = 14
            self.date = date or DDate()
            now = DDate()
            self.context = cmp(
                int("{0}{1}".format(self.date.year, self.date.season)),
                int("{0}{1}".format(now.year, now.season)))
            self.calendar = discordian_calendar(self.date)
            self.month = self.date.SEASONS[self.date.season]
            self.ending_days = ["70", "71", "72", "73"]
            self.day_of_month = self.date.day_of_season
            self.weekday_abbrs = [d[:2].title() for d in self.date.WEEKDAYS]
        else:
            self.max_width = 20
            now = datetime.datetime.now()
            self.date = date or now
            self.context = cmp(
                int("{0}{1}".format(self.date.year,
                                    str(self.date.month).rjust(2, "0"))),
                int("{0}{1}".format(now.year,
                                    str(now.month).rjust(2, "0"))),
            )
            self.month = self.date.strftime("%B")
            # start the week on Sunday
            self.calendar = calendar.TextCalendar(6).formatmonth(
                self.date.year,
                self.date.month,
            ).splitlines()[2:]
            self.ending_days = ["28", "29", "30", "31"]
            self.day_of_month = self.date.strftime("%d")
            self.weekday_abbrs = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]

        if self.eve_real:
            self.year = 23236 + (self.date.year - 1898)
        elif self.eve_game:
            self.year = "YC {0}".format(self.date.year - 1898)
        else:
            self.year = self.date.year
Ejemplo n.º 5
0
def test_data_in_repr():
    """Ensure object data is in the repr."""

    ddate_obj = DDate(datetime.date(year=2012, month=2, day=29))
    assert str(hex(id(ddate_obj))) in repr(ddate_obj)
    for attr in dir(ddate_obj):
        if not attr.startswith("_") and attr.lower() == attr:
            assert str(getattr(ddate_obj, attr)) in repr(ddate_obj)
Ejemplo n.º 6
0
def discordianCalendar(day):
    discordianDay = DDate(day)
    dayInfo = {}
    dayInfo['DayName'] = DDate.WEEKDAYS[discordianDay.day_of_week]
    dayInfo['MonthName'] = DDate.SEASONS[discordianDay.season]
    dayInfo['DayNum'] = str(discordianDay.day_of_season)
    dayInfo['MonthNum'] = str(discordianDay.season)
    dayInfo['YearNum'] = 'YOLD ' + str(discordianDay.year)
    dayInfo['Format'] = 'Discordian'
    return dayInfo
Ejemplo n.º 7
0
def test_days_of_the_year(dateobj, weekday, season, dayofseason, year, strexp):
    """Test specific days of the year."""

    ddate_obj = DDate(dateobj)

    if weekday is None:
        # checks for st tibs edge cases, avoids TypeError's on [None]
        assert ddate_obj.day_of_week == weekday
        assert ddate_obj.season == season
    else:
        assert ddate_obj.WEEKDAYS[ddate_obj.day_of_week] == weekday
        assert ddate_obj.SEASONS[ddate_obj.season] == season

    assert ddate_obj.day_of_season == dayofseason
    assert ddate_obj.year == year
    assert str(ddate_obj) == strexp
Ejemplo n.º 8
0
def discordian_calendar(date):
    """Simulate calendar.TextCalendar for discordian dates.

    Args:
        date: a DDate object

    Returns:
        list of strings to make a calendar month
    """

    first_day_of_season = DDate(
        datetime.date(
            year=date.date.year,
            month=date.date.month,
            day=date.date.day,
        ) - datetime.timedelta(days=date.day_of_season - 1), )

    weeks = []
    first_week = True

    start_day = first_day_of_season.day_of_week
    for week in range(1, 77, 5):
        if first_week:
            weeks.append("{0}{1}".format(
                "  " * start_day,
                " ".join(
                    [str(x).rjust(2, " ") for x in range(1, 6 - start_day)]),
            ))
            first_week = False
        else:
            week_str = " ".join([
                str(x)
                for x in range(week - start_day, min((week - start_day) +
                                                     5, 74))
            ])
            if week_str:
                weeks.append(week_str)

    return weeks
Ejemplo n.º 9
0
 def discordian_date(self, tweet):  # Expects single tweet (list)
     text = str("@" + tweet[0] + " " + str(DDate()))
     print(text)
     self.reply_semiman(text, tweet[2])
Ejemplo n.º 10
0
def ddate(inp):
    return str(DDate())
Ejemplo n.º 11
0
def nextshow(update: Update, context: CallbackContext) -> None:
    """Bot /next callback
    Posts the next scheduled show for a given slug/name and timezone"""

    # Message edit.
    if update.message is None:
        return

    args = update.message.text.split(" ")

    # Which show
    if len(args) < 2:
        slug = next_show_default
    elif args[1].lower() in domains:
        slug = args[1].lower()
    else:
        slug = next_show_default
        args.insert(1, "")  # reverse shift to offer timezone
    domain = domains[slug.lower()]

    try:
        r = requests.get("https://{}/nextshow/".format(domain))
        if r.status_code != 200:
            raise Exception("API returned " + str(r.status_code))
    except Exception as e:
        update.message.reply_text(text="Error: " + str(e))
        raise e
    showtime = datetime.utcfromtimestamp(int(r.text))

    # Start update job
    if "pin" in args:
        user = update.effective_chat.get_member(update.effective_user.id)
        if not user.can_pin_messages and user.status != "creator":
            update.message.reply_text(text="You aren't allowed to do that")
            return
        ctx = {
            "chat": update.effective_chat,
            "message": None,
            "slug": slug,
            "showtime": showtime,
        }
        logging.info(
            "Scheduled next-pin job, %s (%s) for %s",
            update.effective_user.name,
            update.effective_user.id,
            update.effective_chat.title,
        )
        updater.job_queue.run_repeating(
            next_pin_callback,
            60,
            0,
            context=ctx,
            name=f"next_pin_{update.effective_chat.id}",
        )
        return

    # Timezones
    if len(args) < 3:  # no TZ
        tzstr = "America/New_York"
    else:
        tzstr = args[2]

    if tzstr.lower() in ["ddate", "discordian"]:
        datestr = str(DDate(showtime))
        if datestr.startswith("Today is "):
            datestr = datestr[9:]
    elif tzstr.lower() in ["beat", "swatch", "internet"]:
        datestr = beat(showtime)
    else:
        if tzstr.lower() in timezones:  # custom map
            tzstr = timezones[args[2].lower()]
        elif len(tzstr) < 5:  # probably "EDT" style
            tzstr = tzstr.upper()
        # Otherwise try verbatim
        tzobj = tz.gettz(tzstr)
        if tzobj is None:
            update.message.reply_text(text="Sorry, I don't understand")  # TZ or show
            return
        datestr = (
            showtime.astimezone(tzobj).strftime("%a %e %b, %H:%M %Z").replace("  ", " ")
        )

    delta = showtime - datetime.utcnow()
    if delta.total_seconds() < 0:
        update.effective_chat.send_message("A show is currently live or just ended!")
        return

    deltastr = "{} days, {:02}:{:02}".format(
        delta.days, delta.seconds // (60 * 60), (delta.seconds // 60) % 60
    )
    update.effective_chat.send_message(
        text="The next {} is {}. That's {} from now.".format(
            show_names[domain], datestr, deltastr
        )
    )
Ejemplo n.º 12
0
 def handle_today(self, data, match):
     self.send(str(DDate()), data)
Ejemplo n.º 13
0
    def handle_date(self, data, match):
        year = int(match.groupdict()['year'])
        month = int(match.groupdict()['month'])
        day = int(match.groupdict()['day'])

        self.send(str(DDate(datetime.date(year=year, month=month, day=day))), data)
Ejemplo n.º 14
0
def dd(bot, trigger):
    bot.say(str(DDate()))
Ejemplo n.º 15
0
def discordian_calendar(season=None, year=None, dtobj=None):
    """Prints a discordian calendar for a particular season and year.

    Args::

        season: integer cardinal season from 1 to 5
        year: integer discordian year from 1166 to MAXYEAR + 1166
        dtobj: datetime object to instatiate the calendar from (Gregorian)
    """

    now = DDate(dtobj)

    moved_year = None

    if season is None:
        season = now.season
    elif season.lower() == "next":
        season, moved_year = _season_overflow(now.season or 0 + 1, moved_year,
                                              now)
    else:
        # allow for +1, -2, for seasons...
        for symbol, oper in zip(("+", "-"), (operator.add, operator.sub)):
            if symbol in season:
                try:
                    amount = int(season.strip(symbol))
                except ValueError:
                    raise ValueError("unknown season: {}".format(season))
                else:
                    season, moved_year = _season_overflow(
                        oper(now.season or 0, amount),
                        moved_year,
                        now,
                    )
                    break
        else:
            # allow to use the season name or some starting part of it
            input_name = season.lower()
            for season_name in now.SEASONS:
                _name = season_name.lower()
                if input_name == _name or any(
                    [n.startswith(input_name) for n in _name.split(" ")]):
                    season = now.SEASONS.index(season_name)
                    break
            else:
                try:  # last try with a literal int being passed in
                    season = int(season)
                except ValueError:
                    raise ValueError("unknown season: {}".format(season))
                else:
                    if not 1 <= season <= 5:
                        raise ValueError("season must be in 1..5")
                    season -= 1  # allowing cardinal numbers from the user

    if year is None:
        year = moved_year or now.year
    elif year.lower() == "next":
        year = (moved_year or now.year) + 1
    else:
        for symbol, oper in zip(("+", "-"), (operator.add, operator.sub)):
            if symbol in year:
                year = oper(moved_year or now.year, int(year.strip(symbol)))
                break
        else:
            try:
                year = int(year)
            except ValueError:
                raise ValueError("invalid year: {}".format(year))

    if not MINYEAR <= year <= MAXYEAR:
        # otherwise this error isn't that helpful
        raise ValueError("year must be in {}..{}".format(MINYEAR, MAXYEAR))

    if now.day_of_season is None:
        if is_leap_year(year - 1166):
            day_of_season = None
        else:
            day_of_season = 59
        season = season or 0
    else:
        day_of_season = now.day_of_season

    if day_of_season:
        cal_date = DDate(year=year, season=season, day_of_season=day_of_season)
        cal = MultiCalendar(discordian=True, date=cal_date)
        cal.print_calendar()
    else:
        print("{} in YOLD {}".format(now.holiday, year))