From be6284360851a33f429099276c91931614bb8fd8 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 20 Apr 2018 10:02:03 +0200 Subject: [PATCH 01/10] Fix description --- bin/core/imag-mv/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/core/imag-mv/Cargo.toml b/bin/core/imag-mv/Cargo.toml index 41f4a1a3..bdb22309 100644 --- a/bin/core/imag-mv/Cargo.toml +++ b/bin/core/imag-mv/Cargo.toml @@ -3,7 +3,7 @@ name = "imag-mv" version = "0.8.0" authors = ["Matthias Beyer "] -description = "Part of the imag core distribution: imag command" +description = "Part of the imag core distribution: imag-mv command" keywords = ["imag", "PIM", "personal", "information", "management"] readme = "../../../README.md" From 08ce39989f2617f3b97e1c6e9756b44b21b7c320 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 25 Apr 2018 19:34:32 +0200 Subject: [PATCH 02/10] Remove duplicated script: scripts/gen-changelog exists --- scripts/changelog | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100755 scripts/changelog diff --git a/scripts/changelog b/scripts/changelog deleted file mode 100755 index 04969305..00000000 --- a/scripts/changelog +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -if [[ -z "$1" ]]; then - echo "No rev list given" - exit 1 -fi - -for rev in $(git rev-list $1); do - if git notes --ref=changelog list $rev &> /dev/null; then - git log -n 1 --show-notes=* --pretty="format:* %N" $rev - fi -done From a35ebce73a621f68b3020dc8747f2bc0007f0766 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 26 Apr 2018 16:13:58 +0200 Subject: [PATCH 03/10] Add helper to find contacts with imag-contact in mutt --- etc/imag-contact-mutt-query-command-helper.sh | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 etc/imag-contact-mutt-query-command-helper.sh diff --git a/etc/imag-contact-mutt-query-command-helper.sh b/etc/imag-contact-mutt-query-command-helper.sh new file mode 100644 index 00000000..aac0b15a --- /dev/null +++ b/etc/imag-contact-mutt-query-command-helper.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# A helper script for the mutt query_command +# +# Use +# +# query_command = "/path/to/this/script %s" +# +# in mutt to search contacts from mutt with imag. +# + +# mutt wants a one-line status message before the list of contacts. +echo "Searching with imag ..." +imag contact find "$1" --json | \ +jq --raw-output ' + map(.fullname[0] as $FN + | .email + | map({email: ., fullname: $FN})) + | flatten + | map([.email.address, .fullname, .email.properties.TYPE]) + | .[] + | @tsv +' From eebe51b68ec0ae351d678d52e28856403ee40933 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 27 Apr 2018 11:29:49 +0200 Subject: [PATCH 04/10] Add usage example --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index 77ab2769..0861f514 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,48 @@ install-directory is in your `$PATH`), or install the `imag` binary to call `ima ` (also if everything is in your `$PATH`). +## Example usage + +As imag is a big and complex project, we cannot show all tools of the suite +here. But to give you some idea, here's an example: + +```bash +# Lets initialize imag +imag init + +# Recursively import vcf files +imag contact import /home/user/contacts + +# Create a contact (vcf) in the private collection +imag contact create --file /home/user/contacts/private + +# Add a diary entry +imag diary -p private create + +# Uh, I forgot something in a diary entry, select one and edit it +# use the `fzf` tool here (not a part of imag) to select from the IDs +imag diary -p private list | fzf -m | imag edit -I + +# Link a contact to the diary entry +imag link diary/private/2018/01/01/00:00:00 contact/bc222298-casf-40a4-bda1-50aa980a68c9 + +# Annotate a contact with some notes +imag annotate add contact/bc222298-casf-40a4-bda1-50aa980a68c9 contact-notes + +# Write down some notes named "pineapple" +imag notes create "pineapple" + +# Where was that contact again? +imag grep Eva +# Okay, we need to add some imag-internal notes to that contact +imag grep Eva -l | imag edit -I + +# Now save our work +imag git add . # "imag-git" simply calls git in the imag store +imag git commit -m 'Commit message' +``` + + ## Staying up-to-date We have a [official website for imag](https://imag-pim.org), where I post From 9efa4c715f63880d26808e7006e065112a3b8141 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 27 Apr 2018 14:14:55 +0200 Subject: [PATCH 05/10] Add changelog for 0.7.1 --- doc/src/09020-changelog.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index ce024d31..0217717b 100644 --- a/doc/src/09020-changelog.md +++ b/doc/src/09020-changelog.md @@ -22,6 +22,20 @@ This section contains the changelog from the last release to the next release. * Minor changes * Bugfixes +## 0.7.1 + +Bugfix release for fixing: + +* `libimagdiary` did not return the youngest, but the oldest entry id on `::get_youngest_entry_id()`. +* `imag-view` should not always wrap the text, only if -w is passed +* `imag-log show` should order by date +* `imag` does not inherit stdout if detecting imag command versions. +* `imag-contact import` does only allow absolute pathes +* `imag-contact` has most fields optional now, only name is required +* `imag-contact` automatically creates UID +* `imag-contact` automatically generates/warns about missing file extension + + ## 0.7.0 * Major changes From 9f99783c6ebd3088189e0e0c2848e040bc4cc33c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 29 Apr 2018 00:36:38 +0200 Subject: [PATCH 06/10] Add importer for ioverlander into imag-wiki --- etc/ioverlander-wiki-import.sh | 152 +++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 etc/ioverlander-wiki-import.sh diff --git a/etc/ioverlander-wiki-import.sh b/etc/ioverlander-wiki-import.sh new file mode 100644 index 00000000..7f550854 --- /dev/null +++ b/etc/ioverlander-wiki-import.sh @@ -0,0 +1,152 @@ +#!/usr/bin/env bash +# +# This script imports iOverlander data into a imag-wiki +# +# Requirements +# ============ +# +# * imag-wiki +# * imag-gps +# * imag-store +# * jq +# +# Usage +# ===== +# +# Download the JSON data files from app.ioverlander.com and run them through +# this script. +# +# ./this/script wiki-name ioverlander-file.json +# +# What it does +# ============ +# +# It imports each location from the JSON data into one entry at: +# +# //_ +# +# (The location id is added because names are sometimes reused) +# +# * It uses imag-gps to set the GPS data +# * It sets the header of the entry to the data it finds from the JSON object. +# It puts all data in the "userdata.ioverlander" namespace. +# It strips whitespace from the keys. +# It ignores the GPS data from the JSON object though, as this was added via +# imag-gps. +# * It uses the "description" field as entry content. +# +# Warning +# ======= +# +# As the ioverlander data sometimes contains "/" in the name, some entries are +# namespaced. This has to be fixed and the linkings have to be adapted. This is +# not yet handled by this script. +# +# + +WIKI_NAME="$1" +IOVERLANDER_FILE_PATH="$2" + +[[ -z "$WIKI_NAME" ]] && echo "Wiki name missing" && exit 1 +[[ -z "$IOVERLANDER_FILE_PATH" ]] && echo "JSON file missing" && exit 1 + +imag wiki create-wiki "$WIKI_NAME" --no-edit +echo "Created imag wiki '$WIKI_NAME'" + +tobool() { + if [[ "$1" == "Yes" ]]; then + echo "true" + elif [[ "$1" == "No" ]]; then + echo "false" + else + echo "\"$1\"" + fi +} + +object_to_vars() { + jq -r -c 'to_entries | .[] | .key + "=\"" + (.value | tostring | gsub("\\\""; "")) + "\""' +} + + +# The comments in this function can be outcommented for debugging +process_object() { + read -r json + + local location_latitude + local location_longitude + local location_altitude + local location_horizontal_accuracy + local location_vertical_accuracy + local amenities_Open + local amenities_Electricity + local amenities_Wifi + local amenities_Kitchen + local amenities_Restaurant + local amenities_Showers + local amenities_Water + local amenities_Toilets + local amenities_Big_rig_friendly + local amenities_Tent_friendly + local amenities_Pet_friendly + local id + local name + local description + local date_verified + local category_icon_path + local category_icon_pin_path + local country + local category + + #echo "----------------------------------------------------------" + #echo "JSON = $json" + #echo "-----------" + #echo $json | jq '.location' | object_to_vars | sed 's,^,location_,' + #echo $json | jq '.amenities' | object_to_vars | sed 's,^,amenities_,; s, Big,_big,; s, Rig,_rig,; s, Friendly,_friendly,' + #echo $json | jq 'del(.location)|del(.amenities)' | object_to_vars + + eval $(echo $json | jq '.location' | object_to_vars | sed 's,^,location_,') + eval $(echo $json | jq '.amenities' | object_to_vars | sed 's,^,amenities_,; s, Big,_big,; s, Rig,_rig,; s, Friendly,_friendly,') + eval $(echo $json | jq 'del(.location)|del(.amenities)' | object_to_vars) + + local ctry_slug=$(echo $country | sed 's, ,_,g') + local name_slug=$(echo $name | sed 's, ,_,g') + + echo "create = $ctry_slug/${name_slug}_${id}" + + local article=$(imag wiki --wiki "$WIKI_NAME" create "$ctry_slug/${name_slug}_${id}" --no-edit --print-id || exit 1) + + echo "ARTICLE = $article" + + imag gps add --lat="$location_latitude" --long="$location_longitude" "$article" || { + echo "GPS setting failed" + exit 1 + } + imag store update --id "$article" \ + --header \ + "userdata.ioverlander.id=\"$id\"" \ + "userdata.ioverlander.name=\"$name\"" \ + "userdata.ioverlander.date_verified=\"$date_verified\"" \ + "userdata.ioverlander.country=\"$country\"" \ + "userdata.ioverlander.category=\"$category\"" \ + "userdata.ioverlander.amenities.open=$(tobool "$amenities_Open")" \ + "userdata.ioverlander.amenities.electricity=$(tobool "$amenities_Electricity")" \ + "userdata.ioverlander.amenities.wifi=$(tobool "$amenities_Wifi")" \ + "userdata.ioverlander.amenities.kitchen=$(tobool "$amenities_Kitchen")" \ + "userdata.ioverlander.amenities.restaurant=$(tobool "$amenities_Restaurant")" \ + "userdata.ioverlander.amenities.showers=$(tobool "$amenities_Showers")" \ + "userdata.ioverlander.amenities.water=$(tobool "$amenities_Water")" \ + "userdata.ioverlander.amenities.toilets=$(tobool "$amenities_Toilets")" \ + "userdata.ioverlander.amenities.big_rig_friendly=$(tobool "$amenities_Big_rig_friendly")" \ + "userdata.ioverlander.amenities.tent_friendly=$(tobool "$amenities_Tent_friendly")" \ + "userdata.ioverlander.amenities.pet_friendly=$(tobool "$amenities_Pet_friendly")" \ + --content \""$description\"" || { + echo "header/content setting failed"; + exit 1 + } + +} + +cat "$IOVERLANDER_FILE_PATH" | jq -c '.[]' | while read line; do + process_object +done + From b27b392f4b8a618eb4b295e3138c4fdd34e4daec Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 30 Apr 2018 15:47:58 +0200 Subject: [PATCH 07/10] Add trace output --- lib/core/libimagstore/src/file_abstraction/fs.rs | 1 + lib/core/libimagstore/src/store.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/core/libimagstore/src/file_abstraction/fs.rs b/lib/core/libimagstore/src/file_abstraction/fs.rs index 8ee7ee9d..42314502 100644 --- a/lib/core/libimagstore/src/file_abstraction/fs.rs +++ b/lib/core/libimagstore/src/file_abstraction/fs.rs @@ -96,6 +96,7 @@ impl FileAbstractionInstance for FSFileAbstractionInstance { }; *self = FSFileAbstractionInstance::File(file, path); if let FSFileAbstractionInstance::File(ref mut f, _) = *self { + trace!("Writing buffer..."); return f.write_all(&buf).chain_err(|| SEK::FileNotWritten); } unreachable!(); diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs index 44afbea6..cefa42d7 100644 --- a/lib/core/libimagstore/src/store.rs +++ b/lib/core/libimagstore/src/store.rs @@ -177,6 +177,7 @@ impl StoreEntry { fn write_entry(&mut self, entry: &Entry) -> Result<()> { if self.is_borrowed() { assert_eq!(self.id, entry.location); + trace!("Writing entry..."); self.file .write_file_content(entry) .map(|_| ()) @@ -442,11 +443,13 @@ impl Store { debug!("Writing Entry"); se.write_entry(&entry.entry)?; + trace!("Entry written"); if modify_presence { debug!("Modifying presence of {} -> Present", entry.get_location()); se.status = StoreEntryStatus::Present; } + trace!("Entry updated successfully"); Ok(()) } @@ -798,6 +801,7 @@ impl<'a> Drop for FileLockEntry<'a> { use libimagerror::trace::trace_error_dbg; trace!("Dropping: {:?} - from FileLockEntry::drop()", self.get_location()); if let Err(e) = self.store._update(self, true) { + trace!("Error happened in FileLockEntry::drop() while Store::update()ing"); trace_error_dbg(&e); if_cfg_panic!("ERROR WHILE DROPPING: {:?}", e); } From 84f426297e1bb5e7fa1524844cdafce5be085530 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 30 Apr 2018 15:48:08 +0200 Subject: [PATCH 08/10] Add debug output --- lib/entry/libimagentrylink/src/internal.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/internal.rs index 480a07bc..a69995c9 100644 --- a/lib/entry/libimagentrylink/src/internal.rs +++ b/lib/entry/libimagentrylink/src/internal.rs @@ -388,6 +388,8 @@ pub mod iter { impl InternalLinker for Entry { fn get_internal_links(&self) -> Result { + debug!("Getting internal links"); + trace!("Getting internal links from header of '{}' = {:?}", self.get_location(), self.get_header()); let res = self .get_header() .read("links.internal") @@ -400,6 +402,8 @@ impl InternalLinker for Entry { fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result { use internal::iter::IntoValues; + debug!("Setting internal links"); + let self_location = self.get_location().clone(); let mut new_links = vec![]; @@ -430,11 +434,13 @@ impl InternalLinker for Entry { } fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> { + debug!("Adding internal link: {:?}", link); let location = link.get_location().clone().into(); add_internal_link_with_instance(self, link, location) } fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> { + debug!("Removing internal link: {:?}", link); let own_loc = self.get_location().clone().without_base(); let other_loc = link.get_location().clone().without_base(); From 2bf09e7737febf0bdd3a2bd73d4eb89ad67229e6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 30 Apr 2018 15:47:21 +0200 Subject: [PATCH 09/10] Only create directory if it does not exist --- lib/core/libimagstore/src/file_abstraction/fs.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/core/libimagstore/src/file_abstraction/fs.rs b/lib/core/libimagstore/src/file_abstraction/fs.rs index 42314502..b9d9186d 100644 --- a/lib/core/libimagstore/src/file_abstraction/fs.rs +++ b/lib/core/libimagstore/src/file_abstraction/fs.rs @@ -187,9 +187,12 @@ fn open_file>(p: A) -> ::std::io::Result { fn create_file>(p: A) -> ::std::io::Result { if let Some(parent) = p.as_ref().parent() { - debug!("Implicitely creating directory: {:?}", parent); - if let Err(e) = create_dir_all(parent) { - return Err(e); + trace!("'{}' is directory = {}", parent.display(), parent.is_dir()); + if !parent.is_dir() { + trace!("Implicitely creating directory: {:?}", parent); + if let Err(e) = create_dir_all(parent) { + return Err(e); + } } } OpenOptions::new().write(true).read(true).create(true).open(p) From 8f3b725b4367515732b471d191204e83ec0cf763 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 1 May 2018 21:51:27 +0200 Subject: [PATCH 10/10] Show revision which merged the change in generated changelog --- scripts/gen-changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gen-changelog b/scripts/gen-changelog index 3e947980..67d2419f 100644 --- a/scripts/gen-changelog +++ b/scripts/gen-changelog @@ -10,7 +10,7 @@ fi for rev in $(git rev-list "$since"..HEAD | tac); do if git notes --ref=changelog list $rev &> /dev/null; then output=$(git notes --ref=changelog show $rev | sed '2,$s/^/ /') - echo "* $output" + echo "* [$(echo ${rev:0:10})] $output" fi done