More standards compliant representation of skills

main
Bob Mottram 2021-05-13 14:27:35 +01:00
parent ccd02acfeb
commit 0cc86dc131
5 changed files with 132 additions and 45 deletions

View File

@ -98,6 +98,11 @@ from follow import getFollowingFeed
from follow import sendFollowRequest
from follow import unfollowAccount
from follow import createInitialLastSeen
from skills import getSkillsFromString
from skills import noOfActorSkills
from skills import actorHasSkill
from skills import actorSkillValue
from skills import setActorSkillLevel
from auth import authorize
from auth import createPassword
from auth import createBasicAuthHeader
@ -4191,7 +4196,7 @@ class PubServer(BaseHTTPRequestHandler):
# set skill levels
skillCtr = 1
newSkills = {}
actorSkillsCtr = noOfActorSkills(actorJson)
while skillCtr < 10:
skillName = \
fields.get('skillName' + str(skillCtr))
@ -4206,21 +4211,20 @@ class PubServer(BaseHTTPRequestHandler):
if not skillValue:
skillCtr += 1
continue
if not actorJson['skills'].get(skillName):
if not actorHasSkill(actorJson, skillName):
actorChanged = True
else:
if actorJson['skills'][skillName] != \
if actorSkillValue(actorJson, skillName) != \
int(skillValue):
actorChanged = True
newSkills[skillName] = int(skillValue)
setActorSkillLevel(actorJson, skillName, skillValue)
skillsStr = self.server.translate['Skills']
setHashtagCategory(baseDir, skillName,
skillsStr.lower())
skillCtr += 1
if len(actorJson['skills'].items()) != \
len(newSkills.items()):
if noOfActorSkills(actorJson) != \
actorSkillsCtr:
actorChanged = True
actorJson['skills'] = newSkills
# change password
if fields.get('password'):
@ -7461,7 +7465,7 @@ class PubServer(BaseHTTPRequestHandler):
if os.path.isfile(actorFilename):
actorJson = loadJson(actorFilename)
if actorJson:
if actorJson.get('skills'):
if noOfActorSkills(actorJson) > 0:
if self._requestHTTP():
getPerson = \
personLookup(domain,
@ -7486,6 +7490,9 @@ class PubServer(BaseHTTPRequestHandler):
if self.server.keyShortcuts.get(nickname):
accessKeys = \
self.server.keyShortcuts[nickname]
actorSkillsStr = \
actorJson['hasOccupation']['skills']
skills = getSkillsFromString(actorSkillsStr)
msg = \
htmlProfile(self.server.rssIconAtTop,
self.server.cssCache,
@ -7509,8 +7516,7 @@ class PubServer(BaseHTTPRequestHandler):
allowLocalNetworkAccess,
self.server.textModeBanner,
self.server.debug,
accessKeys,
actorJson['skills'],
accessKeys, skills,
None, None)
msg = msg.encode('utf-8')
msglen = len(msg)
@ -7523,7 +7529,10 @@ class PubServer(BaseHTTPRequestHandler):
'show skills')
else:
if self._fetchAuthenticated():
msg = json.dumps(actorJson['skills'],
actorSkillsStr = \
actorJson['hasOccupation']['skills']
skills = getSkillsFromString(actorSkillsStr)
msg = json.dumps(skills,
ensure_ascii=False)
msg = msg.encode('utf-8')
msglen = len(msg)

View File

@ -279,9 +279,8 @@ def _createPersonBase(baseDir: str, nickname: str, domain: str, port: int,
'hasOccupation': {
'@type': 'Occupation',
'name': "",
'skills': "",
'skills': ""
},
'skills': {},
'roles': {},
'availability': None,
'icon': {
@ -317,7 +316,8 @@ def _createPersonBase(baseDir: str, nickname: str, domain: str, port: int,
del newPerson['outbox']
del newPerson['icon']
del newPerson['image']
del newPerson['skills']
if newPerson.get('skills'):
del newPerson['skills']
del newPerson['shares']
del newPerson['roles']
del newPerson['tag']
@ -574,10 +574,14 @@ def personUpgradeActor(baseDir: str, personJson: {},
personJson['hasOccupation'] = {
'@type': 'Occupation',
'name': occupationName,
'skills': "",
'skills': ""
}
updateActor = True
if personJson.get('skills'):
del personJson['skills']
updateActor = True
if updateActor:
personJson['@context'] = [
'https://www.w3.org/ns/activitystreams',

101
skills.py
View File

@ -15,7 +15,89 @@ from utils import getFullDomain
from utils import getNicknameFromActor
from utils import getDomainFromActor
from utils import loadJson
from utils import saveJson
def _setSkillsFromDict(actorJson: {}, skills: {}) -> None:
"""Converts a dict containing skills to a string
"""
skillsStr = ''
for name, value in skills.items():
if skillsStr:
skillsStr += ', '
skillsStr += name + ':' + str(value)
return skillsStr
def getSkillsFromString(skillsStr: str) -> {}:
"""Returns a dict of skills from a string
"""
skillsList = skillsStr.split(',')
skills = {}
for skill in skillsList:
if ':' not in skill:
continue
name = skill.split(':')[0].strip().lower()
valueStr = skill.split(':')[1]
if not valueStr.isdigit():
continue
skills[name] = int(valueStr)
return skills
def actorHasSkill(actorJson: {}, skillName: str) -> bool:
"""Returns true if the actor has the given skill
"""
skills = getSkillsFromString(actorJson['hasOccupation']['skills'])
if not skills:
return False
return skills.get(skillName.lower())
def actorSkillValue(actorJson: {}, skillName: str) -> int:
"""Returns The skill level from an actor
"""
skills = getSkillsFromString(actorJson['hasOccupation']['skills'])
if not skills:
return 0
skillName = skillName.lower()
if skills.get(skillName):
return skills[skillName]
return 0
def noOfActorSkills(actorJson: {}) -> int:
"""Returns the number of skills that an actor has
"""
if actorJson.get('hasOccupation'):
skillsList = actorJson['hasOccupation']['skills'].split(',')
if skillsList:
return int(skillsList)
return 0
def setActorSkillLevel(actorJson: {},
skill: str, skillLevelPercent: int) -> bool:
"""Set a skill level for a person
Setting skill level to zero removes it
"""
if skillLevelPercent < 0 or skillLevelPercent > 100:
return False
if actorJson:
if not actorJson.get('hasOccupation'):
actorJson['hasOccupation'] = {
'@type': 'Occupation',
'name': '',
'skills': ''
}
skills = getSkillsFromString(actorJson['hasOccupation']['skills'])
if skillLevelPercent > 0:
skills[skill] = skillLevelPercent
else:
if skills.get(skill):
del skills[skill]
_setSkillsFromDict(actorJson, skills)
return True
def setSkillLevel(baseDir: str, nickname: str, domain: str,
@ -30,15 +112,8 @@ def setSkillLevel(baseDir: str, nickname: str, domain: str,
return False
actorJson = loadJson(actorFilename)
if actorJson:
if not actorJson.get('skills'):
actorJson['skills'] = {}
if skillLevelPercent > 0:
actorJson['skills'][skill] = skillLevelPercent
else:
del actorJson['skills'][skill]
saveJson(actorJson, actorFilename)
return True
return setActorSkillLevel(actorJson,
skill, skillLevelPercent)
def getSkills(baseDir: str, nickname: str, domain: str) -> []:
@ -50,9 +125,9 @@ def getSkills(baseDir: str, nickname: str, domain: str) -> []:
actorJson = loadJson(actorFilename)
if actorJson:
if not actorJson.get('skills'):
if not actorJson.get('hasOccupation'):
return None
return actorJson['skills']
return getSkillsFromString(actorJson['hasOccupation']['skills'])
return None
@ -112,7 +187,7 @@ def sendSkillViaServer(baseDir: str, session, nickname: str, password: str,
newSkillJson = {
'type': 'Skill',
'actor': actor,
'object': '"'+skillStr+'"',
'object': '"' + skillStr + '"',
'to': [toUrl],
'cc': [ccUrl]
}

View File

@ -20,6 +20,8 @@ from utils import locatePost
from utils import isPublicPost
from utils import firstParagraphFromString
from utils import searchBoxPosts
from skills import noOfActorSkills
from skills import getSkillsFromString
from categories import getHashtagCategory
from feeds import rss2TagHeader
from feeds import rss2TagFooter
@ -414,11 +416,13 @@ def htmlSkillsSearch(actor: str,
actorJson = loadJson(actorFilename)
if actorJson:
if actorJson.get('id') and \
actorJson.get('skills') and \
noOfActorSkills(actorJson) > 0 and \
actorJson.get('name') and \
actorJson.get('icon'):
actor = actorJson['id']
for skillName, skillLevel in actorJson['skills'].items():
actorSkillsStr = actorJson['hasOccupation']['skills']
skills = getSkillsFromString(actorSkillsStr)
for skillName, skillLevel in skills.items():
skillName = skillName.lower()
if not (skillName in skillsearch or
skillsearch in skillName):
@ -453,12 +457,14 @@ def htmlSkillsSearch(actor: str,
if cachedActorJson.get('actor'):
actorJson = cachedActorJson['actor']
if actorJson.get('id') and \
actorJson.get('skills') and \
noOfActorSkills(actorJson) > 0 and \
actorJson.get('name') and \
actorJson.get('icon'):
actor = actorJson['id']
for skillName, skillLevel in \
actorJson['skills'].items():
actorSkillsStr = \
actorJson['hasOccupation']['skills']
skills = getSkillsFromString(actorSkillsStr)
for skillName, skillLevel in skills.items():
skillName = skillName.lower()
if not (skillName in skillsearch or
skillsearch in skillName):

View File

@ -720,18 +720,11 @@ def htmlHeaderWithPersonMarkup(cssFilename: str, instanceTitle: str,
return htmlStr
skillsMarkup = ''
if actorJson.get('skills'):
skillsStr = ''
for skillName, skillValue in actorJson['skills'].items():
if skillsStr:
skillsStr += ', ' + skillName
else:
skillsStr += skillName
if skillsStr:
occupationStr = ''
if actorJson.get('occupationName'):
occupationName = actorJson['occupationName']
occupationStr = ' "name": "' + occupationName + '",\n'
if actorJson.get('hasOccupation'):
skillsStr = actorJson['hasOccupation']['skills']
if actorJson['hasOccupation'].get('name'):
occupationName = actorJson['hasOccupation']['name']
occupationStr = ' "name": "' + occupationName + '",\n'
skillsMarkup = \
' "hasOccupation": {\n' + \
' "@type": "Occupation",\n' + \