<commit_before>import pprint
import sgmllib
import unittest
from test import test_support

class EventCollector(sgmllib.SGMLParser):

    def __init__(self):
        self.events = []
        self.append = self.events.append
        sgmllib.SGMLParser.__init__(self)

    def get_events(self):
        # Normalize the list of events so that buffer artefacts don't
        # separate runs of contiguous characters.
        L = []
        prevtype = None
        for event in self.events:
            type = event[0]
            if type == prevtype == "data":
                L[-1] = ("data", L[-1][1] + event[1])
            else:
                L.append(event)
            prevtype = type
        self.events = L
        return L

    # structure markup

    def unknown_starttag(self, tag, attrs):
        self.append(("starttag", tag, attrs))

    def unknown_endtag(self, tag):
        self.append(("endtag", tag))

    # all other markup

    def handle_comment(self, data):
        self.append(("comment", data))

    def handle_charref(self, data):
        self.append(("charref", data))

    def handle_data(self, data):
        self.append(("data", data))

    def handle_decl(self, decl):
        self.append(("decl", decl))

    def handle_entityref(self, data):
        self.append(("entityref", data))

    def handle_pi(self, data):
        self.append(("pi", data))

    def unknown_decl(self, decl):
        self.append(("unknown decl", decl))

class CDATAEventCollector(EventCollector):
    def start_cdata(self, attrs):
        self.append(("starttag", "cdata", attrs))
        self.setliteral()

class SGMLParserTestCase(unittest.TestCase):

    collector = EventCollector

    def get_events(self, source):
        parser = self.collector()
        try:
            for s in source:
                parser.feed(s)
            parser.close()
        except:
            #self.events = parser.events
            raise
        return parser.get_events()

    def check_events(self, source, expected_events):
        try:
            events = self.get_events(source)
        except:
            import sys
            #print >>sys.stderr, pprint.pformat(self.events)
            raise
        if events != expected_events:
            self.fail("received events did not match expected events\n"
                      "Expected:\n" + pprint.pformat(expected_events) +
                      "\nReceived:\n" + pprint.pformat(events))

    def check_parse_error(self, source):
        parser = EventCollector()
        try:
            parser.feed(source)
            parser.close()
        except sgmllib.SGMLParseError:
            pass
        else:
            self.fail("expected SGMLParseError for %r\nReceived:\n%s"
                      % (source, pprint.pformat(parser.get_events())))

    def test_doctype_decl_internal(self):
        inside = """\
DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
             SYSTEM 'http://www.w3.org/TR/html401/strict.dtd' [
  <!ELEMENT html - O EMPTY>
  <!ATTLIST html
      version CDATA #IMPLIED
      profile CDATA 'DublinCore'>
  <!NOTATION datatype SYSTEM 'http://xml.python.org/notations/python-module'>
  <!ENTITY myEntity 'internal parsed entity'>
  <!ENTITY anEntity SYSTEM 'http://xml.python.org/entities/something.xml'>
  <!ENTITY % paramEntity 'name|name|name'>
  %paramEntity;

]"""
        self.check_events(["<!%s>" % inside], [
            ("decl", inside),
            ])

    def test_doctype_decl_external(self):
        inside = "DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'"
        self.check_events("<!%s>" % inside, [
            ("decl", inside),
            ])

    def test_underscore_in_attrname(self):
        # SF bug #436621
        """Make sure attribute names with underscores are accepted"""
        self.check_events("", [
            ("starttag", "a", [("has_under", "has_under"),
                               ("_under", "_under")]),
            ])

    def test_underscore_in_tagname(self):
        # SF bug #436621
        """Make sure tag names with underscores are accepted"""
        self.check_events("<has_under></has_under>", [
            ("starttag", "has_under", []),
            ("endtag", "has_under"),
            ])

    def test_quotes_in_unquoted_attrs(self):
        # SF bug #436621
        """Be sure quotes in unquoted attributes are made part of the value"""
        self.check_events("", [
            ("starttag", "a", [("href", "foo'bar\"baz")]),
            ])

    def test_xhtml_empty_tag(self):
        """Handling of XHTML-style empty start tags"""
        self.check_events("
text", [
            ("starttag", "br", []),
            ("data", "text"),
            ("starttag", "i", []),
            ("endtag", "i"),
            ])

    def test_processing_instruction_only(self):
        self.check_events("<?processing instruction>", [
            ("pi", "processing instruction"),
            ])

    def test_bad_nesting(self):
        self.check_events("", [
            ("starttag", "a", []),
            ("starttag", "b", []),
            ("endtag", "a"),
            ("endtag", "b"),
            ])

    def test_bare_ampersands(self):
        self.check_events("this text & contains & ampersands &", [
            ("data", "this text & contains & ampersands &"),
            ])

    def test_bare_pointy_brackets(self):
        self.check_events("this < text > contains < bare>pointy< brackets", [
            ("data", "this < text > contains < bare>pointy< brackets"),
            ])

    def test_attr_syntax(self):
        output = [
          ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", "e")])
          ]
        self.check_events("""""", output)
        self.check_events("""""", output)
        self.check_events("""""", output)
        self.check_events("""""", output)

    def test_attr_values(self):
        self.check_events("""""",
                        [("starttag", "a", [("b", "xxx\n\txxx"),
                                            ("c", "yyy\t\nyyy"),
                                            ("d", "\txyz\n")])
                         ])
        self.check_events("""""", [
            ("starttag", "a", [("b", ""), ("c", "")]),
            ])
        # URL construction stuff from RFC 1808:
        safe = "$-_.+"
        extra = "!*'(),"
        reserved = ";/?:@&="
        url = "http://example.com:8080/path/to/file?%s%s%s" % (
            safe, extra, reserved)
        self.check_events("""<e a=%s>""" % url, [
            ("starttag", "e", [("a", url)]),
            ])
        # Regression test for SF patch #669683.
        self.check_events("<e a=rgb(1,2,3)>", [
            ("starttag", "e", [("a", "rgb(1,2,3)")]),
            ])

    def test_attr_values_entities(self):
        """Substitution of entities and charrefs in attribute values"""
        # SF bug #1452246
        self.check_events("""""",
            [("starttag", "a", [("b", "<"),
                                ("c", "<>"),
                                ("d", "&lt->"),
                                ("e", "< "),
                                ("f", "&xxx;"),
                                ("g", " !"),
                                ("h", "Ǵ"),
                                ("i", "x?a=b&c=d;"), ])])

    def test_attr_funky_names(self):
        self.check_events("""""", [
            ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
            ])

    def test_illegal_declarations(self):
        s = 'abc<!spacer type="block" height="25">def'
        self.check_events(s, [
            ("data", "abc"),
            ("unknown decl", 'spacer type="block" height="25"'),
            ("data", "def"),
            ])

    def test_weird_starttags(self):
        self.check_events("<a", [
            ("starttag", "a", []),
            ("starttag", "a", []),
            ])
        self.check_events("</a", [
            ("endtag", "a"),
            ("starttag", "a", []),
            ])

    def test_declaration_junk_chars(self):
        self.check_parse_error("<!DOCTYPE foo $ >")

    def test_get_starttag_text(self):
        s = """<foobar   \n   one="1"\ttwo=2   >"""
        self.check_events(s, [
            ("starttag", "foobar", [("one", "1"), ("two", "2")]),
            ])

    def test_cdata_content(self):
        s = ("<cdata>  &not-an-entity-ref; </cdata>"
             "<notcdata>  </notcdata>")
        self.collector = CDATAEventCollector
        self.check_events(s, [
            ("starttag", "cdata", []),
            ("data", "  &not-an-entity-ref; "),
            ("endtag", "cdata"),
            ("starttag", "notcdata", []),
            ("data", " "),
            ("comment", " comment "),
            ("data", " "),
            ("endtag", "notcdata"),
            ])
        s = """<cdata> <not a='start tag'> </cdata>"""
        self.check_events(s, [
            ("starttag", "cdata", []),
            ("data", " <not a='start tag'> "),
            ("endtag", "cdata"),
            ])

    def test_illegal_declarations(self):
        s = 'abc<!spacer type="block" height="25">def'
        self.check_events(s, [
            ("data", "abc"),
            ("unknown decl", 'spacer type="block" height="25"'),
            ("data", "def"),
            ])

    def test_enumerated_attr_type(self):
        s = "<!DOCTYPE doc [<!ATTLIST doc attr (a | b) >]>"
        self.check_events(s, [
            ('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
            ])

    # XXX These tests have been disabled by prefixing their names with
    # an underscore.  The first two exercise outstanding bugs in the
    # sgmllib module, and the third exhibits questionable behavior
    # that needs to be carefully considered before changing it.

    def _test_starttag_end_boundary(self):
        self.check_events("<a b='<'>", [("starttag", "a", [("b", "<")])])
        self.check_events("'>", [("starttag", "a", [("b", ">")])])

    def _test_buffer_artefacts(self):
        output = [("starttag", "a", [("b", "<")])]
        self.check_events(["<a b='<'>"], output)
        self.check_events(["<a ", "b='<'>"], output)
        self.check_events(["<a b", "='<'>"], output)
        self.check_events(["<a b=", "'<'>"], output)
        self.check_events(["<a b='<", "'>"], output)
        self.check_events(["<a b='<'", ">"], output)

        output = [("starttag", "a", [("b", ">")])]
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["", "'>"], output)
        self.check_events(["'", ">"], output)

        output = [("comment", "abc")]
        self.check_events(["", ""], output)
        self.check_events(["<", "!--abc-->"], output)
        self.check_events(["<!", "--abc-->"], output)
        self.check_events(["<!-", "-abc-->"], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events(["", ""], output)

    def _test_starttag_junk_chars(self):
        self.check_parse_error("<")
        self.check_parse_error("<>")
        self.check_parse_error("</$>")
        self.check_parse_error("</")
        self.check_parse_error("</a")
        self.check_parse_error("<$")
        self.check_parse_error("<$>")
        self.check_parse_error("<!")
        self.check_parse_error("")
        self.check_parse_error("<a")
        self.check_parse_error("<a foo='bar'")
        self.check_parse_error("<a foo='bar")
        self.check_parse_error("'")
        self.check_parse_error("")
        self.check_parse_error("")

def test_main():
    test_support.run_unittest(SGMLParserTestCase)

if __name__ == "__main__":
    test_main()
<commit_msg>add tests for two cases that are handled correctly in the current code, but that SF patch 1504676 as written mis-handles<commit_after>import pprint
import sgmllib
import unittest
from test import test_support

class EventCollector(sgmllib.SGMLParser):

    def __init__(self):
        self.events = []
        self.append = self.events.append
        sgmllib.SGMLParser.__init__(self)

    def get_events(self):
        # Normalize the list of events so that buffer artefacts don't
        # separate runs of contiguous characters.
        L = []
        prevtype = None
        for event in self.events:
            type = event[0]
            if type == prevtype == "data":
                L[-1] = ("data", L[-1][1] + event[1])
            else:
                L.append(event)
            prevtype = type
        self.events = L
        return L

    # structure markup

    def unknown_starttag(self, tag, attrs):
        self.append(("starttag", tag, attrs))

    def unknown_endtag(self, tag):
        self.append(("endtag", tag))

    # all other markup

    def handle_comment(self, data):
        self.append(("comment", data))

    def handle_charref(self, data):
        self.append(("charref", data))

    def handle_data(self, data):
        self.append(("data", data))

    def handle_decl(self, decl):
        self.append(("decl", decl))

    def handle_entityref(self, data):
        self.append(("entityref", data))

    def handle_pi(self, data):
        self.append(("pi", data))

    def unknown_decl(self, decl):
        self.append(("unknown decl", decl))

class CDATAEventCollector(EventCollector):
    def start_cdata(self, attrs):
        self.append(("starttag", "cdata", attrs))
        self.setliteral()

class SGMLParserTestCase(unittest.TestCase):

    collector = EventCollector

    def get_events(self, source):
        parser = self.collector()
        try:
            for s in source:
                parser.feed(s)
            parser.close()
        except:
            #self.events = parser.events
            raise
        return parser.get_events()

    def check_events(self, source, expected_events):
        try:
            events = self.get_events(source)
        except:
            import sys
            #print >>sys.stderr, pprint.pformat(self.events)
            raise
        if events != expected_events:
            self.fail("received events did not match expected events\n"
                      "Expected:\n" + pprint.pformat(expected_events) +
                      "\nReceived:\n" + pprint.pformat(events))

    def check_parse_error(self, source):
        parser = EventCollector()
        try:
            parser.feed(source)
            parser.close()
        except sgmllib.SGMLParseError:
            pass
        else:
            self.fail("expected SGMLParseError for %r\nReceived:\n%s"
                      % (source, pprint.pformat(parser.get_events())))

    def test_doctype_decl_internal(self):
        inside = """\
DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
             SYSTEM 'http://www.w3.org/TR/html401/strict.dtd' [
  <!ELEMENT html - O EMPTY>
  <!ATTLIST html
      version CDATA #IMPLIED
      profile CDATA 'DublinCore'>
  <!NOTATION datatype SYSTEM 'http://xml.python.org/notations/python-module'>
  <!ENTITY myEntity 'internal parsed entity'>
  <!ENTITY anEntity SYSTEM 'http://xml.python.org/entities/something.xml'>
  <!ENTITY % paramEntity 'name|name|name'>
  %paramEntity;

]"""
        self.check_events(["<!%s>" % inside], [
            ("decl", inside),
            ])

    def test_doctype_decl_external(self):
        inside = "DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'"
        self.check_events("<!%s>" % inside, [
            ("decl", inside),
            ])

    def test_underscore_in_attrname(self):
        # SF bug #436621
        """Make sure attribute names with underscores are accepted"""
        self.check_events("", [
            ("starttag", "a", [("has_under", "has_under"),
                               ("_under", "_under")]),
            ])

    def test_underscore_in_tagname(self):
        # SF bug #436621
        """Make sure tag names with underscores are accepted"""
        self.check_events("<has_under></has_under>", [
            ("starttag", "has_under", []),
            ("endtag", "has_under"),
            ])

    def test_quotes_in_unquoted_attrs(self):
        # SF bug #436621
        """Be sure quotes in unquoted attributes are made part of the value"""
        self.check_events("", [
            ("starttag", "a", [("href", "foo'bar\"baz")]),
            ])

    def test_xhtml_empty_tag(self):
        """Handling of XHTML-style empty start tags"""
        self.check_events("
text", [
            ("starttag", "br", []),
            ("data", "text"),
            ("starttag", "i", []),
            ("endtag", "i"),
            ])

    def test_processing_instruction_only(self):
        self.check_events("<?processing instruction>", [
            ("pi", "processing instruction"),
            ])

    def test_bad_nesting(self):
        self.check_events("", [
            ("starttag", "a", []),
            ("starttag", "b", []),
            ("endtag", "a"),
            ("endtag", "b"),
            ])

    def test_bare_ampersands(self):
        self.check_events("this text & contains & ampersands &", [
            ("data", "this text & contains & ampersands &"),
            ])

    def test_bare_pointy_brackets(self):
        self.check_events("this < text > contains < bare>pointy< brackets", [
            ("data", "this < text > contains < bare>pointy< brackets"),
            ])

    def test_attr_syntax(self):
        output = [
          ("starttag", "a", [("b", "v"), ("c", "v"), ("d", "v"), ("e", "e")])
          ]
        self.check_events("""""", output)
        self.check_events("""""", output)
        self.check_events("""""", output)
        self.check_events("""""", output)

    def test_attr_values(self):
        self.check_events("""""",
                        [("starttag", "a", [("b", "xxx\n\txxx"),
                                            ("c", "yyy\t\nyyy"),
                                            ("d", "\txyz\n")])
                         ])
        self.check_events("""""", [
            ("starttag", "a", [("b", ""), ("c", "")]),
            ])
        # URL construction stuff from RFC 1808:
        safe = "$-_.+"
        extra = "!*'(),"
        reserved = ";/?:@&="
        url = "http://example.com:8080/path/to/file?%s%s%s" % (
            safe, extra, reserved)
        self.check_events("""<e a=%s>""" % url, [
            ("starttag", "e", [("a", url)]),
            ])
        # Regression test for SF patch #669683.
        self.check_events("<e a=rgb(1,2,3)>", [
            ("starttag", "e", [("a", "rgb(1,2,3)")]),
            ])

    def test_attr_values_entities(self):
        """Substitution of entities and charrefs in attribute values"""
        # SF bug #1452246
        self.check_events("""""",
            [("starttag", "a", [("b", "<"),
                                ("c", "<>"),
                                ("d", "&lt->"),
                                ("e", "< "),
                                ("f", "&xxx;"),
                                ("g", " !"),
                                ("h", "Ǵ"),
                                ("i", "x?a=b&c=d;"),
                                ("j", "*"),
                                ("k", "*"),
                                ])])

    def test_attr_funky_names(self):
        self.check_events("""""", [
            ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]),
            ])

    def test_illegal_declarations(self):
        s = 'abc<!spacer type="block" height="25">def'
        self.check_events(s, [
            ("data", "abc"),
            ("unknown decl", 'spacer type="block" height="25"'),
            ("data", "def"),
            ])

    def test_weird_starttags(self):
        self.check_events("<a", [
            ("starttag", "a", []),
            ("starttag", "a", []),
            ])
        self.check_events("</a", [
            ("endtag", "a"),
            ("starttag", "a", []),
            ])

    def test_declaration_junk_chars(self):
        self.check_parse_error("<!DOCTYPE foo $ >")

    def test_get_starttag_text(self):
        s = """<foobar   \n   one="1"\ttwo=2   >"""
        self.check_events(s, [
            ("starttag", "foobar", [("one", "1"), ("two", "2")]),
            ])

    def test_cdata_content(self):
        s = ("<cdata>  &not-an-entity-ref; </cdata>"
             "<notcdata>  </notcdata>")
        self.collector = CDATAEventCollector
        self.check_events(s, [
            ("starttag", "cdata", []),
            ("data", "  &not-an-entity-ref; "),
            ("endtag", "cdata"),
            ("starttag", "notcdata", []),
            ("data", " "),
            ("comment", " comment "),
            ("data", " "),
            ("endtag", "notcdata"),
            ])
        s = """<cdata> <not a='start tag'> </cdata>"""
        self.check_events(s, [
            ("starttag", "cdata", []),
            ("data", " <not a='start tag'> "),
            ("endtag", "cdata"),
            ])

    def test_illegal_declarations(self):
        s = 'abc<!spacer type="block" height="25">def'
        self.check_events(s, [
            ("data", "abc"),
            ("unknown decl", 'spacer type="block" height="25"'),
            ("data", "def"),
            ])

    def test_enumerated_attr_type(self):
        s = "<!DOCTYPE doc [<!ATTLIST doc attr (a | b) >]>"
        self.check_events(s, [
            ('decl', 'DOCTYPE doc [<!ATTLIST doc attr (a | b) >]'),
            ])

    # XXX These tests have been disabled by prefixing their names with
    # an underscore.  The first two exercise outstanding bugs in the
    # sgmllib module, and the third exhibits questionable behavior
    # that needs to be carefully considered before changing it.

    def _test_starttag_end_boundary(self):
        self.check_events("<a b='<'>", [("starttag", "a", [("b", "<")])])
        self.check_events("'>", [("starttag", "a", [("b", ">")])])

    def _test_buffer_artefacts(self):
        output = [("starttag", "a", [("b", "<")])]
        self.check_events(["<a b='<'>"], output)
        self.check_events(["<a ", "b='<'>"], output)
        self.check_events(["<a b", "='<'>"], output)
        self.check_events(["<a b=", "'<'>"], output)
        self.check_events(["<a b='<", "'>"], output)
        self.check_events(["<a b='<'", ">"], output)

        output = [("starttag", "a", [("b", ">")])]
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["'>"], output)
        self.check_events(["", "'>"], output)
        self.check_events(["'", ">"], output)

        output = [("comment", "abc")]
        self.check_events(["", ""], output)
        self.check_events(["<", "!--abc-->"], output)
        self.check_events(["<!", "--abc-->"], output)
        self.check_events(["<!-", "-abc-->"], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events([""], output)
        self.check_events(["", ""], output)

    def _test_starttag_junk_chars(self):
        self.check_parse_error("<")
        self.check_parse_error("<>")
        self.check_parse_error("</$>")
        self.check_parse_error("</")
        self.check_parse_error("</a")
        self.check_parse_error("<$")
        self.check_parse_error("<$>")
        self.check_parse_error("<!")
        self.check_parse_error("")
        self.check_parse_error("<a")
        self.check_parse_error("<a foo='bar'")
        self.check_parse_error("<a foo='bar")
        self.check_parse_error("'")
        self.check_parse_error("")
        self.check_parse_error("")

def test_main():
    test_support.run_unittest(SGMLParserTestCase)

if __name__ == "__main__":
    test_main()
<|endoftext|>


<commit_before>import datetime
import decimal
from time import time

from django.utils.hashcompat import md5_constructor
from django.utils.log import getLogger

logger = getLogger('django.db.backends')

class CursorWrapper(object):
    def __init__(self, cursor, connection):
        self.cursor = cursor
        self.connection = connection

    def __getattr__(self, attr):
        if self.connection.is_managed():
            self.connection.set_dirty()
        if attr in self.__dict__:
            return self.__dict__[attr]
        else:
            return getattr(self.cursor, attr)

    def __iter__(self):
        return iter(self.cursor)

class CursorDebugWrapper(CursorWrapper):

    def execute(self, sql, params=()):
        start = time()
        try:
            return self.cursor.execute(sql, params)
        finally:
            stop = time()
            duration = stop - start
            sql = self.connection.ops.last_executed_query(self.cursor, sql, params)
            self.connection.queries.append({
                'sql': sql,
                'time': "%.3f" % duration,
            })
            logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),
                extra={'duration':duration, 'sql':sql, 'params':params}
            )

    def executemany(self, sql, param_list):
        start = time()
        try:
            return self.cursor.executemany(sql, param_list)
        finally:
            stop = time()
            duration = stop - start
            self.connection.queries.append({
                'sql': '%s times: %s' % (len(param_list), sql),
                'time': "%.3f" % duration,
            })
            logger.debug('(%.3f) %s; args=%s' % (duration, sql, param_list),
                extra={'duration':duration, 'sql':sql, 'params':param_list}
            )

###############################################
# Converters from database (string) to Python #
###############################################

def typecast_date(s):
    return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null

def typecast_time(s): # does NOT store time zone information
    if not s: return None
    hour, minutes, seconds = s.split(':')
    if '.' in seconds: # check whether seconds have a fractional part
        seconds, microseconds = seconds.split('.')
    else:
        microseconds = '0'
    return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))

def typecast_timestamp(s): # does NOT store time zone information
    # "2005-07-29 15:48:00.590358-05"
    # "2005-07-29 09:56:00-05"
    if not s: return None
    if not ' ' in s: return typecast_date(s)
    d, t = s.split()
    # Extract timezone information, if it exists. Currently we just throw
    # it away, but in the future we may make use of it.
    if '-' in t:
        t, tz = t.split('-', 1)
        tz = '-' + tz
    elif '+' in t:
        t, tz = t.split('+', 1)
        tz = '+' + tz
    else:
        tz = ''
    dates = d.split('-')
    times = t.split(':')
    seconds = times[2]
    if '.' in seconds: # check whether seconds have a fractional part
        seconds, microseconds = seconds.split('.')
    else:
        microseconds = '0'
    return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
        int(times[0]), int(times[1]), int(seconds), int((microseconds + '000000')[:6]))

def typecast_boolean(s):
    if s is None: return None
    if not s: return False
    return str(s)[0].lower() == 't'

def typecast_decimal(s):
    if s is None or s == '':
        return None
    return decimal.Decimal(s)

###############################################
# Converters from Python to database (string) #
###############################################

def rev_typecast_boolean(obj, d):
    return obj and '1' or '0'

def rev_typecast_decimal(d):
    if d is None:
        return None
    return str(d)

def truncate_name(name, length=None, hash_len=4):
    """Shortens a string to a repeatable mangled version with the given length.
    """
    if length is None or len(name) <= length:
        return name

    hash = md5_constructor(name).hexdigest()[:hash_len]

    return '%s%s' % (name[:length-hash_len], hash)

def format_number(value, max_digits, decimal_places):
    """
    Formats a number into a string with the requisite number of digits and
    decimal places.
    """
    if isinstance(value, decimal.Decimal):
        context = decimal.getcontext().copy()
        context.prec = max_digits
        return u'%s' % str(value.quantize(decimal.Decimal(".1") ** decimal_places, context=context))
    else:
        return u"%.*f" % (decimal_places, value)
<commit_msg>Fixed #15297 -- Corrected an attribute naming regressoin from fixing #9964. Thanks to leonov for the report.<commit_after>import datetime
import decimal
from time import time

from django.utils.hashcompat import md5_constructor
from django.utils.log import getLogger

logger = getLogger('django.db.backends')

class CursorWrapper(object):
    def __init__(self, cursor, db):
        self.cursor = cursor
        self.db = db

    def __getattr__(self, attr):
        if self.db.is_managed():
            self.db.set_dirty()
        if attr in self.__dict__:
            return self.__dict__[attr]
        else:
            return getattr(self.cursor, attr)

    def __iter__(self):
        return iter(self.cursor)

class CursorDebugWrapper(CursorWrapper):

    def execute(self, sql, params=()):
        start = time()
        try:
            return self.cursor.execute(sql, params)
        finally:
            stop = time()
            duration = stop - start
            sql = self.db.ops.last_executed_query(self.cursor, sql, params)
            self.db.queries.append({
                'sql': sql,
                'time': "%.3f" % duration,
            })
            logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),
                extra={'duration':duration, 'sql':sql, 'params':params}
            )

    def executemany(self, sql, param_list):
        start = time()
        try:
            return self.cursor.executemany(sql, param_list)
        finally:
            stop = time()
            duration = stop - start
            self.db.queries.append({
                'sql': '%s times: %s' % (len(param_list), sql),
                'time': "%.3f" % duration,
            })
            logger.debug('(%.3f) %s; args=%s' % (duration, sql, param_list),
                extra={'duration':duration, 'sql':sql, 'params':param_list}
            )

###############################################
# Converters from database (string) to Python #
###############################################

def typecast_date(s):
    return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null

def typecast_time(s): # does NOT store time zone information
    if not s: return None
    hour, minutes, seconds = s.split(':')
    if '.' in seconds: # check whether seconds have a fractional part
        seconds, microseconds = seconds.split('.')
    else:
        microseconds = '0'
    return datetime.time(int(hour), int(minutes), int(seconds), int(float('.'+microseconds) * 1000000))

def typecast_timestamp(s): # does NOT store time zone information
    # "2005-07-29 15:48:00.590358-05"
    # "2005-07-29 09:56:00-05"
    if not s: return None
    if not ' ' in s: return typecast_date(s)
    d, t = s.split()
    # Extract timezone information, if it exists. Currently we just throw
    # it away, but in the future we may make use of it.
    if '-' in t:
        t, tz = t.split('-', 1)
        tz = '-' + tz
    elif '+' in t:
        t, tz = t.split('+', 1)
        tz = '+' + tz
    else:
        tz = ''
    dates = d.split('-')
    times = t.split(':')
    seconds = times[2]
    if '.' in seconds: # check whether seconds have a fractional part
        seconds, microseconds = seconds.split('.')
    else:
        microseconds = '0'
    return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
        int(times[0]), int(times[1]), int(seconds), int((microseconds + '000000')[:6]))

def typecast_boolean(s):
    if s is None: return None
    if not s: return False
    return str(s)[0].lower() == 't'

def typecast_decimal(s):
    if s is None or s == '':
        return None
    return decimal.Decimal(s)

###############################################
# Converters from Python to database (string) #
###############################################

def rev_typecast_boolean(obj, d):
    return obj and '1' or '0'

def rev_typecast_decimal(d):
    if d is None:
        return None
    return str(d)

def truncate_name(name, length=None, hash_len=4):
    """Shortens a string to a repeatable mangled version with the given length.
    """
    if length is None or len(name) <= length:
        return name

    hash = md5_constructor(name).hexdigest()[:hash_len]

    return '%s%s' % (name[:length-hash_len], hash)

def format_number(value, max_digits, decimal_places):
    """
    Formats a number into a string with the requisite number of digits and
    decimal places.
    """
    if isinstance(value, decimal.Decimal):
        context = decimal.getcontext().copy()
        context.prec = max_digits
        return u'%s' % str(value.quantize(decimal.Decimal(".1") ** decimal_places, context=context))
    else:
        return u"%.*f" % (decimal_places, value)
<|endoftext|>


<commit_before># Autoreloading launcher.
# Borrowed from Peter Hunt and the CherryPy project (http://www.cherrypy.org).
# Some taken from Ian Bicking's Paste (http://pythonpaste.org/).
#
# Portions copyright (c) 2004, CherryPy Team (team@cherrypy.org)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright notice,
#       this list of conditions and the following disclaimer in the documentation
#       and/or other materials provided with the distribution.
#     * Neither the name of the CherryPy Team nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os, sys, thread, time

RUN_RELOADER = True

def reloader_thread():
    mtimes = {}
    win = (sys.platform == "win32")
    while RUN_RELOADER:
        for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())):
            if filename.endswith(".pyc") or filename.endswith("*.pyo"):
                filename = filename[:-1]
            if not os.path.exists(filename):
                continue # File might be in an egg, so it can't be reloaded.
            stat = os.stat(filename)
            mtime = stat.st_mtime
            if win:
                mtime -= stat.st_ctime
            if filename not in mtimes:
                mtimes[filename] = mtime
                continue
            if mtime != mtimes[filename]:
                sys.exit(3) # force reload
        time.sleep(1)

def restart_with_reloader():
    while True:
        args = [sys.executable] + sys.argv
        if sys.platform == "win32":
            args = ['"%s"' % arg for arg in args]
        new_environ = os.environ.copy()
        new_environ["RUN_MAIN"] = 'true'
        exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
        if exit_code != 3:
            return exit_code

def main(main_func, args=None, kwargs=None):
    if os.environ.get("RUN_MAIN") == "true":
        if args is None:
            args = ()
        if kwargs is None:
            kwargs = {}
        thread.start_new_thread(main_func, args, kwargs)
        try:
            reloader_thread()
        except KeyboardInterrupt:
            pass
    else:
        try:
            sys.exit(restart_with_reloader())
        except KeyboardInterrupt:
            pass
<commit_msg>Fixed #2036 -- autoreload.py no longer fails for uninstalled 'thread' module. Thanks, plmeister@gmail.com<commit_after># Autoreloading launcher.
# Borrowed from Peter Hunt and the CherryPy project (http://www.cherrypy.org).
# Some taken from Ian Bicking's Paste (http://pythonpaste.org/).
#
# Portions copyright (c) 2004, CherryPy Team (team@cherrypy.org)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright notice,
#       this list of conditions and the following disclaimer in the documentation
#       and/or other materials provided with the distribution.
#     * Neither the name of the CherryPy Team nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os, sys, time

try:
    import thread
except ImportError:
    import dummy_thread as thread

RUN_RELOADER = True

def reloader_thread():
    mtimes = {}
    win = (sys.platform == "win32")
    while RUN_RELOADER:
        for filename in filter(lambda v: v, map(lambda m: getattr(m, "__file__", None), sys.modules.values())):
            if filename.endswith(".pyc") or filename.endswith("*.pyo"):
                filename = filename[:-1]
            if not os.path.exists(filename):
                continue # File might be in an egg, so it can't be reloaded.
            stat = os.stat(filename)
            mtime = stat.st_mtime
            if win:
                mtime -= stat.st_ctime
            if filename not in mtimes:
                mtimes[filename] = mtime
                continue
            if mtime != mtimes[filename]:
                sys.exit(3) # force reload
        time.sleep(1)

def restart_with_reloader():
    while True:
        args = [sys.executable] + sys.argv
        if sys.platform == "win32":
            args = ['"%s"' % arg for arg in args]
        new_environ = os.environ.copy()
        new_environ["RUN_MAIN"] = 'true'
        exit_code = os.spawnve(os.P_WAIT, sys.executable, args, new_environ)
        if exit_code != 3:
            return exit_code

def main(main_func, args=None, kwargs=None):
    if os.environ.get("RUN_MAIN") == "true":
        if args is None:
            args = ()
        if kwargs is None:
            kwargs = {}
        thread.start_new_thread(main_func, args, kwargs)
        try:
            reloader_thread()
        except KeyboardInterrupt:
            pass
    else:
        try:
            sys.exit(restart_with_reloader())
        except KeyboardInterrupt:
            pass
<|endoftext|>


<commit_before>from .group import Group
from .sitebackend import SiteBackend

__version__ = '0.2.0.dev1'

site = SiteBackend(id='backend')
<commit_msg>Bump version to 0.2.0.dev2<commit_after>from .group import Group
from .sitebackend import SiteBackend

__version__ = '0.2.0.dev2'

site = SiteBackend(id='backend')
<|endoftext|>


<commit_before>from django.contrib import admin

class BaseModelAdmin(admin.ModelAdmin):
    """
    Defines a BaseModelAdmin based off of Django's ModelAdmin that supports any
    model built with the BaseModel class so that we're able to save the user
    information of whoever is modifying the object through the admin site.

    This requires that the model you are associating with the ModelAdmin object
    inherits from BaseModel.
    """

    readonly_fields = (
        'last_modified_by_name',
        'time_created',
        'time_modified'
    )

    def last_modified_by_name(self, obj):
        return obj.last_modified_by.get_full_name()
    last_modified_by_name.short_description = 'Last Modified By'

    def last_edited(self, obj):
        return obj.time_modified.strftime('%m/%d/%Y %I:%M %p')
    last_edited.short_description = 'Last Edited'

    def save_model(self, request, obj, form, change):
        if hasattr(obj, 'last_modified_by') and hasattr(request, 'user'):
            obj.last_modified_by = request.user

        obj.save()

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)

        for instance in instances:
            if hasattr(instance, 'last_modified_by') and hasattr(request, 'user'):
                instance.last_modified_by = request.user

            instance.save()

        formset.save_m2m()
<commit_msg>Fixed the readonly fields tuple and added a couple of comments.<commit_after>from django.contrib import admin

class BaseModelAdmin(admin.ModelAdmin):
    """
    Defines a BaseModelAdmin based off of Django's ModelAdmin that supports any
    model built with the BaseModel class so that we're able to save the user
    information of whoever is modifying the object through the admin site.

    This requires that the model you are associating with the ModelAdmin object
    inherits from BaseModel.
    """

    readonly_fields = (
        'last_modified_by',
        'time_created',
        'time_modified'
    )

    def last_modified_by_name(self, obj):
        """
        Method for use in the list_display tuple.
        """

        return obj.last_modified_by.get_full_name()
    last_modified_by_name.short_description = 'Last Modified By'

    def last_edited(self, obj):
        """
        Method for use in the list_display tuple.
        """

        return obj.time_modified.strftime('%m/%d/%Y %I:%M %p')
    last_edited.short_description = 'Last Edited'

    def save_model(self, request, obj, form, change):
        if hasattr(obj, 'last_modified_by') and hasattr(request, 'user'):
            obj.last_modified_by = request.user

        obj.save()

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)

        for instance in instances:
            if hasattr(instance, 'last_modified_by') and hasattr(request, 'user'):
                instance.last_modified_by = request.user

            instance.save()

        formset.save_m2m()
<|endoftext|>


<commit_before>from django.db import models

class EnumField(models.Field):
    __metaclass__ = models.SubfieldBase

    def __init__(self, enumeration, *args, **kwargs):
        self.enumeration = enumeration
        kwargs.setdefault('choices', enumeration.get_choices())

        super(EnumField, self).__init__(*args, **kwargs)

    def get_internal_type(self):
        return 'IntegerField'

    def to_python(self, value):
        return self.enumeration.to_item(value)

    def get_db_prep_save(self, value, connection=None):
        if value is None:
            return value
        return self.to_python(value).value

    def get_db_prep_lookup(self, lookup_type, value, connection=None, prepared=False):
        def prepare(value):
            v = self.to_python(value)
            return self.get_db_prep_save(v, connection=connection)

        if lookup_type in ('exact', 'lt', 'lte', 'gt', 'gte'):
            return [prepare(value)]
        elif lookup_type == 'in':
            return [prepare(v) for v in value]
        elif lookup_type == 'isnull':
            return []

        raise TypeError("Lookup type %r not supported." % lookup_type)

    def south_field_triple(self):
        from south.modelsinspector import introspector
        args, kwargs = introspector(self)
        return ('django.db.models.fields.IntegerField', args, kwargs)
<commit_msg>Generate correct "default" values.<commit_after>from django.db import models

class EnumField(models.Field):
    __metaclass__ = models.SubfieldBase

    def __init__(self, enumeration, *args, **kwargs):
        self.enumeration = enumeration
        kwargs.setdefault('choices', enumeration.get_choices())

        super(EnumField, self).__init__(*args, **kwargs)

    def get_internal_type(self):
        return 'IntegerField'

    def to_python(self, value):
        return self.enumeration.to_item(value)

    def get_db_prep_save(self, value, connection=None):
        if value is None:
            return value
        return self.to_python(value).value

    def get_db_prep_lookup(self, lookup_type, value, connection=None, prepared=False):
        def prepare(value):
            v = self.to_python(value)
            return self.get_db_prep_save(v, connection=connection)

        if lookup_type in ('exact', 'lt', 'lte', 'gt', 'gte'):
            return [prepare(value)]
        elif lookup_type == 'in':
            return [prepare(v) for v in value]
        elif lookup_type == 'isnull':
            return []

        raise TypeError("Lookup type %r not supported." % lookup_type)

    def south_field_triple(self):
        from south.modelsinspector import introspector, NOT_PROVIDED
        args, kwargs = introspector(self)

        # repr(Item) is not only invalid as an lookup value, it actually causes
        # South to generate invalid Python
        if self.default != NOT_PROVIDED:
            kwargs['default'] = repr(self.default.slug)

        return ('django.db.models.fields.IntegerField', args, kwargs)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import json
from django.conf import settings
from django.contrib.auth.views import login as django_login
from django.core.urlresolvers import reverse
from django.http import Http404
from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth import login as auth_login, logout as auth_logout, authenticate
from django.http import HttpResponse

from django_nopassword.forms import AuthenticationForm
from django_nopassword.utils import USERNAME_FIELD
from django_nopassword.models import LoginCode
from django_nopassword.utils import User

def login(request):
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            return render(request, 'registration/sent_mail.html')

    return django_login(request, authentication_form=AuthenticationForm)

def login_with_code(request, login_code):
    code = get_object_or_404(LoginCode, code=login_code)
    user = get_object_or_404(User, pk=code.user_id)
    return login_with_code_and_username(request, username=user.username, login_code=login_code)

def login_with_code_and_username(request, username, login_code):
    code = get_object_or_404(LoginCode, code=login_code)
    user = authenticate(**{USERNAME_FIELD: username, 'code': login_code})

    if user is None:
        raise Http404

    user = auth_login(request, user)

    return redirect(code.next)

def logout(request, redirect_to=None):
    auth_logout(request)
    if redirect_to is None:
        return redirect(reverse('login'))

    else:
        return redirect(redirect_to)

def users_json(request):
    if not getattr(settings, 'NOPASSWORD_AUTOCOMPLETE', False):
        raise Http404

    users = []
    for user in User.objects.filter(is_active=True):
        users.append({
            'value': user.username,
            'username': user.username,
            'full_name': user.get_full_name(),
        })

    return HttpResponse(json.dumps(users), mimetype="application/json")
<commit_msg>save redirect value to LoginCode on generation<commit_after># -*- coding: utf-8 -*-
import json
from django.conf import settings
from django.contrib.auth.views import login as django_login
from django.core.urlresolvers import reverse
from django.http import Http404
from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth import login as auth_login, logout as auth_logout, authenticate
from django.http import HttpResponse

from django_nopassword.forms import AuthenticationForm
from django_nopassword.utils import USERNAME_FIELD
from django_nopassword.models import LoginCode
from django_nopassword.utils import User

def login(request):
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            code = LoginCode.objects.filter(user__username=request.POST.get('username'))[0]
            code.next = request.GET.get('next')
            code.save()
            return render(request, 'registration/sent_mail.html')

    return django_login(request, authentication_form=AuthenticationForm)

def login_with_code(request, login_code):
    code = get_object_or_404(LoginCode, code=login_code)
    user = get_object_or_404(User, pk=code.user_id)
    return login_with_code_and_username(request, username=user.username, login_code=login_code)

def login_with_code_and_username(request, username, login_code):
    code = get_object_or_404(LoginCode, code=login_code)
    user = authenticate(**{USERNAME_FIELD: username, 'code': login_code})
    if user is None:
        raise Http404
    user = auth_login(request, user)
    return redirect(code.next)

def logout(request, redirect_to=None):
    auth_logout(request)
    if redirect_to is None:
        return redirect(reverse('login'))

    else:
        return redirect(redirect_to)

def users_json(request):
    if not getattr(settings, 'NOPASSWORD_AUTOCOMPLETE', False):
        raise Http404

    users = []
    for user in User.objects.filter(is_active=True):
        users.append({
            'value': user.username,
            'username': user.username,
            'full_name': user.get_full_name(),
        })

    return HttpResponse(json.dumps(users), mimetype="application/json")
<|endoftext|>


<commit_before>from django.utils.functional import cached_property
from django.db.migrations.operations.base import Operation
from django.contrib.postgres.operations import CreateExtension

class RDKitExtension(CreateExtension):

    def __init__(self):
        self.name = 'rdkit'

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        super(RDKitExtension, self).database_forwards(app_label,
                                                      schema_editor,
                                                      from_state, to_state)
        # Ensure the RDKit extension is fully loaded, because a subsequent
        # data migration would use the same connection
        with schema_editor.connection.cursor() as c:
            c.execute("SELECT mol_to_smiles('C'::mol)")

class GiSTIndex(Operation):

    reversible = True

    def __init__(self, model_name, name, index_name=None):
        self.model_name = model_name
        self.name = name
        self.index_name = index_name

    def state_forwards(self, app_label, state):
        pass

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        model = from_state.apps.get_model(app_label, self.model_name)
        field = model._meta.get_field(self.name)
        qn = schema_editor.quote_name

        sql_add_gist_index = "CREATE INDEX %(index)s ON %(table)s USING GIST (%(column)s)"

        index_name = (
            self.index_name if self.index_name is not None
            else '%s_%s_gist_idx' % (model._meta.db_table, field.column)
            )

        sql = sql_add_gist_index % {
            "index": qn(index_name),
            "table": qn(model._meta.db_table),
            "column": qn(field.column),
        }
        schema_editor.execute(sql)

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        model = from_state.apps.get_model(app_label, self.model_name)
        field = model._meta.get_field(self.name)
        qn = schema_editor.quote_name

        sql_remove_gist_index = "DROP INDEX %(index)s"

        index_name = (
            self.index_name if self.index_name is not None
            else '%s_%s_gist_idx' % (model._meta.db_table, field.column)
            )

        sql = sql_remove_gist_index % {
            "index": qn(index_name),
        }
        schema_editor.execute(sql)

    def describe(self):
        return "Creates GiST index on %s.%s" % (self.model_name, self.name)

<commit_msg>drop gist index operation<commit_after>from django.contrib.postgres.operations import CreateExtension

class RDKitExtension(CreateExtension):

    def __init__(self):
        self.name = 'rdkit'

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        super(RDKitExtension, self).database_forwards(app_label,
                                                      schema_editor,
                                                      from_state, to_state)
        # Ensure the RDKit extension is fully loaded, because a subsequent
        # data migration would use the same connection
        with schema_editor.connection.cursor() as c:
            c.execute("SELECT mol_to_smiles('C'::mol)")

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# system
from operator import attrgetter

# module
from .cache import cache_method, MethodProxy
from .lazyimport import lazyimport

# lazy imports
django = lazyimport({
    'ContentType' : 'django.contrib.contenttypes.models',
    'cache'       : 'django.core.cache',
    'Q'           : 'django.db.models',
})
db = lazyimport({
    'registry' : 'django_settings.models',
    'Setting'  : 'django_settings.models',
})

class dataapi_set_method_proxy(MethodProxy):
    def __call__(self, type_name, name, value, validate=True):
        get_key      = self._cache_key_for_method('get', name)
        exists_key   = self._cache_key_for_method('exists', name)
        setting      = self.origin_method(type_name, name, value, validate=validate)
        cached_value = self._cache_set(get_key, setting.setting_object.value)
        self._cache_set(exists_key, True)
        return cached_value

NIL = type('NIL', (object,), {})()

class dataapi_get_method_proxy(MethodProxy):
    def _cache_key(self, name): # should accept only "name"
        return self._cache_key_for_method('get', name)

    def __call__(self, name, **kwargs):
        default = kwargs.pop('default', NIL)
        try:
            return super(dataapi_get_method_proxy, self).__call__(name, **kwargs)
        except db.Setting.DoesNotExist:
            if default != NIL:
                return default
            raise

class DataAPIMetaclass(type):
    registry = []

    def setting_changed(cls, new_setting):
        for inst in cls.registry:  # XXX: the whole mechanism should be changed
            inst._set_cache_for(new_setting.name, new_setting.setting_object.value)

    def __call__(cls, *args, **kwargs):
        new = type.__call__(cls, *args, **kwargs)
        cls.registry.append(new)
        return new

class DataAPI(object):
    __metaclass__ = DataAPIMetaclass

    # class level
    name_getter = attrgetter('name')

    def __init__(self, cache_client=None):
        self._client = cache_client

    @property
    def cache(self):  # as lazy as possible
        return self._client or django.cache

    def contenttypes_names(self):
        ctypes = django.ContentType.objects.get_for_models(*db.registry.values()).values()
        return map(self.name_getter, ctypes)
    contenttypes_names = cache_method(contenttypes_names)

    def contenttypes_queryset(self):
        query = django.Q()
        for name in self.contenttypes_names():
            query = query | django.Q(name=name)
        return django.ContentType.objects.filter(query)

    def model_for_name(self, name):
        return db.registry[name]

    def type_names(self):
        return db.registry.names()

    def get(self, name, **kw):
        return db.Setting.objects.get_value(name, **kw)
    get = cache_method(get, dataapi_get_method_proxy)

    def set(self, type_name, name, value, validate=True):
        setting_type = db.registry.elements[type_name]
        return db.Setting.objects.set_value(name, setting_type, value, validate=validate)
    set = cache_method(set, dataapi_set_method_proxy)

    def exists(self, name):
        return bool(db.Setting.objects.value_object_exists(name))
    exists = cache_method(exists)

    def clear_cache(self):
        self.cache.clear()

    # XXX: fix this mechanism
    def _set_cache_for(self, name, value):
        self.get._cache_set(value, name)

data = DataAPI()

<commit_msg>dataapi: get method caching fixed<commit_after># -*- coding: utf-8 -*-
# system
from operator import attrgetter

# module
from .cache import cache_method, MethodProxy
from .lazyimport import lazyimport

# lazy imports
django = lazyimport({
    'ContentType' : 'django.contrib.contenttypes.models',
    'cache'       : 'django.core.cache',
    'Q'           : 'django.db.models',
})
db = lazyimport({
    'registry' : 'django_settings.models',
    'Setting'  : 'django_settings.models',
})

class dataapi_set_method_proxy(MethodProxy):
    def __call__(self, type_name, name, value, validate=True):
        get_key      = self._cache_key_for_method('get', name)
        exists_key   = self._cache_key_for_method('exists', name)
        setting      = self.origin_method(type_name, name, value, validate=validate)
        cached_value = self._cache_set(get_key, setting.setting_object.value)
        self._cache_set(exists_key, True)
        return cached_value

NIL = type('NIL', (object,), {})()

class dataapi_get_method_proxy(MethodProxy):
    def __call__(self, name, **kwargs):
        default = kwargs.pop('default', NIL)
        try:
            return super(dataapi_get_method_proxy, self).__call__(name)
        except db.Setting.DoesNotExist:
            if default != NIL:
                return default
            raise

class DataAPIMetaclass(type):
    registry = []

    def setting_changed(cls, new_setting):
        for inst in cls.registry:  # XXX: the whole mechanism should be changed
            inst._set_cache_for(new_setting.name, new_setting.setting_object.value)

    def __call__(cls, *args, **kwargs):
        new = type.__call__(cls, *args, **kwargs)
        cls.registry.append(new)
        return new

class DataAPI(object):
    __metaclass__ = DataAPIMetaclass

    # class level
    name_getter = attrgetter('name')

    def __init__(self, cache_client=None):
        self._client = cache_client

    @property
    def cache(self):  # as lazy as possible
        return self._client or django.cache

    def contenttypes_names(self):
        ctypes = django.ContentType.objects.get_for_models(*db.registry.values()).values()
        return map(self.name_getter, ctypes)
    contenttypes_names = cache_method(contenttypes_names)

    def contenttypes_queryset(self):
        query = django.Q()
        for name in self.contenttypes_names():
            query = query | django.Q(name=name)
        return django.ContentType.objects.filter(query)

    def model_for_name(self, name):
        return db.registry[name]

    def type_names(self):
        return db.registry.names()

    def get(self, name, **kw):
        return db.Setting.objects.get_value(name, **kw)
    get = cache_method(get, dataapi_get_method_proxy)

    def set(self, type_name, name, value, validate=True):
        setting_type = db.registry.elements[type_name]
        return db.Setting.objects.set_value(name, setting_type, value, validate=validate)
    set = cache_method(set, dataapi_set_method_proxy)

    def exists(self, name):
        return bool(db.Setting.objects.value_object_exists(name))
    exists = cache_method(exists)

    def clear_cache(self):
        self.cache.clear()

    # XXX: fix this mechanism
    def _set_cache_for(self, name, value):
        self.get._cache_set(value, name)

data = DataAPI()

<|endoftext|>


<commit_before>from django_thermostat.models import Context, Thermometer
from django.shortcuts import render_to_response, redirect
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
from settings import HEATER_INCREMENT, LIST_THERMOMETERS_API
from django.core.urlresolvers import reverse
from django_thermostat.mappings import get_mappings
from django_thermometer.temperature import read_temperatures
import simplejson, logging
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist

def set_internal_reference(request, tid):

    try:
        therm = Thermometer.objects.get(is_internal_reference=True)
        if therm.tid == tid or therm.caption == tid:
            return HttpResponse("")
        therm.is_internal_reference = None
        therm.save()
    except ObjectDoesNotExist:
	#no previously selected thermostat
	pass
    except Exception, err:
        logging.error("set_internal_reference: %s" % err)

    try:
        therm = Thermometer.objects.get(Q(tid=tid) | Q(caption=tid))
        therm.is_internal_reference = True
        therm.save()
        return HttpResponse("OK")
    except ObjectDoesNotExist:
        return HttpResponseBadRequest("Thermostats %s not found" % tid)
    except Exception, ex:
        logging.error("set_internal_reference: %s" % ex)
        return HttpResponseServerError(ex)

def home(request):
    context = Context.objects.get_or_create(pk=1)

    return render_to_response(
        "therm/home.html",
        {"context": context, },
    )

def temperatures(request):
    therms = read_temperatures()
    known_therms = {}
    for x in Thermometer.objects.all():
        known_therms[x.tid] = [x.caption, x.is_internal_reference]
    out = {}
    for tid, data in therms.items():
        try:
            out[known_therms[tid][0]] = [data, known_therms[tid][1]]
        except KeyError:
            out[tid] = [data, False]

    response = HttpResponse(
        content=simplejson.dumps(out),
        content_type="application/json")
    response['Cache-Control'] = 'no-cache'
    return response

def dim_temp(request, temp):
    context = Context.objects.get()
    if temp == "confort":
        context.confort_temperature = float(context.confort_temperature) - float(HEATER_INCREMENT)
    if temp == "economic":
        context.economic_temperature = float(context.economic_temperature) - float(HEATER_INCREMENT)
    context.save()
    return redirect(reverse("read_heat_status"))

def bri_temp(request, temp):
    context = Context.objects.get()
    if temp == "confort":
        context.confort_temperature = float(context.confort_temperature) + float(HEATER_INCREMENT)
    if temp == "economic":
        context.economic_temperature = float(context.economic_temperature) + float(HEATER_INCREMENT)
    context.save()
    return redirect(reverse("read_heat_status"))

def toggle_heat_manual(request):
    context = Context.objects.get()
    context.manual = not context.manual
    context.save()
    return redirect(reverse("read_heat_status"))

def toggle_heat_status(request):
    context = Context.objects.get()
    context.heat_on = not context.heat_on
    context.save()

    return HttpResponse("")

def read_heat_status(request):
    response = render_to_response(
        "therm/context.json",
        {"data": Context.objects.get().to_json()},
        content_type="application/json",
    )
    response['Cache-Control'] = 'no-cache'
    return response

def context_js(request):
    return render_to_response(
        "context.js",
        {"temperatures_uri": LIST_THERMOMETERS_API, },
        content_type="application/javascript")
<commit_msg>Added the posibility of using a remote thermometer service in case django_thermostat.settings.LIST_THERMOMETERS_API is not None<commit_after>from django_thermostat.models import Context, Thermometer
from django.shortcuts import render_to_response, redirect
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseServerError
from settings import HEATER_INCREMENT, LIST_THERMOMETERS_API
from django.core.urlresolvers import reverse
from django_thermostat.mappings import get_mappings
from django_thermometer.temperature import read_temperatures
import simplejson, logging, requests
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist

def set_internal_reference(request, tid):

    try:
        therm = Thermometer.objects.get(is_internal_reference=True)
        if therm.tid == tid or therm.caption == tid:
            return HttpResponse("")
        therm.is_internal_reference = None
        therm.save()
    except ObjectDoesNotExist:
	#no previously selected thermostat
	pass
    except Exception, err:
        logging.error("set_internal_reference: %s" % err)

    try:
        therm = Thermometer.objects.get(Q(tid=tid) | Q(caption=tid))
        therm.is_internal_reference = True
        therm.save()
        return HttpResponse("OK")
    except ObjectDoesNotExist:
        return HttpResponseBadRequest("Thermostats %s not found" % tid)
    except Exception, ex:
        logging.error("set_internal_reference: %s" % ex)
        return HttpResponseServerError(ex)

def home(request):
    context = Context.objects.get_or_create(pk=1)

    return render_to_response(
        "therm/home.html",
        {"context": context,
         },
    )

def temperatures(request):
    if not LIST_THERMOMETERS_API is None:
        ret = requests.get(LIST_THERMOMETERS_API)
        response = HttpResponse(
            content=simplejson.dumps(ret.json()),
            content_type="application/json")
        response['Cache-Control'] = 'no-cache'
        return response

    therms = read_temperatures()
    known_therms = {}
    for x in Thermometer.objects.all():
        known_therms[x.tid] = [x.caption, x.is_internal_reference]
    out = {}
    for tid, data in therms.items():
        try:
            out[known_therms[tid][0]] = [data, known_therms[tid][1]]
        except KeyError:
            out[tid] = [data, False]

    response = HttpResponse(
        content=simplejson.dumps(out),
        content_type="application/json")
    response['Cache-Control'] = 'no-cache'
    return response

def dim_temp(request, temp):
    context = Context.objects.get()
    if temp == "confort":
        context.confort_temperature = float(context.confort_temperature) - float(HEATER_INCREMENT)
    if temp == "economic":
        context.economic_temperature = float(context.economic_temperature) - float(HEATER_INCREMENT)
    context.save()
    return redirect(reverse("read_heat_status"))

def bri_temp(request, temp):
    context = Context.objects.get()
    if temp == "confort":
        context.confort_temperature = float(context.confort_temperature) + float(HEATER_INCREMENT)
    if temp == "economic":
        context.economic_temperature = float(context.economic_temperature) + float(HEATER_INCREMENT)
    context.save()
    return redirect(reverse("read_heat_status"))

def toggle_heat_manual(request):
    context = Context.objects.get()
    context.manual = not context.manual
    context.save()
    return redirect(reverse("read_heat_status"))

def toggle_heat_status(request):
    context = Context.objects.get()
    context.heat_on = not context.heat_on
    context.save()

    return HttpResponse("")

def read_heat_status(request):
    response = render_to_response(
        "therm/context.json",
        {"data": Context.objects.get().to_json()},
        content_type="application/json",
    )
    response['Cache-Control'] = 'no-cache'
    return response

def context_js(request):
    return render_to_response(
        "context.js",
        {"temperatures_uri": LIST_THERMOMETERS_API, },
        content_type="application/javascript")
<|endoftext|>


<commit_before># Create your views here.

from django.shortcuts import render, get_object_or_404, redirect
from djangopress.pages.models import Page, PageBlock
from django.conf import settings
from django.http import Http404, HttpResponseForbidden, HttpResponsePermanentRedirect
from djangopress.pages.forms import PageForm, NewBlockForm, TextForm

def show_page(request, path):
    try:
        page = Page.objects.get(location=path, sites__id__exact=settings.SITE_ID,
                visibility="VI", status="PB")
    except Page.DoesNotExist:
        try:
            if path[-1] != '/':
                Page.objects.get(location=path+'/', sites__id__exact=settings.SITE_ID,
                    visibility="VI", status="PB")
                #did not throw an exception, so lets redirect
                return HttpResponsePermanentRedirect(path+'/')
            else:
                raise Http404
        except Page.DoesNotExist:
            raise Http404
    if hasattr(request, 'user'):
        user = request.user
        show_toolbar = user.has_perm('pages.change_page') if user else False
    else:
        show_toolbar = False
    data = {
        "page": page,
        "show_toolbar": show_toolbar,
        "enable_page_edit": "edit_cms_page" in request.GET
    }
    return render(request, page.template.template, data)

def get_blocks(page, identifier, name):
    if identifier:
        return PageBlock.objects.filter(block_id=identifier)
    else:
        return page.blocks.filter(block_name=name)

def get_forms(blocks, name):
    forms = []
    for block in blocks:
        form = TextForm(instance=block, prefix="%s-%s" % (block.pk, name))
        forms.append(form)
    return forms

def page_edit(request, identifier=None, name=None, page=None,
        template_name='pages/editor/block.html'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    page = get_object_or_404(Page, pk=page)

    blocks = get_blocks(page, identifier, name)
    forms = []
    changes = False
    if request.method == 'POST':
        new_block = NewBlockForm(request.POST, prefix=name)
        if new_block.is_valid():
            block = PageBlock(block_name=name, block_id=identifier, position=blocks.count()+1, page=page)
            block.save()
            blocks = get_blocks(page, identifier, name)
            forms = get_forms(blocks, name)
        else:
            for block in blocks:
                prefix = "%s-%s" % (block.pk, name)
                form = TextForm(request.POST, instance=block, prefix=prefix)
                if form.is_valid():
                    form.save(True)
                    changes = True
                else:
                    form = TextForm(instance=block, prefix=prefix)
                forms.append(form)
            print changes
            if changes:
                return redirect(page.location)
    else:
        forms = get_forms(blocks, name)
    new_block = NewBlockForm(prefix=name)
    data = {
        "page": page,
        "forms": forms,
        "new_block": new_block,
        "name": identifier if identifier else name,
    }
    return render(request, template_name, data)

def page_edit_ajax(request):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    action = request.GET.get("action")
    if action == 'edit-page':
        return page_edit_details(request, request.GET.get("page"),
                template_name='pages/editor/details-form.html')
    elif action == 'edit-block':
        return page_edit(request, request.GET.get("identifier"),
                  request.GET.get("name"), request.GET.get("page"),
                  template_name='pages/editor/block-form.html')
    raise Http404

def page_edit_details(request, page, template_name='pages/editor/details.html'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    page = get_object_or_404(Page, pk=page)
    if request.method == 'POST':
        form = PageForm(request.POST, instance=page, prefix="page-primary")
        if form.is_valid():
            form.save(True)
            return redirect(page.location)
    else:
        form = PageForm(instance=page, prefix="page-primary")
    data = {
        "page": page,
        "form": form,
    }
    return render(request, template_name, data)

def page_edit_js(request, template_name='pages/js/edit-page.js'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    return render(request, template_name, content_type="text/javascript")<commit_msg>making a generated js file be cached<commit_after># Create your views here.

from django.shortcuts import render, get_object_or_404, redirect
from djangopress.pages.models import Page, PageBlock
from django.conf import settings
from django.http import Http404, HttpResponseForbidden, HttpResponsePermanentRedirect
from djangopress.pages.forms import PageForm, NewBlockForm, TextForm
from django.utils import cache

def show_page(request, path):
    try:
        page = Page.objects.get(location=path, sites__id__exact=settings.SITE_ID,
                visibility="VI", status="PB")
    except Page.DoesNotExist:
        try:
            if path[-1] != '/':
                Page.objects.get(location=path+'/', sites__id__exact=settings.SITE_ID,
                    visibility="VI", status="PB")
                #did not throw an exception, so lets redirect
                return HttpResponsePermanentRedirect(path+'/')
            else:
                raise Http404
        except Page.DoesNotExist:
            raise Http404
    if hasattr(request, 'user'):
        user = request.user
        show_toolbar = user.has_perm('pages.change_page') if user else False
    else:
        show_toolbar = False
    data = {
        "page": page,
        "show_toolbar": show_toolbar,
        "enable_page_edit": "edit_cms_page" in request.GET
    }
    return render(request, page.template.template, data)

def get_blocks(page, identifier, name):
    if identifier:
        return PageBlock.objects.filter(block_id=identifier)
    else:
        return page.blocks.filter(block_name=name)

def get_forms(blocks, name):
    forms = []
    for block in blocks:
        form = TextForm(instance=block, prefix="%s-%s" % (block.pk, name))
        forms.append(form)
    return forms

def page_edit(request, identifier=None, name=None, page=None,
        template_name='pages/editor/block.html'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    page = get_object_or_404(Page, pk=page)

    blocks = get_blocks(page, identifier, name)
    forms = []
    changes = False
    if request.method == 'POST':
        new_block = NewBlockForm(request.POST, prefix=name)
        if new_block.is_valid():
            block = PageBlock(block_name=name, block_id=identifier, position=blocks.count()+1, page=page)
            block.save()
            blocks = get_blocks(page, identifier, name)
            forms = get_forms(blocks, name)
        else:
            for block in blocks:
                prefix = "%s-%s" % (block.pk, name)
                form = TextForm(request.POST, instance=block, prefix=prefix)
                if form.is_valid():
                    form.save(True)
                    changes = True
                else:
                    form = TextForm(instance=block, prefix=prefix)
                forms.append(form)
            print changes
            if changes:
                return redirect(page.location)
    else:
        forms = get_forms(blocks, name)
    new_block = NewBlockForm(prefix=name)
    data = {
        "page": page,
        "forms": forms,
        "new_block": new_block,
        "name": identifier if identifier else name,
    }
    return render(request, template_name, data)

def page_edit_ajax(request):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    action = request.GET.get("action")
    if action == 'edit-page':
        return page_edit_details(request, request.GET.get("page"),
                template_name='pages/editor/details-form.html')
    elif action == 'edit-block':
        return page_edit(request, request.GET.get("identifier"),
                  request.GET.get("name"), request.GET.get("page"),
                  template_name='pages/editor/block-form.html')
    raise Http404

def page_edit_details(request, page, template_name='pages/editor/details.html'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    page = get_object_or_404(Page, pk=page)
    if request.method == 'POST':
        form = PageForm(request.POST, instance=page, prefix="page-primary")
        if form.is_valid():
            form.save(True)
            return redirect(page.location)
    else:
        form = PageForm(instance=page, prefix="page-primary")
    data = {
        "page": page,
        "form": form,
    }
    return render(request, template_name, data)

def page_edit_js(request, template_name='pages/js/edit-page.js'):
    if not request.user.has_perm('pages.change_page'):
        return HttpResponseForbidden()
    responce = render(request, template_name, content_type="text/javascript")
    cache.patch_response_headers(responce, cache_timeout=60*60*24*30)
    return responce<|endoftext|>


<commit_before>import stripe
from django.db import models, transaction

from .. import enums
from ..enums import APIKeyType
from ..fields import JSONField, StripeCurrencyCodeField, StripeEnumField
from ..settings import djstripe_settings
from .api import APIKey
from .base import StripeModel

class Account(StripeModel):
    """
    Stripe documentation: https://stripe.com/docs/api#account
    """

    djstripe_owner_account = None

    stripe_class = stripe.Account
    business_profile = JSONField(
        null=True, blank=True, help_text="Optional information related to the business."
    )
    business_type = StripeEnumField(
        enum=enums.BusinessType, default="", blank=True, help_text="The business type."
    )
    charges_enabled = models.BooleanField(
        help_text="Whether the account can create live charges"
    )
    country = models.CharField(max_length=2, help_text="The country of the account")
    company = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Information about the company or business. "
            "This field is null unless business_type is set to company."
        ),
    )
    default_currency = StripeCurrencyCodeField(
        help_text="The currency this account has chosen to use as the default"
    )
    details_submitted = models.BooleanField(
        help_text=(
            "Whether account details have been submitted. "
            "Standard accounts cannot receive payouts before this is true."
        )
    )
    email = models.CharField(
        max_length=255, help_text="The primary user’s email address."
    )
    # TODO external_accounts = ...
    individual = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Information about the person represented by the account. "
            "This field is null unless business_type is set to individual."
        ),
    )
    payouts_enabled = models.BooleanField(
        null=True, help_text="Whether Stripe can send payouts to this account"
    )
    product_description = models.CharField(
        max_length=255,
        default="",
        blank=True,
        help_text="Internal-only description of the product sold or service provided "
        "by the business. It’s used by Stripe for risk and underwriting purposes.",
    )
    requirements = JSONField(
        null=True,
        blank=True,
        help_text="Information about the requirements for the account, "
        "including what information needs to be collected, and by when.",
    )
    settings = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Account options for customizing how the account functions within Stripe."
        ),
    )
    type = StripeEnumField(enum=enums.AccountType, help_text="The Stripe account type.")
    tos_acceptance = JSONField(
        null=True,
        blank=True,
        help_text="Details on the acceptance of the Stripe Services Agreement",
    )

    @property
    def default_api_key(self) -> str:
        return self.get_default_api_key()

    def get_default_api_key(self) -> str:
        api_key = APIKey.objects.filter(
            djstripe_owner_account=self, type=APIKeyType.secret
        ).first()
        if api_key:
            return api_key.secret
        return djstripe_settings.get_default_api_key(self.livemode)

    @property
    def business_url(self) -> str:
        """
        The business’s publicly available website.
        """
        if self.business_profile:
            return self.business_profile.get("url", "")
        return ""

    @classmethod
    def get_default_account(cls):
        # As of API version 2020-03-02, there is no permission that can allow
        # restricted keys to call GET /v1/account
        if djstripe_settings.STRIPE_SECRET_KEY.startswith("rk_"):
            return None

        account_data = cls.stripe_class.retrieve(
            api_key=djstripe_settings.STRIPE_SECRET_KEY
        )

        return cls._get_or_create_from_stripe_object(account_data)[0]

    @classmethod
    def get_or_retrieve_for_api_key(cls, api_key: str):
        with transaction.atomic():
            apikey_instance, _ = APIKey.objects.get_or_create_by_api_key(api_key)
            if not apikey_instance.djstripe_owner_account:
                apikey_instance.refresh_account()

            return apikey_instance.djstripe_owner_account

    def __str__(self):
        settings = self.settings or {}
        business_profile = self.business_profile or {}
        return (
            settings.get("dashboard", {}).get("display_name")
            or business_profile.get("name")
            or super().__str__()
        )

    @classmethod
    def _create_from_stripe_object(
        cls,
        data,
        current_ids=None,
        pending_relations=None,
        save=True,
        stripe_account=None,
    ):
        """
        Set the stripe_account to the id of the Account instance being created.

        This ensures that the foreign-key relations that may exist in stripe are
        fetched using the appropriate connected account ID.
        """
        return super()._create_from_stripe_object(
            data=data,
            current_ids=current_ids,
            pending_relations=pending_relations,
            save=save,
            stripe_account=data["id"] if not stripe_account else stripe_account,
        )

    @classmethod
    def _find_owner_account(cls, data):
        # Account model never has an owner account (it's always itself)
        return None

    # "Special" handling of the icon and logo fields
    # Previously available as properties, they moved to
    # settings.branding in Stripe 2019-02-19.
    # Currently, they return a File ID
    @property
    def branding_icon(self):
        from ..models.core import File

        id = self.settings.get("branding", {}).get("icon")
        return File.objects.filter(id=id).first() if id else None

    @property
    def branding_logo(self):
        from ..models.core import File

        id = self.settings.get("branding", {}).get("logo")
        return File.objects.filter(id=id).first() if id else None

    def _attach_objects_post_save_hook(self, cls, data, pending_relations=None):
        from ..models.core import File

        super()._attach_objects_post_save_hook(
            cls, data, pending_relations=pending_relations
        )

        # Retrieve and save the Files in the settings.branding object.
        for field in "icon", "logo":
            file_upload_id = self.settings.get("branding", {}).get(field)
            if file_upload_id:
                try:
                    File.sync_from_stripe_data(
                        File(id=file_upload_id).api_retrieve(stripe_account=self.id)
                    )
                except stripe.error.PermissionError:
                    # No permission to retrieve the data with the key
                    pass
                except stripe.error.InvalidRequestError as e:
                    if "a similar object exists in" in str(e):
                        # HACK around a Stripe bug.
                        # See #830 and commit c09d25f52bfdcf883e9eec0bf6c25af1771a644a
                        pass
                    else:
                        raise
<commit_msg>Logged warning to console if Business icon and/or logo cannot be retrieved<commit_after>import stripe
from django.db import models, transaction

from .. import enums
from ..enums import APIKeyType
from ..fields import JSONField, StripeCurrencyCodeField, StripeEnumField
from ..settings import djstripe_settings
from .api import APIKey
from .base import StripeModel, logger

class Account(StripeModel):
    """
    Stripe documentation: https://stripe.com/docs/api#account
    """

    djstripe_owner_account = None

    stripe_class = stripe.Account
    business_profile = JSONField(
        null=True, blank=True, help_text="Optional information related to the business."
    )
    business_type = StripeEnumField(
        enum=enums.BusinessType, default="", blank=True, help_text="The business type."
    )
    charges_enabled = models.BooleanField(
        help_text="Whether the account can create live charges"
    )
    country = models.CharField(max_length=2, help_text="The country of the account")
    company = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Information about the company or business. "
            "This field is null unless business_type is set to company."
        ),
    )
    default_currency = StripeCurrencyCodeField(
        help_text="The currency this account has chosen to use as the default"
    )
    details_submitted = models.BooleanField(
        help_text=(
            "Whether account details have been submitted. "
            "Standard accounts cannot receive payouts before this is true."
        )
    )
    email = models.CharField(
        max_length=255, help_text="The primary user’s email address."
    )
    # TODO external_accounts = ...
    individual = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Information about the person represented by the account. "
            "This field is null unless business_type is set to individual."
        ),
    )
    payouts_enabled = models.BooleanField(
        null=True, help_text="Whether Stripe can send payouts to this account"
    )
    product_description = models.CharField(
        max_length=255,
        default="",
        blank=True,
        help_text="Internal-only description of the product sold or service provided "
        "by the business. It’s used by Stripe for risk and underwriting purposes.",
    )
    requirements = JSONField(
        null=True,
        blank=True,
        help_text="Information about the requirements for the account, "
        "including what information needs to be collected, and by when.",
    )
    settings = JSONField(
        null=True,
        blank=True,
        help_text=(
            "Account options for customizing how the account functions within Stripe."
        ),
    )
    type = StripeEnumField(enum=enums.AccountType, help_text="The Stripe account type.")
    tos_acceptance = JSONField(
        null=True,
        blank=True,
        help_text="Details on the acceptance of the Stripe Services Agreement",
    )

    @property
    def default_api_key(self) -> str:
        return self.get_default_api_key()

    def get_default_api_key(self) -> str:
        api_key = APIKey.objects.filter(
            djstripe_owner_account=self, type=APIKeyType.secret
        ).first()
        if api_key:
            return api_key.secret
        return djstripe_settings.get_default_api_key(self.livemode)

    @property
    def business_url(self) -> str:
        """
        The business’s publicly available website.
        """
        if self.business_profile:
            return self.business_profile.get("url", "")
        return ""

    @classmethod
    def get_default_account(cls):
        # As of API version 2020-03-02, there is no permission that can allow
        # restricted keys to call GET /v1/account
        if djstripe_settings.STRIPE_SECRET_KEY.startswith("rk_"):
            return None

        account_data = cls.stripe_class.retrieve(
            api_key=djstripe_settings.STRIPE_SECRET_KEY
        )

        return cls._get_or_create_from_stripe_object(account_data)[0]

    @classmethod
    def get_or_retrieve_for_api_key(cls, api_key: str):
        with transaction.atomic():
            apikey_instance, _ = APIKey.objects.get_or_create_by_api_key(api_key)
            if not apikey_instance.djstripe_owner_account:
                apikey_instance.refresh_account()

            return apikey_instance.djstripe_owner_account

    def __str__(self):
        settings = self.settings or {}
        business_profile = self.business_profile or {}
        return (
            settings.get("dashboard", {}).get("display_name")
            or business_profile.get("name")
            or super().__str__()
        )

    @classmethod
    def _create_from_stripe_object(
        cls,
        data,
        current_ids=None,
        pending_relations=None,
        save=True,
        stripe_account=None,
    ):
        """
        Set the stripe_account to the id of the Account instance being created.

        This ensures that the foreign-key relations that may exist in stripe are
        fetched using the appropriate connected account ID.
        """
        return super()._create_from_stripe_object(
            data=data,
            current_ids=current_ids,
            pending_relations=pending_relations,
            save=save,
            stripe_account=data["id"] if not stripe_account else stripe_account,
        )

    @classmethod
    def _find_owner_account(cls, data):
        # Account model never has an owner account (it's always itself)
        return None

    # "Special" handling of the icon and logo fields
    # Previously available as properties, they moved to
    # settings.branding in Stripe 2019-02-19.
    # Currently, they return a File ID
    @property
    def branding_icon(self):
        from ..models.core import File

        id = self.settings.get("branding", {}).get("icon")
        return File.objects.filter(id=id).first() if id else None

    @property
    def branding_logo(self):
        from ..models.core import File

        id = self.settings.get("branding", {}).get("logo")
        return File.objects.filter(id=id).first() if id else None

    def _attach_objects_post_save_hook(self, cls, data, pending_relations=None):
        from ..models.core import File

        super()._attach_objects_post_save_hook(
            cls, data, pending_relations=pending_relations
        )

        # Retrieve and save the Files in the settings.branding object.
        for field in "icon", "logo":
            file_upload_id = self.settings.get("branding", {}).get(field)
            if file_upload_id:
                try:
                    File.sync_from_stripe_data(
                        File(id=file_upload_id).api_retrieve(stripe_account=self.id)
                    )
                except stripe.error.PermissionError:
                    # No permission to retrieve the data with the key
                    logger.warning(
                        f"Cannot retrieve business branding {field} for acct {self.id} with the key."
                    )
                except stripe.error.InvalidRequestError as e:
                    if "a similar object exists in" in str(e):
                        # HACK around a Stripe bug.
                        # See #830 and commit c09d25f52bfdcf883e9eec0bf6c25af1771a644a
                        pass
                    else:
                        raise
<|endoftext|>


<commit_before>from django.shortcuts import render_to_response

def main(self):
    return render_to_response("main.haml")<commit_msg>pushing change to test heroku<commit_after>from django.shortcuts import render_to_response

def main(self):
    return render_to_response("main.haml")

def convert(self, csv_txt):
    return render_to_response("main.haml")<|endoftext|>