Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link to BLOB downloads #2

Open
simonw opened this issue Oct 25, 2020 · 10 comments
Open

Link to BLOB downloads #2

simonw opened this issue Oct 25, 2020 · 10 comments
Labels

Comments

@simonw
Copy link
Owner

simonw commented Oct 25, 2020

As added to Datasette in simonw/datasette#1036

Blocked awaiting release of Datasette 0.51.

@simonw simonw added the blocked label Oct 25, 2020
@simonw
Copy link
Owner Author

simonw commented Oct 25, 2020

I should use row_blob() and document it:

@simonw
Copy link
Owner Author

simonw commented Oct 30, 2020

I can ship this against the new 0.51a1 release.

@simonw
Copy link
Owner Author

simonw commented Jul 10, 2022

Interface with the plugin installed:

CleanShot 2022-07-10 at 09 04 57@2x

Without:

image

@simonw
Copy link
Owner Author

simonw commented Jul 10, 2022

This will be easier after the next Datasette release since it adds the row to the render_cell plugin hook:

@simonw
Copy link
Owner Author

simonw commented Jul 10, 2022

Blocked on that release.

@simonw
Copy link
Owner Author

simonw commented Sep 14, 2022

https://github.com/simonw/datasette/releases/tag/0.62 is out, unblocking this.

@simonw
Copy link
Owner Author

simonw commented Sep 14, 2022

Here's the code in Datasette core that renders the <Binary: x bytes> link:

https://github.com/simonw/datasette/blob/5aa359b86907d11b3ee601510775a85a90224da8/datasette/views/table.py#L934-L948

                display_value = markupsafe.Markup(
                    '<a class="blob-download" href="{}"{}>&lt;Binary:&nbsp;{:,}&nbsp;byte{}&gt;</a>'.format(
                        datasette.urls.row_blob(
                            database_name,
                            table_name,
                            path_from_row_pks(row, pks, not pks),
                            column,
                        ),
                        ' title="{}"'.format(formatted)
                        if "bytes" not in formatted
                        else "",
                        len(value),
                        "" if len(value) == 1 else "s",
                    )
                )

@simonw
Copy link
Owner Author

simonw commented Sep 14, 2022

I need pks, which can be found like this:

        pks = await db.primary_keys(table_name)

But I really don't want to run that for every single time the render_cell hook is called.

@simonw
Copy link
Owner Author

simonw commented Sep 14, 2022

I'm tempted to add pks to the list of arguments to the render_cell() hook in Datasette core.

One catch there though: it's not available for arbitrary database queries, but those need to be supported by this plugin too - like this: https://latest.datasette.io/_memory?sql=select+X%2753514C697465%27

image

Here's how that works: https://github.com/simonw/datasette/blob/5aa359b86907d11b3ee601510775a85a90224da8/datasette/views/database.py#L409-L430

                        elif isinstance(display_value, bytes):
                            blob_url = path_with_format(
                                request=request,
                                format="blob",
                                extra_qs={
                                    "_blob_column": column,
                                    "_blob_hash": hashlib.sha256(
                                        display_value
                                    ).hexdigest(),
                                },
                            )
                            formatted = format_bytes(len(value))
                            display_value = markupsafe.Markup(
                                '<a class="blob-download" href="{}"{}>&lt;Binary:&nbsp;{:,}&nbsp;byte{}&gt;</a>'.format(
                                    blob_url,
                                    ' title="{}"'.format(formatted)
                                    if "bytes" not in formatted
                                    else "",
                                    len(value),
                                    "" if len(value) == 1 else "s",
                                )
                            )

@simonw
Copy link
Owner Author

simonw commented Sep 14, 2022

This code is all complex enough that I think I need to refactor it in Datasette core so I can reuse that here, rather than re-implementing some pretty gnarly Datasette internals just for this plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant