-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
moderation: added proxy and refactoring
- Loading branch information
1 parent
41a1676
commit 0617c59
Showing
7 changed files
with
193 additions
and
137 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (C) 2023 CERN. | ||
# | ||
# ZenodoRDM is free software; you can redistribute it and/or modify | ||
# it under the terms of the MIT License; see LICENSE file for more details. | ||
|
||
"""ZenodoRDM Moderation module.""" | ||
|
||
from flask import current_app | ||
from werkzeug.utils import cached_property | ||
|
||
|
||
class ZenodoModeration: | ||
"""Zenodo content moderation extension.""" | ||
|
||
def __init__(self, app=None): | ||
"""Extension initialization.""" | ||
if app: | ||
self.init_app(app) | ||
|
||
def init_app(self, app): | ||
"""Flask application initialization.""" | ||
app.extensions["zenodo-moderation"] = self | ||
|
||
@cached_property | ||
def domain_tree(self): | ||
"""Initialize and return the DomainTree instance with config-based links.""" | ||
domain_tree = DomainTree() | ||
domain_tree.initialize_links( | ||
current_app.config.get("CONTENT_MODERATION_BANNED_LINKS", []), "banned" | ||
) | ||
domain_tree.initialize_links( | ||
current_app.config.get("CONTENT_MODERATION_SAFE_LINKS", []), "safe" | ||
) | ||
return domain_tree | ||
|
||
|
||
class DomainTree: | ||
"""Domain tree structure to store and check status of domains.""" | ||
|
||
def __init__(self): | ||
"""Initialize an empty tree to hold domains and their statuses.""" | ||
self.tree = {} | ||
|
||
def add_domain(self, domain, status): | ||
"""Add a domain to the tree with its status: 'banned' or 'safe'.""" | ||
parts = domain.strip(".").split(".") | ||
current = self.tree | ||
for part in parts: | ||
current = current.setdefault(part, {}) | ||
current["status"] = status | ||
|
||
def initialize_links(self, links, status): | ||
"""Helper method to add multiple links to the domain tree with a given status.""" | ||
for domain in links: | ||
self.add_domain(domain, status) | ||
|
||
def get_status(self, domain_parts): | ||
"""Retrieve the status of a domain.""" | ||
current = self.tree | ||
for part in domain_parts: | ||
if part in current: | ||
current = current[part] | ||
if "status" in current: | ||
return current["status"] | ||
else: | ||
break | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,67 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (C) 2023 CERN. | ||
# | ||
# ZenodoRDM is free software; you can redistribute it and/or modify | ||
# it under the terms of the MIT License; see LICENSE file for more details. | ||
|
||
"""Handlers for ZenodoRDM Moderation.""" | ||
|
||
from flask import current_app | ||
from invenio_access.permissions import system_identity | ||
|
||
|
||
class BaseScoreHandler: | ||
def __init__(self, app=None, rules=None): | ||
self.app = app | ||
"""Base handler to calculate moderation scores based on rules.""" | ||
|
||
def __init__(self, rules=None): | ||
"""Initialize the score handler with a set of rules.""" | ||
self.rules = rules | ||
|
||
def run(self, identity, draft=None, record=None): | ||
"""Calculate the moderation score for a given record or draft.""" | ||
score = 0 | ||
rules = current_app.config[self.rules] | ||
for rule in rules: | ||
score += rule(identity, draft=draft, record=record) | ||
breakpoint() | ||
|
||
current_app.logger.warning(f"Moderation score for record({record.metadata['title']}): {score}") | ||
current_app.logger.warning( | ||
f"Moderation score for record - [{record.metadata['title']}]: {score}" | ||
) | ||
|
||
|
||
class RecordScoreHandler(BaseScoreHandler): | ||
def __init__(self, app=None): | ||
super().__init__(app, rules="RDM_RECORD_MODERATION_SCORE_RULES") | ||
"""Handler for calculating scores for records.""" | ||
|
||
def __init__(self): | ||
"""Initialize with record moderation rules.""" | ||
super().__init__(rules="RDM_RECORD_MODERATION_SCORE_RULES") | ||
|
||
def publish(self, identity, record): | ||
"""Calculate and log the score when a record is published.""" | ||
score = self.run(identity, record=record) | ||
current_app.logger.info( | ||
f"Record {record.metadata['title']} published with moderation score: {score}" | ||
) | ||
|
||
|
||
class CommunityScoreHandler(BaseScoreHandler): | ||
def __init__(self, app=None): | ||
super().__init__(app, rules="COMMUNITY_MODERATION_SCORE_RULES") | ||
"""Handler for calculating scores for communities.""" | ||
|
||
def __init__(self): | ||
"""Initialize with community moderation rules.""" | ||
super().__init__(rules="COMMUNITY_MODERATION_SCORE_RULES") | ||
|
||
def update(self, identity, community): | ||
"""Calculate and log the score when a community is updated.""" | ||
score = self.run(identity, record=community) | ||
current_app.logger.info( | ||
f"Community {community.metadata['title']} updated with moderation score: {score}" | ||
) | ||
|
||
def create(self, identity, community): | ||
"""Calculate and log the score when a community is created.""" | ||
score = self.run(identity, record=community) | ||
current_app.logger.info( | ||
f"Community {community.metadata['title']} created with moderation score: {score}" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (C) 2023 CERN. | ||
# | ||
# ZenodoRDM is free software; you can redistribute it and/or modify | ||
# it under the terms of the MIT License; see LICENSE file for more details. | ||
|
||
"""Proxy objects for easier access to application objects.""" | ||
|
||
from flask import current_app | ||
from werkzeug.local import LocalProxy | ||
|
||
current_domain_tree = LocalProxy( | ||
lambda: current_app.extensions["zenodo-moderation"].domain_tree | ||
) |
Oops, something went wrong.