Skip to content

Social embeds with oEmbed and Open Graph - #643

Open
po5 wants to merge 6 commits into
rr-:masterfrom
po5:embed
Open

Social embeds with oEmbed and Open Graph#643
po5 wants to merge 6 commits into
rr-:masterfrom
po5:embed

Conversation

@po5

@po5 po5 commented Mar 21, 2024

Copy link
Copy Markdown
Collaborator

Differences with the approaches in #421, #422 and #441:

  • No new dependencies (such as an extra server, Lua scripting module, Caddy)
  • Proper Twitter meta tags (name attribute instead of property)
  • Only serves dynamic HTML on pages we support embeds for (currently only posts but easily extensible)
  • Returns 404 status code on deleted posts
  • Very minimal implementation, easy to review
  • Booru works just like it currently does for those who don't make the routing changes
  • Implements both oEmbed and Open Graph for the very best compatibility

Things that can be improved later:

  • Embedding of videos (currently shows a thumbnail)
  • Caching (I personally don't think it's necessary, better to return up-to-date data and let the instance owner decide)
  • Generic embed for static pages

Meant to be used with an nginx config like:

location ~ ^/booru/(post/[0-9]+)(?:/.*)?$ {
    set $query $1;
    proxy_pass http://127.0.0.1:6666/index/$query;
    proxy_set_header Accept "*/*";
}

Discord
image
Twitter
image

Closes #416

@ninjazan420

Copy link
Copy Markdown

May be a stupid question, but I have never changed something server side wise. So how could I implement it, after changing the files?
What I do for client side updates is docker compose down && docker compose build && docker compose up -d, but it doesn't catch the server updates :)

Thanks for your help!

@milezzz

milezzz commented Jul 7, 2024

Copy link
Copy Markdown

I merged this branch on a fresh git pull of rr-:master and I get 502 bad gateway errors. See screenshot.

CleanShot 2024-07-08 at 02 07 40@2x

The domain is behind cloudflare, if that matters. Any clue what could be causing this? Pulling my hair out :/

@TiredSysOp

Copy link
Copy Markdown

I merged this branch on a fresh git pull of rr-:master and I get 502 bad gateway errors. See screenshot.

CleanShot 2024-07-08 at 02 07 40@2x

The domain is behind cloudflare, if that matters. Any clue what could be causing this? Pulling my hair out :/

Post logs and check this https://github.com/rr-/szurubooru/wiki/Common-errors

@milezzz

milezzz commented Jul 7, 2024

Copy link
Copy Markdown

Well doesn't seem to be a permission issue. When I remove the embed merge and rebuild everything works again. Sorry here's the docker-compose logs output:

server-1  | INFO  [alembic.runtime.migration] Will assume transactional DDL.
server-1  | Starting szurubooru API on port 6666 - Running on 4 threads
server-1  | Traceback (most recent call last):
server-1  |   File "/usr/bin/waitress-serve-3", line 33, in <module>
server-1  |     sys.exit(load_entry_point('waitress==1.4.4', 'console_scripts', 'waitress-serve')())
server-1  |   File "/usr/lib/python3.8/site-packages/waitress/runner.py", line 270, in run
server-1  |     app = resolve(module, obj_name)
server-1  |   File "/usr/lib/python3.8/site-packages/waitress/runner.py", line 211, in resolve
server-1  |     obj = __import__(module_name, fromlist=segments[:1])
server-1  |   File "/opt/app/szurubooru/facade.py", line 11, in <module>
server-1  |     from szurubooru import api, config, db, errors, middleware, rest
server-1  |   File "/opt/app/szurubooru/api/__init__.py", line 2, in <module>
server-1  |     import szurubooru.api.embed_api
server-1  |   File "/opt/app/szurubooru/api/embed_api.py", line 13, in <module>
server-1  |     with open(f"{config.config['data_dir']}/../index.htm") as index:
server-1  | FileNotFoundError: [Errno 2] No such file or directory: '/data//../index.htm'```

@milezzz

milezzz commented Sep 9, 2024

Copy link
Copy Markdown

I took another stab at this but continue to get this error:

FileNotFoundError: [Errno 2] No such file or directory: '/data//../index.htm

I tried hardcoding the directory (/var/www/index.htm), but even that gets the same error which is confusing because I run:

sudo docker exec -it szurubooru-client-1 ls -al /var/www/

...and I confirm the index file is there. I assume it has something to do with the fact I am running inside a docker but not sure what's up. Pretty desperate to get some proper SEO built into my instance so if anyone has an idea how to get this working inside a docker I'd love to hear it.

@neobooru

neobooru commented Sep 29, 2024

Copy link
Copy Markdown
Collaborator

I believe this setup can't work for docker based deployments, because the index.htm file lives inside the client container and the server container wants to read it. I am not sure what the best solution to this would be.
Maybe the best solution would be 'true' server rendered pages? But that requires a lot of work. (E.g. rewriting client to use Nuxt or something like that).

@po5

po5 commented Mar 28, 2025

Copy link
Copy Markdown
Collaborator Author

Should now work in Docker.

@ewof

ewof commented Sep 3, 2025

Copy link
Copy Markdown
Contributor

my site is like booru.domain.com
some of the urls had double slashes like //

@rest.routes.get("/index(?P<path>/.+)")
def post_index(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
    path = _index_path(params)

    if not index_html:
        logging.info("Embed was requested but index.htm file does not exist. Redirecting to 404.")
        return {"return_type": "custom", "status_code": "404", "content": [("content-type", "text/html")]}

    try:
        oembed = get_post(ctx, {}, path)
    except posts.PostNotFoundError:
        return {"return_type": "custom", "status_code": "404", "content": index_html}

    url = config.config["site_url"] + path
    new_html = index_html.replace("</head>", f'''
<meta property="og:site_name" content="{config.config["name"]}">
<meta property="og:url" content="{html.escape(url).replace("//","/")}">
<meta property="og:type" content="article">
<meta property="og:title" content="{html.escape(oembed['title'])}">
<meta name="twitter:title" content="{html.escape(oembed['title'])}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{html.escape(oembed['url']).replace("//","/")}">
<meta property="og:image:url" content="{html.escape(oembed['url']).replace("//","/")}">
<meta property="og:image:width" content="{oembed['width']}">
<meta property="og:image:height" content="{oembed['height']}">
<meta property="article:author" content="{html.escape(oembed['author_name'] or '')}">
<link rel="alternate" type="application/json+oembed" href="{config.config["site_url"]}/api/oembed?url={quote(html.escape(url))}" title="{html.escape(config.config["name"])}"></head>
''').replace("<html>", '<html prefix="og: http://ogp.me/ns#">').replace("<title>Loading...</title>", f"<title>{html.escape(oembed['title'])}</title>").replace("//","/")
    return {"return_type": "custom", "content": new_html}

just replaced them with single slashes in embed_api.py to fix
im using docker tho and it works perfectly fine

also for the nginx used

location ~ ^/(post/[0-9]+)(?:/.*)?$ {
    set $query $1;
    proxy_pass http://127.0.0.1:6666/index/$query;
    proxy_set_header Accept "*/*";
}

instead

@po5

po5 commented Sep 4, 2025

Copy link
Copy Markdown
Collaborator Author

You need to set site_url to the site link without a trailing slash. I guess we could rstrip slashes from it so both work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenGraph embeds

8 participants