first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
FROM python:3.14-alpine
|
||||
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY bootstrap_feeds.py feeds.yaml ./
|
||||
|
||||
ENTRYPOINT ["python3", "bootstrap_feeds.py"]
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Create Miniflux categories and feeds from feeds.yaml.
|
||||
|
||||
Env vars required: MINIFLUX_URL, MINIFLUX_USERNAME, MINIFLUX_PASSWORD.
|
||||
|
||||
Idempotent: existing categories are matched by title, existing feeds are
|
||||
matched by feed_url, both fetched from the API before any create call.
|
||||
Safe to re-run (e.g. every time the Job runs) — only new entries get
|
||||
created.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
MINIFLUX_URL = os.environ["MINIFLUX_URL"].rstrip("/")
|
||||
AUTH = (os.environ["MINIFLUX_USERNAME"], os.environ["MINIFLUX_PASSWORD"])
|
||||
FEEDS_FILE = os.path.join(os.path.dirname(__file__), "feeds.yaml")
|
||||
|
||||
|
||||
def api(method, path, **kwargs):
|
||||
resp = requests.request(method, f"{MINIFLUX_URL}/v1{path}", auth=AUTH, timeout=60, **kwargs)
|
||||
resp.raise_for_status()
|
||||
return resp.json() if resp.content else None
|
||||
|
||||
|
||||
def get_or_create_category(name, existing_categories):
|
||||
if name in existing_categories:
|
||||
return existing_categories[name]
|
||||
category = api("POST", "/categories", json={"title": name})
|
||||
existing_categories[name] = category["id"]
|
||||
print(f"created category: {name}")
|
||||
return category["id"]
|
||||
|
||||
|
||||
def main():
|
||||
with open(FEEDS_FILE) as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
existing_categories = {c["title"]: c["id"] for c in api("GET", "/categories")}
|
||||
existing_feed_urls = {f["feed_url"] for f in api("GET", "/feeds")}
|
||||
|
||||
for category in data["categories"]:
|
||||
category_id = get_or_create_category(category["name"], existing_categories)
|
||||
for feed in category["feeds"]:
|
||||
if feed["url"] in existing_feed_urls:
|
||||
print(f"skip (already added): {feed['title']}")
|
||||
continue
|
||||
try:
|
||||
api(
|
||||
"POST",
|
||||
"/feeds",
|
||||
json={
|
||||
"feed_url": feed["url"],
|
||||
"category_id": category_id,
|
||||
"crawler": feed.get("crawler", False),
|
||||
},
|
||||
)
|
||||
existing_feed_urls.add(feed["url"])
|
||||
print(f"added feed: {feed['title']} ({feed['url']})")
|
||||
except requests.RequestException as exc:
|
||||
print(f"FAILED: {feed['title']} ({feed['url']}): {exc}", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,179 @@
|
||||
# Initial feed list. Kept intentionally small: one or two
|
||||
# confirmed-working (HTTP 200) feeds per category from AGENTS.md.
|
||||
# Add more later with the same structure — see README.md "How to add a source".
|
||||
# crawler: true makes Miniflux fetch the original article page instead of
|
||||
# relying on the (often truncated) RSS/Atom excerpt.
|
||||
categories:
|
||||
- name: Cloud Native
|
||||
feeds:
|
||||
- title: CNCF blog
|
||||
url: https://www.cncf.io/feed/
|
||||
crawler: true
|
||||
- title: Kubernetes blog
|
||||
url: https://kubernetes.io/feed.xml
|
||||
crawler: true
|
||||
- title: AWS Architecture blog
|
||||
url: https://aws.amazon.com/blogs/architecture/feed/
|
||||
crawler: true
|
||||
- title: Docker blog
|
||||
url: https://www.docker.com/feed/
|
||||
crawler: true
|
||||
- title: HashiCorp blog (news)
|
||||
url: https://news.google.com/rss/search?q=%22HashiCorp%22%20blog&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Red Hat blog (news)
|
||||
url: https://news.google.com/rss/search?q=%22Red%20Hat%22%20blog&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Google Cloud blog
|
||||
url: https://cloudblog.withgoogle.com/rss/
|
||||
crawler: true
|
||||
- title: Azure blog
|
||||
url: https://azure.microsoft.com/en-us/blog/feed/
|
||||
crawler: true
|
||||
|
||||
- name: Integration
|
||||
feeds:
|
||||
- title: Google News search
|
||||
url: https://news.google.com/rss/search?q=%22hybrid%20integration%22%20OR%20iPaaS%20OR%20%22integration%20platform%22%20OR%20%22enterprise%20service%20bus%22%20OR%20%22application%20integration%22%20OR%20webMethods%20OR%20%22IBM%20App%20Connect%22%20OR%20Boomi%20OR%20TIBCO%20OR%20MuleSoft%20OR%20Workato&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
|
||||
- name: APIM
|
||||
feeds:
|
||||
- title: Google News search
|
||||
url: https://news.google.com/rss/search?q=%22API%20management%22%20OR%20%22API%20gateway%22%20OR%20%22API%20economy%22%20OR%20OpenAPI%20OR%20AsyncAPI%20OR%20%22API%20security%22%20OR%20Apigee%20OR%20%22Kong%20Gateway%22%20OR%20%22Azure%20API%20Management%22%20OR%20%22Gravitee.io%22%20OR%20%22Tyk%20API%22%20OR%20WSO2%20OR%20%22Amazon%20API%20Gateway%22%20OR%20%22IBM%20API%20Connect%22%20OR%20%22Axway%20Amplify%22%20OR%20%22Postman%20API%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
|
||||
- name: EDA
|
||||
feeds:
|
||||
- title: Confluent blog
|
||||
url: https://www.confluent.io/feed/
|
||||
crawler: true
|
||||
- title: Kai Waehner
|
||||
url: https://www.kai-waehner.de/feed/
|
||||
crawler: true
|
||||
- title: Solace blog
|
||||
url: https://solace.com/feed/
|
||||
crawler: true
|
||||
- title: RabbitMQ blog
|
||||
url: https://www.rabbitmq.com/blog/rss.xml # verify
|
||||
crawler: true
|
||||
- title: AsyncAPI blog
|
||||
url: https://www.asyncapi.com/rss.xml # verify
|
||||
crawler: true
|
||||
|
||||
- name: AI
|
||||
feeds:
|
||||
- title: OpenAI blog
|
||||
url: https://openai.com/blog/rss.xml
|
||||
crawler: false
|
||||
- title: Simon Willison
|
||||
url: https://simonwillison.net/atom/everything/
|
||||
crawler: true
|
||||
- title: Anthropic news
|
||||
url: https://rsshub.bestblogs.dev/anthropic/news
|
||||
crawler: true
|
||||
- title: Huggingface blog
|
||||
url: https://huggingface.co/blog/feed.xml
|
||||
crawler: true
|
||||
- title: Techcrunch AI
|
||||
url: https://techcrunch.com/category/artificial-intelligence/feed/
|
||||
crawler: true
|
||||
- title: Last Week in AI
|
||||
url: https://lastweekin.ai/feed/
|
||||
crawler: true
|
||||
- title: The Batch (Andrew Ng) (news)
|
||||
url: https://news.google.com/rss/search?q=%22The%20Batch%22%20%22DeepLearning.AI%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Microsoft AI blog (news)
|
||||
url: https://news.google.com/rss/search?q=%22Microsoft%20AI%22%20blog&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: LangChain blog (news)
|
||||
url: https://news.google.com/rss/search?q=%22LangChain%22%20blog&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Latent Space
|
||||
url: https://www.latent.space/feed
|
||||
crawler: false # Substack, contenu complet dans le flux
|
||||
- title: MCP releases
|
||||
url: https://github.com/modelcontextprotocol/modelcontextprotocol/releases.atom
|
||||
crawler: false
|
||||
- title: ARC Prize blog (news)
|
||||
url: https://news.google.com/rss/search?q=%22ARC%20Prize%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Baldur Bjarnason
|
||||
url: https://www.baldurbjarnason.com/feed.xml
|
||||
crawler: false # contenu complet dans le flux
|
||||
- title: Yann LeCun (news)
|
||||
url: https://news.google.com/rss/search?q=%22Yann%20LeCun%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Francois Chollet (news)
|
||||
url: https://news.google.com/rss/search?q=%22Fran%C3%A7ois%20Chollet%22%20OR%20%22Francois%20Chollet%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
|
||||
- name: Security
|
||||
feeds:
|
||||
- title: Bleeping Computer
|
||||
url: https://www.bleepingcomputer.com/feed/
|
||||
crawler: true
|
||||
- title: CISA advisories
|
||||
url: https://www.cisa.gov/cybersecurity-advisories/all.xml
|
||||
crawler: false
|
||||
- title: Hacker News
|
||||
url: https://news.ycombinator.com/rss
|
||||
crawler: false
|
||||
|
||||
- name: Sovereignty
|
||||
feeds:
|
||||
- title: Digital sovereignty (news)
|
||||
url: https://news.google.com/rss/search?q=%22digital%20sovereignty%22%20OR%20%22sovereign%20cloud%22%20OR%20%22cloud%20souverain%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: EU regulation - AI Act / Data Act / GAIA-X (news)
|
||||
url: https://news.google.com/rss/search?q=(%22AI%20Act%22%20OR%20%22Data%20Act%22%20OR%20GAIA-X%20OR%20EuroHPC)%20(Europe%20OR%20EU)&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Souverainete numerique FR (news)
|
||||
url: https://news.google.com/rss/search?q=(souverainet%C3%A9%20num%C3%A9rique%20OR%20%22cloud%20de%20confiance%22%20OR%20SecNumCloud)&hl=fr&gl=FR&ceid=FR:fr
|
||||
crawler: true
|
||||
|
||||
- name: Analysts
|
||||
feeds:
|
||||
- title: Sanjeev Mohan
|
||||
url: https://news.google.com/rss/search?q=%22Sanjeev%20Mohan%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Massimo Pezzini
|
||||
url: https://news.google.com/rss/search?q=%22Massimo%20Pezzini%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Gregor Hohpe
|
||||
url: https://news.google.com/rss/search?q=%22Gregor%20Hohpe%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Kai Waehner
|
||||
url: https://news.google.com/rss/search?q=%22Kai%20Waehner%22&hl=en-US&gl=US&ceid=US:en
|
||||
crawler: true
|
||||
- title: Martin Fowler
|
||||
url: https://martinfowler.com/feed.atom
|
||||
crawler: true
|
||||
|
||||
- name: Others
|
||||
feeds:
|
||||
- title: The Register
|
||||
url: https://www.theregister.com/headlines.atom
|
||||
crawler: true
|
||||
- title: InfoQ
|
||||
url: https://feed.infoq.com/
|
||||
crawler: true
|
||||
- title: MIT Technology Review
|
||||
url: https://www.technologyreview.com/feed/
|
||||
crawler: true
|
||||
- title: Open Source Projects
|
||||
url: https://www.opensourceprojects.dev/rss
|
||||
crawler: true
|
||||
- title: Reddit /r/programming
|
||||
url: https://www.reddit.com/r/programming/.rss
|
||||
crawler: false
|
||||
- title: Reddit /r/technology
|
||||
url: https://www.reddit.com/r/technology/.rss
|
||||
crawler: false
|
||||
- title: GitHub blog
|
||||
url: https://github.blog/feed/
|
||||
crawler: true
|
||||
- title: Wired
|
||||
url: https://www.wired.com/feed/rss
|
||||
crawler: true
|
||||
@@ -0,0 +1,2 @@
|
||||
requests
|
||||
PyYAML
|
||||
Reference in New Issue
Block a user