Homepage: tab layout, RSS proxy, and deploy docs
- Reorganize services into OPS/DATA/FEEDS/LINKS tabs with compact DB grid - Add rss-proxy service (29 FDE feeds) and Intel feed groups - Update Palantir theme CSS/JS; Dell wordmark SVG; Proxmox API token auth - Add deploy/docker-compose.homepage.yml and config/homepage/README.md - Stop tracking runtime logs; add .gitignore
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""RSS proxy for ATC Lakehouse — normalized JSON for homepage widgets."""
|
||||
from flask import Flask, jsonify
|
||||
import feedparser
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
FEEDS = {
|
||||
# Hacker News & community
|
||||
"hn-front": "https://hnrss.org/frontpage",
|
||||
"hn-de": "https://hnrss.org/newest?q=data+engineering",
|
||||
"hn-kafka": "https://hnrss.org/newest?q=kafka",
|
||||
"hn-spark": "https://hnrss.org/newest?q=apache+spark",
|
||||
"hn-lakehouse": "https://hnrss.org/newest?q=lakehouse",
|
||||
"lobsters": "https://lobste.rs/rss",
|
||||
# Data architecture & FDE reading
|
||||
"de-weekly": "https://www.dataengineeringweekly.com/feed",
|
||||
"de-central": "https://dataengineeringcentral.substack.com/feed",
|
||||
"pragmatic": "https://blog.pragmaticengineer.com/rss/",
|
||||
"martinfowler": "https://martinfowler.com/feed.atom",
|
||||
"infoq": "https://www.infoq.com/feed/",
|
||||
"oreilly-radar": "https://feeds.feedburner.com/oreilly/radar/atom",
|
||||
"bytebytego": "https://blog.bytebytego.com/feed",
|
||||
"seattle-de": "https://www.seattledataguy.com/feed/",
|
||||
# Platforms & lakehouse stack
|
||||
"confluent": "https://www.confluent.io/rss.xml",
|
||||
"databricks": "https://www.databricks.com/blog/feed.xml",
|
||||
"airflow": "https://airflow.apache.org/blog/index.xml",
|
||||
"debezium": "https://debezium.io/blog.atom",
|
||||
"elastic": "https://www.elastic.co/blog/feed",
|
||||
"minio": "https://blog.min.io/rss.xml",
|
||||
"aws-bigdata": "https://aws.amazon.com/blogs/big-data/feed/",
|
||||
"google-cloud": "https://cloudblog.withgoogle.com/rss/",
|
||||
"cloudflare": "https://blog.cloudflare.com/rss/",
|
||||
"fb-engineering": "https://engineering.fb.com/feed/",
|
||||
# Newsletters
|
||||
"tldr-de": "https://tldr.tech/rss/dataengineering",
|
||||
"thenewstack": "https://thenewstack.io/feed/",
|
||||
"kdnuggets": "https://www.kdnuggets.com/feed",
|
||||
"towardsds": "https://medium.com/feed/towards-data-science",
|
||||
"redmonk": "https://redmonk.com/feed/",
|
||||
}
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
def health():
|
||||
return jsonify({"status": "ok", "count": len(FEEDS), "feeds": sorted(FEEDS.keys())})
|
||||
|
||||
|
||||
@app.get("/feed/<name>")
|
||||
def feed(name):
|
||||
url = FEEDS.get(name)
|
||||
if not url:
|
||||
return jsonify({"error": f"unknown feed: {name}", "feeds": sorted(FEEDS.keys())}), 404
|
||||
parsed = feedparser.parse(url)
|
||||
items = [
|
||||
{
|
||||
"title": e.get("title", "Untitled"),
|
||||
"link": e.get("link", ""),
|
||||
"published": e.get("published", e.get("updated", "")),
|
||||
}
|
||||
for e in parsed.entries[:10]
|
||||
]
|
||||
return jsonify({"title": parsed.feed.get("title", name), "items": items})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=8090)
|
||||
Reference in New Issue
Block a user