Figuring out how Drafts REALLY works
On my way back from Arizona a few weeks ago I decided to play around with Drafts a bit. Now I use Drafts every day. When it went to a subscription model more than a year ago it was a no brainer for me. This is a seriously powerful app when you need it.
But since my initial workflows and shortcuts I've not really done too much with it. But after listening to some stuff from Tim Nahumck I decided I needed to invest a little time ... and honestly there's no better time than cruising at 25k feet on your way back from Phoenix.
Ok, first of all I never really understood workspaces. I had some set up but I didn't get it. That was the first place I started.
Each workspace can have its own action and keyboard shortcut thing which I didn't realize. This has so much potential. I can create workspaces for all sorts of things and have the keyboard shortcut things I need when I need them! This alone is mind blowing and I'm disappointed I didn't look into this feature sooner.
I have 4 workspaces set up:
- OF Templates
- O3
- Scrum
- post ideas
Initially since I didn't really understand the power of the workspace I had them mostly as filtering tools to be used when trying to find a draft. But now with the custom action and keyboards for each workspace I have them set up to filter down to specific tags AND use their own keyboards.
The OF Template workspace is used to create OmniFocus projects based on Taskpaper markup. There are a ton of different actions that I took from Rose Orchard (of Automators fame) that help to either add items with the correct syntax to a Task Paper markdown file OR turn the whole thing into an OmniFocus project. Simply a life saver for when I really know all of the steps that are going to be involved in a project and I want to write them all down!
The O3 workspace is used for processing the notes from the one-on-one I have with my team. There's really only two actions: Parse O3 notes and Add to O3 notes. How are these different? I have a Siri Shortcut that populates a Draft with a template that collects the name of the person and the date time that the O3 occurred. This is the note that is parsed by the first action. The second action is used when someone does something that I want to remember (either good or bad) so that I can bring it up at a more appropriate time (the best time to tell someone about a behavior is right now, but sometimes circumstances prevent that) so I have this little action.
In both cases they append data to a markdown file in Dropbox (i have one file per person that reports to me). The Shortcut also takes any actions that need to be completed and adds them to OmniFocus for me to review later.
The third workspace is Scrum. This workspace has just one action which is "Parse scrum notes". Again, I have a template that is generated from Siri Shortcuts and dropped into Drafts. During the morning standup meetings I have with my team this Draft will have the things I did yesterday, what I'm working on today, and any roadblocks that I have. It also create a section where I can add actions which when the draft is parsed goes into OmniFocus for me to review later (currently the items get added with a due date of today at 1pm ... but I need to revisit that).
The last workspace is post ideas (which is where I'm writing this from). Its custom keyboard is just a markdown one with quick ways to add markdown syntax and a Preview button so I can see what the markdown will render out as.
It's still a work in progress as this draft will end up in Ulysses so it can get posted to my site, but I've seen that I can even post from Drafts to Wordpress so I'm going to give that a shot later on.
There are several other ideas I have bouncing around in my head about ideas for potential workspaces. My only concern at this point is how many workspaces can I have before there are too many to be used effectively.
So glad I had the time on the flight to take a look at workspaces. A huge productivity boost for me!
Upgrading Python in a Virtual Environment
I have been wanting to use my Heroku account for a while with something a little more interesting than a Jupiter Notebook.
I was hoping to try and do something with Django … but there’s a lot to using Django. I have some interesting things I’m doing on my local machine, but it’s not quite ready yet.
I had googled to find other Python Web frameworks and saw that Bottle was an even more light weight framework than Flask, so I thought, hey, maybe I can do something with that.
I found this tutorial on how to do something relatively simple with Bottle and deploying to Heroku. Just what I wanted!
I got through to the end of the tutorial and deployed to Heroku. The terminal output from the Heroku command indicated that a newer version of Python (3.7.3) was available than the one I was on (3.7.1).
I figured it would be easy enough to upgrade to the newest version of Python on my Mac because I had done it before.
I don’t know why I thought the virtual environment would be different than the local install of Python 3 but it turns out they are more tightly coupled than I thought.
Upgrading to 3.7.3 broke the virtual environment I had in PyCharm. I did a bit a googling to see how to upgrade a virtual environment and found nothing. Like literally nothing.
It was ... disheartening. But after a good night’s sleep I had a thought! What if I just delete the virtual environment directory and then recreated it.
I ran this command to remove the virtual environment:
rm -R venv
Then created a virtual environment in PyCharm and now I have 3.7.3 in my virtual environment.
I had to make some changes to the files for deployment to Heroku, but that’s all covered in the tutorial mentioned above.
Sometimes the answer is to just restart it … and sometimes the answer is delete it and start over.
Update¶
I was listening to an episode of Python Bytes and heard Michael Kennedy (of Talk Python to Me fame) describing basically the same issue I had. Turns out, he solved it the same way I did. Nice to know i’m In good company.
Creating Hastags for Social Media with a Drafts Action
Creating meaningful, long #hastags can be a pain in the butt.
There you are, writing up a witty tweet or making that perfect caption for your instagram pic and you realize that you have a fantastic idea for a hash tag that is more of a sentence than a single word.
You proceed to write it out and unleash your masterpiece to the world and just as you hit the submit button you notice that you have a typo, or the wrong spelling of a word and #ohcrap you need to delete and retweet!
That lead me to write a Drafts Action to take care of that.
I’ll leave others to write about the virtues of Drafts, but it’s fantastic.
The Action I created has two steps: (1) to run some JavaScript and (2) to copy the contents of the draft to the Clipboard. You can get my action here.
Here’s the JavaScript that I used to take a big long sentence and turn it into a social media worthy hashtag
var contents = draft.content;
var newContents = "#";
editor.setText(newContents+contents.replace(/ /g, "").toLowerCase());
Super simple, but holy crap does it help!
Making it easy to ssh into a remote server: Addendum
I recently got a new raspberry pi (yes, I might have a problem) and wanted to be able to ssh into it without having to remember the IP or password. Luckily I wrote this helpful post several months ago.
While it go me most of the way there, I did run into a slight issue.
First Issue¶
The issue was that I had a typo for the command to generate a key. I had:
ssh-keyken -t rsa
Which should have been:
ssh-keygen -t rsa
When I copied and pasted the original command the terminal said there was no such command. 🤦♂️
Second Issue¶
Once that go cleared up I went through the steps and was able to get everything set up. Or so I thought. On attempting to ssh into my new pi I was greeted with a password prompt. WTF?
The first thing I did was to check to see what keys were in my \~/.ssh folder. Sure enough there were a couple of them in there.
ls ~/.ssh
id_rsa id_rsa.github id_rsa.github.pub id_rsa.pub known_hosts read_only_key read_only_key.pub
Next, I interrogated the help command for ssh-copy-id to see what flags were available.
Usage: /usr/bin/ssh-copy-id [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname
-f: force mode -- copy keys without trying to check if they are already installed
-n: dry run -- no keys are actually copied
-h|-?: print this help
I figured let’s try the -n flag and get the output from that. Doing so gave me
ryan@Ryans-MBP:~/Desktop$ ssh-copy-id -n pi@newpi
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/ryan/.ssh/id_rsa.github.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
(if you think this is a mistake, you may want to use -f option)
OK … why is it sending the GitHub key? That’s a different problem for a different time. I see another flag available is the -i which will allow me to specify which key I want to send. Aha!
OK, now all that I need to do is use the following command to test the output:
ssh-copy-id -n -i ~/.ssh/id_rsa.pub pi@newpi
And sure enough it’s sending the correct key
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/ryan/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
(if you think this is a mistake, you may want to use -f option)
Remove the -n flag to send it for real
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@newpi
And try to ssh in again
ssh pi@newpi
Success!
I wanted to write this up for 2 reasons:
- So I can refer back to it if I ever need to. This blog is mostly for me to write down technical things that I do so I can remember them later on
- This is the first time I’ve run into an issue with a command like tool and simply used the help to figure out how to fix the problem and I wanted to memorialize that. It felt forking awesome to do that.
Footnote: Yes … calling my new raspberry pi newpi in my hosts file is dumb. Yes, when I get my next new Raspberry Pi I will be wondering what to call it. YEs, I am going to try and remember to make the change before it happens so that I don’t end up with the next Pi being called newnewpi and the one after that being newnewnewpi
Receipts
Every month I set up a budget for my family so that we can track our spending and save money in the ways that we need to while still being able to enjoy life.
I have a couple of Siri Shortcuts that will take a picture and then put that picture into a folder in Dropbox. The reason that I have a couple of them is that one is for physical receipts that we got at a store and the other is for online purchases. I’m sure that these couple be combined into one, but I haven’t done that yet.
One of the great things about these shortcuts is that they will create the folder that the image will go into if it’s not there. For example, the first receipt of March 2019 will create a folder called March in the 2019 folder. If the 2019 folder wasn’t there, it would have created it too.
What it doesn’t do is create the sub folder that all of my processed receipts will go into. Each month I need to create a folder called month_name Processed. And each month I think, there must be a way I can automate this, but because it doesn’t really take that long I’ve never really done it.
Over the weekend I finally had the time to try and write it up and test it out. Nothing too fancy, but it does what I want it to do, and a little more.
# create the variables I'm going to need later
y=$( date +"%Y" )
m=$( date +"%B" )
p=$( date +"%B_Processed" )
# check to see if the Year folder exists and if it doesn't, create it
if [ ! -d /Users/ryan/Dropbox/Family/Financials/$y ]; then
mkdir /Users/ryan/Dropbox/Family/Financials/$y
fi
# check to see if the Month folder exists and if it doesn't, create it
if [ ! -d /Users/ryan/Dropbox/Family/Financials/$y/$m ]; then
mkdir /Users/ryan/Dropbox/Family/Financials/$y/$m
fi
#check to see if the Month_Processed folder exists and if it doesn't, create it
if [ ! -d "/Users/ryan/Dropbox/Family/Financials/$y/$m/$p" ]; then
mkdir "/Users/ryan/Dropbox/Family/Financials/$y/$m/$p"
fi
The last section I use the double quotes “” around the directory name so that I can have a space in the name of the processed folder. Initially I had used an underscore but that’s not how I do it in real life when creating the sub directors, so I had to do a bit of googling and found a helpful resource.
The only thing left to do at this point is get it set up to run automatically so I don’t have to do anything.
In order to do that I needed to add the following to my cronjob:
0 5 1 * * /Users/ryan/Documents/scripts/create_monthly_expense_folders.sh
And now I will have my folder structure created for me automatically on the first of the month at 5am!
Keeping Python up to date on macOS
Sometimes the internet is a horrible, awful, ugly thing. And then other times, it’s exactly what you need.
I have 2 Raspberry Pi each with different versions of Python. One running python 3.4.2 and the other running Python 3.5.3. I have previously tried to upgrade the version of the Pi running 3.5.3 to a more recent version (in this case 3.6.1) and read 10s of articles on how to do it. It did not go well. Parts seemed to have worked, while others didn’t. I have 3.6.1 installed, but in order to run it I have to issue the command python3.6 which is fine but not really what I was looking for.
For whatever reason, although I do nearly all of my Python development on my Mac, it hadn’t occurred to me to upgrade Python there until last night.
With a simple Google search the first result came to Stackoverflow (what else?) and this answer.
brew update
brew upgrade python3
Sometimes things on a Mac do ‘just work’. This was one of those times.
I’m now running Python 3.7.1 and I’ll I needed to do was a simple command in the terminal.
God bless the internet.
Monitoring the temperature of my Raspberry Pi Camera
In late April of this year I wrote a script that would capture the temperature of the Raspberry Pi that sits above my Hummingbird feeder and log it to a file.
It’s a straight forward enough script that captures the date, time and temperature as given by the internal measure_temp function. In code it looks like this:
MyDate="`date +'%m/%d/%Y, %H:%M, '`"
MyTemp="`/opt/vc/bin/vcgencmd measure_temp |tr -d "=temp'C"`"
echo "$MyDate$MyTemp" >> /home/pi/Documents/python_projects/temperature/temp.log
I haven’t ever really done anything with the file, but one thing I wanted to do was to get alerted if (when) the temperature exceeded the recommended level of 70 C.
To do this I installed ssmtp onto my Pi using apt-get
sudo apt-get install ssmtp
With that installed I am able to send an email using the following command:
echo "This is the email body" | mail -s "This is the subject" user@domain.tld
With this tool in place I was able to attempt to send an alert if (when) the Pi’s temperature got above 70 C (the maximum recommended running temp).
At first, I tried adding this code:
if [ "$MyTemp" -gt "70" ]; then
echo "Camera Pi Running Hot" | mail -s "Warning! The Camera Pi is Running Hot!!!" user@domain.tld
fi
Where the $MyTemp came from the above code that gets logged to the temp.log file.
It didn’t work. The problem is that the temperature I’m capturing for logging purposes is a float, while the item it was being compared to was an integer. No problem, I’ll just make the “70” into a “70.0” and that will fix the ... oh wait. That didn’t work either.
OK. I tried various combinations, trying to see what would work and finally determined that there is a way to get the temperature as an integer, but it meant using a different method to capture it. This is done by adding this line:
ComparisonTemp=$(($(cat /sys/class/thermal/thermal_zone0/temp)/1000))
The code above gets the temperature as an integer. I then use that in my if statement for checking the temperature:
if [ "$ComparisonTemp" -gt "70" ]; then
echo "Camera Pi Running Hot" | mail -s "Warning! The Camera Pi is Running Hot!!!" user@domain.tld
fi
Giving a final script that looks like this:
MyDate="`date +'%m/%d/%Y, %H:%M, '`"
MyTemp="`/opt/vc/bin/vcgencmd measure_temp |tr -d "=temp'C"`"
echo "$MyDate$MyTemp" >> /home/pi/Documents/python_projects/temperature/temp.log
ComparisonTemp=$(($(cat /sys/class/thermal/thermal_zone0/temp)/1000))
if [ "$ComparisonTemp" -gt "70" ]; then
echo "Camera Pi Running Hot" | mail -s "Warning! The Camera Pi is Running Hot!!!" user@domain.tld
fi
iPad versus MacBook Pro
May people ask the question ... iPad Pro or MacBook Pro. I decided to really think about this question and see, what is it that I do with each device.
Initially I thought of each device as being its own ‘thing’. I did these things on my iPad Pro and those things on my MacBook Pro. But when I really sat down and thought about it, it turns out that there are things I do exclusively on my iPad Pro, and other things that I do exclusively on my MacBook Pro ... but there are also many things that I do on both.
iPad Pro¶
There are apps which only run on iOS. Drafts is a perfect example. It’s my note taking app of choice. Using my iPhone in conjunction with my iPad makes Drafts one of the most powerful apps I use in the iOS ecosystem.
During meetings I can quickly jot down things that I need to know using my iPhone and no one notices or cares. Later, I can use my iPad Pro to process these notes and make sure that everything gets taken care of.
I can also use Drafts as a powerful automation tool to get ideas into OmniFocus (my To Do App of Choice) easily and without any fuss.
I also use my iPad Pro to process the expenses my family incurs. We use Siri Shortcuts to take a picture of a receipt which is then saved in a folder in Dropbox.
I monitor these images and match them up against expenses (or income) in Mint and categorize the expenses.
This workflow helps to keep me (and my family) in the know about how (and more importantly where) we’re spending our money.
Mint is available as a web page, and I’ve tried to use macOS and this workflow, but it simply didn’t work for me.
Using OmniFocus on the iPad is a dream. I am easily able to process my inbox, perform my weekly review and quickly add new items to do inbox. The ability to drag and drop with with either Apple Pencil or my finger makes it so easy to move tasks around.
The other (obvious) use case for my iPad Pro over my MacBook Pro is media consumption. Everyone says you can’t get real work done on an iPad and they point to how easy it is to consume media on the iPad, but I think that shows the opposite.
When you’re ready to take a break from doing real work, the best media consumption device is the one you have with you 😀
MacBook Pro¶
When I really thought about what I use my MacBook Pro for I was ... surprised. Quite honestly, it’s used mostly to write code (in Python) using my favorite editor (PyCharm) but other than that ... I don’t do much on it that I can’t do on my iPad.
When I record podcast (OK, really, just that one and just that one time) I use my MBP, and if I have a ton of stuff I need to clean up in OmniFocus then I’m over at the MacBook, but really, it’s doesn’t do anything I can’t do on the iPad Pro.
Maybe I don’t do real work in the macOS ecosystem?
What I do on both MacBook Pro and iPad Pro¶
Honestly, they both do a great job of getting me to where I want to go on the internet. Some people think that mobile safari isn’t up to it’s macOS counterpart (and they’re right) but for my (non-coding) needs, it doesn’t really matter to me. They both work really well for me.
I also tend to use OmniFocus on both when I want to mark things as done, add new items, or make bulk edits (OF3 on iOS finally made this one a possibility).
I also use the terminal to access servers via ssh on both platforms. The great thing about the command line is that it’s mostly the same where ever you’re coming from.
Terminus on iOS is a a great terminal app and I can just as easily navigate the server there as I can using the terminal app in macOS.
I’m also just as likely to plan my family’s budget on iOS as I am macOS. It just kind of depends which device is easier to get to, not what I’m planning on doing. Excel on both platforms works really well for me (I work in a Windows environment professionally so Excel is what I use and know for that kind of thing).
Finally, writing. I use Ulysses on both macOS and iOS and really, I love them both. Each app has parity with the other so I never feel like I’m losing something when I write on my MacBook Pro (or on my iPad Pro). Sometimes, it’s hard to really tell which platform I’m on because they do such a good job (for me) to make them basically the same.
All in all, I don’t think it’s a question of which to choose, iPad Pro or MacBook Pro, iOS or macOS ... it’s a matter of what device is closest to me right now? What device will bring me the most joy to use, right now? What device do I want to use right now?
iOS or macOS? iPad Pro or MacBook Pro? These aren’t the right questions to be asking. It should be ... what device do I want to use right now? And don’t care what anyone else thinks.
Fizz Buzz
I was listening to the most recent episode of ATP and John Siracusa mentioned a programmer test called fizz buzz that I hadn’t heard of before.
I decided that I’d give it a shot when I got home using Python and Bash, just to see if I could (I was sure I could, but you know, wanted to make sure).
Sure enough, with a bit of googling to remember some syntax of Python, and learn some syntax for bash, I had two stupid little programs for fizz buzz.
Python¶
def main():
my_number = input("Enter a number: ")
if not my_number.isdigit():
return
else:
my_number = int(my_number)
if my_number%3 == 0 and my_number%15!=0:
print("fizz")
elif my_number%5 == 0 and my_number%15!=0:
print("buzz")
elif my_number%15 == 0:
print("fizz buzz")
else:
print(my_number)
if __name__ == '__main__':
main()
Bash¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
And because if it isn’t in GitHub it didn’t happen, I committed it to my fizz-buzz repo.
I figure it might be kind of neat to write it in as many languages as I can, you know … for when I’m bored.
Adding my Raspberry Pi Project code to GitHub
Over the long holiday weekend I had the opportunity to play around a bit with some of my Raspberry Pi scripts and try to do some fine tuning.
I mostly failed in getting anything to run better, but I did discover that not having my code in version control was a bad idea. (Duh)
I spent the better part of an hour trying to find a script that I had accidentally deleted somewhere in my blog. Turns out it was (mostly) there, but it didn’t ‘feel’ right … though I’m not sure why.
I was able to restore the file from my blog archive, but I decided that was a dumb way to live and given that
- I use version control at work (and have for the last 15 years)
- I’ve used it for other personal projects
However, I’ve only ever used a GUI version of either subversion (at work) or GitHub (for personal projects via PyCharm). I’ve never used it from the command line.
And so, with a bit of time on my hands I dove in to see what needed to be done.
Turns out, not much. I used this GitHub resource to get me what I needed. Only a couple of commands and I was in business.
The problem is that I have a terrible memory and this isn’t something I’m going to do very often. So, I decided to write a bash script to encapsulate all of the commands and help me out a bit.
The script looks like this:
echo "Enter your commit message:"
read commit_msg
git commit -m "$commit_msg"
git remote add origin path/to/repository
git remote -v
git push -u origin master
git add $1
echo ”enter your commit message:”
read commit_msg
git commit -m ”$commit_msg”
git push
I just recently learned about user input in bash scripts and was really excited about the opportunity to be able to use it. Turns out it didn’t take long to try it out! (God I love learning things!)
What the script does is commits the files that have been changed (all of them), adds it to the origin on the GitHub repo that has been specified, prints verbose logging to the screen (so I can tell what I’ve messed up if it happens) and then pushes the changes to the master.
This script doesn’t allow you to specify what files to commit, nor does it allow for branching and tagging … but I don’t need those (yet).
I added this script to 3 of my projects, each of which can be found in the following GitHub Repos:
I had to make the commit.sh executable (with chmod +x commit.sh) but other than that it’s basically plug and play.
Addendum¶
I made a change to my Kings script tonight (Nov 27) and it wouldn’t get pushed to git. After a bit of Googling and playing around, I determined that the original script would only push changes to an empty repo ... not one with stuff, like I had. Changes made to the post (and the GitHub repo!)
Page 9 / 13