# Path: hac/data.py
# class ISite(object):
#     """Site template.
#     """
# 
#     def __init__(self, name=None, id=None, url=None, time_limit_ms=2000,
#                  memory_limit_kbyte=262144, source_limit_kbyte=64):
#         self.name = name
#         self.id = id
#         # 'url' member used to distinguish between different sites.
#         self.url = url
#         self.time_limit_ms = time_limit_ms
#         self.memory_limit_kbyte = memory_limit_kbyte
#         self.source_limit_kbyte = source_limit_kbyte
# 
#         self._info = None
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url', 'time_limit_ms', 'memory_limit_kbyte',
#                 'source_limit_kbyte']
# 
#     @abstractmethod
#     def match_contest(self, conf):
#         """Generates well formated URL of the contest according to user input.
#         """
#         pass
# 
#     @abstractmethod
#     def get_contest(self, url):
#         """Fetches data from the provided contest URL and generates contest
#         object.
#         """
#         pass
# 
#     @abstractmethod
#     def match_problems(self, conf):
#         """Generates list of well formated problem URLs according to user
#         input.
#         """
#         pass
# 
#     @abstractmethod
#     def get_problems(self, urls):
#         """Fetches data from the provided problem URLs and generates list of
#         problem objects.
#         """
#         pass
# 
# class Contest(object):
#     """Contest info container.
#     """
# 
#     def __init__(self, name=None, id=None, url=None):
#         self.name = name
#         self.id = id
#         self.url = url
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url']
# 
# class Problem(object):
#     """Problem info container.
#     """
# 
#     def __init__(self, name=None, id=None, url=None, time_limit_ms=2000,
#                  memory_limit_kbyte=262144, source_limit_kbyte=64, inputs=None,
#                  outputs=None):
#         self.name = name
#         self.id = id
#         self.url = url
#         self.time_limit_ms = time_limit_ms
#         self.memory_limit_kbyte = memory_limit_kbyte
#         self.source_limit_kbyte = source_limit_kbyte
#         self.inputs = inputs or []
#         self.outputs = outputs or []
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url', 'time_limit_ms', 'memory_limit_kbyte',
#                 'source_limit_kbyte', 'inputs', 'outputs']
# 
# Path: hac/util_common.py
# def warn(msg):
#     sys.stderr.write("WARNING: " + msg + os.linesep)
# 
# Path: hac/util_data.py
# class RequestsCache(object):
# 
#     def __init__(self):
#         self._store = {}
# 
#     def get(self, url):
#         if url not in self._store:
#             self._store[url] = requests.get(url)
#         return self._store[url]


import re
import sys
from lxml import html
    from urlparse import urlparse
    from urllib.parse import urlparse
from hac.data import ISite, Contest, Problem
from hac.util_common import warn
from hac.util_data import RequestsCache
                e = t.xpath(SiteSpoj.xpath_problem_name)
                problem.name = (e and str(e[0])) or None
                #   - problem time limit,
                e = t.xpath(SiteSpoj.xpath_problem_time)
                p = e and e[0].strip()[:-1] # remove whitespace characters and 's' at the end
                problem.time_limit_ms = p and float(p) * 1000
                #   - problem source limit,
                e = t.xpath(SiteSpoj.xpath_problem_source)
                p = e and e[0].strip()[:-1] # remove whitespace characters and 'B' at the end
                problem.source_limit_kbyte = p and float(p) / 1000
                #   - problem memory limit,
                e = t.xpath(SiteSpoj.xpath_problem_memory)
                p = e and e[0].strip()[:-2] # remove whitespace characters and 'MB' at the end
                problem.memory_limit_kbyte = p and float(p) * 2**10
                #   - test inputs and outputs.
                e = t.xpath(SiteSpoj.xpath_problem_ins_outs)
                problem.inputs = [i.strip() for i in e[0:][::2]]
                problem.outputs = [o.strip() for o in e[1:][::2]]

                if (problem.name and
                    problem.time_limit_ms and
                    problem.source_limit_kbyte and
                    problem.memory_limit_kbyte and
                    problem.inputs and
                    problem.outputs):
                        problems.append(problem)
                else:
                    warn('Problem "' + problem.id + '" not fetched successfully!')

            else:

# Path: hac/data.py
# class ISite(object):
#     """Site template.
#     """
# 
#     def __init__(self, name=None, id=None, url=None, time_limit_ms=2000,
#                  memory_limit_kbyte=262144, source_limit_kbyte=64):
#         self.name = name
#         self.id = id
#         # 'url' member used to distinguish between different sites.
#         self.url = url
#         self.time_limit_ms = time_limit_ms
#         self.memory_limit_kbyte = memory_limit_kbyte
#         self.source_limit_kbyte = source_limit_kbyte
# 
#         self._info = None
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url', 'time_limit_ms', 'memory_limit_kbyte',
#                 'source_limit_kbyte']
# 
#     @abstractmethod
#     def match_contest(self, conf):
#         """Generates well formated URL of the contest according to user input.
#         """
#         pass
# 
#     @abstractmethod
#     def get_contest(self, url):
#         """Fetches data from the provided contest URL and generates contest
#         object.
#         """
#         pass
# 
#     @abstractmethod
#     def match_problems(self, conf):
#         """Generates list of well formated problem URLs according to user
#         input.
#         """
#         pass
# 
#     @abstractmethod
#     def get_problems(self, urls):
#         """Fetches data from the provided problem URLs and generates list of
#         problem objects.
#         """
#         pass
# 
# class Contest(object):
#     """Contest info container.
#     """
# 
#     def __init__(self, name=None, id=None, url=None):
#         self.name = name
#         self.id = id
#         self.url = url
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url']
# 
# class Problem(object):
#     """Problem info container.
#     """
# 
#     def __init__(self, name=None, id=None, url=None, time_limit_ms=2000,
#                  memory_limit_kbyte=262144, source_limit_kbyte=64, inputs=None,
#                  outputs=None):
#         self.name = name
#         self.id = id
#         self.url = url
#         self.time_limit_ms = time_limit_ms
#         self.memory_limit_kbyte = memory_limit_kbyte
#         self.source_limit_kbyte = source_limit_kbyte
#         self.inputs = inputs or []
#         self.outputs = outputs or []
# 
#     @staticmethod
#     def get_props(verbose=False):
#         return ['id', 'url'] if not verbose else \
#                ['name', 'id', 'url', 'time_limit_ms', 'memory_limit_kbyte',
#                 'source_limit_kbyte', 'inputs', 'outputs']
# 
# Path: hac/util_common.py
# def warn(msg):
#     sys.stderr.write("WARNING: " + msg + os.linesep)
# 
# Path: hac/util_data.py
# class RequestsCache(object):
# 
#     def __init__(self):
#         self._store = {}
# 
#     def get(self, url):
#         if url not in self._store:
#             self._store[url] = requests.get(url)
#         return self._store[url]


# Path: hac/config/site/spoj.py
import re
import sys
from lxml import html
    from urlparse import urlparse
    from urllib.parse import urlparse
from hac.data import ISite, Contest, Problem
from hac.util_common import warn
from hac.util_data import RequestsCache

                e = t.xpath(SiteSpoj.xpath_problem_name)
                problem.name = (e and str(e[0])) or None
                #   - problem time limit,
                e = t.xpath(SiteSpoj.xpath_problem_time)
                p = e and e[0].strip()[:-1] # remove whitespace characters and 's' at the end
                problem.time_limit_ms = p and float(p) * 1000
                #   - problem source limit,
                e = t.xpath(SiteSpoj.xpath_problem_source)
                p = e and e[0].strip()[:-1] # remove whitespace characters and 'B' at the end
                problem.source_limit_kbyte = p and float(p) / 1000
                #   - problem memory limit,
                e = t.xpath(SiteSpoj.xpath_problem_memory)
                p = e and e[0].strip()[:-2] # remove whitespace characters and 'MB' at the end
                problem.memory_limit_kbyte = p and float(p) * 2**10
                #   - test inputs and outputs.
                e = t.xpath(SiteSpoj.xpath_problem_ins_outs)
                problem.inputs = [i.strip() for i in e[0:][::2]]
                problem.outputs = [o.strip() for o in e[1:][::2]]

                if (problem.name and
                    problem.time_limit_ms and
                    problem.source_limit_kbyte and
                    problem.memory_limit_kbyte and
                    problem.inputs and
                    problem.outputs):
                        problems.append(problem)
                else:
                    warn('Problem "' + problem.id + '" not fetched successfully!')

            else:

                warn('Problem "' + problem.id + '" does not exist on Spoj!')