Skip to content

Commit

Permalink
Show active config tags in control panel
Browse files Browse the repository at this point in the history
  • Loading branch information
stijn-uva committed Aug 29, 2023
1 parent 8c83df7 commit d81b392
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 29 deletions.
88 changes: 63 additions & 25 deletions common/config_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,31 +191,8 @@ def get(self, attribute_name, default=None, is_json=False, user=None, tags=None)
if not self.db:
self.with_db()

# be flexible about the input types here
if tags is None:
tags = []
elif type(tags) is str:
tags = [tags]

# can provide either a string or user object
if type(user) is not str:
if hasattr(user, "get_id"):
user = user.get_id()
elif user is not None:
raise TypeError("get() expects None, a User object or a string for argument 'user'")

# user-specific settings are just a special type of tag (which takes
# precedence), same goes for user groups
if user:
user_tags = self.db.fetchone("SELECT tags FROM users WHERE name = %s", (user,))
if user_tags:
try:
tags.extend(user_tags["tags"])
except (TypeError, ValueError):
# should be a JSON list, but isn't
pass

tags.insert(0, f"user:{user}")
# get tags to look for
tags = self.get_active_tags(user, tags)

# query database for any values within the required tags
tags.append("") # empty tag = default value
Expand Down Expand Up @@ -264,6 +241,49 @@ def get(self, attribute_name, default=None, is_json=False, user=None, tags=None)
else:
return final_settings

def get_active_tags(self, user=None, tags=None):
"""
Get active tags for given user/tag list
Used internally to harmonize tag setting for various methods, but can
also be called directly to verify tag activation.
:param user: User object or name. Adds a tag `user:[username]` in
front of the tag list.
:param tags: Tag or tags for the required setting. If a tag is
provided, the method checks if a special value for the setting exists
with the given tag, and returns that if one exists. First matching tag
wins.
:return list: List of tags
"""
# be flexible about the input types here
if tags is None:
tags = []
elif type(tags) is str:
tags = [tags]

# can provide either a string or user object
if type(user) is not str:
if hasattr(user, "get_id"):
user = user.get_id()
elif user is not None:
raise TypeError("get() expects None, a User object or a string for argument 'user'")

# user-specific settings are just a special type of tag (which takes
# precedence), same goes for user groups
if user:
user_tags = self.db.fetchone("SELECT tags FROM users WHERE name = %s", (user,))
if user_tags:
try:
tags.extend(user_tags["tags"])
except (TypeError, ValueError):
# should be a JSON list, but isn't
pass

tags.insert(0, f"user:{user}")

return tags

def set(self, attribute_name, value, is_json=False, tag="", overwrite_existing=True):
"""
Insert OR set value for a setting
Expand Down Expand Up @@ -417,6 +437,24 @@ def get(self, *args, **kwargs):

return self.config.get(*args, **kwargs)

def get_active_tags(self, user=None, tags=None):
"""
Wrap `get_active_tags()`
Takes the `user`, `tags` and `request` given when initialised into
account. If `tags` is set explicitly, the HTTP header-based override
is not applied.
:param user:
:param tags:
:return list:
"""
active_tags = self.config.get_active_tags(user, tags)
if not tags:
active_tags = self.request_override(active_tags)

return active_tags

def request_override(self, tags):
"""
Force tag via HTTP request headers
Expand Down
15 changes: 15 additions & 0 deletions webtool/static/css/control-panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,21 @@ article .stats-container h3:not(.blocktitle) {
border-bottom: 1px dotted var(--contrast-dark);
}

.stats-container div.tag-list {
display: block;
}

.stats-container div.tag-list dt {
float: left;
display: block;
width: 60%;
margin-bottom: 0.25em;
}

.stats-container .property-badge {
margin-right: 0.5em;
}

/**
** Bulk dataset management
*/
Expand Down
6 changes: 3 additions & 3 deletions webtool/templates/controlpanel/frontpage.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ <h3>Disk usage</h3>
</dl>
</div>
<div class="cp-stats">
<h3>Version</h3>
<h3>Configuration</h3>
<dl>
<div><dt>4CAT version</dt>
<dd>{{ __version }}</dd></div>
<div><dt>Up to date?</dt>
<dd>{% if upgrade_available %}<a href="{{ url_for("trigger_restart") }}">Upgrade now</a>{% else %}<i class="fa fa-check" aria-hidden="true"></i><span class="sr-only">Yes</span>{% endif %}</dd></div>
<div class="tag-list"><dt>Active tags</dt>
<dd>{% if tags %}{% for tag in tags %}<span class="property-badge">{{ tag }}</span>{% endfor %}{% else%}None{% endif %}</dd></div>
</dl>
</div>
</ul>
Expand Down
3 changes: 2 additions & 1 deletion webtool/views/views_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ def admin_frontpage():
upgrade_available = not not db.fetchone(
"SELECT * FROM users_notifications WHERE username = '!admins' AND notification LIKE 'A new version of 4CAT%'")

tags = config.get_active_tags(current_user)
return render_template("controlpanel/frontpage.html", flashes=get_flashed_messages(), stats={
"captured": num_items, "datasets": num_datasets, "disk": disk_stats
}, upgrade_available=upgrade_available)
}, upgrade_available=upgrade_available, tags=tags)


@app.route("/admin/users/", defaults={"page": 1})
Expand Down

0 comments on commit d81b392

Please sign in to comment.