Пример #1
0
def convert_date(raw_date: str) -> tuple:
    def _get_datetime_range(date: str) -> tuple:
        """ Makes one day period by received date.

        Parameters
        ----------
        date:
            Date for report generating.

        Returns
        -------
            Datetime range.
        """
        date = datetime.strptime(date, "%Y-%m-%d")
        from_date = date.astimezone(utc)
        from_date = from_date.strftime("%Y-%m-%dT%H:%M:%S.%f%z")

        to_date = (date.replace(
            hour=23, minute=59,
            second=59).astimezone(utc).strftime("%Y-%m-%dT%H:%M:%S.%f%z"))

        return from_date, to_date

    parser = Calendar()
    date, status = parser.parse(raw_date)
    date = datetime(*date[:3]).strftime("%Y-%m-%d")
    return _get_datetime_range(date)
Пример #2
0
class Reminders(commands.Cog):
    """Set reminders."""

    def __init__(self, bot: Bot):
        self.bot = bot
        self.cal = Calendar()
        self.remind_loop.start()

    @commands.command(name="remind", aliases=["remindme"])
    async def remind(self, ctx: Context, t: str, *, message: str):
        """Set a reminder."""

        parsed, success = self.cal.parse(t)

        if not success:
            return await ctx.reply("Please use a valid time string, such as 3d6h.")

        time = mktime(parsed)
        dt = datetime.fromtimestamp(time)

        td = dt - datetime.utcnow()
        total_diff = td.total_seconds()

        if total_diff < 5:
            return await ctx.reply("I can't create reminders less than 5 seconds in the future!")

        id = await self.bot.db.create_reminder(ctx.author.id, ctx.guild.id, ctx.channel.id, ctx.message.id, dt, message)

        await ctx.reply(f"Reminder created with ID {id} set to remind you at <t:{int(dt.timestamp())}:F>.")

    @tasks.loop(seconds=10)
    async def remind_loop(self):
        await self.bot.wait_until_ready()

        rs = await self.bot.db.get_expired_reminders()

        for reminder in rs:
            if reminder["expires"] > datetime.now():
                continue
            logger.info(f"Actioning reminder ID {reminder['id']} from {reminder['userid']}")
            await self.bot.db.mark_reminder_completed(reminder["id"])

            channel = self.bot.get_channel(reminder["cid"])
            if not channel:
                continue

            jump = f"https://discord.com/channels/{reminder['gid']}/{reminder['cid']}/{reminder['mid']}"

            await channel.send(
                f"<@{reminder['userid']}> reminder:\n{reminder['content']}\n\nOriginal message: {jump}",
                allowed_mentions=AllowedMentions(users=True),
            )
Пример #3
0
 def parse(self, response):
     # follow links to offer pages
     offers = response.xpath("//a[@class='href-link tile-title-text']")
     for offer in offers:
         yield response.follow(url=offer.attrib['href'],
                               callback=self.parse_offer)
     # follow pagination link
     tmp_1 = response.xpath(
         "//a[@class='arrows icon-angle-right-gray icon-right-arrow']")
     tmp_2 = response.xpath(
         "//a[@class='arrows icon-right-arrow icon-angle-right-gray']")
     next_page = tmp_1 if 'href' in tmp_1.attrib else tmp_2
     offer_date = response.xpath("//div[@class='creation-date']")
     parsed_date = extract_date(offer_date[len(offer_date) - 1].get())
     gumtree_req = GumtreeRequirements(req)
     cal = Calendar()
     date = cal.parse(parsed_date)
     required_date = cal.parse(' '.join(
         [str(gumtree_req.number_of_days), 'days ago']))
     if date < required_date:
         return
     yield response.follow(next_page.attrib['href'], self.parse)
Пример #4
0
 def parse_offer(self, response):
     """Extracts the details of the offer to search through."""
     unprocessed_date = response.css(
         '#wrapper > div:nth-child(1) > div.vip-header-and-details > div.vip-details'
         ' > ul > li:nth-child(1) > div > span.value').get()
     (_, unprocessed_date, _) = unprocessed_date.split('>')
     (processed_date, _) = unprocessed_date.split('<')
     gumtree_req = GumtreeRequirements(req)
     cal = Calendar()
     offer_submission_date = cal.parse(processed_date)
     required_date = cal.parse(' '.join(
         [str(gumtree_req.number_of_days), 'days ago']))
     if offer_submission_date < required_date:
         return
     spans = response.xpath("//span[@class='value']").getall()
     spans_text = get_processed_text(spans)
     p = response.xpath("//span[@class='pre']").getall()
     p_text = get_processed_text(p)
     text = ' '.join([spans_text, p_text])
     if calculate_intersection(text,
                               gumtree_req.tags) >= gumtree_req.threshold:
         append_to_file(path='scrapy-data/urls.txt', response=response)
Пример #5
0
 def parse_offer(self, response):
     """Extracts the details of the offer to search through."""
     # Extract date of offer submission
     # We don't want an offer which is too old
     unprocessed_date = response.xpath("//div[@class='css-lh1bxu']").get()
     (_, _, unprocessed_date) = unprocessed_date.partition(':')
     (processed_date, _, _) = unprocessed_date.partition('<')
     cal = Calendar()
     offer_submission_date = cal.parse(processed_date)
     otodom_req = OtodomRequirements(req)
     required_date = cal.parse(' '.join(
         [str(otodom_req.number_of_days), 'days ago']))
     if offer_submission_date < required_date:
         return
     li = response.xpath("//li/text()").getall()
     li_text = get_processed_text(li)
     p = response.xpath("//p/text()").getall()
     p_text = get_processed_text(p)
     text = ' '.join([li_text, p_text])
     if calculate_intersection(text,
                               otodom_req.tags) >= otodom_req.threshold:
         append_to_file(path='scrapy-data/urls.txt', response=response)
Пример #6
0
    def parse(self, response):
        # follow links to offer pages
        offers = response.xpath('//a[@data-cy="listing-ad-title"]')
        for offer in offers:
            yield response.follow(url=offer.attrib['href'], callback=self.parse_offer)

        latest_date = response.xpath('//small//span//i[@data-icon="clock"]/../text()').getall().pop()
        olx_req = OlxRequirements(req)
        cal = Calendar()
        required_date = cal.parse(' '.join([str(olx_req.number_of_days), 'days ago']))[0]
        parsed_date = latest_date.replace('\n', '').replace('\t', '')
        latest_date_processed = olx_convert_to_time_struct(parsed_date)
        if latest_date_processed < required_date:
            return
        yield response.follow(url=response.xpath('//a[@data-cy="page-link-next"]').attrib['href'], callback=self.parse)
Пример #7
0
 def clean(self, value):
     """
     Validates that the input can be converted to a time. Returns a Python
     datetime.time object.
     """
     super(NaturalTimeField, self).clean(value)
     if value in EMPTY_VALUES:
         return None
     if isinstance(value, datetime.time):
         return value
     
     c = Calendar()
     parsed = c.parse(value)
     if parsed[1] == 2:
         return datetime.time(*parsed[0][3:6])
     raise ValidationError(self.error_messages['invalid'])
Пример #8
0
def str_to_datetime(string, on_fail_return=None):
    try:
        from dateutil import parser as p
        output = p.parse(string)
        return output
    except:
        from parsedatetime import Calendar
        from datetime import datetime
        c = Calendar()
        output, flags = c.parse(string)
        if flags > 0:
            return datetime(*output[:6])
        else:
            return None

    return None
    def clean(self, value):
        """
        Validates that the input can be converted to a time. Returns a Python
        datetime.time object.
        """
        super(NaturalTimeField, self).clean(value)
        if value in EMPTY_VALUES:
            return None
        if isinstance(value, datetime.time):
            return value

        c = Calendar()
        parsed = c.parse(value)
        if parsed[1] == 2:
            return datetime.time(*parsed[0][3:6])
        raise ValidationError(self.error_messages['invalid'])
Пример #10
0
def str_to_datetime(string, on_fail_return=None):
    try:
        from dateutil import parser as p

        output = p.parse(string)
        return output
    except:
        from parsedatetime import Calendar
        from datetime import datetime

        c = Calendar()
        output, flags = c.parse(string)
        if flags > 0:
            return datetime(*output[:6])
        else:
            return None

    return None
Пример #11
0
def test_olx_convert_to_time_struct_valid_case():
    test_input = {
        'dzisiaj 13:48': 'today 13:48',
        'wczoraj 13:48': 'yesterday 13:48',
        '16 sty': '16 january',
        '16 wrz': '16 september',
        '16 lut': '16 february',
        '16 mar': '16 march',
        '16 kwi': '16 april',
        '16 maj': '16 may',
        '16 cze': '16 june',
        '16 lip': '16 july',
        '16 sie': '16 august',
        '16 paź': '16 october',
        '16 lis': '16 november',
        '16 gru': '16 december',
    }
    cal = Calendar()
    for k, v in test_input.items():
        assert olx_convert_to_time_struct(k) == cal.parse(v)[0]
Пример #12
0
def olx_convert_to_time_struct(date_str):
    olx_date_mapper = {
        'dzisiaj': 'today',
        'wczoraj': 'yesterday',
        'sty': 'january',
        'wrz': 'september',
        'lut': 'february',
        'mar': 'march',
        'kwi': 'april',
        'maj': 'may',
        'cze': 'june',
        'lip': 'july',
        'sie': 'august',
        'paź': 'october',
        'lis': 'november',
        'gru': 'december',
    }
    for k, v in olx_date_mapper.items():
        date_str = date_str.replace(k, v)
    cal = Calendar()
    return cal.parse(date_str)[0]
Пример #13
0
def parse_time(
    time_str: str,
    seconds: int = True
) -> typing.Union[None, int, typing.Tuple[datetime.datetime, int]]:
    """
    Parses a time.

    :param time_str: The time string to parse.
    :return: The total number of seconds between now and then.
    """
    calendar = Calendar()
    t_struct, parse_status = calendar.parse(
        time_str, sourceTime=datetime.datetime.utcnow())

    if parse_status == 0:
        return None

    dt = datetime.datetime(*t_struct[:6])

    diff = np.ceil((dt - datetime.datetime.utcnow()).total_seconds())
    if seconds:
        return diff
    else:
        return dt, diff
Пример #14
0
    def parse(self, response):
        # follow links to offer pages
        offers = response.xpath("//a[@class='property_link property-url']")
        for offer in offers:
            yield response.follow(url=offer.attrib['href'], callback=self.parse_offer)

        latest_date = response.xpath("//span[@class='single-result__category single-result__category--date']")\
                              .getall()\
                              .pop()
        # the strong word appears in the rag when the date is in bold (and it's only bold when the offer has just been
        # added, hence there is no sense in finding out whether is't an old offer
        if 'strong' not in latest_date:
            morizon_req = MorizonRequirements(req)
            cal = Calendar()
            required_date = cal.parse(' '.join([str(morizon_req.number_of_days), 'days ago']))
            parsed_date = extract_from_tag(latest_date)
            latest_date_processed = morizon_convert_to_time_struct(parsed_date)
            if latest_date_processed < required_date:
                return
        yield response.follow(
            url=response.xpath("//a[@class='mz-pagination-number__btn mz-pagination-number__btn--next']")
                        .pop()
                        .attrib['href'],
            callback=self.parse)
Пример #15
0
 def clean(self, value):
     """
     Validates that the input can be converted to a datetime. Returns a
     Python datetime.datetime object.
     """
     super(NaturalDateTimeField, self).clean(value)
     if value in EMPTY_VALUES:
         return None
     if isinstance(value, datetime.datetime):
         return value
     if isinstance(value, datetime.date):
         return datetime.datetime(value.year, value.month, value.day)
     if isinstance(value, list):
         # Input comes from a SplitDateTimeWidget, for example. So, it's two
         # components: date and time.
         if len(value) != 2:
             raise ValidationError(self.error_messages['invalid'])
         value = '%s %s' % tuple(value)
     
     c = Calendar()
     parsed = c.parse(value)
     if parsed[1] == 3:
         return datetime.date(*parsed[0][:6])
     raise ValidationError(self.error_messages['invalid'])
    def clean(self, value):
        """
        Validates that the input can be converted to a datetime. Returns a
        Python datetime.datetime object.
        """
        super(NaturalDateTimeField, self).clean(value)
        if value in EMPTY_VALUES:
            return None
        if isinstance(value, datetime.datetime):
            return value
        if isinstance(value, datetime.date):
            return datetime.datetime(value.year, value.month, value.day)
        if isinstance(value, list):
            # Input comes from a SplitDateTimeWidget, for example. So, it's two
            # components: date and time.
            if len(value) != 2:
                raise ValidationError(self.error_messages['invalid'])
            value = '%s %s' % tuple(value)

        c = Calendar()
        parsed = c.parse(value)
        if parsed[1] == 3:
            return datetime.date(*parsed[0][:6])
        raise ValidationError(self.error_messages['invalid'])
Пример #17
0
    soup = get_page2()
    scripts = soup.find_all('script')
    scores_script = [x.renderContents() for x in scripts if 'myScores' in x.renderContents()][0]
    matches = re.search('.+(\[.+?\]).+', scores_script).groups()[0]
    my_scores = json.loads(matches)

    scores = []
    parser = Calendar()
    for mys in my_scores:
        if not mys['DataReceived'] == 'has-data':
            continue
        date = datetime.datetime.fromtimestamp(
            time.mktime(
                parser.parse(
                    '{} {}'.format(mys['ChartDate'], datetime.datetime.now().year)
                )[0]
            )
        )
        date = date.replace(hour=0, minute=0, second=0)
        output = {
            'date': date.isoformat(),
            'events': float(mys['Events']),
            'events_score': float(mys['EventsScore']),
            'leak': float(mys['Leak']),
            'leak_score': float(mys['LeakScore']),
            'mask': float(mys['Mask']),
            'mask_score': float(mys['MaskScore']),
            'usage': mys['UsageDisplay'],
            'usage_hours': float(mys['Usage']) if mys['Usage'] else 0,
            'score': float(mys['Score'])
Пример #18
0
def execute(pagename, request, fieldname='value', titlesearch=0, statistic=0):
    _ = request.getText
    titlesearch = checkTitleSearch(request)
    if titlesearch < 0:
        check_surge_protect(request, kick=True)  # get rid of spammer
        return

    advancedsearch = isAdvancedSearch(request)

    form = request.values

    # context is relevant only for full search
    if titlesearch:
        context = 0
    elif advancedsearch:
        context = 180  # XXX: hardcoded context count for advancedsearch
    else:
        context = int(form.get('context', 0))

    # Get other form parameters
    needle = form.get(fieldname, '')
    case = int(form.get('case', 0))
    regex = int(form.get('regex', 0))  # no interface currently
    hitsFrom = int(form.get('from', 0))
    highlight_titles = int(form.get('highlight_titles', 1))
    highlight_pages = int(form.get('highlight_pages', 1))
    mtime = None
    msg = ''
    historysearch = 0

    # if advanced search is enabled we construct our own search query
    if advancedsearch:
        and_terms = form.get('and_terms', '').strip()
        or_terms = form.get('or_terms', '').strip()
        not_terms = form.get('not_terms', '').strip()
        #xor_terms = form.get('xor_terms', '').strip()
        categories = form.getlist('categories') or ['']
        timeframe = form.get('time', '').strip()
        language = form.getlist('language') or ['']
        mimetype = form.getlist('mimetype') or [0]
        excludeunderlay = form.get('excludeunderlay', 0)
        nosystemitems = form.get('nosystemitems', 0)
        historysearch = form.get('historysearch', 0)

        mtime = form.get('mtime', '')
        if mtime:
            mtime_parsed = None

            # get mtime from known date/time formats
            for fmt in (request.user.datetime_fmt, request.cfg.datetime_fmt,
                        request.user.date_fmt, request.cfg.date_fmt):
                try:
                    mtime_parsed = time.strptime(mtime, fmt)
                except ValueError:
                    continue
                else:
                    break

            if mtime_parsed:
                mtime = time.mktime(mtime_parsed)
            else:
                # didn't work, let's try parsedatetime
                cal = Calendar()
                mtime_parsed, parsed_what = cal.parse(mtime)
                # XXX it is unclear if usage of localtime here and in parsedatetime module is correct.
                # time.localtime is the SERVER's local time and of no relevance to the user (being
                # somewhere in the world)
                # mktime is reverse function for localtime, so this maybe fixes it again!?
                if parsed_what > 0 and mtime_parsed <= time.localtime():
                    mtime = time.mktime(mtime_parsed)
                else:
                    mtime_parsed = None  # we don't use invalid stuff

            # show info
            if mtime_parsed:
                # XXX mtime_msg is not shown in some cases
                mtime_msg = _(
                    "(!) Only pages changed since '''%s''' are being displayed!",
                    wiki=True) % request.user.getFormattedDateTime(mtime)
            else:
                mtime_msg = _(
                    '/!\\ The modification date you entered was not '
                    'recognized and is therefore not considered for the '
                    'search results!',
                    wiki=True)
        else:
            mtime_msg = None

        word_re = re.compile(r'(\"[\w\s]+"|\w+)', re.UNICODE)
        needle = ''
        if categories[0]:
            needle += 'category:%s ' % ','.join(categories)
        if language[0]:
            needle += 'language:%s ' % ','.join(language)
        if mimetype[0]:
            needle += 'mimetype:%s ' % ','.join(mimetype)
        if excludeunderlay:
            needle += '-domain:underlay '
        if nosystemitems:
            needle += '-domain:system '
        if and_terms:
            needle += '(%s) ' % and_terms
        if not_terms:
            needle += '(%s) ' % ' '.join(
                ['-%s' % t for t in word_re.findall(not_terms)])
        if or_terms:
            needle += '(%s) ' % ' or '.join(word_re.findall(or_terms))

    # check for sensible search term
    stripped = needle.strip()
    if len(stripped) == 0:
        request.theme.add_msg(
            _(
                'Please use a more selective search term instead '
                'of {{{"%s"}}}',
                wiki=True) % wikiutil.escape(needle), "error")
        Page(request, pagename).send_page()
        return
    needle = stripped

    # Setup for type of search
    if titlesearch:
        title = _('Title Search: "%s"')
        sort = 'page_name'
    else:
        if advancedsearch:
            title = _('Advanced Search: "%s"')
        else:
            title = _('Full Text Search: "%s"')
        sort = 'weight'

    # search the pages
    from MoinMoin.search import searchPages, QueryParser, QueryError
    try:
        query = QueryParser(case=case, regex=regex,
                            titlesearch=titlesearch).parse_query(needle)
    except QueryError:  # catch errors in the search query
        request.theme.add_msg(
            _(
                'Your search query {{{"%s"}}} is invalid. Please refer to '
                'HelpOnSearching for more information.',
                wiki=True,
                percent=True) % wikiutil.escape(needle), "error")
        Page(request, pagename).send_page()
        return

    results = searchPages(request, query, sort, mtime, historysearch)

    # directly show a single hit for title searches
    # this is the "quick jump" functionality if you don't remember
    # the pagename exactly, but just some parts of it
    if titlesearch and len(results.hits) == 1:
        page = results.hits[0]
        if not page.attachment:  # we did not find an attachment
            page = Page(request, page.page_name)
            querydict = {}
            if highlight_pages:
                highlight = query.highlight_re()
                if highlight:
                    querydict.update({'highlight': highlight})
            url = page.url(request, querystr=querydict)
            request.http_redirect(url)
            return
    if not results.hits:  # no hits?
        f = request.formatter
        querydict = wikiutil.parseQueryString(request.query_string).to_dict()
        querydict.update({'titlesearch': 0})

        request.theme.add_msg(
            _(
                'Your search query {{{"%s"}}} didn\'t return any results. '
                'Please change some terms and refer to HelpOnSearching for '
                'more information.%s',
                wiki=True,
                percent=True) %
            (wikiutil.escape(needle), titlesearch and ''.join([
                '<br>',
                _('(!) Consider performing a', wiki=True),
                ' ',
                f.url(1, href=request.page.url(request, querydict, escape=0)),
                _('full-text search with your search terms'),
                f.url(0),
                '.',
            ]) or ''), "error")
        Page(request, pagename).send_page()
        return

    # This action generates data using the user language
    request.setContentLanguage(request.lang)

    request.theme.send_title(title % needle, pagename=pagename)

    # Start content (important for RTL support)
    request.write(request.formatter.startContent("content"))

    # Hints
    f = request.formatter
    hints = []

    if titlesearch:
        querydict = wikiutil.parseQueryString(request.query_string).to_dict()
        querydict.update({'titlesearch': 0})

        hints.append(''.join([
            _(
                "(!) You're performing a title search that might not include"
                ' all related results of your search query in this wiki. <<BR>>',
                wiki=True),
            ' ',
            f.url(1, href=request.page.url(request, querydict, escape=0)),
            f.text(
                _('Click here to perform a full-text search with your '
                  'search terms!')),
            f.url(0),
        ]))

    if advancedsearch and mtime_msg:
        hints.append(mtime_msg)

    if hints:
        request.write(searchHints(f, hints))

    # Search stats
    request.write(results.stats(request, request.formatter, hitsFrom))

    # Then search results
    info = not titlesearch
    if context:
        output = results.pageListWithContext(request,
                                             request.formatter,
                                             info=info,
                                             context=context,
                                             hitsFrom=hitsFrom,
                                             hitsInfo=1,
                                             highlight_titles=highlight_titles,
                                             highlight_pages=highlight_pages)
    else:
        output = results.pageList(request,
                                  request.formatter,
                                  info=info,
                                  hitsFrom=hitsFrom,
                                  hitsInfo=1,
                                  highlight_titles=highlight_titles,
                                  highlight_pages=highlight_pages)

    request.write(output)

    request.write(request.formatter.endContent())
    request.theme.send_footer(pagename)
    request.theme.send_closing_html()
Пример #19
0
def morizon_convert_to_time_struct(date_str):
    morizon_date_mapper = {'dzisiaj': 'today', 'wczoraj': 'yesterday'}
    cal = Calendar()
    date_str = morizon_date_mapper[
        date_str] if date_str in morizon_date_mapper else date_str
    return cal.parse(date_str)[0]
Пример #20
0
def human_time_to_datetime(s):
    cal = Calendar()
    t, _ = cal.parse(s)
    return datetime(*t[:6])
Пример #21
0
def fuzzydtparse(request):
    """
    Attempts to parse a natural-language date/time string and return a
    formatted representation of the parsed date/time.
    
    The returned representations are formatted using django's php-style
    datetime formatting facilities. See
    http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now for a
    full specification
    
    GET/POST arguments:
    dtstring *(required)*
        The natural-language date and/or time string to parse.
    
    dateformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a date instance. The default format is
        'l, F jS Y', which produces values like 'Thursday, October 1st 2009'.
    
    timeformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a time instance. The default format is
        'P', which produces values like '6:26 p.m.'.
    
    dtformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a datetime instance. The default format is
        'l, F jS Y, P', which produces values like
        'Thursday, October 1st 2009, 6:26 p.m.'.
    
    require (optional)
        One of 'date', 'time', 'datetime'. If the parsed value is not of the
        specified type, the view will return 400/Bad Request
    
    callback (optional)
        JSONP callback.
    
    Returns a json dictionary containing two values:
    type
        An string indicating the kind of representation returned.
        One of 'date', 'time', or 'datetime'
    
    parsed
        A string representation of the parsed datetime.
        
    Invalid / unparsable datetimes will return 400/Bad Request.
    
    """
    try:
        dtstring = request.REQUEST['dtstring']
    except KeyError:
        return HttpResponseBadRequest()

    
    kind = {
        'date': 1,
        'time': 2,
        'datetime': 3
    }
    
    dateformat = request.REQUEST.get('dateformat', 'l, F jS Y' )
    timeformat = request.REQUEST.get('timeformat', 'P')
    dtformat = request.REQUEST.get('dtformat', 'l, F jS Y, P')
    require = request.REQUEST.get('require', None)
    callback = request.REQUEST.get('callback', None)
    
    if require and require not in kind:
        return HttpResponseBadRequest()
        
    c = Calendar()

    # TODO: possible security hole?
    parsed = c.parse(dtstring)
    if parsed[1] == 0:
        return HttpResponseBadRequest()
    parsed_dt = datetime.datetime(*parsed[0][:6])
    response_dict = {}
    if require and parsed[1] != kind[require]:
        return HttpResponseBadRequest()
    try:
        if parsed[1] == 1:
            response_dict['type'] = 'date'
            response_dict['parsed'] = format(parsed_dt, dateformat)
        elif parsed[1] == 2:
            response_dict['type'] = 'time'
            response_dict['parsed'] = format(parsed_dt, timeformat)
        elif parsed[1] == 3:
            response_dict['type'] = 'datetime'
            response_dict['parsed'] = format(parsed_dt, dtformat)
        else:
            #should never be here
            return HttpResponseBadRequest()
    except:
        return HttpResponseBadRequest()
    
    if callback:
        resp = "%s(%s)" % (callback, json.dumps(response_dict))
    else:
        resp = json.dumps(response_dict)
    return HttpResponse(resp, mimetype='application/javascript')
Пример #22
0
def parse_message(text):
    c = Calendar()
    t_s, p_s = c.parse(text)
    time = datetime(*t_s[:6])
    td = time - datetime.now()
    return None if td.days < 0 else td.total_seconds()
Пример #23
0
    print("relative time (for example, '5 minutes' or 'tomorrow') or an")
    print("actual time (for example, '8am').")
    if error is not None:
        print("\n\n")
        print (error)
    sys.exit(1)

if len(sys.argv) == 1:
    helptext()

from parsedatetime import Calendar
from time import mktime, sleep
from datetime import datetime, timedelta

p = Calendar()
specifiedtime = p.parse(" ".join(sys.argv[1:]))
timeleft = datetime.fromtimestamp(mktime(specifiedtime[0])) - datetime.now()

length = 0

while timeleft > timedelta(microseconds=-1):
    interval = 10
    if timeleft < timedelta(hours=1):
        interval = 1
    if timeleft < timedelta(minutes=10):
        interval = 0.1
    if timeleft < timedelta(minutes=1):
        interval = 0.001
    sys.stdout.write("\b" * length)
    outline = str(timeleft)
    length = len(outline)
Пример #24
0
    print("actual time (for example, '8am').")
    if error is not None:
        print("\n\n")
        print(error)
    sys.exit(1)


if len(sys.argv) == 1:
    helptext()

from parsedatetime import Calendar
from time import mktime, sleep
from datetime import datetime, timedelta

p = Calendar()
specifiedtime = p.parse(" ".join(sys.argv[1:]))
timeleft = datetime.fromtimestamp(mktime(specifiedtime[0])) - datetime.now()

length = 0

while timeleft > timedelta(microseconds=-1):
    interval = 10
    if timeleft < timedelta(hours=1):
        interval = 1
    if timeleft < timedelta(minutes=10):
        interval = 0.1
    if timeleft < timedelta(minutes=1):
        interval = 0.001
    sys.stdout.write("\b" * length)
    outline = str(timeleft)
    length = len(outline)
Пример #25
0
def fuzzydtparse(request):
    """
    Attempts to parse a natural-language date/time string and return a
    formatted representation of the parsed date/time.
    
    The returned representations are formatted using django's php-style
    datetime formatting facilities. See
    http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now for a
    full specification
    
    GET/POST arguments:
    dtstring *(required)*
        The natural-language date and/or time string to parse.
    
    dateformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a date instance. The default format is
        'l, F jS Y', which produces values like 'Thursday, October 1st 2009'.
    
    timeformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a time instance. The default format is
        'P', which produces values like '6:26 p.m.'.
    
    dtformat (optional)
        A format specifier string used to format the returned representation
        if it is determined to be a datetime instance. The default format is
        'l, F jS Y, P', which produces values like
        'Thursday, October 1st 2009, 6:26 p.m.'.
    
    require (optional)
        One of 'date', 'time', 'datetime'. If the parsed value is not of the
        specified type, the view will return 400/Bad Request
    
    callback (optional)
        JSONP callback.
    
    Returns a json dictionary containing two values:
    type
        An string indicating the kind of representation returned.
        One of 'date', 'time', or 'datetime'
    
    parsed
        A string representation of the parsed datetime.
        
    Invalid / unparsable datetimes will return 400/Bad Request.
    
    """
    try:
        dtstring = request.REQUEST['dtstring']
    except KeyError:
        return HttpResponseBadRequest()

    kind = {'date': 1, 'time': 2, 'datetime': 3}

    dateformat = request.REQUEST.get('dateformat', 'l, F jS Y')
    timeformat = request.REQUEST.get('timeformat', 'P')
    dtformat = request.REQUEST.get('dtformat', 'l, F jS Y, P')
    require = request.REQUEST.get('require', None)
    callback = request.REQUEST.get('callback', None)

    if require and require not in kind:
        return HttpResponseBadRequest()

    c = Calendar()

    # TODO: possible security hole?
    parsed = c.parse(dtstring)
    if parsed[1] == 0:
        return HttpResponseBadRequest()
    parsed_dt = datetime.datetime(*parsed[0][:6])
    response_dict = {}
    if require and parsed[1] != kind[require]:
        return HttpResponseBadRequest()
    try:
        if parsed[1] == 1:
            response_dict['type'] = 'date'
            response_dict['parsed'] = format(parsed_dt, dateformat)
        elif parsed[1] == 2:
            response_dict['type'] = 'time'
            response_dict['parsed'] = format(parsed_dt, timeformat)
        elif parsed[1] == 3:
            response_dict['type'] = 'datetime'
            response_dict['parsed'] = format(parsed_dt, dtformat)
        else:
            #should never be here
            return HttpResponseBadRequest()
    except:
        return HttpResponseBadRequest()

    if callback:
        resp = "%s(%s)" % (callback, json.dumps(response_dict))
    else:
        resp = json.dumps(response_dict)
    return HttpResponse(resp, mimetype='application/javascript')
Пример #26
0
    def __init__(self):
        self.parser.add_argument('-s',
                                 '--status',
                                 action='store_true',
                                 help='show rule list with expirations')
        self.parser.add_argument('-c',
                                 '--clean',
                                 action='store_true',
                                 help='clean up expired rules')
        self.parser.add_argument('-r',
                                 '--rule',
                                 help='rule to be added to `ufw`')
        self.parser.add_argument('-p',
                                 '--position',
                                 default=1,
                                 help='position to add the rule')
        self.parser.add_argument('-t',
                                 '--ttl',
                                 default='30 days',
                                 help='time to live for the rule')
        args = self.parser.parse_args()

        # Our file names
        pid_file = '/var/run/' + __file__ + '.pid'
        rules_file = '/usr/local/share/' + __file__ + '/rules'
        tmp_rules_file = '/tmp/' + __file__ + '-rules'

        if args.status:
            if path.exists(rules_file):
                try:
                    print("Expiration\t\tRule")
                    print('=' * 80)

                    # Loops through the rules lines
                    for line in open(rules_file, 'r'):
                        # Breaks apart line into expiration timestamp and rule
                        timestamp, rule = line.strip("\n").split(' ', 1)

                        print(
                            str(datetime.fromtimestamp(float(timestamp))) +
                            "\t" + rule)
                except IOError:
                    self.error('unable to read from the rules file: ' +
                               rules_file)
            else:
                self.error('there are no rules to display')
        elif args.clean:
            # Checks for PID file
            if path.exists(pid_file):
                self.error(__file__ + ' is already running')
            else:
                # Creates the PID file
                try:
                    handle = open(pid_file, 'w')
                    handle.write(str(getpid()))
                    handle.close()
                except IOError:
                    self.error('unable to create PID file: ' + pid_file)

                # Checks for the rules file
                if path.exists(rules_file):
                    # Opens the temporary rules file
                    try:
                        handle = open(tmp_rules_file, 'a')
                    except IOError:
                        self.error('unable to write to the tmp rules file: ' +
                                   tmp_rules_file)

                    try:
                        current_time = time()

                        # Loops through the rules lines
                        for line in open(rules_file, 'r'):
                            # Breaks apart line into expiration timestamp and rule
                            timestamp, rule = line.strip("\n").split(' ', 1)

                            # Checks if rule has expired
                            if current_time < float(timestamp):
                                handle.write(line)
                                print(
                                    str(datetime.fromtimestamp(time())) +
                                    "\tskipped rule\t" + rule)
                            else:
                                try:
                                    self.ufw_execute('delete ' + rule)
                                    print(
                                        str(datetime.fromtimestamp(time())) +
                                        "\tdeleted rule\t" + rule)
                                except CalledProcessError as error:
                                    self.ufw_error(error)

                        handle.close()

                        # Moves the tmp file to the rules file
                        move(tmp_rules_file, rules_file)
                    except IOError:
                        self.error('unable to from the read rules file: ' +
                                   rules_file)

                # Removes the PID
                remove(pid_file)
        elif args.rule:
            rules_path = path.dirname(rules_file)

            if not path.exists(rules_path):
                makedirs(rules_path)

            # Converts the TTL to a timestamp
            cal = Calendar()
            timestamp = mktime(cal.parse(args.ttl)[0])

            # Writes the rule to the rules file
            try:
                # TODO Check if rule already exists and update it instead of adding it again
                handle = open(rules_file, 'a')
                handle.write(str(timestamp) + ' ' + args.rule)
                handle.write("\n")
                handle.close()
            except IOError:
                self.error('unable to write to the rules file: ' + rules_file)

            # Attempts to add the rule to `ufw`
            try:
                self.ufw_execute('insert ' + str(args.position) + ' ' +
                                 args.rule)
            except CalledProcessError as error:
                # Catches an error when attempting to add a rule to an empty database
                if error.output == b"ERROR: Invalid position '1'\n":
                    try:
                        self.ufw_execute(args.rule)
                    except CalledProcessError as error:
                        self.ufw_error(error)
                else:
                    self.ufw_error(error)
        else:
            self.error('no arguments specified')
Пример #27
0
def str_ftime(arg, format):
    cal = Calendar()
    return strftime(format, cal.parse(str(arg))[0])
Пример #28
0
class Giveaway(commands.Cog):

    def __init__(self, bot):
        self.bot = bot
        self.time_parser = Calendar()
        self.min_time = 5
        self.bold = re.compile(r'(\d+)')

    async def prompt(self, ctx, prompt: str):
        await ctx.send(prompt)

        def check(m):
            return m.channel.id == ctx.channel.id and m.author.id == ctx.author.id

        try:
            msg = await self.bot.wait_for('message', timeout=420, check=check)
        except asyncio.TimeoutError:
            embed = discord.Embed(
                title='Timeout',
                descripton='You took too long to respond to my prompt. '
                           'Please restart the command and try again.'
            )
            await ctx.send(embed=embed)
            return None
        return msg.content

    async def create_giveaway(self, ctx, prize, channel, total_time,
                              winners, desc, req_int, role_reqs, invite, req_text, emoji):
        ts = int(time.time() + total_time)
        final_req_text = ''
        req = req_text
        if req:
            final_req_text += req
        else:
            if role_reqs:
                if req_int:
                    req_text += '\U0001f4dd __Must have any of the following roles:__ '
                else:
                    req_text += '\U0001f4dd __Must have all of the following roles:__ '
                req_text += ', '.join(role.mention for role in role_reqs)
            if invite:
                req_text += f'\n\U0001f4dd __Must be in the server:__ ' \
                            f'[**{invite.guild.name}**]({invite})'
        final_req_text = final_req_text or 'No requirements'
        s = '' if winners == 1 else 's'

        embed = discord.Embed(
            title=prize,
            description=desc,
            color=discord.Colour.dark_orange(),
            timestamp=datetime.utcfromtimestamp(ts)
        ).add_field(
            name='\U0001f60e Requirements:',
            value=final_req_text,
            inline=False
        ).add_field(
            name='\u23f0 Ends In:',
            value=self.bold.sub(r'**\1**', precisedelta(total_time)),
            inline=False
        ).add_field(
            name='\U0001f451 Host:',
            value=ctx.author.mention,
            inline=False
        ).set_author(
            name='New Giveaway!',
            icon_url=self.bot.get_icon(ctx.guild)
        ).set_footer(
            text=str(winners) + f' Winner{s} | Ending at ->'
        )
        msg = await channel.send(embed=embed)
        await msg.add_reaction(emoji)

        role_ids = [role.id for role in role_reqs]

        query = '''INSERT INTO giveaways (
                   guild_id, 
                   channel_id,
                   message_id,
                   embed,
                   prize,
                   winners_num,
                   role_req,
                   role_req_type,
                   guild_req,
                   ends_at,
                   ended
                   )
                   VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
                '''
        ended = False if total_time > 30 else True
        dumped = json.dumps(msg.embeds[0].to_dict(), indent=4)
        values = (ctx.guild.id, channel.id, msg.id, dumped,
                  prize, winners, role_ids, req_int,
                  invite.guild.id if invite else None,
                  ts, ended)
        self.bot.message_ids.append(msg.id)
        await self.bot.db.execute(query, *values)

        ping = discord.utils.find(lambda r: 'giveaway ping' in r.name.lower(), ctx.guild.roles)
        if ping:
            msg = await channel.send(ping.mention)
            await msg.delete()

        if ctx.channel.id != channel.id:
            await ctx.send('Giveaway created!')

        if total_time < 30:
            await end(self.bot, ts, msg.id, channel.id, dumped)

    @commands.command(aliases=['create'])
    @is_giveaway_manager()
    async def giveaway(self, ctx):
        channel = await self.prompt(ctx, 'What channel is this giveaway in?')
        try:
            channel = await commands.TextChannelConverter().convert(ctx, channel)
        except commands.ChannelNotFound:
            return await ctx.send('Invalid channel.')

        prize = await self.prompt(ctx, 'What are you giving away?')
        if not prize:
            return

        winners = await self.prompt(ctx, 'How many winners will there be?')
        if not winners:
            return
        try:
            winners = int(winners)
        except ValueError:
            return await ctx.send('Invalid number.')
        if winners < 1:
            return await ctx.send('Must be greater than 1.')

        t = await self.prompt(ctx, 'How long will the giveaway last?')
        if not t:
            return
        parsed = self.time_parser.parse(t)
        ts = time.mktime(parsed[0])
        total = int(ts - time.time())
        if not total:
            return await ctx.send('Invalid time.')

        desc = await self.prompt(ctx, 'Enter a description for this giveaway (150 chars max) '
                                      'or type `skip`.')
        if not desc:
            return

        while len(desc) > 150:
            desc = await self.prompt(ctx, 'Not under 150 characters. Try again.')
            if not desc:
                return
        if desc.lower() == 'skip':
            desc = ''

        roles = await self.prompt(ctx, 'What are the role requirements to enter? '
                                       'Enter comma-separated role names/IDs/mentions. '
                                       'Type `skip` for no role requirements.')
        if not roles:
            return
        role_reqs = []
        req_int = 0
        if roles.lower() != 'skip':
            rc = commands.RoleConverter()
            roles = roles.replace(', ', ',').split(',')
            for role in roles:
                try:
                    role_reqs.append(await rc.convert(ctx, role))
                except commands.RoleNotFound as err:
                    return await ctx.send(f'`{err.argument}` is not a valid role. Try again.')
            req_type = await self.prompt(ctx, 'Does the user need **all** the roles to enter, '
                                              'or **any** of the roles to enter? '
                                              'Respond with `all` or `any`.')
            if not req_type:
                return
            if req_type.lower() == 'all':
                req_int = 0
            elif req_type.lower() == 'any':
                req_int = 1
            else:
                return await ctx.send('Not a valid option.')

        invite_obj = None
        invite = await self.prompt(ctx, 'What server does this user have to be in '
                                        'to enter the giveaway? Enter a **permanent '
                                        'invite link that has infinite uses** or type '
                                        '`skip`.')
        if not invite:
            return
        if invite.lower() != 'skip':
            ic = commands.InviteConverter()
            try:
                invite = await ic.convert(ctx, invite)
            except commands.BadInviteArgument:
                return await ctx.send(f'`{invite}` was not a valid invite.')

            if invite.max_uses or invite.max_age:
                return await ctx.send('The invite provided is not permanent '
                                      'and does not have infinite usage.')

            if isinstance(invite, discord.PartialInviteGuild):
                return await ctx.send('I am not in the server with that invite.')
            in_guild = invite.guild.get_member(ctx.author.id)
            if not in_guild:
                return await ctx.send('You must also be in that server to '
                                      'set it as a requirement.')
            invite_obj = invite

        req_text = await self.prompt(ctx, 'Enter a manual requirement text, '
                                          'or type `skip`.')
        if not req_text:
            return
        if req_text.lower() == 'skip':
            req_text = ''

        emoji = await self.prompt(ctx, 'Enter an emoji that will be reacted for entering, '
                                       'or type `skip` for the default :tada:')
        if not emoji:
            return
        if emoji.lower() == 'skip':
            emoji = '\U0001f389'
        else:
            try:
                emoji = await EmojiConverter().convert(ctx, emoji)
            except commands.EmojiNotFound:
                return await ctx.send(f'`{emoji}` was not a valid emoji. '
                                      "Make sure I am also in the emoji's server")

        await self.create_giveaway(ctx, prize, channel, total, winners, desc,
                                   req_int, role_reqs, invite_obj, req_text, emoji)
Пример #29
0
def str_ftime(arg, format):
    cal = Calendar()
    return strftime(format, cal.parse(str(arg))[0])
Пример #30
0
def convert_date(raw_date: str) -> str:
    parser = Calendar()
    date, status = parser.parse(raw_date)
    date = datetime(*date[:3])
    return date.strftime("%Y-%m-%d")