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

#.apidoc title: Objects Services (OSV)

from functools import wraps
import logging
from psycopg2 import IntegrityError, errorcodes

import orm
import openerp
import openerp.netsvc as netsvc
import openerp.pooler as pooler
import openerp.sql_db as sql_db
from openerp.tools.translate import translate
from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel
import openerp.exceptions

_logger = logging.getLogger(__name__)

# Deprecated.
class except_osv(Exception):
    def __init__(self, name, value):
        self.name = name
        self.value = value
        self.args = (name, value)

service = None

class object_proxy(object):
    def __init__(self):
        global service
        service = self

    def check(f):
        @wraps(f)
        def wrapper(self, dbname, *args, **kwargs):
            """ Wraps around OSV functions and normalises a few exceptions
            """

            def tr(src, ttype):
                # We try to do the same as the _(), but without the frame
                # inspection, since we aready are wrapping an osv function
                # trans_obj = self.get('ir.translation') cannot work yet :(
                ctx = {}
                if not kwargs:
                    if args and isinstance(args[-1], dict):
                        ctx = args[-1]
                elif isinstance(kwargs, dict):
                    ctx = kwargs.get('context', {})

                uid = 1
                if args and isinstance(args[0], (long, int)):
                    uid = args[0]

                lang = ctx and ctx.get('lang')
                if not (lang or hasattr(src, '__call__')):
                    return src

                # We open a *new* cursor here, one reason is that failed SQL
                # queries (as in IntegrityError) will invalidate the current one.
                cr = False

                if hasattr(src, '__call__'):
                    # callable. We need to find the right parameters to call
                    # the  orm._sql_message(self, cr, uid, ids, context) function,
                    # or we skip..
                    # our signature is f(osv_pool, dbname [,uid, obj, method, args])
                    try:
                        if args and len(args) > 1:
                            obj = self.get(args[1])
                            if len(args) > 3 and isinstance(args[3], (long, int, list)):
                                ids = args[3]
                            else:
                                ids = []
                        cr = sql_db.db_connect(dbname).cursor()
                        return src(obj, cr, uid, ids, context=(ctx or {}))
                    except Exception:
                        pass
                    finally:
                        if cr: cr.close()

                    return False # so that the original SQL error will
                                 # be returned, it is the best we have.

                try:
                    cr = sql_db.db_connect(dbname).cursor()
                    res = translate(cr, name=False, source_type=ttype,
                                    lang=lang, source=src)
                    if res:
                        return res
                    else:
                        return src
                finally:
                    if cr: cr.close()

            def _(src):
                return tr(src, 'code')

            try:
                if pooler.get_pool(dbname)._init:
                    raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.')
                return f(self, dbname, *args, **kwargs)
            except orm.except_orm, inst:
                raise except_osv(inst.name, inst.value)
            except except_osv:
                raise
            except IntegrityError, inst:
                osv_pool = pooler.get_pool(dbname)
                for key in osv_pool._sql_error.keys():
                    if key in inst[0]:
                        netsvc.abort_response(1, _('Constraint Error'), 'warning',
                                        tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0])
                if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION):
                    msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set')
                    _logger.debug("IntegrityError", exc_info=True)
                    try:
                        errortxt = inst.pgerror.replace('«','"').replace('»','"')
                        if '"public".' in errortxt:
                            context = errortxt.split('"public".')[1]
                            model_name = table = context.split('"')[1]
                        else:
                            last_quote_end = errortxt.rfind('"')
                            last_quote_begin = errortxt.rfind('"', 0, last_quote_end)
                            model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip()
                        model = table.replace("_",".")
                        model_obj = osv_pool.get(model)
                        if model_obj:
                            model_name = model_obj._description or model_obj._name
                        msg += _('\n\n[object with reference: %s - %s]') % (model_name, model)
                    except Exception:
                        pass
                    netsvc.abort_response(1, _('Integrity Error'), 'warning', msg)
                else:
                    netsvc.abort_response(1, _('Integrity Error'), 'warning', inst[0])
            except Exception:
                _logger.exception("Uncaught exception")
                raise

        return wrapper

    def execute_cr(self, cr, uid, obj, method, *args, **kw):
        object = pooler.get_pool(cr.dbname).get(obj)
        if not object:
            raise except_osv('Object Error', 'Object %s doesn\'t exist' % str(obj))
        return getattr(object, method)(cr, uid, *args, **kw)

    def execute_kw(self, db, uid, obj, method, args, kw=None):
        return self.execute(db, uid, obj, method, *args, **kw or {})

    @check
    def execute(self, db, uid, obj, method, *args, **kw):
        cr = pooler.get_db(db).cursor()
        try:
            try:
                if method.startswith('_'):
                    raise except_osv('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,))
                res = self.execute_cr(cr, uid, obj, method, *args, **kw)
                if res is None:
                    _logger.warning('The method %s of the object %s can not return `None` !', method, obj)
                cr.commit()
            except Exception:
                cr.rollback()
                raise
        finally:
            cr.close()
        return res

    def exec_workflow_cr(self, cr, uid, obj, method, *args):
        wf_service = netsvc.LocalService("workflow")
        return wf_service.trg_validate(uid, obj, args[0], method, cr)

    @check
    def exec_workflow(self, db, uid, obj, method, *args):
        cr = pooler.get_db(db).cursor()
        try:
            try:
                res = self.exec_workflow_cr(cr, uid, obj, method, *args)
                cr.commit()
            except Exception:
                cr.rollback()
                raise
        finally:
            cr.close()
        return res

# deprecated - for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)

def start_object_proxy():
    object_proxy()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[FIX] osv: Automatically retry the typical transaction serialization errors<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

#.apidoc title: Objects Services (OSV)

from functools import wraps
import logging
from psycopg2 import IntegrityError, OperationalError, errorcodes

import orm
import openerp
import openerp.netsvc as netsvc
import openerp.pooler as pooler
import openerp.sql_db as sql_db
from openerp.tools.translate import translate
from openerp.osv.orm import MetaModel, Model, TransientModel, AbstractModel
import openerp.exceptions

import time
import random

_logger = logging.getLogger(__name__)

PG_CONCURRENCY_ERRORS_TO_RETRY = (errorcodes.LOCK_NOT_AVAILABLE, errorcodes.SERIALIZATION_FAILURE, errorcodes.DEADLOCK_DETECTED)
MAX_TRIES_ON_CONCURRENCY_FAILURE = 5

# Deprecated.
class except_osv(Exception):
    def __init__(self, name, value):
        self.name = name
        self.value = value
        self.args = (name, value)

service = None

class object_proxy(object):
    def __init__(self):
        global service
        service = self

    def check(f):
        @wraps(f)
        def wrapper(self, dbname, *args, **kwargs):
            """ Wraps around OSV functions and normalises a few exceptions
            """

            def tr(src, ttype):
                # We try to do the same as the _(), but without the frame
                # inspection, since we aready are wrapping an osv function
                # trans_obj = self.get('ir.translation') cannot work yet :(
                ctx = {}
                if not kwargs:
                    if args and isinstance(args[-1], dict):
                        ctx = args[-1]
                elif isinstance(kwargs, dict):
                    ctx = kwargs.get('context', {})

                uid = 1
                if args and isinstance(args[0], (long, int)):
                    uid = args[0]

                lang = ctx and ctx.get('lang')
                if not (lang or hasattr(src, '__call__')):
                    return src

                # We open a *new* cursor here, one reason is that failed SQL
                # queries (as in IntegrityError) will invalidate the current one.
                cr = False

                if hasattr(src, '__call__'):
                    # callable. We need to find the right parameters to call
                    # the  orm._sql_message(self, cr, uid, ids, context) function,
                    # or we skip..
                    # our signature is f(osv_pool, dbname [,uid, obj, method, args])
                    try:
                        if args and len(args) > 1:
                            obj = self.get(args[1])
                            if len(args) > 3 and isinstance(args[3], (long, int, list)):
                                ids = args[3]
                            else:
                                ids = []
                        cr = sql_db.db_connect(dbname).cursor()
                        return src(obj, cr, uid, ids, context=(ctx or {}))
                    except Exception:
                        pass
                    finally:
                        if cr: cr.close()

                    return False # so that the original SQL error will
                                 # be returned, it is the best we have.

                try:
                    cr = sql_db.db_connect(dbname).cursor()
                    res = translate(cr, name=False, source_type=ttype,
                                    lang=lang, source=src)
                    if res:
                        return res
                    else:
                        return src
                finally:
                    if cr: cr.close()

            def _(src):
                return tr(src, 'code')

            tries = 0
            while True:
                try:
                    if pooler.get_pool(dbname)._init:
                        raise except_osv('Database not ready', 'Currently, this database is not fully loaded and can not be used.')
                    return f(self, dbname, *args, **kwargs)
                except OperationalError, e:
                    # Automatically retry the typical transaction serialization errors
                    if not e.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY or tries >= MAX_TRIES_ON_CONCURRENCY_FAILURE:
                        self.logger.warning("%s, maximum number of tries reached" % errorcodes.lookup(e.pgcode))
                        raise
                    wait_time = random.uniform(0.0, 2 ** tries)
                    tries += 1
                    self.logger.info("%s, retrying %d/%d in %.04f sec..." % (errorcodes.lookup(e.pgcode), tries, MAX_TRIES_ON_CONCURRENCY_FAILURE, wait_time))
                    time.sleep(wait_time)
                except orm.except_orm, inst:
                    raise except_osv(inst.name, inst.value)
                except except_osv:
                    raise
                except IntegrityError, inst:
                    osv_pool = pooler.get_pool(dbname)
                    for key in osv_pool._sql_error.keys():
                        if key in inst[0]:
                            netsvc.abort_response(1, _('Constraint Error'), 'warning',
                                            tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0])
                    if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION):
                        msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set')
                        _logger.debug("IntegrityError", exc_info=True)
                        try:
                            errortxt = inst.pgerror.replace('«','"').replace('»','"')
                            if '"public".' in errortxt:
                                context = errortxt.split('"public".')[1]
                                model_name = table = context.split('"')[1]
                            else:
                                last_quote_end = errortxt.rfind('"')
                                last_quote_begin = errortxt.rfind('"', 0, last_quote_end)
                                model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip()
                            model = table.replace("_",".")
                            model_obj = osv_pool.get(model)
                            if model_obj:
                                model_name = model_obj._description or model_obj._name
                            msg += _('\n\n[object with reference: %s - %s]') % (model_name, model)
                        except Exception:
                            pass
                        netsvc.abort_response(1, _('Integrity Error'), 'warning', msg)
                    else:
                        netsvc.abort_response(1, _('Integrity Error'), 'warning', inst[0])
                except Exception:
                    _logger.exception("Uncaught exception")
                    raise

        return wrapper

    def execute_cr(self, cr, uid, obj, method, *args, **kw):
        object = pooler.get_pool(cr.dbname).get(obj)
        if not object:
            raise except_osv('Object Error', 'Object %s doesn\'t exist' % str(obj))
        return getattr(object, method)(cr, uid, *args, **kw)

    def execute_kw(self, db, uid, obj, method, args, kw=None):
        return self.execute(db, uid, obj, method, *args, **kw or {})

    @check
    def execute(self, db, uid, obj, method, *args, **kw):
        cr = pooler.get_db(db).cursor()
        try:
            try:
                if method.startswith('_'):
                    raise except_osv('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,))
                res = self.execute_cr(cr, uid, obj, method, *args, **kw)
                if res is None:
                    _logger.warning('The method %s of the object %s can not return `None` !', method, obj)
                cr.commit()
            except Exception:
                cr.rollback()
                raise
        finally:
            cr.close()
        return res

    def exec_workflow_cr(self, cr, uid, obj, method, *args):
        wf_service = netsvc.LocalService("workflow")
        return wf_service.trg_validate(uid, obj, args[0], method, cr)

    @check
    def exec_workflow(self, db, uid, obj, method, *args):
        cr = pooler.get_db(db).cursor()
        try:
            try:
                res = self.exec_workflow_cr(cr, uid, obj, method, *args)
                cr.commit()
            except Exception:
                cr.rollback()
                raise
        finally:
            cr.close()
        return res

# deprecated - for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)

def start_object_proxy():
    object_proxy()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before>"""Picklers for working with serialized data."""

from __future__ import unicode_literals

import pickle

from django_evolution.compat.datastructures import OrderedDict

class SortedDict(dict):
    """Compatibility for unpickling a SortedDict.

    Old signatures may use an old Django ``SortedDict`` structure, which does
    not exist in modern versions. This changes any construction of this
    data structure into a :py:class:`collections.OrderedDict`.
    """

    def __new__(cls, *args, **kwargs):
        """Construct an instance of the class.

        Args:
            *args (tuple):
                Positional arguments to pass to the constructor.

            **kwargs (dict):
                Keyword arguments to pass to the constructor.

        Returns:
            collections.OrderedDict:
            The new instance.
        """
        return OrderedDict.__new__(cls, *args, **kwargs)

class DjangoCompatUnpickler(pickle._Unpickler):
    """Unpickler compatible with changes to Django class/module paths.

    This provides compatibility across Django versions for various field types,
    updating referenced module paths for fields to a standard location so
    that the fields can be located on all Django versions.
    """

    def find_class(self, module, name):
        """Return the class for a given module and class name.

        If looking up a class from ``django.db.models.fields``, the class will
        instead be looked up from ``django.db.models``, fixing lookups on
        some Django versions.

        Args:
            module (unicode):
                The module path.

            name (unicode):
                The class name.

        Returns:
            type:
            The resulting class.

        Raises:
            AttributeError:
                The class could not be found in the module.
        """
        if module == 'django.utils.datastructures' and name == 'SortedDict':
            return SortedDict
        elif module == 'django.db.models.fields':
            module = 'django.db.models'

        return super(DjangoCompatUnpickler, self).find_class(module, name)
<commit_msg>Fix the custom unpickler on Python 2.x.<commit_after>"""Picklers for working with serialized data."""

from __future__ import unicode_literals

try:
    # Python 3.x
    from pickle import _Unpickler as Unpickler
except ImportError:
    # Python 2.x
    from pickle import Unpickler

from django_evolution.compat.datastructures import OrderedDict

class SortedDict(dict):
    """Compatibility for unpickling a SortedDict.

    Old signatures may use an old Django ``SortedDict`` structure, which does
    not exist in modern versions. This changes any construction of this
    data structure into a :py:class:`collections.OrderedDict`.
    """

    def __new__(cls, *args, **kwargs):
        """Construct an instance of the class.

        Args:
            *args (tuple):
                Positional arguments to pass to the constructor.

            **kwargs (dict):
                Keyword arguments to pass to the constructor.

        Returns:
            collections.OrderedDict:
            The new instance.
        """
        return OrderedDict.__new__(cls, *args, **kwargs)

class DjangoCompatUnpickler(Unpickler):
    """Unpickler compatible with changes to Django class/module paths.

    This provides compatibility across Django versions for various field types,
    updating referenced module paths for fields to a standard location so
    that the fields can be located on all Django versions.
    """

    def find_class(self, module, name):
        """Return the class for a given module and class name.

        If looking up a class from ``django.db.models.fields``, the class will
        instead be looked up from ``django.db.models``, fixing lookups on
        some Django versions.

        Args:
            module (unicode):
                The module path.

            name (unicode):
                The class name.

        Returns:
            type:
            The resulting class.

        Raises:
            AttributeError:
                The class could not be found in the module.
        """
        if module == 'django.utils.datastructures' and name == 'SortedDict':
            return SortedDict
        elif module == 'django.db.models.fields':
            module = 'django.db.models'

        return Unpickler.find_class(self, module, name)
<|endoftext|>


<commit_before># vim: set sw=2 ts=2 softtabstop=2 expandtab:
from . RunnerBase import RunnerBaseClass
from .. ResultType import ResultType
import logging
import os
import psutil
import re
import sys
import yaml

_logger = logging.getLogger(__name__)

class GPUVerifyRunnerException(Exception):
  def __init__(self, msg):
    self.msg = msg

class GPUVerifyRunner(RunnerBaseClass):
  softTimeoutDiff = 5

  def __init__(self, boogieProgram, workingDirectory, rc):
    _logger.debug('Initialising {}'.format(boogieProgram))
    super(GPUVerifyRunner, self).__init__(boogieProgram, workingDirectory, rc)

    # Sanity checks
    # TODO

    if self.maxTimeInSeconds > 0 and (
       self.maxTimeInSeconds <= self.softTimeoutDiff):
      raise GPUVerifyRunnerException('Need larger timeout')

    if not self.toolPath.endswith('.py'):
      raise GPUVerifyRunnerException(
        'toolPath needs to be the GPUVerify python script')

  @property
  def name(self):
    return "gpuverify"

  @property
  def timeoutWasHit(self):
    if self.hitHardTimeout:
      return True
    else:
      if self.exitCode == 7:
        return True
      else:
        return False

  def getResults(self):
    results = super(GPUVerifyRunner, self).getResults()
    if not self.hitHardTimeout:
      results['exit_code'] = self.exitCode
    return results

  @property
  def failed(self):
    if self.hitHardTimeout:
      return False

    if self.exitCode != 0 or self.exitCode != 6:
      return True

    return self._raisedException()

  def _raisedException(self):
    # HACK: Look for uncaught exceptions in log output.
    if os.path.exists(self.logFile):
      with open(self.logFile, 'r') as f:
        r = re.compile(r'FATAL UNHANDLED EXCEPTION')
        for line in f:
          m = r.search(line)
          if m != None:
            _logger.error('GPUVerify raised an exception')
            return True

    return False

  @property
  def foundBug(self):
    if self.hitHardTimeout:
      return False

    # First try read the tool output and extract if we found a bug
    verifiedCount=0
    errorCount=0
    if os.path.exists(self.logFile):
      with open(self.logFile, 'r') as f:
        r = re.compile(r'GPUVerify kernel analyser finished with (\d+) verified, (\d+) error')
        for line in f:
          m = r.match(line)
          if m != None:
            verifiedCount = int(m.group(1))
            errorCount = int(m.group(2))
        _logger.info('Found {} verified, {} errors'.format(verifiedCount, errorCount))

      if errorCount > 0:
        return True
      elif verifiedCount > 0:
        return False

      # We couldn't parse out the information we wanted so fallback on the exit code
      _logging.warning('Failed to parse info from GPUVerify output, falling back on exit code')

      # GPUVerify exit codes are taken from
      # GPUVerifyScript/error_codes.py
      #
      #   SUCCESS = 0
      #   ...
      #   GPUVERIFYVCGEN_ERROR = 5
      #   BOOGIE_ERROR = 6
      #   TIMEOUT = 7
    if self.exitCode == 0 or self.exitCode == 7:
      return False
    elif self.exitCode == 6:
      # Workaround design flaw in GPUVerify. This exit code
      # can also be emitted if GPUVerify hits an exception
      if self._raisedException():
        return None
      else:
        return True # bug report should been emitted.
    else:
      return None

  def run(self):
    self.hitHardTimeout = False

    # Run using python interpreter
    cmdLine = [ sys.executable, self.toolPath ]

    # Set a soft timeout
    softTimeout = self.maxTimeInSeconds - self.softTimeoutDiff
    cmdLine.append('--timeout={}'.format(softTimeout))

    # Note we ignore self.entryPoint

    # GPUVerify needs PATH environment variable set
    env = {}
    path = os.getenv('PATH')
    if path == None:
      path = ""

    env['PATH'] = path

    # THIS IS A HACK
    # GPUVerify needs the local/group size to be passed
    # We're passing an already processed bpl file
    # so that information is already part of the Boogie
    # program
    # rather than trying to work out what was passed
    # just pass arbitary global and local size and hope
    # this doesn't break anything
    cmdLine.append('--local_size=2')
    cmdLine.append('--num_groups=2')

    cmdLine.extend(self.additionalArgs)

    # Add the boogie source file as last arg
    cmdLine.append(self.programPathArgument)

    # We assume that Boogie has no default timeout
    # so we force the timeout within python
    self.exitCode = None
    try:
      self.exitCode = self.runTool(cmdLine,
        isDotNet=False,
        envExtra=env)
    except psutil.TimeoutExpired as e:
      self.hitHardTimeout = True
      _logger.warning('GPUVerify hit hard timeout')

def get():
  return GPUVerifyRunner
<commit_msg>Fix logic bug in GPUVerifyRunner.failed<commit_after># vim: set sw=2 ts=2 softtabstop=2 expandtab:
from . RunnerBase import RunnerBaseClass
from .. ResultType import ResultType
import logging
import os
import psutil
import re
import sys
import yaml

_logger = logging.getLogger(__name__)

class GPUVerifyRunnerException(Exception):
  def __init__(self, msg):
    self.msg = msg

class GPUVerifyRunner(RunnerBaseClass):
  softTimeoutDiff = 5

  def __init__(self, boogieProgram, workingDirectory, rc):
    _logger.debug('Initialising {}'.format(boogieProgram))
    super(GPUVerifyRunner, self).__init__(boogieProgram, workingDirectory, rc)

    # Sanity checks
    # TODO

    if self.maxTimeInSeconds > 0 and (
       self.maxTimeInSeconds <= self.softTimeoutDiff):
      raise GPUVerifyRunnerException('Need larger timeout')

    if not self.toolPath.endswith('.py'):
      raise GPUVerifyRunnerException(
        'toolPath needs to be the GPUVerify python script')

  @property
  def name(self):
    return "gpuverify"

  @property
  def timeoutWasHit(self):
    if self.hitHardTimeout:
      return True
    else:
      if self.exitCode == 7:
        return True
      else:
        return False

  def getResults(self):
    results = super(GPUVerifyRunner, self).getResults()
    if not self.hitHardTimeout:
      results['exit_code'] = self.exitCode
    return results

  @property
  def failed(self):
    if self.hitHardTimeout:
      return False

    if self.exitCode != 0 and self.exitCode != 6:
      return True

    return self._raisedException()

  def _raisedException(self):
    # HACK: Look for uncaught exceptions in log output.
    if os.path.exists(self.logFile):
      with open(self.logFile, 'r') as f:
        r = re.compile(r'FATAL UNHANDLED EXCEPTION')
        for line in f:
          m = r.search(line)
          if m != None:
            _logger.error('GPUVerify raised an exception')
            return True

    return False

  @property
  def foundBug(self):
    if self.hitHardTimeout:
      return False

    # First try read the tool output and extract if we found a bug
    verifiedCount=0
    errorCount=0
    if os.path.exists(self.logFile):
      with open(self.logFile, 'r') as f:
        r = re.compile(r'GPUVerify kernel analyser finished with (\d+) verified, (\d+) error')
        for line in f:
          m = r.match(line)
          if m != None:
            verifiedCount = int(m.group(1))
            errorCount = int(m.group(2))
        _logger.info('Found {} verified, {} errors'.format(verifiedCount, errorCount))

      if errorCount > 0:
        return True
      elif verifiedCount > 0:
        return False

      # We couldn't parse out the information we wanted so fallback on the exit code
      _logging.warning('Failed to parse info from GPUVerify output, falling back on exit code')

      # GPUVerify exit codes are taken from
      # GPUVerifyScript/error_codes.py
      #
      #   SUCCESS = 0
      #   ...
      #   GPUVERIFYVCGEN_ERROR = 5
      #   BOOGIE_ERROR = 6
      #   TIMEOUT = 7
    if self.exitCode == 0 or self.exitCode == 7:
      return False
    elif self.exitCode == 6:
      # Workaround design flaw in GPUVerify. This exit code
      # can also be emitted if GPUVerify hits an exception
      if self._raisedException():
        return None
      else:
        return True # bug report should been emitted.
    else:
      return None

  def run(self):
    self.hitHardTimeout = False

    # Run using python interpreter
    cmdLine = [ sys.executable, self.toolPath ]

    # Set a soft timeout
    softTimeout = self.maxTimeInSeconds - self.softTimeoutDiff
    cmdLine.append('--timeout={}'.format(softTimeout))

    # Note we ignore self.entryPoint

    # GPUVerify needs PATH environment variable set
    env = {}
    path = os.getenv('PATH')
    if path == None:
      path = ""

    env['PATH'] = path

    # THIS IS A HACK
    # GPUVerify needs the local/group size to be passed
    # We're passing an already processed bpl file
    # so that information is already part of the Boogie
    # program
    # rather than trying to work out what was passed
    # just pass arbitary global and local size and hope
    # this doesn't break anything
    cmdLine.append('--local_size=2')
    cmdLine.append('--num_groups=2')

    cmdLine.extend(self.additionalArgs)

    # Add the boogie source file as last arg
    cmdLine.append(self.programPathArgument)

    # We assume that Boogie has no default timeout
    # so we force the timeout within python
    self.exitCode = None
    try:
      self.exitCode = self.runTool(cmdLine,
        isDotNet=False,
        envExtra=env)
    except psutil.TimeoutExpired as e:
      self.hitHardTimeout = True
      _logger.warning('GPUVerify hit hard timeout')

def get():
  return GPUVerifyRunner
<|endoftext|>


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

#.apidoc title: Objects Services (OSV)

from openerp.osv.orm import except_orm, Model, TransientModel, AbstractModel

# Deprecated, kept for backward compatibility.
# openerp.exceptions.Warning should be used instead.
except_osv = except_orm

# Deprecated, kept for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)

# Deprecated, kept for backward compatibility, in particular for audittrail.
class object_proxy(object):
    def __init__(self):
        import openerp.service.model
        # TODO monkeypatch openerp.service.model to call the new object_service instance methods.

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[REF] object_proxy is no longer used by audittrail (which patches directly openerp.service.model).<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

#.apidoc title: Objects Services (OSV)

from openerp.osv.orm import except_orm, Model, TransientModel, AbstractModel

# Deprecated, kept for backward compatibility.
# openerp.exceptions.Warning should be used instead.
except_osv = except_orm

# Deprecated, kept for backward compatibility.
osv = Model
osv_memory = TransientModel
osv_abstract = AbstractModel # ;-)

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before>"""
JSONField automatically serializes most Python terms to JSON data.
Creates a TEXT field with a default value of "{}".  See test_json.py for
more information.

 from django.db import models
 from django_extensions.db.fields import json

 class LOL(models.Model):
     extra = json.JSONField()
"""

import six
from decimal import Decimal
from django.db import models
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder

try:
    # Django <= 1.6 backwards compatibility
    from django.utils import simplejson as json
except ImportError:
    # Django >= 1.7
    import json

def dumps(value):
    return DjangoJSONEncoder().encode(value)

def loads(txt):
    value = json.loads(
        txt,
        parse_float=Decimal,
        encoding=settings.DEFAULT_CHARSET
    )
    return value

class JSONDict(dict):
    """
    Hack so repr() called by dumpdata will output JSON instead of
    Python formatted data.  This way fixtures will work!
    """
    def __repr__(self):
        return dumps(self)

class JSONList(list):
    """
    As above
    """
    def __repr__(self):
        return dumps(self)

class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)):
    """JSONField is a generic textfield that neatly serializes/unserializes
    JSON objects seamlessly.  Main thingy must be a dict object."""

    def __init__(self, *args, **kwargs):
        default = kwargs.get('default', None)
        if default is None:
            kwargs['default'] = '{}'
        elif isinstance(default, (list, dict)):
            kwargs['default'] = dumps(default)
        models.TextField.__init__(self, *args, **kwargs)

    def to_python(self, value):
        """Convert our string value to JSON after we load it from the DB"""
        if value is None or value == '':
            return {}
        elif isinstance(value, six.string_types):
            res = loads(value)
            if isinstance(res, dict):
                return JSONDict(**res)
            else:
                return JSONList(res)

        else:
            return value

    def get_db_prep_save(self, value, connection):
        """Convert our JSON object to a string before we save"""
        if not isinstance(value, (list, dict)):
            return super(JSONField, self).get_db_prep_save("", connection=connection)
        else:
            return super(JSONField, self).get_db_prep_save(dumps(value),
                                                           connection=connection)

    def south_field_triple(self):
        "Returns a suitable description of this field for South."
        # We'll just introspect the _actual_ field.
        from south.modelsinspector import introspector
        field_class = "django.db.models.fields.TextField"
        args, kwargs = introspector(self)
        # That's our definition!
        return (field_class, args, kwargs)
<commit_msg>Fix `import json` for Python 2.6/2.7, though this bug only shows on Django 1.7 which only supports Python 2.7.<commit_after>"""
JSONField automatically serializes most Python terms to JSON data.
Creates a TEXT field with a default value of "{}".  See test_json.py for
more information.

 from django.db import models
 from django_extensions.db.fields import json

 class LOL(models.Model):
     extra = json.JSONField()
"""
from __future__ import absolute_import
import six
from decimal import Decimal
from django.db import models
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder

try:
    # Django <= 1.6 backwards compatibility
    from django.utils import simplejson as json
except ImportError:
    # Django >= 1.7
    import json

def dumps(value):
    return DjangoJSONEncoder().encode(value)

def loads(txt):
    value = json.loads(
        txt,
        parse_float=Decimal,
        encoding=settings.DEFAULT_CHARSET
    )
    return value

class JSONDict(dict):
    """
    Hack so repr() called by dumpdata will output JSON instead of
    Python formatted data.  This way fixtures will work!
    """
    def __repr__(self):
        return dumps(self)

class JSONList(list):
    """
    As above
    """
    def __repr__(self):
        return dumps(self)

class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)):
    """JSONField is a generic textfield that neatly serializes/unserializes
    JSON objects seamlessly.  Main thingy must be a dict object."""

    def __init__(self, *args, **kwargs):
        default = kwargs.get('default', None)
        if default is None:
            kwargs['default'] = '{}'
        elif isinstance(default, (list, dict)):
            kwargs['default'] = dumps(default)
        models.TextField.__init__(self, *args, **kwargs)

    def to_python(self, value):
        """Convert our string value to JSON after we load it from the DB"""
        if value is None or value == '':
            return {}
        elif isinstance(value, six.string_types):
            res = loads(value)
            if isinstance(res, dict):
                return JSONDict(**res)
            else:
                return JSONList(res)

        else:
            return value

    def get_db_prep_save(self, value, connection):
        """Convert our JSON object to a string before we save"""
        if not isinstance(value, (list, dict)):
            return super(JSONField, self).get_db_prep_save("", connection=connection)
        else:
            return super(JSONField, self).get_db_prep_save(dumps(value),
                                                           connection=connection)

    def south_field_triple(self):
        "Returns a suitable description of this field for South."
        # We'll just introspect the _actual_ field.
        from south.modelsinspector import introspector
        field_class = "django.db.models.fields.TextField"
        args, kwargs = introspector(self)
        # That's our definition!
        return (field_class, args, kwargs)
<|endoftext|>


<commit_before>import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections
from matplotlib import transforms
from matplotlib import ticker

__all__ = ['hinton']

# TOOD: Add yutils.mpl._coll to mpltools and use that for square collection.
class SquareCollection(collections.RegularPolyCollection):
    """Return a collection of squares."""

    def __init__(self, **kwargs):
        super(SquareCollection, self).__init__(4, rotation=np.pi/4., **kwargs)

    def get_transform(self):
        """Return transform scaling circle areas to data space."""
        ax = self.axes
        pts2pixels = 72.0 / ax.figure.dpi
        scale_x = pts2pixels * ax.bbox.width / ax.viewLim.width
        scale_y = pts2pixels * ax.bbox.height / ax.viewLim.height
        return transforms.Affine2D().scale(scale_x, scale_y)

def hinton(inarray, max_value=None):
    """Plot Hinton diagram for visualizing the values of a 2D array.

    Plot representation of an array with positive and negative values
    represented by white and black squares, respectively. The size of each
    square represents the magnitude of each value.

    Unlike the hinton demo in the matplotlib gallery [1]_, this implementation
    uses a RegularPolyCollection to draw squares, which is much more efficient
    than drawing individual Rectangles.

    .. note::
        This function inverts the y-axis to match the origin for arrays.

    .. [1] http://matplotlib.sourceforge.net/examples/api/hinton_demo.html

    Parameters
    ----------
    inarray : array
        Array to plot.
    max_value : float
        Any *absolute* value larger than `max_value` will be represented by a
        unit square.
    """
    ax = plt.gca()
    ax.set_axis_bgcolor('gray')
    # make sure we're working with a numpy array, not a numpy matrix
    inarray = np.asarray(inarray)
    height, width = inarray.shape
    if max_value is None:
        max_value = 2**np.ceil(np.log(np.max(np.abs(inarray)))/np.log(2))
    values = np.clip(inarray/max_value, -1, 1)
    rows, cols = np.mgrid[:height, :width]

    pos = np.where(values > 0)
    neg = np.where(values < 0)
    for idx, color in zip([pos, neg], ['white', 'black']):
        if len(idx[0]) > 0:
            xy = zip(cols[idx], rows[idx])
            circle_areas = np.pi / 2 * np.abs(values[idx])
            squares = SquareCollection(sizes=circle_areas,
                                       offsets=xy, transOffset=ax.transData,
                                       facecolor=color, edgecolor=color)
            ax.add_collection(squares, autolim=True)

    ax.axis('scaled')
    # set data limits instead of using xlim, ylim.
    ax.set_xlim(-0.5, width-0.5)
    ax.set_ylim(height-0.5, -0.5)

    ax.xaxis.set_major_locator(IndexLocator())
    ax.yaxis.set_major_locator(IndexLocator())

class IndexLocator(ticker.Locator):

    def __init__(self, max_ticks=10):
        self.max_ticks = max_ticks

    def __call__(self):
        """Return the locations of the ticks."""
        dmin, dmax = self.axis.get_data_interval()
        if dmax < self.max_ticks:
            step = 1
        else:
            step = np.ceil(dmax / self.max_ticks)
        return self.raise_if_exceeds(np.arange(0, dmax, step))

<commit_msg>Add parameter to set Hinton ticklabels<commit_after>import numpy as np
import matplotlib.pyplot as plt
from matplotlib import collections
from matplotlib import transforms
from matplotlib import ticker

# TOOD: Add yutils.mpl._coll to mpltools and use that for square collection.
class SquareCollection(collections.RegularPolyCollection):
    """Return a collection of squares."""

    def __init__(self, **kwargs):
        super(SquareCollection, self).__init__(4, rotation=np.pi/4., **kwargs)

    def get_transform(self):
        """Return transform scaling circle areas to data space."""
        ax = self.axes
        pts2pixels = 72.0 / ax.figure.dpi
        scale_x = pts2pixels * ax.bbox.width / ax.viewLim.width
        scale_y = pts2pixels * ax.bbox.height / ax.viewLim.height
        return transforms.Affine2D().scale(scale_x, scale_y)

def hinton(inarray, max_value=None, ticklabels=None):
    """Plot Hinton diagram for visualizing the values of a 2D array.

    Plot representation of an array with positive and negative values
    represented by white and black squares, respectively. The size of each
    square represents the magnitude of each value.

    Unlike the hinton demo in the matplotlib gallery [1]_, this implementation
    uses a RegularPolyCollection to draw squares, which is much more efficient
    than drawing individual Rectangles.

    .. note::
        This function inverts the y-axis to match the origin for arrays.

    .. [1] http://matplotlib.sourceforge.net/examples/api/hinton_demo.html

    Parameters
    ----------
    inarray : array
        Array to plot.
    max_value : float
        Any *absolute* value larger than `max_value` will be represented by a
        unit square.
    """

    ax = plt.gca()
    ax.set_axis_bgcolor('gray')
    # make sure we're working with a numpy array, not a numpy matrix
    inarray = np.asarray(inarray)
    height, width = inarray.shape
    if max_value is None:
        max_value = 2**np.ceil(np.log(np.max(np.abs(inarray)))/np.log(2))
    values = np.clip(inarray/max_value, -1, 1)
    rows, cols = np.mgrid[:height, :width]

    pos = np.where(values > 0)
    neg = np.where(values < 0)
    for idx, color in zip([pos, neg], ['white', 'black']):
        if len(idx[0]) > 0:
            xy = zip(cols[idx], rows[idx])
            circle_areas = np.pi / 2 * np.abs(values[idx])
            squares = SquareCollection(sizes=circle_areas,
                                       offsets=xy, transOffset=ax.transData,
                                       facecolor=color, edgecolor=color)
            ax.add_collection(squares, autolim=True)

    ax.axis('scaled')
    # set data limits instead of using xlim, ylim.
    ax.set_xlim(-0.5, width-0.5)
    ax.set_ylim(height-0.5, -0.5)

    if ticklabels is None:
        ax.xaxis.set_major_locator(IndexLocator())
        ax.yaxis.set_major_locator(IndexLocator())
    else:
        ax.set_yticks(np.arange(len(ticklabels)))
        ax.set_xticks(np.arange(len(ticklabels)))

        ax.set_yticklabels(ticklabels)
        ax.set_xticklabels(ticklabels, rotation=90)

class IndexLocator(ticker.Locator):

    def __init__(self, max_ticks=10):
        self.max_ticks = max_ticks

    def __call__(self):
        """Return the locations of the ticks."""
        dmin, dmax = self.axis.get_data_interval()
        if dmax < self.max_ticks:
            step = 1
        else:
            step = np.ceil(dmax / self.max_ticks)
        return self.raise_if_exceeds(np.arange(0, dmax, step))<|endoftext|>


<commit_before>from django.db import models
from time import time
from datetime import date
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
import urlparse

from urlparse import urlparse, parse_qs

from django.template import Template, Context
from django.conf import settings

# This doesn't belong here
def get_upload_file_name(instance, filename):
    return "uploaded_files/%s_%s" % (str(time()).replace('.', '_'), filename)

class Podcast(models.Model):
    rss_url = models.URLField(blank=True)
    title = models.CharField(max_length=200, blank=True)
    description = models.TextField(blank=True)
    image = models.FileField(upload_to=get_upload_file_name, blank=True)
    homepage = models.URLField(blank=True)
    donate_url = models.URLField(blank=True)
    twitter_url = models.URLField(blank=True)
    facebook_url = models.URLField(blank=True)
    instagram_url = models.URLField(blank=True)
    google_plus_url = models.URLField(blank=True)
    youtube_url = models.URLField(blank=True)

    def get_absolute_url(self):
        return reverse('podcast_detail', kwargs={'pk': self.pk})

    def all_podcasts(self):
       return Podcast.objects.all()

    def all_podcast_quotes(self):
       return Quote.objects.filter(episode__podcast=self)

    def __unicode__(self):
        return unicode(self.title)

class Episode(models.Model):
    podcast = models.ForeignKey(Podcast)
    title = models.CharField(max_length=200)
    publication_date = models.DateField(null=True, blank=True)
    description = models.TextField(blank=True)
    episode_url = models.URLField(blank=True)
    donate_url = models.URLField(blank=True)
    image = models.FileField(upload_to=get_upload_file_name, blank=True)
    video_url = models.URLField(blank=True)
    audio_url = models.URLField(blank=True)
    # guests = ...
    # duration = what type of field for length of episode data? needs to match up with format for quote.time_quote_begins and quote.time_quote_ends
    # keywords = ...

    def video_id(self):
        """
        Examples:
        - http://youtu.be/SA2iWivDJiE
        - http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
        - http://www.youtube.com/embed/SA2iWivDJiE
        - http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
        """
        query = urlparse(self.video_url)
        if query.hostname == 'youtu.be':
            return query.path[1:]
        if query.hostname in ('www.youtube.com', 'youtube.com'):
            if query.path == '/watch':
                p = parse_qs(query.query)
                return p['v'][0]
            if query.path[:7] == '/embed/':
                return query.path.split('/')[2]
            if query.path[:3] == '/v/':
                return query.path.split('/')[2]
        return None

    def parse(kwargs):
        url = kwargs.get('url')
        if not url:
            return "[Add video url]"

        id = video_id(url)

        if id is None:
            return "[Bad url]"

        width = int(kwargs.get('width', getattr(settings, 'SHORTCODES_YOUTUBE_WIDTH', 425)))
        height = int(kwargs.get('height', getattr(settings, 'SHORTCODES_YOUTUBE_HEIGHT', 0)))

        if height == 0:
            height = int(round(width / 425.0 * 344.0))

        # many thanks to Amit Agarwal aka @labnol for this snazzy YouTube parser, video_id, parse
        # https://gist.github.com/trojkat/1989762
        # https://labnol.googlecode.com/files/youtube.js

    def all_episodes(self):
       return Episode.objects.filter(podcast__id=self.podcast.id)

    def all_episode_quotes(self):
       return Quote.objects.filter(episode__id=self.id)

    def get_absolute_url(self):
        return reverse('episode_detail', kwargs={'pk': self.pk})

    def __unicode__(self):
        return u'%s - %s' % (self.podcast.title, self.title)

class Quote(models.Model):
    episode = models.ForeignKey(Episode)
    summary = models.CharField(max_length=200)
    text = models.TextField(blank=True)
    submitted_by = models.ForeignKey(User)
    submitted_time = models.DateTimeField(auto_now_add=True)
    time_quote_begins = models.IntegerField(blank=True)
    time_quote_ends = models.IntegerField(blank=True)

    def vote_score(self):
        return Vote.objects.filter(quote__id=self.id).filter(vote_type=1).count() - Vote.objects.filter(quote__id=self.id).filter(vote_type=-1).count()

    def converted_time_begins(self):
        m, s = divmod(self.time_quote_begins, 60)
        h, m = divmod(m, 60)
        print "%d:%02d:%02d" % (h, m, s)
        return "%d:%02d:%02d" % (h, m, s)

    def converted_time_ends(self):
        m, s = divmod(self.time_quote_ends, 60)
        h, m = divmod(m, 60)
        print "%d:%02d:%02d" % (h, m, s)
        return "%d:%02d:%02d" % (h, m, s)

    def get_absolute_url(self):
        return reverse('home')

    def __unicode__(self):
        return u'%s - %s' % (self.episode.podcast.title, self.episode.title)

class Vote(models.Model):
    voter = models.ForeignKey(User)
    quote = models.ForeignKey(Quote)
    UPVOTE = 1
    DOWNVOTE = -1
    VOTE_CHOICES = (
        (UPVOTE, 'Upvote'),
        (DOWNVOTE, 'Downvote'),
    )
    vote_type = models.IntegerField(choices=VOTE_CHOICES)

    class Meta:
        unique_together = (('voter', 'quote'),)

    @classmethod
    def create(cls, voter, quote, vote_type):
        vote = cls(voter=voter, quote=quote, vote_type=vote_type)
        return vote

    def __unicode__(self):
        return "Vote by: " + str(self.voter)
        <commit_msg>Add NOVOTE = 0 to Vote.vote_type<commit_after>from django.db import models
from time import time
from datetime import date
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
import urlparse

from urlparse import urlparse, parse_qs

from django.template import Template, Context
from django.conf import settings

# This doesn't belong here
def get_upload_file_name(instance, filename):
    return "uploaded_files/%s_%s" % (str(time()).replace('.', '_'), filename)

class Podcast(models.Model):
    rss_url = models.URLField(blank=True)
    title = models.CharField(max_length=200, blank=True)
    description = models.TextField(blank=True)
    image = models.FileField(upload_to=get_upload_file_name, blank=True)
    homepage = models.URLField(blank=True)
    donate_url = models.URLField(blank=True)
    twitter_url = models.URLField(blank=True)
    facebook_url = models.URLField(blank=True)
    instagram_url = models.URLField(blank=True)
    google_plus_url = models.URLField(blank=True)
    youtube_url = models.URLField(blank=True)

    def get_absolute_url(self):
        return reverse('podcast_detail', kwargs={'pk': self.pk})

    def all_podcasts(self):
       return Podcast.objects.all()

    def all_podcast_quotes(self):
       return Quote.objects.filter(episode__podcast=self)

    def __unicode__(self):
        return unicode(self.title)

class Episode(models.Model):
    podcast = models.ForeignKey(Podcast)
    title = models.CharField(max_length=200)
    publication_date = models.DateField(null=True, blank=True)
    description = models.TextField(blank=True)
    episode_url = models.URLField(blank=True)
    donate_url = models.URLField(blank=True)
    image = models.FileField(upload_to=get_upload_file_name, blank=True)
    video_url = models.URLField(blank=True)
    audio_url = models.URLField(blank=True)
    # guests = ...
    # duration = what type of field for length of episode data? needs to match up with format for quote.time_quote_begins and quote.time_quote_ends
    # keywords = ...

    def video_id(self):
        """
        Examples:
        - http://youtu.be/SA2iWivDJiE
        - http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
        - http://www.youtube.com/embed/SA2iWivDJiE
        - http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
        """
        query = urlparse(self.video_url)
        if query.hostname == 'youtu.be':
            return query.path[1:]
        if query.hostname in ('www.youtube.com', 'youtube.com'):
            if query.path == '/watch':
                p = parse_qs(query.query)
                return p['v'][0]
            if query.path[:7] == '/embed/':
                return query.path.split('/')[2]
            if query.path[:3] == '/v/':
                return query.path.split('/')[2]
        return None

    def parse(kwargs):
        url = kwargs.get('url')
        if not url:
            return "[Add video url]"

        id = video_id(url)

        if id is None:
            return "[Bad url]"

        width = int(kwargs.get('width', getattr(settings, 'SHORTCODES_YOUTUBE_WIDTH', 425)))
        height = int(kwargs.get('height', getattr(settings, 'SHORTCODES_YOUTUBE_HEIGHT', 0)))

        if height == 0:
            height = int(round(width / 425.0 * 344.0))

        # many thanks to Amit Agarwal aka @labnol for this snazzy YouTube parser, video_id, parse
        # https://gist.github.com/trojkat/1989762
        # https://labnol.googlecode.com/files/youtube.js

    def all_episodes(self):
       return Episode.objects.filter(podcast__id=self.podcast.id)

    def all_episode_quotes(self):
       return Quote.objects.filter(episode__id=self.id)

    def get_absolute_url(self):
        return reverse('episode_detail', kwargs={'pk': self.pk})

    def __unicode__(self):
        return u'%s - %s' % (self.podcast.title, self.title)

class Quote(models.Model):
    episode = models.ForeignKey(Episode)
    summary = models.CharField(max_length=200)
    text = models.TextField(blank=True)
    submitted_by = models.ForeignKey(User)
    submitted_time = models.DateTimeField(auto_now_add=True)
    time_quote_begins = models.IntegerField(blank=True)
    time_quote_ends = models.IntegerField(blank=True)

    def vote_score(self):
        return Vote.objects.filter(quote__id=self.id).filter(vote_type=1).count() - Vote.objects.filter(quote__id=self.id).filter(vote_type=-1).count()

    def converted_time_begins(self):
        m, s = divmod(self.time_quote_begins, 60)
        h, m = divmod(m, 60)
        print "%d:%02d:%02d" % (h, m, s)
        return "%d:%02d:%02d" % (h, m, s)

    def converted_time_ends(self):
        m, s = divmod(self.time_quote_ends, 60)
        h, m = divmod(m, 60)
        print "%d:%02d:%02d" % (h, m, s)
        return "%d:%02d:%02d" % (h, m, s)

    def get_absolute_url(self):
        return reverse('home')

    def __unicode__(self):
        return u'%s - %s' % (self.episode.podcast.title, self.episode.title)

class Vote(models.Model):
    voter = models.ForeignKey(User)
    quote = models.ForeignKey(Quote)
    UPVOTE = 1
    NOVOTE = 0
    DOWNVOTE = -1
    VOTE_CHOICES = (
        (UPVOTE, 'Upvote'),
        (NOVOTE, 'Novote'),
        (DOWNVOTE, 'Downvote'),
    )
    vote_type = models.IntegerField(choices=VOTE_CHOICES)

    class Meta:
        unique_together = (('voter', 'quote'),)

    @classmethod
    def create(cls, voter, quote, vote_type):
        vote = cls(voter=voter, quote=quote, vote_type=vote_type)
        return vote

    def __unicode__(self):
        return "Vote by: " + str(self.voter)
        <|endoftext|>


<commit_before>import sublime
import json
import os.path
from sublime_plugin import TextCommand
from sublime_plugin import EventListener

# shared by the entire plugins.
settings = None
config = None

def plugin_loaded():
    # update settings.
    _update_settings()

    # update config.
    _update_config()

    # add settings modified listener.
    settings.add_on_change('reload', _update_settings)

def _update_config():
    def _load_config():
        def _parse_json(config_file):
            # parse json from config file.
            opened_file = open(config_file, 'r', encoding="utf8")
            return json.loads(opened_file.read(), strict=False)

        path = sublime.packages_path().replace('Packages', '')

        if(sublime.platform() == 'windows'):
            # for windows.
            config_files = (path + '\Local\Auto Save Session.sublime_session',
                            path + '\Local\Session.sublime_session')
        else:
            # for mac/linux.
            config_files = (path + '/Local/Auto Save Session.sublime_session',
                            path + '/Local/Session.sublime_session')

        # preferentially set automatic writing file.
        if(os.path.isfile(config_files[0])):
            config_file = config_files[0]
        else:
            config_file = config_files[1]

        return _parse_json(config_file)

    # use global definition.
    global config

    if(config is None):
        config = _load_config()

    TabStatusStore.set_show_tab_status(get_tab_visibility_option())

def _update_settings():
    # use global definition.
    global settings

    # load settings value from setting file.
    settings = sublime.load_settings('sidebar_separator.sublime-settings')

def get_separate_value():
    # use global definition.
    global settings

    # get separate value and create separater.
    value = settings.get('separate_value', '-')
    count = settings.get('separate_count', '100')

    return value * count

def get_auto_hide_option():
    # use global definition.
    global settings

    # get auto_tab_hide option and return the flag.
    auto_hide_flag = settings.get('auto_tab_hide', True)

    return auto_hide_flag

def get_tab_visibility_option():
    # use global definition.
    global config

    return config['windows'][0]['show_tabs']

class TabControlListener(EventListener):

    def on_window_command(self, window, command, option):
        def _new_window():
            TabStatusStore.set_active_window_status()

        def _toggle_tabs(command, option):
            if(option == 'sidebar_separator' and get_auto_hide_option(
            ) and TabStatusStore.get_show_tab_status()):
                # set tab hide flag.
                TabStatusStore.set_show_tab_status(False)
                return True
            elif(not get_auto_hide_option()):
                TabStatusStore.toggle_show_tab_status()
                return True
            elif(get_auto_hide_option()):
                return False
            else:
                return False

        if(command == 'toggle_tabs'):
            if (not _toggle_tabs(command, option)):
                return ('None')
        elif(command == 'new_window'):
            _new_window()

class TabStatusStore():

    # show_tabs parameter from Session.sublime_session.
    _show_tab_status = {}

    # just before active window status.
    _active_window_status = None

    @classmethod
    def set_active_window_status(store):
        store._active_window_status = TabStatusStore.get_show_tab_status()

    @classmethod
    def get_active_window_status(store):
        return store._active_window_status

    @classmethod
    def get_show_tab_status(store):
        # get active window_id
        window_id = sublime.active_window().id()

        if(not window_id in store._show_tab_status):
            # set just before active window id.
            store._show_tab_status[window_id] = store._active_window_status

        return store._show_tab_status[window_id]

    @classmethod
    def set_show_tab_status(store, status):
        # get active window_id
        window_id = sublime.active_window().id()

        # set show_tab_status.
        store._show_tab_status[window_id] = status

    @classmethod
    def toggle_show_tab_status(store):
        # get active window_id
        window_id = sublime.active_window().id()

        store._show_tab_status[
            window_id] = not store.get_show_tab_status()

class SidebarSeparator(TextCommand):

    def run(self, edit):
        # create separate file.
        self.create_separater()

        # auto tab hide.
        self.hide_tab_bar()

    def create_separater(self):
         # create separate file.
        separate_file = sublime.active_window().new_file()

        # set buffer name.
        separate_file.set_name(get_separate_value())

        # set not save as separate file propertie.
        separate_file.set_scratch(True)

        # set read only propertie.
        separate_file.set_read_only(True)

    def hide_tab_bar(self):
        # controlling the tabs when the flag is true.
        if(get_auto_hide_option() and TabStatusStore.get_show_tab_status()):

            active_window = sublime.active_window()
            active_window.run_command('toggle_tabs', 'sidebar_separator')
<commit_msg>when user's setting file is not exist , crush the plugin.<commit_after>import sublime
import json
import os.path
from sublime_plugin import TextCommand
from sublime_plugin import EventListener

# shared by the entire plugins.
settings = None
config = None

def plugin_loaded():
    # use global definition.
    global settings

    # update settings.
    _update_settings()

    # update config.
    _update_config()

    # add settings modified listener.
    settings.add_on_change('reload', _update_settings)

def _update_config():
    def _load_config():
        def _parse_json(config_file):
            # parse json from config file.
            opened_file = open(config_file, 'r', encoding="utf8")
            return json.loads(opened_file.read(), strict=False)

        path = sublime.packages_path().replace('Packages', '')

        if(sublime.platform() == 'windows'):
            # for windows.
            config_files = (path + '\Local\Auto Save Session.sublime_session',
                            path + '\Local\Session.sublime_session')
        else:
            # for mac/linux.
            config_files = (path + '/Local/Auto Save Session.sublime_session',
                            path + '/Local/Session.sublime_session')

        # preferentially set automatic writing file.
        if(os.path.isfile(config_files[0])):
            config_file = config_files[0]
        else:
            config_file = config_files[1]

        return _parse_json(config_file)

    # use global definition.
    global config

    if(config is None):
        config = _load_config()

    TabStatusStore.set_show_tab_status(get_tab_visibility_option())

def _update_settings():
    # use global definition.
    global settings

    # load settings value from setting file.
    settings = sublime.load_settings('sidebar_separator.sublime-settings')

def get_separate_value():
    # use global definition.
    global settings

    # get separate value and create separater.
    value = settings.get('separate_value', '-')
    count = settings.get('separate_count', 100)

    return value * count

def get_auto_hide_option():
    # use global definition.
    global settings

    # get auto_tab_hide option and return the flag.
    auto_hide_flag = settings.get('auto_tab_hide', True)

    return auto_hide_flag

def get_tab_visibility_option():
    # use global definition.
    global config

    return config['windows'][0]['show_tabs']

class TabControlListener(EventListener):

    def on_window_command(self, window, command, option):
        def _new_window():
            TabStatusStore.set_active_window_status()

        def _toggle_tabs(command, option):
            if(option == 'sidebar_separator' and get_auto_hide_option(
            ) and TabStatusStore.get_show_tab_status()):
                # set tab hide flag.
                TabStatusStore.set_show_tab_status(False)
                return True
            elif(not get_auto_hide_option()):
                TabStatusStore.toggle_show_tab_status()
                return True
            elif(get_auto_hide_option()):
                return False
            else:
                return False

        if(command == 'toggle_tabs'):
            if (not _toggle_tabs(command, option)):
                return ('None')
        elif(command == 'new_window'):
            _new_window()

class TabStatusStore():

    # show_tabs parameter from Session.sublime_session.
    _show_tab_status = {}

    # just before active window status.
    _active_window_status = None

    @classmethod
    def set_active_window_status(store):
        store._active_window_status = TabStatusStore.get_show_tab_status()

    @classmethod
    def get_active_window_status(store):
        return store._active_window_status

    @classmethod
    def get_show_tab_status(store):
        # get active window_id
        window_id = sublime.active_window().id()

        if(not window_id in store._show_tab_status):
            # set just before active window id.
            store._show_tab_status[window_id] = store._active_window_status

        return store._show_tab_status[window_id]

    @classmethod
    def set_show_tab_status(store, status):
        # get active window_id
        window_id = sublime.active_window().id()

        # set show_tab_status.
        store._show_tab_status[window_id] = status

    @classmethod
    def toggle_show_tab_status(store):
        # get active window_id
        window_id = sublime.active_window().id()

        store._show_tab_status[
            window_id] = not store.get_show_tab_status()

class SidebarSeparator(TextCommand):

    def run(self, edit):
        # create separate file.
        self.create_separater()

        # auto tab hide.
        self.hide_tab_bar()

    def create_separater(self):
         # create separate file.
        separate_file = sublime.active_window().new_file()

        # set buffer name.
        separate_file.set_name(get_separate_value())

        # set not save as separate file propertie.
        separate_file.set_scratch(True)

        # set read only propertie.
        separate_file.set_read_only(True)

    def hide_tab_bar(self):
        # controlling the tabs when the flag is true.
        if(get_auto_hide_option() and TabStatusStore.get_show_tab_status()):

            active_window = sublime.active_window()
            active_window.run_command('toggle_tabs', 'sidebar_separator')
<|endoftext|>