<commit_before>import requests
import json

class Clips:
    """Clips class

    Handles the clips endpoint of the Kippt API.
    """
    def __init__(self, kippt):
        """ Instantiates a Clips object.

        Parameters:
        kippt - KipptAPI object

        """
        self.kippt = kippt

    def all(self, **args):
        """ Return all Clips.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def feed(self, **args):
        """ Return the Clip feed.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/feed?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def favorites(self, **args):
        """ Return favorite clips.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/favorites?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def create(self, url, **args):
        """ Create a new Kippt Clip.

        Parameters:
        - url (Required)
        - args Dictionary of other fields

        Accepted fields can be found here:
            https://github.com/kippt/api-documentation/blob/master/objects/clip.md
        """
        # Merge our url as a parameter and JSONify it.
        data = json.dumps(dict({'url': url}, **args))
        r = requests.post(
            "https://kippt.com/api/clips",
            headers=self.kippt.header,
            data=data
        )
        return (r.json())

    def clip(self, id):
        """ Returns a Clip object.

        """
        return Clip(self.kippt, id)

class Clip:
    """Clip class

    Handles individual clip requests.
    """

    def __init__(self, kippt, id):
        """ Instantiates a clip object given a KipptAPI object, and a clip ID.

        """
        self.kippt = kippt
        self.id = id

    # GET Requests
    def content(self):
        """ Retrieve the Clip object.

        """
        r = requests.get(
            "https://kippt.com/api/clips/%s" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def comments(self, **args):
        """ Retrieve comments on a clip.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/%s/comments?limit=%s&offset=%s" % (self.id, limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def likes(self, **args):
        """ Retrieve likes of a clip.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/%s/likes?limit=%s&offset=%s" % (self.id, limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    # PUT & POST Requests
    def update(self, **args):
        """ Updates a Clip.

        Parameters:
        - args Dictionary of other fields

        Accepted fields can be found here:
            https://github.com/kippt/api-documentation/blob/master/objects/clip.md
        """
        # JSONify our data.
        data = json.dumps(args)
        r = requests.put(
            "https://kippt.com/api/clips/%s" % (self.id),
            headers=self.kippt.header,
            data=data)
        return (r.json())

    def like(self):
        """ Like a clip.

        """
        r = requests.post(
            "https://kippt.com/api/clips/%s/likes" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def favorite(self):
        """ Favorite a clip.

        """
        r = requests.post(
            "https://kippt.com/api/clips/%s/favorite" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def comment(self, body):
        """ Comment on a clip.

        Parameters:
        - body (Required)
        """
        # Merge our url as a parameter and JSONify it.
        data = json.dumps({'body': body})
        r = requests.post(
            "https://kippt.com/api/clips/%s/comments" (self.id),
            headers=self.kippt.header,
            data=data
        )
        return (r.json())

    # DELETE Requests
    def delete(self):
        """ Delete a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s" (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def unfavorite(self):
        """ Unfavorite a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/favorite" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def unlike(self):
        """ Unlike a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/likes" % (self.id),
            headers=self.kippt.header)
        return (r.json())

    def uncomment(self, comment_id):
        """ Remove a comment on a clip.

        Parameters:
        - comment_id ID of the comment to be removed.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/comments/%s" % (self.id, comment_id),
            headers=self.kippt.header
        )
        return (r.json())
<commit_msg>Adding search method to clips object.<commit_after>import requests
import json

class Clips:
    """Clips class

    Handles the clips endpoint of the Kippt API.
    """
    def __init__(self, kippt):
        """ Instantiates a Clips object.

        Parameters:
        kippt - KipptAPI object

        """
        self.kippt = kippt

    def all(self, **args):
        """ Return all Clips.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def feed(self, **args):
        """ Return the Clip feed.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/feed?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def favorites(self, **args):
        """ Return favorite clips.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/favorites?limit=%s&offset=%s" % (limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def create(self, url, **args):
        """ Create a new Kippt Clip.

        Parameters:
        - url (Required)
        - args Dictionary of other fields

        Accepted fields can be found here:
            https://github.com/kippt/api-documentation/blob/master/objects/clip.md
        """
        # Merge our url as a parameter and JSONify it.
        data = json.dumps(dict({'url': url}, **args))
        r = requests.post(
            "https://kippt.com/api/clips",
            headers=self.kippt.header,
            data=data
        )
        return (r.json())

    def search(self, query, **args):
        """ Search for a clip.

        Parameters:
        - query String we are searching for.
        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/search?q=%s&limit=%s&offset=%s" % (query, limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def clip(self, id):
        """ Returns a Clip object.

        """
        return Clip(self.kippt, id)

class Clip:
    """Clip class

    Handles individual clip requests.
    """

    def __init__(self, kippt, id):
        """ Instantiates a clip object given a KipptAPI object, and a clip ID.

        """
        self.kippt = kippt
        self.id = id

    # GET Requests
    def content(self):
        """ Retrieve the Clip object.

        """
        r = requests.get(
            "https://kippt.com/api/clips/%s" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def comments(self, **args):
        """ Retrieve comments on a clip.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/%s/comments?limit=%s&offset=%s" % (self.id, limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    def likes(self, **args):
        """ Retrieve likes of a clip.

        """
        limit = args['limit'] if 'limit' in args else 20
        offset = args['offset'] if 'offset' in args else 0

        r = requests.get(
            "https://kippt.com/api/clips/%s/likes?limit=%s&offset=%s" % (self.id, limit, offset),
            headers=self.kippt.header
        )
        return (r.json())

    # PUT & POST Requests
    def update(self, **args):
        """ Updates a Clip.

        Parameters:
        - args Dictionary of other fields

        Accepted fields can be found here:
            https://github.com/kippt/api-documentation/blob/master/objects/clip.md
        """
        # JSONify our data.
        data = json.dumps(args)
        r = requests.put(
            "https://kippt.com/api/clips/%s" % (self.id),
            headers=self.kippt.header,
            data=data)
        return (r.json())

    def like(self):
        """ Like a clip.

        """
        r = requests.post(
            "https://kippt.com/api/clips/%s/likes" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def favorite(self):
        """ Favorite a clip.

        """
        r = requests.post(
            "https://kippt.com/api/clips/%s/favorite" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def comment(self, body):
        """ Comment on a clip.

        Parameters:
        - body (Required)
        """
        # Merge our url as a parameter and JSONify it.
        data = json.dumps({'body': body})
        r = requests.post(
            "https://kippt.com/api/clips/%s/comments" (self.id),
            headers=self.kippt.header,
            data=data
        )
        return (r.json())

    # DELETE Requests
    def delete(self):
        """ Delete a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s" (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def unfavorite(self):
        """ Unfavorite a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/favorite" % (self.id),
            headers=self.kippt.header
        )
        return (r.json())

    def unlike(self):
        """ Unlike a clip.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/likes" % (self.id),
            headers=self.kippt.header)
        return (r.json())

    def uncomment(self, comment_id):
        """ Remove a comment on a clip.

        Parameters:
        - comment_id ID of the comment to be removed.

        """
        r = requests.delete(
            "https://kippt.com/api/clips/%s/comments/%s" % (self.id, comment_id),
            headers=self.kippt.header
        )
        return (r.json())
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-05-28 06:45
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('resources', '0067_auto_20190509_1546'),
    ]

    operations = [
        migrations.AddField(
            model_name='partner',
            name='proxy_account_length',
            field=models.BooleanField(default=False, help_text='Mark as true if the authorization method of this partner is proxy and requires the length of the account (expiry) be specified.'),
        ),
    ]
<commit_msg>rebase and fix migrations<commit_after><|endoftext|>


<commit_before>import threading
import time
import logging

logger = logging.getLogger('ti.pidsupport')

class StoppableThread(threading.Thread):
    def __init__(self):
        super(StoppableThread, self).__init__()
        self._stop = threading.Event()
        self.sleeping = False

    def run(self):
        # NOTE: subclasses MUST override this - this behaviour is
        # only for testing purposes

        # go into a restless but persistent sleep (in 60 second
        # batches)
        while not self.stopped():
            self._interruptable_sleep(60)

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

    def _interruptable_sleep(self, duration, increment=0.5):
        self.sleeping = True
        if duration <= 0:
            return
        slept = 0
        while not self.stopped() and slept < duration:
            snooze = increment if duration - slept > increment else duration - slept
            time.sleep(snooze)
            slept += snooze
        self.sleeping = False

class Retry(object):
    default_exceptions = (Exception,)
    def __init__(self, tries, exceptions=None, delay=0):
        """
        Decorator for retrying a function if exception occurs

        tries -- num tries
        exceptions -- exceptions to catch
        delay -- wait between retries
        from http://peter-hoffmann.com/2010/retry-decorator-python.html
        """
        self.tries = tries
        if exceptions is None:
            exceptions = Retry.default_exceptions
        self.exceptions =  exceptions
        self.delay = delay

    def __call__(self, f):
        def fn(*args, **kwargs):
            exception = None
            for _ in range(self.tries):
                try:
                    return f(*args, **kwargs)
                except self.exceptions, e:
                    logger.debug("Retry, exception: "+e.__repr__())
                    time.sleep(self.delay)
                    exception = e

            #if no success after tries, could raise last exception here...

            logger.debug("Tried mightily, but giving up after {tries} '{exception_type}' exceptions.".format(
                tries=self.tries,
                exception_type=e.__repr__()
            ))

            return False # fail silently...
        return fn<commit_msg>remove pidsupport<commit_after><|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from config.template_middleware import TemplateResponse
from gaecookie.decorator import no_csrf
from gaepermission.decorator import login_required
from tekton import router
from tekton.gae.middleware.redirect import RedirectResponse
from model.db import *
from tekton.gae.middleware.json_middleware import JsonUnsecureResponse
from distutils import log
from json import dumps

__author__ = 'Rodrigo'

__ctx = {'items':'','item':'','categorias':'','categoria_selecionada':'','erros':'','sucesso':-1,'safe':'','encontrado':-1,
         'path_editar':'','path_editar_form':'','path_excluir':'','path_pesquisar':'', 'path_listar':''}

#__ctx = {'items':'','categorias':'','erros':''}

__dct = {'error':''}

@login_required
@no_csrf
def index(id_categoria = None):
    if id_categoria == None or id_categoria == 'all':
        query = Item.query().order(Item.titulo)
        item_lista = query.fetch()
        if id_categoria == 'all':
            __ctx['categoria_selecionada'] = 'all'
        else:
            __ctx['categoria_selecionada'] = ''
    else:
        query = Item.query(Item.id_categoria == id_categoria).order(Item.titulo)
        item_lista = query.fetch()
        __ctx['categoria_selecionada'] = id_categoria

    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()

    if len(item_lista) > 0:
        form = ItemForm()
        item_lista = [form.fill_with_model(item) for item in item_lista] #transforma a classe em dicionário para poder adicionar valores dinamicamente
        p_editar_form = router.to_path(editar_form)
        p_excluir = router.to_path(excluir)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            #item['path_excluir'] = '%s/%s'%(p_excluir,item['id'])
            item['id_categoria'] = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if item['id_categoria'] == cat.key:
                    item['categoria'] = cat.categoria
                    item['id_categoria'] = ''
                    break
        __ctx['itens'] = item_lista
        __ctx['encontrado'] = 1
    else:
        __ctx['encontrado'] = 0
    __ctx['categorias'] = categorias
    __ctx['erros'] = ''
    __ctx['sucesso'] = -1
    __ctx['path_index'] = router.to_path(index)
    __ctx['path_salvar'] = router.to_path(salvar)
    __ctx['path_listar'] = router.to_path(listar)
    __ctx['path_excluir'] = router.to_path(excluir)
    __ctx['path_editar'] = router.to_path(editar)

    __ctx['itens'] = dumps(item_lista) #converte o item_lista para json

    return TemplateResponse(__ctx)

'''
@login_required
@no_csrf
def index(id_categoria = None, buscar = '0'):
    if id_categoria == None or id_categoria == 'all':
        query = Item.query().order(Item.titulo)
        item_lista = query.fetch()
        if id_categoria == 'all':
            __ctx['categoria_selecionada'] = 'all'
        else:
            __ctx['categoria_selecionada'] = ''
    else:
        query = Item.query(Item.id_categoria == id_categoria).order(Item.titulo)
        item_lista = query.fetch()
        __ctx['categoria_selecionada'] = id_categoria

    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()

    if len(item_lista) > 0:
        form = ItemForm()
        item_lista = [form.fill_with_model(item) for item in item_lista] #transforma a classe em dicionário para poder adicionar valores dinamicamente
        p_editar_form = router.to_path(editar_form)
        p_excluir = router.to_path(excluir)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            #item['path_excluir'] = '%s/%s'%(p_excluir,item['id'])
            item['id_categoria'] = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if item['id_categoria'] == cat.key:
                    item['categoria'] = cat.categoria
                    break
        __ctx['itens'] = item_lista
        __ctx['encontrado'] = 1
    else:
        __ctx['encontrado'] = 0
    __ctx['categorias'] = categorias
    __ctx['erros'] = ''
    __ctx['sucesso'] = -1
    __ctx['path_index'] = router.to_path(index)
    __ctx['path_salvar'] = router.to_path(salvar)

    return TemplateResponse(__ctx)
'''

@login_required
@no_csrf
def listar(_resp,id_cat_buscar = None):
    categorias = (Categoria.query().order(Categoria.categoria)).fetch()
    form = ItemForm()

    if id_cat_buscar == 'all' or id_cat_buscar == None:
        item_lista = (Item.query().order(Item.titulo)).fetch()
    else:
        item_lista = (Item.query(Item.id_categoria == id_cat_buscar).order(Item.titulo)).fetch()

    if item_lista > 0:
        item_lista = [form.fill_with_model(p) for p in item_lista]
        p_editar_form = router.to_path(editar_form)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            key_cat = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if key_cat == cat.key:
                    item['categoria'] = cat.categoria
                    break
    else:
        item_lista = {'error':'Não foi encontrado nenhum item.'}
        _resp.set_status(400)

    return JsonUnsecureResponse(item_lista)

@login_required
@no_csrf
def editar(_resp,id,**itens):
    id = int(id)
    item_bd = Item.get_by_id(id)
    item_form = ItemForm(**itens)
    erros = item_form.validate()
    if erros:
        _resp.set_status(400)
        dct = erros
    else:
        item_bd.titulo = itens['titulo']
        item_bd.id_categoria = itens['id_categoria']
        item_bd.descricao = itens['descricao']
        item_bd.put()

        dct = item_form.fill_with_model(item_bd)

    log.info(dct)
    return JsonUnsecureResponse(dct)

@login_required
@no_csrf
def editar_form(id):
    id = int(id)
    item = Item.get_by_id(id)
    item_form = ItemForm()
    item_form.fill_with_model(item)
    __ctx['item'] = item_form
    __ctx['path_editar'] = router.to_path(editar,id)
    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()
    __ctx['categorias'] = categorias
    return TemplateResponse(__ctx,'/meuperfil/caixaesquerda/itens/editar_form.html')

@login_required
@no_csrf
def excluir(_resp,id):
    if id != '' and id != None:
        try:
            chave = ndb.Key(Item,int(id))
            chave.delete()
        except:
            _resp.set_status(400)
            __dct['error'] = 'Ocorreu algum problema ao excluir o item!'
    else:
        _resp.set_status(400)
        __dct['error'] = 'ID do item está vazio!'

    return JsonUnsecureResponse(__dct)

@login_required
@no_csrf
def salvar(_resp,**itens):
    item_form = ItemForm(**itens)
    erros = item_form.validate()
    if erros:
        _resp.set_status(400)
        dct = erros
    else:
        item = item_form.fill_model()
        item.put()
        dct = item_form.fill_with_model(item)
        categorias = (Categoria.query().order(Categoria.categoria)).fetch()
        p_editar_form = router.to_path(editar_form)
        dct['path_editar_form'] = '%s/%s'%(p_editar_form,dct['id'])
        key_cat = ndb.Key(Categoria,int(dct['id_categoria']))
        for cat in categorias:
            if key_cat == cat.key:
                dct['categoria'] = cat.categoria
                break
        log.info(dct)
    return JsonUnsecureResponse(dct)

<commit_msg>refs#7-angular ate video 22.19<commit_after># -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from config.template_middleware import TemplateResponse
from gaecookie.decorator import no_csrf
from gaepermission.decorator import login_required
from tekton import router
from tekton.gae.middleware.redirect import RedirectResponse
from model.db import *
from tekton.gae.middleware.json_middleware import JsonUnsecureResponse
from distutils import log
from json import dumps

__author__ = 'Rodrigo'

__ctx = {'items':'','item':'','categorias':'','categoria_selecionada':'','erros':'','sucesso':-1,'safe':'','encontrado':-1,
         'path_editar':'','path_editar_form':'','path_excluir':'','path_pesquisar':'', 'path_listar':''}

#__ctx = {'items':'','categorias':'','erros':''}

__dct = {'error':''}

@login_required
@no_csrf
def index(id_categoria = None):
    if id_categoria == None or id_categoria == 'all':
        query = Item.query().order(Item.titulo)
        item_lista = query.fetch()
        if id_categoria == 'all':
            __ctx['categoria_selecionada'] = 'all'
        else:
            __ctx['categoria_selecionada'] = ''
    else:
        query = Item.query(Item.id_categoria == id_categoria).order(Item.titulo)
        item_lista = query.fetch()
        __ctx['categoria_selecionada'] = id_categoria

    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()

    if len(item_lista) > 0:
        form = ItemForm()
        item_lista = [form.fill_with_model(item) for item in item_lista] #transforma a classe em dicionário para poder adicionar valores dinamicamente
        p_editar_form = router.to_path(editar_form)
        p_excluir = router.to_path(excluir)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            #item['path_excluir'] = '%s/%s'%(p_excluir,item['id'])
            item['id_categoria'] = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if item['id_categoria'] == cat.key:
                    item['categoria'] = cat.categoria
                    item['id_categoria'] = ''
                    break
        __ctx['itens'] = item_lista
        __ctx['encontrado'] = 1
    else:
        __ctx['encontrado'] = 0
    __ctx['categorias'] = categorias
    __ctx['erros'] = ''
    __ctx['sucesso'] = -1
    __ctx['path_index'] = router.to_path(index)
    __ctx['path_salvar'] = router.to_path(salvar)
    __ctx['path_listar'] = router.to_path(listar)
    __ctx['path_excluir'] = router.to_path(excluir)
    __ctx['path_editar'] = router.to_path(editar)

    __ctx['itens'] = dumps(item_lista) #converte o item_lista para json

    return TemplateResponse(__ctx)

'''
@login_required
@no_csrf
def index(id_categoria = None, buscar = '0'):
    if id_categoria == None or id_categoria == 'all':
        query = Item.query().order(Item.titulo)
        item_lista = query.fetch()
        if id_categoria == 'all':
            __ctx['categoria_selecionada'] = 'all'
        else:
            __ctx['categoria_selecionada'] = ''
    else:
        query = Item.query(Item.id_categoria == id_categoria).order(Item.titulo)
        item_lista = query.fetch()
        __ctx['categoria_selecionada'] = id_categoria

    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()

    if len(item_lista) > 0:
        form = ItemForm()
        item_lista = [form.fill_with_model(item) for item in item_lista] #transforma a classe em dicionário para poder adicionar valores dinamicamente
        p_editar_form = router.to_path(editar_form)
        p_excluir = router.to_path(excluir)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            #item['path_excluir'] = '%s/%s'%(p_excluir,item['id'])
            item['id_categoria'] = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if item['id_categoria'] == cat.key:
                    item['categoria'] = cat.categoria
                    break
        __ctx['itens'] = item_lista
        __ctx['encontrado'] = 1
    else:
        __ctx['encontrado'] = 0
    __ctx['categorias'] = categorias
    __ctx['erros'] = ''
    __ctx['sucesso'] = -1
    __ctx['path_index'] = router.to_path(index)
    __ctx['path_salvar'] = router.to_path(salvar)

    return TemplateResponse(__ctx)
'''

@login_required
@no_csrf
def listar(_resp,id_cat_buscar = None):
    categorias = (Categoria.query().order(Categoria.categoria)).fetch()
    form = ItemForm()

    if id_cat_buscar == 'all' or id_cat_buscar == None:
        item_lista = (Item.query().order(Item.titulo)).fetch()
    else:
        item_lista = (Item.query(Item.id_categoria == id_cat_buscar).order(Item.titulo)).fetch()

    if item_lista > 0:
        item_lista = [form.fill_with_model(p) for p in item_lista]
        p_editar_form = router.to_path(editar_form)
        for item in item_lista:
            item['path_editar_form'] = '%s/%s'%(p_editar_form,item['id'])
            key_cat = ndb.Key(Categoria,int(item['id_categoria']))
            for cat in categorias:
                if key_cat == cat.key:
                    item['categoria'] = cat.categoria
                    break
    else:
        item_lista = {'error':'Não foi encontrado nenhum item.'}
        _resp.set_status(400)

    return JsonUnsecureResponse(item_lista)

@login_required
@no_csrf
def editar(_resp,id,**itens):
    id = int(id)
    item_bd = Item.get_by_id(id)
    item_form = ItemForm(**itens)
    erros = item_form.validate()

    if erros:
        _resp.set_status(400)
        dct = erros
    else:
        item_bd.titulo = itens['titulo']
        item_bd.id_categoria = itens['id_categoria']
        item_bd.descricao = itens['descricao']
        item_bd.put()
        dct = item_form.fill_with_model(item_bd)
        categorias = (Categoria.query().order(Categoria.categoria)).fetch()
        key_cat = ndb.Key(Categoria,int(itens['id_categoria']))
        for cat in categorias:
            if key_cat == cat.key:
                dct['categoria'] = cat.categoria
                break

    log.info(dct)
    return JsonUnsecureResponse(dct)

@login_required
@no_csrf
def editar_form(id):
    id = int(id)
    item = Item.get_by_id(id)
    item_form = ItemForm()
    item_form.fill_with_model(item)
    __ctx['item'] = item_form
    __ctx['path_editar'] = router.to_path(editar,id)
    query = Categoria.query().order(Categoria.categoria)
    categorias = query.fetch()
    __ctx['categorias'] = categorias
    return TemplateResponse(__ctx,'/meuperfil/caixaesquerda/itens/editar_form.html')

@login_required
@no_csrf
def excluir(_resp,id):
    if id != '' and id != None:
        try:
            chave = ndb.Key(Item,int(id))
            chave.delete()
        except:
            _resp.set_status(400)
            __dct['error'] = 'Ocorreu algum problema ao excluir o item!'
    else:
        _resp.set_status(400)
        __dct['error'] = 'ID do item está vazio!'

    return JsonUnsecureResponse(__dct)

@login_required
@no_csrf
def salvar(_resp,**itens):
    item_form = ItemForm(**itens)
    erros = item_form.validate()
    if erros:
        _resp.set_status(400)
        dct = erros
    else:
        item = item_form.fill_model()
        item.put()
        dct = item_form.fill_with_model(item)
        categorias = (Categoria.query().order(Categoria.categoria)).fetch()
        p_editar_form = router.to_path(editar_form)
        dct['path_editar_form'] = '%s/%s'%(p_editar_form,dct['id'])
        key_cat = ndb.Key(Categoria,int(dct['id_categoria']))
        for cat in categorias:
            if key_cat == cat.key:
                dct['categoria'] = cat.categoria
                break
        log.info(dct)
    return JsonUnsecureResponse(dct)

<|endoftext|>


<commit_before>"""
Code to manage fetching and storing courses from external sources.
"""

from celery.task import task
import logging
import requests
from dateutil.parser import parse

from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

from django.conf import settings

from openedx.core.djangoapps.appsembler.external_courses.models import ExternalCourseTile

log = logging.getLogger(__name__)

@task(name='openedx.core.djangoapps.external_courses.fetch_courses')
def fetch_courses():

    num_changed = 0
    num_added = 0
    num_failed = 0
    num_deleted = 0

    if not settings.EDX_ORG_COURSE_API_CATALOG_IDS:
        raise Exception("EDX_ORG_COURSE_API_CATALOG_IDS variable is undefined")

    for catalog_id in settings.EDX_ORG_COURSE_API_CATALOG_IDS:
        client = BackendApplicationClient(
            client_id=settings.EDX_ORG_COURSE_API_CLIENT_ID
        )
        oauth = OAuth2Session(client=client)
        token = oauth.fetch_token(
            token_url=settings.EDX_ORG_COURSE_API_TOKEN_URL,
            client_id=settings.EDX_ORG_COURSE_API_CLIENT_ID,
            client_secret=settings.EDX_ORG_COURSE_API_CLIENT_SECRET,
            token_type=settings.EDX_ORG_COURSE_API_TOKEN_TYPE
        )
        headers = {
            'Content-Type': 'application/json',
            'Authorization': '{token_type} {token}'.format(
                token_type=settings.EDX_ORG_COURSE_API_TOKEN_TYPE,
                token=token['access_token']
            )
        }
        response = requests.get(
            '{api_url}api/v1/catalogs/{catalog_id}/courses/?limit=100&offset=0'.format(
                api_url = settings.EDX_ORG_COURSE_API_URL,
                catalog_id = catalog_id
            ),
            headers=headers)

        if response.status_code != 200:
            log.info(
                'Error in request, the endpoint returned an invalid status code: {code} for the catalog id: {catalog_id}'.format(
                    code=response.status_code, catalog_id=catalog_id
                )
            )
            continue

        if not response.json()['results'] or len(response.json()['results']) <= 0:
            log.info('No results were found for catalog %s' % catalog_id)
            continue

        for course in response.json()['results']:

            course_key = course['key']

            try:
                obj_course = ExternalCourseTile.objects.get(
                    course_key=course_key)
                is_new = False
            except ExternalCourseTile.DoesNotExist:
                obj_course = ExternalCourseTile(course_key=course_key)
                is_new = True

            if len(course['course_runs']) < 1 or course['owners'] < 1: # assuming no run or no owners
                if not is_new:
                    obj_course.delete()
                    num_deleted += 1
                continue

            course_run = course['course_runs'][0]

            try:
                obj_course.title = course['title']
                obj_course.org = course['owners'][0]['key']
                obj_course.course_link = course_run['marketing_url']
                obj_course.image_url = course_run['image']['src']
                obj_course.starts = parse(course_run['start'])
                obj_course.ends = parse(course_run['end'])
                obj_course.pacing_type = course_run['pacing_type']

                if 'seats' in course_run:
                    for seat in course_run['seats']:
                        if seat['type'] == 'credit':
                            obj_course.is_credit_eligible = True
                        elif seat['type'] == 'verified':
                            obj_course.is_verified_eligible = True

                obj_course.save()

                if is_new:
                    num_added += 1
                else:
                    num_changed += 1

            except:
                log.info('Import course failed: ' + course_key)
                num_failed += 1

    return (num_added, num_changed, num_failed, num_deleted, (num_added + num_changed + num_failed + num_deleted))

def is_credit_eligible(course_run):
    """
    Inspect the course seat to check if the course is credit eligible
    :param json_course: The JSON course item
    :return: boolean
    """
    for seat in course_run['seats']:
        if seat['type'] == 'credit':
            return True

    return False<commit_msg>hotfix external course task name<commit_after>"""
Code to manage fetching and storing courses from external sources.
"""

from celery.task import task
import logging
import requests
from dateutil.parser import parse

from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

from django.conf import settings

from openedx.core.djangoapps.appsembler.external_courses.models import ExternalCourseTile

log = logging.getLogger(__name__)

@task(name='openedx.core.djangoapps.appsembler.external_courses.tasks.fetch_courses')
def fetch_courses():

    num_changed = 0
    num_added = 0
    num_failed = 0
    num_deleted = 0

    if not settings.EDX_ORG_COURSE_API_CATALOG_IDS:
        raise Exception("EDX_ORG_COURSE_API_CATALOG_IDS variable is undefined")

    for catalog_id in settings.EDX_ORG_COURSE_API_CATALOG_IDS:
        client = BackendApplicationClient(
            client_id=settings.EDX_ORG_COURSE_API_CLIENT_ID
        )
        oauth = OAuth2Session(client=client)
        token = oauth.fetch_token(
            token_url=settings.EDX_ORG_COURSE_API_TOKEN_URL,
            client_id=settings.EDX_ORG_COURSE_API_CLIENT_ID,
            client_secret=settings.EDX_ORG_COURSE_API_CLIENT_SECRET,
            token_type=settings.EDX_ORG_COURSE_API_TOKEN_TYPE
        )
        headers = {
            'Content-Type': 'application/json',
            'Authorization': '{token_type} {token}'.format(
                token_type=settings.EDX_ORG_COURSE_API_TOKEN_TYPE,
                token=token['access_token']
            )
        }
        response = requests.get(
            '{api_url}api/v1/catalogs/{catalog_id}/courses/?limit=100&offset=0'.format(
                api_url = settings.EDX_ORG_COURSE_API_URL,
                catalog_id = catalog_id
            ),
            headers=headers)

        if response.status_code != 200:
            log.info(
                'Error in request, the endpoint returned an invalid status code: {code} for the catalog id: {catalog_id}'.format(
                    code=response.status_code, catalog_id=catalog_id
                )
            )
            continue

        if not response.json()['results'] or len(response.json()['results']) <= 0:
            log.info('No results were found for catalog %s' % catalog_id)
            continue

        for course in response.json()['results']:

            course_key = course['key']

            try:
                obj_course = ExternalCourseTile.objects.get(
                    course_key=course_key)
                is_new = False
            except ExternalCourseTile.DoesNotExist:
                obj_course = ExternalCourseTile(course_key=course_key)
                is_new = True

            if len(course['course_runs']) < 1 or course['owners'] < 1: # assuming no run or no owners
                if not is_new:
                    obj_course.delete()
                    num_deleted += 1
                continue

            course_run = course['course_runs'][0]

            try:
                obj_course.title = course['title']
                obj_course.org = course['owners'][0]['key']
                obj_course.course_link = course_run['marketing_url']
                obj_course.image_url = course_run['image']['src']
                obj_course.starts = parse(course_run['start'])
                obj_course.ends = parse(course_run['end'])
                obj_course.pacing_type = course_run['pacing_type']

                if 'seats' in course_run:
                    for seat in course_run['seats']:
                        if seat['type'] == 'credit':
                            obj_course.is_credit_eligible = True
                        elif seat['type'] == 'verified':
                            obj_course.is_verified_eligible = True

                obj_course.save()

                if is_new:
                    num_added += 1
                else:
                    num_changed += 1

            except:
                log.info('Import course failed: ' + course_key)
                num_failed += 1

    return (num_added, num_changed, num_failed, num_deleted, (num_added + num_changed + num_failed + num_deleted))

def is_credit_eligible(course_run):
    """
    Inspect the course seat to check if the course is credit eligible
    :param json_course: The JSON course item
    :return: boolean
    """
    for seat in course_run['seats']:
        if seat['type'] == 'credit':
            return True

    return False
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 OpenERP S.A. (<http://www.openerp.com>).
#
#    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/>.
#
##############################################################################
"""
Module to handle publisher warranty contracts as well as notifications from
OpenERP.
"""

import datetime
import logging
import sys
import urllib
import urllib2

import pooler
import release
from osv import osv, fields
from tools.translate import _
from tools.safe_eval import safe_eval
from tools.config import config
from tools import misc

_logger = logging.getLogger(__name__)

"""
Time interval that will be used to determine up to which date we will
check the logs to see if a message we just received was already logged.
@type: datetime.timedelta
"""
_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)

class publisher_warranty_contract(osv.osv):
    """
    Osv representing a publisher warranty contract.
    """
    _name = "publisher_warranty.contract"

    def _get_valid_contracts(self, cr, uid):
        """
        Return the list of the valid contracts encoded in the system.

        @return: A list of contracts
        @rtype: list of publisher_warranty.contract browse records
        """
        return [contract for contract in self.browse(cr, uid, self.search(cr, uid, []))
                if contract.state == 'valid']

    def status(self, cr, uid):
        """ Method called by the client to check availability of publisher warranty contract. """

        contracts = self._get_valid_contracts(cr, uid)
        return {
            'status': "full" if contracts else "none" ,
            'uncovered_modules': list(),
        }

    def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
        """ Method called by the client to send a problem to the publisher warranty server. """

        if not remarks:
            remarks = ""

        valid_contracts = self._get_valid_contracts(cr, uid)
        valid_contract = valid_contracts[0]

        try:
            origin = 'client'
            dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
            db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
            user = self.pool.get("res.users").browse(cr, uid, uid)
            user_name = user.name
            email = user.user_email

            msg = {'contract_name': valid_contract.name,
                'tb': tb,
                'explanations': explanations,
                'remarks': remarks,
                'origin': origin,
                'dbname': cr.dbname,
                'dbuuid': dbuuid,
                'db_create_date': db_create_date,
                'issue_name': issue_name,
                'email': email,
                'user_name': user_name,
            }

            add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
            uo = urllib2.urlopen(config.get("publisher_warranty_url"),
                                    urllib.urlencode({'arg0': msg, "action": "send",}),**add_arg)
            try:
                submit_result = uo.read()
            finally:
                uo.close()

            result = safe_eval(submit_result)

            crm_case_id = result

            if not crm_case_id:
                return False

        except osv.except_osv:
            raise
        except Exception:
            _logger.warning("Error sending problem report", exc_info=1)
            raise osv.except_osv(_("Error"),
                                 _("Error during communication with the publisher warranty server."))

        return True

    def check_validity(self, cr, uid, ids, context=None):
        """
        Check the validity of a publisher warranty contract. This method just call get_logs() but checks
        some more things, so it can be called from a user interface.
        """
        contract_id = ids[0]
        contract = self.browse(cr, uid, contract_id)
        state = contract.state
        validated = state != "unvalidated"

        self.get_logs(cr, uid, ids, cron_mode=False, context=context)

        contract = self.browse(cr, uid, contract_id)
        validated2 = contract.state != "unvalidated"
        if not validated and not validated2:
            raise osv.except_osv(_("Contract validation error"),
                                 _("Please verify your publisher warranty serial number and validity."))
        return True

    def get_logs(self, cr, uid, ids, cron_mode=True, context=None):
        """
        Send a message to OpenERP's publisher warranty server to check the validity of
        the contracts, get notifications, etc...

        @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
        @type cron_mode: boolean
        """
        try:
            try:
                result = get_sys_logs(cr, uid)
            except Exception:
                if cron_mode: # we don't want to see any stack trace in cron
                    return False
                _logger.debug("Exception while sending a get logs messages", exc_info=1)
                raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))

            contracts = result["contracts"]
            for contract in contracts:
                c_id = self.search(cr, uid, [("name","=",contract)])[0]
                # for backward compatibility
                if type(contracts[contract]) == tuple:
                    self.write(cr, uid, c_id, {
                        "date_start": contracts[contract][0],
                        "date_stop": contracts[contract][1],
                        "state": contracts[contract][2],
                        "check_support": False,
                        "check_opw": False,
                        "kind": "",
                    })
                else:
                    self.write(cr, uid, c_id, {
                        "date_start": contracts[contract]["date_from"],
                        "date_stop": contracts[contract]["date_to"],
                        "state": contracts[contract]["state"],
                        "check_support": contracts[contract]["check_support"],
                        "check_opw": contracts[contract]["check_opw"],
                        "kind": contracts[contract]["kind"],
                    })

            limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
            for message in result["messages"]:
                ids = self.pool.get("res.log").search(cr, uid, [("res_model", "=", "publisher_warranty.contract"),
                                                          ("create_date", ">=", limit_date),
                                                          ("name", "=", message)])
                if ids:
                    continue
                self.pool.get('res.log').create(cr, uid,
                        {
                            'name': message,
                            'res_model': "publisher_warranty.contract",
                            "read": True,
                            "user_id": False,
                        },
                        context=context
                )
        except Exception:
            if cron_mode:
                return False # we don't want to see any stack trace in cron
            else:
                raise
        return True

    def get_last_user_messages(self, cr, uid, limit, context=None):
        """
        Get the messages to be written in the web client.
        @return: A list of html messages with ids, can be False or empty.
        @rtype: list of tuples(int,string)
        """
        ids = self.pool.get('res.log').search(cr, uid, [("res_model", "=", "publisher_warranty.contract")]
                                        , order="create_date desc", limit=limit)
        if not ids:
            return []
        messages = [(x.id, x.name) for x in self.pool.get('res.log').browse(cr, uid, ids)]

        return messages

    def del_user_message(self, cr, uid, id, context=None):
        """
        Delete a message.
        """
        self.pool.get('res.log').unlink(cr, uid, [id])

        return True

    _columns = {
        'name' : fields.char('Serial Key', size=384, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
        'date_start' : fields.date('Starting Date', readonly=True),
        'date_stop' : fields.date('Ending Date', readonly=True),
        'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid')
                            , ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True),
        'kind' : fields.char('Kind', size=64, readonly=True),
        "check_support": fields.boolean("Support Level 1", readonly=True),
        "check_opw": fields.boolean("OPW", readonly=True, help="Checked if this is an OpenERP Publisher's Warranty contract (versus older contract types"),
    }

    _defaults = {
        'state': 'unvalidated',
    }

    _sql_constraints = [
        ('uniq_name', 'unique(name)', "That contract is already registered in the system.")
    ]

publisher_warranty_contract()

class maintenance_contract(osv.osv_memory):
    """ Old osv we only keep for compatibility with the clients. """

    _name = "maintenance.contract"

    def status(self, cr, uid):
        return self.pool.get("publisher_warranty.contract").status(cr, uid)

    def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
        return self.pool.get("publisher_warranty.contract").send(cr, uid, tb,
                        explanations, remarks, issue_name)

maintenance_contract()

class publisher_warranty_contract_wizard(osv.osv_memory):
    """
    A wizard osv to help people entering a publisher warranty contract.
    """
    _name = 'publisher_warranty.contract.wizard'
    _inherit = "ir.wizard.screen"

    _columns = {
        'name' : fields.char('Serial Key', size=256, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
        'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")])
    }

    _defaults = {
        "state": "draft",
    }

    def action_validate(self, cr, uid, ids, context=None):
        if not ids:
            return False

        wiz = self.browse(cr, uid, ids[0])
        c_name = wiz.name

        contract_osv = self.pool.get("publisher_warranty.contract")
        contracts = contract_osv.search(cr, uid, [("name","=",c_name)])
        if contracts:
            raise osv.except_osv(_("Error"), _("That contract is already registered in the system."))

        contract_id = contract_osv.create(cr, uid, {
            "name": c_name,
            "state": "unvalidated",
        })

        contract_osv.check_validity(cr, uid, [contract_id])

        self.write(cr, uid, ids, {"state": "finished"})

        # We should return an action ?
        return True

publisher_warranty_contract_wizard()

def get_sys_logs(cr, uid):
    """
    Utility method to send a publisher warranty get logs messages.
    """
    pool = pooler.get_pool(cr.dbname)

    dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
    db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
    limit_date = datetime.datetime.now()
    limit_date = limit_date - datetime.timedelta(15)
    limit_date_str = limit_date.strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
    nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
    nbr_active_users = pool.get("res.users").search(cr, uid, [("date", ">=", limit_date_str)], count=True)
    nbr_share_users = False
    nbr_active_share_users = False
    if "share" in pool.get("res.users")._all_columns:
        nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True)
        nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True)
    contractosv = pool.get('publisher_warranty.contract')
    contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, []))
    user = pool.get("res.users").browse(cr, uid, uid)
    msg = {
        "dbuuid": dbuuid,
        "nbr_users": nbr_users,
        "nbr_active_users": nbr_active_users,
        "nbr_share_users": nbr_share_users,
        "nbr_active_share_users": nbr_active_share_users,
        "dbname": cr.dbname,
        "db_create_date": db_create_date,
        "version": release.version,
        "contracts": [c.name for c in contracts],
        "language": user.context_lang,
    }

    add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
    arguments = {'arg0': msg, "action": "update",}
    arguments_raw = urllib.urlencode(arguments)
    url = config.get("publisher_warranty_url")
    uo = urllib2.urlopen(url, arguments_raw, **add_arg)
    try:
        submit_result = uo.read()
    finally:
        uo.close()

    result = safe_eval(submit_result) if submit_result else {}

    return result

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

<commit_msg>[FIX] publisher warranty missing info<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 OpenERP S.A. (<http://www.openerp.com>).
#
#    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/>.
#
##############################################################################
"""
Module to handle publisher warranty contracts as well as notifications from
OpenERP.
"""

import datetime
import logging
import sys
import urllib
import urllib2

import pooler
import release
from osv import osv, fields
from tools.translate import _
from tools.safe_eval import safe_eval
from tools.config import config
from tools import misc

_logger = logging.getLogger(__name__)

"""
Time interval that will be used to determine up to which date we will
check the logs to see if a message we just received was already logged.
@type: datetime.timedelta
"""
_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)

class publisher_warranty_contract(osv.osv):
    """
    Osv representing a publisher warranty contract.
    """
    _name = "publisher_warranty.contract"

    def _get_valid_contracts(self, cr, uid):
        """
        Return the list of the valid contracts encoded in the system.

        @return: A list of contracts
        @rtype: list of publisher_warranty.contract browse records
        """
        return [contract for contract in self.browse(cr, uid, self.search(cr, uid, []))
                if contract.state == 'valid']

    def status(self, cr, uid):
        """ Method called by the client to check availability of publisher warranty contract. """

        contracts = self._get_valid_contracts(cr, uid)
        return {
            'status': "full" if contracts else "none" ,
            'uncovered_modules': list(),
        }

    def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
        """ Method called by the client to send a problem to the publisher warranty server. """

        if not remarks:
            remarks = ""

        valid_contracts = self._get_valid_contracts(cr, uid)
        valid_contract = valid_contracts[0]

        try:
            origin = 'client'
            dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
            db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
            user = self.pool.get("res.users").browse(cr, uid, uid)
            user_name = user.name
            email = user.user_email

            msg = {'contract_name': valid_contract.name,
                'tb': tb,
                'explanations': explanations,
                'remarks': remarks,
                'origin': origin,
                'dbname': cr.dbname,
                'dbuuid': dbuuid,
                'db_create_date': db_create_date,
                'issue_name': issue_name,
                'email': email,
                'user_name': user_name,
            }

            add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
            uo = urllib2.urlopen(config.get("publisher_warranty_url"),
                                    urllib.urlencode({'arg0': msg, "action": "send",}),**add_arg)
            try:
                submit_result = uo.read()
            finally:
                uo.close()

            result = safe_eval(submit_result)

            crm_case_id = result

            if not crm_case_id:
                return False

        except osv.except_osv:
            raise
        except Exception:
            _logger.warning("Error sending problem report", exc_info=1)
            raise osv.except_osv(_("Error"),
                                 _("Error during communication with the publisher warranty server."))

        return True

    def check_validity(self, cr, uid, ids, context=None):
        """
        Check the validity of a publisher warranty contract. This method just call get_logs() but checks
        some more things, so it can be called from a user interface.
        """
        contract_id = ids[0]
        contract = self.browse(cr, uid, contract_id)
        state = contract.state
        validated = state != "unvalidated"

        self.get_logs(cr, uid, ids, cron_mode=False, context=context)

        contract = self.browse(cr, uid, contract_id)
        validated2 = contract.state != "unvalidated"
        if not validated and not validated2:
            raise osv.except_osv(_("Contract validation error"),
                                 _("Please verify your publisher warranty serial number and validity."))
        return True

    def get_logs(self, cr, uid, ids, cron_mode=True, context=None):
        """
        Send a message to OpenERP's publisher warranty server to check the validity of
        the contracts, get notifications, etc...

        @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
        @type cron_mode: boolean
        """
        try:
            try:
                result = get_sys_logs(cr, uid)
            except Exception:
                if cron_mode: # we don't want to see any stack trace in cron
                    return False
                _logger.debug("Exception while sending a get logs messages", exc_info=1)
                raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))

            contracts = result["contracts"]
            for contract in contracts:
                c_id = self.search(cr, uid, [("name","=",contract)])[0]
                # for backward compatibility
                if type(contracts[contract]) == tuple:
                    self.write(cr, uid, c_id, {
                        "date_start": contracts[contract][0],
                        "date_stop": contracts[contract][1],
                        "state": contracts[contract][2],
                        "check_support": False,
                        "check_opw": False,
                        "kind": "",
                    })
                else:
                    self.write(cr, uid, c_id, {
                        "date_start": contracts[contract]["date_from"],
                        "date_stop": contracts[contract]["date_to"],
                        "state": contracts[contract]["state"],
                        "check_support": contracts[contract]["check_support"],
                        "check_opw": contracts[contract]["check_opw"],
                        "kind": contracts[contract]["kind"],
                    })

            limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
            for message in result["messages"]:
                ids = self.pool.get("res.log").search(cr, uid, [("res_model", "=", "publisher_warranty.contract"),
                                                          ("create_date", ">=", limit_date),
                                                          ("name", "=", message)])
                if ids:
                    continue
                self.pool.get('res.log').create(cr, uid,
                        {
                            'name': message,
                            'res_model': "publisher_warranty.contract",
                            "read": True,
                            "user_id": False,
                        },
                        context=context
                )
        except Exception:
            if cron_mode:
                return False # we don't want to see any stack trace in cron
            else:
                raise
        return True

    def get_last_user_messages(self, cr, uid, limit, context=None):
        """
        Get the messages to be written in the web client.
        @return: A list of html messages with ids, can be False or empty.
        @rtype: list of tuples(int,string)
        """
        ids = self.pool.get('res.log').search(cr, uid, [("res_model", "=", "publisher_warranty.contract")]
                                        , order="create_date desc", limit=limit)
        if not ids:
            return []
        messages = [(x.id, x.name) for x in self.pool.get('res.log').browse(cr, uid, ids)]

        return messages

    def del_user_message(self, cr, uid, id, context=None):
        """
        Delete a message.
        """
        self.pool.get('res.log').unlink(cr, uid, [id])

        return True

    _columns = {
        'name' : fields.char('Serial Key', size=384, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
        'date_start' : fields.date('Starting Date', readonly=True),
        'date_stop' : fields.date('Ending Date', readonly=True),
        'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid')
                            , ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True),
        'kind' : fields.char('Kind', size=64, readonly=True),
        "check_support": fields.boolean("Support Level 1", readonly=True),
        "check_opw": fields.boolean("OPW", readonly=True, help="Checked if this is an OpenERP Publisher's Warranty contract (versus older contract types"),
    }

    _defaults = {
        'state': 'unvalidated',
    }

    _sql_constraints = [
        ('uniq_name', 'unique(name)', "That contract is already registered in the system.")
    ]

publisher_warranty_contract()

class maintenance_contract(osv.osv_memory):
    """ Old osv we only keep for compatibility with the clients. """

    _name = "maintenance.contract"

    def status(self, cr, uid):
        return self.pool.get("publisher_warranty.contract").status(cr, uid)

    def send(self, cr, uid, tb, explanations, remarks=None, issue_name=None):
        return self.pool.get("publisher_warranty.contract").send(cr, uid, tb,
                        explanations, remarks, issue_name)

maintenance_contract()

class publisher_warranty_contract_wizard(osv.osv_memory):
    """
    A wizard osv to help people entering a publisher warranty contract.
    """
    _name = 'publisher_warranty.contract.wizard'
    _inherit = "ir.wizard.screen"

    _columns = {
        'name' : fields.char('Serial Key', size=256, required=True, help="Your OpenERP Publisher's Warranty Contract unique key, also called serial number."),
        'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")])
    }

    _defaults = {
        "state": "draft",
    }

    def action_validate(self, cr, uid, ids, context=None):
        if not ids:
            return False

        wiz = self.browse(cr, uid, ids[0])
        c_name = wiz.name

        contract_osv = self.pool.get("publisher_warranty.contract")
        contracts = contract_osv.search(cr, uid, [("name","=",c_name)])
        if contracts:
            raise osv.except_osv(_("Error"), _("That contract is already registered in the system."))

        contract_id = contract_osv.create(cr, uid, {
            "name": c_name,
            "state": "unvalidated",
        })

        contract_osv.check_validity(cr, uid, [contract_id])

        self.write(cr, uid, ids, {"state": "finished"})

        # We should return an action ?
        return True

publisher_warranty_contract_wizard()

def get_sys_logs(cr, uid):
    """
    Utility method to send a publisher warranty get logs messages.
    """
    pool = pooler.get_pool(cr.dbname)

    dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
    db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
    limit_date = datetime.datetime.now()
    limit_date = limit_date - datetime.timedelta(15)
    limit_date_str = limit_date.strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
    nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
    nbr_active_users = pool.get("res.users").search(cr, uid, [("date", ">=", limit_date_str)], count=True)
    nbr_share_users = False
    nbr_active_share_users = False
    if "share" in pool.get("res.users")._all_columns:
        nbr_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True)], count=True)
        nbr_active_share_users = pool.get("res.users").search(cr, uid, [("share", "=", True), ("date", ">=", limit_date_str)], count=True)
    contractosv = pool.get('publisher_warranty.contract')
    contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, []))
    user = pool.get("res.users").browse(cr, uid, uid)
    msg = {
        "dbuuid": dbuuid,
        "nbr_users": nbr_users,
        "nbr_active_users": nbr_active_users,
        "nbr_share_users": nbr_share_users,
        "nbr_active_share_users": nbr_active_share_users,
        "dbname": cr.dbname,
        "db_create_date": db_create_date,
        "version": release.version,
        "contracts": [c.name for c in contracts],
        "language": user.context_lang,
    }
    msg.update(pool.get("res.company").read(cr,uid,[1],["name","email","phone"])[0])

    add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
    arguments = {'arg0': msg, "action": "update",}
    arguments_raw = urllib.urlencode(arguments)
    url = config.get("publisher_warranty_url")
    uo = urllib2.urlopen(url, arguments_raw, **add_arg)
    try:
        submit_result = uo.read()
    finally:
        uo.close()

    result = safe_eval(submit_result) if submit_result else {}

    return result

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

<|endoftext|>


<commit_before># encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
import re

class Migration(DataMigration):

    def forwards(self, orm):
        def update_username_for_user(user, match_on, sub_with):
            regex = re.compile(match_on)
            if regex.search(user.username):
                user.username = regex.sub(sub_with, user.username)
                user.save()

        # remove whitespace and replace special chars with underscores
        for user in orm['auth.User'].objects.all():
            update_username_for_user(user, "\s", "")
            update_username_for_user(user, "\W", "_")

    def backwards(self, orm):
        pass

    models = {
        'auth.group': {
            'Meta': {'object_name': 'Group'},
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
        },
        'auth.permission': {
            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
        },
        'auth.user': {
            'Meta': {'object_name': 'User'},
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
        },
        'contenttypes.contenttype': {
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
        },
        'main.metadata': {
            'Meta': {'object_name': 'MetaData'},
            'data_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
            'data_type': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
            'data_value': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'xform': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['odk_logger.XForm']"})
        },
        'main.userprofile': {
            'Meta': {'object_name': 'UserProfile'},
            'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'home_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'organization': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'require_auth': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'twitter': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
        },
        'odk_logger.xform': {
            'Meta': {'ordering': "('id_string',)", 'unique_together': "(('user', 'id_string'),)", 'object_name': 'XForm'},
            'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
            'description': ('django.db.models.fields.TextField', [], {'default': "u''", 'null': 'True'}),
            'downloadable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
            'has_start_time': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'id_string': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
            'json': ('django.db.models.fields.TextField', [], {'default': "u''"}),
            'shared': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'shared_data': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'xforms'", 'null': 'True', 'to': "orm['auth.User']"}),
            'xls': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
            'xml': ('django.db.models.fields.TextField', [], {})
        }
    }

    complete_apps = ['main']
<commit_msg>fix for inaccurate migration state (duplicate 0007 migrations)<commit_after># encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
import re

class Migration(DataMigration):

    def forwards(self, orm):
        def update_username_for_user(user, match_on, sub_with):
            regex = re.compile(match_on)
            if regex.search(user.username):
                user.username = regex.sub(sub_with, user.username)
                user.save()

        # remove whitespace and replace special chars with underscores
        for user in orm['auth.User'].objects.all():
            update_username_for_user(user, "\s", "")
            update_username_for_user(user, "\W", "_")

    def backwards(self, orm):
        pass

    models = {
        'auth.group': {
            'Meta': {'object_name': 'Group'},
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
        },
        'auth.permission': {
            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
        },
        'auth.user': {
            'Meta': {'object_name': 'User'},
            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
        },
        'contenttypes.contenttype': {
            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
        },
        'main.metadata': {
            'Meta': {'object_name': 'MetaData'},
            'data_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
            'data_file_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
            'data_type': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
            'data_value': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'xform': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['odk_logger.XForm']"})
        },
        'main.userprofile': {
            'Meta': {'object_name': 'UserProfile'},
            'city': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'country': ('django.db.models.fields.CharField', [], {'max_length': '2', 'blank': 'True'}),
            'description': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'home_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'organization': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'require_auth': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'twitter': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
            'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
        },
        'odk_logger.xform': {
            'Meta': {'ordering': "('id_string',)", 'unique_together': "(('user', 'id_string'),)", 'object_name': 'XForm'},
            'date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
            'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
            'description': ('django.db.models.fields.TextField', [], {'default': "u''", 'null': 'True'}),
            'downloadable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
            'has_start_time': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'id_string': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
            'json': ('django.db.models.fields.TextField', [], {'default': "u''"}),
            'shared': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'shared_data': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
            'title': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'xforms'", 'null': 'True', 'to': "orm['auth.User']"}),
            'xls': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
            'xml': ('django.db.models.fields.TextField', [], {})
        }
    }

    complete_apps = ['main']
<|endoftext|>


<commit_before>"""removed activation_key from the user table and add enabled column

Revision ID: ac35c979311a
Revises: 661199d8768a
Create Date: 2016-02-18 08:54:43.786641

"""

# revision identifiers, used by Alembic.
revision = 'ac35c979311a'
down_revision = '661199d8768a'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa

def upgrade():
    op.drop_column('user', 'activation_key')
    op.add_column('user', sa.Column('enabled', sa.Boolean(), nullable=False,
                                        default=False))

def downgrade():
    op.drop_column('user', 'enabled')
    op.add_column('user', sa.Column('activation_key', sa.String(),
                                        nullable=False, default=''))
<commit_msg>fix migration script<commit_after>"""removed activation_key from the user table and add enabled column

Revision ID: ac35c979311a
Revises: 661199d8768a
Create Date: 2016-02-18 08:54:43.786641

"""

# revision identifiers, used by Alembic.
revision = 'ac35c979311a'
down_revision = '661199d8768a'
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa

def upgrade():
    op.drop_column('user', 'activation_key')
    op.add_column('user', sa.Column('enabled', sa.Boolean(), default=False))

def downgrade():
    op.drop_column('user', 'enabled')
    op.add_column('user', sa.Column('activation_key', sa.String(),
                                        nullable=False, default=''))
<|endoftext|>