feat: add news/stories pipeline which create news from article#2844
feat: add news/stories pipeline which create news from article#2844ahtesham-quraish merged 5 commits intomainfrom
Conversation
1dffb25 to
f5b006d
Compare
a3ba3d3 to
e1df534
Compare
articles/signals.py
Outdated
| @@ -0,0 +1,43 @@ | |||
| """Signal handlers for articles app""" | |||
|
|
|||
| import logging | |||
There was a problem hiding this comment.
Instead of signals, mit-learn has been using pluggy. It would probably be best to do that here as well.
Here is an existing example for the authentication and profiles apps:
Adds several lines to initiate the pluggy hooks & plugins.
from django.apps import AppConfig
from pluggy import HookimplMarker, HookspecMarker
class AuthenticationConfig(AppConfig):
"""Authentication AppConfig"""
name = "authentication"
hookimpl = HookimplMarker(name)
hookspec = HookspecMarker(name)Defines hook functions that are used to trigger plugin actions:
@hookspec
def user_created(self, user, user_data):
"""Trigger actions after a user is created"""
It also sets up the plugin manager for the app. There is a MITOL_AUTHENTICATION_PLUGINS setting used here, which is defined in main/settings_pluggy.py and indicates which plugins are needed for this app. In this case there is a learning_resources plugin and a profiles plugin:
MITOL_AUTHENTICATION_PLUGINS = get_string(
"MITOL_AUTHENTICATION_PLUGINS",
"learning_resources.plugins.FavoritesListPlugin,profiles.plugins.CreateProfilePlugin",
)Each of these apps will have a plugins.py file. Here is the profiles plugin. The function inside the plugin class has a function with the same name and args as the hook defined above in authentication/hooks.py.
class CreateProfilePlugin:
hookimpl = apps.get_app_config("authentication").hookimpl
@hookimpl
def user_created(self, user, user_data):
"""
Perform functions on a newly created user
Args:
user(User): the user that was created
user_data(dict): the user data
"""
profile_data = user_data.get("profile", {})
ensure_profile(user, profile_data)
In authentication/api.py there is a function user_created_actions which calls the hook that will trigger the plugin:
def user_created_actions(*, user, details, **kwargs):
"""
Trigger plugins when a user is created
"""
if kwargs.get("is_new"):
pm = get_plugin_manager()
hook = pm.hook
hook.user_created(user=user, user_data={"profile": details})Currently, this function is called from main/middleware/apisix.py:
user_created_actions(user=user, is_new=created, details=profile_data)So in this case, hooks would be defined in the articles app, and the plugins w/functions would be defined in the news_events app. Something like this:
articles/hooks.py:
@hookspec
def sync_article_to_news_on_publish(self, article):
"""Trigger actions after an article is published""news_events/plugins.py:
class ArticleNewsPlugin:
hookimpl = apps.get_app_config("authentication").hookimpl
@hookimpl
def sync_article_to_news_on_publish(self, article):
"""
Sync a published article to news_events
Args:
article(Article): the article that was published
"""
# The code/logic in the current sync_article_to_news_on_publish would go here.Create a sync_article_actions function, maybe in a new articles/api.py file, and I think you'd call it from articles.views.ArticleViewSet.perform_create?
def perform_create(self, serializer):
clear_views_cache()
article = serializer.save(user=self.request.user)
sync_article_actions(article)but you'll probably need to add an override for partial_update too and call it from within there as well.
It's more complex than the signals approach but it helps keep apps more independent of each other (imports etc) - https://github.com/mitodl/hq/discussions/1638
There was a problem hiding this comment.
check now sir I have used this
| content_text = extract_text_from_content(content_json) | ||
| summary_text = content_text[:500] if content_text else "" |
There was a problem hiding this comment.
For both of these fields, the value contains the title and text of the article repeated twice:
"summary": "A new article yay A new article yay This is a new article - pub 2a This is a new article - pub 2a",
"content": "A new article yay A new article yay This is a new article - pub 2a This is a new article - pub 2a",There was a problem hiding this comment.
Check now please
| "image": image_data, | ||
| "detail": { | ||
| "authors": [author_name] if author_name else [], | ||
| "topics": [], # Add topics if you have them in your Article model |
There was a problem hiding this comment.
More of a question for Ferdi, should we include any default topics for mit-learn articles?
46d236d to
a498ce6
Compare
OpenAPI ChangesShow/hide 26 changes: 6 error, 8 warning, 12 infoUnexpected changes? Ensure your branch is up-to-date with |
a92a39a to
faccf5f
Compare
mbertrand
left a comment
There was a problem hiding this comment.
Looks great, could just use a few more unit tests
5ebe918 to
4dbd80f
Compare
6ce31b0 to
e31e6d7
Compare
for more information, see https://pre-commit.ci
What are the relevant tickets?
https://github.com/mitodl/hq/issues/9784
Description (What does it do?)
We want to introduce an Articles Listing Page that displays all published articles in a unified feed. This page will allow readers to browse available articles and click into individual article detail pages.
Currently, MIT articles are published on Medium, and we rely on Medium’s feed pipeline to populate our news feed. To support native articles created within mit-learn, we are introducing a new pipeline that integrates our internally published articles into the same news feed system.
Screenshots (if appropriate):
Screen.Recording.2026-01-07.at.4.29.44.PM.mov
How can this be tested?
for testing you need to create new article in publish state and on home page see if it is added in stories section, even when you update the published article the published state should be changed
Additional Context