mirror of https://github.com/MISP/misp-dashboard
Merge branch 'skill_trophies' into users
commit
d7293af2e3
|
@ -70,7 +70,8 @@ regularlyDays=7
|
||||||
5=Has published loads of valuable content for the community
|
5=Has published loads of valuable content for the community
|
||||||
|
|
||||||
[TrophyDifficulty]
|
[TrophyDifficulty]
|
||||||
difficulty=5
|
#represent the % of org that can have this rank. Rank 1 is ignored as only 1 org can have it.
|
||||||
|
trophyMapping=[2, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||||
|
|
||||||
[HonorTrophy]
|
[HonorTrophy]
|
||||||
0=No trophy
|
0=No trophy
|
||||||
|
@ -83,7 +84,9 @@ difficulty=5
|
||||||
7=Skilled
|
7=Skilled
|
||||||
8=Advanced
|
8=Advanced
|
||||||
9=Expert
|
9=Expert
|
||||||
10=Master
|
10=Pro
|
||||||
|
11=Master
|
||||||
|
12=Grand Master
|
||||||
|
|
||||||
[HonorTrophyCateg]
|
[HonorTrophyCateg]
|
||||||
categ=["internal_reference", "targeting_data", "antivirus_detection", "payload_delivery", "artifacts_dropped", "payload_installation", "persistence_mechanism", "network_activity", "payload_type", "attribution", "external_analysis", "financial_fraud", "support_Tool", "social_network", "person", "other" ]
|
categ=["internal_reference", "targeting_data", "antivirus_detection", "payload_delivery", "artifacts_dropped", "payload_installation", "persistence_mechanism", "network_activity", "payload_type", "attribution", "external_analysis", "financial_fraud", "support_Tool", "social_network", "person", "other" ]
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Contributor_helper:
|
||||||
for badgeNum in range(1, self.honorBadgeNum+1): #get Num of honorBadge
|
for badgeNum in range(1, self.honorBadgeNum+1): #get Num of honorBadge
|
||||||
self.org_honor_badge_title[badgeNum] = self.cfg_org_rank.get('HonorBadge', str(badgeNum))
|
self.org_honor_badge_title[badgeNum] = self.cfg_org_rank.get('HonorBadge', str(badgeNum))
|
||||||
|
|
||||||
self.trophyDifficulty = self.cfg_org_rank.getfloat('TrophyDifficulty', 'difficulty')
|
self.trophyMapping = json.loads(self.cfg_org_rank.get('TrophyDifficulty', 'trophyMapping'))
|
||||||
self.trophyNum = len(self.cfg_org_rank.options('HonorTrophy'))-1 #0 is not a trophy
|
self.trophyNum = len(self.cfg_org_rank.options('HonorTrophy'))-1 #0 is not a trophy
|
||||||
self.categories_in_trophy = json.loads(self.cfg_org_rank.get('HonorTrophyCateg', 'categ'))
|
self.categories_in_trophy = json.loads(self.cfg_org_rank.get('HonorTrophyCateg', 'categ'))
|
||||||
self.trophy_title = {}
|
self.trophy_title = {}
|
||||||
|
@ -264,25 +264,58 @@ class Contributor_helper:
|
||||||
|
|
||||||
''' TROPHIES '''
|
''' TROPHIES '''
|
||||||
def getOrgTrophies(self, org):
|
def getOrgTrophies(self, org):
|
||||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
self.getAllOrgsTrophyRanking()
|
||||||
|
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||||
trophy = []
|
trophy = []
|
||||||
for categ in self.categories_in_trophy:
|
for categ in self.categories_in_trophy:
|
||||||
key = keyname.format(org=org, orgCateg=categ)
|
key = keyname.format(orgCateg=categ)
|
||||||
trophy_Pnts = self.serv_redis_db.get(key)
|
totNum = self.serv_redis_db.zcard(key)
|
||||||
if trophy_Pnts is not None: #existing
|
if totNum == 0:
|
||||||
trophy_Pnts = float(trophy_Pnts.decode('utf8'))
|
continue
|
||||||
trophy_rank = self.getRankTrophy(trophy_Pnts)
|
pos = self.serv_redis_db.zrank(key, org)
|
||||||
trophy_true_rank = self.getTrueRankTrophy(trophy_Pnts)
|
if pos is None:
|
||||||
trophy.append({ 'categ': categ, 'trophy_points': trophy_Pnts, 'trophy_rank': trophy_rank, 'trophy_true_rank': trophy_true_rank, 'trophy_title': self.trophy_title[trophy_true_rank]})
|
continue
|
||||||
|
trophy_rank = self.posToRankMapping(pos, totNum)
|
||||||
|
trophy_Pnts = self.serv_redis_db.zscore(key, org)
|
||||||
|
trophy.append({ 'categ': categ, 'trophy_points': trophy_Pnts, 'trophy_rank': trophy_rank, 'trophy_true_rank': trophy_rank, 'trophy_title': self.trophy_title[trophy_rank]})
|
||||||
return trophy
|
return trophy
|
||||||
|
|
||||||
|
def getOrgsTrophyRanking(self, categ):
|
||||||
|
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||||
|
res = self.serv_redis_db.zrange(keyname.format(orgCateg=categ), 0, -1, withscores=True, desc=True)
|
||||||
|
res = [[org.decode('utf8'), score] for org, score in res]
|
||||||
|
return res
|
||||||
|
|
||||||
|
def getAllOrgsTrophyRanking(self):
|
||||||
|
dico_categ = {}
|
||||||
|
for categ in self.categories_in_trophy:
|
||||||
|
res = self.getOrgsTrophyRanking(categ)
|
||||||
|
dico_categ[categ] = res
|
||||||
|
|
||||||
|
def posToRankMapping(self, pos, totNum):
|
||||||
|
mapping = self.trophyMapping
|
||||||
|
mapping_num = [math.ceil(float(float(totNum*i)/float(100))) for i in mapping]
|
||||||
|
# print(pos, totNum)
|
||||||
|
if pos == 0: #first
|
||||||
|
position = 1
|
||||||
|
else:
|
||||||
|
temp_pos = pos
|
||||||
|
counter = 1
|
||||||
|
for num in mapping_num:
|
||||||
|
if temp_pos < num:
|
||||||
|
position = counter
|
||||||
|
else:
|
||||||
|
temp_pos -= num
|
||||||
|
counter += 1
|
||||||
|
return self.trophyNum+1 - position
|
||||||
|
|
||||||
def giveTrophyPointsToOrg(self, org, categ, points):
|
def giveTrophyPointsToOrg(self, org, categ, points):
|
||||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||||
self.serv_redis_db.incrby(keyname.format(org=org, orgCateg=categ), points)
|
self.serv_redis_db.zincrby(keyname.format(orgCateg=categ), org, points)
|
||||||
|
|
||||||
def removeTrophyPointsFromOrg(self, org, categ, points):
|
def removeTrophyPointsFromOrg(self, org, categ, points):
|
||||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||||
self.serv_redis_db.incrby(keyname.format(org=org, orgCateg=categ), -points)
|
self.serv_redis_db.zincrby(keyname.format(orgCateg=categ), org, -points)
|
||||||
|
|
||||||
''' AWARDS HELPER '''
|
''' AWARDS HELPER '''
|
||||||
def getLastAwardsFromRedis(self):
|
def getLastAwardsFromRedis(self):
|
||||||
|
@ -469,19 +502,6 @@ class Contributor_helper:
|
||||||
prev = i
|
prev = i
|
||||||
return { 'remainingPts': 0, 'stepPts': self.rankMultiplier**self.levelMax }
|
return { 'remainingPts': 0, 'stepPts': self.rankMultiplier**self.levelMax }
|
||||||
|
|
||||||
def getRankTrophy(self, points):
|
|
||||||
if points <= 0:
|
|
||||||
return 0
|
|
||||||
elif points == 1:
|
|
||||||
return 1
|
|
||||||
else:
|
|
||||||
rank = math.sqrt(points/self.trophyDifficulty)
|
|
||||||
rank = min(self.trophyNum, rank)
|
|
||||||
return float("{:.2f}".format(rank))
|
|
||||||
|
|
||||||
def getTrueRankTrophy(self, ptns):
|
|
||||||
return int(self.getRankTrophy(ptns))
|
|
||||||
|
|
||||||
''' '''
|
''' '''
|
||||||
''' TEST DATA '''
|
''' TEST DATA '''
|
||||||
''' '''
|
''' '''
|
||||||
|
|
|
@ -171,6 +171,11 @@ def contrib():
|
||||||
trophy_categ_list = contributor_helper.categories_in_trophy
|
trophy_categ_list = contributor_helper.categories_in_trophy
|
||||||
trophy_categ_list_str = [ s[0].upper() + s[1:].replace('_', ' ') for s in trophy_categ_list]
|
trophy_categ_list_str = [ s[0].upper() + s[1:].replace('_', ' ') for s in trophy_categ_list]
|
||||||
trophy_title = contributor_helper.trophy_title
|
trophy_title = contributor_helper.trophy_title
|
||||||
|
trophy_title_str = []
|
||||||
|
for i in range(contributor_helper.trophyNum+1):
|
||||||
|
trophy_title_str.append(trophy_title[i])
|
||||||
|
trophy_mapping = ["Top 1"] + [ str(x)+"%" for x in contributor_helper.trophyMapping] + [" "]
|
||||||
|
trophy_mapping.reverse()
|
||||||
|
|
||||||
currOrg = request.args.get('org')
|
currOrg = request.args.get('org')
|
||||||
if currOrg is None:
|
if currOrg is None:
|
||||||
|
@ -192,6 +197,8 @@ def contrib():
|
||||||
trophy_categ_list_id=trophy_categ_list,
|
trophy_categ_list_id=trophy_categ_list,
|
||||||
trophy_categ_list_str=trophy_categ_list_str,
|
trophy_categ_list_str=trophy_categ_list_str,
|
||||||
trophy_title=json.dumps(trophy_title),
|
trophy_title=json.dumps(trophy_title),
|
||||||
|
trophy_title_str=trophy_title_str,
|
||||||
|
trophy_mapping=trophy_mapping,
|
||||||
min_between_reload=cfg.getint('CONTRIB', 'min_between_reload')
|
min_between_reload=cfg.getint('CONTRIB', 'min_between_reload')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,34 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<p style="font-size: 18px; display: inline;">Trophies: </p><p style="display: inline;">Shows your skills in information sharing </p><i> (earned via upvotes or sightings from other organisation)</i>
|
<p style="font-size: 18px; display: inline;">Trophies: </p><p style="display: inline;">Shows your skills in information sharing </p><i> (earned via upvotes or sightings from other organisation)</i>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{% for title in trophy_title_str %}
|
||||||
|
<th>{{ title }}</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id='bodyTableTrophyModal'>
|
||||||
|
<tr>
|
||||||
|
{% for perc in trophy_mapping %}
|
||||||
|
<td>{{ perc }}</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
{% for title in trophy_title_str %}
|
||||||
|
<td>
|
||||||
|
<input type='image' style="display: block; margin-left: auto; margin-right: auto;" height="64" width="64" src="{{ url_for('static', filename='pics/MISPTrophy/'+loop.index0|string+'.png') }}">
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style="font-size: 18px; display: inline;">Acquired trophies: </p>
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
Loading…
Reference in New Issue