A tool for managing my collection of notes.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.4 KiB

#!/usr/bin/env bash
# This file contains functions relating to file operations such as new, edit and deleting files
newFile(){
vecho "newFile $*"
cd "$dataDir" || return
# While there is a - at the begining
local title="$*"
if [ -z "$title" ]; then
echo -n "Enter a title: "
read -r title
fi
local filename
filename="$(escapeFilename "$title.md")"
[ -e "$filename" ] && die "$filename already exists"
echo -e "---
Title: $title
Tags:
-
---
" > "$filename"
editFile "$filename"
}
addFile(){
vecho "addFile $*"
local copiedFile
local subFolder=""
local ext
local file
local filenameTitle
local yaml
local yamlBlock
local yamlTitle
while [[ $1 = -?* ]]; do
case "$1" in
--asset) mkdir -p "${dataDir}assets"; subFolder+="assets/" ;;
--yaml-header) yaml="header" ;;
--yaml-file) yaml="file" ;;
*) die "invalid add option: '$1'." ;;
esac
shift
done
file="$1"
[ -z "$file" ] && die "You must specify a file"
[ -f "$file" ] || die "File $file not found"
ext="${file##*.}"
copiedFile="${file##*/}"
# If the type of yaml entry hasn't been specified on the command line
if [ -z "$yaml" ]; then
# We want a header if it's markdown, otherwise a seperate file
if [ "$ext" = "md" ]; then
yaml="header"
else
yaml="file"
fi
fi
[ -e "$dataDir$copiedFile" ] && die "File $copiedFile already exists"
cp "$file" "$dataDir$subFolder$copiedFile"
# The title as specified in yaml (or empty string)
yamlBlock="$(getYamlBlock "$subFolder$copiedFile")"
yamlTitle="$(getYamlTitle "$subFolder$copiedFile")"
# The title generated from filename
filenameTitle="$(echo "$copiedFile" | tr '_' ' ' | sed -E 's/\..[^.]+$//')"
if [ -z "$yamlTitle" ] || [ "$yamlTitle" = "null" ]; then
# If empty, generate the title from the filename
yamlTitle="$filenameTitle"
else
# If the yaml title and the filename title are different, then use the yaml title
if [ "$yamlTitle" != "$filenameTitle" ]; then
local newFilename=$(escapeFilename "$yamlTitle").$ext
echo mv "$dataDir$subFolder$copiedFile" "$dataDir$subFolder$newFilename"
warn "File renamed from $copiedFile to "$newFilename
copiedFile="$newFilename"
fi
fi
yamlBlock="Title: $yamlTitle
$yamlBlock"
if [ "$yaml" = "header" ]; then
local tmpfile=$(mktemp)
echo "---
$yamlBlock
---" > $tmpfile
sed '1 { /^---/ { :a N; /\n---/! ba; d} }' "$dataDir$subFolder$copiedFile" >> "$tmpfile"
mv "$tmpfile" "$dataDir$subFolder$copiedFile"
else
echo "$yamlBlock" > "$dataDir$subFolder$copiedFile.yaml"
fi
updateFileChange "$subFolder$copiedFile"
}
# Takes the filename as a parameter
editFile(){
vecho "editFile $*"
cd "$dataDir" || return
local filename
filename="$(findFile "$*")"
[ ! -e "$filename" ] && exit 1
"$editor" "$filename"
updateFileChange "$filename"
}
# This is used to update the DB when a file is changed
# param1 is the file
updateFileChange(){
vecho "updateFileChange $*"
cd "$dataDir" || return
local filename
local directory=""
local title
local newFilename
local filetype="normal"
local ext
filename="$(findFile "$*")"
ext="${filename##*.}"
[ ! -e "$filename" ] && die "No such file $1"
if echo "$filename" | grep -q '^assets/'; then
filetype="asset"
directory="assets/"
fi
title="$(getYamlTitle "$filename")"
newFilename="$directory$(escapeFilename "$title.$ext")"
if [ "$filename" = "$newFilename" ]; then
# The title hasn't changed
# check if the file is in the DB
if ! fileInDB "$filename"; then
# If not, add it
echo "INSERT INTO items (filename, title, type)
VALUES ( '$(safeSQL "$filename")',
'$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
sqlite3 "${sqliteFile}"
fi
# Make sure all the tags are up to date
getYamlTags "$filename" | assignTags "$filename"
gitChange "$filename"
else
# The title has changed so we need to move the file
if [ -e "$newFilename" ]; then
# If the place we need to move it to already exists, die
die -e "$newFilename already exists
$filename title changed
Please resolve manually"
else
mv "$filename" "$newFilename"
[ -e "$filename.yaml" ] && mv "$filename.yaml" "$newFilename.yaml"
if fileInDB "$filename"; then
echo "UPDATE items
SET (filename,title) =
('$(safeSQL "$newFilename")','$(safeSQL "$title")')
WHERE filename = '$(safeSQL "$filename")';" |
sqlite3 "${sqliteFile}"
else
# We get here if the title was changed in the create process
echo "INSERT INTO items (filename, title, type)
VALUES ( '$(safeSQL "$newFilename")',
'$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
sqlite3 "${sqliteFile}"
fi
getYamlTags "$filename" | assignTags "$filename"
gitChange "$filename" "$newFilename"
fi
fi
}
deleteFile(){
vecho "deleteFile $*"
cd "$dataDir" || return
local filename
local fileID
local rsp
filename="$(findFile "$*")"
fileID="$(findFileId "$filename")"
[ ! -e "$filename" ] && exit 1
echo -n "Are you sure? [yN] "
read -r rsp
if [[ "$(echo "$rsp" | tr '[:upper:]' '[:lower:]')" = "y"* ]]; then
rm "$filename"
[ -e "$filename.yaml" ] && rm "$filename.yaml"
# This deletes the file from the sql database and any tag links
echo "DELETE FROM items
WHERE id = '$(safeSQL "$fileID")';
DELETE FROM links
WHERE itemID = '$(safeSQL "$fileID")';" |
sqlite3 --column --header "${sqliteFile}"
gitChange "$filename"
fi
}
viewFile(){
vecho "viewFile $*"
cd "$dataDir" || return
local id="$*"
local filename
filename="$(findFile "$id")"
"$pager" "$filename"
}