Skip to content

Commit

Permalink
Add support for Tumblr signposts (#171)
Browse files Browse the repository at this point in the history
These are timeline objects typically used to warn of restricted
searches

Center signpost elements

Add margin to signpost elements

Allow signposts to be cached

Fallback to "" when description is unavailable

Minor CSS organization improvements
  • Loading branch information
syeopite authored Jan 2, 2025
1 parent fb8fc7c commit e4b30fd
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 8 deletions.
8 changes: 6 additions & 2 deletions assets/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ body {
--color-setting-option-desc: var(--light, var(--color-gray-500)) var(--dark, var(--color-dt-gray-250));
--color-settings-theme-select-outline: var(--light, var(--color-primary-400)) var(--dark, var(--color-primary-400));
--color-settings-dropdown-option-bg: var(--light, var(--color-gray-200)) var(--dark, var(--color-dt-gray-400));

--tumblr-signpost-bg: var(--light, var(--color-gray-125)) var(--dark, var(--color-dt-gray-700));
--tumblr-signpost-border: var(--light, var(--color-gray-300)) var(--dark, var(--color-dt-gray-500));
}

html, body, .container {
Expand Down Expand Up @@ -323,8 +326,9 @@ a.logo {

.timeline, .blog-posts {
display: flex;
flex-direction: column;
align-items: center;
gap: 2em;
flex-wrap: wrap;

max-width: 590px;
}
Expand Down Expand Up @@ -498,4 +502,4 @@ li.no-js .control-bar-dropdown-menu {

.page-footer a {
text-decoration: underline;
}
}
45 changes: 45 additions & 0 deletions assets/css/timeline.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* This file contains the styling for various Tumblr timeline objects */

.tumblr-signpost {
display: flex;
flex-direction: row;
align-items: center;
gap: 20px;

width: 350px;
box-sizing: border-box;
overflow: hidden;

margin: 0 20px;
padding: 20px 25px;

background: var(--tumblr-signpost-bg);
color: var(--color-text);
border: 2px solid var(--tumblr-signpost-border);
border-radius: 10px;

box-shadow: rgba(0,0,0,0.2) 0px 1px 3px;
}

.tumblr-signpost svg {
min-width: max-content;
}

.tumblr-signpost p {
line-height: 2;
font-size: 12px;
}

.tumblr-signpost h3 {
font-weight: bold;
margin: 0;
margin-bottom: 10px;
font-size: 14px;
}


@media (max-width: 350px) {
.tumblr-signpost {
width: auto;
}
}
2 changes: 1 addition & 1 deletion src/priviblur_extractor/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from . import base, blog, post, timelines
from . import base, blog, post, timelines, misc

from .base import VERSION
15 changes: 15 additions & 0 deletions src/priviblur_extractor/models/misc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import NamedTuple, Optional

class Signpost(NamedTuple):
title: str
description: Optional[str] = None

def to_json_serialisable(self):
return {
"title": self.title,
"description": self.description
}

@classmethod
def from_json(cls, json):
return cls(**json)
13 changes: 9 additions & 4 deletions src/priviblur_extractor/models/timelines.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from . import base
from .post import Post, ReplyNote, ReblogNote, LikeNote
from .misc import Signpost
from. blog import Blog


Expand Down Expand Up @@ -102,10 +103,12 @@ class Timeline(NamedTuple):
def to_json_serialisable(self):
elements = []
for element in self.elements:
if isinstance(element, Blog):
if isinstance(element, Post):
elements.append({"post": element.to_json_serialisable()})
elif isinstance(element, Blog):
elements.append({"blog": element.to_json_serialisable()})
else:
elements.append({"post": element.to_json_serialisable()})
elements.append({"signpost": element.to_json_serialisable()})

next_ = self.next
if next_:
Expand All @@ -121,10 +124,12 @@ def to_json_serialisable(self):
def from_json(cls, json):
elements = []
for element in json["elements"]:
if blog := element.get("blog"):
if post := element.get("post"):
elements.append(Post.from_json(post))
elif blog := element.get("blog"):
elements.append(Blog.from_json(blog))
else:
elements.append(Post.from_json(element["post"]))
elements.append(Signpost.from_json(element["signpost"]))

json["elements"] = elements

Expand Down
7 changes: 6 additions & 1 deletion src/priviblur_extractor/parse/collection_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ def parse(self):
elements = []
total_raw_elements = len(self.target["elements"])
for element_index, element in enumerate(self.target["elements"]):
if result := items.parse_item(element, element_index, total_raw_elements):
if result := items.parse_item(
element,
element_index,
total_raw_elements,
use_parsers=(items.PostParser, items.SignpostParser)
):
elements.append(result)

return models.timelines.Timeline(
Expand Down
16 changes: 16 additions & 0 deletions src/priviblur_extractor/parse/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,22 @@ def parse(self):
)


class SignpostParser:
def __init__(self, target) -> None:
self.target = target

@classmethod
def process(cls, initial_data):
if initial_data.get("objectType") == "signpost_cta":
return cls(initial_data).parse()

def parse(self):
return models.misc.Signpost(
title=self.target["display"]["title"],
description=helpers.dig_dict(self.target, ("resources", "description")),
)


def parse_item(element, element_index=0, total_elements=1, use_parsers=None):
"""Parses an item from Tumblr API's JSON response into a more usable structure"""
item_number = f"({element_index + 1}/{total_elements})"
Expand Down
7 changes: 7 additions & 0 deletions src/templates/components/signpost.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<figure class="tumblr-signpost">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="48px" width="48px" viewBox="0 -960 960 960"><path d="M451.5-85v-185H234L125-379l109-108.5h217.5v-90H165V-795h286.5v-80H509v80h217.5L835-686.5l-108.5 109H509v90h286V-270H509v185h-57.5Zm-229-550h480l51-51.5-51-51h-480V-635ZM258-327.5h479.5V-430H258l-51.5 51 51.5 51.5ZM222.5-635v-102.5V-635Zm515 307.5V-430v102.5Z"/></svg>
<div>
<h3>{{element.title}}</h3>
<p>{{element.description or ""}}</p>
</div>
</figure>
2 changes: 2 additions & 0 deletions src/templates/macros/insert_content_list.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
{%- if not element.is_advertisement -%}
{%- include 'post/post.jinja' -%}
{%- endif -%}
{% else %}
{%- include 'components/signpost.jinja' -%}
{% endif %}
{%- endfor -%}
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/templates/timeline.jinja
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{% extends "base.jinja" %}
{% from 'macros/insert_content_list.jinja' import insert_content_list with context %}


{% block head %}<link rel="stylesheet" type="text/css" href="/assets/css/timeline.css?v={{app.ctx.CURRENT_COMMIT}}">{% endblock %}
{% block title %}{{title}}{% endblock%}

{% block center %}
Expand Down

0 comments on commit e4b30fd

Please sign in to comment.