Compare commits
4 Commits
4e67b8a966
...
ext_skills
Author | SHA1 | Date | |
---|---|---|---|
6389258a60
|
|||
b8c2644086
|
|||
ec855a542d
|
|||
9a1f3f842a
|
@ -16,3 +16,111 @@ id,name
|
|||||||
15,VHDL
|
15,VHDL
|
||||||
16,go
|
16,go
|
||||||
17,Perl
|
17,Perl
|
||||||
|
18,3D-Druck
|
||||||
|
19,ABAP
|
||||||
|
20,Android
|
||||||
|
21,Ansible
|
||||||
|
22,Arduino
|
||||||
|
23,Bash
|
||||||
|
24,batou
|
||||||
|
25,bind
|
||||||
|
26,Buchführung
|
||||||
|
27,C#
|
||||||
|
28,CAD
|
||||||
|
29,CAM
|
||||||
|
30,Cobol
|
||||||
|
31,CRM
|
||||||
|
32,CSS
|
||||||
|
33,D
|
||||||
|
34,Debian
|
||||||
|
35,Delphi
|
||||||
|
36,DevOPS
|
||||||
|
37,Discourse
|
||||||
|
38,Django
|
||||||
|
39,DNS
|
||||||
|
40,Dovecot
|
||||||
|
41,Elasticsearch
|
||||||
|
42,Emacs
|
||||||
|
43,Email
|
||||||
|
44,ERP
|
||||||
|
45,ESP
|
||||||
|
46,Excel
|
||||||
|
47,Fahrdienstleitung
|
||||||
|
48,Fedora
|
||||||
|
49,FLOSS
|
||||||
|
50,Geographie
|
||||||
|
51,Geologie
|
||||||
|
52,Gnome
|
||||||
|
53,GPS
|
||||||
|
54,Grafana
|
||||||
|
55,GrayLog
|
||||||
|
56,GSM
|
||||||
|
57,GTK
|
||||||
|
58,HTML
|
||||||
|
59,IBM Z
|
||||||
|
60,IMAP
|
||||||
|
61,Ionic
|
||||||
|
62,iOS
|
||||||
|
63,Java
|
||||||
|
64,Kryptographie
|
||||||
|
65,LDAP
|
||||||
|
66,LibreOffice
|
||||||
|
67,Linux
|
||||||
|
68,Literaturgeschichte
|
||||||
|
69,Lithographie
|
||||||
|
70,Lucene
|
||||||
|
71,Mailman
|
||||||
|
72,MariaDB
|
||||||
|
73,Markdown
|
||||||
|
74,Marketing
|
||||||
|
75,Microsoft Office
|
||||||
|
76,Monitoring
|
||||||
|
77,Nagios
|
||||||
|
78,nähen
|
||||||
|
79,NixOS
|
||||||
|
80,odoo
|
||||||
|
81,OpenOffice
|
||||||
|
82,OpenPGP
|
||||||
|
83,OpenStreetMap
|
||||||
|
84,openSUSE
|
||||||
|
85,Oracle
|
||||||
|
86,Percona
|
||||||
|
87,PGP
|
||||||
|
88,Plone
|
||||||
|
89,Postfix
|
||||||
|
90,PowerDNS
|
||||||
|
91,PowerPC
|
||||||
|
92,Projektmanagement
|
||||||
|
93,puppet
|
||||||
|
94,Qt
|
||||||
|
95,R/3
|
||||||
|
96,RedHat
|
||||||
|
97,RHEL
|
||||||
|
98,S/4
|
||||||
|
99,Salt
|
||||||
|
100,SAP
|
||||||
|
101,Scrum
|
||||||
|
102,ScummVM
|
||||||
|
103,Sensu
|
||||||
|
104,sh
|
||||||
|
105,Siemens S5
|
||||||
|
106,Siemens S7
|
||||||
|
107,Simatic
|
||||||
|
108,SLES
|
||||||
|
109,Spring
|
||||||
|
110,SQL
|
||||||
|
111,Stenographie
|
||||||
|
112,Steuerrecht
|
||||||
|
113,Teppich knüpfen
|
||||||
|
114,TeX
|
||||||
|
115,Verlagswesen
|
||||||
|
116,vi(m)
|
||||||
|
117,Windows 10
|
||||||
|
118,Windows 2000
|
||||||
|
119,Windows 2012R2
|
||||||
|
120,Windows 7
|
||||||
|
121,Windows NT
|
||||||
|
122,Windows XP
|
||||||
|
123,x86
|
||||||
|
124,Zope
|
||||||
|
125,zsh
|
||||||
|
|
@ -26,6 +26,31 @@ def seed_contacttypes():
|
|||||||
db.session.add(ContactType(id=int(contacttype["id"]), name=contacttype["name"]))
|
db.session.add(ContactType(id=int(contacttype["id"]), name=contacttype["name"]))
|
||||||
|
|
||||||
|
|
||||||
|
def seed_user(nickname, visible=False, skills=[], languages=[], volunteerwork="", availability="", freetext=""):
|
||||||
|
app.logger.info(f"seeding {nickname} \\o/")
|
||||||
|
|
||||||
|
user = User(auth_id=nickname)
|
||||||
|
db.session.add(user)
|
||||||
|
|
||||||
|
profile = Profile(nickname=nickname,
|
||||||
|
pronouns="",
|
||||||
|
volunteerwork=volunteerwork,
|
||||||
|
availability=availability,
|
||||||
|
freetext=freetext,
|
||||||
|
visible=visible,
|
||||||
|
user=user)
|
||||||
|
|
||||||
|
for skill_data in skills:
|
||||||
|
skill = ProfileSkill(profile=profile, skill_id=skill_data[0], level=skill_data[1])
|
||||||
|
db.session.add(skill)
|
||||||
|
|
||||||
|
for language_data in languages:
|
||||||
|
language = ProfileLanguage(profile=profile, language_id=language_data[0], level=language_data[1])
|
||||||
|
db.session.add(language)
|
||||||
|
|
||||||
|
db.session.add(profile)
|
||||||
|
|
||||||
|
|
||||||
def seed(dev: bool):
|
def seed(dev: bool):
|
||||||
seed_contacttypes()
|
seed_contacttypes()
|
||||||
|
|
||||||
@ -105,23 +130,21 @@ def seed(dev: bool):
|
|||||||
peter_fr = ProfileLanguage(profile=peters_profile, language_id="fr", level=3)
|
peter_fr = ProfileLanguage(profile=peters_profile, language_id="fr", level=3)
|
||||||
db.session.add(peter_fr)
|
db.session.add(peter_fr)
|
||||||
|
|
||||||
app.logger.info("seeding klaus :D")
|
seed_user("klaus")
|
||||||
|
|
||||||
klaus = User(auth_id="klaus")
|
seed_user("dirtydieter",
|
||||||
db.session.add(klaus)
|
visible=True,
|
||||||
|
|
||||||
app.logger.info("seeding dieter \\o/")
|
|
||||||
|
|
||||||
dieter = User(auth_id="dieter")
|
|
||||||
db.session.add(dieter)
|
|
||||||
|
|
||||||
dieters_profile = Profile(nickname="dirtydieter",
|
|
||||||
pronouns="",
|
|
||||||
volunteerwork="Müll sammeln",
|
volunteerwork="Müll sammeln",
|
||||||
availability="Nur nachts",
|
availability="Nur nachts",
|
||||||
freetext="1001010010111!!!",
|
freetext="1001010010111!!!",
|
||||||
|
skills=[(Skill.skill_id_php, 5)])
|
||||||
|
|
||||||
|
seed_user("jutta",
|
||||||
visible=True,
|
visible=True,
|
||||||
user=dieter)
|
languages=[("fr", 5)],
|
||||||
db.session.add(dieters_profile)
|
skills=[(Skill.skill_id_php, 3), (Skill.skill_id_mysql, 4)])
|
||||||
|
seed_user("giesela", visible=True, skills=[(Skill.skill_id_mysql, 3), (Skill.skill_id_postgresql, 5)])
|
||||||
|
seed_user("bertha", visible=False, skills=[(Skill.skill_id_sqlite, 3), (Skill.skill_id_postgresql, 5)])
|
||||||
|
seed_user("monique", visible=True, languages=[("fr", 4)])
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
from flask import make_response, request
|
from flask import make_response, request
|
||||||
|
|
||||||
from ki.models import Profile
|
from ki.models import Profile, ProfileSkill, Skill, ProfileLanguage, Language
|
||||||
|
|
||||||
|
|
||||||
def find_profiles():
|
def find_profiles():
|
||||||
@ -18,13 +18,21 @@ def find_profiles():
|
|||||||
if page_size > 100:
|
if page_size > 100:
|
||||||
return make_response({"messages": {"page_size": "Die maximale Anzahl Einträge pro Seite beträgt 100"}}, 400)
|
return make_response({"messages": {"page_size": "Die maximale Anzahl Einträge pro Seite beträgt 100"}}, 400)
|
||||||
|
|
||||||
query = Profile.query.filter(Profile.visible.is_(True))
|
query = Profile.query.filter(Profile.visible.is_(True)) \
|
||||||
|
.join(Profile.skills, isouter=True).join(ProfileSkill.skill, isouter=True) \
|
||||||
|
.join(Profile.languages, isouter=True).join(ProfileLanguage.language, isouter=True)
|
||||||
|
|
||||||
|
if "search" in request.args:
|
||||||
|
terms = request.args["search"].split(" ")
|
||||||
|
for term in terms:
|
||||||
|
query = query.filter(
|
||||||
|
Profile.nickname.like(f"%{term}%") | Skill.name.like(f"%{term}%") | Language.name.like(f"%{term}%"))
|
||||||
|
|
||||||
if "nickname" in request.args:
|
if "nickname" in request.args:
|
||||||
nickname = request.args.get("nickname")
|
nickname = request.args.get("nickname")
|
||||||
query = query.filter(Profile.nickname.like(f"%{nickname}%"))
|
query = query.filter(Profile.nickname.like(f"%{nickname}%"))
|
||||||
|
|
||||||
count = query.count()
|
count = query.distinct(Profile.id).count()
|
||||||
|
|
||||||
offset = (page - 1) * page_size
|
offset = (page - 1) * page_size
|
||||||
db_profiles = query.limit(page_size).offset(offset).all()
|
db_profiles = query.limit(page_size).offset(offset).all()
|
||||||
|
39
ki/models.py
39
ki/models.py
@ -133,6 +133,13 @@ class Address(db.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Skill(db.Model):
|
class Skill(db.Model):
|
||||||
|
skill_id_php = 1
|
||||||
|
skill_id_python = 3
|
||||||
|
skill_id_sqlalchemy = 7
|
||||||
|
skill_id_mysql = 9
|
||||||
|
skill_id_postgresql = 10
|
||||||
|
skill_id_sqlite = 11
|
||||||
|
|
||||||
__tablename__ = "skill"
|
__tablename__ = "skill"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
@ -146,6 +153,19 @@ class Skill(db.Model):
|
|||||||
|
|
||||||
|
|
||||||
class ProfileSkill(db.Model):
|
class ProfileSkill(db.Model):
|
||||||
|
level1_text = "bis 6 Monate"
|
||||||
|
level2_text = "bis 1 Jahr"
|
||||||
|
level3_text = "bis 3 Jahre"
|
||||||
|
level4_text = "bis 5 Jahre"
|
||||||
|
level5_text = "mehr als 5 Jahre"
|
||||||
|
level_texts = {
|
||||||
|
1: level1_text,
|
||||||
|
2: level2_text,
|
||||||
|
3: level3_text,
|
||||||
|
4: level4_text,
|
||||||
|
5: level5_text,
|
||||||
|
}
|
||||||
|
|
||||||
__tablename__ = "profile_skill"
|
__tablename__ = "profile_skill"
|
||||||
|
|
||||||
profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True)
|
profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True)
|
||||||
@ -175,8 +195,8 @@ class ProfileSearchtopic(db.Model):
|
|||||||
class Language(db.Model):
|
class Language(db.Model):
|
||||||
__tablename__ = "language"
|
__tablename__ = "language"
|
||||||
|
|
||||||
id = Column(String(2), primary_key=True)
|
id = Column(String(4), primary_key=True)
|
||||||
name = Column(String(25), nullable=False)
|
name = Column(String(100), nullable=False)
|
||||||
|
|
||||||
profiles = relationship("ProfileLanguage", back_populates="language")
|
profiles = relationship("ProfileLanguage", back_populates="language")
|
||||||
|
|
||||||
@ -185,10 +205,23 @@ class Language(db.Model):
|
|||||||
|
|
||||||
|
|
||||||
class ProfileLanguage(db.Model):
|
class ProfileLanguage(db.Model):
|
||||||
|
level1_text = "keine Angabe"
|
||||||
|
level2_text = "Grundkenntnisse"
|
||||||
|
level3_text = "Gut"
|
||||||
|
level4_text = "Fließend"
|
||||||
|
level5_text = "Muttersprache"
|
||||||
|
level_texts = {
|
||||||
|
1: level1_text,
|
||||||
|
2: level2_text,
|
||||||
|
3: level3_text,
|
||||||
|
4: level4_text,
|
||||||
|
5: level5_text,
|
||||||
|
}
|
||||||
|
|
||||||
__tablename__ = "profile_language"
|
__tablename__ = "profile_language"
|
||||||
|
|
||||||
profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True)
|
profile_id = Column(Integer, ForeignKey("profile.id"), primary_key=True)
|
||||||
language_id = Column(String(2), ForeignKey("language.id"), primary_key=True)
|
language_id = Column(String(4), ForeignKey("language.id"), primary_key=True)
|
||||||
level = Column(SmallInteger, nullable=False)
|
level = Column(SmallInteger, nullable=False)
|
||||||
|
|
||||||
profile = relationship("Profile", back_populates="languages")
|
profile = relationship("Profile", back_populates="languages")
|
||||||
|
@ -34,9 +34,59 @@ class TestFindProfilesEndpoint(ApiTest):
|
|||||||
|
|
||||||
response = self.client.get("/users/profiles", headers={"Authorization": "Bearer " + token})
|
response = self.client.get("/users/profiles", headers={"Authorization": "Bearer " + token})
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 4}, response.json)
|
||||||
|
self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0])
|
||||||
|
|
||||||
|
def test_find_dieter(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=dieter%20php", headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertDictContainsSubset({"total": 1}, response.json)
|
self.assertDictContainsSubset({"total": 1}, response.json)
|
||||||
self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0])
|
self.assertDictContainsSubset({"nickname": "dirtydieter"}, response.json["profiles"][0])
|
||||||
|
|
||||||
|
def test_not_find_dieter(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=dieter%20sqlite",
|
||||||
|
headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 0}, response.json)
|
||||||
|
|
||||||
|
def test_find_sql(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=sql", headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 2}, response.json)
|
||||||
|
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
|
||||||
|
self.assertDictContainsSubset({"nickname": "giesela"}, response.json["profiles"][1])
|
||||||
|
|
||||||
|
def test_find_postgres(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=post", headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 1}, response.json)
|
||||||
|
self.assertDictContainsSubset({"nickname": "giesela"}, response.json["profiles"][0])
|
||||||
|
|
||||||
|
def test_find_php_franzosen(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=php%20franz", headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 1}, response.json)
|
||||||
|
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
|
||||||
|
|
||||||
|
def test_find_franzosen(self):
|
||||||
|
token = self.login("peter", "geheim")["token"]
|
||||||
|
|
||||||
|
response = self.client.get("/users/profiles?search=französisch", headers={"Authorization": "Bearer " + token})
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertDictContainsSubset({"total": 2}, response.json)
|
||||||
|
self.assertDictContainsSubset({"nickname": "jutta"}, response.json["profiles"][0])
|
||||||
|
self.assertDictContainsSubset({"nickname": "monique"}, response.json["profiles"][1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "main":
|
if __name__ == "main":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
"""Initial migration.
|
"""Initial migration.
|
||||||
|
|
||||||
Revision ID: 6269064f6b51
|
Revision ID: 9183e2335b05
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2021-08-02 21:28:50.484098
|
Create Date: 2021-08-02 21:51:30.400680
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '6269064f6b51'
|
revision = '9183e2335b05'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
@ -24,8 +24,8 @@ def upgrade():
|
|||||||
sa.PrimaryKeyConstraint('id')
|
sa.PrimaryKeyConstraint('id')
|
||||||
)
|
)
|
||||||
op.create_table('language',
|
op.create_table('language',
|
||||||
sa.Column('id', sa.String(length=2), nullable=False),
|
sa.Column('id', sa.String(length=4), nullable=False),
|
||||||
sa.Column('name', sa.String(length=25), nullable=False),
|
sa.Column('name', sa.String(length=100), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.PrimaryKeyConstraint('id')
|
||||||
)
|
)
|
||||||
op.create_table('profile',
|
op.create_table('profile',
|
||||||
@ -71,7 +71,7 @@ def upgrade():
|
|||||||
)
|
)
|
||||||
op.create_table('profile_language',
|
op.create_table('profile_language',
|
||||||
sa.Column('profile_id', sa.Integer(), nullable=False),
|
sa.Column('profile_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('language_id', sa.String(length=2), nullable=False),
|
sa.Column('language_id', sa.String(length=4), nullable=False),
|
||||||
sa.Column('level', sa.SmallInteger(), nullable=False),
|
sa.Column('level', sa.SmallInteger(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
|
sa.ForeignKeyConstraint(['language_id'], ['language.id'], ),
|
||||||
sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ),
|
sa.ForeignKeyConstraint(['profile_id'], ['profile.id'], ),
|
Reference in New Issue
Block a user