<commit_before>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from __future__ import division, print_function

import gevent.monkey
import gevent.queue
import gevent.pool
import gevent
import requests
import dateutil.parser
import timeit

from collections import OrderedDict
from bs4 import BeautifulSoup
from unidecode import unidecode
from decimal import Decimal
from fuzzywuzzy import fuzz
from armory.serialize import jsonify

from .conf import settings
from .utils import timed_function


class AvailabilityResults(object):
    def __init__(self):
        self.status = 'failed'
        self.errors = []
        self.results = None
        self.available = False


class DragonCon(object):
    site_url = 'http://www.dragoncon.org/'

    def __init__(self):
        self._log = settings.get_logger(__name__)
        self._site_main = None
        self._start = None
        self._end = None
        self._dates_selector = '.region-countdown > div > h2'

    def run(self):
        log = self._log
        try:
            dcstr = '{0}'.format(self.event_info())
            log.info(dcstr)
        except KeyboardInterrupt:
            pass
        except requests.exceptions.ConnectionError as e:
            log.debug('{0}'.format(e))
            log.error('connection error! now aborting!')
        log.info('dragoncon bot exiting\n')

    def monitor_room_availability(self):
        log = self._log
        for w in settings._warnings:
            log.info(w)
        gevent.monkey.patch_all()
        log.info('gevent monkey patching done')
        tasks = []
        try:
            host_hotels = ConHostHotels(
                self.start,
                self.end
            )
            log.debug('spawning host hotel runner')
            tasks.append(gevent.spawn(host_hotels))
            log.debug('waiting for tasks to complete')
            gevent.wait(tasks)
        except KeyboardInterrupt:
            gevent.killall(tasks)
        except requests.exceptions.ConnectionError as e:
            log.debug('{0}'.format(e))
            log.error('connection error! now aborting!')
            gevent.killall(tasks)
        log.info('dragoncon bot exiting\n')

    def get_room_availability(self):
        log = self._log
        log.debug('runonce check not implemented')

    @property
    def site_main(self):
        if self._site_main is None:
            try:
                r = requests.get('http://www.dragoncon.org/')
                self._site_main = BeautifulSoup(r.text, 'lxml')
            except:
                raise
        return self._site_main

    @property
    def start(self):
        if self._start is None:
            self._populate_dates()
        return self._start

    @property
    def end(self):
        if self._end is None:
            self._populate_dates()
        return self._end

    def _populate_dates(self):
        log = self._log
        domdate = self.site_main.body.select(self._dates_selector)
        domlen = len(domdate)
        if domlen != 1:
            errmsg = "incorrect number of objects ({0}) returned from '{1}'"
            raise ValueError(errmsg.format(domlen, self._dates_selector))
        dateinfo = unidecode(domdate[0].get_text())
        parts = [p.strip().replace(',', ' ') for p in dateinfo.split('-')]
        parts = [' '.join(p.split()) for p in parts]
        log.debug(parts)
        numparts = len(parts)
        if numparts != 2:
            errmsg = "incorrect number of dates detected: {0} from {1}"
            errmsg = errmsg.format(numparts, parts)
            log.error(errmsg)
            raise ValueError(errmsg)
        self._start = dateutil.parser.parse(parts[0]).date()
        self._end = dateutil.parser.parse(parts[1]).date()
        self._start = self._start.replace(year=self._end.year)
        log.info("start date: {0}".format(self._start))
        log.info("  end date: {0}".format(self._end))
        if settings.cache:
            # do caching things
            pass

    def event_info(self):
        info = OrderedDict()
        info['con'] = 'Dragon Con'
        info['url'] = self.site_url
        info['start'] = self.start
        info['end'] = self.end
        return '{0}'.format(jsonify(info))


class ConHostHotels(object):
    def __init__(self, start, end, interval=1):
        self._log = settings.get_logger(__name__)
        self._start = start
        self._end = end
        self.interval = interval

    def __call__(self):
        log = self._log
        hotels = []
        try:
            log.debug('spawning room availability monitors')
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'hyatt',
                self.hyatt_room_availability))
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'hilton',
                self.hilton_room_availability))
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'mariott',
                self.mariott_room_availability))
            log.debug('waiting for room availability monitoring to complete')
            gevent.wait(hotels)<commit_msg>Moved host hotel methods into DragonCon class<commit_after>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from __future__ import division, print_function

import gevent.monkey
import gevent.queue
import gevent.pool
import gevent
import requests
import dateutil.parser
import timeit

from collections import OrderedDict
from bs4 import BeautifulSoup
from unidecode import unidecode
from decimal import Decimal
from fuzzywuzzy import fuzz
from armory.serialize import jsonify

from .conf import settings
from .utils import timed_function


class AvailabilityResults(object):
    def __init__(self):
        self.status = 'failed'
        self.errors = []
        self.results = None
        self.available = False


class DragonCon(object):
    site_url = 'http://www.dragoncon.org/'

    def __init__(self):
        self._log = settings.get_logger(__name__)
        self._site_main = None
        self._start = None
        self._end = None
        self._dates_selector = '.region-countdown > div > h2'

    def run(self):
        log = self._log
        try:
            dcstr = '{0}'.format(self.event_info())
            log.info(dcstr)
        except KeyboardInterrupt:
            pass
        except requests.exceptions.ConnectionError as e:
            log.debug('{0}'.format(e))
            log.error('connection error! now aborting!')
        log.info('dragoncon bot exiting\n')

    def monitor_room_availability(self):
        log = self._log
        for w in settings._warnings:
            log.info(w)
        gevent.monkey.patch_all()
        log.info('gevent monkey patching done')
        tasks = []
        try:
            host_hotels = ConHostHotels(
                self.start,
                self.end
            )
            log.debug('spawning host hotel runner')
            tasks.append(gevent.spawn(host_hotels))
            log.debug('waiting for tasks to complete')
            gevent.wait(tasks)
        except KeyboardInterrupt:
            gevent.killall(tasks)
        except requests.exceptions.ConnectionError as e:
            log.debug('{0}'.format(e))
            log.error('connection error! now aborting!')
            gevent.killall(tasks)
        log.info('dragoncon bot exiting\n')

    def get_room_availability(self):
        log = self._log
        log.debug('runonce check not implemented')

    @property
    def site_main(self):
        if self._site_main is None:
            try:
                r = requests.get('http://www.dragoncon.org/')
                self._site_main = BeautifulSoup(r.text, 'lxml')
            except:
                raise
        return self._site_main

    @property
    def start(self):
        if self._start is None:
            self._populate_dates()
        return self._start

    @property
    def end(self):
        if self._end is None:
            self._populate_dates()
        return self._end

    def _populate_dates(self):
        log = self._log
        domdate = self.site_main.body.select(self._dates_selector)
        domlen = len(domdate)
        if domlen != 1:
            errmsg = "incorrect number of objects ({0}) returned from '{1}'"
            raise ValueError(errmsg.format(domlen, self._dates_selector))
        dateinfo = unidecode(domdate[0].get_text())
        parts = [p.strip().replace(',', ' ') for p in dateinfo.split('-')]
        parts = [' '.join(p.split()) for p in parts]
        log.debug(parts)
        numparts = len(parts)
        if numparts != 2:
            errmsg = "incorrect number of dates detected: {0} from {1}"
            errmsg = errmsg.format(numparts, parts)
            log.error(errmsg)
            raise ValueError(errmsg)
        self._start = dateutil.parser.parse(parts[0]).date()
        self._end = dateutil.parser.parse(parts[1]).date()
        self._start = self._start.replace(year=self._end.year)
        log.info("start date: {0}".format(self._start))
        log.info("  end date: {0}".format(self._end))
        if settings.cache:
            # do caching things
            pass

    def event_info(self):
        info = OrderedDict()
        info['con'] = 'Dragon Con'
        info['url'] = self.site_url
        info['start'] = self.start
        info['end'] = self.end
        return '{0}'.format(jsonify(info))

    def host_setup(self, start, end, interval=1):
        self._log = settings.get_logger(__name__)
        self._start = start
        self._end = end
        self.interval = interval

    def __call__(self):
        log = self._log
        hotels = []
        try:
            log.debug('spawning room availability monitors')
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'hyatt',
                self.hyatt_room_availability))
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'hilton',
                self.hilton_room_availability))
            hotels.append(gevent.spawn(
                self._monitor_rooms, 'mariott',
                self.mariott_room_availability))
            log.debug('waiting for room availability monitoring to complete')
            gevent.wait(hotels)
{'fraction_non_alphanumeric': 0.10516640866873066, 'fraction_numerical': 0.003676470588235294, 'mean_word_length': 2.0546690307328603, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7020752', 'n_tokens_mistral': 3012, 'n_tokens_neox': 2936, 'n_words': 685}