Adds the ability to add files that already exist

Work on #16

This was a relatively large amount of work. It introduces assets which
are stored in the assets sub directory and stored in the database with
the asset type in the database.
master
Jonathan Hodgson 4 years ago
parent 980eef941b
commit a3bbe9b4a2
  1. 97
      inc/file-management
  2. 3
      inc/init
  3. 4
      inc/yaml
  4. 34
      kb

@ -23,6 +23,85 @@ Tags:
editFile "$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 # Takes the filename as a parameter
editFile(){ editFile(){
vecho "editFile $*" vecho "editFile $*"
@ -37,13 +116,23 @@ editFile(){
# This is used to update the DB when a file is changed # This is used to update the DB when a file is changed
# param1 is the file # param1 is the file
updateFileChange(){ updateFileChange(){
vecho "updateFileChange $*"
cd "$dataDir" || return
local filename local filename
local directory=""
local title local title
local newFilename local newFilename
local filetype="normal"
local ext
filename="$(findFile "$1")" filename="$(findFile "$1")"
ext="${filename##*.}"
[ ! -e "$filename" ] && die "No such file $1" [ ! -e "$filename" ] && die "No such file $1"
if echo "$filename" | grep -q '^assets/'; then
filetype="asset"
directory="assets/"
fi
title="$(getYamlTitle "$filename")" title="$(getYamlTitle "$filename")"
newFilename="$(escapeFilename "$title.md")" newFilename="$directory$(escapeFilename "$title.$ext")"
if [ "$filename" = "$newFilename" ]; then if [ "$filename" = "$newFilename" ]; then
# The title hasn't changed # The title hasn't changed
# check if the file is in the DB # check if the file is in the DB
@ -51,7 +140,7 @@ updateFileChange(){
# If not, add it # If not, add it
echo "INSERT INTO items (filename, title, type) echo "INSERT INTO items (filename, title, type)
VALUES ( '$(safeSQL "$filename")', VALUES ( '$(safeSQL "$filename")',
'$(safeSQL "$title")', 'normal' );" | '$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
sqlite3 "${sqliteFile}" sqlite3 "${sqliteFile}"
fi fi
# Make sure all the tags are up to date # Make sure all the tags are up to date
@ -76,7 +165,7 @@ Please resolve manually"
# We get here if the title was changed in the create process # We get here if the title was changed in the create process
echo "INSERT INTO items (filename, title, type) echo "INSERT INTO items (filename, title, type)
VALUES ( '$(safeSQL "$newFilename")', VALUES ( '$(safeSQL "$newFilename")',
'$(safeSQL "$title")', 'normal' );" | '$(safeSQL "$title")', '$(safeSQL "$filetype")' );" |
sqlite3 "${sqliteFile}" sqlite3 "${sqliteFile}"
fi fi
@ -86,6 +175,7 @@ Please resolve manually"
} }
deleteFile(){ deleteFile(){
vecho "deleteFile $*"
cd "$dataDir" || return cd "$dataDir" || return
local filename local filename
local fileID local fileID
@ -108,6 +198,7 @@ deleteFile(){
} }
viewFile(){ viewFile(){
vecho "viewFile $*"
cd "$dataDir" || return cd "$dataDir" || return
local id="$1" local id="$1"

@ -15,7 +15,8 @@ initKnowledgeBase(){
git init "$dataDir" > "$output" git init "$dataDir" > "$output"
# TODO: make gitignore use new sqlite file # TODO: make gitignore use new sqlite file
echo "/knowledgebase.sqlite3" >> "${dataDir}/.gitignore" # Datadir always has a trailing slash
echo "/knowledgebase.sqlite3" >> "${dataDir}.gitignore"
git -C "$dataDir" add .gitignore > "$output" git -C "$dataDir" add .gitignore > "$output"
git -C "$dataDir" commit -m "Knowledge base initialised" > "$output" git -C "$dataDir" commit -m "Knowledge base initialised" > "$output"

@ -40,8 +40,8 @@ getYamlTitle(){
} }
getYamlTags(){ getYamlTags(){
vecho "getYamlTitle $*" vecho "getYamlTags $*"
cd "$dataDir" || return cd "$dataDir" || return
getYamlBlock "$1" | yq -r '.Tags | join("\n")' getYamlBlock "$1" | yq -r '.Tags | if . == null then [] else . end | join("\n")'
} }

34
kb

@ -41,6 +41,10 @@ die(){
exit 1 exit 1
} }
warn(){
necho -e "${YELLOW}$*${NC}" > /dev/tty
}
# Normal echo # Normal echo
# Echo if quiet is 0 # Echo if quiet is 0
necho(){ necho(){
@ -53,7 +57,7 @@ necho(){
# Echo if verbose is 1 # Echo if verbose is 1
vecho(){ vecho(){
if [ "$verbose" -eq 1 ]; then if [ "$verbose" -eq 1 ]; then
echo "$@" echo "$@" > /dev/tty
fi fi
} }
@ -143,9 +147,15 @@ makedb(){
# Makes file names safe # Makes file names safe
escapeFilename(){ escapeFilename(){
vecho "escapeFilename $*" vecho "escapeFilename $*"
echo "$1" | if [[ "$1" = assets/* ]]; then
tr ' ' '_' | # replace spaces with underscores echo -n "assets/"
tr -d '/' # Delete slashes echo "$(escapeFilename "${1#*/}")"
#echo "assets/$(escapeFilename "${1#*/}")"
else
echo "$1" |
tr ' ' '_' | # replace spaces with underscores
tr '/' '_' # replace slashes with underscores
fi
} }
findFileId(){ findFileId(){
@ -180,7 +190,7 @@ findFile(){
echo "$filename.md" echo "$filename.md"
exit 0 exit 0
else else
die "No such file or ID $filename" die "No such file or ID '$filename'"
exit 1 exit 1
fi fi
fi fi
@ -240,7 +250,7 @@ listEntries(){
case "$1" in case "$1" in
--noheader) header="" ;; --noheader) header="" ;;
--normal) typeorlist+=" OR items.type = 'normal'" ;; --normal) typeorlist+=" OR items.type = 'normal'" ;;
--assets) typeorlist+=" OR items.type = 'assets'" ;; --asset|--assets) typeorlist+=" OR items.type = 'asset'" ;;
--links) typeorlist+=" OR items.type = 'links'" ;; --links) typeorlist+=" OR items.type = 'links'" ;;
*) die "invalid list option: '$1'." ;; *) die "invalid list option: '$1'." ;;
esac esac
@ -277,7 +287,7 @@ mainScript() {
############## Begin Script Here ################### ############## Begin Script Here ###################
#################################################### ####################################################
if [ "${args[0]}" != "init" ]; then if [ "${args[0]}" != "init" ]; then
cd "$dataDir" || return #cd "$dataDir" || return
# Check to see if datadir is a git repo # Check to see if datadir is a git repo
if ! git rev-parse 2> /dev/null; then if ! git rev-parse 2> /dev/null; then
# If not, ensure we don't run git commands # If not, ensure we don't run git commands
@ -286,6 +296,7 @@ mainScript() {
fi fi
case "${args[0]}" in case "${args[0]}" in
add) addFile "${args[@]:1}"; safeExit ;;
deepsearch) deepSearch "${args[@]:1}"; safeExit ;; deepsearch) deepSearch "${args[@]:1}"; safeExit ;;
del|delete) deleteFile "${args[@]:1}"; safeExit ;; del|delete) deleteFile "${args[@]:1}"; safeExit ;;
edit) editFile "${args[@]:1}"; safeExit ;; edit) editFile "${args[@]:1}"; safeExit ;;
@ -344,6 +355,10 @@ usage() {
update <file> [<file>] Updates the database and git repo of a changed file update <file> [<file>] Updates the database and git repo of a changed file
If 2 files are given, it assumes a move If 2 files are given, it assumes a move
view View a file view View a file
add [options] <file> Adds a file
--asset Adds the file as an asset
--yaml-header Adds a yaml header (default for markdown files)
--yaml-file Adds a yaml file (default for non-markdown files)
fuzzy [command] Fuzzy select a file fuzzy [command] Fuzzy select a file
command is what to do with the selected file command is what to do with the selected file
edit or view edit or view
@ -400,7 +415,8 @@ while [[ $1 = -?* ]]; do
-v|--verbose) verbose=1 ;; -v|--verbose) verbose=1 ;;
-q|--quiet) quiet=1 ;; -q|--quiet) quiet=1 ;;
-d|--debug) debug=1;; -d|--debug) debug=1;;
--data) dataDir="$2"; shift ;; # Ensure that the dataDir has a trailing slash
--data) dataDir="${2%%/}/"; shift ;;
--sqlite) sqliteFile="$2"; shift ;; --sqlite) sqliteFile="$2"; shift ;;
--editor) editor="$2"; shift ;; --editor) editor="$2"; shift ;;
--pager) pager="$2"; shift ;; --pager) pager="$2"; shift ;;
@ -413,7 +429,7 @@ done
# If the sqlite file hasn't been specified on the command line, make it a file # If the sqlite file hasn't been specified on the command line, make it a file
# called knowledgebase.sqlite3 in the dataDir # called knowledgebase.sqlite3 in the dataDir
[ -z "$sqliteFile" ] && sqliteFile="${dataDir}/knowledgebase.sqlite3" [ -z "$sqliteFile" ] && sqliteFile="${dataDir}knowledgebase.sqlite3"
# Store the remaining part as arguments. # Store the remaining part as arguments.
args+=("$@") args+=("$@")

Loading…
Cancel
Save