Skip to content

Commit

Permalink
Release 0.1.2 (#1)
Browse files Browse the repository at this point in the history
* - Added Extraction Icon
- Added No Active Training when Character has no Active Pilot Licence
- Changed Skillfarm API now display both SkillQueue and SkillQueue Filtered
- Performance Updates

* Bump to 0.1.2

* Update README
  • Loading branch information
Geuthur authored Sep 22, 2024
1 parent dd10ed7 commit 9bfddb0
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 41 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## \[0.1.2\] - 2024-09-22

### Added

- Skillfarm
- Skill Extraktion Icon
- Info Button Color change when Skill Extraktion is ready

### Fixed

- Skillfarm Progressbar
- Display more then 100%
- If no Filter is active display 0%
- Shows `No Active Training` although active training is in progress

### Changed

- Skillfarm API
- Performance Optimations
- Added Skillqueue & Skillqueue Filtered

## \[0.1.1\] - 2024-09-22

### Added
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ ______________________________________________________________________
## Features<a name="features"></a>

- Graphical Design
- Characters Overview
- Skillfarm Information Sheet
- Filtered Skill Queue
- Filtered Skills
- Highlight finished Skills
- Filter Skills for each Character
- Characters Overview
- Highlight finished Skills
- No Active Training hint

## Upcoming<a name="upcoming"></a>

Expand Down
2 changes: 1 addition & 1 deletion skillfarm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from skillfarm.app_settings import SKILLFARM_APP_NAME

__version__ = "0.1.1"
__version__ = "0.1.2"
__title__ = "Skillfarm"

USER_AGENT_TEXT = f"{SKILLFARM_APP_NAME} v{__version__}"
58 changes: 37 additions & 21 deletions skillfarm/api/character/skillfarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def get_character_skillfarm(request, character_id: int):
characters = [main]

skills_queue_dict = defaultdict(list)
skills_queue_dict_filtered = defaultdict(list)
skills_dict = defaultdict(list)
characters_dict = []
output = []
Expand All @@ -55,9 +56,11 @@ def get_character_skillfarm(request, character_id: int):
eve_group__eve_category__id=16
).values_list("name", flat=True)

# Get all Characters
# Get all Characters and related data in one query
audit = SkillFarmAudit.objects.filter(
character__eve_character__in=characters
).select_related(
"character__eve_character",
)

for character in audit:
Expand Down Expand Up @@ -88,9 +91,13 @@ def get_character_skillfarm(request, character_id: int):
character_filters &= Q(eve_type__name__in=skillset.skillset)

# Get all Skills for the current character if skillset is defined
skills = CharacterSkill.objects.select_related(
"character__eve_character", "eve_type"
).filter(character_filters)
skills = CharacterSkill.objects.filter(
character_filters,
character__eve_character=character.character.eve_character,
).select_related(
"eve_type",
"character",
)

for entry in skills:
character_obj = entry.character.eve_character
Expand All @@ -99,25 +106,23 @@ def get_character_skillfarm(request, character_id: int):
dict_data = {
"skill": f"{entry.eve_type.name} {level}",
"level": entry.active_skill_level,
"skillpoints": entry.skillpoints_in_skill,
}

skills_dict[character_obj].append(dict_data)

# Get all Skill Queue for the current character
skillsqueue = CharacterSkillqueueEntry.objects.select_related(
"character__eve_character", "eve_type"
).filter(character_filters)

skills_data = []

if character.character.eve_character in skills_dict:
skills_data = skills_dict[character.character.eve_character]
skillsqueue = CharacterSkillqueueEntry.objects.filter(
character__eve_character=character.character.eve_character
).select_related(
"eve_type",
"character",
)
skillsqueue_filtered = skillsqueue.filter(character_filters)

# Add the skillqueue to the dict
for entry in skillsqueue:
def process_skill_queue_entry(entry):
character_obj = entry.character.eve_character
level = arabic_number_to_roman(entry.finished_level)

dict_data = {
"skill": f"{entry.eve_type.name} {level}",
"start_sp": entry.level_start_sp,
Expand All @@ -126,15 +131,25 @@ def get_character_skillfarm(request, character_id: int):
"start_date": entry.start_date,
"finish_date": entry.finish_date,
}
return character_obj, dict_data

skills_queue_dict[character_obj].append(dict_data)
if character.character.eve_character in skills_dict:
skills_data = skills_dict[character.character.eve_character]

skillqueue_data = []
# Process all skill queue entries and filtered skill queue entries in one loop
for entry in skillsqueue:
character_obj, dict_data = process_skill_queue_entry(entry)
skills_queue_dict[character_obj].append(dict_data)
if entry in skillsqueue_filtered:
skills_queue_dict_filtered[character_obj].append(dict_data)

if character.character.eve_character in skills_queue_dict:
skillqueue_data = skills_queue_dict[
character.character.eve_character
]
skills_data = skills_dict.get(character.character.eve_character, [])
skillqueue_data = skills_queue_dict.get(
character.character.eve_character, []
)
skillqueuefiltered_data = skills_queue_dict_filtered.get(
character.character.eve_character, []
)

characters_dict.append(
{
Expand All @@ -146,6 +161,7 @@ def get_character_skillfarm(request, character_id: int):
"notification": character.notification,
"last_update": update_status,
"skillset": skillset.skillset if skillset else [],
"skillqueuefiltered": skillqueuefiltered_data,
"skillqueue": skillqueue_data,
"skills": skills_data,
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 78 additions & 16 deletions skillfarm/static/skillfarm/js/skillfarm.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ document.addEventListener('DOMContentLoaded', function() {
var alarmActivated = skillfarmSettings.alarmActivatedText;
var alarmDeactivated = skillfarmSettings.alarmDeactivatedText;
var notupdated = skillfarmSettings.notUpdatedText;
var noActiveTraining = skillfarmSettings.noActiveTrainingText;

function switchAlarmUrl(characterId) {
return urlAlarm
Expand Down Expand Up @@ -54,17 +55,17 @@ document.addEventListener('DOMContentLoaded', function() {
// Initialize DataTable
var table = $('#skillfarm-details').DataTable({
order: [[0, 'asc']],
pageLength: 25,
pageLength: 50,
columnDefs: [
{ 'orderable': false, 'targets': 'no-sort' }
],
createdRow: function(row, data, dataIndex) {
$('td:eq(4)', row).addClass('text-end');
$('td:eq(5)', row).addClass('text-end');
}
});

function totalProgressbar (skills) {
var skillJson = JSON.parse(skills);
function totalProgressbar (skillqueue) {
var skillJson = JSON.parse(skillqueue);
var totalSP = 0;
var trainedSP = 0;

Expand All @@ -78,6 +79,47 @@ document.addEventListener('DOMContentLoaded', function() {
return progressPercent;
}

function calculateSumProgressBar(skillqueue, skills) {
var skillqueueJson = JSON.parse(skillqueue);
var skillsJson = JSON.parse(skills);

if (skillsJson.length === 0) {
return totalProgressbar(skillqueue);
}

// Extract unique skill names without levels and optional hyphen from the skillqueue
var uniqueSkillNames = [...new Set(skillqueueJson.map(skill => skill.skill.replace(/\s[IV-]*$/, '')))];

// Find the highest end_sp for each unique skill name
var totalEndSp = uniqueSkillNames.reduce((total, skillName) => {
var highestSkill = skillqueueJson
.filter(skill => skill.skill.replace(/\s[IV-]*$/, '') === skillName)
.reduce((prev, current) => (prev.end_sp > current.end_sp) ? prev : current);
return total + highestSkill.end_sp;
}, 0);

// Sum the skillpoints of all skills in the skills array
var totalSkillpoints = skillsJson.reduce((total, skill) => total + skill.skillpoints, 0);

// Calculate the progress percentage
var progressPercent = (totalSkillpoints / totalEndSp) * 100;

// Handle cases where progressPercent is Infinity or exceeds 100%
if (!isFinite(progressPercent)) {
progressPercent = 100;
} else if (progressPercent > 100) {
progressPercent = 100;
}

console.log(progressPercent);
return progressPercent;
}

function hasActiveTraining(skillqueueJson) {
const queueJson = JSON.parse(skillqueueJson);
return queueJson.some(skill => skill.start_date !== null && skill.finish_date !== null);
}

// Fetch data using AJAX
$.ajax({
url: url,
Expand All @@ -99,25 +141,41 @@ document.addEventListener('DOMContentLoaded', function() {
`;

// Serialize skills to JSON string
const skillqueueFilteredJson = JSON.stringify(character.skillqueuefiltered);
const skillqueueJson = JSON.stringify(character.skillqueue);
const skillsJson = JSON.stringify(character.skills);
const hasSkillLevel5 = JSON.parse(skillsJson).some(skill => skill.level === 5);

const progressBarHtml = `
<div class="progress-outer flex-grow-1 me-2">
<div class="progress" style="position: relative;">
<div class="progress-bar progress-bar-warning progress-bar-striped active" role="progressbar" style="width: ${calculateSumProgressBar(skillqueueFilteredJson, skillsJson)}%; box-shadow: -1px 3px 5px rgba(0, 180, 231, 0.9);"></div>
<div class="progress-value" style="position: absolute; width: 100%; text-align: center;">${calculateSumProgressBar(skillqueueFilteredJson, skillsJson).toFixed(0)}%</div>
</div>
</div>
`;

const noActiveTrainingHtml = `
<div class="text-danger fw-bold">${noActiveTraining}</div>
`;

const skillCell = `
<td>
<div class="d-flex align-items-center">
<div class="progress-outer flex-grow-1 me-2">
<div class="progress" style="position: relative;">
<div class="progress-bar progress-bar-warning progress-bar-striped active" role="progressbar" style="width: ${totalProgressbar(skillqueueJson)}%; box-shadow: -1px 3px 5px rgba(0, 180, 231, 0.9);" aria-valuenow="${totalProgressbar(skillqueueJson)}" aria-valuemin="0" aria-valuemax="100"></div>
<div class="progress-value" style="position: absolute; width: 100%; text-align: center;">${totalProgressbar(skillqueueJson).toFixed(0)}%</div>
</div>
</div>
<button class="btn btn-primary btn-sm btn-square" data-bs-toggle="modal" data-bs-target="#skillQueueModal" data-character-id="${character.character_id}" data-character-name="${character.character_name}" data-skillqueue='${skillqueueJson}' data-skills='${skillsJson}' onclick="showskillQueueModal(this)">
<span class="fas fa-info"></span>
</button>
${hasActiveTraining(skillqueueJson) ? progressBarHtml : noActiveTrainingHtml}
</div>
</td>
`;

const skillStatus = JSON.parse(skillsJson).some(skill => skill.level === 5) ? '<img src="/static/skillfarm/images/skillExtractor.png" class="rounded-circle" style="width: 32px">' : '';
const skillStatusWarning = JSON.parse(skillsJson).some(skill => skill.level === 5) ? 'bg-warning' : '';
const skillListHtml = `
<button class="btn btn-primary btn-sm btn-square ${skillStatusWarning}" data-bs-toggle="modal" data-bs-target="#skillQueueModal" data-character-id="${character.character_id}" data-character-name="${character.character_name}" data-skillqueue='${skillqueueFilteredJson}' data-skills='${skillsJson}' onclick="showskillQueueModal(this)">
<span class="fas fa-info"></span>
</button>
${skillStatus}
`;

// Last Updated
const lastUpdatedCell = character.last_update
? `<td data-order="${new Date(character.last_update).getTime()}">${new Date(character.last_update).toLocaleString()}</td>`
Expand Down Expand Up @@ -160,7 +218,7 @@ document.addEventListener('DOMContentLoaded', function() {
</td>
`;

row.push(characterCell, skillCell, lastUpdatedCell, filterstatusCell, actionsCell);
row.push(characterCell, skillCell, skillListHtml, lastUpdatedCell, filterstatusCell, actionsCell);
table.row.add(row).draw();
});
});
Expand Down Expand Up @@ -420,8 +478,12 @@ function showskillQueueModal(button) {
<div class="progress-value" style="position: absolute; width: 100%; text-align: center;">${progressPercent.toFixed(0)}%</div>
</div>
</td>
<td data-order="${new Date(skill.start_date).getTime()}">${new Date(skill.start_date).toLocaleString()}</td>
<td data-order="${new Date(skill.finish_date).getTime()}">${new Date(skill.finish_date).toLocaleString()}</td>
<td data-order="${skill.start_date ? new Date(skill.start_date).getTime() : ''}">
${skill.start_date ? new Date(skill.start_date).toLocaleString() : 'No Active Training'}
</td>
<td data-order="${skill.finish_date ? new Date(skill.finish_date).getTime() : ''}">
${skill.finish_date ? new Date(skill.finish_date).toLocaleString() : 'No Active Training'}
</td>
`;
skillQueueTbody.appendChild(tr);
});
Expand Down
3 changes: 2 additions & 1 deletion skillfarm/templates/skillfarm/partials/table/skillfarm.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<table class="table table-striped table-hover w-100" id="skillfarm-details">
<thead>
<th class="col-character w-auto">{% translate "Character" %}</th>
<th class="col-quue w-auto no-sort">{% translate "Skill Queue" %}</th>
<th class="col-quue w-auto no-sort">{% translate "Progress" %}</th>
<th class="col-skill w-auto no-sort">{% translate "Skill Info" %}</th>
<th class="col-last-updated w-auto">{% translate "Last Updated" %}</th>
<th class="col-filter w-auto no-sort">{% translate "Filter" %}</th>
<th class="col-actions w-auto no-sort text-end">{% translate "Actions" %}</th>
Expand Down
1 change: 1 addition & 0 deletions skillfarm/templates/skillfarm/skillfarm.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ <h3>{% translate "Skillfarm Details" %} </h3>
switchAlarmConfirmText: '{% translate "Are you sure to Switch Alarm" %}',
switchAlarmText: '{% translate "Toggle Alarm" %}',
notUpdatedText: '{% translate "Not Updated Yet" %}',
noActiveTrainingText: '{% translate "No Active Training" %}',

alarmActivatedText: '{% translate "Notification Activated" %}',
alarmDeactivatedText: '{% translate "Notification Deactivated" %}',
Expand Down

0 comments on commit 9bfddb0

Please sign in to comment.