<commit_before>"""
opsin - A Cinfony module for accessing OPSIN from CPython and Jython

Global variables:
  opsin - the underlying OPSIN library (uk.ac.cam.ch.wwmm.opsin)
  informats - a dictionary of supported input formats
  outformats - a dictionary of supported output formats
"""

import os
import sys

if sys.platform[:4] == "java": # Jython
    import uk.ac.cam.ch.wwmm.opsin as opsin
else: # CPython
    import jpype
    if not jpype.isJVMStarted():
        _jvm = os.environ['JPYPE_JVM']
        _cp = os.environ['CLASSPATH']
        jpype.startJVM(_jvm, "-Djava.class.path=" + _cp)
    opsin = jpype.JPackage("uk").ac.cam.ch.wwmm.opsin

try:
    _nametostruct = opsin.NameToStructure.getInstance()
    _restoinchi = opsin.NameToInchi.convertResultToInChI
except TypeError:
    raise ImportError("The OPSIN Jar file cannot be found.")

informats = {'iupac': 'IUPAC name'}
"""A dictionary of supported input formats"""
outformats = {'cml': "Chemical Markup Language", 'inchi': "InChI",
              'smi': "SMILES"}
"""A dictionary of supported output formats"""

def readstring(format, string):
    """Read in a molecule from a string.

    Required parameters:
       format - see the informats variable for a list of available
                input formats
       string

    Example:
    >>> input = "propane"
    >>> mymol = readstring("iupac", input)
    """
    if format!="iupac":
        raise ValueError("%s is not a recognised OPSIN format" % format)

    result = _nametostruct.parseChemicalName(string)
    if str(result.getStatus()) == "FAILURE":
        raise IOError("Failed to convert '%s' to format '%s'\n%s" % (
            string, format, result.getMessage()))

    return Molecule(result)

class Molecule(object):
    """Represent a opsinjpype Molecule.

    Required parameters:
       OpsinResult -- the result of using OPSIN to parse an IUPAC string

    Methods:
       write()

    The underlying OpsinResult can be accessed using the attribute:
       OpsinResult
    """
    _cinfony = True

    def __init__(self, OpsinResult):
        if hasattr(OpsinResult, "_cinfony"):
            raise IOError, "An opsin Molecule cannot be created from another Cinfony Molecule"

        self.OpsinResult = OpsinResult

    def __str__(self):
        return self.write()
    @property
    def _exchange(self):
        return (0, self.write("smi"))
    def write(self, format="smi", filename=None, overwrite=False):
        """Write the molecule to a file or return a string.

        Optional parameters:
           format -- see the outformats variable for a list of available
                     output formats (default is "smi")
           filename -- default is None
           overwite -- if the output file already exists, should it
                       be overwritten? (default is False)

        If a filename is specified, the result is written to a file.
        Otherwise, a string is returned containing the result.
        """
        if format not in outformats:
            raise ValueError,"%s is not a recognised OPSIN format" % format

        if filename is not None and not overwrite and os.path.isfile(filename):
            raise IOError, "%s already exists. Use 'overwrite=True' to overwrite it." % filename

        if format == "cml":
            result = str(self.OpsinResult.getCml().toXML())
        elif format == "inchi":
            result = str(_restoinchi(self.OpsinResult))
        elif format == "smi":
            result = str(self.OpsinResult.getSmiles())

        if filename:
            outputfile = open(filename, "w")
            print >> outputfile, result
            outputfile.close()
        else:
            return result

if __name__=="__main__": #pragma: no cover
    mol = readstring("iupac", "propane")
    print mol.write("inchi")
<commit_msg>Remove trailing quotes in JVM for opsin<commit_after>"""
opsin - A Cinfony module for accessing OPSIN from CPython and Jython

Global variables:
  opsin - the underlying OPSIN library (uk.ac.cam.ch.wwmm.opsin)
  informats - a dictionary of supported input formats
  outformats - a dictionary of supported output formats
"""

import os
import sys

if sys.platform[:4] == "java": # Jython
    import uk.ac.cam.ch.wwmm.opsin as opsin
else: # CPython
    import jpype
    if not jpype.isJVMStarted():
        _jvm = os.environ['JPYPE_JVM']
        if _jvm[0] == '"': # Handle trailing quotes
            _jvm = _jvm[1:-1]
        _cp = os.environ['CLASSPATH']
        jpype.startJVM(_jvm, "-Djava.class.path=" + _cp)
    opsin = jpype.JPackage("uk").ac.cam.ch.wwmm.opsin

try:
    _nametostruct = opsin.NameToStructure.getInstance()
    _restoinchi = opsin.NameToInchi.convertResultToInChI
except TypeError:
    raise ImportError("The OPSIN Jar file cannot be found.")

informats = {'iupac': 'IUPAC name'}
"""A dictionary of supported input formats"""
outformats = {'cml': "Chemical Markup Language", 'inchi': "InChI",
              'smi': "SMILES"}
"""A dictionary of supported output formats"""

def readstring(format, string):
    """Read in a molecule from a string.

    Required parameters:
       format - see the informats variable for a list of available
                input formats
       string

    Example:
    >>> input = "propane"
    >>> mymol = readstring("iupac", input)
    """
    if format!="iupac":
        raise ValueError("%s is not a recognised OPSIN format" % format)

    result = _nametostruct.parseChemicalName(string)
    if str(result.getStatus()) == "FAILURE":
        raise IOError("Failed to convert '%s' to format '%s'\n%s" % (
            string, format, result.getMessage()))

    return Molecule(result)

class Molecule(object):
    """Represent a opsinjpype Molecule.

    Required parameters:
       OpsinResult -- the result of using OPSIN to parse an IUPAC string

    Methods:
       write()

    The underlying OpsinResult can be accessed using the attribute:
       OpsinResult
    """
    _cinfony = True

    def __init__(self, OpsinResult):
        if hasattr(OpsinResult, "_cinfony"):
            raise IOError, "An opsin Molecule cannot be created from another Cinfony Molecule"

        self.OpsinResult = OpsinResult

    def __str__(self):
        return self.write()
    @property
    def _exchange(self):
        return (0, self.write("smi"))
    def write(self, format="smi", filename=None, overwrite=False):
        """Write the molecule to a file or return a string.

        Optional parameters:
           format -- see the outformats variable for a list of available
                     output formats (default is "smi")
           filename -- default is None
           overwite -- if the output file already exists, should it
                       be overwritten? (default is False)

        If a filename is specified, the result is written to a file.
        Otherwise, a string is returned containing the result.
        """
        if format not in outformats:
            raise ValueError,"%s is not a recognised OPSIN format" % format

        if filename is not None and not overwrite and os.path.isfile(filename):
            raise IOError, "%s already exists. Use 'overwrite=True' to overwrite it." % filename

        if format == "cml":
            result = str(self.OpsinResult.getCml().toXML())
        elif format == "inchi":
            result = str(_restoinchi(self.OpsinResult))
        elif format == "smi":
            result = str(self.OpsinResult.getSmiles())

        if filename:
            outputfile = open(filename, "w")
            print >> outputfile, result
            outputfile.close()
        else:
            return result

if __name__=="__main__": #pragma: no cover
    mol = readstring("iupac", "propane")
    print mol.write("inchi")
<|endoftext|>


<commit_before>
<commit_msg>Update __init__.py<commit_after>
import os
from django.conf import settings
<|endoftext|>


<commit_before><commit_msg>version bump to 0.1.13<commit_after><|endoftext|>


<commit_before><commit_msg>next steps in finishing longer training after gs<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wikipedia, re, string
import math

RE_LINKS = re.compile('(\[\[[Uu]ser *: *(.+?) *(?:\| *(.*?) *)?\]\])')

RE_USER = re.compile('\[\[[Uu]ser ?: ?(.+?) ?[\|\]]')
RE_LISTED = re.compile('\n\s*[\*#]\s*(\[.+?\]+|\S+)[^\n]*')
RE_RIBBONBEARER = re.compile('\{\{.*?\|\s*name ?=\s*(.+?)(?:\}|\|\s*\w+\s*=)', re.DOTALL)
RE_CARDRECIPIENT = re.compile('recipient ?=\s*(.+?)(?:\}|\|\s*\w+\s*=)')
RE_ENTITLED = re.compile('==+(\[\[[Uu]ser.*?\])=+=')
RE_MEETUP = re.compile('\{\{\s*[Mm]eet-up.*?\|\s*name\s*=\s*(.+?)(?:\}|\|\s*\w+\s*=)', re.DOTALL)
RE_FIRST = re.compile('^.*?(\[\[[Uu]ser.+?\]\])', re.DOTALL)

improbablenames = ["and", "i", "we", "the", "one", "all attendees", "everyone"]

def fuzzyadd(a,b): #combine two fuzzy values
  return (a+b)/2.0
  #return sqrt(a*a+b*b)

debug_fuzz = None
debug_links = None
def getDebugFuzz():
  global debug_fuzz
  return debug_fuzz

def getDebugLinks():
  global debug_links
  return debug_links

def normalize(dic):
  maxfuzz = 0
  for p,v in dic.items():
    if len(p)==0:
      del dic[p]
      continue
    if v>maxfuzz:
      maxfuzz=v
  if maxfuzz>0:
    for p,v in dic.items():
      dic[p]=v/maxfuzz
  return dic

def unscorify(word):
  return word.replace("_"," ")

def splitgrouped(word):
  return re.split(",| and |&", word)

def identifyParticipants(text, page, getLinks = False):
  global debug_fuzz
  global debug_links

  #print "===",page,"==="
  fuzzy = {} #user id -> probability of being a participant
  text = unscorify(text)

  pseudonyms = {}
  userlinks  = {}
  usernames  = {}

  if "[[Category:Not reached - Did not attempt]]" in text:
    return []

  scoring = {
    RE_USER: 1,
    RE_RIBBONBEARER: 3,
    RE_CARDRECIPIENT: -5,
    RE_ENTITLED: 20,
    RE_MEETUP: 10,
    RE_FIRST: 2,
  }

  sections = getSectionRegex(text, "(participants?|(the )?people|attendees?|adventurers?)\??", True)
  if sections:
    scoring[RE_LISTED] = 5;
    text = sections

# identify pseudonyms, and user links
  links = RE_LINKS.findall(text)
  for part in links:
    pseudonyms[part[0].lower()] = part[1].lower()
    userlinks [part[1].lower()] = part[0]
    usernames [part[0].lower()] = part[1]
    if not part[2].lower() in improbablenames:
      pseudonyms[part[2].lower()] = part[1].lower()
      usernames [part[2].lower()] = part[1]
      userlinks [part[2].lower()] = part[0]

  text = text.lower()

  for rex, score in scoring.items():
    match = rex.findall(text)
    for group in match:
      parts = splitgrouped(group)
      for part in parts:
        part = part.lower().strip()
        if not part in improbablenames:
          if part in pseudonyms:
            fuzzy[pseudonyms[part]]=fuzzy.get(pseudonyms[part],0) + score
          else:
            fuzzy[part]=fuzzy.get(part,0) + score
            usernames[part.lower()] = part

  #increase the score of a potential participant by the number of mentions¹ vs total mentions
  mentions = {}
  mcount   = 0.0
  for p in fuzzy.keys():
    mentions[p] = len(re.findall(re.escape(p), text, re.IGNORECASE))
    mcount += mentions[p]
  for p in pseudonyms.keys():
    if p not in fuzzy.keys():
      pseudo_mentions = len(re.findall(re.escape(p), text, re.IGNORECASE)) + len(re.findall(re.escape(p), pseudonyms[p], re.IGNORECASE))
      if RE_USER.match(p):
        mentions_per_link = len(re.findall(re.escape(pseudonyms[p]), p, re.IGNORECASE))
        pseudo_mentions -= pseudo_mentions * mentions_per_link
      mentions[pseudonyms[p]] = mentions.get(pseudonyms[p],0) + pseudo_mentions
      mcount += pseudo_mentions

  if mcount>0:
    for p,v in mentions.items():
      fuzzy[p]=fuzzyadd(fuzzy.get(p,0),v/mcount)

  if len(fuzzy)==0: #only if we still don't have fuzz
    history = page.getVersionHistory(getAll=True)
    #compare the edit history with the page content
    editors = [change[2] for change in history]
    for editor in editors:
      if editor.lower() in text.lower():
        fuzzy[editor]=0.5

  if len(fuzzy)==0: #only if we still don't have fuzz
    wlh = [r for r in page.getReferences()]
    #get user pages from the reference counter
    for l in wlh:
      if "User:" in l.title():
        fuzzy[l.title()[5:]]=0.5
    if len(fuzzy)>1: #but not too much, I say
      fuzzy = {}

  fuzzy = normalize(fuzzy)

  participants = []
  for p,v in fuzzy.items():
    if p in improbablenames:
      v = fuzzyadd(v,-1)
    if v>=0.35:
      participants.append(p)

  debug_fuzz = fuzzy
  debug_links = userlinks

  if getLinks:
    return [userlinks.get(p,p) for p in participants] #that is: return a list of [userlinks[p] if it exists, else return p]
  else:
    return participants

def getUsers(page):
  """
returns a list of expeditions participants found in the text of a geohashing expedition page.
ingredients: one wikipedia.Page object
  """
  text = page.get()
  title = page.title()
  wikipedia.output(u'Parsing %s...' % title)

  if(text[0] == u"="):  # a hack?
    text = u"\n" + text

  if(text[1] == u"="):
     text = u"\n" + text

#Generate the list of people
#First look in appropriately named "who" sections
  peopleSecText = getSectionRegex(text, "(participants?|people)\??")
  if(peopleSecText != None):
    peopleText = getPeopleText(text, peopleSecText)

#If that fails, look for all unique [[User:*]] tags in the expedition page
  if((peopleSecText == None) or (len(peopleText) == 0)):
    peopleText = getUserList(text)

  return peopleText

def getSections(text, subSects = None):
   text = "\n" + text
   if (subSects == None):
      split_text = re.split("\n", text)
      minlen = 99
      for line in split_text:
         match = re.match("\s*=+", line)
         if ((match != None) and (len(string.strip(match.group(0))) < minlen)):
            minlen = len(string.strip(match.group(0)))
      equal_str = u""
      for i in range(0,minlen):
         equal_str += u"="
      regex_text = u"\n\s*" + equal_str + "([^=]*?)" + equal_str
   else:
      regex_text = "\n\s*=+([^=]*?)=+"

   text_arr = re.split(regex_text, text)
   for i in range(0,len(text_arr)):
       text_arr[i] = string.strip(text_arr[i])

   section_hash = {}
   section_hash[""] = text_arr[0]

   for i in range(1,len(text_arr),2):
     title = string.lower(text_arr[i])
     section_hash[title] = section_hash.get(title,"") + text_arr[i+1]

#   for i in section_hash.keys():
#      print i + ":",
#      print ":" + section_hash[i]

   return section_hash

def getSection(text, name_arr, subSects = None):
  """
This will look for a section with one of the names in name_arr
The search is case insensitive, and returns the first match, starting from name_arr[0] and continuing to name_arr[len(name_arr)-1]
It will return the body of the appropriate section, or None if there were no matches for the section name.
If subSects != None, then it will search for all subsections which match as well.
  """
  sections = getSections(text, subSects)
  code = ""
  for header in name_arr:
      if header in sections:
          code += sections[header] +"\n"
  if ((len(name_arr) == 0) and ("" in sections)):
      return sections[""]
  if len(code)>0:
    return code
  return None

def getSectionRegex(text, regex_text, subSects = None):
    """
This will look for a section with a name that matches the regex_text
It will return the body of the appropriate section, or None if there were no matches for the section name.
If subSects != None, then it will search for all subsections which match as well.
    """
    sections = getSections(text, subSects)
    if ((regex_text == None) and ("" in sections)):
        return sections[""]
    else:
        for keys in sections.keys():
            if(re.match(regex_text, keys)):
                return sections[keys]
    return None

def getUserUist(text):
  """This will look for all unique user tags on a page, and make a list out of them."""
  regex_res = re.findall("\[\[User:.*?\]\]", text, re.I)
  regex_lower = []
  for i in range(0,len(regex_res)):
    regex_lower.append(re.sub("_", " ", regex_res[i].lower()))
    regex_lower[i] = re.sub(" ?| ?", "|", regex_lower[i])
    regex_lower[i] = re.sub("'s", "", regex_lower[i])
  result_arr = []
  for i in range(0,len(regex_lower)):
    for j in range(i+1,len(regex_lower)):
      if (regex_lower[i] == regex_lower[j]):
        break
      else:
        result_arr.append(regex_res[i])

  temp_str = u", "
  return temp_str.join(result_arr)

def getPeopleText(text, people_text):
  """This function will parse a list of users, and return them in a comma separated list."""
  people_text = re.sub("<!--.*?(-->|$)", "", people_text)
  people_text = string.strip(re.sub("^\[[^][]*?\]", "", people_text))
  people_text_arr = re.split("\n", people_text)

  people_text = u""

  if (len(people_text_arr[0]) == 0):
    people_regex_str = re.compile("^(\[\[.*?\]\]|[^ ]*)")
  elif (people_text_arr[0][0] == "*"):
    people_regex_str = re.compile("^\*\s*(\[\[.*?\]\]|[^ ]*)")
  elif (people_text_arr[0][0] == ":"):
    people_regex_str = re.compile("^:\s*(\[\[.*?\]\]|[^ ]*)")
  else:
    people_regex_str = re.compile("^(\[\[.*?\]\]|[^ ]*)")

  match_obj = people_regex_str.match(people_text_arr[0])
  people_text += match_obj.group(1)

  if(re.match("=", people_text_arr[0])):
    people_text = getUserList(text)
  else:
    for i in range(1,len(people_text_arr)):
      match_obj = people_regex_str.match(people_text_arr[i])
      if ((match_obj != None) and (len(match_obj.group(1)) != 0)):
        if(re.search("Category", people_text_arr[i])):
          pass
        elif (re.match("=", people_text_arr[i])):
          pass
        else:
          people_text += u", "
          people_text += match_obj.group(1)
  return people_text
<commit_msg>retrying parse without section recognition if no results are found<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wikipedia, re, string
import math

RE_LINKS = re.compile('(\[\[[Uu]ser *: *(.+?) *(?:\| *(.*?) *)?\]\])')

RE_USER = re.compile('\[\[[Uu]ser ?: ?(.+?) ?[\|\]]')
RE_LISTED = re.compile('\n\s*[\*#]\s*(\[.+?\]+|\S+)[^\n]*')
RE_RIBBONBEARER = re.compile('\{\{.*?\|\s*name ?=\s*(.+?)(?:\}|\|\s*\w+\s*=)', re.DOTALL)
RE_CARDRECIPIENT = re.compile('recipient ?=\s*(.+?)(?:\}|\|\s*\w+\s*=)')
RE_ENTITLED = re.compile('==+(\[\[[Uu]ser.*?\])=+=')
RE_MEETUP = re.compile('\{\{\s*[Mm]eet-up.*?\|\s*name\s*=\s*(.+?)(?:\}|\|\s*\w+\s*=)', re.DOTALL)
RE_FIRST = re.compile('^.*?(\[\[[Uu]ser.+?\]\])', re.DOTALL)

improbablenames = ["and", "i", "we", "the", "one", "all attendees", "everyone"]

def fuzzyadd(a,b): #combine two fuzzy values
  return (a+b)/2.0
  #return sqrt(a*a+b*b)

debug_fuzz = None
debug_links = None
def getDebugFuzz():
  global debug_fuzz
  return debug_fuzz

def getDebugLinks():
  global debug_links
  return debug_links

def normalize(dic):
  maxfuzz = 0
  for p,v in dic.items():
    if len(p)==0:
      del dic[p]
      continue
    if v>maxfuzz:
      maxfuzz=v
  if maxfuzz>0:
    for p,v in dic.items():
      dic[p]=v/maxfuzz
  return dic

def unscorify(word):
  return word.replace("_"," ")

def splitgrouped(word):
  return re.split(",| and |&", word)

def identifyParticipants(origtext, page, getLinks = False, getSections = True):
  global debug_fuzz
  global debug_links

  #print "===",page,"==="
  fuzzy = {} #user id -> probability of being a participant
  text = unscorify(origtext)

  pseudonyms = {}
  userlinks  = {}
  usernames  = {}

  if "[[Category:Not reached - Did not attempt]]" in text:
    return []

  scoring = {
    RE_USER: 1,
    RE_RIBBONBEARER: 3,
    RE_CARDRECIPIENT: -5,
    RE_ENTITLED: 20,
    RE_MEETUP: 10,
    RE_FIRST: 2,
  }

  if getSections:
    sections = getSectionRegex(text, "(participants?|(the )?people|attendees?|adventurers?)\??", True)
    if sections:
      scoring[RE_LISTED] = 5;
      text = sections

# identify pseudonyms, and user links
  links = RE_LINKS.findall(text)
  for part in links:
    pseudonyms[part[0].lower()] = part[1].lower()
    userlinks [part[1].lower()] = part[0]
    usernames [part[0].lower()] = part[1]
    if not part[2].lower() in improbablenames:
      pseudonyms[part[2].lower()] = part[1].lower()
      usernames [part[2].lower()] = part[1]
      userlinks [part[2].lower()] = part[0]

  text = text.lower()

  for rex, score in scoring.items():
    match = rex.findall(text)
    for group in match:
      parts = splitgrouped(group)
      for part in parts:
        part = part.lower().strip()
        if not part in improbablenames:
          if part in pseudonyms:
            fuzzy[pseudonyms[part]]=fuzzy.get(pseudonyms[part],0) + score
          else:
            fuzzy[part]=fuzzy.get(part,0) + score
            usernames[part.lower()] = part

  #increase the score of a potential participant by the number of mentions¹ vs total mentions
  mentions = {}
  mcount   = 0.0
  for p in fuzzy.keys():
    mentions[p] = len(re.findall(re.escape(p), text, re.IGNORECASE))
    mcount += mentions[p]
  for p in pseudonyms.keys():
    if p not in fuzzy.keys():
      pseudo_mentions = len(re.findall(re.escape(p), text, re.IGNORECASE)) + len(re.findall(re.escape(p), pseudonyms[p], re.IGNORECASE))
      if RE_USER.match(p):
        mentions_per_link = len(re.findall(re.escape(pseudonyms[p]), p, re.IGNORECASE))
        pseudo_mentions -= pseudo_mentions * mentions_per_link
      mentions[pseudonyms[p]] = mentions.get(pseudonyms[p],0) + pseudo_mentions
      mcount += pseudo_mentions

  if mcount>0:
    for p,v in mentions.items():
      fuzzy[p]=fuzzyadd(fuzzy.get(p,0),v/mcount)

  if len(fuzzy)==0: #only if we still don't have fuzz
    if getSections:
      return identifyParticipants(origtext, page, getLinks, getSections = False)

  if len(fuzzy)==0: #only if we still don't have fuzz
    history = page.getVersionHistory(getAll=True)
    #compare the edit history with the page content
    editors = [change[2] for change in history]
    for editor in editors:
      if editor.lower() in text.lower():
        fuzzy[editor]=0.5

  if len(fuzzy)==0: #only if we still don't have fuzz
    wlh = [r for r in page.getReferences()]
    #get user pages from the reference counter
    for l in wlh:
      if "User:" in l.title():
        fuzzy[l.title()[5:]]=0.5
    if len(fuzzy)>1: #but not too much, I say
      fuzzy = {}

  fuzzy = normalize(fuzzy)

  participants = []
  for p,v in fuzzy.items():
    if p in improbablenames:
      v = fuzzyadd(v,-1)
    if v>=0.35:
      participants.append(p)

  debug_fuzz = fuzzy
  debug_links = userlinks

  if getLinks:
    return [userlinks.get(p,p) for p in participants] #that is: return a list of [userlinks[p] if it exists, else return p]
  else:
    return participants

def getUsers(page):
  """
returns a list of expeditions participants found in the text of a geohashing expedition page.
ingredients: one wikipedia.Page object
  """
  text = page.get()
  title = page.title()
  wikipedia.output(u'Parsing %s...' % title)

  if(text[0] == u"="):  # a hack?
    text = u"\n" + text

  if(text[1] == u"="):
     text = u"\n" + text

#Generate the list of people
#First look in appropriately named "who" sections
  peopleSecText = getSectionRegex(text, "(participants?|people)\??")
  if(peopleSecText != None):
    peopleText = getPeopleText(text, peopleSecText)

#If that fails, look for all unique [[User:*]] tags in the expedition page
  if((peopleSecText == None) or (len(peopleText) == 0)):
    peopleText = getUserList(text)

  return peopleText

def getSections(text, subSects = None):
   text = "\n" + text
   if (subSects == None):
      split_text = re.split("\n", text)
      minlen = 99
      for line in split_text:
         match = re.match("\s*=+", line)
         if ((match != None) and (len(string.strip(match.group(0))) < minlen)):
            minlen = len(string.strip(match.group(0)))
      equal_str = u""
      for i in range(0,minlen):
         equal_str += u"="
      regex_text = u"\n\s*" + equal_str + "([^=]*?)" + equal_str
   else:
      regex_text = "\n\s*=+([^=]*?)=+"

   text_arr = re.split(regex_text, text)
   for i in range(0,len(text_arr)):
       text_arr[i] = string.strip(text_arr[i])

   section_hash = {}
   section_hash[""] = text_arr[0]

   for i in range(1,len(text_arr),2):
     title = string.lower(text_arr[i])
     section_hash[title] = section_hash.get(title,"") + text_arr[i+1]

#   for i in section_hash.keys():
#      print i + ":",
#      print ":" + section_hash[i]

   return section_hash

def getSection(text, name_arr, subSects = None):
  """
This will look for a section with one of the names in name_arr
The search is case insensitive, and returns the first match, starting from name_arr[0] and continuing to name_arr[len(name_arr)-1]
It will return the body of the appropriate section, or None if there were no matches for the section name.
If subSects != None, then it will search for all subsections which match as well.
  """
  sections = getSections(text, subSects)
  code = ""
  for header in name_arr:
      if header in sections:
          code += sections[header] +"\n"
  if ((len(name_arr) == 0) and ("" in sections)):
      return sections[""]
  if len(code)>0:
    return code
  return None

def getSectionRegex(text, regex_text, subSects = None):
    """
This will look for a section with a name that matches the regex_text
It will return the body of the appropriate section, or None if there were no matches for the section name.
If subSects != None, then it will search for all subsections which match as well.
    """
    sections = getSections(text, subSects)
    if ((regex_text == None) and ("" in sections)):
        return sections[""]
    else:
        for keys in sections.keys():
            if(re.match(regex_text, keys)):
                return sections[keys]
    return None

def getUserUist(text):
  """This will look for all unique user tags on a page, and make a list out of them."""
  regex_res = re.findall("\[\[User:.*?\]\]", text, re.I)
  regex_lower = []
  for i in range(0,len(regex_res)):
    regex_lower.append(re.sub("_", " ", regex_res[i].lower()))
    regex_lower[i] = re.sub(" ?| ?", "|", regex_lower[i])
    regex_lower[i] = re.sub("'s", "", regex_lower[i])
  result_arr = []
  for i in range(0,len(regex_lower)):
    for j in range(i+1,len(regex_lower)):
      if (regex_lower[i] == regex_lower[j]):
        break
      else:
        result_arr.append(regex_res[i])

  temp_str = u", "
  return temp_str.join(result_arr)

def getPeopleText(text, people_text):
  """This function will parse a list of users, and return them in a comma separated list."""
  people_text = re.sub("<!--.*?(-->|$)", "", people_text)
  people_text = string.strip(re.sub("^\[[^][]*?\]", "", people_text))
  people_text_arr = re.split("\n", people_text)

  people_text = u""

  if (len(people_text_arr[0]) == 0):
    people_regex_str = re.compile("^(\[\[.*?\]\]|[^ ]*)")
  elif (people_text_arr[0][0] == "*"):
    people_regex_str = re.compile("^\*\s*(\[\[.*?\]\]|[^ ]*)")
  elif (people_text_arr[0][0] == ":"):
    people_regex_str = re.compile("^:\s*(\[\[.*?\]\]|[^ ]*)")
  else:
    people_regex_str = re.compile("^(\[\[.*?\]\]|[^ ]*)")

  match_obj = people_regex_str.match(people_text_arr[0])
  people_text += match_obj.group(1)

  if(re.match("=", people_text_arr[0])):
    people_text = getUserList(text)
  else:
    for i in range(1,len(people_text_arr)):
      match_obj = people_regex_str.match(people_text_arr[i])
      if ((match_obj != None) and (len(match_obj.group(1)) != 0)):
        if(re.search("Category", people_text_arr[i])):
          pass
        elif (re.match("=", people_text_arr[i])):
          pass
        else:
          people_text += u", "
          people_text += match_obj.group(1)
  return people_text
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
r"""Format notebooks using the TensorFlow docs style.

Install dependencies:
$ pip3 install -U [--user] absl-py

Usage:
$ nbfmt.py [options] notebook.ipynb [...]
$ find . -name "*\.ipynb" | xargs ./tools/nbfmt.py

See the TensorFlow notebook template:
https://github.com/tensorflow/docs/blob/master/tools/templates/notebook.ipynb
And the TensorFlow docs contributor guide:
https://www.tensorflow.org/community/contribute/docs
"""
import json
import os
import pathlib
import re
import sys
import textwrap

from typing import Any, Dict, Optional

from absl import app
from absl import flags

OSS = True

flags.DEFINE_bool(
    "preserve_outputs", None,
    "Configures the notebook to either preserve, or clear outputs."
    "- If `True`: Set the notebook to keep outputs.\n"
    "- If `False`: Set the notebook to clear outputs.\n"
    "- If unset (`None`): keep the notebook's current setting.\n"
    "  - If it's not set in the notebook, set the notebook to preserve outputs "
    "(to match the colab default).\n"
    "If a notebook is configured to clear outputs, this script will clear them "
    "when run.\n"
    "Colab respects this setting. Jupyter does not.")
flags.DEFINE_integer(
    "indent", 2, "Indention level for pretty-printed JSON.", lower_bound=0)
flags.DEFINE_bool("test", False,
                  "Test if the notebook is formatted (useful for CI).")

FLAGS = flags.FLAGS

def warn(msg: str) -> None:
  """Print highlighted warning message to stderr.

  Args:
    msg: String to print to console.
  """
  # Use terminal codes to print color output to console.
  print(f" \033[33m {msg}\033[00m", file=sys.stderr)

def remove_extra_fields(data) -> None:
  """Deletes extra notebook fields.

  Jupyter format spec:
  https://nbformat.readthedocs.io/en/latest/format_description.html

  Args:
    data: object representing a parsed JSON notebook.
  """

  def filter_keys(data, keep_list) -> None:
    to_delete = set(data.keys()) - frozenset(keep_list)
    for key in to_delete:
      del data[key]

  # These top-level fields are required:
  filter_keys(data, ["cells", "metadata", "nbformat_minor", "nbformat"])
  # All metadata is optional according to spec, but we use some of it.
  # For example, this removes "language_info" and other editor-specific fields.
  filter_keys(data["metadata"], ["accelerator", "colab", "kernelspec"])

def clean_cells(data) -> None:
  """Remove empty cells and strip outputs from `data` object.

  Args:
    data: object representing a parsed JSON notebook.
  """
  remove_extra_fields(data)

  # Clear leading and trailing newlines.
  for cell in data["cells"]:
    source = cell["source"]
    while source and source[0] == "\n":
      source.pop(0)
    while source and source[-1] == "\n":
      source.pop()
    cell["source"] = source

  # remove empty cells
  data["cells"] = [cell for cell in data["cells"] if any(cell["source"])]

  # `private_outputs` will default to False. If `private_outputs` is True, then
  # the output will be removed from the notebook.
  private_outputs = (
      data.get("metadata", {}).get("colab", {}).get("private_outputs", False))

  has_outputs = False
  for cell in data["cells"]:
    if cell["cell_type"] != "code":
      continue

    # Clean cell metadata: remove the "executionInfo" block, this is what adds
    # the little user photos in Colab.
    cell_meta = cell.get("metadata", {})
    cell_meta.pop("executionInfo", None)
    cell["metadata"] = cell_meta

    # Clear any code cell outputs if notebook set to private outputs.
    if private_outputs and cell.get("outputs"):
      has_outputs = True
      # Clear code outputs
      cell["execution_count"] = 0
      cell["outputs"] = []

    # Ensure outputs field exists since part of the nbformat spec.
    if cell.get("outputs", None) is None:
      cell["outputs"] = []

  if has_outputs:
    warn("Removed the existing output cells.")

def update_metadata(data: Dict[str, Any],
                    filepath: Optional[pathlib.Path] = None) -> None:
  """Set notebook metadata on `data` object using TF docs style.

  Args:
    data: object representing a parsed JSON notebook.
    filepath: String of notebook filepath passed to the command-line.
  """
  metadata = data.get("metadata", {})
  colab = metadata.get("colab", {})
  # Set preferred metadata for notebook docs.
  if filepath is not None:
    colab["name"] = os.path.basename(filepath)

  colab["provenance"] = []
  colab["toc_visible"] = True
  # Always remove "last_runtime".
  colab.pop("last_runtime", None)

  metadata["colab"] = colab
  data["metadata"] = metadata

def update_license_cell(data: Dict[str, Any]) -> None:
  """Format license cell to hide code pane from the Colab form.

  Args:
    data: object representing a parsed JSON notebook.
  """
  # This pattern in Apache and MIT license boilerplate.
  license_re = re.compile(r"#@title.*License")

  for idx, cell in enumerate(data["cells"]):
    src_text = "".join(cell["source"])

    if license_re.search(src_text):
      # Hide code pane from license form
      metadata = cell.get("metadata", {})
      metadata["cellView"] = "form"
      data["cells"][idx]["metadata"] = metadata

def main(argv):
  if len(argv) <= 1:
    raise app.UsageError("Missing arguments.")

  found_error = False  # Track errors for final return code.
  test_fail_notebooks = []

  files = []
  for path in argv[1:]:
    path = pathlib.Path(path)
    if path.is_file():
      files.append(path)
    elif path.is_dir():
      files.extend(path.rglob("*.ipynb"))
    else:
      found_error = True
      warn(f"Bad arg: {str(path)}")

  for fp in files:
    print(f"Notebook: {fp}", file=sys.stderr)

    if fp.suffix != ".ipynb":
      warn("Not an '.ipynb' file, skipping.")
      found_error = True
      test_fail_notebooks.append(fp)
      continue

    with open(fp, "r", encoding="utf-8") as f:
      try:
        data = json.load(f)
      except ValueError as err:
        print(f"  {err.__class__.__name__}: {err}", file=sys.stderr)
        warn("Unable to load JSON, skipping.")
        found_error = True
        test_fail_notebooks.append(fp)
        continue

    if FLAGS.preserve_outputs is not None:
      # Overwrite the value of `private_outputs`
      colab = data.get("metadata", {}).get("colab", {})
      colab["private_outputs"] = not FLAGS.preserve_outputs
      data["metadata"]["colab"] = colab

    # Set top-level notebook defaults.
    data["nbformat"] = 4
    data["nbformat_minor"] = 0

    clean_cells(data)
    update_metadata(data, filepath=fp)
    update_license_cell(data)

    nbjson = json.dumps(
        data, sort_keys=True, ensure_ascii=False, indent=FLAGS.indent)
    if not OSS:
      nbjson = nbjson.replace("<", r"\u003c").replace(">", r"\u003e")
    expected_output = (nbjson + "\n").encode("utf-8")

    if FLAGS.test:
      # Compare formatted contents with original file contents.
      src_bytes = fp.read_bytes()
      if expected_output != src_bytes:
        test_fail_notebooks.append(fp)
    else:
      fp.write_bytes(expected_output)

  if FLAGS.test:
    if test_fail_notebooks:
      error_template = textwrap.dedent("""
      [test] The following notebooks are not formatted:
      {notebooks}
      Format with: nbfmt.py notebook.ipynb [...]
      """)
      notebooks = "\n".join([f"- {str(fp)}" for fp in test_fail_notebooks])
      print(error_template.format(notebooks=notebooks), file=sys.stderr)
      sys.exit(1)
    else:
      print("[test] Notebooks are formatted", file=sys.stderr)
      sys.exit(0)

  if found_error:
    sys.exit(1)

if __name__ == "__main__":
  app.run(main)
<commit_msg>nbfmt: fix error message<commit_after>#!/usr/bin/env python3
# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
r"""Format notebooks using the TensorFlow docs style.

Install dependencies:
$ pip3 install -U [--user] absl-py

Usage:
$ nbfmt.py [options] notebook.ipynb [...]
$ find . -name "*\.ipynb" | xargs ./tools/nbfmt.py

See the TensorFlow notebook template:
https://github.com/tensorflow/docs/blob/master/tools/templates/notebook.ipynb
And the TensorFlow docs contributor guide:
https://www.tensorflow.org/community/contribute/docs
"""
import json
import os
import pathlib
import re
import sys
import textwrap

from typing import Any, Dict, Optional

from absl import app
from absl import flags

OSS = True

flags.DEFINE_bool(
    "preserve_outputs", None,
    "Configures the notebook to either preserve, or clear outputs."
    "- If `True`: Set the notebook to keep outputs.\n"
    "- If `False`: Set the notebook to clear outputs.\n"
    "- If unset (`None`): keep the notebook's current setting.\n"
    "  - If it's not set in the notebook, set the notebook to preserve outputs "
    "(to match the colab default).\n"
    "If a notebook is configured to clear outputs, this script will clear them "
    "when run.\n"
    "Colab respects this setting. Jupyter does not.")
flags.DEFINE_integer(
    "indent", 2, "Indention level for pretty-printed JSON.", lower_bound=0)
flags.DEFINE_bool("test", False,
                  "Test if the notebook is formatted (useful for CI).")

FLAGS = flags.FLAGS

def warn(msg: str) -> None:
  """Print highlighted warning message to stderr.

  Args:
    msg: String to print to console.
  """
  # Use terminal codes to print color output to console.
  print(f" \033[33m {msg}\033[00m", file=sys.stderr)

def remove_extra_fields(data) -> None:
  """Deletes extra notebook fields.

  Jupyter format spec:
  https://nbformat.readthedocs.io/en/latest/format_description.html

  Args:
    data: object representing a parsed JSON notebook.
  """

  def filter_keys(data, keep_list) -> None:
    to_delete = set(data.keys()) - frozenset(keep_list)
    for key in to_delete:
      del data[key]

  # These top-level fields are required:
  filter_keys(data, ["cells", "metadata", "nbformat_minor", "nbformat"])
  # All metadata is optional according to spec, but we use some of it.
  # For example, this removes "language_info" and other editor-specific fields.
  filter_keys(data["metadata"], ["accelerator", "colab", "kernelspec"])

def clean_cells(data) -> None:
  """Remove empty cells and strip outputs from `data` object.

  Args:
    data: object representing a parsed JSON notebook.
  """
  remove_extra_fields(data)

  # Clear leading and trailing newlines.
  for cell in data["cells"]:
    source = cell["source"]
    while source and source[0] == "\n":
      source.pop(0)
    while source and source[-1] == "\n":
      source.pop()
    cell["source"] = source

  # remove empty cells
  data["cells"] = [cell for cell in data["cells"] if any(cell["source"])]

  # `private_outputs` will default to False. If `private_outputs` is True, then
  # the output will be removed from the notebook.
  private_outputs = (
      data.get("metadata", {}).get("colab", {}).get("private_outputs", False))

  has_outputs = False
  for cell in data["cells"]:
    if cell["cell_type"] != "code":
      continue

    # Clean cell metadata: remove the "executionInfo" block, this is what adds
    # the little user photos in Colab.
    cell_meta = cell.get("metadata", {})
    cell_meta.pop("executionInfo", None)
    cell["metadata"] = cell_meta

    # Clear any code cell outputs if notebook set to private outputs.
    if private_outputs and cell.get("outputs"):
      has_outputs = True
      # Clear code outputs
      cell["execution_count"] = 0
      cell["outputs"] = []

    # Ensure outputs field exists since part of the nbformat spec.
    if cell.get("outputs", None) is None:
      cell["outputs"] = []

  if has_outputs:
    warn("Removed the existing output cells.")

def update_metadata(data: Dict[str, Any],
                    filepath: Optional[pathlib.Path] = None) -> None:
  """Set notebook metadata on `data` object using TF docs style.

  Args:
    data: object representing a parsed JSON notebook.
    filepath: String of notebook filepath passed to the command-line.
  """
  metadata = data.get("metadata", {})
  colab = metadata.get("colab", {})
  # Set preferred metadata for notebook docs.
  if filepath is not None:
    colab["name"] = os.path.basename(filepath)

  colab["provenance"] = []
  colab["toc_visible"] = True
  # Always remove "last_runtime".
  colab.pop("last_runtime", None)

  metadata["colab"] = colab
  data["metadata"] = metadata

def update_license_cell(data: Dict[str, Any]) -> None:
  """Format license cell to hide code pane from the Colab form.

  Args:
    data: object representing a parsed JSON notebook.
  """
  # This pattern in Apache and MIT license boilerplate.
  license_re = re.compile(r"#@title.*License")

  for idx, cell in enumerate(data["cells"]):
    src_text = "".join(cell["source"])

    if license_re.search(src_text):
      # Hide code pane from license form
      metadata = cell.get("metadata", {})
      metadata["cellView"] = "form"
      data["cells"][idx]["metadata"] = metadata

def main(argv):
  if len(argv) <= 1:
    raise app.UsageError("Missing arguments.")

  found_error = False  # Track errors for final return code.
  test_fail_notebooks = []

  files = []
  for path in argv[1:]:
    path = pathlib.Path(path)
    if path.is_file():
      files.append(path)
    elif path.is_dir():
      files.extend(path.rglob("*.ipynb"))
    else:
      found_error = True
      warn(f"Invalid file or directory: {str(path)}")

  for fp in files:
    print(f"Notebook: {fp}", file=sys.stderr)

    if fp.suffix != ".ipynb":
      warn("Not an '.ipynb' file, skipping.")
      found_error = True
      test_fail_notebooks.append(fp)
      continue

    with open(fp, "r", encoding="utf-8") as f:
      try:
        data = json.load(f)
      except ValueError as err:
        print(f"  {err.__class__.__name__}: {err}", file=sys.stderr)
        warn("Unable to load JSON, skipping.")
        found_error = True
        test_fail_notebooks.append(fp)
        continue

    if FLAGS.preserve_outputs is not None:
      # Overwrite the value of `private_outputs`
      colab = data.get("metadata", {}).get("colab", {})
      colab["private_outputs"] = not FLAGS.preserve_outputs
      data["metadata"]["colab"] = colab

    # Set top-level notebook defaults.
    data["nbformat"] = 4
    data["nbformat_minor"] = 0

    clean_cells(data)
    update_metadata(data, filepath=fp)
    update_license_cell(data)

    nbjson = json.dumps(
        data, sort_keys=True, ensure_ascii=False, indent=FLAGS.indent)
    if not OSS:
      nbjson = nbjson.replace("<", r"\u003c").replace(">", r"\u003e")
    expected_output = (nbjson + "\n").encode("utf-8")

    if FLAGS.test:
      # Compare formatted contents with original file contents.
      src_bytes = fp.read_bytes()
      if expected_output != src_bytes:
        test_fail_notebooks.append(fp)
    else:
      fp.write_bytes(expected_output)

  if FLAGS.test:
    if test_fail_notebooks:
      error_template = textwrap.dedent("""
      [test] The following notebooks are not formatted:
      {notebooks}
      Format with: nbfmt.py notebook.ipynb [...]
      """)
      notebooks = "\n".join([f"- {str(fp)}" for fp in test_fail_notebooks])
      print(error_template.format(notebooks=notebooks), file=sys.stderr)
      sys.exit(1)
    else:
      print("[test] Notebooks are formatted", file=sys.stderr)
      sys.exit(0)

  if found_error:
    sys.exit(1)

if __name__ == "__main__":
  app.run(main)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
    # Clay

    A rapid prototyping tool

    ------------
    Copyright © 2011 by [Lúcuma labs] (http://lucumalabs.com).
    See `AUTHORS.md` for more details.
    License: [MIT License] (http://www.opensource.org/licenses/mit-license.php).

"""
from .core import *

__version__ = '0.2.1'
<commit_msg>version bumped to 0.22<commit_after># -*- coding: utf-8 -*-
"""
    # Clay

    A rapid prototyping tool

    ------------
    Copyright © 2011 by [Lúcuma labs] (http://lucumalabs.com).
    See `AUTHORS.md` for more details.
    License: [MIT License] (http://www.opensource.org/licenses/mit-license.php).

"""
from .core import *

__version__ = '0.22'
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import os.path
import codecs
import dfstrings
import time
import optparse

def make_js_from_po(path):
    strings = []
    for po in [p for p in dfstrings.get_po_strings(path) if "scope" in p and "dragonfly" in p["scope"] ]:
        strings.append(u"""ui_strings.%s="%s";""" % (po["jsname"], po["msgstr"]))
    return """/* Generated from %s at %s */
window.ui_strings || ( window.ui_strings  = {} )
window.ui_strings.lang_code = "%s";
%s""" % (unicode(os.path.basename(path)),
        unicode(time.asctime()),
        unicode(os.path.splitext(os.path.basename(path))[0]),
        u"\n".join(strings))

def _process_file(inpath, outfd):
    lines = [p["msgstr"] for p in dfstrings.get_po_strings(inpath)
        if "scope" in p and "dragonfly" in p["scope"] ]

    bad_escaped = dfstrings.get_strings_with_bad_escaping(lines)
    if bad_escaped:
        print "error: %s contains strings with bad escaping: %s" % (inpath, bad_escaped)
        return 1

    bad_format = dfstrings.get_strings_with_bad_format(lines)
    if bad_format:
        print "error: %s contains strings with bad formatting: %s" % (inpath, bad_format)
        return 1

    data = make_js_from_po(inpath)
    outfd.write(data)

def _process_dir(dirpath, destpath):
    files = _find_pofiles(dirpath)
    files.sort()

    for i, path in enumerate(files):
        out = os.path.join(destpath, "ui_strings-%s.js" % os.path.basename(path)[:-3])
        print "writing %s. (%s of %s)" % (out, i+1, len(files))
        outfd = codecs.open(out, "w", encoding="utf_8_sig")
        _process_file(path, outfd)
        outfd.close()

def _find_pofiles(top):
    """Make a list of all po files in dirctory top, or any subdir"""
    matches = []
    for dirpath, dirnames, filenames in os.walk(top):
        # only add files that are 5 chars long (<countrycode>.po)
        # and that ends in .po
        # and that does not already exist in the matches list
        # Search is top down, so most shallow match will remain
        matches.extend([os.path.join(dirpath, e)
                        for e in filenames
                        if len(e) == 5
                        and e.endswith(".po")
                        and e not in [os.path.basename(x) for x in matches]])
    return matches

def _parse_options():
    usage = """%prog [options] input [output]"""

    parser = optparse.OptionParser(usage)
    parser.add_option("-d", "--directory", dest="directory",
                      default=False, action="store_true",
                      help="Operate on directories rather than single files")

    options, args = parser.parse_args()

    if len(args) == 0:
        parser.error("Not enough arguments")

    if options.directory and len(args) != 2:
        parser.error("Need both source and target directory")

    return options, args

def main():
    options, args = _parse_options()

    if options.directory:
        _process_dir(args[0], args[1])
    else:
        outfd = sys.stdout
        if len(args) > 1:
            outfd = codecs.open(sys.argv[1], "w", encoding="utf_8_sig")

        _process_file(args[0], outfd)

        if not outfd is sys.stdout:
            outfd.close()

    return 0

if __name__ == "__main__":
    sys.exit(main())

<commit_msg>Made the po file detection less dumb<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import os.path
import codecs
import dfstrings
import time
import optparse

def make_js_from_po(path):
    strings = []
    for po in [p for p in dfstrings.get_po_strings(path) if "scope" in p and "dragonfly" in p["scope"] ]:
        strings.append(u"""ui_strings.%s="%s";""" % (po["jsname"], po["msgstr"]))
    return """/* Generated from %s at %s */
window.ui_strings || ( window.ui_strings  = {} )
window.ui_strings.lang_code = "%s";
%s""" % (unicode(os.path.basename(path)),
        unicode(time.asctime()),
        unicode(os.path.splitext(os.path.basename(path))[0]),
        u"\n".join(strings))

def _process_file(inpath, outfd):
    lines = [p["msgstr"] for p in dfstrings.get_po_strings(inpath)
        if "scope" in p and "dragonfly" in p["scope"] ]

    bad_escaped = dfstrings.get_strings_with_bad_escaping(lines)
    if bad_escaped:
        print "error: %s contains strings with bad escaping: %s" % (inpath, bad_escaped)
        return 1

    bad_format = dfstrings.get_strings_with_bad_format(lines)
    if bad_format:
        print "error: %s contains strings with bad formatting: %s" % (inpath, bad_format)
        return 1

    data = make_js_from_po(inpath)
    outfd.write(data)

def _process_dir(dirpath, destpath):
    files = _find_pofiles(dirpath)
    files.sort()

    for i, path in enumerate(files):
        out = os.path.join(destpath, "ui_strings-%s.js" % os.path.basename(path)[:-3])
        print "writing %s. (%s of %s)" % (out, i+1, len(files))
        outfd = codecs.open(out, "w", encoding="utf_8_sig")
        _process_file(path, outfd)
        outfd.close()

def _find_pofiles(top):
    """Make a list of all po files in dirctory top, or any subdir"""
    matches = []
    for dirpath, dirnames, filenames in os.walk(top):
        # only add files that are named <something>.po and that is in
        # a dir named <something>. As in, dirname and filename must match.
        matches.extend([os.path.join(dirpath, e)
                        for e in filenames
                        if os.path.basename(dirpath)+".po" == e])
    return matches

def _parse_options():
    usage = """%prog [options] input [output]"""

    parser = optparse.OptionParser(usage)
    parser.add_option("-d", "--directory", dest="directory",
                      default=False, action="store_true",
                      help="Operate on directories rather than single files")

    options, args = parser.parse_args()

    if len(args) == 0:
        parser.error("Not enough arguments")

    if options.directory and len(args) != 2:
        parser.error("Need both source and target directory")

    return options, args

def main():
    options, args = _parse_options()

    if options.directory:
        _process_dir(args[0], args[1])
    else:
        outfd = sys.stdout
        if len(args) > 1:
            outfd = codecs.open(sys.argv[1], "w", encoding="utf_8_sig")

        _process_file(args[0], outfd)

        if not outfd is sys.stdout:
            outfd.close()

    return 0

if __name__ == "__main__":
    sys.exit(main())

<|endoftext|>


<commit_before>from clay.ast import *
from clay.env import *
from clay.types import *
from clay.error import *
from clay.multimethod import multimethod

#
# env operations
#

def addIdent(env, name, entry) :
    assert type(name) is Identifier
    if env.hasEntry(name.s) :
        raiseError("name redefinition", name)
    env.add(name.s, entry)

def lookupIdent(env, name) :
    assert type(name) is Identifier
    entry = env.lookup(name.s)
    if entry is None :
        raiseError("undefined name", name)
    return entry

def lookupPredicate(env, name) :
    x = lookupIdent(env, name)
    if type(x) is not PredicateEntry :
        raiseError("not a predicate", name)
    return x

def lookupOverloadable(env, name) :
    x = lookupIdent(env, name)
    if type(x) is not OverloadableEntry :
        raiseError("not an overloadable", name)
    return x

#
# primitivesEnv
#

def primitivesEnv() :
    env = Env()
    def a(name, klass) :
        env.add(name, klass(env,None))
    a("Bool", BoolTypeEntry)
    a("Char", CharTypeEntry)
    a("Int", IntTypeEntry)
    a("Void", VoidTypeEntry)
    a("Array", ArrayTypeEntry)
    a("Ref", RefTypeEntry)

    a("default", PrimOpDefault)
    a("array", PrimOpArray)
    a("arraySize", PrimOpArraySize)
    a("arrayValue", PrimOpArrayValue)

    a("boolNot", PrimOpBoolNot)
    a("charToInt", PrimOpCharToInt)
    a("intToChar", PrimOpIntToChar)
    a("charEquals", PrimOpCharEquals)
    a("charLesser", PrimOpCharLesser)
    a("charLesserEquals", PrimOpCharLesserEquals)
    a("charGreater", PrimOpCharGreater)
    a("charGreaterEquals", PrimOpCharGreaterEquals)
    a("intAdd", PrimOpIntAdd)
    a("intSubtract", PrimOpIntSubtract)
    a("intMultiply", PrimOpIntMultiply)
    a("intDivide", PrimOpIntDivide)
    a("intModulus", PrimOpIntModulus)
    a("intNegate", PrimOpIntNegate)
    a("intEquals", PrimOpIntEquals)
    a("intLesser", PrimOpIntLesser)
    a("intLesserEquals", PrimOpIntLesserEquals)
    a("intGreater", PrimOpIntGreater)
    a("intGreaterEquals", PrimOpIntGreaterEquals)
    return env

#
# buildTopLevelEnv
#

def buildTopLevelEnv(program) :
    env = Env(primitivesEnv())
    for item in program.topLevelItems :
        addTopLevel(item, env)

addTopLevel = multimethod()

@addTopLevel.register(PredicateDef)
def foo(x, env) :
    addIdent(env, x.name, PredicateEntry(env,x))

@addTopLevel.register(InstanceDef)
def foo(x, env) :
    entry = InstanceEntry(env, x)
    lookupPredicate(env, x.name).instances.append(entry)

@addTopLevel.register(RecordDef)
def foo(x, env) :
    addIdent(env, x.name, RecordEntry(env,x))

@addTopLevel.register(StructDef)
def foo(x, env) :
    addIdent(env, x.name, StructEntry(env,x))

@addTopLevel.register(VariableDef)
def foo(x, env) :
    defEntry = VariableDefEntry(env, x)
    for i,variable in enumerate(x.variables) :
        addIdent(env, variable.name, VariableEntry(env,defEntry,i))

@addTopLevel.register(ProcedureDef)
def foo(x, env) :
    addIdent(env, x.name, ProcedureEntry(env,x))

@addTopLevel.register(OverloadableDef)
def foo(x, env) :
    addIdent(env, x.name, OverloadableEntry(env,x))

@addTopLevel.register(OverloadDef)
def foo(x, env) :
    entry = OverloadEntry(env, x)
    lookupOverloadable(env, x.name).overloads.append(entry)

#
# error checking getters
#

def oneTypeParam(container, memberList) :
    if len(memberList) != 1 :
        raiseError("exactly one type parameter expected", container)
    return memberList[0]

def nTypeParams(n, container, memberList) :
    if len(memberList) != n :
        raiseError("exactly %d type parameter(s) expected" % n, container)
    return memberList

def oneArg(container, memberList) :
    if len(memberList) != 1 :
        raiseError("exactly one argument expected", container)
    return memberList[0]

def nArgs(n, container, memberList) :
    if len(memberList) !+ n :
        raiseError("exactly %d argument(s) expected" % n, container)
    return memberList

def intLiteralValue(x) :
    if type(x) is not IntLiteral :
        raiseError("int literal expected", x)
    return x.value

#
# inferType : (expr, env) -> (isValue, type)
#             throws RecursiveInferenceError
#

class RecursiveInferenceError(Exception) :
    def __init__(self, astNode) :
        self.astNode = astNode

inferType = multimethod()

def inferValueType(x, env, verify=None) :
    isValue, resultType = inferType(x, env)
    if not isValue :
        raiseError("value expected", x)
    if verify is not None :
        if not verify(resultType) :
            raiseError("invalid type", x)
    return resultType

def inferTypeType(x, env, verify=None) :
    isValue, resultType = inferType(x, env)
    if not isValue :
        raiseError("type expected", x)
    if verify is not None :
        if not verify(resultType) :
            raiseError("invalid type", x)
    return resultType

@inferType.register(AddressOfExpr)
def foo(x, env) :
    return True, RefType(inferValueType(x.expr, env))

@inferType.register(IndexExpr)
def foo(x, env) :
    if type(x.expr) is NameRef :
        entry = lookupIdent(env, x.expr.name)
        handler = inferNamedIndexExpr.getHandler(type(entry))
        if handler is not None :
            return handler(entry, x, env)
    return inferArrayIndexing(x, env)

def inferArrayIndexing(x, env) :
    def isIndexable(t) :
        return isArrayType(t) or isArrayValueType(t)
    indexableType = inferValueType(x.expr, env, isIndexable)
    index = oneArg(x, x.indexes)
    indexType = inferValueType(index, env, isIntType)
    return True, indexableType.type

# begin inferNamedIndexExpr

inferNamedIndexExpr = multimethod()

@inferNamedIndexExpr.register(ArrayTypeEntry)
def foo(entry, x, env) :
    typeParam = oneTypeParam(x, x.indexes)
    return False, ArrayType(inferTypeType(typeParam, env))

@inferNamedIndexExpr.register(ArrayValueTypeEntry)
def foo(entry, x, env) :
    typeParam, size = nTypeParams(2, x, x.indexes)
    typeParam = inferTypeType(typeParam, env)
    return False, ArrayValueType(typeParam, intLiteralValue(size))

@inferNamedIndexExpr.register(RefTypeEntry)
def foo(entry, x, env) :
    typeParam = oneTypeParam(x, x.indexes)
    return False, RefType(inferTypeType(typeParam, env))

@inferNamedIndexExpr.register(RecordEntry)
def foo(entry, x, env) :
    assert False

@inferNamedIndexExpr.register(StructEntry)
def foo(entry, x, env) :
    assert False

# end inferNamedIndexExpr

@inferType.register(CallExpr)
def foo(x, env) :
    if type(x.expr) is NameRef :
        entry = lookupIdent(env, x.expr.name)
        handler = inferNamedCallExpr.getHandler(type(entry))
        if handler is not None :
            return handler(entry, x, env)
    return inferIndirectCall(x, env)

def insertIndirectCall(x, env) :
    def isCallable(t) :
        return isRecordType(t) or isStructType(t)
    callableType = inferTypeType(x.expr, env, isCallable)
    assert False

# begin inferNamedCallExpr

inferNamedCallExpr = multimethod()

@inferNamedCallExpr.register(PrimOpDefault)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferTypeType(arg, env)
    return True, argType

@inferNamedCallExpr.register(PrimOpArray)
def foo(entry, x, env) :
    args = nArgs(2, x, x.args)
    nType = inferValueType(args[0], env, isIntType)
    vType = inferValueType(args[1], env)
    return True, ArrayType(vType)

@inferNamedCallExpr.register(PrimOpArraySize)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    arrayType = inferValueType(arg, env, isArrayType)
    return True, intType

@inferNamedCallExpr.register(PrimOpArrayValue)
def foo(entry, x, env) :
    args = nArgs(2, x, x.args)
    n = intLiteralValue(args[0])
    vType = inferValueType(args[1], env)
    return True, ArrayValueType(vType, n)

@inferNamedCallExpr.register(PrimOpBoolNot)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferValueType(arg, env, isBoolType)
    return True, boolType

@inferNamedCallExpr.register(PrimOpCharToInt)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferValueType(arg, env, isCharType)
    return True, intType

@inferNamedCallExpr.register(PrimOpIntToChar)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferValueType(arg, env, isIntType)
    return True, charType

def inferCharComparison(entry, x, env) :
    args = nArgs(2, x, x.args)
    arg1Type = inferValueType(args[0], env, isCharType)
    arg2Type = inferValueType(args[1], env, isCharType)
    return True, boolType

inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharEquals)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharLesser)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharLesserEquals)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharGreater)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharGreaterEquals)

def inferIntBinaryOp(entry, x, env) :
    args = nArgs(2, x, x.args)
    arg1Type = inferValueType(args[0], env, isIntType)
    arg2Type = inferValueType(args[1], env, isIntType)
    return True, intType

inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntAdd)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntSubtract)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntMultiply)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntDivide)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntModulus)

@inferNamedCallExpr.register(PrimOpIntNegate)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferValueType(arg, env, isIntType)
    return True, intType

def inferIntComparison(entry, x, env) :
    args = nArgs(2, x, x.args)
    arg1Type = inferValueType(args[0], env, isIntType)
    arg2Type = inferValueType(args[1], env, isIntType)
    return True, boolType

inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntEquals)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntLesser)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntLesserEquals)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntGreater)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntGreaterEquals)

@inferNamedCallExpr.register(RecordEntry)
def foo(entry, x, env) :
    assert False

@inferNamedCallExpr.register(StructEntry)
def foo(entry, x, env) :
    assert False

@inferNamedCallExpr.register(ProcedureEntry)
def foo(entry, x, env) :
    argsInfo = tuple([inferExpr(y, env) for y in x.args])
    returnType = entry.returnTypes.get(argsInfo)
    if returnType is not None :
        if returnType is False :
            raise RecursiveInferenceError(x)
        return True, returnType
    entry.returnTypes[argsInfo] = False
    returnType = None
    try :
        returnType = inferProcedureReturnType(entry, argsInfo, x)
        return returnType
    finally :
        if returnType is None :
            del entry.returnTypes[argsInfo]
        else :
            entry.returnTypes[argsInfo] = returnType

def bindTypeVariables(env, typeVarNames) :
    tvarEntries = []
    for tvarName in ast.typeVars :
        tvarEntry = TypeVarEntry(env, tvarName, TypeVariable())
        tvarEntries.append(tvarEntry)
        addIdent(env, tvarName, tvarEntry)
    return tvarEntries

def reduceTypeVariables(typeVarEntries) :
    for entry in typeVarEntries :
        t = typeDeref(entry.type)
        if t is None :
            raiseError("unresolved type variable", entry.ast)
        entry.type = t

def inferProcedureReturnType(entry, argsInfo, callExpr) :
    ast = entry.ast
    if len(ast.args) != len(argsInfo) :
        raiseError("incorrect no. of arguments", callExpr)
    env = Env(entry.env)
    typeVarEntries = bindTypeVariables(env, ast.typeVars)
    for i, formalArg in enumerate(ast.args) :
        isValue, argType = argsInfo[i]
        if type(formalArg) is ValueArgument :
            if not isValue :
                raiseError("expected a value", callExpr.args[i])
            formalTypeExpr = arg.variable.type
        elif type(formalArg) is TypeArgument :
            if isValue :
                raiseError("expected a type", callExpr.args[i])
            formalTypeExpr = arg.type
        else :
            assert False
        formalType = inferTypeType(formalTypeExpr, env)
        if not typeUnify(typePattern, argType) :
            raiseError("type mismatch", callExpr.args[i])
    if ast.typeConditions is not None :
        assert False
    reduceTypeVariables(typeVarEntries)
    for i, formalArg in enumerate(arg.args) :
        isValue, argType = argsInfo[i]
        if type(formalArg) is ValueArgument :
            if formalArg.isRef :
                argType = RefType(argType)
            argName = formalArg.variable.name
            localVarEntry = LocalVariableEntry(env, argName, argType)
            addIdent(env, argName, localVarEntry)
    declaredReturnType = None
    if ast.returnType is not None :
        declaredReturnType = inferTypeType(ast.returnType, env)
    assert False

@inferNamedCallExpr.register(OverloadableEntry)
def foo(entry, x, env) :
    assert False

@inferNamedCallExpr.register(TypeVarEntry)
def foo(entry, x, env) :
    assert False

# end inferNamedCallExpr

#
# remove temp name used for multimethod instances
#

del foo
<commit_msg>fixed several bugs, and added stub implementations for remaining cases of inferExpr.<commit_after>from clay.ast import *
from clay.env import *
from clay.types import *
from clay.error import *
from clay.multimethod import multimethod

#
# env operations
#

def addIdent(env, name, entry) :
    assert type(name) is Identifier
    if env.hasEntry(name.s) :
        raiseError("name redefinition", name)
    env.add(name.s, entry)

def lookupIdent(env, name) :
    assert type(name) is Identifier
    entry = env.lookup(name.s)
    if entry is None :
        raiseError("undefined name", name)
    return entry

def lookupPredicate(env, name) :
    x = lookupIdent(env, name)
    if type(x) is not PredicateEntry :
        raiseError("not a predicate", name)
    return x

def lookupOverloadable(env, name) :
    x = lookupIdent(env, name)
    if type(x) is not OverloadableEntry :
        raiseError("not an overloadable", name)
    return x

#
# primitivesEnv
#

def primitivesEnv() :
    env = Env()
    def a(name, klass) :
        env.add(name, klass(env,None))
    a("Bool", BoolTypeEntry)
    a("Char", CharTypeEntry)
    a("Int", IntTypeEntry)
    a("Void", VoidTypeEntry)
    a("Array", ArrayTypeEntry)
    a("Ref", RefTypeEntry)

    a("default", PrimOpDefault)
    a("array", PrimOpArray)
    a("arraySize", PrimOpArraySize)
    a("arrayValue", PrimOpArrayValue)

    a("boolNot", PrimOpBoolNot)
    a("charToInt", PrimOpCharToInt)
    a("intToChar", PrimOpIntToChar)
    a("charEquals", PrimOpCharEquals)
    a("charLesser", PrimOpCharLesser)
    a("charLesserEquals", PrimOpCharLesserEquals)
    a("charGreater", PrimOpCharGreater)
    a("charGreaterEquals", PrimOpCharGreaterEquals)
    a("intAdd", PrimOpIntAdd)
    a("intSubtract", PrimOpIntSubtract)
    a("intMultiply", PrimOpIntMultiply)
    a("intDivide", PrimOpIntDivide)
    a("intModulus", PrimOpIntModulus)
    a("intNegate", PrimOpIntNegate)
    a("intEquals", PrimOpIntEquals)
    a("intLesser", PrimOpIntLesser)
    a("intLesserEquals", PrimOpIntLesserEquals)
    a("intGreater", PrimOpIntGreater)
    a("intGreaterEquals", PrimOpIntGreaterEquals)
    return env

#
# buildTopLevelEnv
#

def buildTopLevelEnv(program) :
    env = Env(primitivesEnv())
    for item in program.topLevelItems :
        addTopLevel(item, env)

addTopLevel = multimethod()

@addTopLevel.register(PredicateDef)
def foo(x, env) :
    addIdent(env, x.name, PredicateEntry(env,x))

@addTopLevel.register(InstanceDef)
def foo(x, env) :
    entry = InstanceEntry(env, x)
    lookupPredicate(env, x.name).instances.append(entry)

@addTopLevel.register(RecordDef)
def foo(x, env) :
    addIdent(env, x.name, RecordEntry(env,x))

@addTopLevel.register(StructDef)
def foo(x, env) :
    addIdent(env, x.name, StructEntry(env,x))

@addTopLevel.register(VariableDef)
def foo(x, env) :
    defEntry = VariableDefEntry(env, x)
    for i,variable in enumerate(x.variables) :
        addIdent(env, variable.name, VariableEntry(env,defEntry,i))

@addTopLevel.register(ProcedureDef)
def foo(x, env) :
    addIdent(env, x.name, ProcedureEntry(env,x))

@addTopLevel.register(OverloadableDef)
def foo(x, env) :
    addIdent(env, x.name, OverloadableEntry(env,x))

@addTopLevel.register(OverloadDef)
def foo(x, env) :
    entry = OverloadEntry(env, x)
    lookupOverloadable(env, x.name).overloads.append(entry)

#
# error checking getters
#

def oneTypeParam(container, memberList) :
    if len(memberList) != 1 :
        raiseError("exactly one type parameter expected", container)
    return memberList[0]

def nTypeParams(n, container, memberList) :
    if len(memberList) != n :
        raiseError("exactly %d type parameter(s) expected" % n, container)
    return memberList

def oneArg(container, memberList) :
    if len(memberList) != 1 :
        raiseError("exactly one argument expected", container)
    return memberList[0]

def nArgs(n, container, memberList) :
    if len(memberList) != n :
        raiseError("exactly %d argument(s) expected" % n, container)
    return memberList

def intLiteralValue(x) :
    if type(x) is not IntLiteral :
        raiseError("int literal expected", x)
    return x.value

#
# inferType : (expr, env) -> (isValue, type)
#             throws RecursiveInferenceError
#

class RecursiveInferenceError(Exception) :
    def __init__(self, astNode) :
        super(RecursiveInferenceError, self).__init__()
        self.astNode = astNode

inferType = multimethod()

def inferValueType(x, env, verify=None) :
    isValue, resultType = inferType(x, env)
    if not isValue :
        raiseError("value expected", x)
    if verify is not None :
        if not verify(resultType) :
            raiseError("invalid type", x)
    return resultType

def inferTypeType(x, env, verify=None) :
    isValue, resultType = inferType(x, env)
    if not isValue :
        raiseError("type expected", x)
    if verify is not None :
        if not verify(resultType) :
            raiseError("invalid type", x)
    return resultType

@inferType.register(AddressOfExpr)
def foo(x, env) :
    return True, RefType(inferValueType(x.expr, env))

@inferType.register(IndexExpr)
def foo(x, env) :
    if type(x.expr) is NameRef :
        entry = lookupIdent(env, x.expr.name)
        handler = inferNamedIndexExpr.getHandler(type(entry))
        if handler is not None :
            return handler(entry, x, env)
    return inferArrayIndexing(x, env)

def inferArrayIndexing(x, env) :
    def isIndexable(t) :
        return isArrayType(t) or isArrayValueType(t)
    indexableType = inferValueType(x.expr, env, isIndexable)
    index = oneArg(x, x.indexes)
    inferValueType(index, env, isIntType)
    return True, indexableType.type

# begin inferNamedIndexExpr

inferNamedIndexExpr = multimethod()

@inferNamedIndexExpr.register(ArrayTypeEntry)
def foo(entry, x, env) :
    typeParam = oneTypeParam(x, x.indexes)
    return False, ArrayType(inferTypeType(typeParam, env))

@inferNamedIndexExpr.register(ArrayValueTypeEntry)
def foo(entry, x, env) :
    typeParam, size = nTypeParams(2, x, x.indexes)
    typeParam = inferTypeType(typeParam, env)
    return False, ArrayValueType(typeParam, intLiteralValue(size))

@inferNamedIndexExpr.register(RefTypeEntry)
def foo(entry, x, env) :
    typeParam = oneTypeParam(x, x.indexes)
    return False, RefType(inferTypeType(typeParam, env))

@inferNamedIndexExpr.register(RecordEntry)
def foo(entry, x, env) :
    raise NotImplementedError

@inferNamedIndexExpr.register(StructEntry)
def foo(entry, x, env) :
    raise NotImplementedError

# end inferNamedIndexExpr

@inferType.register(CallExpr)
def foo(x, env) :
    if type(x.expr) is NameRef :
        entry = lookupIdent(env, x.expr.name)
        handler = inferNamedCallExpr.getHandler(type(entry))
        if handler is not None :
            return handler(entry, x, env)
    return inferIndirectCall(x, env)

def inferIndirectCall(x, env) :
    def isCallable(t) :
        return isRecordType(t) or isStructType(t)
    inferTypeType(x.expr, env, isCallable)
    raise NotImplementedError

# begin inferNamedCallExpr

inferNamedCallExpr = multimethod()

@inferNamedCallExpr.register(PrimOpDefault)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    argType = inferTypeType(arg, env)
    return True, argType

@inferNamedCallExpr.register(PrimOpArray)
def foo(entry, x, env) :
    args = nArgs(2, x, x.args)
    inferValueType(args[0], env, isIntType)
    vType = inferValueType(args[1], env)
    return True, ArrayType(vType)

@inferNamedCallExpr.register(PrimOpArraySize)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    inferValueType(arg, env, isArrayType)
    return True, intType

@inferNamedCallExpr.register(PrimOpArrayValue)
def foo(entry, x, env) :
    args = nArgs(2, x, x.args)
    n = intLiteralValue(args[0])
    vType = inferValueType(args[1], env)
    return True, ArrayValueType(vType, n)

@inferNamedCallExpr.register(PrimOpBoolNot)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    inferValueType(arg, env, isBoolType)
    return True, boolType

@inferNamedCallExpr.register(PrimOpCharToInt)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    inferValueType(arg, env, isCharType)
    return True, intType

@inferNamedCallExpr.register(PrimOpIntToChar)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    inferValueType(arg, env, isIntType)
    return True, charType

def inferCharComparison(entry, x, env) :
    args = nArgs(2, x, x.args)
    inferValueType(args[0], env, isCharType)
    inferValueType(args[1], env, isCharType)
    return True, boolType

inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharEquals)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharLesser)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharLesserEquals)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharGreater)
inferNamedCallExpr.addHandler(inferCharComparison, PrimOpCharGreaterEquals)

def inferIntBinaryOp(entry, x, env) :
    args = nArgs(2, x, x.args)
    inferValueType(args[0], env, isIntType)
    inferValueType(args[1], env, isIntType)
    return True, intType

inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntAdd)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntSubtract)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntMultiply)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntDivide)
inferNamedCallExpr.addHandler(inferIntBinaryOp, PrimOpIntModulus)

@inferNamedCallExpr.register(PrimOpIntNegate)
def foo(entry, x, env) :
    arg = oneArg(x, x.args)
    inferValueType(arg, env, isIntType)
    return True, intType

def inferIntComparison(entry, x, env) :
    args = nArgs(2, x, x.args)
    inferValueType(args[0], env, isIntType)
    inferValueType(args[1], env, isIntType)
    return True, boolType

inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntEquals)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntLesser)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntLesserEquals)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntGreater)
inferNamedCallExpr.addHandler(inferIntComparison, PrimOpIntGreaterEquals)

@inferNamedCallExpr.register(RecordEntry)
def foo(entry, x, env) :
    raise NotImplementedError

@inferNamedCallExpr.register(StructEntry)
def foo(entry, x, env) :
    raise NotImplementedError

@inferNamedCallExpr.register(ProcedureEntry)
def foo(entry, x, env) :
    argsInfo = tuple([inferType(y, env) for y in x.args])
    returnType = entry.returnTypes.get(argsInfo)
    if returnType is not None :
        if returnType is False :
            raise RecursiveInferenceError(x)
        return True, returnType
    entry.returnTypes[argsInfo] = False
    returnType = None
    try :
        returnType = inferProcedureReturnType(entry, argsInfo, x)
        return returnType
    finally :
        if returnType is None :
            del entry.returnTypes[argsInfo]
        else :
            entry.returnTypes[argsInfo] = returnType

def bindTypeVariables(env, typeVarNames) :
    tvarEntries = []
    for tvarName in typeVarNames :
        tvarEntry = TypeVarEntry(env, tvarName, TypeVariable())
        tvarEntries.append(tvarEntry)
        addIdent(env, tvarName, tvarEntry)
    return tvarEntries

def reduceTypeVariables(typeVarEntries) :
    for entry in typeVarEntries :
        t = typeDeref(entry.type)
        if t is None :
            raiseError("unresolved type variable", entry.ast)
        entry.type = t

def inferProcedureReturnType(entry, argsInfo, callExpr) :
    ast = entry.ast
    if len(ast.args) != len(argsInfo) :
        raiseError("incorrect no. of arguments", callExpr)
    env = Env(entry.env)
    typeVarEntries = bindTypeVariables(env, ast.typeVars)
    for i, formalArg in enumerate(ast.args) :
        isValue, argType = argsInfo[i]
        if type(formalArg) is ValueArgument :
            if not isValue :
                raiseError("expected a value", callExpr.args[i])
            formalTypeExpr = formalArg.variable.type
        elif type(formalArg) is TypeArgument :
            if isValue :
                raiseError("expected a type", callExpr.args[i])
            formalTypeExpr = formalArg.type
        else :
            assert False
        formalType = inferTypeType(formalTypeExpr, env)
        if not typeUnify(formalType, argType) :
            raiseError("type mismatch", callExpr.args[i])
    if ast.typeConditions is not None :
        raise NotImplementedError
    reduceTypeVariables(typeVarEntries)
    for i, formalArg in enumerate(ast.args) :
        isValue, argType = argsInfo[i]
        if type(formalArg) is ValueArgument :
            if formalArg.isRef :
                argType = RefType(argType)
            argName = formalArg.variable.name
            localVarEntry = LocalVariableEntry(env, argName, argType)
            addIdent(env, argName, localVarEntry)
    declaredReturnType = None
    if ast.returnType is not None :
        declaredReturnType = inferTypeType(ast.returnType, env)
    raise NotImplementedError

@inferNamedCallExpr.register(OverloadableEntry)
def foo(entry, x, env) :
    raise NotImplementedError

@inferNamedCallExpr.register(TypeVarEntry)
def foo(entry, x, env) :
    raise NotImplementedError

# end inferNamedCallExpr

@inferType.register(FieldRef)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(TupleRef)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(PointerRef)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(ArrayExpr)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(TupleExpr)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(NameRef)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(BoolLiteral)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(IntLiteral)
def foo(x, env) :
    raise NotImplementedError

@inferType.register(CharLiteral)
def foo(x, env) :
    raise NotImplementedError

#
# remove temp name used for multimethod instances
#

del foo
<|endoftext|>


<commit_before>import requests
import json
from distutils.version import LooseVersion
import zipfile
import os
import shutil
from io import BytesIO
import console
import ui

class release (object):
	def __init__(self, j = None):
		self.__url = ''
		self.__assets_url = ''
		self.__upload_url = ''
		self.__html_url = ''
		self.__id = 0
		self.__tag_name = ''
		self.__target_commitish = ''
		self.__name = ''
		self.__draft = True
		self.__author = None
		self.__prerelease = True
		self.__created_at = ''
		self.__published_at = ''
		self.__assets = []
		self.__tarball_url = ''
		self.__zipball_url = ''
		self.__body = ''

		if not j == None:
			self.url = j['url']
			self.assets_url = j['assets_url']
			self.upload_url = j['upload_url']
			self.html_url = j['html_url']
			self.id = j['id']
			self.tag_name = j['tag_name']
			self.target_commitish = j['target_commitish']
			self.name = j['name']
			self.draft = j['draft']
			self.author = j['author']
			self.prerelease = j['prerelease']
			self.created_at = j['created_at']
			self.published_at = j['published_at']
			self.assets = j['assets']
			self.tarball_url = j['tarball_url']
			self.zipball_url = j['zipball_url']
			self.body = j['body']

		@property
		def url(self):
			return self.__url

		@url.setter
		def url(self, obj):
			self.__url = obj

		@property
		def assets_url(self):
			return self.__assets_url

		@assets_url.setter
		def assets_url(self, obj):
			self.__assets_url = obj

		@property
		def upload_url(self):
			return self.__upload_url

		@upload_url.setter
		def upload_url(self, obj):
			self.__upload_url = obj

		@property
		def html_url(self):
			return self.__html_url

		@html_url.setter
		def html_url(self, obj):
			self.__html_url = obj

		@property
		def id(self):
			return self.__id

		@id.setter
		def id(self, obj):
			self.__id = obj

		@property
		def tag_name(self):
			return self.__tag_name

		@tag_name.setter
		def tag_name(self, obj):
			self.__tag_name = obj

		@property
		def target_commitish(self):
			return self.__target_commitish

		@target_commitish.setter
		def target_commitish(self, obj):
			self.__target_commitish = obj

		@property
		def name(self):
			return self.__name

		@name.setter
		def name(self, obj):
			self.__name = obj

		@property
		def draft(self):
			return self.__draft

		@draft.setter
		def draft(self, obj):
			self.__draft = obj

		@property
		def author(self):
			return self.__author

		@author.setter
		def author(self, obj):
			self.__author = author(obj)

		@property
		def prerelease(self):
			return self.__prerelease

		@prerelease.setter
		def prerelease(self, obj):
			self.__prerelease = obj

		@property
		def created_at(self):
			return self.__created_at

		@created_at.setter
		def created_at(self, obj):
			self.__created_at = obj

		@property
		def published_at(self):
			return self.__published_at

		@published_at.setter
		def published_at(self, obj):
			self.__published_at = obj

		@property
		def assets(self):
			return self.__assets

		@assets.setter
		def assets(self, obj):
			self.__assets = obj

		@property
		def tarball_url(self):
			return self.__tarball_url

		@tarball_url.setter
		def tarball_url(self, obj):
			self.__tarball_url = obj

		@property
		def zipball_url(self):
			return self.__zipball_url

		@zipball_url.setter
		def zipball_url(self, obj):
			self.__zipball_url = obj

		@property
		def body(self):
			return self.__body

		@body.setter
		def body(self, obj):
			self.__body = obj

class author (object):
	def __init__(self, j = None):
		self.__login = ''
		self.__id = 0
		self.__avatar_url = ''
		self.__gravatar_id = ''
		self.__url = ''
		self.__html_url = ''
		self.__followers_url = ''
		self.__following_url = ''
		self.__gists_url = ''
		self.__starred_url = ''
		self.__subscriptions_url = ''
		self.__organizations_url = ''
		self.__repos_url = ''
		self.__events_url = ''
		self.__received_events_url = ''
		self.__type = ''
		self.__site_admin = True

		if not j == None:
			self.login = j['login']
			self.id = j['id']
			self.avatar_url = j['avatar_url']
			self.gravatar_id = j['gravatar_id']
			self.url = j['url']
			self.html_url = j['html_url']
			self.followers_url = j['followers_url']
			self.following_url = j['following_url']
			self.gists_url = j['gists_url']
			self.starred_url = j['starred_url']
			self.subscriptions_url = j['subscriptions_url']
			self.organizations_url = j['organizations_url']
			self.repos_url = j['repos_url']
			self.events_url = j['events_url']
			self.received_events_url = j['received_events_url']
			self.type = j['type']
			self.site_admin = j['site_admin']

		@property
		def login(self):
			return self.__login

		@login.setter
		def login(self, obj):
			self.__login = obj

		@property
		def id(self):
			return self.__id

		@id.setter
		def id(self, obj):
			self.__id = obj

		@property
		def avatar_url(self):
			return self.__avatar_url

		@avatar_url.setter
		def avatar_url(self, obj):
			self.__avatar_url = obj

		@property
		def gravatar_id(self):
			return self.__gravatar_id

		@gravatar_id.setter
		def gravatar_id(self, obj):
			self.__gravatar_id = obj

		@property
		def url(self):
			return self.__url

		@url.setter
		def url(self, obj):
			self.__url = obj

		@property
		def html_url(self):
			return self.__html_url

		@html_url.setter
		def html_url(self, obj):
			self.__html_url = obj

		@property
		def followers_url(self):
			return self.__followers_url

		@followers_url.setter
		def followers_url(self, obj):
			self.__followers_url = obj

		@property
		def following_url(self):
			return self.__following_url

		@following_url.setter
		def following_url(self, obj):
			self.__following_url = obj

		@property
		def gists_url(self):
			return self.__gists_url

		@gists_url.setter
		def gists_url(self, obj):
			self.__gists_url = obj

		@property
		def starred_url(self):
			return self.__starred_url

		@starred_url.setter
		def starred_url(self, obj):
			self.__starred_url = obj

		@property
		def subscriptions_url(self):
			return self.__subscriptions_url

		@subscriptions_url.setter
		def subscriptions_url(self, obj):
			self.__subscriptions_url = obj

		@property
		def organizations_url(self):
			return self.__organizations_url

		@organizations_url.setter
		def organizations_url(self, obj):
			self.__organizations_url = obj

		@property
		def repos_url(self):
			return self.__repos_url

		@repos_url.setter
		def repos_url(self, obj):
			self.__repos_url = obj

		@property
		def events_url(self):
			return self.__events_url

		@events_url.setter
		def events_url(self, obj):
			self.__events_url = obj

		@property
		def received_events_url(self):
			return self.__received_events_url

		@received_events_url.setter
		def received_events_url(self, obj):
			self.__received_events_url = obj

		@property
		def type(self):
			return self.__type

		@type.setter
		def type(self, obj):
			self.__type = obj

		@property
		def site_admin(self):
			return self.__site_admin

		@site_admin.setter
		def site_admin(self, obj):
			self.__site_admin = obj

class Updater (object):
	def __init__(self):
		self.latestReleaseUrl = 'https://api.github.com/repos/shaun-h/pydoc/releases/latest'
		self.releasesUrl = 'https://api.github.com/repos/shaun-h/pydoc/releases'
		if os.path.exists('.version'):
			f = open('.version', 'r')
			self.currentVersion = f.read()
			f.close()
		else:
			self.currentVersion = '0'
			f = open('.version', 'w')
			f.write(self.currentVersion)
			f.close()

	@ui.in_background
	def checkForUpdate(self):
		try:
			console.show_activity('Checking for update...')
			response = requests.get(self.latestReleaseUrl)
			data = json.loads(response.text)
			rel = release(data)
			console.hide_activity()
			if rel.prerelease == False:
				if LooseVersion(self.currentVersion) < LooseVersion(rel.tag_name.replace('v','')):
					ret = console.alert('Update available', rel.tag_name + ' is available, would you like to install it. /n/nDetails: ' + rel.body.replace('/r/n','/n'), hide_cancel_button=True, button1 = 'No', button2 = 'Yes')
					if ret == 2:
						self.install(rel)
				else:
					console.alert('No update available', 'v' + self.currentVersion + ' is the current version.', hide_cancel_button=True, button1 = 'Ok')
		except requests.exceptions.ConnectionError as e:
			console.alert('Check your internet connection', 'Unable to check for update.', hide_cancel_button=True, button1 = 'Ok')

	def install(self, release):
		console.show_activity('Installing ' + release.tag_name)
		request = requests.get(release.zipball_url)
		file = zipfile.ZipFile(BytesIO(request.content))
		toRemove = file.namelist()[0]

		filelist = [f for f in os.listdir('.') if not f in ['Docsets', '.wcsync']]
		for f in filelist:
			if os.path.isdir(f):
				shutil.rmtree(f)
			else:
				os.remove(f)
		file.extractall()
		for filename in os.listdir(toRemove):
			shutil.move(os.path.join(toRemove, filename), filename)
		shutil.rmtree(toRemove)
		file.close()

		f = open('.version', 'w')
		f.write(release.tag_name.replace('v',''))
		f.close()
		console.hide_activity()
		console.alert('Installed', release.tag_name + ' installed, please restart Pythonista', hide_cancel_button=True, button1 = 'Ok')

	def ignoreUpdate(self):
		pass

	def reinstallCurrentVersion(self):
		print('Reinstall current version')

	def showAvailableVersions(self):
		print('Show available versions')

if __name__ == '__main__':
	if os.path.exists('.version'):
		os.remove('.version')

	u = Updater()
	u.checkForUpdate()
<commit_msg>fixed issue with updater not displaying new lines<commit_after>import requests
import json
from distutils.version import LooseVersion
import zipfile
import os
import shutil
from io import BytesIO
import console
import ui

class release (object):
	def __init__(self, j = None):
		self.__url = ''
		self.__assets_url = ''
		self.__upload_url = ''
		self.__html_url = ''
		self.__id = 0
		self.__tag_name = ''
		self.__target_commitish = ''
		self.__name = ''
		self.__draft = True
		self.__author = None
		self.__prerelease = True
		self.__created_at = ''
		self.__published_at = ''
		self.__assets = []
		self.__tarball_url = ''
		self.__zipball_url = ''
		self.__body = ''

		if not j == None:
			self.url = j['url']
			self.assets_url = j['assets_url']
			self.upload_url = j['upload_url']
			self.html_url = j['html_url']
			self.id = j['id']
			self.tag_name = j['tag_name']
			self.target_commitish = j['target_commitish']
			self.name = j['name']
			self.draft = j['draft']
			self.author = j['author']
			self.prerelease = j['prerelease']
			self.created_at = j['created_at']
			self.published_at = j['published_at']
			self.assets = j['assets']
			self.tarball_url = j['tarball_url']
			self.zipball_url = j['zipball_url']
			self.body = j['body']

		@property
		def url(self):
			return self.__url

		@url.setter
		def url(self, obj):
			self.__url = obj

		@property
		def assets_url(self):
			return self.__assets_url

		@assets_url.setter
		def assets_url(self, obj):
			self.__assets_url = obj

		@property
		def upload_url(self):
			return self.__upload_url

		@upload_url.setter
		def upload_url(self, obj):
			self.__upload_url = obj

		@property
		def html_url(self):
			return self.__html_url

		@html_url.setter
		def html_url(self, obj):
			self.__html_url = obj

		@property
		def id(self):
			return self.__id

		@id.setter
		def id(self, obj):
			self.__id = obj

		@property
		def tag_name(self):
			return self.__tag_name

		@tag_name.setter
		def tag_name(self, obj):
			self.__tag_name = obj

		@property
		def target_commitish(self):
			return self.__target_commitish

		@target_commitish.setter
		def target_commitish(self, obj):
			self.__target_commitish = obj

		@property
		def name(self):
			return self.__name

		@name.setter
		def name(self, obj):
			self.__name = obj

		@property
		def draft(self):
			return self.__draft

		@draft.setter
		def draft(self, obj):
			self.__draft = obj

		@property
		def author(self):
			return self.__author

		@author.setter
		def author(self, obj):
			self.__author = author(obj)

		@property
		def prerelease(self):
			return self.__prerelease

		@prerelease.setter
		def prerelease(self, obj):
			self.__prerelease = obj

		@property
		def created_at(self):
			return self.__created_at

		@created_at.setter
		def created_at(self, obj):
			self.__created_at = obj

		@property
		def published_at(self):
			return self.__published_at

		@published_at.setter
		def published_at(self, obj):
			self.__published_at = obj

		@property
		def assets(self):
			return self.__assets

		@assets.setter
		def assets(self, obj):
			self.__assets = obj

		@property
		def tarball_url(self):
			return self.__tarball_url

		@tarball_url.setter
		def tarball_url(self, obj):
			self.__tarball_url = obj

		@property
		def zipball_url(self):
			return self.__zipball_url

		@zipball_url.setter
		def zipball_url(self, obj):
			self.__zipball_url = obj

		@property
		def body(self):
			return self.__body

		@body.setter
		def body(self, obj):
			self.__body = obj

class author (object):
	def __init__(self, j = None):
		self.__login = ''
		self.__id = 0
		self.__avatar_url = ''
		self.__gravatar_id = ''
		self.__url = ''
		self.__html_url = ''
		self.__followers_url = ''
		self.__following_url = ''
		self.__gists_url = ''
		self.__starred_url = ''
		self.__subscriptions_url = ''
		self.__organizations_url = ''
		self.__repos_url = ''
		self.__events_url = ''
		self.__received_events_url = ''
		self.__type = ''
		self.__site_admin = True

		if not j == None:
			self.login = j['login']
			self.id = j['id']
			self.avatar_url = j['avatar_url']
			self.gravatar_id = j['gravatar_id']
			self.url = j['url']
			self.html_url = j['html_url']
			self.followers_url = j['followers_url']
			self.following_url = j['following_url']
			self.gists_url = j['gists_url']
			self.starred_url = j['starred_url']
			self.subscriptions_url = j['subscriptions_url']
			self.organizations_url = j['organizations_url']
			self.repos_url = j['repos_url']
			self.events_url = j['events_url']
			self.received_events_url = j['received_events_url']
			self.type = j['type']
			self.site_admin = j['site_admin']

		@property
		def login(self):
			return self.__login

		@login.setter
		def login(self, obj):
			self.__login = obj

		@property
		def id(self):
			return self.__id

		@id.setter
		def id(self, obj):
			self.__id = obj

		@property
		def avatar_url(self):
			return self.__avatar_url

		@avatar_url.setter
		def avatar_url(self, obj):
			self.__avatar_url = obj

		@property
		def gravatar_id(self):
			return self.__gravatar_id

		@gravatar_id.setter
		def gravatar_id(self, obj):
			self.__gravatar_id = obj

		@property
		def url(self):
			return self.__url

		@url.setter
		def url(self, obj):
			self.__url = obj

		@property
		def html_url(self):
			return self.__html_url

		@html_url.setter
		def html_url(self, obj):
			self.__html_url = obj

		@property
		def followers_url(self):
			return self.__followers_url

		@followers_url.setter
		def followers_url(self, obj):
			self.__followers_url = obj

		@property
		def following_url(self):
			return self.__following_url

		@following_url.setter
		def following_url(self, obj):
			self.__following_url = obj

		@property
		def gists_url(self):
			return self.__gists_url

		@gists_url.setter
		def gists_url(self, obj):
			self.__gists_url = obj

		@property
		def starred_url(self):
			return self.__starred_url

		@starred_url.setter
		def starred_url(self, obj):
			self.__starred_url = obj

		@property
		def subscriptions_url(self):
			return self.__subscriptions_url

		@subscriptions_url.setter
		def subscriptions_url(self, obj):
			self.__subscriptions_url = obj

		@property
		def organizations_url(self):
			return self.__organizations_url

		@organizations_url.setter
		def organizations_url(self, obj):
			self.__organizations_url = obj

		@property
		def repos_url(self):
			return self.__repos_url

		@repos_url.setter
		def repos_url(self, obj):
			self.__repos_url = obj

		@property
		def events_url(self):
			return self.__events_url

		@events_url.setter
		def events_url(self, obj):
			self.__events_url = obj

		@property
		def received_events_url(self):
			return self.__received_events_url

		@received_events_url.setter
		def received_events_url(self, obj):
			self.__received_events_url = obj

		@property
		def type(self):
			return self.__type

		@type.setter
		def type(self, obj):
			self.__type = obj

		@property
		def site_admin(self):
			return self.__site_admin

		@site_admin.setter
		def site_admin(self, obj):
			self.__site_admin = obj

class Updater (object):
	def __init__(self):
		self.latestReleaseUrl = 'https://api.github.com/repos/shaun-h/pydoc/releases/latest'
		self.releasesUrl = 'https://api.github.com/repos/shaun-h/pydoc/releases'
		if os.path.exists('.version'):
			f = open('.version', 'r')
			self.currentVersion = f.read()
			f.close()
		else:
			self.currentVersion = '0'
			f = open('.version', 'w')
			f.write(self.currentVersion)
			f.close()

	@ui.in_background
	def checkForUpdate(self):
		try:
			console.show_activity('Checking for update...')
			response = requests.get(self.latestReleaseUrl)
			data = json.loads(response.text)
			rel = release(data)
			console.hide_activity()
			if rel.prerelease == False:
				print(rel.body)
				if LooseVersion(self.currentVersion) < LooseVersion(rel.tag_name.replace('v','')):
					ret = console.alert('Update available', rel.tag_name + ' is available, would you like to install it. \n\n Details: ' + rel.body.replace('\r\n','\n'), hide_cancel_button=True, button1 = 'No', button2 = 'Yes')
					if ret == 2:
						self.install(rel)
				else:
					console.alert('No update available', 'v' + self.currentVersion + ' is the current version.', hide_cancel_button=True, button1 = 'Ok')
		except requests.exceptions.ConnectionError as e:
			console.alert('Check your internet connection', 'Unable to check for update.', hide_cancel_button=True, button1 = 'Ok')

	def install(self, release):
		console.show_activity('Installing ' + release.tag_name)
		request = requests.get(release.zipball_url)
		file = zipfile.ZipFile(BytesIO(request.content))
		toRemove = file.namelist()[0]

		filelist = [f for f in os.listdir('.') if not f in ['Docsets', '.wcsync']]
		for f in filelist:
			if os.path.isdir(f):
				shutil.rmtree(f)
			else:
				os.remove(f)
		file.extractall()
		for filename in os.listdir(toRemove):
			shutil.move(os.path.join(toRemove, filename), filename)
		shutil.rmtree(toRemove)
		file.close()

		f = open('.version', 'w')
		f.write(release.tag_name.replace('v',''))
		f.close()
		console.hide_activity()
		console.alert('Installed', release.tag_name + ' installed, please restart PyDoc', hide_cancel_button=True, button1 = 'Ok')

	def ignoreUpdate(self):
		pass

	def reinstallCurrentVersion(self):
		print('Reinstall current version')

	def showAvailableVersions(self):
		print('Show available versions')

if __name__ == '__main__':
	if os.path.exists('.version'):
		os.remove('.version')

	u = Updater()
	u.checkForUpdate()
<|endoftext|>