Updating my meeting Workflow for Drafts 5
Drafts is a productivity app created by Greg Pierce (\@AgileTortoise).
I’ve loved and used Drafts 4 every day for the last several years. I loved it so much I even contributed to the Tip Jar Greg had in the app. Seriously, it’s an amazing app. If you haven’t downloaded it already you totally should.
Recently, Greg released Drafts 5. With this new version comes a new Business Model as well. Instead of a single pay (and hope people ‘tip’ you) he’s converted to a subscription model.
I signed up for the free week and didn’t have a real opportunity to use it before my free week was converted into a pay week but I’ve no regrets. I like what Greg does and want him to keep updating his app so that I can get the benefits of it once I have a real chance to dive in.
Part of the reason I wasn’t able to really use the new version is the way that I primarily use Drafts. I have a WorkFlow that takes a meeting on my work calendar and allows me to take notes about that meetings.
It’s one of the most useful productivity tools I have during my morning standup meetings with my team, and it’s useful for the other (sometimes endless) meetings that I go to.
With the release of Drafts 5 I was not longer able to use both Drafts 5 AND my workflow, so I needed to update my workflow.
With Drafts 4 it was just one of the built in Apps. Because Drafts 5 limits some of the functionality unless you have the PRO version I don’t think that Workflow will be updated to include Drafts 5 like it did Drafts 4.
Once I realized that AND since I’m paying for the app I figured I’d need to update my Workflow instead of waiting and hoping that Workflow would be updated to include Drafts 5.
In order to make the update I had to look for URL Scheme for Drafts 5 ... but I couldn’t really find one. I assumed that Drafts 5 URL Scheme would be the same as Drafts 4 (I was right) and made various attempts at getting a copy of the Workflow to work with Drafts 5.
This is the section of the workflow that needs to be updated:
Since Drafts 5 isn’t included in the Built in Apps I was going to need to pass a URL and open the app.
This would require 3 separate steps in Workflow
- Convert Text into URL Encoded string
- Prepend the URL Scheme for creating a new draft to the URL Encoded String
- Open the URL
This basically means that 1 step is now replaced with 3 ... but hey, that’s the price of progress must be paid!
Both the Drafts 4 and Drafts 5 versions of these workflows are available.
If you enjoy them, hit me up in the comments or let me know on Twitter \@ryancheley!
Automating the Hummingbird Video Upload to YouTube or How I finally got Cron to do what I needed it to do but in the ugliest way possible
Several weeks ago in Cronjob Redux I wrote that I had finally gotten Cron to automate the entire process of compiling the h264
files into an mp4
and uploading it to YouTube.
I hadn’t. And it took the better part of the last 2 weeks to figure out what the heck was going on.
Part of what I wrote before was correct. I wasn’t able to read the client_secrets.json
file and that was leading to an error.
I was not correct on the creation of the create_mp4.sh
though.
The reason I got it to run automatically that night was because I had, in my testing, created the create_mp4.sh
and when cron ran my run_script.sh
it was able to use what was already there.
The next night when it ran, the create_mp4.sh
was already there, but the h264
files that were referenced in it weren’t. This lead to no video being uploaded and me being confused.
The issue was that cron was unable to run the part of the script that generates the script to create the mp4
file.
I’m close to having a fix for that, but for now I did the most inelegant thing possible. I broke up the script in cron so it looks like this:
00 06 * * * /home/pi/Documents/python_projects/cleanup.sh
10 19 * * * /home/pi/Documents/python_projects/create_script_01.sh
11 19 * * * /home/pi/Documents/python_projects/create_script_02.sh >> $HOME/Documents/python_projects/create_mp4.sh 2>&1
12 19 * * * /home/pi/Documents/python_projects/create_script_03.sh
13 19 * * * /home/pi/Documents/python_projects/run_script.sh
At 6am every morning the cleanup.sh
runs and removes the h264
files, the mp4
file and the create_mp4.sh
script
At 7:10pm the ‘header’ for the create_mp4.sh
runs. At 7:11pm the ‘body’ for create_mp4.sh
runs. At 7:12pm the ‘footer’ for create_mp4.sh
runs.
Finally at 7:13pm the run_script.sh
compiles the h264
files into an mp4
and uploads it to YouTube.
Last night while I was at a School Board meeting the whole process ran on it’s own. I was super pumped when I checked my YouTube channel and saw that the May 1 hummingbird video was there and I didn’t have to do anything.
Cronjob Redux
After days of trying to figure this out, I finally got the video to upload via a cronjob.
There were 2 issues.
Issue the first
Finally found the issue. Original script from YouTube developers guidehad this:
CLIENT_SECRETS_FILE = "client_secrets.json"
And then a couple of lines later, this:
% os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE))
When crontab
would run the script it would run from a path that wasn’t where the CLIENT_SECRETS_FILE
file was and so a message would be displayed:
WARNING: Please configure OAuth 2.0
To make this sample run you will need to populate the client_secrets.json file
found at:
%s
with information from the Developers Console
https://console.developers.google.com/
For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
What I needed to do was to update the CLIENT_SECRETS_FILE
to be the whole path so that it could always find the file.
A simple change:
CLIENT_SECRETS_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE))
Issue the second
When the create_mp4.sh
script would run it was reading all of the h264
files from the directory where they lived BUT they were attempting to output the mp4
file to /
which it didn’t have permission to write to.
This was failing silently (I’m still not sure how I could have caught the error). Since there was no mp4
file to upload that script was failing (though it was true that the location of the CLIENT_SECRETS_FILE
was an issue).
What I needed to do was change the create_mp4.sh
file so that when the MP4Box command output the mp4
file to the proper directory. The script went from this:
(echo '#!/bin/sh'; echo -n "MP4Box"; array=($(ls ~/Documents/python_projects/*.h264)); for index in ${!array[@]}; do if [ "$index" -eq 0 ]; then echo -n " -add ${array[index]}"; else echo -n " -cat ${array[index]}"; fi; done; echo -n " hummingbird.mp4") > create_mp4.sh
To this:
(echo '#!/bin/sh'; echo -n "MP4Box"; array=($(ls ~/Documents/python_projects/*.h264)); for index in ${!array[@]}; do if [ "$index" -eq 0 ]; then echo -n " -add ${array[index]}"; else echo -n " -cat ${array[index]}"; fi; done; echo -n " /home/pi/Documents/python_projects/hummingbird.mp4") > /home/pi/Documents/python_projects/create_mp4.sh
The last bit /home/pi/Documents/python_projects/create_mp4.sh
may not be necessary but I’m not taking any chances.
The video posted tonight is the first one that was completely automatic!
Now … if I could just figure out how to automatically fill up my hummingbird feeder.
Cronjob Redux
After days of trying to figure this out, I finally got the video to upload via a cronjob.
There were 2 issues.
Issue the first
Finally found the issue. Original script from YouTube developers guidehad this:
CLIENT_SECRETS_FILE = "client_secrets.json"
And then a couple of lines later, this:
% os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE))
When crontab
would run the script it would run from a path that wasn’t where the CLIENT_SECRETS_FILE
file was and so a message would be displayed:
WARNING: Please configure OAuth 2.0
To make this sample run you will need to populate the client_secrets.json file
found at:
%s
with information from the Developers Console
https://console.developers.google.com/
For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
What I needed to do was to update the CLIENT_SECRETS_FILE
to be the whole path so that it could always find the file.
A simple change:
CLIENT_SECRETS_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE))
Issue the second
When the create_mp4.sh
script would run it was reading all of the h264
files from the directory where they lived BUT they were attempting to output the mp4
file to /
which it didn’t have permission to write to.
This was failing silently (I’m still not sure how I could have caught the error). Since there was no mp4
file to upload that script was failing (though it was true that the location of the CLIENT_SECRETS_FILE
was an issue).
What I needed to do was change the create_mp4.sh
file so that when the MP4Box command output the mp4
file to the proper directory. The script went from this:
(echo '#!/bin/sh'; echo -n "MP4Box"; array=($(ls ~/Documents/python_projects/*.h264)); for index in ${!array[@]}; do if [ "$index" -eq 0 ]; then echo -n " -add ${array[index]}"; else echo -n " -cat ${array[index]}"; fi; done; echo -n " hummingbird.mp4") > create_mp4.sh
To this:
(echo '#!/bin/sh'; echo -n "MP4Box"; array=($(ls ~/Documents/python_projects/*.h264)); for index in ${!array[@]}; do if [ "$index" -eq 0 ]; then echo -n " -add ${array[index]}"; else echo -n " -cat ${array[index]}"; fi; done; echo -n " /home/pi/Documents/python_projects/hummingbird.mp4") > /home/pi/Documents/python_projects/create_mp4.sh
The last bit /home/pi/Documents/python_projects/create_mp4.sh
may not be necessary but I’m not taking any chances.
The video posted tonight is the first one that was completely automatic!
Now … if I could just figure out how to automatically fill up my hummingbird feeder.
Cronjob ... Finally
I’ve mentioned before that I have been working on getting the hummingbird video upload automated.
Each time I thought I had it, and each time I was wrong.
For some reason I could run it from the command line without issue, but when the cronjob would try and run it ... nothing.
Turns out, it was running, it just wasn’t doing anything. And that was my fault.
The file I had setup in cronjob was called run_scrip.sh
At first I was confused because the script was suppose to be writing out to a log file all of it’s activities. But it didn’t appear to.
Then I noticed that the log.txt file it was writing was in the main \`
directory. That should have been my first clue.
I kept trying to get the script to run, but suddenly, in a blaze of glory, realized that it was running, it just wasn’t doing anything.
And it wasn’t doing anything for the same reason that the log file was being written to the \`
directory.
All of the paths were relative instead of absolute, so when the script ran the command ./create_mp4.sh
it looks for that script in the home directory, didn’t find it, and moved on.
The fix was simple enough, just add absolute paths and we’re golden.
That means my run_script.sh
goes from this:
# Create the script that will be run
./create_script.sh
echo "Create Shell Script: $(date)" >> log.txt
# make the script that was just created executable
chmod +x /home/pi/Documents/python_projects/create_mp4.sh
# Create the script to create the mp4 file
/home/pi/Documents/python_projects/create_mp4.sh
echo "Create MP4 Shell Script: $(date)" >> /home/pi/Documents/python_projects/log.txt
# upload video to YouTube.com
/home/pi/Documents/python_projects/upload.sh
echo "Uploaded Video to YouTube.com: $(date)" >> /home/pi/Documents/python_projects/log.txt
# Next we remove the video files locally
rm /home/pi/Documents/python_projects/*.h264
echo "removed h264 files: $(date)" >> /home/pi/Documents/python_projects/log.txt
rm /home/pi/Documents/python_projects/*.mp4
echo "removed mp4 file: $(date)" >> /home/pi/Documents/python_projects/log.txt
To this:
# change to the directory with all of the files
cd /home/pi/Documents/python_projects/
# Create the script that will be run
/home/pi/Documents/python_projects/create_script.sh
echo "Create Shell Script: $(date)" >> /home/pi/Documents/python_projects/log.txt
# make the script that was just created executable
chmod +x /home/pi/Documents/python_projects/create_mp4.sh
# Create the script to create the mp4 file
/home/pi/Documents/python_projects/create_mp4.sh
echo "Create MP4 Shell Script: $(date)" >> /home/pi/Documents/python_projects/log.txt
# upload video to YouTube.com
/home/pi/Documents/python_projects/upload.sh
echo "Uploaded Video to YouTube.com: $(date)" >> /home/pi/Documents/python_projects/log.txt
# Next we remove the video files locally
rm /home/pi/Documents/python_projects/*.h264
echo "removed h264 files: $(date)" >> /home/pi/Documents/python_projects/log.txt
rm /home/pi/Documents/python_projects/*.mp4
echo "removed mp4 file: $(date)" >> /home/pi/Documents/python_projects/log.txt
I made this change and then started getting an error about not being able to access a json
file necessary for the upload to YouTube. Sigh.
Then while searching for what directory the cronjob was running from I found this very simple idea. The response was, why not just change it to the directory you want. 🤦♂️
I added the cd
to the top of the file:
# change to the directory with all of the files
cd /home/pi/Documents/python_projects/
Anyway, now it works. Finally!
Tomorrow will be the first time (unless of course something else goes wrong) that The entire process will be automated. Super pumped!
Using MP4Box to concatenate many .h264 files into one MP4 file
The general form of the concatenate command for MP4Box is:
MP4Box -add <filename>.ext -cat <filename>.ext output.ext
1
When you have more than a couple of output files, you’re going to want to automate that -cat
part as much as possible because let’s face it, writing out that statement even more than a couple of times will get really old really fast.
The method below works but I’m sure that there is a better way to do it.
- echo out the command you want to run. In this case:
(echo -n "MP4Box "; for i in *.h264; do echo -n " -cat $i"; done; echo -n " hummingbird.mp4") >> com.txt
- Edit the file
com.txt
created in (1) so that you can change the first-cat
to-add
vim com.txt
- While still in
vim
editing thecom.txt
file add the#!/bin/sh
to the first line. When finished, exit vim2 - Change the mode of the file so it can run
chmod +x com.txt
- Run the file:
./com.txt
Why am I doing all of this? I have a Raspberry Pi with a Camera attachment and a motion sensor. I’d like to watch the hummingbirds that come to my hummingbird feeder with it for a day or two and get some sweet video. We’ll see how it goes.
Pushing Changes from Pythonista to GitHub - Step 1
With the most recent release of the iOS app Workflow I was toying with the idea of writing a workflow that would allow me to update / add a file to a GitHub repo via a workflow.
My thinking was that since Pythonista is only running local files on my iPad if I could use a workflow to access the api elements to push the changes to my repo that would be pretty sweet.
In order to get this to work I'd need to be able to accomplosh the following things (not necessarily in this order)
- Have the workflow get a list of all of the repositories in my GitHub
- Get the current contents of the app to the clip board
- Commit the changes to the master of the repo
I have been able to write a Workflow that will get all of the public repos of a specified github user. Pretty straight forward stuff.
The next thing I'm working on getting is to be able to commit the changes from the clip board to a specific file in the repo (if one is specified) otherwise a new file would be created.
I really just want to 'have the answer' for this, but I know that the journey will be the best part of getting this project completed.
So for now, I continue to read the GitHub API Documentation to discover exactly how to do what I want to do.
Page 2 / 2