mirror of https://github.com/MISP/misp-dashboard
Updated ranking level decision + updated support of message for zmq + Updated badge acquisition display to match data in DB
parent
1550f25b30
commit
a3c853e490
|
@ -91,17 +91,18 @@ class Contributor_helper:
|
||||||
else:
|
else:
|
||||||
requirement_fulfilled.append(i)
|
requirement_fulfilled.append(i)
|
||||||
final_rank += 1
|
final_rank += 1
|
||||||
num_of_previous_req_not_fulfilled = len([x for x in requirement_not_fulfilled if x<final_rank])
|
#num_of_previous_req_not_fulfilled = len([x for x in requirement_not_fulfilled if x<final_rank])
|
||||||
final_rank = final_rank - num_of_previous_req_not_fulfilled
|
#final_rank = final_rank - num_of_previous_req_not_fulfilled
|
||||||
|
final_rank = len(requirement_fulfilled)
|
||||||
return {'final_rank': final_rank, 'req_fulfilled': requirement_fulfilled, 'req_not_fulfilled': requirement_not_fulfilled}
|
return {'final_rank': final_rank, 'req_fulfilled': requirement_fulfilled, 'req_not_fulfilled': requirement_not_fulfilled}
|
||||||
|
|
||||||
def giveContribRankToOrg(self, org, rankNum):
|
def giveContribRankToOrg(self, org, rankNum):
|
||||||
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
||||||
self.serv_redis_db.set(keyname.format(org=orgName, orgCateg='CONTRIB_REQ_'+str(rankNum)), 1)
|
self.serv_redis_db.set(keyname.format(org=org, orgCateg='CONTRIB_REQ_'+str(rankNum)), 1)
|
||||||
|
|
||||||
def removeContribRankFromOrg(self, org, rankNum):
|
def removeContribRankFromOrg(self, org, rankNum):
|
||||||
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
||||||
self.serv_redis_db.delete(keyname.format(org=orgName, orgCateg='CONTRIB_REQ_'+str(rankNum)))
|
self.serv_redis_db.delete(keyname.format(org=org, orgCateg='CONTRIB_REQ_'+str(rankNum)))
|
||||||
|
|
||||||
# 1 for fulfilled, 0 for not fulfilled, -1 for not relevant
|
# 1 for fulfilled, 0 for not fulfilled, -1 for not relevant
|
||||||
def getCurrentContributionStatus(self, org):
|
def getCurrentContributionStatus(self, org):
|
||||||
|
@ -119,16 +120,38 @@ class Contributor_helper:
|
||||||
to_ret[i] = -1
|
to_ret[i] = -1
|
||||||
return {'rank': final_rank, 'status': to_ret, 'totPoints': self.getOrgContributionTotalPoints(org)}
|
return {'rank': final_rank, 'status': to_ret, 'totPoints': self.getOrgContributionTotalPoints(org)}
|
||||||
|
|
||||||
def updateOrgContributionRank(self, orgName, pnts_to_add, contribType, eventTime, isLabeled):
|
def updateOrgContributionRank(self, orgName, pnts_to_add, action, contribType, eventTime, isLabeled):
|
||||||
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
||||||
#update total points
|
# update total points
|
||||||
totOrgPnts = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='points'), pnts_to_add)
|
totOrgPnts = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='points'), pnts_to_add)
|
||||||
|
|
||||||
|
# update date variables
|
||||||
|
if contribType == 'Attribute':
|
||||||
|
attributeWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='ATTR_WEEK_COUNT'), 1)
|
||||||
|
self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='ATTR_WEEK_COUNT'), util.ONE_DAY*7)
|
||||||
|
|
||||||
|
if contribType == 'Proposal':
|
||||||
|
proposalWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='PROP_WEEK_COUNT'), 1)
|
||||||
|
self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='PROP_WEEK_COUNT'), util.ONE_DAY*7)
|
||||||
|
|
||||||
|
if contribType == 'Sighting':
|
||||||
|
sightingWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='SIGHT_WEEK_COUNT'), 1)
|
||||||
|
self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='SIGHT_WEEK_COUNT'), util.ONE_DAY*7)
|
||||||
|
|
||||||
|
if contribType == 'Event':
|
||||||
|
eventWeekCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='EVENT_WEEK_COUNT'), 1)
|
||||||
|
self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='EVENT_WEEK_COUNT'), util.ONE_DAY*7)
|
||||||
|
|
||||||
|
eventMonthCount = self.serv_redis_db.incrby(keyname.format(org=orgName, orgCateg='EVENT_MONTH_COUNT'), 1)
|
||||||
|
self.serv_redis_db.expire(keyname.format(org=orgName, orgCateg='EVENT_MONTH_COUNT'), util.ONE_DAY*7)
|
||||||
|
|
||||||
# getRequirement parameters
|
# getRequirement parameters
|
||||||
heavilyCount = self.heavilyCount
|
heavilyCount = self.heavilyCount
|
||||||
recentDays = self.recentDays
|
recentDays = self.recentDays
|
||||||
regularlyDays = self.regularlyDays
|
regularlyDays = self.regularlyDays
|
||||||
isRecent = (datetime.datetime.now() - eventTime).days > recentDays
|
isRecent = (datetime.datetime.now() - eventTime).days > recentDays
|
||||||
|
|
||||||
|
print("contribType: {}, action: {}".format(contribType, action))
|
||||||
print("isLabeled: {}, isRecent: {}, totOrgPnts".format(isLabeled, isRecent, totOrgPnts))
|
print("isLabeled: {}, isRecent: {}, totOrgPnts".format(isLabeled, isRecent, totOrgPnts))
|
||||||
#update contribution Requirement
|
#update contribution Requirement
|
||||||
contrib = [] #[[contrib_level, contrib_ttl], [], ...]
|
contrib = [] #[[contrib_level, contrib_ttl], [], ...]
|
||||||
|
@ -145,9 +168,9 @@ class Contributor_helper:
|
||||||
contrib.append([5, util.ONE_DAY*recentDays])
|
contrib.append([5, util.ONE_DAY*recentDays])
|
||||||
if totOrgPnts >= self.org_rank_requirement_pnts[6] and contribType == 'Event':
|
if totOrgPnts >= self.org_rank_requirement_pnts[6] and contribType == 'Event':
|
||||||
contrib.append([6, util.ONE_DAY*365])
|
contrib.append([6, util.ONE_DAY*365])
|
||||||
if totOrgPnts >= self.org_rank_requirement_pnts[7] and contribType == 'Event':
|
if totOrgPnts >= self.org_rank_requirement_pnts[7] and contribType == 'Event' and eventMonthCount>=1:
|
||||||
contrib.append([7, util.ONE_DAY*recentDays])
|
contrib.append([7, util.ONE_DAY*recentDays])
|
||||||
if totOrgPnts >= self.org_rank_requirement_pnts[8] and contribType == 'Event':
|
if totOrgPnts >= self.org_rank_requirement_pnts[8] and contribType == 'Event' and eventWeekCount>=1:
|
||||||
contrib.append([8, util.ONE_DAY*regularlyDays])
|
contrib.append([8, util.ONE_DAY*regularlyDays])
|
||||||
if totOrgPnts >= self.org_rank_requirement_pnts[9] and contribType == 'Event' and isLabeled:
|
if totOrgPnts >= self.org_rank_requirement_pnts[9] and contribType == 'Event' and isLabeled:
|
||||||
contrib.append([9, util.ONE_DAY*regularlyDays])
|
contrib.append([9, util.ONE_DAY*regularlyDays])
|
||||||
|
@ -179,11 +202,11 @@ class Contributor_helper:
|
||||||
|
|
||||||
def giveBadgeToOrg(self, org, badgeNum):
|
def giveBadgeToOrg(self, org, badgeNum):
|
||||||
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
||||||
self.serv_redis_db.set(keyname.format(org=orgName, orgCateg='BADGE_'+str(badgeNum)), 1)
|
self.serv_redis_db.set(keyname.format(org=org, orgCateg='BADGE_'+str(badgeNum)), 1)
|
||||||
|
|
||||||
def removeBadgeFromOrg(self, org, badgeNum):
|
def removeBadgeFromOrg(self, org, badgeNum):
|
||||||
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
keyname = 'CONTRIB_ORG:{org}:{orgCateg}'
|
||||||
self.serv_redis_db.delete(keyname.format(org=orgName, orgCateg='BADGE_'+str(badgeNum)))
|
self.serv_redis_db.delete(keyname.format(org=org, orgCateg='BADGE_'+str(badgeNum)))
|
||||||
|
|
||||||
''' MONTHLY CONTRIBUTION '''
|
''' MONTHLY CONTRIBUTION '''
|
||||||
def getOrgPntFromRedis(self, org, date):
|
def getOrgPntFromRedis(self, org, date):
|
||||||
|
|
|
@ -324,6 +324,46 @@ function addLastContributor(datatable, data, update) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateProgressBar(org) {
|
||||||
|
if(currOrg != org)
|
||||||
|
return;
|
||||||
|
$.getJSON( url_getOrgRank+'?org='+org, function( data ) {
|
||||||
|
var rank = Math.floor(data.rank);
|
||||||
|
var rankDec = data.rank-rank;
|
||||||
|
var popoverRank = $('#btnCurrRank').data('bs.popover');
|
||||||
|
popoverRank.options.content = generateRankingSheet(rank, rankDec, data.stepPts, data.points, data.remainingPts);
|
||||||
|
$('#orgRankDiv').html(getMonthlyRankIcon(rank, 40, true));
|
||||||
|
$('#orgNextRankDiv').html(getMonthlyRankIcon(rank+1, 40, true));
|
||||||
|
if (data.rank > 16){
|
||||||
|
$('#progressBarDiv').width(1*150); //150 is empty bar width
|
||||||
|
} else {
|
||||||
|
$('#progressBarDiv').width((data.rank - rank)*150); //150 is empty bar width
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOvertakePnts() {
|
||||||
|
var prevOrgName = "";
|
||||||
|
var prevOrgPnts = 0;
|
||||||
|
datatableTop.rows().every( function() {
|
||||||
|
var row = this.node();
|
||||||
|
var orgRowName = $(this.data()[5])[0].text; // contained in <a>
|
||||||
|
var orgRowPnts = this.data()[0]
|
||||||
|
if(orgRowName == currOrg) {
|
||||||
|
if(prevOrgName == ""){ //already first
|
||||||
|
$('#orgToOverTake').text(orgRowName);
|
||||||
|
$('#pntsToOvertakeNext').text(0);
|
||||||
|
} else {
|
||||||
|
$('#orgToOverTake').text(prevOrgName);
|
||||||
|
$('#pntsToOvertakeNext').text(parseInt(prevOrgPnts)-orgRowPnts);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prevOrgName = orgRowName;
|
||||||
|
prevOrgPnts = orgRowPnts;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateProgressHeader(org) {
|
function updateProgressHeader(org) {
|
||||||
currOrg = org;
|
currOrg = org;
|
||||||
// get Org rank
|
// get Org rank
|
||||||
|
@ -395,36 +435,16 @@ function updateProgressHeader(org) {
|
||||||
|
|
||||||
// colorize badge if acquired
|
// colorize badge if acquired
|
||||||
$.getJSON( url_getHonorBadges+'?org='+org, function( data ) {
|
$.getJSON( url_getHonorBadges+'?org='+org, function( data ) {
|
||||||
for(var i=0; i<data.length; i++) {
|
for(var i=0; i<numberOfBadges; i++) { // remove
|
||||||
if (data[i] == 1) {
|
|
||||||
$('#divBadge_'+(i+1)).addClass('circlBadgeAcquired');
|
|
||||||
} else {
|
|
||||||
$('#divBadge_'+(i+1)).removeClass('circlBadgeAcquired');
|
$('#divBadge_'+(i+1)).removeClass('circlBadgeAcquired');
|
||||||
}
|
}
|
||||||
|
for(var i=0; i<data.length; i++) { // add
|
||||||
|
$('#divBadge_'+(data[i])).addClass('circlBadgeAcquired');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//update overtake points
|
//update overtake points
|
||||||
var prevOrgName = "";
|
updateOvertakePnts();
|
||||||
var prevOrgPnts = 0;
|
|
||||||
datatableTop.rows().every( function() {
|
|
||||||
var row = this.node();
|
|
||||||
var orgRowName = $(this.data()[5])[0].text; // contained in <a>
|
|
||||||
var orgRowPnts = this.data()[0]
|
|
||||||
if(orgRowName == currOrg) {
|
|
||||||
if(prevOrgName == ""){ //already first
|
|
||||||
$('#orgToOverTake').text(orgRowName);
|
|
||||||
$('#pntsToOvertakeNext').text(0);
|
|
||||||
} else {
|
|
||||||
$('#orgToOverTake').text(prevOrgName);
|
|
||||||
$('#pntsToOvertakeNext').text(parseInt(prevOrgPnts)-orgRowPnts);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
prevOrgName = orgRowName;
|
|
||||||
prevOrgPnts = orgRowPnts;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//Add new data to linechart
|
//Add new data to linechart
|
||||||
$.getJSON( url_getOrgOvertime+'?org='+org, function( data ) {
|
$.getJSON( url_getOrgOvertime+'?org='+org, function( data ) {
|
||||||
var toPlot = dataTop5Overtime.slice(0); //cloning data
|
var toPlot = dataTop5Overtime.slice(0); //cloning data
|
||||||
|
@ -531,7 +551,8 @@ $(document).ready(function() {
|
||||||
var json = jQuery.parseJSON( event.data );
|
var json = jQuery.parseJSON( event.data );
|
||||||
addLastContributor(datatableLast, json, true);
|
addLastContributor(datatableLast, json, true);
|
||||||
datatableLast.draw();
|
datatableLast.draw();
|
||||||
updateProgressHeader(json.org)
|
updateProgressBar(json.org);
|
||||||
|
updateOvertakePnts();
|
||||||
sec_before_reload = refresh_speed; //reset timer at each contribution
|
sec_before_reload = refresh_speed; //reset timer at each contribution
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -397,6 +397,7 @@
|
||||||
var categ_list = JSON.parse('{{ categ_list|safe }}');
|
var categ_list = JSON.parse('{{ categ_list|safe }}');
|
||||||
var org_rank_obj = JSON.parse('{{ org_rank_json|safe }}');
|
var org_rank_obj = JSON.parse('{{ org_rank_json|safe }}');
|
||||||
var org_honor_badge_title = JSON.parse('{{ org_honor_badge_title|safe }}');
|
var org_honor_badge_title = JSON.parse('{{ org_honor_badge_title|safe }}');
|
||||||
|
var numberOfBadges = {{ org_honor_badge_title_list|length }};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script src="{{ url_for('static', filename='js/contrib.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/contrib.js') }}"></script>
|
||||||
|
|
|
@ -126,15 +126,21 @@ def getFields(obj, fields):
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def noSpaceLower(str):
|
def noSpaceLower(text):
|
||||||
return str.lower().replace(' ', '_')
|
return text.lower().replace(' ', '_')
|
||||||
|
|
||||||
#pntMultiplier if one contribution rewards more than others. (e.g. shighting may gives more points than editing)
|
#pntMultiplier if one contribution rewards more than others. (e.g. shighting may gives more points than editing)
|
||||||
def handleContribution(zmq_name, org, contribType, categ, action, pntMultiplier=1, eventTime=datetime.datetime.now(), isLabeled=False):
|
def handleContribution(zmq_name, org, contribType, categ, action, pntMultiplier=1, eventTime=datetime.datetime.now(), isLabeled=False):
|
||||||
if action in ['edit', None]:
|
if action in ['edit', None]:
|
||||||
pass
|
pass
|
||||||
#return #not a contribution?
|
#return #not a contribution?
|
||||||
|
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
nowSec = int(time.time())
|
||||||
|
pnts_to_add = DEFAULT_PNTS_REWARD
|
||||||
|
|
||||||
# is a valid contribution
|
# is a valid contribution
|
||||||
|
if categ is not None:
|
||||||
try:
|
try:
|
||||||
pnts_to_add = DICO_PNTS_REWARD[noSpaceLower(categ)]
|
pnts_to_add = DICO_PNTS_REWARD[noSpaceLower(categ)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -144,16 +150,15 @@ def handleContribution(zmq_name, org, contribType, categ, action, pntMultiplier=
|
||||||
push_to_redis_zset('CONTRIB_DAY', org, count=pnts_to_add)
|
push_to_redis_zset('CONTRIB_DAY', org, count=pnts_to_add)
|
||||||
#CONTRIB_CATEG retain the contribution per category, not the point earned in this categ
|
#CONTRIB_CATEG retain the contribution per category, not the point earned in this categ
|
||||||
push_to_redis_zset('CONTRIB_CATEG', org, count=DEFAULT_PNTS_REWARD, endSubkey=':'+noSpaceLower(categ))
|
push_to_redis_zset('CONTRIB_CATEG', org, count=DEFAULT_PNTS_REWARD, endSubkey=':'+noSpaceLower(categ))
|
||||||
|
publish_log(zmq_name, 'CONTRIBUTION', {'org': org, 'categ': categ, 'action': action, 'epoch': nowSec }, channel=CHANNEL_LASTCONTRIB)
|
||||||
|
|
||||||
serv_redis_db.sadd('CONTRIB_ALL_ORG', org)
|
serv_redis_db.sadd('CONTRIB_ALL_ORG', org)
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
|
||||||
nowSec = int(time.time())
|
|
||||||
serv_redis_db.zadd('CONTRIB_LAST:'+util.getDateStrFormat(now), nowSec, org)
|
serv_redis_db.zadd('CONTRIB_LAST:'+util.getDateStrFormat(now), nowSec, org)
|
||||||
serv_redis_db.expire('CONTRIB_LAST:'+util.getDateStrFormat(now), ONE_DAY) #expire after 1 day
|
serv_redis_db.expire('CONTRIB_LAST:'+util.getDateStrFormat(now), ONE_DAY) #expire after 1 day
|
||||||
|
|
||||||
contributor_helper.updateOrgContributionRank(org, pnts_to_add, contribType, eventTime=datetime.datetime.now(), isLabeled=isLabeled)
|
contributor_helper.updateOrgContributionRank(org, pnts_to_add, action, contribType, eventTime=datetime.datetime.now(), isLabeled=isLabeled)
|
||||||
|
|
||||||
publish_log(zmq_name, 'CONTRIBUTION', {'org': org, 'categ': categ, 'action': action, 'epoch': nowSec }, channel=CHANNEL_LASTCONTRIB)
|
|
||||||
|
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
@ -173,6 +178,10 @@ def handler_keepalive(zmq_name, jsonevent):
|
||||||
to_push = [ jsonevent['uptime'] ]
|
to_push = [ jsonevent['uptime'] ]
|
||||||
publish_log(zmq_name, 'Keepalive', to_push)
|
publish_log(zmq_name, 'Keepalive', to_push)
|
||||||
|
|
||||||
|
def handler_object(zmq_name, jsondata):
|
||||||
|
print('obj')
|
||||||
|
return
|
||||||
|
|
||||||
def handler_sighting(zmq_name, jsondata):
|
def handler_sighting(zmq_name, jsondata):
|
||||||
print('sending' ,'sighting')
|
print('sending' ,'sighting')
|
||||||
jsonsight = jsondata['Sighting']
|
jsonsight = jsondata['Sighting']
|
||||||
|
@ -199,6 +208,26 @@ def handler_event(zmq_name, jsonobj):
|
||||||
else:
|
else:
|
||||||
handler_attribute(zmq_name, attributes)
|
handler_attribute(zmq_name, attributes)
|
||||||
|
|
||||||
|
try:
|
||||||
|
action = jsonobj['action']
|
||||||
|
except KeyError:
|
||||||
|
action = None
|
||||||
|
try:
|
||||||
|
eventLabeled = len(jsonobj['EventTag']) > 0
|
||||||
|
except KeyError:
|
||||||
|
eventLabeled = False
|
||||||
|
try:
|
||||||
|
org = jsonobj['Orgc']['name']
|
||||||
|
except KeyError:
|
||||||
|
org = None
|
||||||
|
|
||||||
|
if org is not None:
|
||||||
|
handleContribution(zmq_name, org,
|
||||||
|
'Event',
|
||||||
|
None,
|
||||||
|
action,
|
||||||
|
isLabeled=eventLabeled)
|
||||||
|
|
||||||
def handler_attribute(zmq_name, jsonobj, hasAlreadyBeenContributed=False):
|
def handler_attribute(zmq_name, jsonobj, hasAlreadyBeenContributed=False):
|
||||||
# check if jsonattr is an attribute object
|
# check if jsonattr is an attribute object
|
||||||
if 'Attribute' in jsonobj:
|
if 'Attribute' in jsonobj:
|
||||||
|
@ -267,6 +296,7 @@ dico_action = {
|
||||||
"misp_json_event": handler_event,
|
"misp_json_event": handler_event,
|
||||||
"misp_json_self": handler_keepalive,
|
"misp_json_self": handler_keepalive,
|
||||||
"misp_json_attribute": handler_attribute,
|
"misp_json_attribute": handler_attribute,
|
||||||
|
"misp_json_object": handler_object,
|
||||||
"misp_json_sighting": handler_sighting,
|
"misp_json_sighting": handler_sighting,
|
||||||
"misp_json_organisation": handler_log,
|
"misp_json_organisation": handler_log,
|
||||||
"misp_json_user": handler_log,
|
"misp_json_user": handler_log,
|
||||||
|
|
Loading…
Reference in New Issue