Age | Commit message (Collapse) | Author | Files | Lines |
|
When I ran `pass show some/password`, gpg, which uses pinentry would start its
ncurses password prompt. For many this wouldn't be a problem but my current
vterm version cannot send the <return> key to ncurses, so once that prompt
appears, I cannot get rid of it without C-c and killing the shell. For a day or
more I just opened suffered through this.
Today I dug more into the issue and when I ran `pinentry --version` it warned
that it couldn't connect to DBUS. After searching for more information on this,
people with similar issues recommended starting their window managers with
`dbus-launch`. I previously started Emacs with `dbus-launch`, but only because
some i3 documentation told me to do so and I just copied them. Then I switched
to EXWM and copied that pattern over. A friend of mine uses EXWM and starts his
without calling `dbus-launch` but `exec emacs`. I mirrored this thinking that I
no longer needed `dbus-launch`. What I didn't know, however, was that this
friend was using a Nix-built Emacs (like me) except that his wrapped a native
Emacs installation while mine doesn't. His natively wrapped Emacs installation
has the proper variables set to interact with dbus and other important Linuxy
things that I don't fully understand. Since I'm using a Nix-built Emacs, some of
my variables are unset or set to different values than programs expect. This is
why when I try and start `gnome-terminal` or `terminator`, they refuse to start
and warn about many unset or incorrectly variables and not being able to bind to
sockets, etc.
This change reverts back to using `dbus-launch` until I have a better
understanding of Linux, Nix, etc.
|
|
After reading these docs
https://api.youneedabudget.com/v1#/Transactions/createTransaction I successfully
made a request to post a transaction to my YNAB account. Hastily created a
client.go that doesn't contain much at the moment.
|
|
Grouping entries by country and sorting according to Done -> Todo.
I should consider sorting the country groups alphabetically by the country name
and then each entry alphabetically by its city name.
Right now, however, this isn't a priority.
|
|
I would like to see Istanbul and Ankara one day.
|
|
In 2013, I lived in Grenoble with a host family. During that time, I visited
Lyons, as well as a few other locations that aren't tracked by this document at
the time of this writing.
|
|
Removing a trailing comma from Dubrovnik, Croatia.
|
|
I spent two weeks on the Spanish islands of Ibiza and Formentera over the
summer.
I went to Hamburg twice to visit Mimi's family - once in the summer; once for
Christmas.
In the Fall, I went to Bordeaux with Mimi where we stayed at a charming Airbnb.
I spent New Years Eve in Amsterdam with Matty, Ryan, and Conor.
I may be missing a few other places that I visited in 2019; it was an active
year.
|
|
git-subtree-dir: travel_hitlist
git-subtree-mainline: 3fa827681622dc9f20d5095a781e78dbaaa23791
git-subtree-split: a97002bb21425c4d36335e9d70a1ec8bad6b51f2
|
|
Without these KBDs, C-k kills buffers. As an evil-mode user, I expect C-k to
move upwards. As such, adding the `ivy-switch-buffer-map` to my existing ivy
KBDs that handle a similar use-case.
Note: I'm unsure why the KBDs in evil-collection didn't cover this.
|
|
For awhile I had a mixture of ivy and ido. Disabling ido and preferring ivy for
everything.
|
|
I ran `M-x package-autoremove` that deleted `ts.el`, which wasn't listed in my
default.nix. Adding it...
|
|
- Move state "gen server" to the top of main/0
- Initialize it as empty
- Ensure that persistTokens/2 is called whenever the state changes
- Support setState/2 (similar in spirit to getState/0)
|
|
Problem:
When SIGINT signals we're sent to the token server, it would shut down without
completing the shutdown procedure. The shutdown procedure would persist the
application state (i.e. access and refresh tokens).
This is problematic for the following sequence of events:
t0. Access and refresh tokens retrieved from kv.json and used as app state.
t1. Tokens are refreshed but not persisted. (I'm still unsure how this
happens). Remember that this means the previous access and refresh tokens
from t0 are now invalid.
t2. User sends a SIGINT.
t3. Token server shuts down.
t4. Token server is restarted, kv.json is used as the app state even though its
tokens are now invalid.
t5. Tokens are attempted to refresh, Monzo API rejects the tokens because
they're invalid.
Now we need to provide the token server with valid access and refresh tokens
otherwise we will repeat the loop described above. This means going through the
client authorization flow again or copying and pasting the tokens logged from
the token server into kv.json. Either scenario is more manual than I'd prefer.
Solution:
Use a buffered channel to receive the os.Signal. I got this idea after reading
these docs: https://golang.org/pkg/os/signal/#Notify and I debugged this issue
shortly thereafter.
I also rearranged the order of operations in main/0 to ensure that
handleInterrupts/0, which registers the event listeners, occurs before
scheduleTokenRefresh/2 is called. This allows the token server to gracefully
shutdown even if it's in the middle of the scheduleTokenRefresh/2 call.
|
|
None of this code is functional at the moment. I'm just writing some ideas of
how I'd like to work.
|
|
Consume the newly relocated auth package.
Additionally:
- Debugged error where JSON was properly decoding but not populating the
refreshTokenResponse struct, so my application was signaling false positive
messages about token refresh events.
- Logging more often and more data to help my troubleshooting
- Refreshing tokens as soon as the app starts just to be safe
- Clean up the code in general
|
|
Relocated the logic for authorizing clients into a separate package that the
tokens server now depends on. Moving this helped me separate concerns. I removed
a few top-level variables and tried to write more pure versions of the
authorization functions to avoid leaking Monzo-specific details.
|
|
Exposing functions to print HTTP request and response structs.
|
|
I'm writing sensitive data here, so I'd like to ignore it instead of encrypting
it and publishing it. Perhaps later on, I can extend the key-value store to
handle encryption and decryption but that feels like overkill for now.
|
|
Listen for SIGINT and SIGTERM signals and write the current state to the
key-value store before shutting down.
|
|
Attempting to read the persisted tokens from the key-value store when the server
begins. The server currently fails when those values are empty.
TODO
- Consider adding logic for knowing if the cached tokens are expired and prompt
the user to reauthorize the client using a web browser.
|
|
- Package tokens.go with Nix
- Add monzo_ynab.{job,tokens} to shell.nix
|
|
Removing a half-baked Monzo HTTP client. A more fully supported and differently
designed one is forthcoming.
|
|
- Created a gopkgs directory and registered it with default.nix's readTree
- Moved monzo_ynab/utils -> gopkgs
- Consumed utils.go in main.go
- Renamed monzo_ynab -> job
|
|
In order to persist my access and refresh tokens, I needed a store. I think
using a database like SQLite may have been fine for this but was heavier weight
than what I wanted.
I decided to write a simple key-value store when the state is encoded and JSON
in a file called kv.json.
TODO:
- Support field nesting
- Support better error handling
- Support parameterizing the store path (i.e. ./kv.json)
|
|
I created a server to manage my access and refresh tokens. This server exposes a
larger API than it needs to at the moment, but that should change. The goal is
to expose a GET at /token to retrieve a valid access token. The server should
take care of refreshing tokens before they expire and getting entirely new
tokens, should they become so stale that I need to re-authorize my application.
A lot of my development of this project has been clumsy. I'm new to Go; I didn't
understand OAuth2.0; I'm learning concurrent programming (outside of the context
of comfortable Elixir/Erlang).
My habits for writing programs in compiled languages feels amateurish. I find
myself dropping log.Println's all over the source code when I should be using
proper debugging tools like Delve and properly logging with things like
httputil.Dump{Request,Response}.
The application right now is in a transitional state. There is still plenty of
code in main.go that belongs in tokens.go. For instance, the client
authorization code belongs in the tokens server.
Another question I haven't answered is where is the monzo client that I can use
to make function calls like `monzo.Transactions` or `monzo.Accounts`?
The benefit of having a tokens server is that it allows me to maintain state of
the tokens while I'm developing. This way, I can stop and start main.go without
disturbing the state of the access tokens. Of course this isn't the primary
benefit, which is to abstract over the OAuth details and expose an API
that gives me an access token whenever I request one.
The first benefit that I listed could and perhaps should be solved by
introducing some simple persistence. I'd like to write the access tokens to disk
when I shutdown the tokens server and read them from disk when I start the
tokens server. This will come. I could have done this before introducing the
tokens server, and it would have saved me a few hours I think.
Where has my time gone? Mostly I've been re-authorizing my client
unnecessarily. This process is expensive because it opens a web browser, asks me
to enter my email address, sends me an email, I then click the link in that
email. Overall this takes maybe 1-3 minutes in total. Before my tokens server
existed, however, I was doing this about 10-20 times per hour. It's a little
disappointing that I didn't rectify this earlier. I'd like to remain vigilant
and avoid making similar workflow mistakes as I move ahead.
|
|
I'm continuing to use restclient-mode, and I'm enjoying it. Updating the scratch
file with more endpoints and credentials.
|
|
Uploading some snippets I created to help me better understand concurrency in
general and specifically concurrency in golang.
|
|
I enjoyed using term-switcher so much that I ended up adopting vterm as my
primary terminal. After reaching for vterm as often as I did, I realized that I
would enjoy supporting cycling through instances, creating new instances,
deleting existing instances, renaming instances. Thus spawned vterm-mgt.el.
I'm particularly excited about the KBD to toggle between vterm instances and
source code buffers.
|
|
Supporting these functions was a little tricky. For example, how should we
handle calling cycle/remove on the item that is currently focused? After
attempting to be clever, I decided to just set the value to nil and let the
consumer decide what is best for them. I can always support a more opinionated
version that fallsback to previous-index if previous-index is set. But until I
have a better idea of how I'm going to consume this, I think nil is the best
option.
|
|
I oftentimes call `cycle/focus` and pass `(lambda (a) (equal a b))`. This
function should tighten up my code.
|
|
Add predicate for determining if a cycle contains items.
Updated cycle/{new,from-list} to support setting current-index to nil when a
consumer calls it with an empty list.
|
|
- generate_board: writing
- print_board: reading
- neighbords: reading
I'm working up to creating a function to initialize a game board where no three
adjacent cells either vertically or horizontally should be the same value.
|
|
Recently I've been asked a few interview questions that involve reading from or
writing to a grid, matrix, game board, etc. I am not as fast as I'd like to be
at this, so I'm going practice.
Here I'm practicing reading from existing matrices. I should practice writing to
empty boards, reading neigboring cells, wrapping around the board (in the case
of Conway's Game of Life), and other useful practices.
|
|
I've been using restclient.el and `restclient-mode` lately to test API calls,
and I'm enjoying. I think it might make sense to track these scratch files in
the repo. Who knows? They may serve as a form of documentation.
|
|
Define transaction structs for both Monzo and YNAB. Each package has a `main`
function that runs some shallow but preliminary round-trip tests for the
serializers and decoders.
The fixtures.json file that each of them is referencing has been ignored in case
either contains confidential data of which I'm unaware.
|
|
Define my YNAB personal access token as an environment variable. Prefix Monzo
environment variables with "monzo_" to more easily differentiate between Monzo
credentials and YNAB credentials.
|
|
Whenever possible, prefer starting things as systemd units instead of
instantiating them in ~/.profile and other dotfiles.
|
|
I removed most of the packages that I install with `nix-env`. You can view these
with `nix-env --query`. This is one small step in a grander project to migrate
entirely to a declarative config managed by Nix.
|
|
This does two things:
1. Starts lorri daemon
2. Moves ssh-agent and docker daemon startup calls to ~/.profile
I'm still not entirely sure when ~/.profile is evaluated... I'd like to use
systemd to startup and manage these background services, but I currently don't
have a strong enough desire to do this.
|
|
`stack path --local-doc-root` gets evaluated when I create a shell, which is not
what I intended.
|
|
dkish was an idea to quickly create REPLs for all sorts of languages like
Haskell, Elixir, Clojure. I haven't used these, and if I started wanting these
with my newfound comfort with Nix, I think I'd reach for that instead.
|
|
I'm in the midst of transitioning onto a few new tools.
My previous workflow just used `nix-env` to install *some* packages. I didn't
have a prescribed methodology for which packages I would install using `nix-env`
and which ones I would install using `sudo apt-get install`. Sometimes if a
package would be available in my aptitude repositories, I'd use that; other
times when it wasn't available I'd use `nix-env`. One complication about being
on gLinux intead of NixOS is that some packages (e.g. nixpkgs.terminator) is
available via `nix-env -iA nixpkgs.terminator`, but the installation won't
actually run on my gLinux. In these instances, I would install terminator from
the aptitude repositories.
Then @tazjin introduced me to his Emacs configuration that he builds using
Nix. What appealed to me about his built Emacs is that it worked as expected on
either a NixOS machine and on gLinux (and presumably on other non-NixOS machines
as well).
A setup towards which I'm working is to own one or a few NixOS machines whose
configurations are entirely managed with Nix. On devices like my work machines,
which cannot run NixOS, I can build as much of the software that I need using
Nix and attempt to minimize the ad hoc configuration either with shell scripts,
python, golang, or more Nix code... it's clear that I still don't have a clear
idea of how that part will work.
For now, I'm adopting nix, nix-env, lorri, direnv, and weening off of aptitude
as much as I can. Things are a bit messy, but my general trend feels
positive. Stay tuned for more updates.
|
|
From what I currently understand, lorri is a tool (sponsored by Target) that
uses nix and direnv to build and switch between environments quickly and
easily.
When you run `lorri init` inside of a directory, lorri creates a shell.nix and
an .envrc file. The .envrc file calls `eval "$(lorri direnv)"` and the shell.nix
calls `<nixpkgs>.mkShell`, which creates a shell environment exposing
dependencies on $PATH and environment variables. lorri uses direnv to ensure
that $PATH and the environment variables are available depending on your CWD.
lorri becomes especially powerful because of Emacs's `direnv-mode`, which
ensures that Emacs buffers can access anything exposed by direnv as well.
I still need to learn more about how lorri works and how it will affect my
workflow, but I'm enjoying what I've seen thus far, and I'm optimistic about the
road ahead.
|
|
actors.go is my attempt to better understand golang's channels. I'm mapping my
understanding of concurrency from my experience with Elixir / Erlang and actors
onto golang until I have more opinions.
|
|
Since I did not pass my one-site interview with DM, but I have been invited to
attempt again, I decided to partition this directory into two parts:
1. part_one: Hosting the exercises that I completed before my first attempt at
earning the job.
2. part_two: Hosting the exercise that I will complete before my second attempt
at earning the job.
|
|
My Emacs initialization fails for a few reasons, which I haven't prioritized
time to investigate yet:
- Some OCaml deps are absent
- godoc is absent
|
|
After some toil and lots of learning, monzo_ynab is receiving access and refresh
tokens from Monzo. I can now use these tokens to fetch my transactions from the
past 24 hours and then forward them along to YNAB.
If YNAB's API requires OAuth 2.0 login flow for authorization, I should be able
to set that up in about an hour, which would be much faster than it took me to
setup the login flow for Monzo. Learning can be a powerful thing.
See the TODOs scattered around for a general idea of some (but not all) of the
work that remains.
TL;DR
- Package monzo_ynab with buildGo
- Move some utility functions to sibling packages
- Add a README with a project overview, installation instructions, and a brief
note about my ideas for deployment
Note: I have some outstanding questions about how to manage state in Go. Should
I use channels? Should I use a library? Are top-level variables enough? Answers
to some or all of these questions and more coming soon...
|
|
I discovered direnv's convenient `source_up` function today. I needed it to
inherit the values defined in ~/briefcase/.envrc, and it's working exactly as I
expected it would. What a fine piece of software direnv is.
|
|
I'm now pulling the authorization code off of Monzo's request to my redirect
URI. I intend to use exchange that code for an access and refresh token. Once I
have these two items, I should be able to interact with Monzo's API much more
easily.
|
|
- Prefer goimports to gofmt. goimports calls gofmt; it also adds and removes
dependencies.
- Assert the presence of goimports, godoc, godef
- KBD godef to M-.
- Support the M-x compile command for calling `go build -v`
|