| Age | Commit message (Collapse) | Author |
|
For whatever reason, the environment variables in my `.htaccess` weren't
getting passed to my FastCGI executables on my production server.
Wasn't sure how to get them passed to the programs, so decided instead
to compile the env variables into the binaries.
To do that, we source the environment file before building the release
builds in the Docker container.
|
|
My production server is on Ubuntu 14.04, but I was building the FastCGI
executables with Debian Stretch.
Discovered the problem like this:
$ ./fulfillment.fcgi
./fulfillment.fcgi: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
$ ldd fulfillment.fcgi
linux-vdso.so.1 => (0x000003a94301e000)
libssl.so.1.1 => not found
libcrypto.so.1.1 => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000003a94273d000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x000003a942535000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000003a942317000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000003a942101000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000003a941d38000)
/lib64/ld-linux-x86-64.so.2 (0x000003a942dfe000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000003a941a32000)
In order to link against the right dynamic libraries, build on Ubuntu
Trusty. To do that, I downloaded the Dockerfile at:
https://github.com/rust-lang-nursery/docker-rust/blob/c34d6993e8f9403c18f348de85787f1585fd3375/1.30.1/stretch/Dockerfile
and changed the first line to:
FROM buildpack-deps:trusty
I then built an image from the Dockerfile and tagged it:
$ docker image build .
$ docker image tag IMAGE_ID rust:1.30.1-trusty
|
|
|
|
Got this error from the production MySQL server:
(details: Error 1235: This version of MySQL doesn't yet support
'multiple triggers with the same action time and event for one table')
Change our triggers so we only have one for `BEFORE INSERT`.
|
|
Ended up with this error when running my migrations against the
production server:
error: migration failed in line 0: BEGIN;
CREATE TABLE purchasers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
secret VARCHAR(255),
created_at DATETIME NOT NULL DEFAULT UTC_TIMESTAMP(),
updated_at DATETIME NOT NULL DEFAULT UTC_TIMESTAMP()
);
CREATE TRIGGER purchasers_updated_at
BEFORE UPDATE
ON purchasers FOR EACH ROW
SET NEW.updated_at = UTC_TIMESTAMP();
COMMIT;
(details: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UTC_TIMESTAMP(),
updated_at DATETIME NOT NULL DEFAULT UTC_TIMESTAMP()
);
CR' at line 6)
Using MySQL 5.6.34 in production and MariaDB 10.3.10 locally. Guess you
can't use `DEFAULT UTC_TIMESTAMP()` there.
To use `UTC_TIMESTAMP()`, create a couple new triggers to set the
timestamp in the `created_at` and `updated_at` columns.
|
|
Otherwise it gets rendered small when the page first loads, then expands
to the correct dimensions after the page has loaded. This removes the
jump-cut effect.
|
|
The scroll position is now kept when the modal overlay opens.
|
|
Holds production `.htaccess` and `env` files.
|
|
This line was causing a server error. Happily, the corrected version
looks even nicer.
|
|
To deploy, run
$ make deploy
This checks prerequisites and runs `scripts/deploy.sh`.
Makefile:
Include a new target that builds the Rust binaries for Linux using
Docker.
The script `rsync`s the website files to the server, moves some files
around on the server, and runs the database migrations.
Currently I'm getting an error at the database migration stage, as it
seems I can't use `UTC_TIMESTAMP()` as a default column value. Need to
correct that to get a clean deployment.
|
|
This directory will store archives of program releases.
|
|
Renames the binary. The name "license-generator" no longer seems apt at
this point. That binary doesn't actually generate a license, it serves
as the webhook endpoint for Paddle's license fulfillment. Our `license`
binary handles the actual license generation.
The URL I'll be using for the webhook is `/fulfillment`, so this also
makes sense from that perspective.
|
|
Add the instructions we put in the fulfillment email to the
thank-you/license download page. Want to make sure buyers know how to
license the software after purchasing it.
Rephrase the install text to be simpler and more to the point.
|
|
Include install and license instructions in the purchase fulfillment
email.
|
|
Paddle will take the text from the response of this endpoint and include
it in the purchase fulfillment email to a customer.
Include the URL for the purchaser to download their license. Use the
'url' crate's parser to build the URL in order to URL-escape special
characters.
Honestly I'd rather have had a system where the license file gets
included in the receipt email. Unfortunately, with the Paddle
fulfillment mechanism I'm using, we can only send text. I learned after
building the download endpoint that I could manage fulfillment myself.
This would require me to listen to an "alert"-type Paddle webhook, and
send the email myself (which would include the license file). Since I
already built the license download page, I decided to just use it
instead of doing the emailing. Also, my web host limits my SMTP usage,
so there could be issues there. I'd have to do the emailing in a
separate batch process instead of in the webhook handler to ensure that
no emails would get dropped.
|
|
These are the commands I used to convert the demo video into
HTML5-suitable video formats.
The commands are copied from guides I found on the net looking for
`ffmpeg` HTML5 video conversion. I did add the `-b 275k` setting on the
WebM video to sort of match the bitrate I saw on the MP4 video.
Otherwise it ends up being horrible quality without the flag, or around
14 Mb with the `-b:v 1M` flag (this version results in ~4 Mb).
|
|
Move the existing thank-you page to `thank-you-license-download.html`.
Use `thank-you.html` as the final page of the purchase flow. Paddle will
redirect to this page at the end of purchase. Allows us to retain some
branding during purchase.
Using the existing HTML file for a better URL.
|
|
Do this on all pages that aren't the home page.
|
|
Done already.
|
|
|
|
Doesn't make sense to me to have this page be tracked by search engines.
|
|
|
|
When the screen width gets small enough to clip the video, reduce the
width of the video to the content width.
Couldn't use the same larger-than-content-width layout, at least not
easily, because the percentage would need to be dependent on the window
width, not the width of the video element's container.
|
|
Not committing the video files. They're only 3 & 4 megabytes each, but
that still seems a bit too much to keep in version control.
Add the video to the home page and center it in the content area. We
give it a negative margin to center it since it's wider than the
container.
|
|
|
|
Just tested the program on 10.8 and it didn't work. It ran just fine,
but didn't run map actions, and I'm not sure why. Used the release
build, so I didn't debug it at all.
Since I'm planning an imminent public release, just set the minimum to
an OS version that we know for sure works.
In the future, I'd still like to get the program working on 10.8. We can
always bring down the minimum OS version.
|
|
Turns out this doesn't work very well. It activates the application
switcher, but doesn't deactivate it, so it doesn't go away. Bad example.
Oh well.
|
|
|
|
Give an example of a multi-button trigger mapping.
|
|
Also a section linking to them on the home page.
Generated in the main DomeKey repository with:
$ a2x --no-xmllint --format xhtml doc/dome-key.1.intermediate.txt
$ a2x --no-xmllint --format xhtml doc/dome-key-mappings.7.txt
Deciding to go with the AsciiDoc CSS for now and not bother with making
these pages fit with the site's style to make things easy.
|
|
Clicking on the "Buy" button brings up the Paddle checkout modal
overlay.
|
|
|
|
|
|
Trying to add a little more entropy to the calculation.
Went with chrono instead of `std::time` because it gives me an `i64`
timestamp instead of a `Result`.
|
|
Also add some section comments.
Here we point
/license
and
/license/download
to `license.fcgi`, and
/fulfillment
to `fulfillment.fcgi`. The actual FastCGI binaries with the `.fcgi`
extension get redirected to 404 because we already have nicer-looking
URLs for them.
|
|
|
|
|
|
|
|
Hadn't tested this when I made it. Was outputting a formatted byte
string instead of the plain base64, which resulted in `b'BASE_64'` being
inserted. Output the real base64 to get the image to decode properly.
|
|
HTML copied from the 404 page, but I remove the `text-center` on the
error message because it doesn't look good. Took a multiline message for
me to realise it.
|
|
The `set_404()` function doesn't do this, as it makes no assumptions
about response content type.
|
|
Base structure copied from `404.html`. Python script based on the
`generate_homebrew_formula.py` script in the main DomeKey repository.
The filename comes from the Apache server configuration.
Generate the 500 page because we can't rely on dependencies. This gets
the CSS and logo and includes them inline in the HTML page.
Thanks to this answer for explaining how to get a byte string from a
file to send to the base64 encoder:
https://stackoverflow.com/questions/45482272/typeerror-a-bytes-like-object-is-required-not-str-python-2-to-3/45482834#45482834
|
|
Match the change in `index.html`.
|
|
The `REQUEST_URI` parameter gives us the URL path including the query
string. Unfortunately, there's no param for just the path without the
query string. Well, that's not entirely true. On my production server
I'll be using Apache, and in development I'm using Lighttpd. Apache
provides a `SCRIPT_URL` param that does include just the path, but
Lighttpd doesn't appear to have an equivalent.
I wasn't able to figure out how to add a `SCRIPT_URL` param in Lighttpd
manually, either. Using `bin-environment` in the FastCGI config didn't
work, and using `setenv.add-environment` wouldn't allow me to set it to
both of our routes (I assume).
In light of this, just grab the path from `REQUEST_URI` by getting the
part in front of `?`.
|
|
The query string is already included in the `REQUEST_URI` param. What we
had would just print it twice.
|
|
|
|
|
|
Want to be able to use our static image and CSS assets from the FCGI
code when rendering HTML.
|
|
|
|
I want to be able to use the exact same logic for the `/license` route.
To do so, we move the common logic to a new `build_response()` function.
For all responses we need to return from `build_response()`, make new
structs `HtmlResponse` and `ZipResponse` that write the response in the
desired format.
The `ZipResponse` does what we're already doing in `/license/download`.
The `HtmlResponse` will respond with HTML and show a thank-you page on
success.
|