Skip to content

Commit

Permalink
Merge branch 'project-logs'
Browse files Browse the repository at this point in the history
  • Loading branch information
thijzert committed Feb 20, 2023
2 parents f5a6d1f + e2ffdd5 commit cbdac93
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 54 deletions.
39 changes: 31 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,54 @@ This is a Journaling utility I wrote in Go. It features a command-line utility f

Go-journal was originally created as a replacement for [jrnl](https://github.com/maebert/jrnl), but other than the storage format the two share very little.

Usage
Overview
-----
This repository builds two executables. The first, `jrnl`, kinda sorta emulates what @maebert did. One can either pass the `--create` flag to add an entry by piping some text to stdin, or the `--search` flag to look for any journal entries that contain all of the following arguments.

The `journal-server` spins up a web server with an interface for adding entries to the journal. (Not reading them!)
It's secured via the very advanced 'secret bookmark' method, which easily enables one to use the interface on your smartphone, no matter the species. Loss of this bookmark may result in some spam entries being added, but since the web interface is write-only your journal itself remains safe from prying eyes.
It's secured via the very advanced 'secret bookmark' method, which easily enables one to use the interface on your smartphone, no matter the species. Accidental exposure of this bookmark may result in some spam entries being added, but since the web interface is write-only your journal itself remains safe from prying eyes.

There are two notable exceptions to the "write-only" policy in the web server. First, there's the special `@BWV` tag. If you're anything like me, you like keeping track of which music you've played, and in particular, which [BWV numbers](https://en.wikipedia.org/wiki/List_of_compositions_by_Johann_Sebastian_Bach#BWV) you can cross off. `journal-server` exposes a (non-exhaustive) list of BWV numbers, that turn green as they become tagged in your journal.

Second, if you specify a projects directory, the file names in that directory can be selected through a dropdown list. If a project log file is selected, the journal entry is appended to that file in addition to the journal file.

Usage
-----
### `jrnl`
Add entries to the journal, or search for past entries.

Command-line arguments:

* `--journal_file=FILE`: read or write journal entries to or from `FILE`.
* `--search`: search the journal and print matching entries. All other command-line arguments are search terms.
* `--create`: add a new journal entry. This reads input from stdin and adds it to the journal.
* `--date=DATE`: (when adding an entry) use `DATE` for the new journal entry, instead of the current date and time.

### `journal-server`
Start a web server

Command-line arguments:

One notable exception to the "write-only" policy is the special `@BWV` tag. If you're anything like me, you like keeping track of which music you've played, and in particular, which [BWV numbers](https://en.wikipedia.org/wiki/List_of_compositions_by_Johann_Sebastian_Bach#BWV) you can cross off. `journal-server` exposes a (non-exhaustive) list of BWV numbers, that turn green as they become tagged in your journal.
* `--listen=IP:PORT`: listen on port `PORT`, on IP `IP`. Defaults to ':8848'.
* `--journal_file=FILE`: read or write journal entries to or from `FILE`. `FILE` defaults to 'journal.txt' in the current directory.
* `--password_file=FILE`: read passwords from `FILE`. This file should be in the apache htpasswd format, with bcrypt hashes. `FILE` defaults to '.htpasswd' in the current directory.
* `--secret_parameter=URLKEY`: Pass the API key in this URL parameter, making it less obvious to find and brute force. Defaults to 'apikey'
* `--attachments_dir=DIR`: Directory for storing attached files. If this parameter is not specified, attaching uploaded files is disabled.
* `--projects_dir=DIR`: Directory with project log files. If this parameter is not specified, adding entries to a project log is disabled.

Building
--------
First install or update the prerequisites:

```
go get ./...
gem install scss
go get -u github.com/jteeuwen/go-bindata/...
go get -u github.com/gorilla/mux
go get -u github.com/gorilla/context
go get -u golang.org/x/crypto/bcrypt
```

Afterwards, execute `build.sh` to build both binaries.

`journal-server` listens on port 8848 by default, and uses the file `journal.txt` in the current directory for storage. These options can be tweaked using the `--listen` and `--journal-file` flags respectively.
Furthermore, it needs a `.htpasswd` file to verify the bookmarked API key. Use your favorite utility to create it. (Use the bcrypt hash!)
Furthermore, it needs a `.htpasswd` file to verify the bookmarked API key. This file should take the Apache htpasswd format; use any standard utility to create it. (But tell it to use the bcrypt hash.)

If you just want to quickly give it a go, create a file `.htpasswd` with the following contents:

Expand Down
18 changes: 15 additions & 3 deletions bin/journal-server/assets/js/autosave-draft.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const AUTOSAVE_INTERVAL_MS = 2500;
}

const ipt_body = editform.querySelector("textarea");
const ipt_project = editform.querySelector("#ipt-project") || document.createElement("input");
const ipt_draft_id = editform.querySelector("input[type=hidden][name=draft_id]");
if ( !ipt_body || !ipt_draft_id ) {
return;
Expand Down Expand Up @@ -34,13 +35,22 @@ const AUTOSAVE_INTERVAL_MS = 2500;
let pb = new FormData();
pb.set("draft_id", draft_id);
pb.set("body", ipt_body.value);
pb.set("project", ipt_project.value);

document.querySelectorAll("#list-of-attached-files li input[type=checkbox]").forEach((x) => {
if ( x.checked ) {
pb.set(x.name, "on");
}
})

let draft_emptied = (ipt_body.value.trim() === '');
let q = await fetch(draft_url, {method: "POST", body: pb});
q = await q.json();
if ( q.ok == 1 ) {
save_status.innerText = "Draft saved";
save_time.innerText = `Last saved at ${(new Date()).toTimeString().slice(0,5)}`;
draft_id = q.draft_id;
ipt_draft_id.value = draft_id;

if ( draft_emptied ) {
save_status.innerText = "Draft deleted";
Expand All @@ -58,14 +68,16 @@ const AUTOSAVE_INTERVAL_MS = 2500;
};

let current_body = ipt_body.value;
let current_project = ipt_project.value;
window.setInterval(async () => {
if ( ipt_body.value == current_body ) {
if ( ipt_body.value == current_body && ipt_project.value == current_project ) {
return;
}

try {
await save_draft();
current_body = ipt_body.value;
await save_draft();
current_body = ipt_body.value;
current_project = ipt_project.value;
} catch ( e ) {
console.error("automatic save failed")
}
Expand Down
4 changes: 2 additions & 2 deletions bin/journal-server/assets/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ main

.journal-entry
{
input[type=text], textarea, input[type=submit], button {
input[type=text], textarea, input[type=submit], button, select {
width: 100%;
&:focus-visible {
outline: none;
Expand All @@ -61,7 +61,7 @@ main
padding-bottom: 120px;
}

input[type=text], input[type=submit] {
input[type=text], input[type=submit], select {
padding: 10px 20px;
}
}
Expand Down
10 changes: 10 additions & 0 deletions bin/journal-server/assets/templates/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
<input type="hidden" id="ipt-draft-id" name="draft_id" />
<input type="submit" value="Save" />
</p>
{{if .Projects}}
<p>
<select type="text" id="ipt-project" name="project" placeholder="Project">
<option value="">Tag project...</option>
{{range .Projects}}
<option value="{{.}}">{{. | ProjectName}}</option>
{{end}}
</select>
</p>
{{end}}
{{if .CanAttachFiles}}
<ul id="list-of-attached-files"></ul>
<p>
Expand Down
Loading

0 comments on commit cbdac93

Please sign in to comment.