implement searchtopics
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
weeman 2021-07-05 20:39:49 +02:00
parent 61bf24eab2
commit 7a72287c00
Signed by: weeman
GPG Key ID: 34F0524D4DA694A1
8 changed files with 102 additions and 17 deletions

View File

@ -6,7 +6,8 @@ import csv
import logging
from app import app, db
from ki.models import Address, Contact, ContactType, Language, Skill, Profile, ProfileLanguage, ProfileSkill, User
from ki.models import Address, Contact, ContactType, Language, Skill, Profile, ProfileLanguage, ProfileSearchtopic, \
ProfileSkill, User
def seed_contacttypes():
@ -91,6 +92,12 @@ def seed(dev: bool):
peters_php_skill = ProfileSkill(profile=peters_profile, skill_id=1, level=5)
db.session.add(peters_php_skill)
peters_python_searchtopic = ProfileSearchtopic(profile=peters_profile, skill_id=3)
db.session.add(peters_python_searchtopic)
peters_php_searchtopic = ProfileSearchtopic(profile=peters_profile, skill_id=1)
db.session.add(peters_php_searchtopic)
peter_de = ProfileLanguage(profile=peters_profile, language_id="de", level=5)
db.session.add(peter_de)

View File

@ -5,7 +5,8 @@
from flask import make_response, request
from sqlalchemy import not_
from ki.models import Address, Contact, ContactType, Language, User, Profile, ProfileLanguage, ProfileSkill, Skill
from ki.models import Address, Contact, ContactType, Language, User, Profile, ProfileLanguage, ProfileSearchtopic, \
ProfileSkill, Skill
from app import db
@ -71,6 +72,30 @@ def update_skills(profile, skills_data):
not_(ProfileSkill.skill_id.in_(profile_skill_ids))).delete()
def update_searchtopics(profile, searchtopics_data):
profile_searchtopics_ids = []
for searchtopic_data in searchtopics_data:
skill_name = searchtopic_data["skill"]["name"]
skill = Skill.query.filter(Skill.name == skill_name).first()
if (skill is None):
skill = Skill(name=skill_name)
db.session.add(skill)
profile_searchtopic = ProfileSearchtopic.query.filter(ProfileSearchtopic.profile == profile,
ProfileSearchtopic.skill == skill).first()
if (profile_searchtopic is None):
profile_searchtopic = ProfileSearchtopic(profile=profile, skill=skill)
db.session.add(profile_searchtopic)
profile_searchtopics_ids.append(skill.id)
ProfileSearchtopic.query.filter(ProfileSearchtopic.profile == profile,
not_(ProfileSearchtopic.skill_id.in_(profile_searchtopics_ids))).delete()
def update_contacts(profile, contacts_data):
contact_ids_to_be_deleted = list(map(lambda c: c.id, profile.contacts))
@ -116,6 +141,7 @@ def update_profile(user_id: int):
update_address(profile, request.json.get("address", {}))
update_contacts(profile, request.json.get("contacts", {}))
update_skills(profile, request.json.get("skills", {}))
update_searchtopics(profile, request.json.get("searchtopics"))
update_languages(profile, request.json.get("languages", {}))
db.session.commit()

View File

@ -40,6 +40,7 @@ class Profile(db.Model):
contacts = relationship("Contact")
address = relationship("Address", uselist=False, back_populates="profile")
skills = relationship("ProfileSkill", back_populates="profile")
searchtopics = relationship("ProfileSearchtopic", back_populates="profile")
languages = relationship("ProfileLanguage", back_populates="profile")
def to_dict(self):
@ -53,6 +54,7 @@ class Profile(db.Model):
"address": self.address.to_dict(),
"contacts": list(map(lambda contact: contact.to_dict(), self.contacts)),
"skills": list(map(lambda skill: skill.to_dict(), self.skills)),
"searchtopics": list(map(lambda searchtopic: searchtopic.to_dict(), self.searchtopics)),
"languages": list(map(lambda language: language.to_dict(), self.languages))
}
@ -135,6 +137,7 @@ class Skill(db.Model):
name = Column(String(25), unique=True, nullable=False)
profiles = relationship("ProfileSkill", back_populates="skill")
searchtopics = relationship("ProfileSearchtopic", back_populates="skill")
def to_dict(self):
return {"id": self.id, "name": self.name, "icon_url": "/skills/{}/icon".format(self.id)}
@ -154,6 +157,19 @@ class ProfileSkill(db.Model):
return {"profile_id": self.profile_id, "skill": self.skill.to_dict(), "level": self.level}
class ProfileSearchtopic(db.Model):
__tablename__ = "profile_searchtopic"
profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True)
skill_id = Column(Integer, ForeignKey("skill.id"), primary_key=True)
profile = relationship("Profile", back_populates="searchtopics")
skill = relationship("Skill", back_populates="searchtopics")
def to_dict(self):
return {"profile_id": self.profile_id, "skill": self.skill.to_dict()}
class Language(db.Model):
__tablename__ = "language"

View File

@ -70,6 +70,19 @@ class TestProfileEndpoint(ApiTest):
},
"level": 5
}],
"searchtopics": [{
"profile_id": 1,
"skill": {
"id": 3,
"name": "Python",
"icon_url": "/skills/3/icon"
}
}, {
"profile_id": 1,
"skill": {
"name": "Assembler"
}
}],
"languages": [{
"id": 1,
"language": {
@ -132,6 +145,17 @@ class TestProfileEndpoint(ApiTest):
self.assertEqual(second_skill.skill.name, "Tschunkproduktion")
self.assertEqual(second_skill.level, 5)
searchtopics = profile.searchtopics
self.assertEqual(len(searchtopics), 2)
first_searchtopic = searchtopics[0]
self.assertEqual(first_searchtopic.skill.id, 3)
self.assertEqual(first_searchtopic.skill.name, "Python")
second_searchtopic = searchtopics[1]
self.assertEqual(second_searchtopic.skill.id, 14)
self.assertEqual(second_searchtopic.skill.name, "Assembler")
languages = profile.languages
self.assertEqual(len(languages), 2)
@ -213,6 +237,21 @@ class TestProfileEndpoint(ApiTest):
},
"level": 3
}],
"searchtopics": [{
"profile_id": 1,
"skill": {
"id": 1,
"name": "PHP",
"icon_url": "/skills/1/icon"
}
}, {
"profile_id": 1,
"skill": {
"id": 3,
"name": "Python",
"icon_url": "/skills/3/icon"
}
}],
"languages": [{
"profile_id": 1,
"language": {

1
migrations/README Normal file
View File

@ -0,0 +1 @@
Generic single-database configuration.

View File

@ -1,7 +1,3 @@
; SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
;
; SPDX-License-Identifier: AGPL-3.0-or-later
# A generic, single database configuration.
[alembic]

View File

@ -1,7 +1,3 @@
# SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from __future__ import with_statement
import logging

View File

@ -1,12 +1,8 @@
# SPDX-FileCopyrightText: WTF Kooperative eG <https://wtf-eg.de/>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Initial migration.
Revision ID: ebb2dd1fb371
Revision ID: 1e1b2be49756
Revises:
Create Date: 2021-07-02 16:20:18.160228
Create Date: 2021-07-05 20:36:04.047270
"""
from alembic import op
@ -14,7 +10,7 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ebb2dd1fb371'
revision = '1e1b2be49756'
down_revision = None
branch_labels = None
depends_on = None
@ -80,6 +76,13 @@ def upgrade():
sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ),
sa.PrimaryKeyConstraint('profile_id', 'language_id')
)
op.create_table('profile_searchtopic',
sa.Column('profile_id', sa.Integer(), nullable=False),
sa.Column('skill_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ),
sa.ForeignKeyConstraint(['skill_id'], ['skill.id'], ),
sa.PrimaryKeyConstraint('profile_id', 'skill_id')
)
op.create_table('profile_skill',
sa.Column('profile_id', sa.Integer(), nullable=False),
sa.Column('skill_id', sa.Integer(), nullable=False),
@ -111,6 +114,7 @@ def downgrade():
op.drop_table('token')
op.drop_table('user')
op.drop_table('profile_skill')
op.drop_table('profile_searchtopic')
op.drop_table('profile_language')
op.drop_table('contact')
op.drop_table('address')