39640-vm/core/views.py
Flatlogic Bot c559e6fffc 1
2026-04-14 16:55:47 +00:00

129 lines
5.0 KiB
Python

import hashlib
from django.contrib import messages
from django.db.models import Q
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from .forms import ArticleFilterForm, OriginalArticleForm
from .models import Article, NewsSource, Topic
from .rss import sync_active_sources
def _published_articles():
return Article.objects.filter(is_published=True).select_related('topic', 'source')
def _build_filter_form(data=None):
return ArticleFilterForm(data or None)
def home(request):
sync_active_sources(limit=6)
filter_form = _build_filter_form(request.GET or None)
stories = _published_articles()
if filter_form.is_valid():
query = filter_form.cleaned_data.get('q')
topic_slug = filter_form.cleaned_data.get('topic')
if query:
stories = stories.filter(
Q(title__icontains=query)
| Q(excerpt__icontains=query)
| Q(content__icontains=query)
| Q(author_name__icontains=query)
)
if topic_slug:
stories = stories.filter(topic__slug=topic_slug)
featured_story = stories.filter(is_featured=True).first() or stories.first()
spotlight_stories = stories.exclude(pk=getattr(featured_story, 'pk', None))[:6]
original_story = _published_articles().filter(article_kind=Article.ArticleKind.ORIGINAL).first()
context = {
'page_title': 'Signal / Startup & Tech Newsroom',
'meta_description': 'A polished startup and tech news magazine with RSS aggregation, editorial curation, and a fast CMS workflow.',
'filter_form': filter_form,
'featured_story': featured_story,
'spotlight_stories': spotlight_stories,
'topics': Topic.objects.order_by('name'),
'sources': NewsSource.objects.filter(is_active=True).order_by('name')[:6],
'story_count': stories.count(),
'original_story': original_story,
'last_updated': _published_articles().first(),
}
return render(request, 'core/index.html', context)
def article_list(request):
sync_active_sources(limit=4)
filter_form = _build_filter_form(request.GET or None)
stories = _published_articles()
selected_topic = None
if filter_form.is_valid():
query = filter_form.cleaned_data.get('q')
topic_slug = filter_form.cleaned_data.get('topic')
if query:
stories = stories.filter(
Q(title__icontains=query)
| Q(excerpt__icontains=query)
| Q(content__icontains=query)
| Q(author_name__icontains=query)
)
if topic_slug:
stories = stories.filter(topic__slug=topic_slug)
selected_topic = Topic.objects.filter(slug=topic_slug).first()
context = {
'page_title': 'All Stories / Signal',
'meta_description': 'Browse curated startup and tech stories by topic, recency, and editorial origin.',
'filter_form': filter_form,
'stories': stories[:24],
'selected_topic': selected_topic,
'topics': Topic.objects.order_by('name'),
}
return render(request, 'core/article_list.html', context)
def article_detail(request, slug):
article = get_object_or_404(_published_articles(), slug=slug)
related_articles = _published_articles().filter(topic=article.topic).exclude(pk=article.pk)[:3]
context = {
'page_title': f'{article.title} / Signal',
'meta_description': article.excerpt or 'Read the latest curated startup and tech story on Signal.',
'article': article,
'related_articles': related_articles,
}
return render(request, 'core/article_detail.html', context)
def article_submit(request):
if request.method == 'POST':
form = OriginalArticleForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.article_kind = Article.ArticleKind.ORIGINAL
article.is_published = True
article.published_at = timezone.now()
article.dedupe_key = hashlib.sha256(f"original|{timezone.now().isoformat()}|{article.title}".encode('utf-8')).hexdigest()
article.save()
messages.success(request, 'Your editorial story is live in the newsroom.')
return redirect('article_submit_success', slug=article.slug)
else:
form = OriginalArticleForm()
context = {
'page_title': 'Publish a Story / Signal CMS',
'meta_description': 'Draft an original startup or tech story and publish it into the Signal magazine flow.',
'form': form,
}
return render(request, 'core/article_form.html', context)
def article_submit_success(request, slug):
article = get_object_or_404(Article, slug=slug, article_kind=Article.ArticleKind.ORIGINAL)
context = {
'page_title': 'Story Published / Signal CMS',
'meta_description': 'Your original story has been published and added to the curated tech newsroom.',
'article': article,
}
return render(request, 'core/article_submit_success.html', context)