<commit_before>"""
Class to read DBF files.
"""

import os
import datetime
import collections

from .struct_parser import StructParser
from .field_parser import FieldParser
from .common import parse_string
from .ifiles import ifind
from .fpt import FPT

DBFHeader = StructParser(
    'DBFHeader',
    '<BBBBLHHHBBLLLBBH',
    ['dbversion',
     'year',
     'month',
     'day',
     'numrecords',
     'headerlen',
     'recordlen',
     'reserved1',
     'incomplete_transaction',
     'encryption_flag',
     'free_record_thread',
     'reserved2',
     'reserved3',
     'mdx_flag',
     'language_driver',
     'reserved4',
     ])

DBFField = StructParser(
    'DBFField',
    '<11scLBBHBBBB7sB',
    ['name',
     'type',
     'address',
     'length',
     'decimal_count',
     'reserved1',
     'workarea_id',
     'reserved2',
     'reserved3',
     'set_fields_flag',
     'reserved4',
     'index_field_flag',
     ])

FieldValue = collections.namedtuple('Field', 'name value')

def expand_year(year):
    """
    Convert 2-digit year to 4-digit year.
    """

    if year < 80:
        return 2000 + year
    else:
        return 1900 + year

class DBF(list):
    """
    Class to read DBF files.
    """

    def __init__(self, filename,
                 encoding='latin1',  # Todo: is this a good default?
                 raw=False,
                 ignorecase=True,
                 lowernames=False,
                 parserclass=FieldParser,
                 recfactory=dict,
                 peek=False):

        self.encoding = encoding
        self.recfactory = recfactory
        self.raw = raw
        self.ignorecase = ignorecase
        self.lowernames = lowernames
        self.parserclass = parserclass

        self._field_parser = self.parserclass(self.encoding)

        # Name part before .dbf is the table name
        self.name = os.path.basename(filename)
        self.name = os.path.splitext(self.name)[0]
        self.name = self.name.lower()

        if ignorecase:
            self.filename = ifind(filename)
        else:
            self.filename = filename

        # Filled in by self._read_headers()
        self.memofilename = None
        self.header = None
        self.fields = []       # namedtuples
        self.field_names = []  # strings

        with open(self.filename, mode='rb') as self.file:
            self._read_headers()
            self._check_headers()

            self.date = datetime.date(expand_year(self.header.year),
                                      self.header.month,
                                      self.header.day)

            self.deleted = []

            if not peek:
                self._load()

        del self.file

    def _read_headers(self):
        #
        # Todo: more checks
        # http://www.clicketyclick.dk/databases/xbase/format/dbf_check.html#CHECK_DBF
        #
        self.header = DBFHeader.read(self.file)

        #
        # Read field headers
        #
        while 1:
            sep = self.file.read(1)
            if sep in (b'\x0d', '\n', ''):
                # End of field headers
                break

            fh = DBFField.read(self.file, prepend=sep)
            # We need to fix the name and type

            fieldname = parse_string(fh.name, self.encoding)
            if self.lowernames:
                fieldname = fieldname.lower()
            fieldtype = parse_string(fh.type, self.encoding)

            fh = fh._replace(name=fieldname,
                             type=fieldtype)

            self.field_names.append(fh.name)

            self.fields.append(fh)

        if len(self.fields) < 1:
            raise ValueError('dbf file must have at least one field: %s' % self.filename)

        # Check for memo file
        field_types = set([f.type for f in self.fields])
        if 'M' in field_types:
            fn = os.path.splitext(self.filename)[0] + '.fpt'
            match = ifind(self.filename, ext='.fpt')
            if match:
                self.memofilename = match
            else:
                # Todo: warn and return field as byte string?
                raise IOError('Missing memo file: %r' % fn)

    def _check_headers(self):
        """Check headers for possible format errors."""

        for field in self.fields:

            if field.type == '0' and field.length != 1:
                    ValueError('Field of type 0 must have length 1 (was %s)' % field.length)

            elif field.type == 'I' and field.length != 4:
                    ValueError('Field type I must have length 4 (was %s)' % field.length)

            elif field.type == 'L' and field.length != 1:
                    ValueError('Field type L must have length 1 (was %s)' % field.length)

            elif not self._field_parser.field_type_supported(field.type):
                # Todo: return as byte string?
                ValueError('Unknown field type: %r' % (field.type))

    def _read_record(self, fpt=None):
        items = []  # List of Field
        for field in self.fields:
            value = self.file.read(field.length)
            if self.raw:
                value = value  # Just return the byte string
            else:
                value = self._field_parser.parse(field, value)

                #
                # Decoding memo fields requires a little more
                # trickery.
                #
                if field.type == 'M':
                    if value == None:
                        value = ''
                    else:
                        fptrecord = fpt[value]
                        if ftprecord.type == 'memo':
                            # Decode to unicode
                            value = parse_string(fptrecord.data, self.encoding)
                        else:
                            # Byte array
                            value = fptrecord.data

            items.append(FieldValue(name=field.name, value=value))

        row = self.recfactory(items)

        return row

    def _load(self):

        #
        # Get memo file
        #
        if self.memofilename and not self.raw:
            fpt = FPT(self.memofilename)
        else:
            fpt = None

        #
        # Skip header
        #
        self.file.seek(self.header.headerlen, 0)

        #
        # Read records
        #
        while 1:
            sep = self.file.read(1)

            if sep == b'':
                break  # End of file reached
            elif sep == b' ':
                row = self._read_record(fpt)
                self.append(row)
            elif sep == b'*':
                row = self._read_record(fpt)
                self.deleted.append(row)

    def __repr__(self):
        return '%s(%r, encoding=%r)' % (
            self.__class__.__name__,
            self.filename,
            self.encoding)

    #
    # Context manager
    # Todo: why is this a context manager?
    #
    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        pass
<commit_msg>DBF is no longer a context manager.<commit_after>"""
Class to read DBF files.
"""

import os
import datetime
import collections

from .struct_parser import StructParser
from .field_parser import FieldParser
from .common import parse_string
from .ifiles import ifind
from .fpt import FPT

DBFHeader = StructParser(
    'DBFHeader',
    '<BBBBLHHHBBLLLBBH',
    ['dbversion',
     'year',
     'month',
     'day',
     'numrecords',
     'headerlen',
     'recordlen',
     'reserved1',
     'incomplete_transaction',
     'encryption_flag',
     'free_record_thread',
     'reserved2',
     'reserved3',
     'mdx_flag',
     'language_driver',
     'reserved4',
     ])

DBFField = StructParser(
    'DBFField',
    '<11scLBBHBBBB7sB',
    ['name',
     'type',
     'address',
     'length',
     'decimal_count',
     'reserved1',
     'workarea_id',
     'reserved2',
     'reserved3',
     'set_fields_flag',
     'reserved4',
     'index_field_flag',
     ])

FieldValue = collections.namedtuple('Field', 'name value')

def expand_year(year):
    """
    Convert 2-digit year to 4-digit year.
    """

    if year < 80:
        return 2000 + year
    else:
        return 1900 + year

class DBF(list):
    """
    Class to read DBF files.
    """

    def __init__(self, filename,
                 encoding='latin1',  # Todo: is this a good default?
                 raw=False,
                 ignorecase=True,
                 lowernames=False,
                 parserclass=FieldParser,
                 recfactory=dict,
                 peek=False):

        self.encoding = encoding
        self.recfactory = recfactory
        self.raw = raw
        self.ignorecase = ignorecase
        self.lowernames = lowernames
        self.parserclass = parserclass

        self._field_parser = self.parserclass(self.encoding)

        # Name part before .dbf is the table name
        self.name = os.path.basename(filename)
        self.name = os.path.splitext(self.name)[0]
        self.name = self.name.lower()

        if ignorecase:
            self.filename = ifind(filename)
        else:
            self.filename = filename

        # Filled in by self._read_headers()
        self.memofilename = None
        self.header = None
        self.fields = []       # namedtuples
        self.field_names = []  # strings

        with open(self.filename, mode='rb') as self.file:
            self._read_headers()
            self._check_headers()

            self.date = datetime.date(expand_year(self.header.year),
                                      self.header.month,
                                      self.header.day)

            self.deleted = []

            if not peek:
                self._load()

        del self.file

    def _read_headers(self):
        #
        # Todo: more checks
        # http://www.clicketyclick.dk/databases/xbase/format/dbf_check.html#CHECK_DBF
        #
        self.header = DBFHeader.read(self.file)

        #
        # Read field headers
        #
        while 1:
            sep = self.file.read(1)
            if sep in (b'\x0d', '\n', ''):
                # End of field headers
                break

            fh = DBFField.read(self.file, prepend=sep)
            # We need to fix the name and type

            fieldname = parse_string(fh.name, self.encoding)
            if self.lowernames:
                fieldname = fieldname.lower()
            fieldtype = parse_string(fh.type, self.encoding)

            fh = fh._replace(name=fieldname,
                             type=fieldtype)

            self.field_names.append(fh.name)

            self.fields.append(fh)

        if len(self.fields) < 1:
            raise ValueError('dbf file must have at least one field: %s' % self.filename)

        # Check for memo file
        field_types = set([f.type for f in self.fields])
        if 'M' in field_types:
            fn = os.path.splitext(self.filename)[0] + '.fpt'
            match = ifind(self.filename, ext='.fpt')
            if match:
                self.memofilename = match
            else:
                # Todo: warn and return field as byte string?
                raise IOError('Missing memo file: %r' % fn)

    def _check_headers(self):
        """Check headers for possible format errors."""

        for field in self.fields:

            if field.type == '0' and field.length != 1:
                    ValueError('Field of type 0 must have length 1 (was %s)' % field.length)

            elif field.type == 'I' and field.length != 4:
                    ValueError('Field type I must have length 4 (was %s)' % field.length)

            elif field.type == 'L' and field.length != 1:
                    ValueError('Field type L must have length 1 (was %s)' % field.length)

            elif not self._field_parser.field_type_supported(field.type):
                # Todo: return as byte string?
                ValueError('Unknown field type: %r' % (field.type))

    def _read_record(self, fpt=None):
        items = []  # List of Field
        for field in self.fields:
            value = self.file.read(field.length)
            if self.raw:
                value = value  # Just return the byte string
            else:
                value = self._field_parser.parse(field, value)

                #
                # Decoding memo fields requires a little more
                # trickery.
                #
                if field.type == 'M':
                    if value == None:
                        value = ''
                    else:
                        fptrecord = fpt[value]
                        if ftprecord.type == 'memo':
                            # Decode to unicode
                            value = parse_string(fptrecord.data, self.encoding)
                        else:
                            # Byte array
                            value = fptrecord.data

            items.append(FieldValue(name=field.name, value=value))

        row = self.recfactory(items)

        return row

    def _load(self):

        #
        # Get memo file
        #
        if self.memofilename and not self.raw:
            fpt = FPT(self.memofilename)
        else:
            fpt = None

        #
        # Skip header
        #
        self.file.seek(self.header.headerlen, 0)

        #
        # Read records
        #
        while 1:
            sep = self.file.read(1)

            if sep == b'':
                break  # End of file reached
            elif sep == b' ':
                row = self._read_record(fpt)
                self.append(row)
            elif sep == b'*':
                row = self._read_record(fpt)
                self.deleted.append(row)

    def __repr__(self):
        return '%s(%r, encoding=%r)' % (
            self.__class__.__name__,
            self.filename,
            self.encoding)
x
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from mysite.gsb.models import Tiers, Titre, Cat, Ope, Banque, Cours, Ib, Exercice, Rapp, Moyen, Echeance, Generalite, Compte_titre, Ope_titre, Compte
from django.contrib import admin
from django.contrib import messages
from django.db import models

def fusion(classe, request, queryset, sens = 'ab'):
    """fonction générique de fusion entre 2 objets"""
    nom_module = queryset[0]._meta.module_name
    if queryset.count() != 2:
        messages.error(request, u"attention, vous devez selectionner 2 %(type)s et uniquement 2, vous en avez selectionné %(n)s" % {'n':queryset.count(), 'type':nom_module})
        return
    a = queryset[0]
    b = queryset[1]
    if type(a) != type(b):
        classe.message_user(request, u"attention vous devez selectionner deux item du meme type")
        return
    try:
        if sens == 'ab':
            message = u"fusion effectuée, dans la type \"%s\", \"%s\" a été fusionnée dans \"%s\"" % (nom_module, a, b)
            a.fusionne(b)
        else:
            message = u"fusion effectuée, dans la type \"%s\", \"%s\" a été fusionnée dans \"%s\"" % (nom_module, b, a)
            b.fusionne(a)
        classe.message_user(request, message)
    except:
        classe.message_user(request, u"probleme")

class Cat_admin(admin.ModelAdmin):
    """classe admin pour les categories"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première catégorie dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde catégorie dans la première"

    list_editable = ('nom',)
    list_display = ('id', 'nom', 'type')
    list_display_links = ('id',)
    list_filter = ('type',)
    radio_fields = {'type':admin.VERTICAL}

class Ib_admin(admin.ModelAdmin):
    """admin pour les ib"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première IB dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde IB dans la première"

    list_editable = ('nom',)
    list_display = ('id', 'nom', 'type')
    list_display_links = ('id',)
    list_filter = ('type',)
    radio_fields = {'type':admin.VERTICAL}

class Compte_admin(admin.ModelAdmin):
    """admin pour les comptes normaux"""
    #actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier compte dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second compte dans le premier"
    fieldsets = [
            (None, {'fields': ('nom', 'type', 'ouvert')}),
            (u'information sur le compte', {'fields': ('banque', 'guichet', 'num_compte', 'cle_compte'), 'classes': ['collapse']}),
            (u'soldes', {'fields': ('solde_init', 'solde_mini_voulu', 'solde_mini_autorise'), 'classes': ['collapse']}),
            (u'moyens par défaut', {'fields': ('moyen_debit_defaut', 'moyen_credit_defaut'), 'classes': ['collapse']}),
            ]
    list_display = ('nom', 'solde', 'type', 'ouvert')
    list_filter = ('type', 'banque', 'ouvert')

class Ope_titre_inline(admin.TabularInline):
    model = Ope_titre
    extra = 1
    readonly_fields = ('invest',)

class Compte_titre_admin(admin.ModelAdmin):
    """compte titre avec inline"""
    #actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier compte_titre dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du premier compte_titre dans le premier"
    fieldsets = [
            (None, {'fields': ('nom', 'type', 'ouvert')}),
            (u'information sur le compte', {'fields': ('banque', 'guichet', 'num_compte', 'cle_compte'), 'classes': ['collapse']}),
            (u'soldes', {'fields': ('solde_init', 'solde_mini_voulu', 'solde_mini_autorise'), 'classes': ['collapse']}),
            (u'moyens par défaut', {'fields': ('moyen_debit_defaut', 'moyen_credit_defaut'), 'classes': ['collapse']})
            ]
    inlines = (Ope_titre_inline,)
    list_display = ('nom', 'solde')
    list_filter = ('type', 'banque', 'ouvert')

class Ope_admin(admin.ModelAdmin):
    """classe de gestion de l'amdmin pour les opes"""
    fieldsets = [
            (None, {'fields': ('compte', 'date', 'montant', 'tiers', 'moyen', 'cat', 'jumelle', 'mere')}),
            (u'informations diverses', {'fields': ('date_val', 'num_cheque', 'notes', 'exercice', 'ib'), 'classes': ['collapse']}),
            (u'pointage', {'fields': ('pointe', 'rapp'), 'classes': ['collapse']}),
            ]
    readonly_fields = ('jumelle', 'mere')
    ordering = ('-date',)
    list_display = ('id', 'compte', 'date', 'montant', 'tiers', 'moyen', 'cat')
    list_filter = ('compte', 'date', 'pointe', 'rapp')
    search_fields = ['tiers__nom']

class Cours_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les  cours des titres """
    list_display = ('date', 'titre', 'valeur')
    list_editable = ('valeur',)
    list_filter = ('date', 'titre')
    ordering = ('-date',)

class Titre_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les titres"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier titre dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second titre dans le premier"
    list_display = ('nom', 'isin', 'last_cours')
    readonly_fields = ('tiers',)
    list_filter = ('type',)
    inlines = (Ope_titre_inline,)
    formfield_overrides = {
        models.TextField: {'widget': admin.widgets.AdminTextInputWidget},
    }
class Moyen_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les moyens de paiements"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier moyen de paiment dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second moyen dans le premier"
    list_filter = ('type',)
    fields = ['type', 'nom']

class Tiers_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les tiers"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier tiers dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second tiers dans le premier"
    list_editable = ('nom', 'notes')
    list_display = ('id', 'nom', 'notes', 'is_titre')
    list_display_links = ('id',)
    list_filter = ('is_titre',)

class Ech_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les écheances d'operations"""
    list_display = ('id', 'compte', 'date', 'montant', 'tiers', 'moyen', 'cat')
    list_filter = ('compte', 'date')
    list_editable = ('date',)

class Banque_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les banques"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première banque dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde banque dans la première"

class Rapp_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les rapprochements"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier rapprochement dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second rapprochement dans le premier"

class Exo_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les exercices"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier exercice dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second exercice dans le premier"

    list_filter = ('date_debut', 'date_fin')

class Gen_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les preferences"""
    pass

admin.site.register(Tiers, Tiers_admin)
admin.site.register(Cat, Cat_admin)
admin.site.register(Compte, Compte_admin)
admin.site.register(Ope, Ope_admin)
admin.site.register(Titre, Titre_admin)
admin.site.register(Banque, Banque_admin)
admin.site.register(Cours, Cours_admin)
admin.site.register(Ib, Ib_admin)
admin.site.register(Exercice, Exo_admin)
admin.site.register(Rapp, Rapp_admin)
admin.site.register(Moyen, Moyen_admin)
admin.site.register(Echeance, Ech_admin)
admin.site.register(Generalite, Gen_admin)
admin.site.register(Compte_titre, Compte_titre_admin)
<commit_msg>admin de ope_titre<commit_after># -*- coding: utf-8 -*-
from mysite.gsb.models import Tiers, Titre, Cat, Ope, Banque, Cours, Ib, Exercice, Rapp, Moyen, Echeance, Generalite, Compte_titre, Ope_titre, Compte
from django.contrib import admin
from django.contrib import messages
from django.db import models

def fusion(classe, request, queryset, sens = 'ab'):
    """fonction générique de fusion entre 2 objets"""
    nom_module = queryset[0]._meta.module_name
    if queryset.count() != 2:
        messages.error(request, u"attention, vous devez selectionner 2 %(type)s et uniquement 2, vous en avez selectionné %(n)s" % {'n':queryset.count(), 'type':nom_module})
        return
    a = queryset[0]
    b = queryset[1]
    if type(a) != type(b):
        classe.message_user(request, u"attention vous devez selectionner deux item du meme type")
        return
    try:
        if sens == 'ab':
            message = u"fusion effectuée, dans la type \"%s\", \"%s\" a été fusionnée dans \"%s\"" % (nom_module, a, b)
            a.fusionne(b)
        else:
            message = u"fusion effectuée, dans la type \"%s\", \"%s\" a été fusionnée dans \"%s\"" % (nom_module, b, a)
            b.fusionne(a)
        classe.message_user(request, message)
    except:
        classe.message_user(request, u"probleme")

class Cat_admin(admin.ModelAdmin):
    """classe admin pour les categories"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première catégorie dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde catégorie dans la première"

    list_editable = ('nom',)
    list_display = ('id', 'nom', 'type')
    list_display_links = ('id',)
    list_filter = ('type',)
    radio_fields = {'type':admin.VERTICAL}

class Ib_admin(admin.ModelAdmin):
    """admin pour les ib"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première IB dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde IB dans la première"

    list_editable = ('nom',)
    list_display = ('id', 'nom', 'type')
    list_display_links = ('id',)
    list_filter = ('type',)
    radio_fields = {'type':admin.VERTICAL}

class Compte_admin(admin.ModelAdmin):
    """admin pour les comptes normaux"""
    #actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier compte dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second compte dans le premier"
    fieldsets = [
            (None, {'fields': ('nom', 'type', 'ouvert')}),
            (u'information sur le compte', {'fields': ('banque', 'guichet', 'num_compte', 'cle_compte'), 'classes': ['collapse']}),
            (u'soldes', {'fields': ('solde_init', 'solde_mini_voulu', 'solde_mini_autorise'), 'classes': ['collapse']}),
            (u'moyens par défaut', {'fields': ('moyen_debit_defaut', 'moyen_credit_defaut'), 'classes': ['collapse']}),
            ]
    list_display = ('nom', 'solde', 'type', 'ouvert')
    list_filter = ('type', 'banque', 'ouvert')

class Compte_titre_admin(admin.ModelAdmin):
    """compte titre avec inline"""
    #actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier compte_titre dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du premier compte_titre dans le premier"
    fieldsets = [
            (None, {'fields': ('nom', 'type', 'ouvert')}),
            (u'information sur le compte', {'fields': ('banque', 'guichet', 'num_compte', 'cle_compte'), 'classes': ['collapse']}),
            (u'soldes', {'fields': ('solde_init', 'solde_mini_voulu', 'solde_mini_autorise'), 'classes': ['collapse']}),
            (u'moyens par défaut', {'fields': ('moyen_debit_defaut', 'moyen_credit_defaut'), 'classes': ['collapse']})
            ]

    list_display = ('nom', 'solde')
    list_filter = ('type', 'banque', 'ouvert')

class Ope_admin(admin.ModelAdmin):
    """classe de gestion de l'amdmin pour les opes"""
    fieldsets = [
            (None, {'fields': ('compte', 'date', 'montant', 'tiers', 'moyen', 'cat', 'jumelle', 'mere')}),
            (u'informations diverses', {'fields': ('date_val', 'num_cheque', 'notes', 'exercice', 'ib'), 'classes': ['collapse']}),
            (u'pointage', {'fields': ('pointe', 'rapp'), 'classes': ['collapse']}),
            ]
    readonly_fields = ('jumelle', 'mere')
    ordering = ('-date',)
    list_display = ('id', 'compte', 'date', 'montant', 'tiers', 'moyen', 'cat')
    list_filter = ('compte', 'date', 'pointe', 'rapp')
    search_fields = ['tiers__nom']

class Cours_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les  cours des titres """
    list_display = ('date', 'titre', 'valeur')
    list_editable = ('valeur',)
    list_filter = ('date', 'titre')
    ordering = ('-date',)

class Titre_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les titres"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier titre dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second titre dans le premier"
    list_display = ('nom', 'isin', 'last_cours')
    readonly_fields = ('tiers',)
    list_filter = ('type',)
    formfield_overrides = {
        models.TextField: {'widget': admin.widgets.AdminTextInputWidget},
    }
class Moyen_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les moyens de paiements"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier moyen de paiment dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second moyen dans le premier"
    list_filter = ('type',)
    fields = ['type', 'nom']

class Tiers_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les tiers"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier tiers dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second tiers dans le premier"
    list_editable = ('nom', 'notes')
    list_display = ('id', 'nom', 'notes', 'is_titre')
    list_display_links = ('id',)
    list_filter = ('is_titre',)

class Ech_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les écheances d'operations"""
    list_display = ('id', 'compte', 'date', 'montant', 'tiers', 'moyen', 'cat')
    list_filter = ('compte', 'date')

class Banque_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les banques"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion de la première banque dans la seconde"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion de la seconde banque dans la première"

class Rapp_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les rapprochements"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier rapprochement dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second rapprochement dans le premier"

class Exo_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les exercices"""
    actions = ['fusionne_a_dans_b', 'fusionne_b_dans_a']
    def fusionne_a_dans_b(self, request, queryset):
        fusion(self, request, queryset, 'ab')
    fusionne_a_dans_b.short_description = u"fusion du premier exercice dans le second"
    def fusionne_b_dans_a(self, request, queryset):
        fusion(self, request, queryset, 'ba')
    fusionne_b_dans_a.short_description = u"fusion du second exercice dans le premier"

    list_filter = ('date_debut', 'date_fin')

class Gen_admin(admin.ModelAdmin):
    """classe de gestion de l'admin pour les preferences"""
    pass

class Ope_titre_admin(admin.ModelAdmin):
    list_display = ('id', 'date', 'compte', 'titre',  'nombre', 'cours','invest')
    readonly_fields = ('invest',)
    list_display_links = ('id',)
    list_filter = ('date', 'compte', 'titre',)

admin.site.register(Tiers, Tiers_admin)
admin.site.register(Cat, Cat_admin)
admin.site.register(Compte, Compte_admin)
admin.site.register(Ope, Ope_admin)
admin.site.register(Titre, Titre_admin)
admin.site.register(Banque, Banque_admin)
admin.site.register(Cours, Cours_admin)
admin.site.register(Ib, Ib_admin)
admin.site.register(Exercice, Exo_admin)
admin.site.register(Rapp, Rapp_admin)
admin.site.register(Moyen, Moyen_admin)
admin.site.register(Echeance, Ech_admin)
admin.site.register(Generalite, Gen_admin)
admin.site.register(Compte_titre, Compte_titre_admin)
admin.site.register(Ope_titre,Ope_titre_admin)
<|endoftext|>


<commit_before>#!/usr/bin/env python
#coding=utf8

"""
This module contains functions used by a Dehacked table entry to filter certain values when reading or writing
them.
"""

import math
import re

def filter_thing_flags_read(value, table):
    """
    Filters a thing's flags value.

    Extended patches can use mnemonics for flag names, separated by plus signs.

    @raise LookupError: if the value contains an unknown mnemonic.
    """

    items = re.split(r"[,+| \t\f\r]+", value)

    if len(items) <= 1 and value.isalpha() == True:
        return value

    out = 0
    for item in items:
        item = item.strip()

        # Find the index of the flag mnemonic and convert it to a flag value.
        flag = table.flags.get(item)
        if flag is None:
            raise LookupError('Ignoring unknown thing flag {}.'.format(item))
        bit = int(math.pow(2, flag['index']))
        out += bit

    return out

def filter_thing_flags_write(value, table):
    """
    Returns a thing flags value as a string of mnemonics.
    """

    bit = 1
    out = []

    for _ in range(0, 32):
        if (value & bit) == 0:
            bit *= 2
            continue

        for key, flag in table.flags.iteritems():
            if int(math.pow(2, flag['index'])) == bit:
                out.append(key)
                break

        bit *= 2

    if len(out) == 0:
        return 0
    else:
        return '+'.join(out)<commit_msg>Fix flag delimiter support from 30ec188.<commit_after>#!/usr/bin/env python
#coding=utf8

"""
This module contains functions used by a Dehacked table entry to filter certain values when reading or writing
them.
"""

import math
import re

def filter_thing_flags_read(value, table):
    """
    Filters a thing's flags value.

    Extended patches can use mnemonics for flag names, separated by plus signs.

    @raise LookupError: if the value contains an unknown mnemonic.
        """

    if value.isdigit() == True:
        return value

    items = re.split(r"[,+| \t\f\r]+", value)
    out = 0

    for item in items:
        item = item.strip()

        # Find the index of the flag mnemonic and convert it to a flag value.
        flag = table.flags.get(item)
        if flag is None:
            raise LookupError('Ignoring unknown thing flag {}.'.format(item))
        bit = int(math.pow(2, flag['index']))
        out += bit

    return out

def filter_thing_flags_write(value, table):
    """
    Returns a thing flags value as a string of mnemonics.
    """

    bit = 1
    out = []

    for _ in range(0, 32):
        if (value & bit) == 0:
            bit *= 2
            continue

        for key, flag in table.flags.iteritems():
            if int(math.pow(2, flag['index'])) == bit:
                out.append(key)
                break

        bit *= 2

    if len(out) == 0:
        return 0
    else:
        return '+'.join(out)<|endoftext|>


<commit_before>#!/bin/env python
# coding=utf8
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import base64
import requests
import json
import urllib
import time
import random
import datetime

# 获得响应头信息中的Content-Type域
def urlOpenGetHeaders(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')
    page = urllib.request.urlopen(req)
    html = page.getheader('Content-Type')
    return html

# 获得url的源码
def urlOpen(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')

    if False:
        proxies = ['110.73.8.151:8123', '110.73.10.78:8123', '36.249.193.19:8118']
        proxy = random.choice(proxies)
        proxy_support = urllib.request.ProxyHandler({'http':proxy})
        opener = urllib.request.build_opener(proxy_support)
        opener.addheaders = [('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')]
        urllib.request.install_opener(opener)
        page = urllib.request.urlopen(url)
    else:
        page = urllib.request.urlopen(req)

    html = page.read()
    return html

# 根据名字、后缀和url下载到本地文件夹
def download(title,post,url):
    filename = title + "." +post
    with open(filename, 'wb') as f:
        music = urlOpen(url)
        f.write(music)

def getPostStr(pKey, song_id):
    rsaKey = RSA.importKey(pKey)
    cipher = Cipher_pkcs1_v1_5.new(rsaKey)
    encry = cipher.encrypt(song_id)
    return base64.b64encode(encry)

# 获取歌曲的实际的url
def getSongRealUrl(songidVal):
    url = 'http://www.aekun.com/api/getMusicbyid/'
    r = requests.post(url, {
        'songid': songidVal
    })
    return r.content

# 将需要的数据写入本地文件
def writeStrToFile(writeStr):
    print(writeStr)
    with open("downurl.txt","a",encoding="UTF-8") as f:
        f.write(writeStr)
        f.write("\n")

# 获取最新的推荐歌曲编号
def getMaxSongs():
    url = "http://www.aekun.com/new/"
    html = urlOpen(url).decode('utf-8')
    a = html.find('
 songIdInt:
                songIdInt = line
    return songIdInt

# 下载歌曲的主程序部分
def downloadMusicMain():
    # 获取pKey
    f = open('public.pem')
    pKey = f.read()
    f.close()

    songIdInt = 3509719
    songIdInt = getNowSongId(songIdInt)
    songIdInt = songIdInt + 1
    maxSong = getMaxSongs()
    print("start from:%s,end with:%s"%(songIdInt,maxSong))
    # 3505251			|10			|2015084685			|▌▌Chillout ▌▌Losing Ground Michael FK & Groundfold  -----3505251.mp3
    while(True):
        if songIdInt > maxSong:
            break

        time.sleep(10)
        try:
            urlOpen("http://www.aekun.com/song/" + str(songIdInt))
        except ConnectionResetError:
            print("Error occur")
        songId = str(songIdInt).encode('utf-8')
        print(songId)
        songidVal = getPostStr(pKey, songId)

        try:
            ret = getSongRealUrl(songidVal)
        except (ConnectionError , ConnectionResetError):
            print("ConnectionError")
            time.sleep(3)
            continue

        ret = ret.decode('utf-8')
        #ret = '{"state":"success","message":"ok","action":null,"data":{"url":"http://us.aekun.com/upload/75AAB77BC2D16123F9F2E8B6C68FCB8E.mp3","song_name":"就算遇到挫折、受到嘲笑，也要勇敢的向前跑！","coll":0,"singername":"小哥","singerpic":"https://m4.aekun.com/user_l_5973822_20170513135220.png"}}'
        print(ret)
        ret = json.loads(ret)
        print(ret)
        status = ret['state']
        if status != 'success':
            print(status)
            break
        downUrl = ret['data']
        if isinstance(downUrl,str):
            if downUrl.strip() == '':
                html = urlOpen("http://www.aekun.com/song/" + str(songIdInt)).decode('utf-8')
                songIdInt = songIdInt + 1
                continue
        elif isinstance(downUrl,dict):
            pass
        else:
            continue

        downUrl = ret['data']['url']
        if downUrl is None:
            continue
        if downUrl.strip() == "":
            continue
        post = downUrl[-3:]
        post = post.lower()
        if post != 'mp3' and post != 'm4a':
            tmp = urlOpenGetHeaders(downUrl)
            if tmp.find('mp3') != -1:
                post = 'mp3'
        songName = ret['data']['song_name']
        writeStr = "%-10s|%-50s|%-5s|%s"%(songIdInt,songName,post,downUrl)
        writeStrToFile(writeStr)
        songIdInt = songIdInt + 1

    now = datetime.datetime.now()
    now = now.strftime('%Y-%m-%d %H:%M:%S')
    writeStrToFile(str(now) + '\t\t\t' + str(maxSong))

if __name__ == '__main__':
    downloadMusicMain()
<commit_msg>modify the download logic<commit_after>#!/bin/env python
# coding=utf8
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import base64
import requests
import json
import urllib
import time
import random
import datetime
import hashlib

# 获得响应头信息中的Content-Type域
def urlOpenGetHeaders(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')
    page = urllib.request.urlopen(req)
    html = page.getheader('Content-Type')
    return html

# 获得url的源码
def urlOpen(url):
    req = urllib.request.Request(url)
    req.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')

    if False:
        proxies = ['110.73.8.151:8123', '110.73.10.78:8123', '36.249.193.19:8118']
        proxy = random.choice(proxies)
        proxy_support = urllib.request.ProxyHandler({'http':proxy})
        opener = urllib.request.build_opener(proxy_support)
        opener.addheaders = [('User-Agent','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')]
        urllib.request.install_opener(opener)
        page = urllib.request.urlopen(url)
    else:
        page = urllib.request.urlopen(req)

    html = page.read()
    return html

# 根据名字、后缀和url下载到本地文件夹
def download(title,post,url):
    filename = title + "." +post
    with open(filename, 'wb') as f:
        music = urlOpen(url)
        f.write(music)

def getPostStr(pKey, song_id):
    rsaKey = RSA.importKey(pKey)
    cipher = Cipher_pkcs1_v1_5.new(rsaKey)
    encry = cipher.encrypt(song_id)
    return base64.b64encode(encry)

# 获取歌曲的实际的url
def getSongRealUrl(songidVal):
    url = 'http://www.aekun.com/api/getMusicbyid/'
    r = requests.post(url, {
        'songid': songidVal
    })
    return r.content

# 将需要的数据写入本地文件
def writeStrToFile(writeStr):
    print(writeStr)
    with open("downurl.txt","a",encoding="UTF-8") as f:
        f.write(writeStr)
        f.write("\n")

# 获取最新的推荐歌曲编号
def getMaxSongs():
    url = "http://www.aekun.com/new/"
    html = urlOpen(url).decode('utf-8')
    a = html.find('
 songIdInt:
                songIdInt = line
    return songIdInt

# 下载歌曲的主程序部分
def downloadMusicMain():
    # 获取pKey
    f = open('public.pem')
    pKey = f.read()
    f.close()

    songIdInt = 3509719
    songIdInt = getNowSongId(songIdInt)
    songIdInt = songIdInt + 1
    maxSong = getMaxSongs()
    print("start from:%s,end with:%s"%(songIdInt,maxSong))
    t = time.time()
    t = int(round(t * 1000))
    print(t)
    m2 = hashlib.md5()
    src = str(songIdInt) + "|" + str(t)
    print(src)
    m2.update(src.encode("utf8"))
    t = m2.hexdigest()
    print(t)
    # 3505251			|10			|2015084685			|▌▌Chillout ▌▌Losing Ground Michael FK & Groundfold  -----3505251.mp3
    while(False):
        if songIdInt > maxSong:
            break

        time.sleep(10)
        try:
            urlOpen("http://www.aekun.com/song/" + str(songIdInt))
        except ConnectionResetError:
            print("Error occur")
        songId = str(songIdInt).encode('utf-8')
        print(songId)
        songidVal = getPostStr(pKey, songId)

        try:
            ret = getSongRealUrl(songidVal)
        except (ConnectionError , ConnectionResetError):
            print("ConnectionError")
            time.sleep(3)
            continue

        ret = ret.decode('utf-8')
        #ret = '{"state":"success","message":"ok","action":null,"data":{"url":"http://us.aekun.com/upload/75AAB77BC2D16123F9F2E8B6C68FCB8E.mp3","song_name":"就算遇到挫折、受到嘲笑，也要勇敢的向前跑！","coll":0,"singername":"小哥","singerpic":"https://m4.aekun.com/user_l_5973822_20170513135220.png"}}'
        print(ret)
        ret = json.loads(ret)
        print(ret)
        status = ret['state']
        if status != 'success':
            print(status)
            break
        downUrl = ret['data']
        if isinstance(downUrl,str):
            if downUrl.strip() == '':
                html = urlOpen("http://www.aekun.com/song/" + str(songIdInt)).decode('utf-8')
                songIdInt = songIdInt + 1
                continue
        elif isinstance(downUrl,dict):
            pass
        else:
            continue

        downUrl = ret['data']['url']
        if downUrl is None:
            continue
        if downUrl.strip() == "":
            continue
        post = downUrl[-3:]
        post = post.lower()
        if post != 'mp3' and post != 'm4a':
            tmp = urlOpenGetHeaders(downUrl)
            if tmp.find('mp3') != -1:
                post = 'mp3'
        songName = ret['data']['song_name']
        writeStr = "%-10s|%-50s|%-5s|%s"%(songIdInt,songName,post,downUrl)
        writeStrToFile(writeStr)
        songIdInt = songIdInt + 1

    now = datetime.datetime.now()
    now = now.strftime('%Y-%m-%d %H:%M:%S')
    writeStrToFile(str(now) + '\t\t\t' + str(maxSong))

if __name__ == '__main__':
    downloadMusicMain()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# tuned-resonator
# experiments with google physical-web mdns broadcast

'''
from google's repo:
The Physical Web is about getting URLs into the physical world.
However, this isn't limited to just Bluetooth Low Energy (BLE) beacons.
mDNS is a service broadcast technique used in Wifi networks.
It has a two advantages over BLE:

Only people logged into your wifi can see the mDNS URLs. This means that in an appartment, your neighbors can't see your devices.
It doesn't have the length restrictions of BLE has so a URL can be along as you'd like (well, at least up to 100 characters).
Below is an example of how to setup a Raspberry Pi to broadcast a Physical Web URL using mDNS. We hope others are willing to contribute and offer more versions.
If so, we'll create an mDNS directory for all the alternatives.

You'll first need a mDNS service on your RPi. Avahi is the one we use here: $ sudo apt-get install avahi-daemon

You'll then place a '.service' file into the /etc/avahi/services directory. Our sample file 'physical-web-url.service' looks like this:

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">http://www.mycompany.com/xyz.html</name>
  <service>
    <host-name>www.mycompany.com</host-name>
    <type>_http._tcp</type>
    <port>80</port>
    <txt-record>path=/xyz.html</txt-record>
  </service>
</service-group>
Then <name> tag must be unique on your network.
We are suggesting that you use the URL as your name to be safe.
That should be it.
If you have the latest client on your phone, the web page http://www.mycompany.com/xyz.html will now show up in your list of nearby devices.
Note: the iOS app supports mDNS, but not the Android app yet.
It will be updated within a few days for Android 5.0 devices.
If people are stuck on older versions, please let us know (or feel free add it yourself ;-)

'''

from lxml import etree
from lxml import objectify
import requests
# import keys
# import feedparser
import json
from subprocess import call
# call("touch tempGrep.txt")
call("cat", "/var/log/remote_aka.log | grep 'trans Host GET' > tempGrep.txt")
# example: d = feedparser.parse('http://feedparser.org/docs/examples/atom10.xml')
# d['feed']['title']

## curriculum example - total number of keywords in last 7200 minutes, ie 5 days
# q = requests.get(keys.url, params=keys.params)
# q.json()
# print q.text

## feedparser example - number of items in some feed
# d = feedparser.parse(keys.feedurl)
# print d['feed']['summary']

'''
02/2015 revisit; this will now attempt to parse logfiles from tinyproxy

copy logfile into local/temp file
wipe logfile so it can be refilled
open tempfile
extract all urls form tempfile
throw away all urls that end in .[png, svg, gif, jpeg, js, ipa, css] - make this case-insensitive
'''
with open('tempGrep.txt') as f:
    content = f.readlines()
    for line in content:
        last = line.split(' ')
        print last[-3] ## this is the URL tinyproxy reports

local_url = '192.168.0.113'
hostname = 'bender.local'

# create XML to update the resonator.service file
# this should update the .service file with recent data but idk what yet
# maybe last three topics or something?
'''
root = objectify.Element('service-group')
t_name = objectify.SubElement(root, 'name')
t_name.attrib['replace-wildcards'] = 'yes'
# t_name._setText('http://akamediasystem.com?total=%s' % a)
t_name._setText('http://192.168.0.113/?state=%s' % a)
t_service = objectify.SubElement(root, 'service')
tt_hostname = objectify.SubElement(t_service, 'host-name')
tt_hostname._setText(hostname)
tt_type = objectify.SubElement(t_service, 'type')
tt_type._setText('_http._tcp')
tt_port = objectify.SubElement(t_service, 'port')
tt_port._setText('80')
tt_txtrecord = objectify.SubElement(t_service, 'txt-record')
tt_txtrecord._setText('path=/?state=%s' % a)
objectify.deannotate(root, cleanup_namespaces=True)
s = '<?xml version="1.0" standalone="no"?><!--*-nxml-*--><!DOCTYPE service-group SYSTEM "avahi-service.dtd">'+etree.tostring(root, pretty_print=True)
# print s
f = open('/etc/avahi/services/resonator-avahi.service', 'w')
f.write(s)
f.close()
'''
# here we could also update the <meta> properties of the local website

<commit_msg>parsing stuff<commit_after>#!/usr/bin/env python
# tuned-resonator
# experiments with google physical-web mdns broadcast

'''
from google's repo:
The Physical Web is about getting URLs into the physical world.
However, this isn't limited to just Bluetooth Low Energy (BLE) beacons.
mDNS is a service broadcast technique used in Wifi networks.
It has a two advantages over BLE:

Only people logged into your wifi can see the mDNS URLs. This means that in an appartment, your neighbors can't see your devices.
It doesn't have the length restrictions of BLE has so a URL can be along as you'd like (well, at least up to 100 characters).
Below is an example of how to setup a Raspberry Pi to broadcast a Physical Web URL using mDNS. We hope others are willing to contribute and offer more versions.
If so, we'll create an mDNS directory for all the alternatives.

You'll first need a mDNS service on your RPi. Avahi is the one we use here: $ sudo apt-get install avahi-daemon

You'll then place a '.service' file into the /etc/avahi/services directory. Our sample file 'physical-web-url.service' looks like this:

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">http://www.mycompany.com/xyz.html</name>
  <service>
    <host-name>www.mycompany.com</host-name>
    <type>_http._tcp</type>
    <port>80</port>
    <txt-record>path=/xyz.html</txt-record>
  </service>
</service-group>
Then <name> tag must be unique on your network.
We are suggesting that you use the URL as your name to be safe.
That should be it.
If you have the latest client on your phone, the web page http://www.mycompany.com/xyz.html will now show up in your list of nearby devices.
Note: the iOS app supports mDNS, but not the Android app yet.
It will be updated within a few days for Android 5.0 devices.
If people are stuck on older versions, please let us know (or feel free add it yourself ;-)

'''

from lxml import etree
from lxml import objectify
import requests
# import keys
# import feedparser
import json
from subprocess import call
# call("touch tempGrep.txt")
# call("cat", "/var/log/remote_aka.log | grep 'trans Host GET' > tempGrep.txt")
os.system("cat /var/log/remote_aka.log | grep 'trans Host GET' > tempGrep.txt")
# example: d = feedparser.parse('http://feedparser.org/docs/examples/atom10.xml')
# d['feed']['title']

## curriculum example - total number of keywords in last 7200 minutes, ie 5 days
# q = requests.get(keys.url, params=keys.params)
# q.json()
# print q.text

## feedparser example - number of items in some feed
# d = feedparser.parse(keys.feedurl)
# print d['feed']['summary']

'''
02/2015 revisit; this will now attempt to parse logfiles from tinyproxy

copy logfile into local/temp file
wipe logfile so it can be refilled
open tempfile
extract all urls form tempfile
throw away all urls that end in .[png, svg, gif, jpeg, js, ipa, css] - make this case-insensitive
'''
with open('tempGrep.txt') as f:
    content = f.readlines()
    for line in content:
        last = line.split(' ')
        print last[-3] ## this is the URL tinyproxy reports

local_url = '192.168.0.113'
hostname = 'bender.local'

# create XML to update the resonator.service file
# this should update the .service file with recent data but idk what yet
# maybe last three topics or something?
'''
root = objectify.Element('service-group')
t_name = objectify.SubElement(root, 'name')
t_name.attrib['replace-wildcards'] = 'yes'
# t_name._setText('http://akamediasystem.com?total=%s' % a)
t_name._setText('http://192.168.0.113/?state=%s' % a)
t_service = objectify.SubElement(root, 'service')
tt_hostname = objectify.SubElement(t_service, 'host-name')
tt_hostname._setText(hostname)
tt_type = objectify.SubElement(t_service, 'type')
tt_type._setText('_http._tcp')
tt_port = objectify.SubElement(t_service, 'port')
tt_port._setText('80')
tt_txtrecord = objectify.SubElement(t_service, 'txt-record')
tt_txtrecord._setText('path=/?state=%s' % a)
objectify.deannotate(root, cleanup_namespaces=True)
s = '<?xml version="1.0" standalone="no"?><!--*-nxml-*--><!DOCTYPE service-group SYSTEM "avahi-service.dtd">'+etree.tostring(root, pretty_print=True)
# print s
f = open('/etc/avahi/services/resonator-avahi.service', 'w')
f.write(s)
f.close()
'''
# here we could also update the <meta> properties of the local website

<|endoftext|>


<commit_before>from django.conf import settings
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import HttpRequest
from django.test import TestCase
try:
    import json
except ImportError:
    import simplejson as json

class ViewsWithoutSlashesTestCase(TestCase):
    urls = 'slashless.api.urls'

    def setUp(self):
        super(ViewsWithoutSlashesTestCase, self).setUp()
        self.old_debug = settings.DEBUG
        settings.DEBUG = True

    def tearDown(self):
        settings.DEBUG = self.old_debug
        super(ViewsWithoutSlashesTestCase, self).tearDown()

    def test_gets_without_trailing_slash(self):
        resp = self.client.get('/api/v1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 2)
        self.assertEqual(deserialized['notes'], {'list_endpoint': '/api/v1/notes', 'schema': '/api/v1/notes/schema'})

        resp = self.client.get('/api/v1/notes', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 2)
        self.assertEqual(deserialized['meta']['limit'], 20)
        self.assertEqual(len(deserialized['objects']), 2)
        self.assertEqual([obj['title'] for obj in deserialized['objects']], [u'First Post!', u'Another Post'])

        resp = self.client.get('/api/v1/notes/1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 9)
        self.assertEqual(deserialized['title'], u'First Post!')

        # Due to the way Django parses URLs, ``get_multiple`` won't work without
        # a trailing slash. This will cause the ``get_detail`` to match
        # instead, resulting in a 500.
        resp = self.client.get('/api/v1/notes/set/2;1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 404)
        self.assertEqual(json.loads(resp.content)["error_message"], "Invalid resource lookup data provided (mismatched type).")
<commit_msg>Removed an error-prone test that gives inconsistent results across versions of Django.<commit_after>from django.conf import settings
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import HttpRequest
from django.test import TestCase
try:
    import json
except ImportError:
    import simplejson as json

class ViewsWithoutSlashesTestCase(TestCase):
    urls = 'slashless.api.urls'

    def setUp(self):
        super(ViewsWithoutSlashesTestCase, self).setUp()
        self.old_debug = settings.DEBUG
        settings.DEBUG = True

    def tearDown(self):
        settings.DEBUG = self.old_debug
        super(ViewsWithoutSlashesTestCase, self).tearDown()

    def test_gets_without_trailing_slash(self):
        resp = self.client.get('/api/v1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 2)
        self.assertEqual(deserialized['notes'], {'list_endpoint': '/api/v1/notes', 'schema': '/api/v1/notes/schema'})

        resp = self.client.get('/api/v1/notes', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 2)
        self.assertEqual(deserialized['meta']['limit'], 20)
        self.assertEqual(len(deserialized['objects']), 2)
        self.assertEqual([obj['title'] for obj in deserialized['objects']], [u'First Post!', u'Another Post'])

        resp = self.client.get('/api/v1/notes/1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 200)
        deserialized = json.loads(resp.content)
        self.assertEqual(len(deserialized), 9)
        self.assertEqual(deserialized['title'], u'First Post!')

        # Due to the way Django parses URLs, ``get_multiple`` won't work without
        # a trailing slash. This will cause the ``get_detail`` to match
        # instead, resulting in a 500.
        resp = self.client.get('/api/v1/notes/set/2;1', data={'format': 'json'})
        self.assertEqual(resp.status_code, 404)
        # This behavior is inconsistent across versions of Django. 1.3+ doesn't
        # seem to cause this error to be available.
        # self.assertEqual(json.loads(resp.content)["error_message"], "Invalid resource lookup data provided (mismatched type).")
<|endoftext|>


<commit_before>import sys
import datetime
import json
import logging
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from json.decoder import JSONDecodeError
from django.core.management.base import BaseCommand
from backend.api_v2.models import Click
from backend.api_v2.models import Event
from backend.api_v2.models import Trial
from backend.api_v2.models import Survey
from backend.logger.models import HTTPRequest

logging.basicConfig(
    level=logging.ERROR,
    format='%(message)s',
    filename='error.log',
)

log = logging.getLogger(__name__)

def decode_json(obj):
    for key, value in obj.items():
        if 'datetime' in key:
            obj[key] = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%fZ').replace(tzinfo=datetime.timezone.utc)
        elif key == 'colors':
            obj[key] = ','.join(value)
    return obj

def get_data(request):
    try:
        return json.loads(request, object_hook=decode_json)
    except JSONDecodeError:
        print(f'JSON decode error: {data.sha1}')
        sys.exit(1)

def save_data(http_request_sha1, trial, survey, clicks, events):
    try:
        trial = Trial.objects.create(http_request_sha1=http_request_sha1, **trial)

        if survey:
            Survey.objects.create(trial=trial, **survey)

        for click in clicks:
            Click.objects.create(trial=trial, **click)

        for event in events:
            Event.objects.create(trial=trial, **event)

        trial.validate()
        trial.calculate()

        Click.objects.filter(trial=trial).delete()
        Event.objects.filter(trial=trial).delete()

    except IntegrityError as e:
        out = f'{http_request_sha1} IntegrityError: {e}'
        log.warning(out)

    except ValidationError as e:
        out = f'{http_request_sha1} ValidationError: {e}'
        print(out)
        log.error(out)

    except ValueError as e:
        out = f'{http_request_sha1} ValueError: {e}'
        print(out)
        log.error(out)

def clean():
    Survey.objects.all().delete()
    Click.objects.all().delete()
    Event.objects.all().delete()
    Trial.objects.all().delete()

class Command(BaseCommand):
    help = 'Recalculate whole database.'

    def handle(self, *args, **options):

        with open('error.log') as file:
            errors = [line.replace('\n', '') for line in file]

            print(errors)
        return

        # for request in HTTPRequest.objects.all():
        for request in HTTPRequest.objects.filter(sha1__in=errors):
            data = get_data(request.data)
            save_data(
                http_request_sha1=request.sha1,
                trial=data.get('trial', None),
                survey=data.get('survey', None),
                clicks=data.get('clicks'),
                events=data.get('events'),
            )
<commit_msg>Fixes #time 1m<commit_after>import sys
import datetime
import json
import logging
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from json.decoder import JSONDecodeError
from django.core.management.base import BaseCommand
from backend.api_v2.models import Click
from backend.api_v2.models import Event
from backend.api_v2.models import Trial
from backend.api_v2.models import Survey
from backend.logger.models import HTTPRequest

logging.basicConfig(
    level=logging.ERROR,
    format='%(message)s',
    filename='error.log',
)

log = logging.getLogger(__name__)

def decode_json(obj):
    for key, value in obj.items():
        if 'datetime' in key:
            obj[key] = datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%fZ').replace(tzinfo=datetime.timezone.utc)
        elif key == 'colors':
            obj[key] = ','.join(value)
    return obj

def get_data(request):
    try:
        return json.loads(request, object_hook=decode_json)
    except JSONDecodeError:
        print(f'JSON decode error: {data.sha1}')
        sys.exit(1)

def save_data(http_request_sha1, trial, survey, clicks, events):
    try:
        trial = Trial.objects.create(http_request_sha1=http_request_sha1, **trial)

        if survey:
            Survey.objects.create(trial=trial, **survey)

        for click in clicks:
            Click.objects.create(trial=trial, **click)

        for event in events:
            Event.objects.create(trial=trial, **event)

        trial.validate()
        trial.calculate()

        Click.objects.filter(trial=trial).delete()
        Event.objects.filter(trial=trial).delete()

    except IntegrityError as e:
        out = f'{http_request_sha1} IntegrityError: {e}'
        log.warning(out)

    except ValidationError as e:
        out = f'{http_request_sha1} ValidationError: {e}'
        print(out)
        log.error(out)

    except ValueError as e:
        out = f'{http_request_sha1} ValueError: {e}'
        print(out)
        log.error(out)

def clean():
    Survey.objects.all().delete()
    Click.objects.all().delete()
    Event.objects.all().delete()
    Trial.objects.all().delete()

class Command(BaseCommand):
    help = 'Recalculate whole database.'

    def handle(self, *args, **options):

        with open('error.log') as file:
            errors = [line.replace('\n', '') for line in file]

        # for request in HTTPRequest.objects.all():
        for request in HTTPRequest.objects.filter(sha1__in=errors):
            data = get_data(request.data)
            save_data(
                http_request_sha1=request.sha1,
                trial=data.get('trial', None),
                survey=data.get('survey', None),
                clicks=data.get('clicks'),
                events=data.get('events'),
            )
<|endoftext|>


<commit_before># Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Aragorn(Package):
    """ARAGORN, a program to detect tRNA genes and tmRNA genes in nucleotide
    sequences."""

    homepage = "http://mbio-serv2.mbioekol.lu.se/ARAGORN"
    url      = "http://mbio-serv2.mbioekol.lu.se/ARAGORN/Downloads/aragorn1.2.38.tgz"

    version('1.2.38', '1df0ed600069e6f520e5cd989de1eaf0')

    phases = ['build', 'install']

    def build(self, spec, prefix):
        cc = Executable(spack_cc)
        cc('-O3', '-ffast-math', '-finline-functions',
           '-oaragorn', 'aragorn' + format(spec.version.dotted) + '.c')

    def install(self, spec, prefix):
        mkdirp(prefix.bin)
        install('aragorn', prefix.bin)
<commit_msg>aragorn: add version 1.2.36 (#9817)<commit_after># Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Aragorn(Package):
    """ARAGORN, a program to detect tRNA genes and tmRNA genes in nucleotide
    sequences."""

    homepage = "http://mbio-serv2.mbioekol.lu.se/ARAGORN"
    url      = "http://mbio-serv2.mbioekol.lu.se/ARAGORN/Downloads/aragorn1.2.38.tgz"

    version('1.2.38', '1df0ed600069e6f520e5cd989de1eaf0')
    version('1.2.36', 'ab06032589e45aa002f8616333568e9ab11034b3a675f922421e5f1c3e95e7b5')

    phases = ['build', 'install']

    def build(self, spec, prefix):
        cc = Executable(spack_cc)
        cc('-O3', '-ffast-math', '-finline-functions',
           '-oaragorn', 'aragorn' + format(spec.version.dotted) + '.c')

    def install(self, spec, prefix):
        mkdirp(prefix.bin)
        install('aragorn', prefix.bin)
<|endoftext|>


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

from . import handlers
from . import uimodules
from .util import rooted_path
import firenado.tornadoweb

class DDOSSOComponent(firenado.tornadoweb.TornadoComponent):

    def get_handlers(self):
        self.conf['social']['enabled'] = False
        if (self.conf['social']['facebook']['enabled'] or
                self.conf['social']['google']['enabled'] or
                self.conf['social']['twitter']['enabled']):
            self.conf['social']['enabled'] = True
        root = self.conf['root']
        return [
            (r"%s" % rooted_path(root, "/"), handlers.IndexHandler),
            (r"%s" % rooted_path(root, "/captcha/(.*)"), handlers.CaptchaHandler),
            (r"%s" % rooted_path(root, "/sign_in"), handlers.SgninHandler),
            (r"%s" % rooted_path(root, "/sign_up"), handlers.SignupHandler),
            (r"%s" % rooted_path(root, "google/sign_up"),
             handlers.GoogleSignupHandler),
            (r"%s" % rooted_path(root, "google/oauth2callback"),
             handlers.GoogleLoginHandler),
            (r"%s" % rooted_path(root, "discourse/sign_on"),
             handlers.DiscourseSSOHandler),
            (r"%s" % rooted_path(root, "discourse/login"),
             handlers.LoginHandler),
        ]

    def get_ui_modules(self):
        return uimodules

    def get_config_file(self):
        return "ddosso"

    def install(self):
        from sqlalchemy import text
        from firenado.util.sqlalchemy_util import Base
        from .diaspora.models import DddossoUserBase
        print('Installing DDOSSO...')
        print('Creating DDOSSO users table ...')
        engine = self.application.get_data_source(
            'diaspora').engine
        engine.echo = False
        # Dropping all
        # TODO Not to drop all if something is installed right?

        DddossoUserBase.__table__.drop(engine, checkfirst=True)
        # Creating database
        DddossoUserBase.__table__.create(engine)
        engine.dispose()
<commit_msg>Added profile and social handlers.<commit_after>#!/usr/bin/env python
#
# Copyright 2016 Flavio Garcia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from . import handlers
from . import uimodules
from .util import rooted_path
import firenado.tornadoweb

class DDOSSOComponent(firenado.tornadoweb.TornadoComponent):

    def get_handlers(self):
        self.conf['social']['enabled'] = False
        if (self.conf['social']['facebook']['enabled'] or
                self.conf['social']['google']['enabled'] or
                self.conf['social']['twitter']['enabled']):
            self.conf['social']['enabled'] = True
        root = self.conf['root']
        return [
            (r"%s" % rooted_path(root, "/"), handlers.IndexHandler),
            (r"%s" % rooted_path(root, "/captcha/(.*)"),
             handlers.CaptchaHandler),
            (r"%s" % rooted_path(root, "/profile"), handlers.ProfileHandler),
            (r"%s" % rooted_path(root, "/sign_in"), handlers.SigninHandler),
            (r"%s" % rooted_path(root, "/sign_up"), handlers.SignupHandler),
            (r"%s" % rooted_path(root, "/sign_up/social"),
             handlers.SignupSocialHandler),
            (r"%s" % rooted_path(root, "google/sign_up"),
             handlers.GoogleSignupHandler),
            (r"%s" % rooted_path(root, "google/oauth2callback"),
             handlers.GoogleLoginHandler),
            (r"%s" % rooted_path(root, "discourse/sign_on"),
             handlers.DiscourseSSOHandler),
            (r"%s" % rooted_path(root, "discourse/login"),
             handlers.LoginHandler),
        ]

    def get_ui_modules(self):
        return uimodules

    def get_config_file(self):
        return "ddosso"

    def install(self):
        from sqlalchemy import text
        from firenado.util.sqlalchemy_util import Base
        from .diaspora.models import DddossoUserBase
        print('Installing DDOSSO...')
        print('Creating DDOSSO users table ...')
        engine = self.application.get_data_source(
            'diaspora').engine
        engine.echo = False
        # Dropping all
        # TODO Not to drop all if something is installed right?

        DddossoUserBase.__table__.drop(engine, checkfirst=True)
        # Creating database
        DddossoUserBase.__table__.create(engine)
        engine.dispose()
<|endoftext|>


<commit_before>##############################################################################
#
#    Copyright (C) 2019 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Christopher Meier <dev@c-meier.ch>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
import yaml
import logging

from odoo import api, fields, models
from odoo.tools import html2plaintext

_logger = logging.getLogger(__name__)

class CrmWordpressRequest(models.Model):
    _inherit = "crm.claim"

    front_matter = fields.Text()

    # -------------------------------------------------------
    # Mail gateway
    # -------------------------------------------------------

    # Parse the new message to check if it comes from Wordpress and if so parse
    # it and fill the new object.
    @api.multi
    def message_new(self, msg, custom_values=None):
        if custom_values is None:
            custom_values = {}
        defaults = {}

        # Read YAML front matter
        yaml_delim = "---" + "\n"
        desc = html2plaintext(msg.get("body")) if msg.get("body") else ""
        if desc.startswith(yaml_delim):
            parts = desc[len(yaml_delim):].split("\n" + yaml_delim, 1)

            if len(parts) == 2:  # Does contain a front matter.
                defaults["front_matter"] = parts[0]
                desc = parts[1]
                try:
                    front_matter = yaml.load(parts[0])
                except yaml.YAMLError:
                    _logger.warning("Could not parse the front matter.", exc_info=True)
                else:
                    self._parse_front_matter(front_matter, defaults)
            defaults["description"] = "
{}
".format(desc)

        defaults.update(custom_values)

        return super().message_new(msg, custom_values=defaults)

    def _parse_front_matter(self, fm, values):
        # Match the partner
        match_obj = self.env["res.partner.match.wp"]

        if "title" in fm:
            fm["title"] = match_obj.match_title(fm["title"])

        if "lang" in fm:
            fm["lang"] = match_obj.match_lang(fm["lang"])

        partner = match_obj.match_partner_to_infos(fm, options={"skip_create": True})
        values["partner_id"] = partner.id

        # TODO CO-3280 This won't work as crm.claim.type is no more used in v12
        if "claim_type" in fm:
            type_name = fm["claim_type"]
            type_obj = self.env["crm.claim.type"]
            ct = type_obj.search([("name", "=ilike", type_name)], limit=1)
            if ct:
                values["claim_type"] = ct.id
<commit_msg>CO-3280 Delete using of claim_type, since it's not usefull anymore<commit_after>##############################################################################
#
#    Copyright (C) 2019 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: Christopher Meier <dev@c-meier.ch>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
import yaml
import logging

from odoo import api, fields, models
from odoo.tools import html2plaintext

_logger = logging.getLogger(__name__)

class CrmWordpressRequest(models.Model):
    _inherit = "crm.claim"

    front_matter = fields.Text()

    # -------------------------------------------------------
    # Mail gateway
    # -------------------------------------------------------

    # Parse the new message to check if it comes from Wordpress and if so parse
    # it and fill the new object.
    @api.multi
    def message_new(self, msg, custom_values=None):
        if custom_values is None:
            custom_values = {}
        defaults = {}

        # Read YAML front matter
        yaml_delim = "---" + "\n"
        desc = html2plaintext(msg.get("body")) if msg.get("body") else ""
        if desc.startswith(yaml_delim):
            parts = desc[len(yaml_delim):].split("\n" + yaml_delim, 1)

            if len(parts) == 2:  # Does contain a front matter.
                defaults["front_matter"] = parts[0]
                desc = parts[1]
                try:
                    front_matter = yaml.load(parts[0])
                except yaml.YAMLError:
                    _logger.warning("Could not parse the front matter.", exc_info=True)
                else:
                    self._parse_front_matter(front_matter, defaults)
            defaults["description"] = "
{}
".format(desc)

        defaults.update(custom_values)

        return super().message_new(msg, custom_values=defaults)

    def _parse_front_matter(self, fm, values):
        # Match the partner
        match_obj = self.env["res.partner.match.wp"]

        if "title" in fm:
            fm["title"] = match_obj.match_title(fm["title"])

        if "lang" in fm:
            fm["lang"] = match_obj.match_lang(fm["lang"])

        partner = match_obj.match_partner_to_infos(fm, options={"skip_create": True})
        values["partner_id"] = partner.id
<|endoftext|>