Skip to content

Commit

Permalink
moderation: added proxy and refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
0einstein0 committed Oct 31, 2024
1 parent 41a1676 commit 0617c59
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 137 deletions.
24 changes: 6 additions & 18 deletions invenio.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ from invenio_vocabularies.services.custom_fields import (
)
from invenio_rdm_records.services.components.signal import SignalComponent
from invenio_rdm_records.services.components import DefaultRecordsComponents
from invenio_rdm_records.services.communities.components import CommunityServiceComponents
from invenio_oauthclient.views.client import auto_redirect_login

from invenio_communities.communities.services import facets as community_facets
Expand All @@ -71,7 +70,6 @@ from zenodo_rdm import providers as zenodo_providers
from zenodo_rdm import facets as zenodo_community_facets
from zenodo_rdm.metrics.config import METRICS_CACHE_UPDATE_INTERVAL
from zenodo_rdm.openaire.records.components import OpenAIREComponent
from zenodo_rdm.moderation.components import RecordContentModerationComponent, CommunityContentModerationComponent
from zenodo_rdm.moderation.handlers import RecordScoreHandler, CommunityScoreHandler
from zenodo_rdm.moderation.rules import files_rule, verified_user_rule, links_rule,text_sanitization_rule
from zenodo_rdm.github.schemas import CitationMetadataSchema
Expand Down Expand Up @@ -750,19 +748,17 @@ METRICS_UPTIME_ROBOT_URL = "https://api.uptimerobot.com/v2/getMonitors"
METRICS_UPTIME_ROBOT_API_KEY = None

# Other configs
RDM_RECORDS_SERVICE_COMPONENTS = [
comp for comp in DefaultRecordsComponents if comp.__name__ != "ContentModerationComponent"
] + [
RecordContentModerationComponent,
RDM_RECORDS_SERVICE_COMPONENTS = DefaultRecordsComponents + [
OpenAIREComponent,
SignalComponent,
]
"""Addd OpenAIRE component to records service."""

RDM_RECORD_MODERATION_HANDLERS = [
RDM_CONTENT_MODERATION_HANDLERS = [
RecordScoreHandler(),
CommunityScoreHandler(),
]
"""Handler for record moderation."""
"""Handler for content moderation."""

RDM_CONTENT_MODERATION_FILE_SIZE = 2000000
"""Threshold filesize for moderation."""
Expand All @@ -778,14 +774,6 @@ RDM_RECORD_MODERATION_SCORE_RULES = [
]
"""Scoring rules for record moderation."""

COMMUNITIES_SERVICE_COMPONENTS = CommunityServiceComponents + [
CommunityContentModerationComponent
]

COMMUNITY_MODERATION_HANDLERS = [
CommunityScoreHandler(),
]
"""Handler for community moderation."""

COMMUNITY_MODERATION_SCORE_RULES = [
links_rule,
Expand All @@ -795,10 +783,10 @@ COMMUNITY_MODERATION_SCORE_RULES = [
"""Scoring rules for communtiy moderation."""

CONTENT_MODERATION_BANNED_LINKS = []
"""Disallowed banned links for user moderation."""
"""Disallowed banned links for moderation."""

CONTENT_MODERATION_SAFE_LINKS = []
"""Allowed safe links for user moderation."""
"""Allowed safe links for moderation."""

RDM_SEARCH_SORT_BY_VERIFIED = True
"""Enable the sorting of records by verified."""
Expand Down
2 changes: 2 additions & 0 deletions site/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ invenio_base.apps =
zenodo_rdm_sitemap = zenodo_rdm.sitemap.ext:ZenodoSitemap
profiler = zenodo_rdm.profiler:Profiler
zenodo_rdm_metrics = zenodo_rdm.metrics.ext:ZenodoMetrics
zenodo_rdm_moderation = zenodo_rdm.moderation.ext:ZenodoModeration
invenio_openaire = zenodo_rdm.openaire.ext:OpenAIRE
zenodo_rdm_stats = zenodo_rdm.stats.ext:ZenodoStats
invenio_base.api_apps =
zenodo_rdm_legacy = zenodo_rdm.legacy.ext:ZenodoLegacy
profiler = zenodo_rdm.profiler:Profiler
zenodo_rdm_metrics = zenodo_rdm.metrics.ext:ZenodoMetrics
zenodo_rdm_moderation = zenodo_rdm.moderation.ext:ZenodoModeration
invenio_openaire = zenodo_rdm.openaire.ext:OpenAIRE
invenio_base.api_blueprints =
zenodo_rdm_legacy = zenodo_rdm.legacy.views:blueprint
Expand Down
28 changes: 0 additions & 28 deletions site/zenodo_rdm/moderation/components.py

This file was deleted.

69 changes: 69 additions & 0 deletions site/zenodo_rdm/moderation/ext.py
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
56 changes: 48 additions & 8 deletions site/zenodo_rdm/moderation/handlers.py
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}"
)
15 changes: 15 additions & 0 deletions site/zenodo_rdm/moderation/proxies.py
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
)
Loading

0 comments on commit 0617c59

Please sign in to comment.