Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions meta_creator/hermes_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import json
import os
from .token_handling_in_toml import update_token_to_toml, remove_token_from_toml
from .utils import merge_people_metadata

# hermes_utils.py

def run_hermes_commands(url, token=None):
errors = []
Expand Down Expand Up @@ -121,27 +124,27 @@ def run_hermes_commands(url, token=None):

# Authors
author_info = hermes_metadata_dict.get('author', [])
authors_metadata = [
authors_metadata = merge_people_metadata([
{
"@type": "Person",
"givenName": author.get("givenName", ""),
"familyName": author.get("familyName", ""),
"email": author.get("email", "")
}
for author in author_info
]
])

# Contributors
contributor_info = hermes_metadata_dict.get('contributor', [])
contributors_metadata = [
contributors_metadata = merge_people_metadata([
{
"@type": "Person",
"givenName": contributor.get("givenName", ""),
"familyName": contributor.get("familyName", ""),
"email": contributor.get("email", "")
}
for contributor in contributor_info
]
])


hermes_metadata_dict = {
Expand Down
49 changes: 38 additions & 11 deletions meta_creator/templates/meta_creator/showdata.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ <h4>Metdata in JSON format</h4>
</div>
</div>
<textarea name="txtareaJSON" id="metadata-json">{{ my_json_str }}</textarea>

</form>
</div><!-- metadataFormDisplay -->
<div id="formContainer" class="form-container col-lg-12 col-md-12" >
Expand Down Expand Up @@ -280,17 +281,23 @@ <h1>Extra Hints!</h1>
</div>
{% elif forloop.first or not unique_tab %}
<!-- small_table -->
<div class="long_field">
<div class="long_field copyright_table">
{% with specific_types=type_metadata|get_array:key default_type=value.0|get:"@type"%}
{% if not unique_tab %}

<div class="action" >
<label for="{{ key }}">{{ key|camel_to_spaces_lower }}</label>
<div class="custom-tooltip-metadata">
<span class="tooltip-text-metadata">
{% if key in description_metadata %}{{ description_metadata|get:key }}{% endif %}
</span>
<i class="fa fa-info-circle" aria-hidden="true"></i>
</div>
{% elif key == "contributor" %}
<span class="highlight-tag confirmBar" style="float: right; display: none;"> Do You want to delete row?<span class="acknowledge-tag yesBtn">YES</span><span class="acknowledge-tag noBtn" style="color: red;">NO</span></span>
</div>


{% elif key == "contributor" %}
<div class="relative-wrapper">
<!-- <button type="button" class=" collapsible-button" data-bs-toggle="collapse" data-bs-target="#multiCollapseContributors" aria-expanded="false" aria-controls="multiCollapseContributors">Who are Contributors?</button> -->
<div class="person-info collapsible-content collapse" id="multiCollapsecontributor">
Expand All @@ -304,15 +311,27 @@ <h1>Extra Hints!</h1>
<div class="person-info collapsible-content collapse" id="multiCollapsemaintainer">
<p>An "maintainer" in software authorship is someone who significantly maintainers to the creation and development of software, including roles like coding, project management, and documentation.</p>
</div>
<span class="highlight-tag"> ⚠️ Click on contributors, authors, or maintainers to see the description<span class="acknowledge-tag">Got it!</span></span>
<div class="action">
<span class="highlight-tag"> ⚠️ Click on contributors, authors, or maintainers to see the description<span class="acknowledge-tag">Got it!</span></span>

<span><i class="fas fa-trash-alt delete-row-btn" title="Delete row" style="cursor:pointer; display: none;"></i></span>
<span><i class="fa-solid fa-table-list" title="Merge Rows" style="cursor:pointer; display: none;"></i></span>
<span class="highlight-tag delete-row" style="float: right; display: none;"> Do You want to delete row?<span class="acknowledge-tag deleteRow">YES</span><span class="acknowledge-tag reject" style="color: red;">NO</span></span>
<span class="highlight-tag merge-row" style="float: right; display: none;"> Do You want to merges selected rows?<span class="acknowledge-tag mergeRow">YES</span><span class="acknowledge-tag reject" style="color: red;">NO</span></span>
</div>


</div>

{% endif %}
<input type="hidden" id="{{ key }}TableHiddenInput" name="{{ key }}TableHiddenInput"
value='{{ value }}'>
<table class="auto-property table table-responsive table-bordered table-hover" id="{{ key }}Table" data-at-type={{default_type}} unique-tab={{unique_tab}}>
{% if key == "contributor" %}
<div class="scrollable">
{% endif %}
<table class="auto-property table table-responsive table-hover" id="{{ key }}Table" data-at-type={{default_type}} unique-tab={{unique_tab}}>
<thead>
<tr>
<th class="text-center" data-col="" style="width: fit-content;">Select</th>
{% for col, value in specific_types.items %}
<th data-col="{{ col }}" data-coltype="{{ value }}" class="align-items-center">
{{ col|camel_to_spaces_lower }}
Expand All @@ -327,7 +346,7 @@ <h1>Extra Hints!</h1>
{% if unique_tab %}
{% for col, value in metadata_dict.items %}
<th data-col="{{ col }}" data-coltype="element">
<button type="button" class=" collapsible-button" data-bs-toggle="collapse" data-bs-target="#multiCollapse{{ col }}" aria-expanded="false" aria-controls="multiCollapseContributors">{{ col|camel_to_spaces_lower }}</button>
<button type="button" class=" collapsible-button" data-bs-toggle="collapse" data-bs-target="#multiCollapse{{ col }}" aria-expanded="false" aria-controls="multiCollapseContributors" added >{{ col|camel_to_spaces_lower }}</button>
<!-- <div class="person-info collapsible-content collapse" id="multiCollapse{{ col }}">
<p>{% if col in description_metadata %}{{ description_metadata|get:col }}{% endif %}</p>
</div> -->
Expand All @@ -340,13 +359,16 @@ <h1>Extra Hints!</h1>
</th>
{% endfor %}
{% endif %}
<th data-col="del" data-coltype="delete">Row Control</th>
<th data-col="del" data-coltype="delete" ></th>
</tr>
</thead>
<tbody>
{% for row in value %}
{% if row|row_has_values:specific_types.keys %}
<tr>
<td class="text-center" data-col="select" data-coltype="select">
<input type="checkbox" class="checkbox-select" data-role="select" name="checkbox-select">
</td>
{% for col, value in specific_types.items %}
{% if value == 'tagging' or value == 'tagging_autocomplete' or value == 'dropdown' %}
<td class="table-tagging-cell" data-type={{default_type}} data-coltype="{{ value }}" data-col="{{ col }}" data-row="{{ forloop.parentloop.counter0 }}">
Expand All @@ -356,7 +378,7 @@ <h1>Extra Hints!</h1>
{% endfor %}
</div>
{% if value == 'tagging' %}
<input class="tag-input" type="text" style="display:none;" placeholder="Add tag and press Enter" />
<input class="tag-input" type="text" style="display:none;" placeholder="Add Email and press Enter" />
{% else %}
<input class="tag-input" type="text" style="display:none;" placeholder="Type and select from list" />
{% endif %}
Expand All @@ -380,20 +402,21 @@ <h1>Extra Hints!</h1>
</td>
{% endfor %}
{% endif %}
<td class="d-flex justify-content-center align-items-center" style="height: 50px;">
<i class="fas fa-trash-alt delete-row-btn" title="Delete row" style="cursor:pointer;"></i>
<td >
<!-- <i class="fas fa-trash-alt delete-row-btn" title="Delete row" style="cursor:pointer;"></i> -->
</td>
</tr>
{% endif %}
{% endfor %}
<!-- Add Row Inputs -->
<tr class="add-row-controls" data-table-key="{{ key }}">
<td></td>
{% for col, value in specific_types.items %}
{% if value == 'tagging' or value == 'tagging_autocomplete' %}
<td class="tags-table-container add-row-tags-container" data-type={{default_type}} data-coltype="{{ value }}" data-col="{{ col }}">
<!-- Tags will be inserted here by JS -->
{% if value == "tagging" %}
<input type="text" class="add-row-tag-input" data-type={{default_type}} data-coltype="{{ value }}" data-col="{{ col }}" placeholder="Add tag for {{col|camel_to_spaces_lower}} and press Enter" />
<input type="text" class="add-row-tag-input" data-type={{default_type}} data-coltype="{{ value }}" data-col="{{ col }}" placeholder="Add {{col|camel_to_spaces_lower}} and press Enter" />
{% else %}
<input type="text" class="add-row-tag-input" data-type={{default_type}} data-coltype="{{ value }}" data-col="{{ col }}" placeholder="Type and select from list for {{col|camel_to_spaces_lower}}" />
{% endif %}
Expand Down Expand Up @@ -425,8 +448,12 @@ <h1>Extra Hints!</h1>
<button type="button" class="add-row-btn" data-table-key="{{ key }}">Add</button>
</td>
</tr>

</tbody>
</table>
{% if key == "contributor" %}
</div>
{% endif %}
{% endwith %}
</div>
{% endif %}
Expand Down
85 changes: 85 additions & 0 deletions meta_creator/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#utils.py


# hermes_utils.py

def merge_people_metadata(people_list):
"""
Merge duplicate person entries (case-insensitive) based on givenName + familyName.
Collect all unique emails, but if all are the same, keep only one.

Example:
Input:
[
{"givenName": "Micheal", "familyName": "Jack", "email": "micheal@example.com"},
{"givenName": "micheal", "familyName": "jack", "email": "MICHEAL@example.com"},
{"givenName": "micheal", "familyName": "jack", "email": "micheal.jack@work.com"},
{"givenName": "Jane", "familyName": "Smith", "email": ""}
]

Output:
[
{
"@type": "Person",
"givenName": "Micheal",
"familyName": "jack",
"email": ["micheal@example.com", "micheal.jack@work.com"]
},
{
"@type": "Person",
"givenName": "Jane",
"familyName": "Smith",
"email": ""
}
]
"""
if not people_list:
return []

merged = {}

for person in people_list:
given = person.get("givenName", "").strip().lower()
family = person.get("familyName", "").strip().lower()
email = person.get("email", "").strip().lower()

if not given and not family:
# skip if no name info
continue

key = (given, family)

# Initialize entry if not present
if key not in merged:
merged[key] = {
"@type": "Person",
"givenName": person.get("givenName", "").strip().title(),
"familyName": person.get("familyName", "").strip().title(),
"emails": set()
}

# Add email if present
if email:
merged[key]["emails"].add(email)

# Format results
merged_people = []
for person in merged.values():
emails = list(person["emails"])
if not emails:
email_field = ""
elif len(emails) == 1:
email_field = emails[0]
else:
# Check if all emails are identical ignoring case (e.g., same email written differently)
normalized = {e.lower() for e in emails}
email_field = emails[0] if len(normalized) == 1 else sorted(list(normalized))

merged_people.append({
"@type": "Person",
"givenName": person["givenName"],
"familyName": person["familyName"],
"email": email_field
})

return merged_people
Loading