<commit_before>#! /usr/bin/env python

###############################################################################
##
##  Copyright 2014 <NAME>.
##
##  This program is free software; you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation; either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License along
##  with this program. If not, see <http://www.gnu.org/licenses/>.
##
###############################################################################

"""
This program does something.
"""

import sys
import os
import argparse
import collections
import pyopentree

try:
    import vcr
    CACHING_AVAILABLE = True
except ImportError:
    CACHING_AVAILABLE = False
    pass

__prog__ = os.path.basename(__file__)
__version__ = "1.0.0"
__description__ = __doc__
__author__ = '<NAME>'
__copyright__ = 'Copyright (C) 2014 <NAME>.'

import pprint
_DEBUG_LOG = pprint.PrettyPrinter(
        indent=0,
        width=80,
        depth=None,
        stream=None)

class OpenTreeDoiSearcher(pyopentree.OpenTreeService):

    StudyInfo = collections.namedtuple("StudyInfo", ["study_id", "doi", "citation"])

    def __init__(self, *args, **kwargs):
        self.cache_path = kwargs.pop("cache_path",
                ".opentree.cache.yaml")
        pyopentree.OpenTreeService.__init__(self, *args, **kwargs)

    def open_url(self, request):
        if CACHING_AVAILABLE:
            with vcr.use_cassette(self.cache_path,
                    record_mode="new_episodes"):
                return pyopentree.OpenTreeService.open_url(self, request)
        else:
            return pyopentree.OpenTreeService.open_url(self, request)

    def slice_from(self, slice_from, slice_limit):
        """
        - slice_from: 1-based index of where to start slice; defaults to None (=first)
        - slice_limit: number of items to get; defaults to None (=all)
        """
        if slice_from is not None:
            slice_start = slice_from - 1
        else:
            slice_start = None
        if slice_limit is not None:
            if slice_start is None:
                slice_to = slice_limit
            else:
                slice_to = slice_start + slice_limit
        else:
            slice_to = None
        slice_result = slice(slice_from, slice_to)
        return slice_result

    def yield_studies(
            self,
            list_from=None,
            max_studies=None):
        studies_dict = self.studies_find_studies()
        study_list = []
        study_slice = self.slice_from(list_from, max_studies)
        for study_dict in studies_dict["matched_studies"][study_slice]:
            study_id = study_dict["ot:studyId"]
            study_dict = pyopentree.get_study_meta(study_id)["nexml"]
            citation = study_dict.get("^ot:studyPublicationReference", None)
            doi_dict = study_dict.get("^ot:studyPublication", None)
            if doi_dict is not None:
                doi = doi_dict["@href"]
            else:
                doi = None
            if doi is not None:
                s = OpenTreeDoiSearcher.StudyInfo(
                        study_id=study_id,
                        doi=doi,
                        citation=citation)
                yield s

    def list_studies(self,
            list_from=None,
            max_studies=None,
            as_table=True,
            table_column_delimiter="\t",
            out=sys.stdout):
        for study in self.yield_studies(
                list_from=list_from,
                max_studies=max_studies):
            if as_table:
                out.write("{}{}{}\n".format(
                    study.doi,
                    table_column_delimiter,
                    study.citation))
            else:
                out.write("[{}]\n{}\n\n".format(
                    study.doi,
                    study.citation))

    def get_trees(self,
            doi,
            schema="nexml"):
        # verbose
        tree_ids = self.studies_find_trees(
                study_property="ot:studyPublication",
                value=doi,
                exact=True)
        print(tree_ids)

def main():
    """
    Main CLI handler.
    """

    parser = argparse.ArgumentParser(description=__description__)
    subparsers = parser.add_subparsers(help='commands', dest="subparser_name")

    # list studies
    list_studies_parser = subparsers.add_parser("list-studies", help="List contents")
    list_studies_parser.add_argument("--filter-for-taxon",
            action="append",
            default=False,
            help="Filter for studies with specific taxa (multiple filters will be OR'd together).")
    list_studies_parser.add_argument("--list-from",
            type=int,
            default=None,
            help="First study to list (default: first)")
    list_studies_parser.add_argument("--max-studies",
            type=int,
            default=None,
            help="Maximum number of studies to list.")
    list_studies_parser.add_argument("--as-table",
            action="store_true",
            default=False,
            help="Format as (tab-delimited) rows.")

    # get trees
    get_trees_parser = subparsers.add_parser("get-trees", help="Retrieve trees")
    get_trees_parser.add_argument("doi",
            help="DOI of the study containing the trees to retrieve")
    get_trees_parser.add_argument("-f", "--format",
            dest="schema",
            choices=["nexus", "newick", "nexml"],
            default="nexml",
            help="DOI of the study containing the trees to retrieve (default: '%(default)s').")

    # # A delete command
    # delete_parser = subparsers.add_parser('delete', help='Remove a directory')
    # delete_parser.add_argument('dirname', action='store', help='The directory to remove')
    # delete_parser.add_argument('--recursive', '-r', default=False, action='store_true',
    #                         help='Remove the contents of the directory, too',
    #                         )
    # ots = pyopentree.OpenTreeService()

    args = parser.parse_args()

    ots = OpenTreeDoiSearcher()
    if args.subparser_name == "list-studies":
        ots.list_studies(
                list_from=args.list_from,
                max_studies=args.max_studies,
                as_table=args.as_table,
                )
    elif args.subparser_name == "get-trees":
        # http://dx.doi.org/10.1111/j.1365-294X.2012.05606.x
        ots.get_trees(
            doi=args.doi,
            schema=args.schema)
    else:
        parser.print_usage(sys.stderr)
        sys.exit(1)


    # studies = ots.studies_find_studies()
    # study_ids = []
    # for study_dict in studies["matched_studies"][:10]:
    #     study_ids.append(study_dict["ot:studyId"])
    # for study_id in study_ids:
    #     study_dict = ots.get_study_meta(study_id)
    #     x = study_dict["nexml"]
    #     citation = x.get('^ot:studyPublicationReference', None)
    #     doi_dict = x.get('^ot:studyPublication', None)
    #     if doi_dict is not None:
    #         doi = doi_dict["@href"]
    #     else:
    #         doi = None
    #     if doi is not None:<commit_msg>Removing caching facility<commit_after>#! /usr/bin/env python

###############################################################################
##
##  Copyright 2014 <NAME>.
##
##  This program is free software; you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation; either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License along
##  with this program. If not, see <http://www.gnu.org/licenses/>.
##
###############################################################################

"""
This program does something.
"""

import sys
import os
import argparse
import collections
import pyopentree

__prog__ = os.path.basename(__file__)
__version__ = "1.0.0"
__description__ = __doc__
__author__ = '<NAME>'
__copyright__ = 'Copyright (C) 2014 <NAME>.'

import pprint
_DEBUG_LOG = pprint.PrettyPrinter(
        indent=0,
        width=80,
        depth=None,
        stream=None)

class OpenTreeDoiSearcher(pyopentree.OpenTreeService):

    StudyInfo = collections.namedtuple("StudyInfo", ["study_id", "doi", "citation"])

    def __init__(self, *args, **kwargs):
        self.cache_path = kwargs.pop("cache_path",
                ".opentree.cache.yaml")
        pyopentree.OpenTreeService.__init__(self, *args, **kwargs)

    def slice_from(self, slice_from, slice_limit):
        """
        - slice_from: 1-based index of where to start slice; defaults to None (=first)
        - slice_limit: number of items to get; defaults to None (=all)
        """
        if slice_from is not None:
            slice_start = slice_from - 1
        else:
            slice_start = None
        if slice_limit is not None:
            if slice_start is None:
                slice_to = slice_limit
            else:
                slice_to = slice_start + slice_limit + 1
        else:
            slice_to = None
        slice_result = slice(slice_from, slice_to)
        return slice_result

    def yield_studies(
            self,
            list_from=None,
            max_studies=None):
        studies_dict = self.studies_find_studies()
        study_list = []
        study_slice = self.slice_from(list_from, max_studies)
        for study_dict in studies_dict["matched_studies"][study_slice]:
            study_id = study_dict["ot:studyId"]
            study_dict = pyopentree.get_study_meta(study_id)["nexml"]
            citation = study_dict.get("^ot:studyPublicationReference", None)
            doi_dict = study_dict.get("^ot:studyPublication", None)
            if doi_dict is not None:
                doi = doi_dict["@href"]
            else:
                doi = None
            if doi is not None:
                s = OpenTreeDoiSearcher.StudyInfo(
                        study_id=study_id,
                        doi=doi,
                        citation=citation)
                yield s

    def get_trees(self,
            doi,
            schema="nexml"):
        study_query = self.studies_find_studies(
                property_name="ot:studyPublication",
                property_value=doi,
                exact=True,
                verbose=False)
        matched_studies = study_query["matched_studies"]
        if not matched_studies:
            return None
        else:
            return "OK"

def main():
    """
    Main CLI handler.
    """

    parser = argparse.ArgumentParser(description=__description__)
    subparsers = parser.add_subparsers(help='commands', dest="subparser_name")

    # list studies
    list_studies_parser = subparsers.add_parser("list-studies", help="List contents")
    list_studies_parser.add_argument("--filter-for-taxon",
            action="append",
            default=False,
            help="Filter for studies with specific taxa (multiple filters will be OR'd together).")
    list_studies_parser.add_argument("--list-from",
            type=int,
            default=None,
            help="First study to list (default: first)")
    list_studies_parser.add_argument("--max-studies",
            type=int,
            default=None,
            help="Maximum number of studies to list.")
    list_studies_parser.add_argument("--as-table",
            action="store_true",
            default=False,
            help="Format as (tab-delimited) rows.")

    # get trees
    get_trees_parser = subparsers.add_parser("get-trees", help="Retrieve trees")
    get_trees_parser.add_argument("doi",
            help="DOI of the study containing the trees to retrieve")
    get_trees_parser.add_argument("-f", "--format",
            dest="schema",
            choices=["nexus", "newick", "nexml"],
            default="nexml",
            help="DOI of the study containing the trees to retrieve (default: '%(default)s').")

    # # A delete command
    # delete_parser = subparsers.add_parser('delete', help='Remove a directory')
    # delete_parser.add_argument('dirname', action='store', help='The directory to remove')
    # delete_parser.add_argument('--recursive', '-r', default=False, action='store_true',
    #                         help='Remove the contents of the directory, too',
    #                         )
    # ots = pyopentree.OpenTreeService()

    args = parser.parse_args()

    ots = OpenTreeDoiSearcher()
    if args.subparser_name == "list-studies":
        out = sys.stdout
        for study in ots.yield_studies(
                list_from=args.list_from,
                max_studies=args.max_studies):
            if args.as_table:
                out.write("{}\t{}\n".format(
                    study.doi,
                    study.citation))
            else:
                out.write("[{}]\n{}\n\n".format(
                    study.doi,
                    study.citation))
    elif args.subparser_name == "get-trees":
        # http://dx.doi.org/10.1111/j.1365-294X.2012.05606.x
        trees_string = ots.get_trees(doi=args.doi, schema=args.schema)
        if trees_string is None:
            sys.exit("No studies found with DOI: '{}'".format(args.doi))
        print(trees_string)
    else:
        parser.print_usage(sys.stderr)
        sys.exit(1)


    # studies = ots.studies_find_studies()
    # study_ids = []
    # for study_dict in studies["matched_studies"][:10]:
    #     study_ids.append(study_dict["ot:studyId"])
    # for study_id in study_ids:
    #     study_dict = ots.get_study_meta(study_id)
    #     x = study_dict["nexml"]
    #     citation = x.get('^ot:studyPublicationReference', None)
    #     doi_dict = x.get('^ot:studyPublication', None)
    #     if doi_dict is not None:
    #         doi = doi_dict["@href"]
    #     else:
    #         doi = None
    #     if doi is not None:
{'fraction_non_alphanumeric': 0.1260123541523679, 'fraction_numerical': 0.005833905284831846, 'mean_word_length': 2.230820399113082, 'pattern_counts': {'":': 4, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 10}, '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': '4621362', 'n_tokens_mistral': 4399, 'n_tokens_neox': 4128, 'n_words': 983}