mirror of https://github.com/MISP/misp-dashboard
Merge branch 'skill_trophies' into trendings
commit
0c057dfe2d
|
@ -70,7 +70,8 @@ regularlyDays=7
|
|||
5=Has published loads of valuable content for the community
|
||||
|
||||
[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]
|
||||
0=No trophy
|
||||
|
@ -83,7 +84,9 @@ difficulty=5
|
|||
7=Skilled
|
||||
8=Advanced
|
||||
9=Expert
|
||||
10=Master
|
||||
10=Pro
|
||||
11=Master
|
||||
12=Grand Master
|
||||
|
||||
[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" ]
|
||||
|
|
|
@ -22,7 +22,7 @@ class Contributor_helper:
|
|||
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.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.categories_in_trophy = json.loads(self.cfg_org_rank.get('HonorTrophyCateg', 'categ'))
|
||||
self.trophy_title = {}
|
||||
|
@ -264,25 +264,58 @@ class Contributor_helper:
|
|||
|
||||
''' TROPHIES '''
|
||||
def getOrgTrophies(self, org):
|
||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
||||
self.getAllOrgsTrophyRanking()
|
||||
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||
trophy = []
|
||||
for categ in self.categories_in_trophy:
|
||||
key = keyname.format(org=org, orgCateg=categ)
|
||||
trophy_Pnts = self.serv_redis_db.get(key)
|
||||
if trophy_Pnts is not None: #existing
|
||||
trophy_Pnts = float(trophy_Pnts.decode('utf8'))
|
||||
trophy_rank = self.getRankTrophy(trophy_Pnts)
|
||||
trophy_true_rank = self.getTrueRankTrophy(trophy_Pnts)
|
||||
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]})
|
||||
key = keyname.format(orgCateg=categ)
|
||||
totNum = self.serv_redis_db.zcard(key)
|
||||
if totNum == 0:
|
||||
continue
|
||||
pos = self.serv_redis_db.zrank(key, org)
|
||||
if pos is None:
|
||||
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
|
||||
|
||||
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):
|
||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
||||
self.serv_redis_db.incrby(keyname.format(org=org, orgCateg=categ), points)
|
||||
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||
self.serv_redis_db.zincrby(keyname.format(orgCateg=categ), org, points)
|
||||
|
||||
def removeTrophyPointsFromOrg(self, org, categ, points):
|
||||
keyname = 'CONTRIB_TROPHY:{org}:{orgCateg}'
|
||||
self.serv_redis_db.incrby(keyname.format(org=org, orgCateg=categ), -points)
|
||||
keyname = 'CONTRIB_TROPHY:{orgCateg}'
|
||||
self.serv_redis_db.zincrby(keyname.format(orgCateg=categ), org, -points)
|
||||
|
||||
''' AWARDS HELPER '''
|
||||
def getLastAwardsFromRedis(self):
|
||||
|
@ -469,19 +502,6 @@ class Contributor_helper:
|
|||
prev = i
|
||||
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 '''
|
||||
''' '''
|
||||
|
|
|
@ -173,6 +173,11 @@ def contrib():
|
|||
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_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')
|
||||
if currOrg is None:
|
||||
|
@ -194,6 +199,8 @@ def contrib():
|
|||
trophy_categ_list_id=trophy_categ_list,
|
||||
trophy_categ_list_str=trophy_categ_list_str,
|
||||
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')
|
||||
)
|
||||
|
||||
|
|
|
@ -182,6 +182,34 @@
|
|||
</table>
|
||||
</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>
|
||||
|
||||
<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">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
|
|
Loading…
Reference in New Issue