Commit graph

662 commits

Author SHA1 Message Date
Damien Elmes
434fdae4f0 Merge pull request #805 from cecini/duecounts
align rslib get_subnode impl with anki pythonapi find_deck_in_tree
2020-11-06 10:57:49 +10:00
Damien Elmes
aaa950f66c handle notes with invalid utf8 2020-11-06 10:21:51 +10:00
Damien Elmes
e049062147 fix missing buildinfo on Windows 2020-11-05 11:21:27 +10:00
Damien Elmes
f24d80bac5 update to latest fluent libs, and integrate maximum digit handling
We now limit number of digits in our formatter, instead of relying
on an upstream patch.
2020-11-03 14:10:45 +10:00
Damien Elmes
cfbbb69648 trailing newline .ftl check can happen at build time
Removes the need to build ripgrep for CI
2020-11-01 14:59:45 +10:00
Damien Elmes
ce3b08ac58 initial Bazel conversion
Running and testing should be working on the three platforms, but
there's still a fair bit that needs to be done:

- Wheel building + testing in a venv still needs to be implemented.
- Python requirements still need to be compiled with piptool and pinned;
need to compile on all platforms then merge
- Cargo deps in cargo/ and rslib/ need to be cleaned up, and ideally
unified into one place
- Currently using rustls to work around openssl compilation issues
on Linux, but this will break corporate proxies with custom SSL
authorities; need to conditionally use openssl or use
https://github.com/seanmonstar/reqwest/pull/1058
- Makefiles and docs still need cleaning up
- It may make sense to reparent ts/* to the top level, as we don't
nest the other modules under a specific language.
- rspy and pylib must always be updated in lock-step, so merging
rspy into pylib as a private module would simplify things.
- Merging desktop-ftl and mobile-ftl into the core ftl would make
managing and updating translations easier.
- Obsolete scripts need removing.
- And probably more.
2020-11-01 14:26:58 +10:00
cecini
e12c09bd11 align rslib get_subnode impl with anki pythonapi find_deck_in_tree, fix nestdeck due counts issue 2020-10-29 23:53:26 +08:00
Andreas Reis
c77ac81e9d Add audio & object tags to media check
Makes the media check recognize files in <audio> and <object> tags as used.

They've been observed/supported by the WebView (checked: Anki, AnkiDroid) since just about forever already and are extremely useful if one knows a thing about web dev.
2020-10-25 13:09:57 +01:00
abdo
29d17bf608 Ensure non-empty names
https://github.com/ankitects/anki/pull/801/
2020-10-22 16:11:06 +03:00
abdo
69da22a2b9 Strip double quotes from names
Strip double quotes from all kinds of names

https://github.com/ankitects/anki/pull/798
2020-10-21 21:48:49 +03:00
Damien Elmes
791894d2d0 fix new clippy lints 2020-10-09 21:35:53 +10:00
Damien Elmes
d3de0bbaff reindex when checking database
Came across a user with a corrupt index:

sqlite> pragma integrity_check;
 integrity_check = wrong # of entries in index ix_revlog_cid
 integrity_check = wrong # of entries in index ix_cards_sched

This is not picked up by a quick check, and a vacuum does not
fix it, but a reindex does.

AnkiWeb currently performs a full check when a file is uploaded
to it, so this was leading to "corrupt" to show up when syncing
the collection, with a local DB check not reporting/fixing the issue.
2020-10-05 17:40:43 +10:00
Damien Elmes
61bbe6a604 fix * handling in unqualifed text as well
https://forums.ankiweb.net/t/anki-2-1-desktop-searching-with-only-when-limited-to-a-field/3789/4
2020-09-29 21:18:19 +10:00
Damien Elmes
2e7c71b415 fix escaping of * in field search
mentioned in
https://github.com/ankitects/anki/pull/769
2020-09-27 16:04:08 +10:00
Damien Elmes
b39612eb33 rename downgrade method for clarity 2020-09-22 15:53:26 +10:00
Damien Elmes
ea7b8c5e49 update schema to fix default initial ease in deck configs
Closes #766

- changes the on-disk representation from % to a multiplier,
eg 250 -> 2.5, as this is consistent with the other options
- resets deck configs at or below 1.3 to 2.5
- for any cards that were using a reset deck config, reset their
current factor if it's at or below 2.0x. The cutoff is arbitrary,
and just intended to make sure we catch cards the user has rated
Easy on multiple times. The existing due dates are left alone.
2020-09-22 08:16:39 +10:00
Damien Elmes
4d66bafc51 stop is:due gathering learning cards that are not due yet
https://forums.ankiweb.net/t/how-to-avoid-rebuilding-filtered-decks-to-skip-learning-cards-steps/3551/
2020-09-21 11:41:54 +10:00
Damien Elmes
2a5ebad11f fix incorrect SQL in previous change 2020-09-19 12:27:00 +10:00
Damien Elmes
35470fdcf3 congrats_info() failed if learning card had negative due
https://forums.ankiweb.net/t/integralvalueoutofrange-for-filtered-deck/3353
2020-09-18 20:14:35 +10:00
Damien Elmes
717ea6db3d sched_timing_today() needs a default rollover hour
When unset it was reverting to the V1 code.

https://forums.ankiweb.net/t/daily-counts-are-reset-on-sync/3441/16
2020-09-18 19:13:47 +10:00
Damien Elmes
779a8930e7 check original due in card stats
https://forums.ankiweb.net/t/how-come-some-of-my-cards-are-showing-retrospective-due-dates/3434/6
2020-09-17 14:36:18 +10:00
Aleksa Sarai
96da137314 rs: remove most &mut references in BackendService
The previous implementation had some slightly questionable memory safety
properties (older versions of PyO3 didn't uphold the Rust aliasing rules
and would thus create multiple &mut references to #[pyclass] objects).
This explains why Backend has internal Mutex<T>s even though all of its
methods took &mut self.

The solution is to simply make all methods take &self, which luckily
doesn't pose too make issues -- most of the code inside Backend already
has sufficient locking. The only two things which needed to be
explicitly handled where:

1. "self.runtime" which was fairly easy to handle. All usages of
   the Runtime only require an immutable reference to create a new
   Handle, so we could switch to OnceCell which provides
   lazy-initialisation semantics without needing a more heavy-handed
   Mutex<tokio::runtime::Handle>.

2. "self.sync_abort" was simply wrapped in a Mutex<>, though some of the
   odd semantics of sync_abort (not being able to handle multiple
   processes synchronising at the same time) become pretty obvious with
   this change (for now we just log a warning in that case). In
   addition, switch to an RAII-style guard to make sure we don't forget
   to clear the abort_handle.

As a result, we now no longer break Rust's aliasing rules and we can
build with newer versions of PyO3 which have runtime checks for these
things (and build on stable Rust).

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
2020-09-05 19:37:59 +10:00
Damien Elmes
cce0ee2b03 handle quoted html chars in media check
https://forums.ankiweb.net/t/unable-to-play-longer-audio-on-cards/1313/30
2020-09-04 09:36:38 +10:00
Damien Elmes
f32d773e25 set_deck() 2020-09-03 17:42:46 +10:00
Damien Elmes
f7d4bf8489 support did:[deck id] search 2020-09-03 16:43:22 +10:00
Damien Elmes
32759a55e4 log 0 day interval as 1 day
Allows distinguishing it from resetting to new, and is treated as
a one day delay when answering anyway.
2020-09-03 16:00:06 +10:00
Damien Elmes
7c169daa95 move card sorting and resetting to backend 2020-09-03 15:54:15 +10:00
Damien Elmes
72142d51c4 set local offset when saving preferences 2020-09-03 12:43:18 +10:00
Damien Elmes
366c5c4774 log manual reschedule, but ignore the log entry in the stats 2020-09-02 17:56:23 +10:00
Damien Elmes
31b7d7d645 move reschedCards() to backend 2020-09-02 17:56:23 +10:00
Damien Elmes
396081d329 move filtered deck empty/fill to backend
emptying of individual card ids still to be done
2020-09-02 17:56:23 +10:00
Damien Elmes
7f42500e53 rename some card+note fields in backend 2020-09-01 10:24:38 +10:00
Damien Elmes
9f51347e1e move bury/suspend into backend 2020-09-01 10:24:38 +10:00
Damien Elmes
988b3c00c1 move unbury/unsuspend routines into backend 2020-09-01 10:24:38 +10:00
Damien Elmes
4894025cfc add separate sched/user bury searches, and fix bury enums 2020-09-01 10:24:38 +10:00
Damien Elmes
2a6206be91 handle null return from sum() in other columns 2020-09-01 10:24:38 +10:00
Damien Elmes
999b659c3a reimplement congrats screen in Rust+Typescript 2020-09-01 10:24:38 +10:00
Damien Elmes
55ae49e251 fix nonbreaking spaces breaking media
https://forums.ankiweb.net/t/unable-to-play-longer-audio-on-cards/1313
2020-08-30 11:23:12 +10:00
Soren Bjornstad
0614642052 fix unanchored regex in bulk tag add routine
Previously, it was not possible to add a substring of an existing tag.
For example, with the tag "foobar", you could not add the tag "foo",
"bar" or "oob".

Because the match was unanchored, the regex checking whether the tag
already existed determined that the tag was present when it was not.
2020-08-28 16:21:23 -05:00
Damien Elmes
7cfeb6cbb3 check if we need to unbury at the start of the sync process
https://forums.ankiweb.net/t/bug-buried-cards-in-filtered-decks-not-being-unburied-next-day/2541/24
2020-08-28 21:09:07 +10:00
Damien Elmes
b9f6bde2dc catch leading/trailing boolean operators
https://forums.ankiweb.net/t/is-it-only-me-anki-giving-corrupt-collection-error/2424/20
2020-08-27 09:59:29 +10:00
Damien Elmes
41a47fcf01 fix some clippy lints 2020-08-26 19:02:56 +10:00
Damien Elmes
fb4105013f add escape hatch for very slow connections 2020-08-26 18:44:20 +10:00
Damien Elmes
8c7c2eeda3 specify I/O timeout
We need to be a bit conservative here due to buffer bloat - in the
upload case on a slow link, it can appear that no I/O is happening
when a buffer is draining.
2020-08-26 18:30:51 +10:00
Damien Elmes
3b8c7f22d2 don't crash when upgrading collection with ntid of 0 2020-08-23 14:14:44 +10:00
Damien Elmes
8c558e4e5d normalize field before checking duplicates
https://forums.ankiweb.net/t/unicode-normalisation/2531
2020-08-23 12:09:55 +10:00
Damien Elmes
e281d8947d ensure we don't crash on a zero field notetype 2020-08-23 12:09:36 +10:00
Damien Elmes
db92548987 fix empty cards not ignoring <br>
https://forums.ankiweb.net/t/bug-report-empty-cards-are-not-recognized/2555
2020-08-23 11:44:49 +10:00
Damien Elmes
3a2031272b catch timeout error 2020-08-21 19:03:23 +10:00
Damien Elmes
26e69d5070 ensure tag replacements fully match
https://anki.tenderapp.com/discussions/private/5180-anki-desktop-bug-removing-a-tag-removes-all-substrings
2020-08-19 15:35:20 +10:00
Damien Elmes
cb68958b59 strip nuls from tags as well
https://forums.ankiweb.net/t/unable-to-sync-between-macbook-and-my-iphone/2405
2020-08-19 15:34:21 +10:00
Damien Elmes
724005386c catch attempt to update missing note
https://forums.ankiweb.net/t/bug-report-editor-updating-non-existing-card/2117/4?u=dae
2020-08-17 19:44:27 +10:00
Damien Elmes
2e7ecfb1d2 allow setting sort field before add 2020-08-17 19:44:09 +10:00
Damien Elmes
cb821a9e3c fix globs not working in bulk tag add/remove 2020-08-17 18:14:00 +10:00
Damien Elmes
692164df7c journal mode was not being set on media db 2020-08-17 12:30:14 +10:00
Damien Elmes
54bb782809 handle <%foo%> inside {{#conditional}}
https://forums.ankiweb.net/t/the-latest-version-of-ios-cannot-display-the-template-normally/2142
2020-08-12 19:28:26 +10:00
Damien Elmes
d0d2ba15e2 generate extra templates when recovering notetype 2020-08-10 13:42:37 +10:00
Damien Elmes
a4c8825aeb show ordinal if card template missing 2020-08-10 13:41:22 +10:00
Damien Elmes
ffd1638400 fix assertion failure when recovering notetype
Notes need to have their notetype ID updated to reflect the
newly created notetype.

https://forums.ankiweb.net/t/anki-crashes-on-sync-study-export/1978
2020-08-08 12:26:00 +10:00
Damien Elmes
bdf6e2b87d handle negative review times in sync 2020-08-07 15:02:03 +10:00
Damien Elmes
60730af9f4 fix negative review times in DB check 2020-08-07 14:37:44 +10:00
Damien Elmes
c03d3f6c7f add some extra help to the json decode error 2020-08-07 13:13:11 +10:00
Damien Elmes
176ab312da handle some instances of floats when an integer is expected during sync 2020-08-03 17:47:15 +10:00
Damien Elmes
99140fb189 fix conditional negation being lost on field rename
https://forums.ankiweb.net/t/anki-force-changes-all-to/1694
2020-08-02 10:09:24 +10:00
Damien Elmes
bd37a7e17e fix moves into/out of a filtered deck not syncing
the mtime comparison should have only been done if the object in the
local collection was also pending
2020-07-31 15:39:30 +10:00
Damien Elmes
47d3666ad0 fix hour graph not handling timezones west of UTC
https://forums.ankiweb.net/t/statistics-bugs-after-update-2-1-5-to-2-1-29/1620
2020-07-31 13:33:41 +10:00
Damien Elmes
a93145c4c7 handle preview repeat in deck list 2020-07-30 09:11:13 +10:00
Damien Elmes
3da7884e19 reject double comma in id list
https://forums.ankiweb.net/t/anki-2-1-29-and-below-2-small-bugs/1496
2020-07-29 13:05:34 +10:00
Damien Elmes
f4bd143050 handle multiple clozes in cloze-only filter
https://forums.ankiweb.net/t/built-in-tts-not-reading-multiple-clozes/1516
2020-07-29 12:54:29 +10:00
Damien Elmes
55891fc8f7 clearer message when template error is preventing save 2020-07-29 12:53:03 +10:00
Damien Elmes
3099edf8ee show card stats in reverse order like older Anki versions 2020-07-28 09:49:27 +10:00
Damien Elmes
8f470ce23d fix note/card ids being flipped in card stats 2020-07-28 09:49:11 +10:00
Damien Elmes
9ec58c10ec strip unwanted control characters when writing fields
closes #661
2020-07-24 09:18:05 +10:00
Damien Elmes
61f0c3eec0 add cloze-only filter
https://anki.tenderapp.com/discussions/ankidesktop/42383-two-feature-suggestions
2020-07-21 12:59:28 +10:00
Damien Elmes
ce2c553840 i18n some sync errors 2020-07-16 13:55:59 +10:00
Damien Elmes
e471497bd2 add platform version back into sync metadata 2020-07-16 10:12:41 +10:00
Damien Elmes
bbc75cdf5d update rslib/rspy deps 2020-07-12 11:38:25 +10:00
Damien Elmes
d35bc85ead is:review should include relearning cards
https://forums.ankiweb.net/t/anki-2-1-28-beta/629/36

This issue appears to have existed since the V2 scheduler was
introduced - the old Python search code was ignoring Relearn as well.
2020-07-09 11:07:50 +10:00
Damien Elmes
3a75161778 fix deck tree with a day delta, and support arbitrary timestamps 2020-07-06 19:16:03 +10:00
Damien Elmes
71dbbd9fa8 set schema on collection creation 2020-07-03 11:55:27 +10:00
Damien Elmes
9bb45673a8 show clearer error when media db locked
should not happen frequently during a sync, but may happen during
the initial change checking stage

https://forums.ankiweb.net/t/error-when-adding-audio-file/495/2
2020-07-01 11:19:06 +10:00
Damien Elmes
f43aa54ed9 fix media db conflict aborting immediately instead of after 5s
https://forums.ankiweb.net/t/error-when-adding-audio-file/495/2
2020-07-01 11:17:33 +10:00
Damien Elmes
8cfafdbc32 supported edited:n
https://forums.ankiweb.net/t/feature-request-advanced-broswer-search-by-edited/268
2020-07-01 10:17:57 +10:00
Damien Elmes
06d9f64dea lint fixes 2020-06-29 15:53:56 +10:00
Damien Elmes
693fcfce7d i18n card counts 2020-06-29 15:48:01 +10:00
Damien Elmes
349eca843b get i18n working in typescript 2020-06-29 15:48:01 +10:00
Damien Elmes
618fc65282 handle revlog entries with negative review times 2020-06-29 15:48:01 +10:00
Damien Elmes
4be8e7923a fix partially quoted text not handling escaped quotes
https://forums.ankiweb.net/t/how-to-search-for-cards-containing-quotes/500/10
2020-06-29 15:48:01 +10:00
Damien Elmes
0293f2220c qt's js code now shares ts/node_modules; more graph work 2020-06-29 15:48:01 +10:00
Damien Elmes
4d88b6521d cards added graph 2020-06-29 15:48:01 +10:00
Damien Elmes
1e9901e9bd experiment with exposing raw card/revlog data to frontend 2020-06-29 15:48:00 +10:00
Damien Elmes
fd258d15c5 some initial work on updating the graphs 2020-06-29 15:48:00 +10:00
Damien Elmes
61efce295e fix v2 scheduler cutoff being used if previously activated 2020-06-23 12:46:40 +09:00
Damien Elmes
710e5ecce2 formatting fix 2020-06-22 11:58:31 +10:00
Damien Elmes
cec1fdece5 move revlog out of sync code, and add enums
and remove type=4, which does not appear to be used
2020-06-16 16:31:36 +10:00
Damien Elmes
f5694a7e4a migrate card stats to backend
Currently this renders the HTML directly like the previous Python
implementation - doing it in JS would probably make more sense in the
future.
2020-06-15 17:22:16 +10:00
Damien Elmes
965fd848d1 on upgrade, mark decks modified that are renamed 2020-06-14 14:48:58 +10:00
Damien Elmes
07874f8328 handle db errors the same way as other backend requests 2020-06-12 20:39:02 +10:00
Damien Elmes
dc8297644b pass db json back as bytes 2020-06-12 20:20:29 +10:00
Damien Elmes
1773c6eec9 don't exclude the default deck from the normal name list
https://forums.ankiweb.net/t/issue-backend-get-deck-names-doesnt-return-default-deck/52
2020-06-11 14:36:00 +10:00
Damien Elmes
4092da9dbe use vendored hyper for panic fix 2020-06-11 13:30:35 +10:00
Damien Elmes
d5cd9af53b fix review cards with high intervals not being reset properly
would lead to a "fixed .. with invalid card property" message that
didn't go away
2020-06-09 20:11:26 +10:00
Damien Elmes
a11d803030 switch default leech action to tag only 2020-06-09 12:03:47 +10:00
Damien Elmes
6d7be475e6 catch invalid regex in search
https://github.com/ankitects/anki/pull/652
2020-06-09 11:46:07 +10:00
Damien Elmes
c6e5dc0ef6 check full upload return text 2020-06-09 08:50:16 +10:00
Damien Elmes
75471224fa add progress to db check 2020-06-08 21:07:36 +10:00
Damien Elmes
e74e5c604b add daily count updating to backend 2020-06-05 19:49:53 +10:00
Damien Elmes
55f8b87548 support generating a due tree for a different date 2020-06-05 09:38:31 +10:00
Damien Elmes
c5e65d02e1 add note/card removal to backend 2020-06-04 18:21:04 +10:00
Damien Elmes
cb7d78dde5 "Template" special field should have been called "Card" 2020-06-02 16:47:30 +10:00
Damien Elmes
c8b585b3e4 automatically abort the media sync on full sync 2020-06-02 16:22:53 +10:00
Damien Elmes
7dc8df748b ensure sync indicator updates after download 2020-06-02 15:10:41 +10:00
Damien Elmes
7536a3b899 fix full download on Windows 2020-06-02 15:06:23 +10:00
Damien Elmes
ca704187c6 skip note update if unchanged 2020-06-02 13:32:36 +10:00
Damien Elmes
d7a2e78c0b change sync label to indicate sync state
- blue for normal sync, red for full sync required
- refactor status fetching code so we don't hold a collection lock
during the network request, which slows things down
- fix sync spinner restarting when returning to deck list
2020-06-02 13:23:01 +10:00
Damien Elmes
42c34b60c0 use a shared async runtime instead of recreating each time 2020-06-02 09:35:27 +10:00
Damien Elmes
a3e5068952 add some syncing tests - please see alpha2 notes before syncing 2020-06-01 19:44:25 +10:00
Damien Elmes
c6712cbf2c fix \n in buildhash 2020-06-01 19:38:45 +10:00
Damien Elmes
80210ab6bd handle missing counts in sanity check 2020-06-01 19:38:41 +10:00
Damien Elmes
300769aac7 if both sides empty, allow either 2020-06-01 18:11:43 +10:00
Damien Elmes
2ca3108bee don't put dyn=False in schema11 dconf's "other" 2020-06-01 18:11:40 +10:00
Damien Elmes
da2dc7bd8c tell AnkiWeb to abort on interrupt 2020-06-01 13:57:10 +10:00
Damien Elmes
ad3082d1c8 handle aborting normal sync
- Use a separate abort handle, as the media sync is running
in the background and we need to be able to target them separately.
The current progress handling is going to need a rethink if we introduce
any other background tasks in the future.
- Roll back the transaction when interrupting.
2020-06-01 13:57:10 +10:00
Damien Elmes
da1e0527ca report normal sync progress
Also:
- provide a way for the progress handler to skip the throttling so that
we can ensure progress is updated at the end of a stage
- show 'checking' at the end of full sync
2020-06-01 13:57:10 +10:00
Damien Elmes
1c52d11133 rework usn handling in sync 2020-06-01 13:57:10 +10:00
Damien Elmes
1303013ad6 add due counts to sanity check 2020-06-01 13:57:10 +10:00
Damien Elmes
0787381a99 login/full up/full down plugged in 2020-06-01 13:57:10 +10:00
Damien Elmes
aaed0464e5 rework progress handling
- client now polls status instead of backend pushing it
- supports multiple threads
- update throttling happens in one place
2020-06-01 13:57:10 +10:00
Damien Elmes
c4032c0176 another snapshot of sync work
progress handler is going to need to be reworked to function across
threads
2020-06-01 13:57:10 +10:00
Damien Elmes
b5284e8993 make sure we invalidate cache after direct update 2020-06-01 13:57:10 +10:00
Damien Elmes
2114fdf6f5 more syncing work
no checks yet
2020-06-01 13:57:10 +10:00
Damien Elmes
4d1e8d678d full upload/download HTTP code 2020-06-01 13:57:10 +10:00
Damien Elmes
f17dec9f2a start on HTTP client for syncing 2020-06-01 13:57:10 +10:00
Damien Elmes
91e3256e6a move dupe check to backend 2020-05-24 19:48:56 +10:00
Damien Elmes
e9fea26d1c use keyword args for calls with more than one argument 2020-05-24 09:12:47 +10:00
Damien Elmes
bbcc566e6d migrate the remaining methods 2020-05-24 08:36:50 +10:00
Damien Elmes
93f18c14d4 migrate more scheduling/media/etc
almost there
2020-05-23 21:34:19 +10:00
Damien Elmes
8b93a0c19d migrate notetypes, update GIL list 2020-05-23 20:43:55 +10:00
Damien Elmes
35489d5fa7 add some more newtypes to the RPC defs 2020-05-23 16:58:01 +10:00
Damien Elmes
8df2ab65fb migrate cards and notes 2020-05-23 16:19:48 +10:00
Damien Elmes
32a071cf79 migrate decks and dconf methods 2020-05-23 15:09:16 +10:00
Damien Elmes
927ed25b02 more methods 2020-05-23 14:01:36 +10:00
Damien Elmes
d57ded706f migrate more methods to service 2020-05-22 22:09:33 +10:00
Damien Elmes
36024ed086 start reworking protobuf handling
Will allow us to cut down on boilerplate by automatically generating
code from RPC service definitions
2020-05-22 20:56:15 +10:00
Damien Elmes
3f8a3afb78 fix extending limits in custom study
https://anki.tenderapp.com/discussions/beta-testing/1967-2126-189-g7384df8f-crash-at-note-types-fields-save
2020-05-20 14:13:40 +10:00
Damien Elmes
c78e8425aa automatically omit notes or cards table when possible 2020-05-19 11:27:02 +10:00
Damien Elmes
5e1583df59 fix unit test bug triggered by low resolution win32 timer
We don't yet have a remove_note(), so just remove all cards for now.
2020-05-18 19:02:54 +10:00
Damien Elmes
facbe53649 fix cutoff adjustment test in other timezones 2020-05-18 14:08:02 +10:00
Damien Elmes
01ebe964e9 bytes->blob in sql 2020-05-18 13:36:45 +10:00
Damien Elmes
4438be2c8d protobuf tidyups 2020-05-18 09:26:14 +10:00