<commit_before>"""
From my blog post:
<http://tanghaibao.blogspot.com/2010/02/getting-phylogeny-from-list-of.html>

Example:
>>> mylist = [3702, 3649, 3694, 3880]
>>> t = TaxIDTree(mylist)
>>> print t
(((Carica_papaya,Arabidopsis_thaliana)Brassicales,(Medicago_truncatula,Populus_trichocarpa)fabids)rosids);
>>> t.print_tree()
<BLANKLINE>
               /-Carica_papaya

          /---|

         |     \-Arabidopsis_thaliana

---- /---|

         |     /-Medicago_truncatula

          \---|

               \-Populus_trichocarpa
"""

from urllib2 import urlopen
from ClientForm import ParseResponse
from BeautifulSoup import BeautifulSoup

from jcvi.utils.cbook import memoized


URL = "http://itol.embl.de/other_trees.shtml"


class TaxIDTree(object):

    def __init__(self, list_of_taxids):
        # If only one taxid provided, get full tree with nameExp
        # else, get default tree
        if isinstance(list_of_taxids, int):  # single taxon
            list_of_taxids = [list_of_taxids]
            form_element_id = "nameExp"
        else:
            form_element_id = "nameCol"

        # the data to send in
        form_data = "\n".join(str(x) for x in list_of_taxids)
        response = urlopen(URL)
        forms = ParseResponse(response, backwards_compat=False)
        form = forms[0]

        form["ncbiIDs"] = form_data<commit_msg>Added exception handling mechanism to jcvi.utils.taxonomy.TaxIDTree() to re-open the URL when the connection times out<commit_after>"""
From my blog post:
<http://tanghaibao.blogspot.com/2010/02/getting-phylogeny-from-list-of.html>

Example:
>>> mylist = [3702, 3649, 3694, 3880]
>>> t = TaxIDTree(mylist)
>>> print t
(((Carica_papaya,Arabidopsis_thaliana)Brassicales,(Medicago_truncatula,Populus_trichocarpa)fabids)rosids);
>>> t.print_tree()
<BLANKLINE>
               /-Carica_papaya

          /---|

         |     \-Arabidopsis_thaliana

---- /---|

         |     /-Medicago_truncatula

          \---|

               \-Populus_trichocarpa
"""
import time
import logging

from urllib2 import urlopen
from ClientForm import ParseResponse
from BeautifulSoup import BeautifulSoup

from jcvi.utils.cbook import memoized


URL = "http://itol.embl.de/other_trees.shtml"


class TaxIDTree(object):

    def __init__(self, list_of_taxids):
        # If only one taxid provided, get full tree with nameExp
        # else, get default tree
        if isinstance(list_of_taxids, int):  # single taxon
            list_of_taxids = [list_of_taxids]
            form_element_id = "nameExp"
        else:
            form_element_id = "nameCol"

        # the data to send in
        form_data = "\n".join(str(x) for x in list_of_taxids)

        success = False
        while not success:
            try:
                response = urlopen(URL)
                success = True
            except (urllib2.URLError, urllib2.HTTPError,
                    RuntimeError, KeyError) as e:
                logging.error(e)
                logging.debug("wait 5 seconds to reconnect...")
                time.sleep(5)

        forms = ParseResponse(response, backwards_compat=False)
        form = forms[0]

        form["ncbiIDs"] = form_data
{'fraction_non_alphanumeric': 0.10863422291993721, 'fraction_numerical': 0.0163265306122449, 'mean_word_length': 2.3785790031813363, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '3663470', 'n_tokens_mistral': 1103, 'n_tokens_neox': 1002, 'n_words': 223}