Vino
🍷It’s your cellar, your dear cantina 🍷
vino
is an Emacs program for cellar tracking and wine rating. Every entity is stored as separate Org file, vino
provides convenient functions to query and manipulate these files.
Please note, that vino
does not ship with collection of Org file for wines, producers, grapes, appellations or wine regions. The idea is that each user creates their own collection and learns about huge world of wine in the process.
Checkout barberry.io as a showcase of what can be built on top of vino
together with vulpea
.
Goals
- Provide functionality to create wine entries and to rate them.
- Provide functionality to track availability of wine entries.
- Provide functionality to evolve rating system.
- Provide functionality for maintenance.
- Provide functionality to query wine entries based on different predicates.
- Be able to handle big (1000+) collection of wine entries.
Status and roadmap
This project started as a rewrite of +org-wine.el from org-brain to org-roam (of course, using vulpea) in performance pursuit (it become critical as I have 1k+ of wine entries and around 2k of grape, producers, appellations, regions notes).
- [X] v0.1 - feature parity with +org-wine.el.
- [X] v0.2 - dedicated database for
vino
needs. - [X] v0.3 - migration to
org-roam
V2. - [ ] v0.4 - migration to Vulpea database extension capabilities.
- [ ] v0.5 - querying and viewing.
- [ ] v0.6 - inventory solutions (built-in and external like lib-inventory.el).
Migration to v0.4
As part of vino#121, vino
stopped maintaining its own database and instead started to use Vulpea database extension mechanism that basically allows to extend Org Roam database. So all your vino
data is now stored inside org-orma-db-location
. This is a change that breaks API by removing some variables and functions.
The decision to use Vulpea database extension capabilities is dictated by desire to (a) reduce parsing duplication, (b) to align database lifecycle with vulpea and Org Roam, (c) to reduce code and (d) to get all Vulpea goodies related to database out of box (more to come).
Removed public variables
vino-db-location
, useorg-roam-db-location
instead.vino-db-gc-threshold
, useorg-roam-db-gc-threshold
instead.
Removed public functions
vino-db-sync
, useorg-roam-db-sync
instead.
Anything else?
If you encounter troubles migrating to v0.4
, feel free to open an issue.
Getting started
Installing
vino
is not available via MELPA, so you can install it manually, using straight, quelpa, or any other tool. Once installed, you need to call vino-setup
once.
Keep in mind that vino
depends on vulpea.
straight.el
(straight-use-package vulpea)
(vulpea-setup)
(straight-use-package
'(vino :type git :host github :repo "d12frosted/vino"))
(vino-setup)
;; optionally sync the database
(org-roam-db-sync)
In case you have integration with use-package:
(use-package vino
:straight (vino
:type git
:host github
:repo "d12frosted/vino")
:hook
(after-init . vino-setup)
:config
;; optionally sync the database when vino is loaded
(org-roam-db-sync))
Configuration
There are several things that you must configure before using vino
:
org-roam-directory
- this is where yourvino
files will be located. See Notes structure for more information on how to structure this directory.vino-rating-props
- this variable describes your rating system. See Configure rating system for more information on how to setup this variable.vino-availability-fn
- function to check availability ofvino-entry
. It is called withID
ofvino-entry
and must return a cons of acquired and consumed numbers, e.g.(const 10 4)
means that this particular wine was acquired 10 times and consumed 4 times, making 6 available.vino-availability-add-fn
- function to add certain amount ofvino-entry
to your cellar. Function is called withID
ofvino-entry
, amount, source and date arguments.vino-availability-sub-fn
- function to subtract certain amount ofvino-entry
from your cellar. Function is called withID
ofvino-entry
, amount, action and date arguments.vino-sources-fn
- function to list wine sources. Used in, for example, completion of sources when you acquire a wine. Function is called withID
ofvino-entry
.
Optionally you can configure the following variables:
vino-carbonation-types
- list of carbonation types, e.g.still
andsparkling
. Modify it in case you want to be more granular, e.g.traditional-sparkling
,pet-nat
, etc.vino-colour-types
- list of wine colours, e.g.red
,white
androse
. You might want to addorange
unless you are marking them aswhite
.vino-sweetness-levels
- a property list where key is carbonation type and value is list of sweetness levels (e.g.dry
,sweet
, etc).vino-rating-template
- template for a new wine ratings. See template configuration section for more information.vino-rating-extra-meta
- a list of additional meta to be queried when rating a wine. See it’s documentation for more information.vino-entry-template
- template a for new wine entry. See template configuration section for more information.vino-grape-template
- template for a new grape note. Useful when selecting a grape for wine entry that does not exist or when callingvino-grape-create
. See template configuration section for more information.vino-producer-template
- template for a new producer note. Used byvino-producer-create
. See template configuration section for more information.vino-region-template
- template for a new region note. Used byvino-region-create
. See template configuration section for more information.vino-appellation-template
- template for a new appellation note. Used byvino-appellation-create
. See template configuration section for more information.
Example configuration
Mandatory values (uses functions from +inventory.el).
(setq
org-roam-directory (concat (getenv "HOME")
"/org-roam/")
vino-rating-props '((1 . (("SCORE" . 3)))
(2 . (("AROMA_QUALITY" . 3)
("AROMA_INTENSITY" . 2)
("AROMA_COMPLEXITY" . 3)
("BALANCE" . 3)
("FLAVOURS" . 2)
("AFTERTASTE" . 3)
("GENERAL" . 4))))
vino-availability-fn
(lambda (id)
(cons
(inventory-total-in wine-inventory-file id)
(inventory-total-out wine-inventory-file id)))
vino-availability-add-fn
(lambda (id amount source date)
(inventory-add wine-inventory-file id amount source date))
vino-availability-sub-fn
(lambda (id amount action date)
(inventory-sub wine-inventory-file id amount action date))
vino-sources-fn
(lambda (_)
(inventory-sources wine-inventory-file)))
Optional variables (with their default values):
(setq
vino-carbonation-types '(still
sparkling)
vino-colour-types '(red
white
rose)
vino-sweetness-levels (list 'still '(dry
semi-dry
semi-sweet
sweet)
'sparkling '(brut-nature
extra-brut
brut
extra-dry
dry
demi-sec
doux))
vino-rating-extra-meta (list
(list
:name "location"
:read-fn (lambda ()
(vulpea-select "Location"))
:mode 'single
:type 'note)
(list
:name "convive"
:read-fn (lambda ()
(vulpea-select
"Convive"
:filter-fn (lambda (note)
(seq-contains-p
(vulpea-note-tags note)
"people"))))
:mode 'multiple
:type 'note))
vino-rating-template (list :file-name "wine/rating/${id}.org")
vino-entry-template (list :file-name "wine/cellar/${id}.org")
vino-grape-template (list :file-name "wine/grape/%<%Y%m%d%H%M%S>-${slug}.org")
vino-producer-template (list :file-name "wine/producer/%<%Y%m%d%H%M%S>-${slug}.org")
vino-region-template (list :file-name "wine/region/%<%Y%m%d%H%M%S>-${slug}.org")
vino-appellation-template (list :file-name "wine/appellation/%<%Y%m%d%H%M%S>-${slug}.org"))
Interactive functions
vino-entry-create
- create a newvino-entry
according tovino-entry-template
. It interactively reads carbonation type, colour type, sweetness level, producer, name, vintage, appellation or region, grapes, alcohol level, sugar, resources and price. Producer, appellation, region and grapes are linked usingorg-roam
.vino-entry-find-file
- select and visitvino-entry
.vino-entry-update
- update visiting (or selected)vino-entry
. It refreshesrating
andavailability
(usingvino-availability-fn
). You rarely need to use this function, unless availability or rating is modified manually.vino-entry-update-title
- update visiting (or selected)vino-entry
title. It also changes the title of all linkedratings
. You only need this function if you modify a producer name, wine entry name or vintage manually and want to update everything. Might take a while, depending on amount of linkedratings
.vino-entry-set-grapes
- set grapes of visiting (or selected)vino-entry
by replacing existing.vino-entry-set-region
- set region (or appellation) of visiting (or selected)vino-entry
by replacing existing.vino-entry-acquire
- acquire visiting (or selected)vino-entry
. Reads a source, amount, price and date, and callsvino-availability-add-fn
.vino-entry-consume
- consume visiting (or selected)vino-entry
. Reads a action, amount and date, and callsvino-availability-sub-fn
. For convenience also asks you to rate entry if the action isconsume
.vino-entry-rate
- rate a visiting (or selected)vino-entry
. Reads a date, props defined byvino-rating-props
, creates a new rating note according tovino-rating-template
and creates a link between wine and rating.vino-grape-create
- create a newgrape
note according tovino-grape-template
.vino-grape-find-file
- select and visitgrape
note.vino-producer-create
- create a newproducer
note according tovino-producer-template
.vino-producer-find-file
- select and visitproducer
note.vino-region-create
- create a newregion
note according tovino-region-template
.vino-appellation-create
- create a newappellation
note according tovino-appellation-template
.vino-region-find-file
- select and visitregion
orappellation
note.
Notes structure
vino
assumes the following structure of your org-roam-directory
:
. └── wine ├── appellation │ ├── cerasuolo_di_vittoria_docg.org │ ├── etna_doc.org │ ├── igp_terre_siciliane.org │ └── ... ├── cellar │ ├── 2c012cee-878b-4199-9d3b-782d671bd198.org │ ├── 4faf700f-c8b9-403d-977c-8dee9e577514.org │ ├── b20373db-43d3-4f2c-992c-6c6b5a4f3960.org │ ├── c9937e3e-c83d-4d8d-a612-6110e6706252.org │ └── ... ├── grape │ ├── frappato.org │ ├── nerello_mascalese.org │ ├── nero_d_avola.org │ └── ... ├── producer │ ├── arianna_occhipinti.org │ ├── pyramid_valley.org │ └── ... ├── rating │ ├── be7777a9-7993-44cf-be9e-0ae65297a35d.org │ ├── bbc0c0f6-6f85-41a8-a386-f2017ceeaeb3.org │ ├── 727d03f3-828a-4957-aaa9-a19fd0438a15.org │ ├── d9e29c8e-06af-41d3-a573-72942cea64da.org │ ├── a5022e95-4584-43bd-ac55-599a942a6933.org │ └── ... └── region ├── central_otago.org ├── gisborne.org ├── kumeu.org └── ...
It’s totally fine to have other notes in your org-roam-directory
and even in wine
folder. Storing vino
files in dedicated directories is not mandatory, it just better organises notes.
Appellation/region
Each file represents either an appellation (like Cerasuolo di Vittoria DOCG or Morgon AOC) or a wine region (like Central Otago in New Zealand or Codru in Moldova). There are no restrictions on these files, except for presence of appellation
or region
tag in addition to wine
tag. See Tags section for more information.
$ cat wine/region/20201214120801-codru.org :PROPERTIES: :ID: b5758d14-61a2-4255-a47d-3cff3b58b321 :END: #+title: Codru #+filetags: wine region - country :: [[id:6ce0bd2d-9018-4c5f-b896-639a85a6e7a4][Moldova]] Codru wine region is located in the central area of [[id:6ce0bd2d-9018-4c5f-b896-639a85a6e7a4][Moldova]]. More than 60% of vineyards are located in this region. Two biggest cellars in the world ([[id:2374143f-5b7e-46ae-9ffc-649f529aaf70][Mileștii Mici]] and [[id:849a36b0-b24b-49e6-9e5d-19fc7ee13a78][Cricova]]) are located here.
Producer
Each file represents a producer (like Occhipinti or Vino di Anna). There are no restrictions on these files, except for presence of producer
tag in addition to wine
tag. See Tags section for more information.
$ cat wine/producer/20200511140611-arianna_occhipinti.org :PROPERTIES: :ID: 8f62b3bd-2a36-4227-a0d3-4107cd8dac19 :END: #+title: Arianna Occhipinti #+filetahs: wine producer @AriannaOcchipinti - resources :: [[https://www.bowlerwine.com/producer/occhipinti][bowlerwine.com]] Arianna Occhipinti is a winemaker from [[id:3717adb1-4815-4ba6-9730-a884554214c9][Vittoria]] who founded her own winery in 2004, bottled her first commercial vintage in 2006 and today works exclusively with estate fruit. Her 25 hectares feature only autochthonous varieties - 50% [[id:b968250e-2035-4b18-bd9f-fce99d5f9915][Frappato]], 35% [[id:c9731b65-61f8-4007-9dbf-d54056f55cc4][Nero d'Avola]] and 15% white varieties [[id:63532852-c67a-4b8d-ac42-1ae9be28610e][Albanello]] and [[id:ab59e210-e7ed-4362-832c-4c4daa2b9e05][Zibibbo]]. Almost all vines are young as she planted them, most of them a guyot-trained. But she also added to her holdings 60-years-old albarello-trained vines which she initially rented. ...
Grape
Each file represents a producer (like Occhipinti or Vino di Anna). There are no restrictions on these files, except for presence of producer
tag in addition to wine
tag. See Tags section for more information.
$ cat wine/grape/20200406154953-nerello_mascalese.org :PROPERTIES: :ID: 9c1a5bec-9390-429e-bea9-4f1cce05f79c :END: #+title: Nerello Mascalese #+filetags: wine grape - resources :: [[https://winefolly.com/grapes/nerello-mascalese/][Winefolly]] - resources :: [[https://italianwinecentral.com/variety/nerello-mascalese/][italianwinecentral.com]] A rare red Sicilian grape producing fine light to medium-bodied red wines reminiscent of Pinot Noir. The best examples are found growing on the volcanic soils of Mount Etna. Primary flavours: - Dried [[id:7a945d62-b5f0-4542-bb1a-f4c8f9dd736b][Cherry]] - Orange [[id:8403a37b-be67-4efc-92f1-377aea0c8c50][Zest]] - Dried [[id:83a86596-437f-4931-a147-af1bd7734d28][Thyme]] - [[id:76cef2c9-0fc7-4802-8873-1c78a6be21da][Allspice]] - Crushed [[id:3b843816-3c5b-4758-89f6-804596087881][Gravel]] Taste profile: - sweetness: bone-dry - body: medium-light - tannins: medium - acidity: medium-high - alcohol: 11.5-13.5% ABV Handling - serve: 12-15°C - glass type: [[id:a88ce31d-bfb0-4343-9359-c4a366ad6a6b][Aroma Collector Glass]] - decant: 30 minutes - cellar: 10+ years
Vino entry
Each file represents a wine, specified by producer, name and vintage. Obviously, you don’t need to create separate files for two bottles of La Stoppa Ageno 2015, but you definitely need separate note from La Stoppa Ageno 2017 (vintage is different).
It’s best if you create a vino entry using vino-entry-create
interactive function. It reads all required information, creates new file (uses ID
as file name), fills it will provided information and links producer, grapes, appellation and region.
Vino entry is defined as a cl-struct
:
(cl-defstruct vino-entry
carbonation
colour
sweetness
producer
name
vintage
appellation
region
grapes
alcohol
sugar
resources
price
acquired
consumed
rating
ratings)
Most of the fields are mandatory, except for:
vintage
- unless specified, printed asNV
string;sugar
- unless specified, printed asNA
string;rating
- unlessratings
list is non-nil, printed asNA
string;ratings
- unless empty, omitted from the file.
Title if the file is set automatically upon creation and can be updated using vino-entry-update-title
if you modify something manually. This also updates the title of linked rating files.
Availability is modified using vino-entry-acquire
and vino-entry-consume
. In case you edited availability manually outside, use vino-entry-update
to sync it.
Rating is updated automatically upon using vino-entry-rate
and can be updated using vino-entry-update
if you modify any rating note manually.
Vino entry files require the presence of cellar
tag in addition to wine
tag. See Tags section for more information.
$ cat wine/cellar/c9937e3e-c83d-4d8d-a612-6110e6706252.org :PROPERTIES: :ID: c9937e3e-c83d-4d8d-a612-6110e6706252 :END: #+title: Arianna Occhipinti Bombolieri BB 2017 #+filetags: wine cellar - carbonation :: still - colour :: red - sweetness :: dry - producer :: [[id:8f62b3bd-2a36-4227-a0d3-4107cd8dac19][Arianna Occhipinti]] - name :: Bombolieri BB - vintage :: 2017 - appellation :: [[id:8353e2fc-8034-4540-8254-4b63fb5a421a][IGP Terre Siciliane]] - grapes :: [[id:cb1eb3b9-6233-4916-8c05-a3a4739e0cfa][Frappato]] - alcohol :: 13 - sugar :: 1 - price :: 50.00 EUR - acquired :: 2 - consumed :: 1 - available :: 1 - resources :: [[http://www.agricolaocchipinti.it/it/vinicontrada][agricolaocchipinti.it]] - rating :: NA #+begin_quote Il Frappato stems from a dream which I had when I was a girl to make a wine that knows the land that I work, the air I breath, and my own thoughts. It is bitter, bloody and elegant. That is Vittoria and the Iblei Mountains. It is the wine that most resembles me, brave, original and rebellious. But not only. It has peasant origins, for this it loves its roots and the past that it brings in; but, at the same time, it is able to fight to improve itself. It knows refinement without forgetting itself. Arianna Occhipinti #+end_quote
Vino rating
Each file represents a rating or a tasting note, specified by vino entry and tasting date. You should create a new rating using vino-entry-rate
. It reads rating values according to vino-rating-props
, creates a file (with ID
as file name) and fills it will provided information. Then it links newly created rating from vino entry and updates the latter.
Rating files require the presence of rating
tag in addition to wine
tag. See
Tags section for more information.
$ cat wine/rating/f1ecb856-c009-4a65-a8d0-8191a9de66dd.org :PROPERTIES: :ID: f1ecb856-c009-4a65-a8d0-8191a9de66dd :END: #+title: Arianna Occhipinti Bombolieri BB 2017 - 2021-01-15 #+filetags: wine rating - wine :: [[id:c9937e3e-c83d-4d8d-a612-6110e6706252][Arianna Occhipinti Bombolieri BB 2017]] - date :: 2021-01-15 - version :: 1 - score :: 14 - score_max :: 20 - total :: 7.0
Tags
Each vino file must contain a wine
tag in addition to type tag (appellation
, region
, producer
, grape
, cellar
or rating
), meaning that each file must contain a respective #+filetags
property:
:PROPERTIES: :ID: 1f4e920e-bfd4-4624-8445-fa8480962c17 :END: #+title: La Stoppa Ageno 2015 #+filetags: wine cellar ...
Files are tagged automatically by vino
when entities are being created. You can not change that. But since tags in #+filetags
property are subject to inheritance, you should add vino
tags to org-tags-exclude-from-inheritance
(which is done for you in vino-setup
) or disable inheritance completely by setting org-use-tag-inheritance
to nil.
Database
vino
extends Org Roam database with tables that can be used for fast querying of information. Right now there are no interactive uses for this database, they are planned in v0.6 and v0.5. But you already can build something on your own.
Available tables (see vulpea-db--tables
for full specification):
cellar
- containsvino-entry
(see Vino entry) with some technical metadata (id
,file
andhash
);ratings
- containsvino-rating
(see Vino rating) with some technical metadata (id
,file
andhash
).
In order to build database you need to manually call org-roam-db-sync
(either from your init.el
file after vino-setup
or interactively).
If you properly installed vino
(e.g. called vino-setup
), then every time you modify and save a file, database will be automatically updated.
In order to query information from database you might use org-roam-db-query
:
;; query top rated wines with rating >= 9
(org-roam-db-query
[:select [producer name vintage rating]
:from cellar
:where (>= rating 9)
:order-by rating :desc])
How to …
Configure templates
All the notes created by vino
are created using vulpea-create
function according to the configurable templates:
vino-grape-template
vino-producer-template
vino-region-template
vino-appellation-template
vino-entry-template
vino-rating-template
Each template is a property list accepting following values:
:file-name
(mandatory) - file name relative toorg-roam-directory
;:head
(optional) - extra header of the created note;:body
(optional) - body of the created note;:tags
(optional) - extra tags for the created note;:properties
(optional) - extra properties to put intoPROPERTIES
block;:context
(optional) - extra variables for:file-name
,:head
,:body
templates.
The template is transformed into vulpea-create
call by:
- providing title (usually read interactively);
- providing
file-name
from template; - providing tags according to entity being created;
- providing
head
,body
,properties
andcontext
from template; - setting
:unnarrowed
and:immediate-finish
both tot
.
Configure rating system
Rating is configured by vino-rating-prop
. My experience shows that rating system evolves over time. You start with something simple (like a capped number), then little by little you start to make your rating system more complex, until one day it’s too complex and you return to something simpler :D
So vino-rating-prop
is a list of all your rating systems, starting with the first version up to your current. This variable has the following format:
'((1 . PROPS)
(2 . PROPS)
(3 . PROPS)
...)
And PROPS
defines a specific version of rating system:
(("PROP_1" . PROP)
("PROP_2" . PROP)
("PROP_3" . PROP)
...)
Each PROP
can be of one of the following types:
number
- then the property value is a number inclusively between0
andPROP
, user is prompted for a number usingread-number
duringvino-entry-rate
;list
- then the property value is a number inclusively between0
and the length ofPROP
, user is prompted to select one element from the listcar
’s usingcompleting-read
duringvino-entry-rate
and thecdr
of selected element is used as value;function
- then the property value is a number between0
andcdr
ofPROP
result, function is called with without arguments duringvino-entry-rate
andcar
of the result is used as value.
Final score is calculated as sum of the values divided by sum of max values and multiplied by 10. So the final rating is a floating number from 0
to 10
.
Here are several examples to illustrate.
- Simple rating system that allows user to assign a single number from
0
to3
which is stored asSCORE
.(setq vino-rating-props '((1 . (("SCORE" . 3)))))
- Another simple rating system that uses multiple properties.
(setq vino-rating-props '((2 . (("AROMA_QUALITY" . 3) ("AROMA_INTENSITY" . 2) ("AROMA_COMPLEXITY" . 3) ("BALANCE" . 3) ("FLAVOURS" . 2) ("AFTERTASTE" . 3) ("GENERAL" . 4)))))
- A complex use cases that uses a function for
AROMA_QUALITY
(so default value is 3, but if wine has any taints, the value is decreased) and lists for everything else.(setq vino-rating-props '((3 . (("AROMA_QUALITY" . (lambda () (let* ((total 3) (res total) (ans t) (quit-on "no taints") (opts (list quit-on "aggressive ethanol" "massive brett attack" "VA, especially nail polish removal"))) (while ans (setq ans (completing-read "Any taints? " opts)) (setq opts (delete ans opts)) (if (string-equal ans "no taints") (setq ans nil) (setq res (max 0 (- res 1)))) (when (equal res 0) (setq ans nil))) (cons res total)))) ("AROMA_INTENSITY" . (("aroma can be perceived without putting nose into glass" . 2) ("aroma can be perceived only by putting nose into glass" . 1) ("closed, you need to put a lot of effort to get the aroma" . 0))) ("AROMA_RICHNESS" . (("more than 3 different notes" . 3) ("only 3 notes" . 2) ("only 2 notes" . 1) ("only 1 note" . 0))) ("AROMA_COMPLEXITY" . (("sophisticated, multilayered" . 1) ("simple" . 0))) ("BALANCE" . (("perfectly balanced, everything is in its place" . 3) ("well balanced, might be a small issue" . 2) ("average, either one bigger issue or two small" . 1) ("unbalanced, everything else" . 0))) ("FLAVOURS" . (("multiple flavours" . 1) ("only one flavour" . 0))) ("EVOLUTION" . (("taste and flavours evolve over time in mouth" . 1) ("plain, straightforward" . 0))) ("AFTERTASTE" . (("long, lasting more than 30 seconds" . 2) ("average, lasting more than 10 seconds" . 1) ("short" . 0))) ("GENERAL" . (("life changing" . 4) ("great wine, I will definitely look into tasting it once more" . 3) ("good wine, will drink it again with pleasure if situation arises" . 2) ("average wine, only with parents" . 1) ("bad wine, only for enemies" . 0)))))))
Store images and other attachments
vino
operates with org-mode
files, meaning that you can use org-attach
to store images as well as other attachments. Refer to Org mode documentation for more information.
Query additional metadata when creating a new wine entry
See vino#65.
Query additional metadata when rating a wine entry
See vino#64.
Coding
vino
is developed using eldev. If you are using flycheck
, it is advised to also use flycheck-eldev, as it makes dependencies and project files available thus mitigating false negative results from default Emacs Lisp checker.
Building and testing
vino
tests are written using buttercup testing framework. And eldev is used to run them both locally and on CI. In order to run the tests locally, first install eldev
and then run:
$ make test
Please note, that the linter is used in this project, so you might want to run it as well:
$ make lint
FAQ
Why not generalise?
My experience shows that some parts of the code base can be shared for tracking other things, like tea (I have a decent collection of tea, that I also track and rate) and books. And I am sure there are many more uses cases.
But since most of the time I write about wine, I want to focus solely on this topic and avoid making perfect an enemy of good.
That being said, please contact me if you wish to use it for other things, I would love to hear your use case and help you with building solution for you.
Why not Cellar Tracker, Vivino, etc.?
Frankly speaking, I don’t trust them to be my source of truth. In my sense both services have the following drawbacks:
- Data is not owned by you.
- No API to get your information.
- There is no way to modify invalid data.
- Requires internet connection.
- Not helpful for learning - every piece of information is already there.
- Hard limit on amount of information you can put there.
- Not extensible.
vino
is about learning about wine, owning your data and extending your tools. With the power of org-roam
you can do everything :)
That being said, I still use Vivino for:
- Reading tasting notes of peoples whose opinion I respect. This also helps me to find new interesting bottles available in my location.
- Sharing some of my notes. This stimulates me to work on short and concise tasting notes.
So you can use both!
Acknowledgements
Logo was created by Iryna Rutylo.