# Path: xdfile/html.py
# def mkhref(text, link, title=""):
#     if title:
#         return '<a href="%s" title="%s">%s</a>' % (link, title, text)
#     else:
#         return '<a href="%s">%s</a>' % (link, text)
# 
# def html_select_options(options, strmaker=str, force_top="", add_total=True):
#     if not options:
#         return strmaker(force_top)
# 
#     if isinstance(options, Counter):
#         pairs = options.items()
#     else:
#         groups = {}
#         for opt in options:
#             s = strmaker(opt)
#             if not s in groups:
#                 groups[s] = [opt]
#             else:
#                 groups[s].append(opt)
# 
#         pairs = [(k, len(v)) for k, v in groups.items()]
# 
#     return html_select_options_freq(pairs, strmaker=strmaker, force_top=force_top, add_total=add_total)
# 
# Path: xdfile/utils.py
# COLSEP = '\t'
# 
# EOL = '\n'
# 
# Path: xdfile/xdfile.py
# @memoize
# def corpus():
#     from .utils import log
# 
#     args = get_args()
# 
#     ret = []
# 
#     for fullfn, contents in find_files(args.corpusdir, ext='.xd'):
#         try:
#             progress(fullfn)
# 
#             xd = xdfile(contents.decode("utf-8"), fullfn)
# 
#             ret.append(xd)
#         except Exception as e:
#             error("corpus(): %s" % str(e))
#             if args.debug:
#                 raise
# 
#     progress()
# 
#     return ret
# 
# Path: xdfile/utils.py
# EOL = '\n'
# COLSEP = '\t'
# COLUMN_SEPARATOR = COLSEP
# WEEKDAYS = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# class bcolors:
# class AttrDict(dict):
# class OutputZipFile(zipfile.ZipFile):
# class OutputFile:
# class OutputDirectory:
# def space_with_nbsp(text):
# def split_xdid(xdid):
# def br_with_n(text):
# def get_log():
# def log(s, minverbose=0, severity='INFO'):
# def info(_s, _m=0):
# def warn(_s, _m=0):
# def error(_s, _m=0):
# def summary(_s, _m=0):
# def debug(s):
# def progress(rest=None, every=1):
# def args_parser(desc=""):
# def get_args(desc="", parser=None):
# def find_files(*paths, **kwargs):
# def to_timet(y, mon=1, d=1, h=0, m=0, s=0):
# def generate_zip_files(data):
# def find_files_with_time(*paths, **kwargs):
# def filetime(fn):
# def iso8601(timet=None):
# def datestr_to_datetime(s):
# def parse_xdid(path):
# def parse_pathname(path):
# def parse_pubid(fn):
# def construct_date(y, m, d):
# def parse_iso8601(s):
# def parse_seqnum(s):
# def parse_date_from_filename(fn):
# def clean_filename(fn):
# def replace_ext(fn, newext):
#     def __init__(self, *args, **kwargs):
# def autoconvert(v):
# def parse_tsv_data(contents, objname=None):
# def parse_tsv(fn, objname=None):
# def parse_tsv_rows(fn, objname=None):
#     def __init__(self, fnzip, toplevel="", log=True):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def __del__(self):
#     def __init__(self, outfp=None):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def write_row(self, fields):
#     def write_html(self, fn, innerhtml, title=""):
# def strip_toplevel(fn):
# def disambiguate_fn(fn, all_filenames):
#     def __init__(self, toplevel_dir):
#     def exists(self, fn):
#     def open_file(self, fn, mode='w'):
#     def close_file(self, fn):
#     def write_file(self, fn, contents, timet=None):
#     def write_html(self, fn, innerhtml, title=""):
#     def write_row(self, fn, headerstr, values):
# def open_output(fnout=None):
# def memoize(obj):
#     def memoizer(*args, **kwargs):
# def __dict_replace(s, d):
# def escape(data, entities={}):
# def consecutive(text):


import os.path
import codecs
import fnmatch
from collections import Counter, namedtuple
from .html import mkhref, html_select_options
from .utils import COLSEP, EOL
from .xdfile import corpus
from xdfile import utils


@utils.memoize
def xd_publications():
    return dict((r.PublicationAbbr, r) for r in read_rows('gxd/publications'))


def xd_puzzle(xdid):
    return xd_puzzles_dict().get(xdid)


@utils.memoize
def xd_puzzles_dict():
    return dict((p.xdid, p) for p in _puzzles())


def xd_puzzles(xdid=''):
    if not xdid:
        return _puzzles()

    return [p for p in _puzzles() if p.xdid.startswith(xdid)]


def get_author(xdid=''):
    r = xd_puzzles(xdid)
    return str(r[0].Author) if r else "???"


@utils.memoize
def _puzzles():

# Path: xdfile/html.py
# def mkhref(text, link, title=""):
#     if title:
#         return '<a href="%s" title="%s">%s</a>' % (link, title, text)
#     else:
#         return '<a href="%s">%s</a>' % (link, text)
# 
# def html_select_options(options, strmaker=str, force_top="", add_total=True):
#     if not options:
#         return strmaker(force_top)
# 
#     if isinstance(options, Counter):
#         pairs = options.items()
#     else:
#         groups = {}
#         for opt in options:
#             s = strmaker(opt)
#             if not s in groups:
#                 groups[s] = [opt]
#             else:
#                 groups[s].append(opt)
# 
#         pairs = [(k, len(v)) for k, v in groups.items()]
# 
#     return html_select_options_freq(pairs, strmaker=strmaker, force_top=force_top, add_total=add_total)
# 
# Path: xdfile/utils.py
# COLSEP = '\t'
# 
# EOL = '\n'
# 
# Path: xdfile/xdfile.py
# @memoize
# def corpus():
#     from .utils import log
# 
#     args = get_args()
# 
#     ret = []
# 
#     for fullfn, contents in find_files(args.corpusdir, ext='.xd'):
#         try:
#             progress(fullfn)
# 
#             xd = xdfile(contents.decode("utf-8"), fullfn)
# 
#             ret.append(xd)
#         except Exception as e:
#             error("corpus(): %s" % str(e))
#             if args.debug:
#                 raise
# 
#     progress()
# 
#     return ret
# 
# Path: xdfile/utils.py
# EOL = '\n'
# COLSEP = '\t'
# COLUMN_SEPARATOR = COLSEP
# WEEKDAYS = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
#     HEADER = '\033[95m'
#     OKBLUE = '\033[94m'
#     OKGREEN = '\033[92m'
#     WARNING = '\033[93m'
#     FAIL = '\033[91m'
#     ENDC = '\033[0m'
#     BOLD = '\033[1m'
#     UNDERLINE = '\033[4m'
# class bcolors:
# class AttrDict(dict):
# class OutputZipFile(zipfile.ZipFile):
# class OutputFile:
# class OutputDirectory:
# def space_with_nbsp(text):
# def split_xdid(xdid):
# def br_with_n(text):
# def get_log():
# def log(s, minverbose=0, severity='INFO'):
# def info(_s, _m=0):
# def warn(_s, _m=0):
# def error(_s, _m=0):
# def summary(_s, _m=0):
# def debug(s):
# def progress(rest=None, every=1):
# def args_parser(desc=""):
# def get_args(desc="", parser=None):
# def find_files(*paths, **kwargs):
# def to_timet(y, mon=1, d=1, h=0, m=0, s=0):
# def generate_zip_files(data):
# def find_files_with_time(*paths, **kwargs):
# def filetime(fn):
# def iso8601(timet=None):
# def datestr_to_datetime(s):
# def parse_xdid(path):
# def parse_pathname(path):
# def parse_pubid(fn):
# def construct_date(y, m, d):
# def parse_iso8601(s):
# def parse_seqnum(s):
# def parse_date_from_filename(fn):
# def clean_filename(fn):
# def replace_ext(fn, newext):
#     def __init__(self, *args, **kwargs):
# def autoconvert(v):
# def parse_tsv_data(contents, objname=None):
# def parse_tsv(fn, objname=None):
# def parse_tsv_rows(fn, objname=None):
#     def __init__(self, fnzip, toplevel="", log=True):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def __del__(self):
#     def __init__(self, outfp=None):
#     def write_file(self, fn, contents, timet=None):
#     def write(self, data):
#     def write_row(self, fields):
#     def write_html(self, fn, innerhtml, title=""):
# def strip_toplevel(fn):
# def disambiguate_fn(fn, all_filenames):
#     def __init__(self, toplevel_dir):
#     def exists(self, fn):
#     def open_file(self, fn, mode='w'):
#     def close_file(self, fn):
#     def write_file(self, fn, contents, timet=None):
#     def write_html(self, fn, innerhtml, title=""):
#     def write_row(self, fn, headerstr, values):
# def open_output(fnout=None):
# def memoize(obj):
#     def memoizer(*args, **kwargs):
# def __dict_replace(s, d):
# def escape(data, entities={}):
# def consecutive(text):


# Path: xdfile/metadatabase.py
import os.path
import codecs
import fnmatch
from collections import Counter, namedtuple
from .html import mkhref, html_select_options
from .utils import COLSEP, EOL
from .xdfile import corpus
from xdfile import utils



@utils.memoize
def xd_publications():
    return dict((r.PublicationAbbr, r) for r in read_rows('gxd/publications'))


def xd_puzzle(xdid):
    return xd_puzzles_dict().get(xdid)


@utils.memoize
def xd_puzzles_dict():
    return dict((p.xdid, p) for p in _puzzles())


def xd_puzzles(xdid=''):
    if not xdid:
        return _puzzles()

    return [p for p in _puzzles() if p.xdid.startswith(xdid)]


def get_author(xdid=''):
    r = xd_puzzles(xdid)
    return str(r[0].Author) if r else "???"


@utils.memoize
def _puzzles():

    return utils.parse_tsv_rows('pub/puzzles.tsv', "Puzzle")