diff --git a/README.md b/README.md index 4067f55..0869d63 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,17 @@ A simple todo list tool for people who live on the command-line By Jesse Laprade -## Todo +# New things added! + +Now default directory and file permissions are more private! `~/.rodo/` is now +set to 700 by default, and `~/.rodo/todo.txt` is set to 600 by default. + +# Todo -- [ ] Only allow quoted items to be added - [ ] Add color option to config.rkt file - [ ] Encrypt todo-list file -- [ ] Change default permissions of `~/.rodo` folder and `todo-list` file -- [ ] Add note on .bash_history about items being added here before going into the todo-list file +- [ ] Add note on .bash_history about items being added here before going into + the todo.txt file # Screenshot @@ -21,6 +25,8 @@ By Jesse Laprade * [Platforms](https://github.com/m455/rodo#platforms) * [Requirements](https://github.com/m455/rodo#requirements) * [Downloading](https://github.com/m455/rodo#downloading) + * [Option one: Via GitHub on a web browser](https://github.com/m455/rodo#option-one-via-github-on-a-web-browser) + * [Option two: Via Git](https://github.com/m455/rodo#option-two-via-git) * [Setup](https://github.com/m455/rodo#setup) * [GNU/Linux](https://github.com/m455/rodo#gnulinux) * [Usage](https://github.com/m455/rodo#usage) @@ -38,22 +44,34 @@ Below is a list of platform(s) that `rodo` is currently available for. Below is a list of items needed for running `rodo` on your machine. * [Racket 6.x](https://racket-lang.org/) -* [Git](https://git-scm.com/) (Optional method for downloading using `git clone`) +* [GNU coreutils](https://wiki.debian.org/coreutils)(`chmod` at least) # Downloading -Currently, there are two ways to download the source code. Please choose one: +Currently, there are two options for downloading the source code. Choose one from the +list below: -* Via GitHub on a web browser - 1. Click the *Clone or download* button at the top of this page - 2. Click *Download ZIP* from the drop-down list +## Option one: Via GitHub on a web browser -* Via Git - * Run `git clone https://github.com/m455/rodo` on the command line +Follow the steps below to download `rodo` from your web browser. + +1. Click the *Clone or download* button at the top of this page +2. Click *Download ZIP* from the drop-down list + +## Option two: Via Git + +Follow the steps below to download `rodo` using the `git` command. + +1. Ensure Git is installed +2. Run `git clone https://github.com/m455/rodo` on the command line # Setup -Follow the steps below to set up `rodo` on your platform, if available. +Follow the sections below to set up `rodo`, so it can be used from anywhere on +your system. + +**If you just want to test it out, just run `cd` into the downloaded +directory and run `./rodo.rkt`.** ## GNU/Linux @@ -61,8 +79,9 @@ Follow the steps below to add `rodo` to your `$PATH`. ### Set up a `$PATH` -Follow the steps below if you haven't set up a `$PATH`. If you have set up a `$PATH` already, -then skip to the next step, [Adding `rodo` to your `$PATH`](https://github.com/m455/rodo#adding-rodo-to-your-path). +Follow the steps below if you haven't set up a `$PATH`. If you have set up a +`$PATH` already, then skip to the next step, [Adding `rodo` to your +`$PATH`](https://github.com/m455/rodo#adding-rodo-to-your-path). 1. Create a directory for your `$PATH` by running `mkdir ~/bin/` 2. Add your newly-created `~/bin/` to your `$PATH` by running `echo "export PATH=~/bin:\$PATH" >> .bashrc` @@ -78,48 +97,54 @@ Follow the steps below if you have set up your `$PATH`. racket ~/path/to/rodo.rkt "$@" ``` -Note: If you downloaded the project to your `~/downloads/` folder you would change the line +For example: If you downloaded the project to your `~/downloads/` folder you would change the line `racket ~/path/to/rodo.rkt "$@"` to `racket ~/downloads/rodo/rodo.rkt "$@"`. 2. Save the file 3. Make the file executable by running `chmod u+x ~/bin/name-of-your-file` -If you prefer to use an executable, rather than a wrapper, -you can create an executable binary file with `raco exe rodo.rkt` when in the same -folder as the `rodo.rkt` file. If you are having trouble with this please refer to Racket's documentation -regarding the [creation of standalone executables](https://docs.racket-lang.org/raco/exe.html). +If you prefer to use an executable, rather than a wrapper, you can create an +executable binary file with `raco exe rodo.rkt` when in the same folder as the +`rodo.rkt` file. If you are having trouble with this please refer to Racket's +documentation regarding the [creation of standalone executables](https://docs.racket-lang.org/raco/exe.html). # Usage -Type `rodo` plus one of the options below with a space -between `rodo` and the option. +Type `rodo` plus one of the commands below with a space +between `rodo` and the command. -`init` - Initializes a file called `todo-list` in `~/.rodo/` by default +`init` - Initializes a file called `todo.txt` in `~/.rodo/` by default (The +directory and filename can be changed by modifying the `config.rkt` file) -`ls` - Lists items from the list +`ls` - Displays items from the todo list in a vertical format -`add` - Adds an entry to the list +`add` - Adds an entry to the todo list -`rm` - Removes an item from the list +`rm` - Removes an item from the todo list -**Note:** You may have to run `rodo ls` to see which number corresponds to which item when removing items. +Note: You may have to run `rodo ls` to see which number corresponds to which item when removing items. ## Usage examples -The examples below assume that you have `rodo` [set up](https://github.com/m455/rodo#set-up-a-path) in your `$PATH` +The examples below assume that you have `rodo` [set up in your `$PATH`](https://github.com/m455/rodo#set-up-a-path) in your `$PATH` `rodo init` `rodo ls` -`rodo add bread` (Single-word entry) (**Soon the use of unquoted items will be depreciated**) +`rodo add "go to the park"` -`rodo add "go to the bank"` (Multi-word entry) +Note: If you leave out the double quotation marks here, only the first word +will be added. In the example above, only "go" would be added to the list. `rodo rm 1` # Configuring `rodo` -Right now, the configurations can be found in the `config.rkt file`. Settings, such as program name, path, and directory can be changed. +Caution: Change the `config.rkt` file at your own risk, as it may break things! + +Right now, the configurations can be found in the `config.rkt file`. Settings, +such as the program name, directory, and the filename of the todo list file can +be changed. diff --git a/config.rkt b/config.rkt index ffd0ceb..c5a04e3 100644 --- a/config.rkt +++ b/config.rkt @@ -2,17 +2,15 @@ (provide (all-defined-out)) (define program-name "rodo") -(define program-directory ".rodo/") -(define program-path "~/") -(define program-file "todo-list") +(define program-directory "~/.rodo/") +(define program-file "todo.txt") (define remove-command "rm") (define add-command "add") (define list-command "ls") (define initialize-command "init") (define help-command '("-h" "--help")) -(define path +(define path (expand-user-path (string-append - program-path program-directory program-file))) diff --git a/init.rkt b/init.rkt index d7d9b2e..6cc1d59 100644 --- a/init.rkt +++ b/init.rkt @@ -14,12 +14,11 @@ ([user-input (read-line)]) (cond [(member user-input (hash-ref messages:y/n 'yes)) - (util:display-hash-ref messages:messages 'creating-folder) - (util:display-hash-ref messages:messages 'creating-file) - (util:create-folder) + (util:display-hash-ref messages:messages 'creating) + (util:create-directory) (util:create-file) (if (and - (util:check-for-folder) + (util:check-for-directory) (util:check-for-file)) (util:display-hash-ref messages:messages 'successfully-created) (util:display-hash-ref messages:messages 'creation-error))] diff --git a/messages.rkt b/messages.rkt index e4647b5..993097a 100644 --- a/messages.rkt +++ b/messages.rkt @@ -6,140 +6,120 @@ (define messages (hash - 'show-help (string-append - config:initialize-command - " - " - "initialize a file in " - config:program-path - config:program-directory - config:program-file - "\n" - "Example: " - "rodo init\n\n" + 'show-help (string-append + "Usage:" + "\n" + "rodo [optional argument]\n" + "\n" - config:list-command ":\n" - "lists items on the list" - "\n" - "Example: " - "rodo ls\n\n" + config:initialize-command ":\n" + "Initialize a file in " + config:program-directory + config:program-file "\n" - config:add-command ":\n" - "adds an item to the list" - "\n" - "Example: " - "rodo add bread\n\n" - "Note: For multi-word items you will need to\n" - "surround your item in double quotes as so:\n" - "rodo add \"go to the bank\"\n\n" + "Example: " + "rodo init\n" + "\n" - config:remove-command ":\n" - "removes an item from the list\n" - "Example: " - "rodo rm 1\n\n" - "Note: You may have to run `rodo ls` to see which\n" - "number corresponds to which item to remove it.\n") + config:list-command ":\n" + "Lists items on the list" + "\n" + "Example: " + "rodo ls\n" + "\n" - 'empty-todo-list - "> There is nothing in your list \n" + config:add-command ":\n" + "Adds an item to the list" + "\n" + "Example: " + "rodo add bread\n" + "\n" - 'show-usage - (string-append - "> For usage type " - "`" config:program-name " -h`" - " or " - "`" config:program-name " --help`\n") + "Note: For multi-word items you will need to\n" + "surround your item in double quotes as so:\n" + "rodo add \"go to the bank\"\n" + "\n" - 'creating-folder - (string-append - "> creating a " - config:program-directory - " folder in " - config:program-path "\n") + config:remove-command ":\n" + "Removes an item from the list\n" + "Example: " + "rodo rm 1\n" + "\n" - 'creating-file - (string-append - "> creating a " - config:program-file - " file in " - config:program-path - config:program-directory "\n") + "Note: You may have to use the ls command to see\n" + "which number corresponds to which item\n") - 'creation-error - (string-append - "> Error: Could not create " - config:program-file - " in " - config:program-directory - config:program-path ".\n" - "> This may be due to directory permissions\n") + 'empty-todo-list "> There is nothing in your list \n" - 'file-already-exists - (string-append - "> Error: " - config:program-name - " already exists in " - config:program-path - config:program-directory - config:program-file "\n") + 'show-usage (string-append + "> For usage type " + "`" config:program-name " -h`" + " or " + "`" config:program-name " --help`\n") - 'successfully-created - (string-append - "> " - config:program-path - config:program-directory - config:program-file - " has been successfully created\n") + 'creating (string-append + "> Creating " + config:program-file + " file in " + config:program-directory "\n") - 'file-not-found - (string-append - "> Error: Could not find " - config:program-path - config:program-directory - config:program-file "\n") + 'creation-error (string-append + "> Error: Could not create " + config:program-file + " in " + config:program-directory + ".\n" + "> This may be due to directory permissions\n") - 'init-y/n - (string-append - "> A " - config:program-file - " file will be created in " - config:program-path - config:program-directory "\n" - "> Are you sure you want to continue? [y/n]\n") + 'file-already-exists (string-append + "> Error: " + config:program-name + " already exists in " + config:program-directory + config:program-file "\n") - 'try-init - (string-append - "> Try typing " - "`" config:program-name " init` " - "to set it up\n") + 'successfully-created (string-append + "> " + config:program-directory + config:program-file + " has been successfully created\n") - 'terminating - (string-append - "> Exiting " - config:program-name - "\n") + 'file-not-found (string-append + "> Error: Could not find " + config:program-directory + config:program-file "\n") - 'choose-y/n - "> Error: Please choose y or n\n" + 'init-y/n (string-append + "> A " + config:program-file + " file will be created in the directory " + config:program-directory "\n" + "> Are you sure you want to continue? [y/n]\n") - 'not-in-list - "> Error: Item does not exist\n" + 'try-init (string-append + "> Try typing " + "`" config:program-name " init` " + "to set it up\n") - 'item-added-prefix - "> Added " + 'terminating (string-append + "> Exiting " + config:program-name + "\n") - 'item-added-suffix - " to list\n" + 'choose-y/n "> Error: Please choose y or n\n" - 'item-removed-prefix - "> Removed " + 'not-in-list "> Error: Item does not exist\n" - 'item-removed-suffix - " from list\n")) + 'item-added-prefix "> Added " + + 'item-added-suffix " to list\n" + + 'item-removed-prefix "> Removed " + + 'item-removed-suffix " from list\n")) (define y/n (hash - 'yes - '("yes" "Yes" "y" "Y") + 'yes '("yes" "Yes" "y" "Y") - 'no - '("no" "No" "n" "N"))) + 'no '("no" "No" "n" "N"))) diff --git a/util.rkt b/util.rkt index 0adaf7f..2176e1b 100644 --- a/util.rkt +++ b/util.rkt @@ -3,38 +3,46 @@ (require (prefix-in list: racket/list) (prefix-in file: racket/file) (prefix-in string: racket/string) + (prefix-in system: racket/system) (prefix-in config: "config.rkt") (prefix-in messages: "messages.rkt")) (provide (all-defined-out)) +(define (set-permissions permissions file-or-directory) + (let* ([converted-permissions (number->string permissions)] + [converted-file-or-directory + (cond [(path? file-or-directory) (path->string file-or-directory)] + [else file-or-directory])]) + (system:system + (string-append "chmod" " " converted-permissions " " converted-file-or-directory)))) + (define (check-for-file) (file-exists? config:path)) (define (create-file) (let ([opened-file - (open-output-file config:path - #:mode 'text - #:exists 'can-update)]) - (close-output-port opened-file))) + (open-output-file config:path + #:mode 'text + #:exists 'can-update)]) + (close-output-port opened-file)) + (set-permissions 600 config:path)) -(define (check-for-folder) +(define (check-for-directory) (directory-exists? (expand-user-path - (string-append - config:program-path - config:program-directory)))) + (string-append + config:program-directory)))) -(define (create-folder) +(define (create-directory) (make-directory (expand-user-path - (string-append - config:program-path - config:program-directory)))) + (string-append + config:program-directory))) + (set-permissions 700 config:program-directory)) (define (display-hash-ref hash-list key) (display (hash-ref hash-list key))) -;; Just so I don't have to keep typing -;; "#:mode...#:line-mode..." every time +;; Just so I don't have to keep typing "#:mode...#:line-mode..." every time (define (file->string-list config:path-to-file) (let ([todo-list (file:file->lines config:path-to-file #:mode 'text @@ -69,10 +77,10 @@ (define (display-prettified-list) (display - (string:string-join - (prefix-with-number (file->string-list config:path)) - "\n" - #:after-last "\n"))) + (string:string-join + (prefix-with-number (file->string-list config:path)) + "\n" + #:after-last "\n"))) ;; This is a bit of ugly scheme sorcery (define (append-to-end args lst) @@ -90,58 +98,58 @@ (define (show-list) (cond [(and - (check-for-folder) - (check-for-file)) + (check-for-directory) + (check-for-file)) (if - ;; If file exists, see if it's empty, if so - ;; tell the user - (list-empty? config:path) - (display-hash-ref messages:messages 'empty-todo-list) - ;; If file isn't empty, display a pretty list - (display-prettified-list))] + ;; If file exists, see if it's empty, if so + ;; tell the user + (list-empty? config:path) + (display-hash-ref messages:messages 'empty-todo-list) + ;; If file isn't empty, display a pretty list + (display-prettified-list))] ;; If file doesn't exist, tell the user [else - (display-hash-ref messages:messages 'file-not-found) - (display-hash-ref messages:messages 'try-init)])) + (display-hash-ref messages:messages 'file-not-found) + (display-hash-ref messages:messages 'try-init)])) (define (add-item-to-file args) ;; Add item to end of list and write to file (let ([new-list (append-to-end args config:path)]) (file:display-to-file - (string:string-join new-list "\n") - config:path - #:mode 'text - #:exists 'replace) + (string:string-join new-list "\n") + config:path + #:mode 'text + #:exists 'replace) (display-item-added args))) (define (add-item args) (if (and - (check-for-folder) - (check-for-file)) - (add-item-to-file (vector-ref args 1)) - (begin - (display-hash-ref messages:messages 'file-not-found) - (display-hash-ref messages:messages 'try-init)))) + (check-for-directory) + (check-for-file)) + (add-item-to-file (vector-ref args 1)) + (begin + (display-hash-ref messages:messages 'file-not-found) + (display-hash-ref messages:messages 'try-init)))) (define (remove-item-from-file args) (let* ([removed-item (get-removed-item config:path args)] [new-list (remove removed-item (file->string-list config:path))]) (file:display-to-file - (string:string-join new-list "\n") - config:path - #:mode 'text - #:exists 'replace) + (string:string-join new-list "\n") + config:path + #:mode 'text + #:exists 'replace) (display-item-removed removed-item))) (define (remove-item args) (cond [(list-empty? config:path) (display-hash-ref messages:messages 'empty-todo-list)] [(and - (check-for-folder) - (check-for-file)) + (check-for-directory) + (check-for-file)) (remove-item-from-file (vector-ref args 1))] - [(and (not (check-for-folder)) (not (check-for-file))) + [(and (not (check-for-directory)) (not (check-for-file))) (begin (display-hash-ref messages:messages 'file-not-found) (display-hash-ref messages:messages 'try-init))]))