Add existing scripts
This commit is contained in:
1 parent
2ab5a42c2b
commit
3c05d74104
31 files changed
+1138
No files matched your search
@@ -0,0 +1,34 @@
|
||||
# This script is meant to be sourced in other scripts to make colorizing easier.
|
||||
# It should not be made executable and run stand-alone.
|
||||
|
||||
# Set Select Graphic Rendition (SGR)
|
||||
GROFF_NO_SGR=1
|
||||
|
||||
# Modifiers
|
||||
RESET=$'\e[0m'
|
||||
BOLD=$'\e[1m' # also used as bright
|
||||
DIM=$'\e[2m'
|
||||
UNDERLINE=$'\e[4m'
|
||||
BLINK=$'\e[5m' # this may not work in all terminals
|
||||
INVERT=$'\e[7m' # swaps background and foreground colors
|
||||
|
||||
# Foreground colors
|
||||
FG_BLACK=$'\e[0;30m'
|
||||
FG_RED=$'\e[0;31m'
|
||||
FG_GREEN=$'\e[0;32m'
|
||||
FG_YELLOW=$'\e[0;33m'
|
||||
FG_BLUE=$'\e[0;34m'
|
||||
FG_MAGENTA=$'\e[0;35m'
|
||||
FG_CYAN=$'\e[0;36m'
|
||||
FG_WHITE=$'\e[0;37m'
|
||||
|
||||
# Background colors
|
||||
BG_BLACK=$'\e[40m'
|
||||
BG_RED=$'\e[41m'
|
||||
BG_GREEN=$'\e[42m'
|
||||
BG_YELLOW=$'\e[43m'
|
||||
BG_BLUE=$'\e[44m'
|
||||
BG_MAGENTA=$'\e[45m'
|
||||
BG_CYAN=$'\e[46m'
|
||||
BG_WHITE=$'\e[47m'
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Source file to set colorization in less and man
|
||||
# To change between ansi escape and tput, change commenting as required
|
||||
#
|
||||
# Change the variable below to specify the colorization method to use
|
||||
# Valid values are "ansi" and "tput"
|
||||
COLORIZER="tput"
|
||||
|
||||
# Set pagers and turn off select graphic rendition (SGR)
|
||||
export GROFF_NO_SGR=1
|
||||
export MANPAGER='less'
|
||||
export PAGER='less'
|
||||
|
||||
|
||||
# Check the COLORIZER variable to use the requested method
|
||||
if [[ "$COLORIER" == "ansi" ]]; then
|
||||
# Set ansi escape codes to colorize less/man output
|
||||
export LESS_TERMCAP_mb=$'\e[1;31m' # blinking text mode (if supported), set to bold/red
|
||||
export LESS_TERMCAP_md=$'\e[1;31m' # bold text mode, set to bold/red
|
||||
export LESS_TERMCAP_me=$'\e[0m' # ends all special formatting (like mb, md, etc.)
|
||||
export LESS_TERMCAP_se=$'\e[0m' # ends standout mode
|
||||
export LESS_TERMCAP_so=$'\e[1;33;44m' # begin standout mode, bold/yellow text w/ blue background
|
||||
export LESS_TERMCAP_ue=$'\e[0m' # end underline mode
|
||||
export LESS_TERMCAP_us=$'\e[4;1;32m' # begin underline mode, bold/green text w/ underline
|
||||
export LESS_TERMCAP_mr=$'\e[7m' # begin reverse video mode
|
||||
export LESS_TERMCAP_mh=$'\e[2m' # begin dim, half bright mode
|
||||
export LESS_TERMCAP_ZN=$'\e[74m' # begin subscript mode, possibly not supported
|
||||
export LESS_TERMCAP_ZV=$'\e[75m' # end subscript mode, possibly not supported
|
||||
export LESS_TERMCAP_ZO=$'\e[73m' # begin superscript mode, possibly not supported
|
||||
export LESS_TERMCAP_ZW=$'\e[75m' # end superscript mode, possible not supported
|
||||
elif [[ "$COLORIZER" == "tput" ]]; then
|
||||
# Set tput values to match the same colors above (see line comments above for descriptions)
|
||||
export LESS_TERMCAP_md=$(tput bold; tput setaf 1)
|
||||
export LESS_TERMCAP_me=$(tput sgr0)
|
||||
export LESS_TERMCAP_se=$(tput sgr0)
|
||||
export LESS_TERMCAP_so=$(tput bold; tput setaf 3; tput setab 4)
|
||||
export LESS_TERMCAP_ue=$(tput sgr0)
|
||||
export LESS_TERMCAP_us=$(tput smul; tput bold; tput setaf 2)
|
||||
export LESS_TERMCAP_mr=$(tput rev)
|
||||
export LESS_TERMCAP_mh=$(tput dim)
|
||||
export LESS_TERMCAP_ZN=$(tput ssubm)
|
||||
export LESS_TERMCAP_ZV=$(tput rsubm)
|
||||
export LESS_TERMCAP_ZO=$(tput ssupm)
|
||||
export LESS_TERMCAP_ZW=$(tput rsupm)
|
||||
else
|
||||
echo
|
||||
echo ***** COLORIZER variable must be set to colorize man/less output *****
|
||||
echo
|
||||
fi
|
||||
@@ -0,0 +1,23 @@
|
||||
# To have scripts not write everything out to stdout so results can be captured
|
||||
# redirect any output not wanted to /dev/null
|
||||
#
|
||||
# This is the original that outputs 1 or 0 with echo
|
||||
command_exists_1 () {
|
||||
if type "$1" >> /dev/null; then
|
||||
echo "1"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# A better version is to use the return keyword
|
||||
# This command can be used in an if statement, if needed
|
||||
# The logic has to be reversed - the shell treats 0 as success
|
||||
command_exists() {
|
||||
if type "$1" >> /dev/null; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# Inform the user of the output they can expect.
|
||||
|
||||
echo "common commands:"
|
||||
|
||||
|
||||
# Show the most commonly used commands
|
||||
tail ~/.bash_history -n 1000 \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n 10
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Inform the user of the output they can expect.
|
||||
|
||||
echo "common commands:"
|
||||
|
||||
|
||||
# The following variables control how the command runs.
|
||||
history_lines=1000 # The number of lines of history to search through
|
||||
command_count=10 # The number of common commands to show
|
||||
|
||||
# Show the most commonly used commands
|
||||
tail ~/.bash_history -n ${history_lines} \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n ${command_count}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
# Inform the user of the output they can expect.
|
||||
|
||||
echo "common commands:"
|
||||
|
||||
|
||||
# The following variables control how the command runs.
|
||||
shell_binary="" # A place to store the shell binary value
|
||||
history_file="" # A place to store the history file path
|
||||
history_lines=1000 # The number of lines of history to search through
|
||||
command_count=10 # The number of common commands to show
|
||||
|
||||
# Check whether you can determine the name of the shell binary
|
||||
shell_regex="([^/]+$)"
|
||||
if [[ $SHELL =~ $shell_regex ]]; then
|
||||
# Depending on the name of the shell binary, set the history filepath
|
||||
shell_binary=${BASH_REMATCH[1]}
|
||||
if [[ $shell_binary == "bash" ]]; then
|
||||
history_file=~/.bash_history
|
||||
elif [[ $shell_binary == "zsh" ]]; then
|
||||
history_file=~/.zsh_history
|
||||
fi
|
||||
fi
|
||||
|
||||
# If you are searching through the bash history, you can look at the history file
|
||||
# to get the most common commands
|
||||
if [[ $shell_binary == "bash" ]]; then
|
||||
|
||||
# Show the most commonly used commands
|
||||
tail "${history_file}" -n ${history_lines} \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n ${command_count}
|
||||
|
||||
elif [[ $shell_binary == "zsh" ]]; then
|
||||
|
||||
# Z shell shitory lines look like this:
|
||||
# : 1621135004:0;uname -a
|
||||
# Run the same command as above, and extract everything _after_ the
|
||||
# semicolon, which is the command text
|
||||
tail "${history_file}" -n ${history_lines} \
|
||||
| cut -d';' -f2 \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n ${command_count}
|
||||
else
|
||||
|
||||
# show a warning to the user that you don't know where the history file
|
||||
# is for their shell
|
||||
echo "Sorry, I don't know where to find the history file for '${SHELL}'"
|
||||
fi
|
||||
Executable
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# Exit if any command fails
|
||||
set -e
|
||||
|
||||
# Inform the user of the output they can expect.
|
||||
|
||||
echo "common commands:"
|
||||
|
||||
write_command_then_count() {
|
||||
# Get the command and count, which currently looks like:
|
||||
# '42 git commit'
|
||||
# Then write th e command with the count afterward
|
||||
local line="$1"
|
||||
local count=$(echo "${line}" | cut -d' ' -f1)
|
||||
local command=$(echo "${line}" | cut -d' ' -f2-)
|
||||
echo "${command} (${count})"
|
||||
}
|
||||
|
||||
|
||||
# The following variables control how the command runs.
|
||||
shell_binary="" # A place to store the shell binary value
|
||||
history_file="" # A place to store the history file path
|
||||
history_lines=1000 # The number of lines of history to search through
|
||||
command_count=${1:-10} # The number of common commands to show
|
||||
|
||||
# Check whether you can determine the name of the shell binary
|
||||
shell_regex="([^/]+$)"
|
||||
if [[ $SHELL =~ $shell_regex ]]; then
|
||||
# Depending on the name of the shell binary, set the history filepath
|
||||
shell_binary=${BASH_REMATCH[1]}
|
||||
if [[ $shell_binary == "bash" ]]; then
|
||||
history_file=~/.bash_history
|
||||
elif [[ $shell_binary == "zsh" ]]; then
|
||||
history_file=~/.zsh_history
|
||||
fi
|
||||
fi
|
||||
|
||||
# If you are searching through the bash history, you can look at the history file
|
||||
# to get the most common commands
|
||||
if [[ $shell_binary == "bash" ]]; then
|
||||
|
||||
# Show the most commonly used commands
|
||||
commands=$(tail "${history_file}" -n ${history_lines} \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n ${command_count})
|
||||
|
||||
elif [[ $shell_binary == "zsh" ]]; then
|
||||
|
||||
# Z shell shitory lines look like this:
|
||||
# : 1621135004:0;uname -a
|
||||
# Run the same command as above, and extract everything _after_ the
|
||||
# semicolon, which is the command text
|
||||
commands=$(tail "${history_file}" -n ${history_lines} \
|
||||
| cut -d';' -f2 \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sed 's/^ *//' \
|
||||
| sort -n -r \
|
||||
| head -n ${command_count})
|
||||
else
|
||||
|
||||
# show a warning to the user that you don't know where the history file
|
||||
# is for their shell
|
||||
echo "Sorry, I don't know where to find the history file for '${SHELL}'"
|
||||
fi
|
||||
|
||||
# Print each command, showing its order in the list
|
||||
# Commands are separated by newlines, so temporarily change IFS to loop over
|
||||
# each line of the commands
|
||||
counter=1
|
||||
old_ifs=$IFS
|
||||
IFS=$'\n'
|
||||
for command in $commands
|
||||
do
|
||||
use_count=$(echo "$command" | cut -d' ' -f 1)
|
||||
use_command=$(echo "$command" | cut -d' ' -f 2)
|
||||
printf "$(tput bold; tput setaf 3)%-5s $(tput sgr0)$(tput setaf 6)%-5s $(tput sgr0)%-5s\n" "$counter" "$use_count" "$use_command"
|
||||
counter=$((counter + 1))
|
||||
done
|
||||
IFS=$old_ifs
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# When files or symlinks may include a space in the name,
|
||||
# this style of looping over them can come in handy.
|
||||
#
|
||||
# Save the current value of IFS, so you can restore it later. Split on newlines.
|
||||
old_ifs=$IFS
|
||||
IFS=$'\n'
|
||||
|
||||
# Find all symlinks and print each one
|
||||
links=$(find ~ -type l -maxdepth 1)
|
||||
|
||||
for link in $links
|
||||
do
|
||||
echo "Found Link: $link"
|
||||
done
|
||||
|
||||
# Restore the original IFS value
|
||||
IFS=$old_ifs
|
||||
|
||||
# While this can be used to cover a specific edge case, if you change the IFS
|
||||
# variable often, that is a sign that a programming or other scripting language
|
||||
# would provide a better solution
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# An example of how to ensure a user really wants to interrupt an operation
|
||||
# Useful for scripts where interruption could be harmful
|
||||
|
||||
interrupt_count=0
|
||||
on_interrupt() {
|
||||
if [ $interrupt_count -lt 1 ]; then
|
||||
echo "Canceling this operation can cause errors."
|
||||
echo "Press Ctrl-C again if you are sure you want to cancel."
|
||||
interrupt_count=$((interrupt_count + 1))
|
||||
else
|
||||
# Convention is to use the status code 130 for interrupted scripts.
|
||||
echo "Canceling long operation"
|
||||
printf "$(tput cr)$(tput el)"
|
||||
exit 130
|
||||
fi
|
||||
}
|
||||
|
||||
trap on_interrupt INT
|
||||
|
||||
total_time=0
|
||||
while [ $total_time -le 600 ]; do
|
||||
printf "$(tput cr)$(tput el)Long operation: ${total_time} seconds elapsed\r"
|
||||
sleep 3
|
||||
total_time=$((total_time + 3))
|
||||
done
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Load the example history provided by the Effective Shell book
|
||||
|
||||
# If the book examples aren't available, load them
|
||||
if [ ! -d ~/effective-shell ]; then
|
||||
echo -e "\e[0;36mCopying Effective Shell example files\e[0m"
|
||||
curl effective.sh | sh
|
||||
fi
|
||||
|
||||
# Check if there is a backup of the history file already
|
||||
if [ ! -f ~/.bash_history.backup ]; then
|
||||
# if not, make a backup of the file
|
||||
cp ~/.bash_history ~/.bash_history.backup
|
||||
# copy the example history
|
||||
cp ~/effective-shell/data/history.txt ~/.bash_history
|
||||
# clear the history
|
||||
history -c
|
||||
# reload the history
|
||||
history -r
|
||||
echo -e "\e[1;31mThe history file has been backed up and test data staged\e[0m"
|
||||
else
|
||||
echo -e "\e[1;33mThere is already a history file backup\e[0m"
|
||||
fi
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
for(int i = 0; i < 1000000; i++) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python3.14
|
||||
|
||||
for i in range(1_000_000):
|
||||
pass
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Print a message in each of the 8 ANSI terminal colors
|
||||
|
||||
rainbow() {
|
||||
local message="$1"
|
||||
local reset='\e[0m'
|
||||
for ((color=31; color<=37; color++))
|
||||
do
|
||||
color_code="\\e[0;${color}m"
|
||||
if [ -t 1 ]; then
|
||||
printf "${color} - ${color_code}${message}${reset}\n"
|
||||
else
|
||||
printf "${color} - ${message}\n"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
31 - Good afternoon
|
||||
32 - Good afternoon
|
||||
33 - Good afternoon
|
||||
34 - Good afternoon
|
||||
35 - Good afternoon
|
||||
36 - Good afternoon
|
||||
37 - Good afternoon
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Create an empty array to store random numbers
|
||||
random_numbers=()
|
||||
|
||||
# As long as the length of the array is less than 5, continue to loop
|
||||
while [ ${#random_numbers[@]} -lt 5 ]
|
||||
do
|
||||
# Get a random number; ask the user if they want to add it to the array
|
||||
random_number=$RANDOM
|
||||
read -p "Add $random_number to the list? (y/n): " choice
|
||||
|
||||
# If the user chose "y", add the random number to the array
|
||||
if [ "$choice" = "y" ]; then random_numbers+=($random_number); fi
|
||||
done
|
||||
|
||||
# Show the contents of the array
|
||||
echo "Random Numbers: ${random_numbers[@]}"
|
||||
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
# Restore the real history file after running book examples
|
||||
|
||||
# Check for a backup file
|
||||
if [ -f ~/.bash_history.backup ]; then
|
||||
# Rename the backukp file as the current file
|
||||
mv ~/.bash_history.backup ~/.bash_history
|
||||
# Clear the example history
|
||||
history -c
|
||||
# Reload the history from the restored file
|
||||
history -r
|
||||
echo -e "\e[1;36mThe original history has been restored\e[0m"
|
||||
else
|
||||
echo -e "\e[1;33mThere is no backup history to restore\e[0m"
|
||||
fi
|
||||
Executable
+228
@@ -0,0 +1,228 @@
|
||||
# Note: this script should be sourced into your shell. For this reason it does
|
||||
# not specify a shebang.
|
||||
#
|
||||
# set-ps1: set the command prompt (PS1) variable to a named 'theme'.
|
||||
#
|
||||
# example:
|
||||
#
|
||||
# set-ps1 simple
|
||||
#
|
||||
# If no 'theme' is provided, the original PS1 value that was set in the shell
|
||||
# startup files is used.
|
||||
|
||||
# Keep track of the original PS1 value.
|
||||
_original_ps1="${PS1}"
|
||||
|
||||
set_ps1() {
|
||||
# Foreground colours.
|
||||
local fg_black=$(tput setaf 0) # \033[30m
|
||||
local fg_red=$(tput setaf 1) # \033[31m
|
||||
local fg_green=$(tput setaf 2) # \033[32m
|
||||
local fg_yellow=$(tput setaf 3) # \033[33m
|
||||
local fg_blue=$(tput setaf 4) # \033[34m
|
||||
local fg_magenta=$(tput setaf 5) # \033[35m
|
||||
local fg_cyan=$(tput setaf 6) # \033[36m
|
||||
local fg_white=$(tput setaf 7) # \033[37m
|
||||
|
||||
# Background colours.
|
||||
local bg_black=$(tput setab 0) # \033[40m
|
||||
local bg_red=$(tput setab 1) # \033[41m
|
||||
local bg_green=$(tput setab 2) # \033[42m
|
||||
local bg_yellow=$(tput setab 3) # \033[43m
|
||||
local bg_blue=$(tput setab 4) # \033[44m
|
||||
local bg_magenta=$(tput setab 5) # \033[45m
|
||||
local bg_cyan=$(tput setab 6) # \033[46m
|
||||
local bg_white=$(tput setab 7) # \033[47m
|
||||
|
||||
# Text styles and reset. Note that on some terminals 'bold' will produce
|
||||
# light colours for bright colours, on others it will actually show the text
|
||||
# in bold.
|
||||
local bold=$(tput bold) # \033[1m
|
||||
local dim=$(tput dim) # \033[2m
|
||||
local start_underline=$(tput smul) # \033[4m
|
||||
local stop_underline=$(tput rmul) # \033[24m
|
||||
local reset=$(tput sgr0) # \033[0m
|
||||
|
||||
# If you need them, you can get other terminal capabilties such as the
|
||||
# number of colours, lines, columns, etc.
|
||||
local colors=$(tput colors) # Number of colours, e.g. '8' or '256'
|
||||
local lines=$(tput lines) # Number of lines in the terminal
|
||||
local cols=$(tput cols) # Number of columns in the terminal
|
||||
|
||||
# Special characters for PS1 strings:
|
||||
# \a an ASCII bell character (07)
|
||||
# \d the date in "Weekday Month Date" format (e.g., "Tue May 26")
|
||||
# \D{format}
|
||||
# the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The
|
||||
# braces are required
|
||||
# \e an ASCII escape character (033)
|
||||
# \h the hostname up to the first `.'
|
||||
# \H the hostname
|
||||
# \j the number of jobs currently managed by the shell
|
||||
# \l the basename of the shell's terminal device name
|
||||
# \n newline
|
||||
# \r carriage return
|
||||
# \s the name of the shell, the basename of $0 (the portion following the final slash)
|
||||
# \t the current time in 24-hour HH:MM:SS format
|
||||
# \T the current time in 12-hour HH:MM:SS format
|
||||
# \@ the current time in 12-hour am/pm format
|
||||
# \A the current time in 24-hour HH:MM format
|
||||
# \u the username of the current user
|
||||
# \v the version of bash (e.g., 2.00)
|
||||
# \V the release of bash, version + patch level (e.g., 2.00.0)
|
||||
# \w the current working directory, with $HOME abbreviated with a tilde (uses the value of the PROMPT_DIRTRIM variable)
|
||||
# \W the basename of the current working directory, with $HOME abbreviated with a tilde
|
||||
# \! the history number of this command
|
||||
# \# the command number of this command
|
||||
# \$ if the effective UID is 0, a #, otherwise a $
|
||||
# \nnn the character corresponding to the octal number nnn
|
||||
# \\ a backslash
|
||||
# \[ begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt
|
||||
# \] end a sequence of non-printing characters
|
||||
|
||||
# Depending on the name of the theme provided, set the prompt.
|
||||
case $1 in
|
||||
basic)
|
||||
# Debian/Ubuntu style:
|
||||
# \u@\h - username@host
|
||||
# \w - working directory
|
||||
# \$ - prompt
|
||||
PS1="\u@\h:\w\\$ "
|
||||
;;
|
||||
|
||||
debian)
|
||||
# Debian/Ubuntu style:
|
||||
# \u@\h - username@host (bold/green)
|
||||
# \w - working directory (bold/blue)
|
||||
# \$ - prompt (# if root, otherwise $) (bold/white)
|
||||
PS1="\[${bold}${fg_green}\]\u@\h:\[${fg_blue}\]\w\[${fg_white}\]\\$\[${reset}\] "
|
||||
;;
|
||||
|
||||
datetime)
|
||||
# A style that shows the date and time:
|
||||
# \D{%Y-%m-%d} - the year/month/date (in white)
|
||||
# \@ - the time (in green)
|
||||
# \$ - prompt (# if root, otherwise $) (bold/white)
|
||||
PS1="\[${fg_white}\]\D{%Y-%m-%d} \[${bold}${fg_green}\]\@\[${fg_white}\] \\$\[${reset}\] "
|
||||
;;
|
||||
|
||||
git)
|
||||
# A Debian style prompt with the git info above it.
|
||||
PS1="\$(_git_info)"$'\n'"\\[${bold}${fg_green}\]\u@\h:\[${fg_blue}\]\w\[${fg_white}\]\\$\[${reset}\] "
|
||||
;;
|
||||
|
||||
dwmkerr)
|
||||
# The current folder, up to 3 items shown, the git info, then the prompt.
|
||||
# Starts with a leading newline to space out commands.
|
||||
PS1=$'\n'"\[${bold}${fg_blue}\$(_pwd_max_folders 3)${reset}\] \$(_git_info)"$'\n'"\[${bold}${fg_white}\]\\$\[${reset}\] "
|
||||
;;
|
||||
|
||||
|
||||
# Add your own themes here!
|
||||
|
||||
*)
|
||||
# Restore PS1 to its original value.
|
||||
PS1="${_original_ps1}"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# If we are in Z-Shell convert the PS1 to use Z-Shell format.
|
||||
[ -n "$ZSH_VERSION" ] && PS1=$(_to_zsh "$PS1")
|
||||
}
|
||||
|
||||
# Build a string that shows:
|
||||
# - The branch (underlined if 'main') in green
|
||||
# - A red exclamation if there are any local changes not committed
|
||||
# - An indicator of the number of stashed items, if any.
|
||||
_git_info() {
|
||||
# Don't write anything if we're not in a folder tracked by git.
|
||||
if ! [ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" == "true" ]
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
# Local copies of the colours for this function.
|
||||
local fg_red=$(tput setaf 1)
|
||||
local fg_green=$(tput setaf 2)
|
||||
local fg_yellow=$(tput setaf 3)
|
||||
local start_underline=$(tput smul)
|
||||
local stop_underline=$(tput rmul)
|
||||
local reset=$(tput sgr0)
|
||||
# Git details.
|
||||
local git_branch_name="$(git branch --show-current)"
|
||||
local git_any_local_changes="$(git status --porcelain=v1 2>/dev/null)"
|
||||
local git_stash_count="$(git rev-list --walk-reflogs --count \
|
||||
refs/stash -- 2>/dev/null)" # Ignore error when no stashes
|
||||
local git_info=""
|
||||
if [ "${git_branch_name}" = "main" ]; then
|
||||
git_info="${fg_green}${start_underline}${git_branch_name}${reset}"
|
||||
else
|
||||
git_info="${fg_green}${git_branch_name}${reset}"
|
||||
fi
|
||||
if ! [ -z "${git_any_local_changes}" ]; then
|
||||
# Note that we have to be careful to put the exclamation mark
|
||||
# in single quotes so that it is not expanded to the last command!
|
||||
git_info="${git_info} ${fg_red}"'!'"${reset}"
|
||||
fi
|
||||
if [ "${git_stash_count:-0}" -gt 0 ]; then
|
||||
git_info="${git_info} ${fg_yellow}${git_stash_count} in stash${reset}"
|
||||
fi
|
||||
printf "${git_info}"
|
||||
}
|
||||
|
||||
# Show the pwd, limited to a certain number of folders.
|
||||
_pwd_max_folders() {
|
||||
local max_folders="$1"
|
||||
# Write the PWD, replace the home path with a tilde, then cut out the last
|
||||
# of the directories, up to the max folders value.
|
||||
echo "${PWD/#$HOME/~}" | rev | cut -d'/' -f1-${max_folders} | rev
|
||||
}
|
||||
|
||||
# Convert a Bash PS1 string to a ZSH PS1 string.
|
||||
_to_zsh() {
|
||||
# Note that the following sequences are not supported as they don't have
|
||||
# an Z-Shell equivalent. Mappings have been worked out from this document:
|
||||
# https://zsh.sourceforge.io/Doc/Release/Prompt-Expansion.html#Prompt-Expansion
|
||||
#
|
||||
# \l the basename of the shell's terminal device name
|
||||
# \s the name of the shell, the basename of $0 (the portion following the final slash)
|
||||
# \T the current time in 12-hour HH:MM:SS format
|
||||
# \v the version of bash (e.g., 2.00)
|
||||
# \V the release of bash, version + patch level (e.g., 2.00.0)
|
||||
# \W the basename of the current working directory, with $HOME abbreviated with a tilde
|
||||
# \# the command number of this command
|
||||
|
||||
# Replace Bash special characters with Z-Shell special characters.
|
||||
# Before we echo out the PS1 value, we need to replace '\u' with '%n'. If we
|
||||
# don't do this here with shell parameter expansion, then 'echo' thinks '\u'
|
||||
# is the beginning of a unicode character. This took quite a while to work
|
||||
# out. I have left the replacement of '\u' to '%n' in the 'sed' call below
|
||||
# but it not needed as the shell expansion below handles it.
|
||||
# Note that before we replace '\$' with '%#', we replace '\$(' temporarily
|
||||
# to SHELL_EXPAND, otherwise things like '\$(_my_func)' would be transformed
|
||||
# to '%#(_my_func)', i.e. we need to replace the prompt special character
|
||||
# but not escaped shell functions.
|
||||
local zsh_ps1="$(echo ${1/\\u/%n} | sed \
|
||||
-e 's/\\\[/%{/g' \
|
||||
-e 's/\\\]/%}/g' \
|
||||
-e 's/\\\d/%w/g' \
|
||||
-e 's/\\\D/%D/g' \
|
||||
-e 's/\\\u/%n/g' \
|
||||
-e 's/\\\h/%m/g' \
|
||||
-e 's/\\\H/%M/g' \
|
||||
-e 's/\\\j/%j/g' \
|
||||
-e 's/\\\t/%*/g' \
|
||||
-e 's/\\\A/%T/g' \
|
||||
-e 's/\\\@/%@/g' \
|
||||
-e 's/\\\w/%~/g' \
|
||||
-e 's/\\\!/%!/g' \
|
||||
-e 's/\\\$(/SHELL_EXPAND/g' \
|
||||
-e 's/\\\$/%#/g' \
|
||||
-e 's/SHELL_EXPAND/\\\$(/g' \
|
||||
)"
|
||||
|
||||
# Print the sequence. Note that we need to escape the % symbol.
|
||||
local zsh_ps1_escaped=$(echo "${zsh_ps1}" | sed 's/%/%%/g')
|
||||
printf "${zsh_ps1_escaped}"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Show the top "n" values of a set (first number is the "n" to get)
|
||||
show_top() {
|
||||
local n=$1
|
||||
local values=${@:2:n}
|
||||
echo "Top ${n} values: ${values}"
|
||||
}
|
||||
|
||||
|
||||
# This version uses shift to get the same result
|
||||
show_top2 () {
|
||||
# Grab the number of values to show, then shift.
|
||||
local n=$1
|
||||
shift
|
||||
|
||||
# Get the set of vaules to show
|
||||
local values=${@:1:n}
|
||||
echo "Top ${n} values: ${values}"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
CREATE EXTENSION IF NOT EXISTS ltree;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "ProgressType" AS ENUM (
|
||||
'PAGES',
|
||||
'PERCENTAGE',
|
||||
'SECONDS'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "BookFormat" AS ENUM (
|
||||
'HARDCOVER',
|
||||
'TRADE_PAPERBACK',
|
||||
'MASS_MARKET_PAPERBACK',
|
||||
'EBOOK',
|
||||
'AUDIOBOOK'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "ReadingStatus" AS ENUM (
|
||||
'WANT_TO_READ',
|
||||
'CURRENTLY_READING',
|
||||
'READ',
|
||||
'DNF',
|
||||
'PAUSED'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "TierType" AS ENUM (
|
||||
'FREE',
|
||||
'NOADS',
|
||||
'ANALYTICS_PLUS',
|
||||
'PREMIUM'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "UserRole" AS ENUM (
|
||||
'USER',
|
||||
'AGENT',
|
||||
'AUTHOR',
|
||||
'MODERATOR',
|
||||
'EDITOR',
|
||||
'PUBLISHER',
|
||||
'ADMIN'
|
||||
);
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
display_name TEXT,
|
||||
role "UserRole" DEFAULT 'USER'::"UserRole",
|
||||
tier "TierType" DEFAULT 'FREE'::"TierType",
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
is_enabled BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS publishers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
website TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS books (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
isbn_13 VARCHAR(13) UNIQUE,
|
||||
format "BookFormat" NOT NULL,
|
||||
published_year INT,
|
||||
cover_image_url TEXT,
|
||||
total_pages INT,
|
||||
total_audio_seconds INT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS authors (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID,
|
||||
name TEXT NOT NULL,
|
||||
bio TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS author_agents (
|
||||
agent_id UUID NOT NULL,
|
||||
author_id UUID NOT NULL,
|
||||
PRIMARY KEY (agent_id, author_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS book_authors (
|
||||
book_id UUID REFERENCES books(id) ON DELETE CASCADE,
|
||||
author_id UUID REFERENCES authors(id) ON DELETE CASCADE,
|
||||
author_order INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (book_id, author_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS book_publishers (
|
||||
book_id UUID REFERENCES books(id) ON DELETE CASCADE,
|
||||
publisher_id UUID REFERENCES publishers(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (book_id, publisher_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS author_publishers (
|
||||
publisher_id UUID NOT NULL,
|
||||
author_id UUID NOT NULL,
|
||||
PRIMARY KEY (publisher_id, author_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_publishers (
|
||||
publisher_id UUID NOT NULL,
|
||||
user_id UUID NOT NULL,
|
||||
PRIMARY KEY (publisher_id, user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_books (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||
book_id UUID REFERENCES books(id) ON DELETE CASCADE NOT NULL,
|
||||
status "ReadingStatus" NOT NULL,
|
||||
is_favorite BOOLEAN DEFAULT FALSE,
|
||||
dnf_reason TEXT, -- Nullable, used only if status is 'DNF'
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (user_id, book_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reading_sessions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_book_id UUID REFERENCES user_books(id) ON DELETE CASCADE NOT NULL,
|
||||
progress_type "ProgressType" NOT NULL, -- 'PAGES', 'PERCENTAGE', 'SECONDS'
|
||||
session_start INT NOT NULL DEFAULT 0,
|
||||
session_end INT NOT NULL,
|
||||
total_progress INT NOT NULL,
|
||||
notes TEXT,
|
||||
logged_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reviews (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||
book_id UUID REFERENCES books(id) ON DELETE CASCADE NOT NULL,
|
||||
overall_rating NUMERIC(3,2) CHECK (overall_rating >= 0 AND overall_rating <= 5.00), -- Allows 4.25, 4.5
|
||||
pacing_rating NUMERIC(3,2) CHECK (pacing_rating >= 0 AND pacing_rating <= 5.00), -- Multi-dimensional
|
||||
prose_rating NUMERIC(3,2) CHECK (prose_rating >= 0 AND prose_rating <= 5.00),
|
||||
character_rating NUMERIC(3,2) CHECK (character_rating >= 0 AND character_rating <= 5.00),
|
||||
review_text TEXT,
|
||||
is_spoiler BOOLEAN DEFAULT FALSE,
|
||||
spoiler_cutoff_progress INT, -- Hides review if reader hasn't reached this page/percentage
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (user_id, book_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS shelves (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
path ltree NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS book_shelves (
|
||||
book_id UUID REFERENCES user_books(id),
|
||||
shelf_id UUID NOT NULL REFERENCES shelves(id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (book_id, shelf_id)
|
||||
);
|
||||
|
||||
-- Database Performance Indexes
|
||||
CREATE INDEX idx_user_books_user_status ON user_books(user_id, status);
|
||||
CREATE INDEX idx_books_isbn ON books(isbn_13);
|
||||
CREATE INDEX idx_reviews_book_rating ON reviews(book_id, overall_rating);
|
||||
CREATE INDEX idx_shelves_path_gist ON shelves USING gist (path);
|
||||
CREATE UNIQUE INDEX idx_user_shelf_path ON shelves (user_id, path);
|
||||
|
||||
GRANT usage ON SCHEMA public TO tomes_user;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO tomes_user;
|
||||
@@ -0,0 +1,5 @@
|
||||
DROP TABLE author_agents, author_publishers, book_authors, book_shelves,
|
||||
shelves, authors, publishers, user_publishers, reading_sessions,
|
||||
reviews, shelves, user_books, books, users;
|
||||
|
||||
DROP TYPE "BookFormat", "ProgressType", "ReadingStatus", "TierType", "UserRole";
|
||||
@@ -0,0 +1,45 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict fXlKByDlYAidtT90ZdDHF56j3Ix7FrPcpjSCCvaSCa7HbxnN2SQaXsBjzcdek1q
|
||||
|
||||
-- Dumped from database version 18.4 (Ubuntu 18.4-0ubuntu0.26.04.1)
|
||||
-- Dumped by pg_dump version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: authors; Type: TABLE DATA; Schema: public; Owner: chris
|
||||
--
|
||||
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('89b1198a-6ad8-4039-942e-970ddb61514c', NULL, 'James Patterson', NULL, '2026-08-02 18:15:11.519+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('de9700a3-bb7d-4616-92eb-2918bc74072e', NULL, 'Michael Connelly', NULL, '2026-08-02 18:15:11.522+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('352a696c-3dc6-4307-876e-327edf719119', NULL, 'Brian Sitts', NULL, '2026-08-02 18:15:11.523+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('5172620d-45dc-4c24-9829-512e2c900fd7', NULL, 'Tom Clancy', NULL, '2026-08-02 18:15:11.524+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('f4c56ec1-6ff4-483c-8eeb-44f391af2e57', NULL, 'M. P. Woodward', NULL, '2026-08-02 18:15:11.525+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('3411c148-3bb1-4cb0-9059-154ca6609ff2', NULL, 'Jason Myers', NULL, '2026-08-02 18:15:11.527+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('b48480b0-ea05-4223-b3c3-0d1d4101b3b4', NULL, 'Rick Copeland', NULL, '2026-08-02 18:15:11.528+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('4c89babf-b1a2-40f4-996a-9f3853438544', NULL, 'Stan Sakai', NULL, '2026-08-02 18:15:11.529+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('9e3f1e0c-87b9-45d3-ab0e-3130c5d7b1a9', NULL, 'Stephen King', NULL, '2026-08-02 18:15:11.53+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('53ff5686-3b85-4719-b4f0-edce9325cd04', NULL, 'Dean Koontz', NULL, '2026-08-02 18:15:11.531+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('e4e3c5f7-9eb8-4e3d-9f27-35650c48f04b', NULL, 'Mark Greaney', NULL, '2026-08-02 18:15:11.532+00');
|
||||
INSERT INTO public.authors (id, user_id, name, bio, created_at) VALUES ('053d7dca-2e77-47a7-a316-a34c4090e4e0', NULL, 'James Joyce', NULL, '2026-08-10 16:53:43.249504+00');
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict fXlKByDlYAidtT90ZdDHF56j3Ix7FrPcpjSCCvaSCa7HbxnN2SQaXsBjzcdek1q
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict Ureq9Zr3sxHwBT50DepdrW70MZeA905r7amJN992A5Vy4Z7bxuljU23Ll8ow7rW
|
||||
|
||||
-- Dumped from database version 18.4 (Ubuntu 18.4-0ubuntu0.26.04.1)
|
||||
-- Dumped by pg_dump version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: book_authors; Type: TABLE DATA; Schema: public; Owner: chris
|
||||
--
|
||||
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('e9a145ac-5167-4db6-a35e-fcc34010c844', '89b1198a-6ad8-4039-942e-970ddb61514c', 0);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('5cce3730-38e2-41f8-921a-b4139b644e3b', '89b1198a-6ad8-4039-942e-970ddb61514c', 1);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('5cce3730-38e2-41f8-921a-b4139b644e3b', '352a696c-3dc6-4307-876e-327edf719119', 2);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('8959975c-4f19-46ca-818e-8841e7814637', 'de9700a3-bb7d-4616-92eb-2918bc74072e', 0);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('674e5751-a7fe-4b0e-910c-fcb348b81ab7', '5172620d-45dc-4c24-9829-512e2c900fd7', 1);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('674e5751-a7fe-4b0e-910c-fcb348b81ab7', 'f4c56ec1-6ff4-483c-8eeb-44f391af2e57', 2);
|
||||
INSERT INTO public.book_authors (book_id, author_id, author_order) VALUES ('f1f8fe28-4217-4e35-a577-853ebc5d65b9', '053d7dca-2e77-47a7-a316-a34c4090e4e0', 0);
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict Ureq9Zr3sxHwBT50DepdrW70MZeA905r7amJN992A5Vy4Z7bxuljU23Ll8ow7rW
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
INSERT INTO public.book_publishers (book_id, publisher_id) VALUES ('e9a145ac-5167-4db6-a35e-fcc34010c844', 'eaf00b0f-b12b-4bde-8ee4-d9f320001884');
|
||||
INSERT INTO public.book_publishers (book_id, publisher_id) VALUES ('5cce3730-38e2-41f8-921a-b4139b644e3b', '83109f47-8369-4ced-9f6e-761d8c3eceb4');
|
||||
INSERT INTO public.book_publishers (book_id, publisher_id) VALUES ('8959975c-4f19-46ca-818e-8841e7814637', '83109f47-8369-4ced-9f6e-761d8c3eceb4');
|
||||
INSERT INTO public.book_publishers (book_id, publisher_id) VALUES ('f1f8fe28-4217-4e35-a577-853ebc5d65b9', 'aa69017d-b8ef-43cd-98f9-e092923f56d2');
|
||||
INSERT INTO public.book_publishers (book_id, publisher_id) VALUES ('674e5751-a7fe-4b0e-910c-fcb348b81ab7', '68fe8a8b-4dbd-4cea-a20f-11d98d3e2406');
|
||||
@@ -0,0 +1,38 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict WW5eMeJxZE5yJ8tp2dNtUPBiQcTN2c493qw0JRhxbL3tJVqqMEbYUyfOoVJG9Nd
|
||||
|
||||
-- Dumped from database version 18.4 (Ubuntu 18.4-0ubuntu0.26.04.1)
|
||||
-- Dumped by pg_dump version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: books; Type: TABLE DATA; Schema: public; Owner: chris
|
||||
--
|
||||
|
||||
INSERT INTO public.books (id, title, description, isbn_13, format, published_year, cover_image_url, total_pages, total_audio_seconds, created_at) VALUES ('e9a145ac-5167-4db6-a35e-fcc34010c844', 'Along Came A Spider', NULL, '9781455523566', 'MASS_MARKET_PAPERBACK', 2018, NULL, 459, NULL, '2026-08-10 16:50:19.991047+00');
|
||||
INSERT INTO public.books (id, title, description, isbn_13, format, published_year, cover_image_url, total_pages, total_audio_seconds, created_at) VALUES ('5cce3730-38e2-41f8-921a-b4139b644e3b', 'Holmes, Marple & Poe', NULL, '9781538710784', 'TRADE_PAPERBACK', 2024, NULL, 355, NULL, '2026-08-10 16:50:19.997354+00');
|
||||
INSERT INTO public.books (id, title, description, isbn_13, format, published_year, cover_image_url, total_pages, total_audio_seconds, created_at) VALUES ('8959975c-4f19-46ca-818e-8841e7814637', 'Nightshade', NULL, '9780316588485', 'HARDCOVER', 2025, NULL, 341, NULL, '2026-08-10 16:50:19.999223+00');
|
||||
INSERT INTO public.books (id, title, description, isbn_13, format, published_year, cover_image_url, total_pages, total_audio_seconds, created_at) VALUES ('f1f8fe28-4217-4e35-a577-853ebc5d65b9', 'Ulysses (Gabler Edition)', NULL, '9780394743127', 'TRADE_PAPERBACK', 1986, NULL, 688, NULL, '2026-08-10 16:50:20.001004+00');
|
||||
INSERT INTO public.books (id, title, description, isbn_13, format, published_year, cover_image_url, total_pages, total_audio_seconds, created_at) VALUES ('674e5751-a7fe-4b0e-910c-fcb348b81ab7', 'Tom Clancy Terminal Velocity', NULL, '9780593178032', 'HARDCOVER', 2025, NULL, 436, NULL, '2026-08-10 16:50:20.002142+00');
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict WW5eMeJxZE5yJ8tp2dNtUPBiQcTN2c493qw0JRhxbL3tJVqqMEbYUyfOoVJG9Nd
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict efVV0qggaXPBO9j0yQizZ69vZMTzIt5CSvL3S9b44aNGom4MWxUhA2LfPMrzJVD
|
||||
|
||||
-- Dumped from database version 18.4 (Ubuntu 18.4-0ubuntu0.26.04.1)
|
||||
-- Dumped by pg_dump version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: publishers; Type: TABLE DATA; Schema: public; Owner: chris
|
||||
--
|
||||
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('d064858f-1320-41c7-89ed-0e614a6b5275', 'HarperCollins', 'https://www.harpercollins.com/', '2026-08-10 14:35:54.165062+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('60479d8b-abcc-470e-9365-863cfdf07942', 'Penguin Random House', 'https://www.penguinrandomhouse.com/', '2026-08-10 14:35:54.166369+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('e39f16fd-4079-4e3c-9072-f4ad93333425', 'Macmillan Publishers', 'https://us.macmillan.com/', '2026-08-10 14:35:54.167056+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('bd270e3b-9126-44b7-91d2-a0112e9a3ecf', 'Scholastic Corporation', 'https://www.scholastic.com/home', '2026-08-10 14:35:54.167979+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('701ceb17-df36-4b60-88c5-688afc054412', 'Simon & Schuster', 'https://www.simonandschuster.com/', '2026-08-10 14:35:54.168658+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('7c5c52ff-ad1c-4470-8d3a-6d2303f44c2a', 'Bantam Publishing', 'https://www.bantampublishing.com/', '2026-08-10 14:35:54.169314+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('4e5412a7-1364-4838-a5c8-47fbe173cd75', 'Houghton Mifflin Harcourt', 'https://www.hmhco.com/', '2026-08-10 14:35:54.16996+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('8ff8e9d6-d1c2-4e4b-9c9a-2545e55fd4ed', 'McGraw-Hill Education', 'https://www.mheducation.com/', '2026-08-10 14:35:54.170612+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('855108e3-593b-4b2c-8eb5-43ef6835f20e', 'Pearson Education', 'https://www.pearson.com', '2026-08-10 14:35:54.171286+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('1c200f80-1316-447f-a739-66025f97184f', 'W. W. Norton & Company', 'https://wwnorton.com/', '2026-08-10 14:35:54.172011+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('83109f47-8369-4ced-9f6e-761d8c3eceb4', 'Little, Brown & Company', 'https://www.hachettebookgroup.com/imprint/little-brown-and-company/', '2026-08-10 14:35:54.172704+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('11707922-8879-455f-95c2-54cb7625a4ff', 'Kindle Direct Publishing', 'https://kdp.amazon.com/', '2026-08-10 14:35:54.173363+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('022421c9-b005-4344-99f2-8b1d2905d985', 'Barnes & Noble Press', 'https://press.barnesandnoble.com/', '2026-08-10 14:35:54.174033+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('96536c7e-ffed-4c1c-90ff-e08c32c03db4', 'Apple Books', 'https://www.apple.com/apple-books/', '2026-08-10 14:35:54.174679+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('a3dea549-d83a-49a9-951c-c3c7b114864d', 'Kobo', 'https://www.kobo.com/us/', '2026-08-10 14:35:54.175326+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('61ae9190-18c9-4a20-b55b-ba199d7e7275', 'Candlewick Press', 'https://www.candlewick.com/', '2026-08-10 14:35:54.17594+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('34d9ad56-c90c-44b2-9fae-db53bca9ea20', 'Chronicle Books', 'https://www.chroniclebooks.com/', '2026-08-10 14:35:54.176581+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('eaf00b0f-b12b-4bde-8ee4-d9f320001884', 'Grand Central Publishing', 'https://www.hachettebookgroup.com/imprint/grand-central-publishing/', '2026-08-10 14:35:54.177231+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('aa69017d-b8ef-43cd-98f9-e092923f56d2', 'Vintage', 'https://knopfdoubleday.com/imprint/vintage/', '2026-08-10 14:35:54.177893+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('68fe8a8b-4dbd-4cea-a20f-11d98d3e2406', 'G. P. Putnam''s Sons', 'https://www.penguin.com/putnam/', '2026-08-10 14:35:54.178535+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('f19a0067-763a-487b-accd-34dd26113004', 'Lagardère SA', 'https://www.lagardere.com/en/home/', '2026-08-10 14:35:54.17917+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('a49a6faf-f0ca-4c5c-afa7-59ef8cb656ce', 'Hachette Livre', 'https://www.hachette.com/', '2026-08-10 14:35:54.179806+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('32827e5b-bcf5-4e35-a230-ae3477eabcf5', 'Le Livre de Poche', 'https://www.livredepoche.com/', '2026-08-10 14:35:54.180399+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('041ccaa3-0f8e-4d3f-be8a-9768cc019d95', 'O''Reilly Media', 'https://www.oreilly.com/', '2026-08-10 14:35:54.181053+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('d7ff0668-5ef3-4729-ae9e-4db180f61eb4', 'Knopf Doubleday', 'https://knopfdoubleday.com/', '2026-08-10 14:37:33.982413+00');
|
||||
INSERT INTO public.publishers (id, name, website, created_at) VALUES ('3acf87c5-ffb3-4dc0-95b1-15f78d977111', 'Hachette Book Group', 'https://www.hachettebookgroup.com/', '2026-08-10 14:37:33.983517+00');
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict efVV0qggaXPBO9j0yQizZ69vZMTzIt5CSvL3S9b44aNGom4MWxUhA2LfPMrzJVD
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
\restrict qlbEiTLcs0n6OfMTYScKDUs7xlFe5bcBUt3DUt2BlNqvC9jTbGl08Uh5r9iJzrT
|
||||
|
||||
-- Dumped from database version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
-- Dumped by pg_dump version 18.4 (Ubuntu 18.4-1.pgdg24.04+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET transaction_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: tomes_user
|
||||
--
|
||||
|
||||
INSERT INTO public.users (id, email, username, display_name, role, tier, created_at, is_enabled) VALUES ('88c325e2-d1de-430f-b4a5-96c9c621845d', 'ole088@gmail.com', 'chris', 'Chris', 'ADMIN', 'PREMIUM', '2026-07-27 22:00:25.987', true);
|
||||
INSERT INTO public.users (id, email, username, display_name, role, tier, created_at, is_enabled) VALUES ('12e90f24-7d06-470e-a2c7-39319b981bcc', 'natashastales@gmail.com', 'natasha', 'Natasha', 'AUTHOR', 'PREMIUM', '2026-07-27 22:00:26.033', true);
|
||||
INSERT INTO public.users (id, email, username, display_name, role, tier, created_at, is_enabled) VALUES ('4a749c17-68cb-43e5-aad0-75cda6ca8734', 'chimaia6454@gmail.com', 'chiara', 'Chi Chi', 'USER', 'FREE', '2026-07-27 22:00:26.039', true);
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
\unrestrict qlbEiTLcs0n6OfMTYScKDUs7xlFe5bcBUt3DUt2BlNqvC9jTbGl08Uh5r9iJzrT
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Original sum function, only allows for two values
|
||||
orig_sum() {
|
||||
local value1=$1
|
||||
local value2=$2
|
||||
local result=$(( value1 + value2 ))
|
||||
echo "The sum of ${value1} and ${value2} is ${result}"
|
||||
}
|
||||
|
||||
# Improved sum function that allows as many as required
|
||||
sum() {
|
||||
local total=0
|
||||
for value in $@; do
|
||||
total=$(( total + value ))
|
||||
done
|
||||
|
||||
# Write the result
|
||||
echo "Summed $# values for a total of: ${total}"
|
||||
}
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Add color codes
|
||||
source ./ansi_colors.sh
|
||||
|
||||
message="This is a simple message"
|
||||
|
||||
echo -e "Foreground Red, Background White: ${FG_RED}${BG_WHITE}${message}${RESET}"
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Exit if any command fails and enable tracing
|
||||
set -ex
|
||||
|
||||
# Get today's date in the format YYYY-MM-DD
|
||||
today=$(date +"%Y-%m-%d")
|
||||
|
||||
# Create a path to today's temp folder and then make sure the folder exists
|
||||
temp_path="/tmp/${today}"
|
||||
mkdir -p "${temp_path}"
|
||||
|
||||
# Now make a symlink to the folder in your homedir
|
||||
ln -sf "${temp_path}" "${HOME}/today"
|
||||
|
||||
# Disable tracing
|
||||
set +x
|
||||
|
||||
# Write out the path you created
|
||||
echo "${temp_path}"
|
||||
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the online script to install WinApps in the current user profile
|
||||
bash <(curl https://raw.githubusercontent.com/winapps-org/winapps/main/setup.sh)
|
||||
|
||||
Reference in new issue
Block a user