class Media(BaseModel):
    # base table containing all media entries
    title = peewee.CharField(unique=True)
    alt_title = peewee.CharField(null=True)
    series = peewee.ForeignKeyField(Series, backref='sequels', null=True)
    order = peewee.DecimalField(
        max_digits=2, null=True
    )  # the story's chronological order ex: Star Wars Ep. 1, 2, 3, 4, 5, 6 | NOT 4, 5, 6, 1, 2, 3
    media_type = peewee.ForeignKeyField(
        MediaTypes, backref='media')  # movie | tv show | etc
    animated = peewee.BooleanField()
    country = peewee.ForeignKeyField(Countries,
                                     backref='media')  # USA | UK | Japan | etc
    language = peewee.ManyToManyField(Languages, backref='media')
    subtitles = peewee.BooleanField(null=True)
    year = peewee.IntegerField(constraints=[peewee.Check('year > 1900')],
                               null=True)  # release year
    genres = peewee.ManyToManyField(Genres, backref='media')
    director = peewee.ForeignKeyField(Directors, backref='media', null=True)
    studio = peewee.ForeignKeyField(Studios, backref='media', null=True)
    actors = peewee.ManyToManyField(
        Actors, backref='media')  # ManyToManyField does not support null=True
    plot = peewee.CharField(null=True)
    rating = peewee.IntegerField(constraints=[
        peewee.Check('rating >= 1 AND rating <=10')
    ],
                                 null=True)  # 1 to 10
    tags = peewee.ManyToManyField(
        Tags, backref='media')  # ManyToManyField does not support null=True
    notes = peewee.CharField(null=True)
Exemple #2
0
class Tag(peewee.Model):
    tagname = peewee.CharField()
    names = peewee.ManyToManyField(Name, backref="tags")

    class Meta:
        database = db
        db_table = "tags"  # file name to path,no repeat
Exemple #3
0
    def ready(self):
        models = [
            model for model in django.apps.apps.get_models()
            if not model._meta.proxy
        ]

        # resolve simple fields, bind "pw" field to django model
        for model in models:
            inner = self.get_peewee_class_inner(model)
            inner['django_model'] = model
            model.pw = type(self.get_klass_name(model), (ProxyModel, ), inner)
            self.PEEWEE_MODELS_CACHE[model] = model.pw

        # resolve deferred foreign keys, we use DeferredForeignKey, to avoid cycle foreign keys
        for model in models:
            DeferredForeignKey.resolve(model.pw)

        # resolve many_to_many fields
        for model in models:
            meta = model._meta
            for field in meta.many_to_many:
                peewee_model = self.PEEWEE_MODELS_CACHE[model]
                through_model = self.get_many_to_many_model(
                    getattr(model, field.column))
                peewee_model._meta.add_field(
                    field.column,
                    peewee.ManyToManyField(
                        self.PEEWEE_MODELS_CACHE[field.related_model],
                        through_model=through_model))

        self.patch_database_required_functions()
Exemple #4
0
class Note(BaseModel):
    model = pv.ForeignKeyField(Model, backref='notes')
    data = sqlite_ext.JSONField()              # format = dict()
    constraint = ConstraintField(unique=True)  # format = list()
    _tags = pv.ManyToManyField(Tag, backref='notes')

    created = pv.DateTimeField(constraints=[pv.SQL('DEFAULT CURRENT_TIMESTAMP')])
    modified = pv.DateTimeField(constraints=[pv.SQL('DEFAULT CURRENT_TIMESTAMP')])

    info = sqlite_ext.JSONField(default=dict)

    def to_dict(self):
        return super(Note, self).to_dict(manytomany=False, backrefs=False,
                                         exclude=['_tags'], extra_attrs=['tags'])

    @property
    def tags(self):
        return [t.name for t in self._tags]

    def mark(self, tag='marked'):
        Tag.get_or_create(name=tag)[0].notes.add(self)

    add_tag = mark

    def unmark(self, tag='marked'):
        Tag.get_or_create(name=tag)[0].notes.remove(self)

    remove_tag = unmark
Exemple #5
0
class Note(components.BaseDocumentModel):
    title = peewee.TextField()
    content = peewee.TextField()
    is_archived = peewee.BooleanField(default=False)
    is_pinned = peewee.BooleanField(default=False)
    tags = peewee.ManyToManyField(Tag)
    category = peewee.ForeignKeyField(Category, null=True, default=None, backref="notes")
    due_date = peewee.DateTimeField(null=True, default=None, formats=["%s", "%Y-%m-%d"])
Exemple #6
0
class Dish(peewee.Model):
    name = peewee.CharField()
    served_at = peewee.ForeignKeyField(Restaurant)
    price_in_cents = peewee.IntegerField()
    ingredients = peewee.ManyToManyField(Ingredient)

    class Meta:
        database = db
Exemple #7
0
class Milestone(components.BaseDocumentModel):
    name = peewee.TextField()
    description = peewee.TextField()
    due_date = peewee.DateTimeField(null=True,
                                    default=None,
                                    formats=["%s", "%Y-%m-%d"])
    tags = peewee.ManyToManyField(Tag)
    category = peewee.ForeignKeyField(Category, null=True, default=None)
    pass
Exemple #8
0
class Chat(peewee.Model):

    name = peewee.CharField(max_length=20, unique=True)
    users = peewee.ManyToManyField(User, backref="users_list")
    admin = peewee.ForeignKeyField(User, backref="chats")

    class Meta:
        database = db
        table_name = "chats"
Exemple #9
0
class Page(BaseModel):
    """Страница"""
    name = peewee.CharField(max_length=200)
    slug = peewee.CharField(unique=True)
    sequence = peewee.IntegerField()
    blocks = peewee.ManyToManyField(Block, backref='pages')

    class Meta:
        db_table = 'page'
Exemple #10
0
class Clase(pwe.Model):
    class Meta:
        database = psql_db
        table_name = 'clases'

    id_clase = pwe.AutoField()
    nombre = pwe.CharField(max_length=100, null=False)
    horario = pwe.CharField(max_length=100, null=False)
    alumnos = pwe.ManyToManyField(model=Alumno,
                                  backref="clases",
                                  through_model=deferred_alumno_clase)
Exemple #11
0
class OzonProduct(peewee.Model):
    id = peewee.AutoField()
    url = peewee.TextField()
    price = peewee.TextField()
    title = peewee.TextField()
    images = peewee.TextField()

    categories = peewee.ManyToManyField(OzonCategory, backref='goods')

    class Meta:
        database = psql_db
        db_table = "vasiliy_vanchuk__ozon_product"
 class User(BaseModel):
     class Meta:
         table_name = "users"
     name = peewee.TextField(null=False, unique=True)
     password = peewee.TextField(null=False)
     display_name = peewee.TextField(null=True)
     created = peewee.DateTimeField(null=False, default=datetime.now, formats=["%s"])
     edited = peewee.DateTimeField(null=False, default=datetime.now, index=True, formats=["%s"])
     user_ref_id = peewee.UUIDField(null=False, unique=True, index=True, default=uuid4)
     is_deleted = peewee.BooleanField(null=False, default=False)
     is_active = peewee.BooleanField(null=False, default=False)
     permissions = peewee.ManyToManyField(Role, backref="users")
Exemple #13
0
class Post(BaseModel):
    post_id = pw.TextField(index=True)
    image_uri = pw.TextField()
    description = pw.TextField()
    comments = pw.ManyToManyField(Comment, backref="post")
    date = pw.DateTimeField(default=datetime.datetime.now)
    hashtags = pw.TextField(default="")
    mentions = pw.TextField(default="")
    likes = pw.IntegerField(default=0)
    relevance = pw.FloatField(default=0.0)
    sentiment = pw.FloatField(default=0.0)
    comments_sentiment = pw.FloatField(default=0.0)
    comments_count = pw.IntegerField(default=0)
Exemple #14
0
class Message(database.db.basemodel):
    user = peewee.ForeignKeyField(User, related_name='messages')
    #message = AESEncryptedField(conf.get_config("taemin").get("aes_password", "banane").encode("utf-8"))
    message = peewee.TextField()
    key = peewee.TextField(null=True)
    value = peewee.TextField(null=True)
    target = peewee.TextField(null=True)
    chan = peewee.ForeignKeyField(Chan, related_name='messages', null=True)
    link = peewee.ForeignKeyField(Link,
                                  related_name='messages',
                                  null=True,
                                  on_delete='SET NULL')
    highlights = peewee.ManyToManyField(User, backref='hl')

    created_at = peewee.DateTimeField(default=datetime.datetime.now)
Exemple #15
0
class Model(BaseModel):
    name = pv.TextField(unique=True)
    css = pv.TextField(default='')
    js = pv.TextField(default='')
    fonts = pv.ManyToManyField(Media, backref='models')
    # templates

    @classmethod
    def clean(cls):
        i = 0
        for db_model in cls.select():
            if not db_model.templates:
                i += 1
                db_model.delete_instance()

        return i

    @classmethod
    def add(cls, name, templates, css='', js=''):
        """

        :param name:
        :param list templates: list of dict or list of TemplateMaker
        :param css:
        :param js:
        :return:
        """
        with database.atomic():
            db_model = cls.create(name=name, css=css, js=js)
            for template in templates:
                Template.create(
                    model_id=db_model.id,
                    name=template['name'],
                    question=template['question'],
                    answer=template['answer']
                )

        return db_model

    def __repr__(self):
        return f'<Model: "{self.name}">'

    def to_viewer(self):
        d = model_to_dict(self)
        d['fonts'] = [repr(f) for f in self.fonts]
        d['templates'] = [t.name for t in self.templates]

        return d
Exemple #16
0
class Roles(BaseModel):
    title = peewee.CharField(max_length=32, verbose_name="角色名")
    permission = peewee.ManyToManyField(Permissions,
                                        backref="role_permission",
                                        on_delete="CASCADE")

    @classmethod
    def newData(cls, params):
        params = tuple(params)
        if params:
            return cls.select().where(*params)
        else:
            return cls.select()

    class Meta:
        table_name = "roles"
Exemple #17
0
class Users(BaseModel):
    username = peewee.CharField(max_length=32, verbose_name="用户名")
    password = peewee.CharField(max_length=255, verbose_name="密码")
    is_staff = peewee.BooleanField(default=False, verbose_name="是否职员")
    is_superuser = peewee.BooleanField(default=False, verbose_name="是否管理员")
    is_lock = peewee.BooleanField(default=False, verbose_name="是否锁定")
    is_confirm = peewee.BooleanField(default=False, verbose_name="是否确定")
    role = peewee.ManyToManyField(Roles,
                                  backref="user_role",
                                  on_delete="CASCADE")

    @classmethod
    def newData(cls, params):
        params = tuple(params)
        if params:
            return cls.select().where(*params)
        else:
            return cls.select()

    class Meta:
        table_name = "users"
Exemple #18
0
class Retailer(peewee.Model):
    name = peewee.CharField()
    description = peewee.CharField(null=True)
    picture = peewee.CharField(null=True)
    active = peewee.BooleanField(default=True)
    ad_model = peewee.CharField(null=True,
                                verbose_name=u'c/a')  #TODO: to choices
    legal_info = peewee.TextField(null=True)
    countries = peewee.ManyToManyField(Country,
                                       backref='retailers',
                                       through_model=DefferedThroughRetailer)
    currency = peewee.ForeignKeyField(Currency)
    sm_accounts_white = postgres_ext.ArrayField(peewee.IntegerField, null=True)
    sm_accounts_black = postgres_ext.ArrayField(peewee.IntegerField, null=True)

    #NOTE: deprecated, will be removed
    datafeed_url = peewee.CharField(null=True)
    index_key = peewee.CharField(max_length=3, default='rus')
    url_key_mode = peewee.CharField(max_length=1, default='F')
    datafeed_params = postgres_ext.BinaryJSONField(default={})
    international = peewee.BooleanField(default=False)

    class Meta:
        database = db
        schema = 'store'
        table_alias = 'r'

    @property
    def feed(self):
        return self.feed_settings.first()

    @property
    def feeds(self):
        return [
            fs for fs in self.feed_settings.where(FeedSettings.active == True)
        ]
Exemple #19
0
class FlrMenu(BaseModel):
    name = pw.CharField()
    section_id = pw.ForeignKeyField(FlrMenuSection, backref="menus")
    groups = pw.ManyToManyField(Registry["FlrGroup"])
    sequence = pw.IntegerField(default=1)

    @classmethod
    def get_menus(cls):
        user = Registry["FlrUser"].get_by_id(request.uid)
        user_groups = set([x.id for x in user.groups])
        result = []
        for section in FlrMenuSection.select().order_by(
                FlrMenuSection.sequence):
            section_obj = {'id': section.id, 'name': section.name, 'menus': []}
            for menu in section.menus.order_by(FlrMenu.sequence):
                menu_groups = [g.id for g in menu.groups]
                if not menu.groups or user_groups.intersection(menu_groups):
                    section_obj["menus"].append({
                        "id": menu.id,
                        "name": menu.name
                    })
            if section_obj["menus"]:
                result.append(section_obj)
        return result
Exemple #20
0
class User(components.BaseUser):
    class Meta:
        table_name = "users"

    display_name = peewee.TextField(null=True)
    created = peewee.DateTimeField(null=False,
                                   default=datetime.now,
                                   formats=["%s"])
    edited = peewee.DateTimeField(null=False,
                                  default=datetime.now,
                                  index=True,
                                  formats=["%s"])

    user_ref_id = peewee.UUIDField(null=False,
                                   unique=True,
                                   index=True,
                                   default=uuid4)
    is_deleted = peewee.BooleanField(null=False, default=False)
    is_active = peewee.BooleanField(null=False, default=False)

    permissions = peewee.ManyToManyField(Role, backref="users")

    def changed(self):
        self.edited = datetime.now()
Exemple #21
0
                model_rule[
                    "perm_read"] = model_rule["perm_read"] or rule.perm_read
                model_rule["perm_update"] = model_rule[
                    "perm_update"] or rule.perm_update
                model_rule["perm_create"] = model_rule[
                    "perm_create"] or rule.perm_create
                model_rule["perm_delete"] = model_rule[
                    "perm_delete"] or rule.perm_delete
        return data


class FlrGroup(BaseModel):
    name = pw.CharField(help_text="Nombre")


FlrUser._meta.add_field("groups", pw.ManyToManyField(FlrGroup))

FlrUser.r()
FlrGroup.r()
FlrUserFlrGroup = FlrUser.groups.get_through_model()


class FlrACL(BaseModel):
    group_id = pw.ForeignKeyField(FlrGroup, help_text="Group", backref="acls")
    model = pw.CharField(help_text="Model")
    perm_read = pw.BooleanField(help_text="Read permission",
                                null=True,
                                default=False)
    perm_update = pw.BooleanField(help_text="Update permission",
                                  null=True,
                                  default=False)
Exemple #22
0
class Image(BaseModel):
    file_id = pv.IntegerField(null=True)
    filename = pv.TextField(null=False)
    checksum = pv.TextField(null=False)
    image_hash = ImageHashField(null=True)
    tags = pv.ManyToManyField(Tag, backref='images')

    @classmethod
    def from_bytes_io(cls, im_bytes_io, filename=None, tags=None):
        """
        :param im_bytes_io:
        :param str filename:
        :param str|list|tuple tags:
        :return:
        """

        if tags is None:
            tags = list()
        elif isinstance(tags, str):
            tags = [tags]

        if not filename or filename == 'image.png':
            filename = slugify('-'.join(tags)) + str(uuid4())[:8] + '.png'

        filename = nonrepeat_filename(filename,
                                      root=str(config['blob_folder']))

        filename = str(config['blob_folder'].joinpath(filename))
        checksum = get_checksum(im_bytes_io)

        im = PIL.Image.open(im_bytes_io)
        image_hash = get_image_hash(im)

        im.save(filename)

        db_image = cls.create(file_id=os.stat(filename).st_ino,
                              filename=filename,
                              checksum=checksum,
                              image_hash=image_hash)

        for tag in set(tags):
            db_image.tags.add(Tag.get_or_create(name=tag)[0])

        return db_image

    @classmethod
    def from_existing(cls, filename, tags=None):
        if tags is None:
            tags = list()

        filename = str(filename)

        db_image = cls.create(file_id=os.stat(filename).st_ino,
                              filename=filename,
                              checksum=get_checksum(filename),
                              image_hash=get_image_hash(filename))

        for tag in tags:
            db_image.tags.add(Tag.get_or_create(name=tag)[0])

        db_image.path = filename

        return db_image

    @classmethod
    def similar_images(cls, im):
        image_hash = get_image_hash(im)

        if config['hash_difference_threshold']:
            for db_image in cls.select():
                if db_image.image_hash - image_hash < config[
                        'hash_difference_threshold']:
                    yield db_image
        else:
            return cls.select().where(cls.image_hash == image_hash)

    def get_image(self, max_width=800, max_height=800):
        url = self.url
        if url:
            return f'<img src="{url}" style="max-width: {max_width}px; max-height: {max_height}px;" />'

    def _repr_html_(self):
        return self.get_image(800, 800)

    def _repr_json_(self):
        result = self.to_json()
        result['image'] = self.filename

        return result

    @property
    def url(self):
        if not urlparse(self.filename).netloc:
            return 'http://{}:{}/images?filename={}'.format(
                config['host'], config['port'],
                quote(str(self.filename), safe=''))
        else:
            return self.filename

    def to_json(self):
        return dict(id=self.id,
                    image=self.get_image(400, 400),
                    filename=self.filename,
                    notes=[n.data for n in self.notes],
                    tags=[t.name for t in self.tags])

    handsontable_config = {
        'renderers': {
            'image': 'html'
        },
        'config': {
            'colWidths': {
                'image': 400
            }
        }
    }
Exemple #23
0
class Card(BaseModel):
    item = pv.TextField(unique=True)
    info = sqlite_ext.JSONField(null=True)
    srs_level = pv.IntegerField(null=True)
    next_review = pv.DateTimeField(null=True)
    tags = pv.ManyToManyField(Tag, backref='cards', on_delete='cascade')

    backup = None

    def __repr__(self):
        return self.item

    def _repr_markdown_(self):
        type_ = Settings.get().type_
        if type_ == 'markdown':
            return self.item

    def _repr_html_(self):
        type_ = Settings.get().type_
        if type_ == 'html':
            return self.item

    def mark(self, tag='marked'):
        Tag.get_or_create(name=tag)[0].notes.add(self)

    def unmark(self, tag='marked'):
        Tag.get_or_create(name=tag)[0].notes.remove(self)

    def right(self):
        if not self.backup:
            self.backup = model_to_dict(self)

        if not self.srs_level:
            self.srs_level = 0
        else:
            self.srs_level = self.srs_level + 1

        srs = Settings.get()['srs']
        try:
            self.next_review = datetime.now() + srs[self.srs_level]
        except IndexError:
            self.next_review = None

        self.save()

    correct = next_srs = right

    def wrong(self, next_review=timedelta(minutes=10)):
        if not self.backup:
            self.backup = model_to_dict(self)

        if self.srs_level and self.srs_level > 0:
            self.srs_level = self.srs_level - 1

        self.bury(next_review)

    incorrect = previous_srs = wrong

    def bury(self, next_review=timedelta(hours=4)):
        if not self.backup:
            self.backup = model_to_dict(self)

        if isinstance(next_review, timedelta):
            self.next_review = datetime.now() + next_review
        else:
            self.next_review = next_review
        self.save()

    def undo(self):
        if self.backup:
            dict_to_model(Card, self.backup).save()

    @classmethod
    def iter_quiz(cls, **kwargs):
        db_cards = list(cls.search(**kwargs))
        random.shuffle(db_cards)

        return iter(db_cards)

    @classmethod
    def iter_due(cls, **kwargs):
        return cls.iter_quiz(due=True, **kwargs)

    @classmethod
    def search(cls, tags=None, due=Any, offset=0, limit=None):
        query = cls.select()

        if due is True:
            query = query.where(Card.next_review < datetime.now())
        elif due is False:
            query = query.where(Card.next_review >= datetime.now())
        elif due is None:
            query = query.where(Card.next_review.is_null(True))
        elif isinstance(due, timedelta):
            query = query.where(Card.next_review < datetime.now() + due)
        elif isinstance(due, datetime):
            query = query.where(Card.next_review < due)

        if tags:
            for tag in tags:
                query = query.join(CardTag).join(Tag).where(Tag.name.contains(tag))

        query = query.order_by(cls.next_review.desc())

        if offset:
            query = query.offset(offset)
        if limit:
            query = query.limit(limit)

        return query

    def to_dict(self):
        return model_to_dict(self, manytomany=True)

    @classmethod
    def add(cls, item, tags, **kwargs):
        with database.atomic():
            db_card = cls.create(item=item, info=kwargs)
            for tag in tags:
                Tag.get_or_create(name=tag)[0].cards.add(db_card)

            return db_card
Exemple #24
0
class Evaluacion(BaseModel):
	examen = peewee.ForeignKeyField(Examen, backref='evaluaciones',null = True) #una evaluacion con examen null es para cargar notas de practicos
	preguntas = peewee.ManyToManyField(Pregunta, backref='evaluaciones')
	cursada = peewee.ForeignKeyField(Cursada, backref='evaluaciones')
	titulo = peewee.CharField()
	fecha = peewee.DateTimeField()
Exemple #25
0
class Cursada(BaseModel):
	curso = peewee.ForeignKeyField(Curso, backref='cursadas')
	nombre = peewee.CharField()
	profesores = peewee.ManyToManyField(Usuario,through_model= ProfesorThroughDeferred, backref='cursadasEnLasQueEsProfesor')
	alumnos = peewee.ManyToManyField(Usuario,through_model= AlumnoThroughDeferred, backref='cursadasEnLasQueEsAlumno')
	inicio = peewee.DateTimeField()
Exemple #26
0
class Attachment(BaseModel):
    rawmsg = pw.ManyToManyField(RawMsg, backref='attachments')
    file_checksum = pw.CharField(help_text='Checksum of the file on disk')
    original_filename = pw.CharField(help_text='Original filename')
    content_type = pw.CharField(help_text='Original content type')
Exemple #27
0
class Card(BaseModel):
    template = pv.ForeignKeyField(Template, backref='cards')
    note = pv.ForeignKeyField(Note, backref='cards')
    _front = pv.TextField(unique=True)
    srs_level = pv.IntegerField(null=True)
    next_review = pv.DateTimeField(null=True)
    _decks = pv.ManyToManyField(Deck, backref='cards')

    last_review = pv.DateTimeField(constraints=[pv.SQL('DEFAULT CURRENT_TIMESTAMP')])
    info = sqlite_ext.JSONField(default=dict)

    backup = None

    def to_dict(self, max_depth=2, **kwargs):
        d = super(Card, self).to_dict(manytomany=False, backrefs=False,
                                      exclude=['_decks', '_front', 'note'],
                                      extra_attrs=['decks', 'front', 'back'])
        d['note'] = self.note.to_dict()
        return d

    @property
    def decks(self):
        return [d.name for d in self._decks]

    @property
    def front(self):
        text = self.template.front
        for k, v in self.note.data.items():
            text = text.replace('{{%s}}' % k, str(v))

        return text

    @property
    def back(self):
        text = self.template.back
        if not text:
            return '\n'.join(' ' * 4 + line for line in json.dumps(
                self.note.data,
                indent=2, ensure_ascii=False
            ).split('\n'))

        for k, v in self.note.data.items():
            text = text.replace('{{%s}}' % k, str(v))

        return text

    def __repr__(self):
        return self.front

    @property
    def data(self):
        return self.note.data

    def add_deck(self, deck_name):
        Deck.get_or_create(name=deck_name)[0].cards.add(self)

    def remove_deck(self, deck_name):
        Deck.get_or_create(name=deck_name)[0].cards.remove(self)

    def mark(self, tag='marked'):
        return self.note.mark(tag)

    def unmark(self, tag='marked'):
        return self.note.unmark(tag)

    def right(self, step=1):
        self.undo()

        if not self.backup:
            self.backup = model_to_dict(self)

        print(self.srs_level)

        if self.srs_level is None:
            self.srs_level = 0
        else:
            self.srs_level = self.srs_level + step

        srs = Settings.get().srs
        try:
            self.next_review = datetime.now() + srs[self.srs_level]
        except IndexError:
            self.next_review = None

        assert isinstance(self.info, dict)

        self.info['lapse'] = 0
        self.info['streak'] = self.info.get('streak', 0) + 1
        self.info['total_right'] = self.info.get('total_right', 0) + 1

        self.save()

    correct = next_srs = right

    def easy(self, max_srs_level_enabled=3):
        if self.srs_level < max_srs_level_enabled:
            return self.right(step=2)
        else:
            raise ValueError

    def wrong(self, next_review=timedelta(minutes=10)):
        self.undo()

        if not self.backup:
            self.backup = model_to_dict(self)

        if self.srs_level is not None and self.srs_level > 0:
            self.srs_level = self.srs_level - 1

        assert isinstance(self.info, dict)

        self.info['streak'] = 0
        self.info['lapse'] = self.info.get('lapse', 0) + 1
        self.info['total_wrong'] = self.info.get('total_wrong', 0) + 1

        self.bury(next_review)

    incorrect = previous_srs = wrong

    def bury(self, next_review=timedelta(hours=4)):
        if not self.backup:
            self.backup = model_to_dict(self)

        if isinstance(next_review, timedelta):
            self.next_review = datetime.now() + next_review
        else:
            self.next_review = next_review

        self.save()

    def reset(self):
        self.srs_level = None
        self.next_review = None
        self.save()

    def undo(self):
        if self.backup:
            dict_to_model(Card, self.backup).save()

    @classmethod
    def iter_quiz(cls, **kwargs):
        db_cards = list(cls.search(**kwargs))
        random.shuffle(db_cards)

        return iter(db_cards)

    @classmethod
    def iter_due(cls, **kwargs):
        return cls.iter_quiz(due=True, **kwargs)

    @classmethod
    def search(cls, q_str='', deck=None, tags=None, due=None, offset=0, limit=None):
        """

        :param q_str:
        :param deck:
        :param tags:
        :param bool|None|timedelta|datetime due:
        :param offset:
        :param limit:
        :return:
        """
        query = cls.select()
        due_is_set = False
        note_keys = None

        result = parse_query(q_str)
        if result:
            for seg in result:
                if len(seg) == 1:
                    if note_keys is None:
                        note_keys = set()
                        for srs_note in Note.select(Note.data):
                            note_keys.update(srs_note.data.keys())

                        note_keys = tuple(note_keys)
                    q_note = Note.data[note_keys[0]].contains(seg[0])

                    for k in note_keys[1:]:
                        q_note |= Note.data[k].contains(seg[0])

                    query = query.switch(cls).join(Note).where(q_note)
                else:
                    if seg[0] == 'due':
                        due_is_set = True
                        if seg[2].lower() == 'true':
                            query = query.switch(cls).where(cls.next_review < datetime.now())
                        elif seg[2].lower() == 'false':
                            query = query.switch(cls).where(cls.next_review.is_null(True))
                        else:
                            dur_sec = pytimeparse.parse(seg[2])
                            if dur_sec:
                                _due = datetime.now() + timedelta(seconds=dur_sec)
                            else:
                                _due = dateutil.parser.parse(seg[2])

                            query = query.switch(cls).where(cls.next_review < _due)
                    elif seg[0] == 'deck':
                        deck_q = (Deck.name == seg[2])
                        if seg[1] != '=':
                            deck_q = (deck_q | Deck.name.startswith(seg[2] + '::'))

                        query = query.switch(cls).join(CardDeck).join(Deck).where(deck_q)
                    elif seg[0] == 'tag':
                        if seg[1] == '=':
                            query = query.switch(cls).join(Note).join(NoteTag).join(Tag)\
                                .where(Tag.name == seg[2])
                        else:
                            query = query.switch(cls).join(Note).join(NoteTag).join(Tag)\
                                .where(Tag.name.contains(seg[2]))
                    else:
                        if seg[1] == '=':
                            query = query.switch(cls).join(Note).where(Note.data[seg[0]] == seg[2])
                        elif seg[1] == '>':
                            query = query.switch(cls).join(Note).where(Note.data[seg[0]] > seg[2])
                        elif seg[1] == '<':
                            query = query.switch(cls).join(Note).where(Note.data[seg[0]] < seg[2])
                        else:
                            query = query.switch(cls).join(Note).where(Note.data[seg[0]].contains(seg[2]))

        if due is True:
            query = query.switch(cls).where(cls.next_review < datetime.now())
        elif due is False:
            query = query.switch(cls).where(cls.next_review.is_null(True))
        elif isinstance(due, timedelta):
            query = query.switch(cls).where(cls.next_review < datetime.now() + due)
        elif isinstance(due, datetime):
            query = query.switch(cls).where(cls.next_review < due)
        else:
            if not due_is_set:
                query = query.where((cls.next_review < datetime.now()) | cls.next_review.is_null(True))

        if deck:
            query = query.switch(cls).join(CardDeck).join(Deck).where(Deck.name.startswith(deck + '::')
                                                                      | (Deck.name == deck))

        if tags:
            for tag in tags:
                query = query.switch(cls).join(Note).join(NoteTag).join(Tag).where(Tag.name.contains(tag))

        query = query.order_by(cls.next_review.desc())

        if offset:
            query = query.offset(offset)
        if limit:
            query = query.limit(limit)

        return query
Exemple #28
0
class Product(BaseModel):
    product_name = peewee.CharField()
    description = peewee.CharField()
    tags = peewee.ManyToManyField(Tag)
    price = peewee.DecimalField()
    quantity = peewee.IntegerField()
Exemple #29
0
 class User(Base):
     hobbies = pw.ManyToManyField(Hobby, backref='users')
Exemple #30
0
class Note(BaseModel):
    data = sqlite_ext.JSONField()
    model = pv.ForeignKeyField(Model, backref='notes')
    media = pv.ManyToManyField(Media, backref='notes', on_delete='cascade')
    tags = pv.ManyToManyField(Tag, backref='notes', on_delete='cascade')
    h = pv.TextField(unique=True)

    def mark(self, tag):
        Tag.get_or_create(name=tag)[0].notes.add(self)

    def unmark(self, tag):
        Tag.get_or_create(name=tag)[0].notes.remove(self)

    def rename_field(self, old_name, new_name):
        for db_note in Note.select(Note.data, Note.model_id).where(model_id=self.model_id):
            if old_name in db_note.data.keys():
                db_note.data[new_name] = db_note.data.pop(old_name)
                db_note.save()

    @classmethod
    def add(cls, data, model, card_to_decks: dict, media: dict=None, tags: list=None):
        if media is None:
            media = dict()
        if tags is None:
            tags = list()

        with database.atomic():
            if isinstance(model, int) or (isinstance(model, str) and model.isdigit()):
                db_model = Model.get(id=int(model))
            elif isinstance(model, Model):
                db_model = model
            else:
                db_model = Model.get(name=model)

            db_note = cls.create(
                data=data,
                model_id=db_model.id
            )

            for template, deck in card_to_decks.items():
                if isinstance(deck, int) or (isinstance(deck, str) and deck.isdigit()):
                    db_deck = Deck.get(id=int(deck))
                elif isinstance(deck, Deck):
                    db_deck = deck
                else:
                    db_deck = Deck.get_or_create(name=deck)[0]

                if isinstance(template, int) or (isinstance(template, str) and template.isdigit()):
                    db_template = Template.get(id=int(template))
                elif isinstance(template, Template):
                    db_template = template
                else:
                    db_template = Template.get(model_id=db_model.id, name=template)

                Card.create(
                    note_id=db_note.id,
                    deck_id=db_deck.id,
                    template_id=db_template.id
                )

            for media_name, media_path in media.items():
                type_ = {
                    'audio': MediaType.audio,
                    'font': MediaType.font
                }.get(magic.from_file(media_path, mime=True).split('/')[0], MediaType.image)

                with open(media_path, 'rb') as f:
                    Media.create(
                        name=media_name,
                        data=f.read(),
                        type_=type_
                    )

            for tag_name in tags:
                Tag.get_or_create(name=tag_name)[0].notes.add(db_note)

        return db_note

    @classmethod
    def search(cls, model_name=None, deck_name=None, tags=None, data=None, **kwargs):
        db_query = cls.select()
        if deck_name:
            db_query = db_query \
                .join(Card).join(Deck) \
                .where(Deck.name.contains(deck_name))

        db_query = cls._build_query(db_query, model_name=model_name, tags=tags, data=data, **kwargs)

        return db_query

    @classmethod
    def _build_query(cls, db_query, model_name=None, tags=None, data=None, **kwargs):
        if data is None:
            data = dict()
        data.update(kwargs)

        db_query = db_query.switch(cls)

        if data:
            for k, v in data.items():
                db_query = db_query.where(cls.data[k].contains(v))
        if model_name:
            db_query = db_query \
                .join(Model) \
                .where(Model.name.contains(model_name))
        if tags:
            db_query = db_query\
                .join(NoteTag).join(Tag)\
                .where(~Tag.name.not_in(tags))

        return db_query

    def to_viewer(self):
        d = model_to_dict(self)
        d['cards'] = '<br/>'.join(c.html for c in self.cards)
        d['tags'] = [t.name for t in self.tags]

        return d

    viewer_config = {
        'renderer': {
            'cards': 'html'
        },
        'colWidth': {
            'cards': 400
        }
    }