crunk
1 year ago
13 changed files with 246 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
/.venv/ |
|||
/__pycache__/ |
|||
*.pyc |
|||
*.egg-info/ |
|||
.eggs/ |
|||
build/ |
|||
dist/ |
|||
pip-wheel-metadata/ |
|||
|
|||
test/* |
|||
*.db |
@ -0,0 +1,16 @@ |
|||
# Crunk columns |
|||
|
|||
crunk-columns is a work in progress website/portfolio maker. |
|||
part of the crunk suite of software. |
|||
Heavily inspired by [multifeeder](https://git.vvvvvvaria.org/varia/multifeeder) |
|||
This is a [PESOS](https://indieweb.org/PESOS) style website maker. |
|||
By filling in your desired columns in the columns.toml file you can make your own portfolio page in seconds |
|||
By adding your own css you can lose countless of hours tweaking everything. |
|||
|
|||
|
|||
## work in progress. |
|||
|
|||
|
|||
## POSSE is a much better approach, what are you even doing? |
|||
Yes, but I am lazy and I already exist on the internet and this is a way to bring |
|||
it all together. |
@ -0,0 +1,14 @@ |
|||
import os |
|||
from flask import Flask |
|||
# from flask_sqlalchemy import SQLAlchemy |
|||
#db = SQLAlchemy() |
|||
#migrate = Migrate() |
|||
|
|||
def create_app(): |
|||
APP = Flask(__name__) |
|||
#APP.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///data/crunk_data.db" |
|||
#APP.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True |
|||
# db.init_app(APP) |
|||
# migrate.init_app(APP, db, render_as_batch=True) |
|||
|
|||
return APP |
@ -0,0 +1,12 @@ |
|||
class Column: |
|||
def __init__(self, title, entries): |
|||
self.title = title |
|||
self.entries = entries |
|||
self.sort_order = None |
|||
self.limit = None |
|||
|
|||
def set_sort_order(self, sort_order): |
|||
self.sort_order = sort_order |
|||
|
|||
def set_limit(self, limit): |
|||
self.limit = limit |
@ -0,0 +1,11 @@ |
|||
[[column]] |
|||
id = 1 |
|||
urls = ["https://varia.zone/logs/x-y/feed.rss.xml","https://varia.zone/logs/x-y-protocols/feed.rss.xml"] |
|||
title = "code" |
|||
|
|||
[[column]] |
|||
id = 2 |
|||
urls = ["https://post.lurk.org/@cmos4040.rss"] |
|||
sort_order = "chronological" |
|||
title = "circulations" |
|||
limit = 100 |
@ -0,0 +1,22 @@ |
|||
from feedparser import parse |
|||
import random |
|||
|
|||
def _parse_single_rss_feed(url): |
|||
feed = parse(url) |
|||
entries = {} |
|||
for entrynumber, entry in enumerate(feed.entries): |
|||
if entry.has_key("title"): |
|||
entries[entry.title] = [] |
|||
entrylist = entries[entry.title] |
|||
else: |
|||
title = str(entrynumber) |
|||
entries[title] = [] |
|||
entrylist = entries[title] |
|||
entrylist.append(entry.description) |
|||
return entries |
|||
|
|||
def parse_rss_feeds(urls): |
|||
entries = {} |
|||
for url in urls: |
|||
entries.update(_parse_single_rss_feed(url)) |
|||
return entries |
@ -0,0 +1,22 @@ |
|||
[tool.black] |
|||
line-length = 79 |
|||
target-version = ["py37","py38","py39"] |
|||
|
|||
exclude = ''' |
|||
/( |
|||
\.eggs |
|||
| \.git |
|||
| \.hg |
|||
| \.mypy_cache |
|||
| \.tox |
|||
| \.venv |
|||
| _build |
|||
| buck-out |
|||
| build |
|||
| dist |
|||
# The following are specific to Black, you probably don't want those. |
|||
| blib2to3 |
|||
| tests/data |
|||
| profiling |
|||
)/ |
|||
''' |
@ -0,0 +1,20 @@ |
|||
import tomli |
|||
from column import Column |
|||
from parse_rss_feeds import parse_rss_feeds |
|||
|
|||
|
|||
with open("columns.toml", "rb") as f: |
|||
feeds_dict = tomli.load(f) |
|||
|
|||
feeds_file = feeds_dict["column"] |
|||
columns = [] |
|||
for feed_from_file in feeds_file: |
|||
entries = parse_rss_feeds(feed_from_file["urls"]) |
|||
title = feed_from_file["title"] |
|||
column = Column(title=title, entries=entries) |
|||
if "limit" in feed_from_file: |
|||
print(feed_from_file["limit"]) |
|||
columns.append(column) |
|||
|
|||
for column in columns: |
|||
print(column.title) |
@ -0,0 +1,44 @@ |
|||
from flask import ( |
|||
render_template, |
|||
redirect, |
|||
) |
|||
import tomli |
|||
|
|||
from parse_rss_feeds import parse_rss_feeds |
|||
from app import create_app |
|||
from column import Column |
|||
|
|||
APP = create_app() |
|||
|
|||
|
|||
@APP.route("/singlefeed") |
|||
def singlefeed(): |
|||
with open("columns.toml", "rb") as f: |
|||
feeds_dict = tomli.load(f) |
|||
feeds = feeds_dict["column"] |
|||
|
|||
feed = parse_rss_feeds(feeds[0]["urls"][0]) |
|||
return render_template("singlefeed.html", feed=feed) |
|||
|
|||
|
|||
@APP.route("/") |
|||
def index(): |
|||
with open("columns.toml", "rb") as f: |
|||
column_dict = tomli.load(f) |
|||
columns_file = column_dict["column"] |
|||
columns = [] |
|||
for column_from_file in columns_file: |
|||
entries = parse_rss_feeds(column_from_file["urls"]) |
|||
title = column_from_file["title"] |
|||
column = Column(title=title, entries=entries) |
|||
if "limit" in column_from_file: |
|||
column.set_limit(column_from_file["limit"]) |
|||
if "sort_order" in column_from_file: |
|||
column.set_sort_order(column_from_file["sort_order"]) |
|||
columns.append(column) |
|||
return render_template("index.html", columns=columns) |
|||
|
|||
|
|||
if __name__ == "__main__": |
|||
APP.debug = True |
|||
APP.run(port=5000) |
@ -0,0 +1,34 @@ |
|||
body { |
|||
text-rendering: optimizelegibility; |
|||
-moz-text-size-adjust: none; |
|||
} |
|||
.crunkcolumns { |
|||
display: grid; |
|||
grid-auto-flow: column; |
|||
grid-gap: 10px; |
|||
grid-template-columns: repeat(auto-fill, 350px); |
|||
} |
|||
|
|||
.feed { |
|||
grid-template-columns: inherit; |
|||
} |
|||
|
|||
.feeditem { |
|||
display: flex; |
|||
width: 350px; |
|||
position: relative; |
|||
flex-direction: column; |
|||
box-sizing: border-box; |
|||
border: 1px solid black; |
|||
margin-top: 1px; |
|||
padding: 3px; |
|||
} |
|||
|
|||
.feeditem h2, p{ |
|||
margin-bottom: 3px; |
|||
margin-top: 3px; |
|||
} |
|||
img { |
|||
max-width: 100%; |
|||
max-height: 100%; |
|||
} |
@ -0,0 +1,14 @@ |
|||
<!DOCTYPE html> |
|||
<html lang='en'> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<title>Title</title> |
|||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/base.css')}}"> |
|||
<link rel="shortcut icon" href="{{ url_for('static', filename='icons/favicon.ico') }}"> |
|||
</head> |
|||
<body> |
|||
{% block main %} |
|||
{% endblock main %} |
|||
</body> |
|||
</html> |
@ -0,0 +1,16 @@ |
|||
{% extends "base.html" %} |
|||
{% block main %} |
|||
<div class="crunkcolumns"> |
|||
{% for column in columns %} |
|||
<div class="feed"> |
|||
<h1>{{ column.title }}</h1> |
|||
{% for feedtitle, text in column.entries.items() %} |
|||
<div class="feeditem"> |
|||
<h2>{{ feedtitle }}</h2> |
|||
{{ text[0]|safe }} |
|||
</div> |
|||
{% endfor%} |
|||
</div> |
|||
{% endfor%} |
|||
</div> |
|||
{% endblock %} |
@ -0,0 +1,10 @@ |
|||
{% extends "base.html" %} |
|||
{% block main %} |
|||
|
|||
{% for feedtitle, text in feed.items() %} |
|||
<div class="event"> |
|||
<h2>{{ feedtitle }}</h2> |
|||
{{ text[0]|safe }} |
|||
</div> |
|||
{% endfor%} |
|||
{% endblock %} |
Loading…
Reference in new issue