Skip to content

Commit

Permalink
Merge pull request matryer#1513 from jgclark/master
Browse files Browse the repository at this point in the history
Add plugin for NotePlan v3
  • Loading branch information
matryer authored Dec 11, 2020
2 parents 35d25fb + 8955588 commit 6893c35
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 0 deletions.
238 changes: 238 additions & 0 deletions Lifestyle/ToDo/NotePlan3.15m.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
#!/usr/bin/env ruby
# coding: utf-8

# <bitbar.title>Todo Today for NotePlan v3</bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>Jonathan Clark</bitbar.author>
# <bitbar.author.github>jgclark</bitbar.author.github>
# <bitbar.desc>A todo list taken from NotePlan v3 and displayed with customizable color-code. Mark tasks "done" simply by clicking on them in the menubar drop-down list. This was based on "Todo.NotePlan" by Richard Guay which in turn was based on "Todo Colour" plugin by Srdgh.</bitbar.desc>
# <bitbar.dependencies>ruby</bitbar.dependencies>
# <bitbar.image></bitbar.image>
# <bitbar.abouturl>https://noteplan.co/</bitbar.abouturl>
#
# Modifications by Jonathan Clark
# 2020/10/30:
# - Update NP data storage filepaths for NotePlan 3 beta
# (including CloudKit change at v3.0.15 beta)
# - Make CloudKit location the default
# - tweak colours and falgs to suit my needs
# - ignore tasks with dates scheduled into the future
# - improve some non-tasks it was including
# - code clean up
# 2020/11/29:
# - auto-detect storage type (CloudKit > iCloud Drive > Drobpox if there are multiple)
# - add option to specify the file extension in use (default to md, but can be txt)
#
# Modifications by Guillaume Barrette
# 2017/07/01:
# - Added option to show subtasks
# 2017/06/15:
# - Changed TRUE/FALSE constant to true/false since uppercase are deprecated in ruby 2.4
# - Changed labels to start with '#' to follow NotePlan way of tagging
# - Allow to change Fonts by the user
# - Added a new parameter for users to specify if want the task to be archived
# at the end of the file or not
# - Added alternate action to mark as cancelled instead of done (using the
# Option modifier key)
# - Allow indentation at beginning of task
# 2017/06/03:
# - Added 'divide_with_header' to allow to show sections separated by headers
# - Updated the algorithm to skip all items that are not a task (Skip anything that
# doesn't starts with '- ' or '* ' and if followed by [x], [>], [-])
# 2017/05/28:
# - Fixed the line number of item to mark as done by getting the id before stripping
# the lines that are not a task
# - Scheduled task (to another day - [>]) are now skipped also
# 2017/05/20:
# - Added Black and White NotePlan menubar icon
# - Repaired a bug when there was no newline on the last line the done task would
# get appended to the last line instead of a new line at the end
# - Added the time in the @done(YYYY-MM-DD HH:MM) so it's like NotePlan preference
# - Added User Parameters so it's easy to determine if we want to append the
# @done(...) string at the end of the done task and if we want the black or white
# menubar icon
# - Changed the menubar icon to a templateImage so the color changes automatically
# when using a dark menubar (removed the white icon)
# - Removed 'use_black_icon' parameters since now it's automatic
# - Changed encoding method and removed the use of 'force_encoding("utf-8")'
# - Repaired a bug if there was no file already created for that day in NotePlan
#
# Modifications by Richard Guay
# 2017/05/20:
# - Added using emoji option
# - fixed character encoding on removing an item
# - Proper parsing of [ ] in the todo.
# - cleanup
require 'date'

#################################
# User Parameters:
insert_date_on_done_task = true # If true, the date would be inserted with the @done tag
use_emoji_as_icon = false # If true, will show emoji, otherwise it will use the black or white icon.
use_star = true # if true, will look for and use '*' instead of '-'
show_alt_task = true # If true, tasks marked with the alternate character ('* ' if use_star is FALSE or '- ' if use_star is TRUE) would be shown in the task list. For example, this could be useful to use them as bullet list.
show_subtasks = true # If true, subtasks would be shown in the list
divide_with_header = true # If true, headers would be listed and a separator is put between lists
archive_task_at_end = false # If true, the task would get archived to the end of the note
file_extension = '.md' # Defaults to file extension type 'md' -- can change to '.txt'

standard_font = '' # Font used for tasks
header_font = 'Helvetica-Bold' # Font used for headers if listed with 'divide_with_header'
#################################

Encoding.default_internal = Encoding::UTF_8
Encoding.default_external = Encoding::UTF_8

USERNAME = ENV['LOGNAME'] # pull username from environment
USER_DIR = ENV['HOME'] # pull home directory from environment
DROPBOX_DIR = "#{USER_DIR}/Dropbox/Apps/NotePlan/Documents".freeze
ICLOUDDRIVE_DIR = "#{USER_DIR}/Library/Mobile Documents/iCloud~co~noteplan~NotePlan/Documents".freeze
CLOUDKIT_DIR = "#{USER_DIR}/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3".freeze
data_root_filepath = DROPBOX_DIR if Dir.exist?(DROPBOX_DIR) && Dir[File.join(DROPBOX_DIR, '**', '*')].count { |file| File.file?(file) } > 1
data_root_filepath = ICLOUDDRIVE_DIR if Dir.exist?(ICLOUDDRIVE_DIR) && Dir[File.join(ICLOUDDRIVE_DIR, '**', '*')].count { |file| File.file?(file) } > 1
data_root_filepath = CLOUDKIT_DIR if Dir.exist?(CLOUDKIT_DIR) && Dir[File.join(CLOUDKIT_DIR, '**', '*')].count { |file| File.file?(file) } > 1

todo_file_loc = File.expand_path(data_root_filepath + '/Calendar/' + Date.today.strftime('%Y%m%d') + file_extension)

if ARGV.empty?
# Add further priority labels here
priority_labels = ['@urgent', '#high']

# Change priority color here
priority_marker = '🔴'

# Customise label color-code here:
labels = {
'@admin' => 'orange',
'@liz' => 'yellow',
'@home' => 'green',
'@martha' => 'purple', # pink is too light
'@Health' => 'cadetblue',
'@church' => 'blue', # lightblue is too light
'@tutorials' => 'violet',
'@Envato' => 'darkorange',
'@workflow' => 'purple',
'@tutorial' => 'cobaltblue'
}

lines_in_file = File.exist?(todo_file_loc.to_s) ? IO.readlines(todo_file_loc.to_s) : []
lines = []

# Remove all lines that are not a todo. Stop at the first empty line.
line_number = []
line_number_id = 0
task_style_to_search = show_alt_task ? ['- ', '* '] : use_star ? ['* '] : ['- ']
lines_in_file.each_index do |key|
# Clean out leading and trailing white spaces (space, tabs, etc)
line = lines_in_file[key].gsub(/\s+$/, '')
task_line = show_subtasks ? line.gsub(/^\s+/, '') : line
if task_line.start_with?(*task_style_to_search) && !task_line[2..4].start_with?('[x]', '[>]', '[-]') # Get only active Task items
# Now check if doesn't have a >YYYY-MM-DD that schedules it into the future
break if task_line =~ /\s>\d{4}\-\d{2}\-\d{2}/

# It's a todo line to display. Remove the leading task marker and add to the list.
if use_star
lines.push(line.gsub(/^(\s*)\*\s*(\[ \]\s*)*/, '\1'))
else
lines.push(line.gsub(/^(\s*)\-\s*(\[ \]\s*)*/, '\1'))
end
line_number.push(line_number_id)
elsif divide_with_header && line =~ /^#+\s+/ # i.e. this is a header line
lines.push(line)
line_number.push(line_number_id)
end
line_number_id += 1
end

# Give the header. It's the NotePlan icon or an emoji briefcase with the number of items todo
icon_base64 = 'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAQAAAACj/OVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAHdElNRQfkChwAHRNqrC5wAAABSElEQVRYw2NgGAWjYBRQCXAy8AIxnYAxw384NKKHhf9R4KiFoxYOpIXGDPxkWsjFYEKqZQ5Q476QYSFMRpfcYJtDgoU3yQvuZ2iG/mfwIsLCBgxdl8hLFhD4h0EMj4VKWPX8p8RCEHzPwILVwv84IZGgHY8RG9H4t/GodSU+FmPwGEMsVCI1axygwLIF5Gb+V2RY9oGy8oaV4R9J1rFQo5BLIdIyR2qWrBcJWLaL2nXELwIWnqCmZROJDNIsalgmT1KS+cMgTIllzCSmUAh8A0zZZIEXFGT8Y6Ra1kCFoq2IeOt24DEG3Skb8Khtprx6wlYfMjJ8pbR6wq8Zm6gwZRZextCoRUQTwx1D113yGlGrSWhEbSG3zapOQTPxO1RGhdSsIUd2y5uNQWa0bzFq4ciyMAjJOnF6jdXYMrgwmI6Oj42CUUAVAABntNYrW391eQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0xMC0yOFQwMDoyOToxOSswMDowMDOfhXoAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMTAtMjhUMDA6Mjg6MjMrMDA6MDCH/w5VAAAAAElFTkSuQmCC'

line_count = 0
lines.each { |line| line_count += 1 unless line.start_with?('#') }
if use_emoji_as_icon
puts "💼#{line_count}"
else
puts "#{line_count} |templateImage=#{icon_base64}"
end

puts '---'

cfn = File.expand_path(__FILE__)

# Create the list of items to do in the menu.
item_number = 0
lines.each do |item|
line_color = ''
line = item.chomp
if priority_labels.any? { |s| line.include? s }
# If line contains priority label, display in priority color
# line_color = priority_color
# If line contains priority label, prefix item with priority_marker
line = priority_marker + ' ' + line
else
# If line contains no priority label, cycle through labels hash,
# and if line contains a label display in corresponding color
labels.each { |label, label_color| line_color = label_color if line.include?(label) }
end
# If the line contains no label, display in default color. Otherwise, in
# chosen color. Clicking line launches this script with line number as
# the parameter.
line_font = standard_font
if line.start_with?('#')
puts('---') unless line.start_with?('##')
line_font = header_font
end
line_params = "#{line_color.empty? ? '' : 'color=' + line_color} #{line_font.empty? ? '' : 'font=' + line_font} bash='#{cfn}' param1=#{line_number[item_number]}"
puts("#{line} | " + line_params + " param2=x terminal=false trim=false refresh=\n")
puts("#{line} | alternate=true " + line_params + " param2=- terminal=false trim=false refresh=\n")
item_number += 1
end
puts '---'
puts "Click an item to mark as 'done'"
puts "Click an item to mark as 'cancelled' | alternate=true"
puts 'Refresh now (normally every 15m) | refresh='
else
# This is what to do when clicking on an item. We want to move
# the item to the Archive section and set it as done. If there
# isn't an Archive area, create it and add the task to it.

# Get the task number to archive.
do_num = ARGV[0].to_i
mark = ARGV[1]

# Get the list of todos and setup variables
todo_file = File.open(todo_file_loc.to_s)
lines_in_file = IO.readlines(todo_file)

unless lines_in_file[do_num].start_with?('#') # Do nothing if the item is a header
task = ''
lines = []
line_number = 0

lines_in_file[-1] = lines_in_file[-1] + "\n" unless lines_in_file[-1].include? "\n"

# Process the todo list lines
lines_in_file.each do |line|
if line_number != do_num
# It is one of the other lines. Just push it into the stack
lines.push(line)
else
# Get the line to be moved to the archive area
task = if insert_date_on_done_task
line.chomp + (mark == 'x' ? " @done(#{Time.new.strftime('%Y-%m-%d %H:%M')})\n" : "\n")
else
task = line.chomp + "\n"
end
task = task.gsub(/^(\s*)([\-\*]+)\s*(\[ \]\s*)*/, '\1\2 [' + mark + '] ') # Works with both task style, useful if mix with 'show_alt_task', also it keeps the indentation at beginning of the line
lines.push(task) if archive_task_at_end
end
line_number += 1
end

# Add the task to the bottom
lines.push(task) if archive_task_at_end

# Save the file
IO.write(todo_file, lines.join)
end
end
1 change: 1 addition & 0 deletions Lifestyle/ToDo/noteplan-menubar-56px.b64
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAQAAAACj/OVAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAHdElNRQfkChwAHRNqrC5wAAABSElEQVRYw2NgGAWjYBRQCXAy8AIxnYAxw384NKKHhf9R4KiFoxYOpIXGDPxkWsjFYEKqZQ5Q476QYSFMRpfcYJtDgoU3yQvuZ2iG/mfwIsLCBgxdl8hLFhD4h0EMj4VKWPX8p8RCEHzPwILVwv84IZGgHY8RG9H4t/GodSU+FmPwGEMsVCI1axygwLIF5Gb+V2RY9oGy8oaV4R9J1rFQo5BLIdIyR2qWrBcJWLaL2nXELwIWnqCmZROJDNIsalgmT1KS+cMgTIllzCSmUAh8A0zZZIEXFGT8Y6Ra1kCFoq2IeOt24DEG3Skb8Khtprx6wlYfMjJ8pbR6wq8Zm6gwZRZextCoRUQTwx1D113yGlGrSWhEbSG3zapOQTPxO1RGhdSsIUd2y5uNQWa0bzFq4ciyMAjJOnF6jdXYMrgwmI6Oj42CUUAVAABntNYrW391eQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0xMC0yOFQwMDoyOToxOSswMDowMDOfhXoAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMTAtMjhUMDA6Mjg6MjMrMDA6MDCH/w5VAAAAAElFTkSuQmCC
81 changes: 81 additions & 0 deletions System/uptime.5m.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash

# <bitbar.title>uptime</bitbar.title>
# <bitbar.version>v1.2</bitbar.version>
# <bitbar.author>Matteo Ferrando</bitbar.author>
# <bitbar.author.github>chamini2</bitbar.author.github>
# <bitbar.desc>Show uptime command information. Tweaked by Jonathan Clark to be more compact.</bitbar.desc>
# <bitbar.image>http://i.imgur.com/qaIxpJN.png</bitbar.image>

# the `sed` command removes the occasional leading whitespace
INFO=$(uptime | sed 's/^ *//g')
echo "$INFO" | awk -F'[ ,:\t\n]+' '
{
PLURAL = 1
VERBOSE = 0
SEP = ", "
DS = " day"
HS = " hr"
MS = " min"
SS = " sec"
################################
D = H = M = S = 0
if (substr($5,0,1) == "d") {
# up for a day or more
D = $4
P = $6
Q = $7
} else {
P = $4
Q = $5
}
if (int(Q) == 0) {
# words evaluate to zero
# exact times format, like `P = 55`, `Q = secs`
Q = substr(Q,0,1)
if (Q == "h") { H = P }
else if (Q == "m") { M = P }
else if (Q == "s") { S = P }
} else {
# hh:mm format, like `P = 4`, `Q = 20`
H = P
M = Q
}
MSG = "↑ " include(D, DS, SEP, PLURAL, (D > 0))
MSG = MSG include(H, HS, SEP, PLURAL, (D == 0 || VERBOSE))
MSG = MSG include(M, MS, SEP, PLURAL, (D == 0 || VERBOSE))
# MSG = MSG include(S, SS, SEP, PLURAL, (D == 0 || VERBOSE))
# remove the remaining SEP
MSG = substr(MSG, 0, length(MSG) - length(SEP))
# print "[", MSG, "] | size=12"
print MSG, "| size=12"
}
function include(VAL, UNIT, SUFFIX, PLURAL, VERBOSE) {
VAL = int(VAL)
if (PLURAL && VAL != 1) {
UNIT = UNIT"s"
}
if (VERBOSE) { # VAL > 0 || VERBOSE) {
return (VAL UNIT SUFFIX)
} else {
# return ""
}
}'

echo "---"
echo "$INFO" | tr "," "\n" | tail -n 2
echo "---"
echo "Refresh now (normally every 5m) | refresh="

0 comments on commit 6893c35

Please sign in to comment.