├── .gitignore ├── 2Do └── AddTaskFromMail.applescript ├── Airmail ├── ComposeMail.applescript └── SaveAttachment.applescript ├── Alfred ├── CompileCommonMark.sh ├── CopyContentToClipboard.sh ├── CopyFileListToClipboard.sh ├── CopyFiles.sh ├── Markdown2Richtext.sh ├── MoveFiles.sh ├── PrependCreationDate.sh └── PrependModificationDate.sh ├── Bookmarklets └── geticon.js ├── Caffeine ├── ToggleCaffeine.applescript └── alfred_CaffeineStatus.applescript ├── Calendar └── addalarms.py ├── Finder ├── OpenDespiteGatekeeper.sh └── RandomizeFolder.applescript ├── Hazel ├── AddToEvernote.applescript ├── CompileCommonMark.sh ├── ConvertImagesForDigitalFrame.sh └── RandomizeFilename.sh ├── Mail ├── ComposeMail.applescript ├── ExportMail.applescript ├── SaveAttachment.applescript └── VacuumIndex.applescript ├── Photos ├── ExportFavorites.applescript ├── SortPicsIntoWeeks.applescript └── TagPhotosWithAlbumNames.applescript ├── README.md ├── TextExpander ├── CreateHTMLSnippets.applescript ├── CreateMediaWikiSnippets.applescript ├── CreateParenthesesSnippets.applescript ├── FindSnippet.applescript ├── MakeLaunchCenterList.applescript ├── MakeLaunchClipboardAction.applescript └── SafariSessionMd.applescript ├── Things ├── AddTask.applescript ├── AddTaskFromAirmail.applescript ├── AddTaskFromMail.applescript ├── Contacts.applescript ├── ParseQuery.applescript ├── ShowTodayTasks.applescript └── ShowTodayTasksCount.applescript ├── _README.md ├── build_docs.py └── iTunes ├── RefreshSelection.applescript └── RenameMusic.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.scpt 2 | -------------------------------------------------------------------------------- /2Do/AddTaskFromMail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | description: > 3 | Adds a new task to Things. (For use with Alfredapp: 4 | alfredapp.com and Arimail: airmail.com) 5 | 6 | name: Add new task from selected mail to 2Do 7 | apps: 2Do,Mail 8 | description: > 9 | Creates a new task in 2Dos default list with a link to the selected 10 | message in Mail. 11 | parameters: 12 | TODO_TAGS: "Tags for the newly created task, **default**: `\"Mail\"`" 13 | TASK_PREFIX: "Prefix for the mail subject to use in the tasks title, **default**: `\"Read: \"`" 14 | INBOX_NAME: "Name of the list to add the task to, **default**: `\"Inbox\"`" 15 | compile: true 16 | *) 17 | property TODO_TAGS : "Mail" 18 | property TASK_PREFIX : "Lesen: " 19 | property INBOX_NAME : "Eingang" 20 | 21 | on alfred_script(q) 22 | tell application "Mail" 23 | set theMail to first item of (get selection) 24 | set theSubject to subject of theMail 25 | set theMessage to "message://<" & (message id of theMail as rich text) & ">" 26 | set theSender to sender of theMail 27 | set theContent to content of theMail 28 | end tell 29 | 30 | tell application "Safari" 31 | set theURL to "twodo://x-callback-url/add?task=" & TASK_PREFIX & theSubject & "&action=url:" & theMessage & "¬e=" & theContent & "&tags=" & TODO_TAGS 32 | open location theURL 33 | -- delay 1 34 | close current tab of window 1 35 | end tell 36 | 37 | return theURL 38 | end alfred_script 39 | -------------------------------------------------------------------------------- /Airmail/ComposeMail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Compose mail 3 | apps: Airmail 2 4 | description: Quickly compose an email in Airmail 2 5 | parameters: 6 | SUBJ: Subject line 7 | SENDR: Sending account to use 8 | RECEIPIENTS: List of recipient mails 9 | CC: List of cc mails 10 | BCC: List of bcc mails 11 | TESNIP: Abbreviation of a TextExpander snippet to use as content 12 | compile: false 13 | *) 14 | 15 | property SUBJ : "" 16 | property SENDR : "" 17 | property RECEIPIENTS : {""} 18 | property CC : {""} 19 | property BCC : {""} 20 | property TESNIP : "" 21 | 22 | 23 | tell application "Airmail 2" 24 | set newMail to make new outgoing message with properties {subject:SUBJ, sender:SENDR} 25 | repeat with R in RECEIPIENTS 26 | make new to recipient at end of newMail's to recipients with properties {name:"", address:R} 27 | end repeat 28 | repeat with C in CC 29 | make new cc recipient at end of newMail's cc recipients with properties {name:"", address:C} 30 | end repeat 31 | repeat with B in BCC 32 | make new bcc recipient at end of newMail's bcc recipients with properties {name:"", address:B} 33 | end repeat 34 | 35 | compose newMail 36 | activate 37 | 38 | if TESNIP is not "" then 39 | delay 1 40 | tell application "TextExpander" to expand abbreviation TESNIP 41 | end if 42 | end tell 43 | -------------------------------------------------------------------------------- /Airmail/SaveAttachment.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Save attachments 3 | apps: Airmail 3 4 | description: Use as a script in Airmail rules to save attachments to the selected folder. 5 | parameters: 6 | DOWNLOADS: Folder to save attachments to 7 | compile: false 8 | *) 9 | property DOWNLOADS : "~/Downloads" 10 | 11 | on processMessage(theMessage) 12 | try 13 | tell application "Airmail 3" 14 | repeat with anAttach in mail attachments of theMessage 15 | set aFilename to filename of anAttach 16 | set aFile to quoted form of aFilename 17 | set fldr to quoted form of DOWNLOADS 18 | 19 | do shell script "cp " & (aFile as text) & " " & (fldr as text) & "" 20 | end repeat 21 | end tell 22 | end try 23 | end processMessage 24 | -------------------------------------------------------------------------------- /Alfred/CompileCommonMark.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Compile CommonMark 3 | # apps: Alfred, CommonMark, Markdown, Tag 4 | # description: > 5 | # Converts any markdown file to html using 6 | # CommonMark (http://commonmark.org) and 7 | # copies all tags with tag (https://github.com/jdberry/tag/). 8 | # parameters: 9 | 10 | IFS=" " 11 | files="{query}" 12 | for file in $files; do 13 | newfile="${file%.*}.html" 14 | /usr/local/bin/cmark -t html --safe "$file" > "$newfile" 15 | tags=`/usr/local/bin/tag -N "$file"` 16 | /usr/local/bin/tag --set $tags "$newfile" 17 | done 18 | -------------------------------------------------------------------------------- /Alfred/CopyContentToClipboard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Copy content 3 | # apps: Alfred 4 | # description: > 5 | # Copies the content of the selected file 6 | # to the clipboard. 7 | # parameters: 8 | 9 | cat "{query}" | pbcopy 10 | -------------------------------------------------------------------------------- /Alfred/CopyFileListToClipboard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: List files 3 | # apps: Alfred 4 | # description: > 5 | # Copies a list of all files in the selected 6 | # folder to the clipboard. 7 | # parameters: 8 | 9 | ls -A -1 "{query}" | pbcopy 10 | -------------------------------------------------------------------------------- /Alfred/CopyFiles.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Copy files 3 | # apps: Alfred 4 | # description: "Copies the passed in files to `folder`" 5 | # parameters: 6 | # folder: "The folder the files will be copied to, **default**: `~/Downloads`" 7 | folder="~/Downloads" 8 | 9 | IFS=" " 10 | files="{query}" 11 | for file in $files 12 | do cp "$file" "$folder" 13 | done 14 | -------------------------------------------------------------------------------- /Alfred/Markdown2Richtext.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Compile CommonMark to RTF 3 | # apps: Alfred, CommonMark, Markdown, Tag 4 | # description: > 5 | # Converts any markdown file to rich text using 6 | # CommonMark (http://commonmark.org) and copies all tags with 7 | # tag (https://github.com/jdberry/tag/). 8 | # parameters: 9 | 10 | IFS=" " 11 | files="{query}" 12 | for file in $files; do 13 | newfile="${file%.*}.rtf" 14 | /usr/local/bin/pandoc -r commonmark -w rtf -s -out "$newfile" "$file" 15 | tags=`/usr/local/bin/tag -N "$file"` 16 | /usr/local/bin/tag --set $tags "$newfile" 17 | done 18 | -------------------------------------------------------------------------------- /Alfred/MoveFiles.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Move files 3 | # apps: Alfred 4 | # description: "Moves the passed in files to `folder`" 5 | # parameters: 6 | # folder: "The folder the files will be moved to, **default**: `~/Downloads`" 7 | folder="~/Downloads" 8 | 9 | IFS=" " 10 | files="{query}" 11 | for file in $files 12 | do mv "$file" "$folder" 13 | done 14 | -------------------------------------------------------------------------------- /Alfred/PrependCreationDate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Prepend with creation date 3 | # apps: Alfred 4 | # description: > 5 | # Prepends the selected filename with the creation date. 6 | # parameters: 7 | 8 | IFS=" " 9 | files="{query}" 10 | for file in $files 11 | do mv "$file" "`dirname \"$file\"`/`date '+%Y-%m-%d'`_`basename \"$file\"`" 12 | done 13 | -------------------------------------------------------------------------------- /Alfred/PrependModificationDate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # name: Prepend with modification date 3 | # apps: Alfred 4 | # description: > 5 | # Prepends the selected filename with the date 6 | # of the last modification. 7 | # parameters: 8 | 9 | IFS=" " 10 | files="{query}" 11 | for file in $files; do 12 | mtime=`date -j -f "%s" "$(stat -f '%m' \"$file\")" +"%F"` 13 | mv "$file" "`dirname \"$file\"`/${mtime}_`basename \"$file\"`" 14 | done 15 | -------------------------------------------------------------------------------- /Bookmarklets/geticon.js: -------------------------------------------------------------------------------- 1 | /* 2 | name: Get Icon 3 | apps: Safari, Chrome 4 | description: Shows an icon for the current page. Requires jQuery. 5 | parameters: 6 | compile: false 7 | */ 8 | function $sorted(selector, attrName) { 9 | return $($(selector).toArray().sort(function(a, b) { 10 | var aVal = parseInt(a.getAttribute(attrName)); 11 | var bVal = parseInt(b.getAttribute(attrName)); 12 | return aVal - bVal; 13 | })); 14 | } 15 | 16 | var icons = $sorted('link[rel=apple-touch-icon]', 'sizes').last(); 17 | if (icons.length === 0) { 18 | icons = $sorted('link[rel=apple-touch-icon-precomposed]', 'sizes').last(); 19 | } 20 | if (icons.filter('[href]').length > 0) { 21 | window.location = icons.attr('href'); 22 | } else { 23 | $('img').each(function(i, e) { 24 | $(e) 25 | .css('border', '2px dashed lime') 26 | .css('cursor', 'pointer') 27 | .hover(function() { 28 | $(this).css('border', '2px dashed magenta'); 29 | }, function(e) { 30 | $(this).css('border', '2px dashed lime'); 31 | }) 32 | .click(function(e) { 33 | e.preventDefault(); 34 | window.location = $(this).attr('src'); 35 | }); 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /Caffeine/ToggleCaffeine.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Set Caffeine state 3 | apps: Caffeine, Alfred 4 | description: > 5 | Use as Alfred action to activate/deactivate 6 | Caffein or toggle the state. Pass 'activate', 7 | 'deactivate' or 'toggle' to the action. 8 | parameters: 9 | compile: false 10 | *) 11 | on alfred_script(q) 12 | if q is not in {"toggle", "deactivate", "activate"} then 13 | set q to "toggle" 14 | end if 15 | 16 | tell application "Caffeine" 17 | set status to "not been changed." 18 | if active and q is in {"toggle", "deactivate"} then 19 | turn off 20 | set status to "been deactivated." 21 | else if not active and q is in {"toggle", "activate"} then 22 | turn on 23 | set status to "been activated." 24 | end if 25 | 26 | set output to "Caffeine has " & status 27 | 28 | return output 29 | end tell 30 | end alfred_script 31 | -------------------------------------------------------------------------------- /Caffeine/alfred_CaffeineStatus.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Show Caffeine state 3 | apps: Caffeine, Alfred 4 | description: > 5 | Use in Alfred script filter to show Caffeins 6 | state (active or inactive) in the action item. 7 | parameters: 8 | compile: false 9 | *) 10 | set theState to "inactive." 11 | tell application "Caffeine" 12 | if active is true then 13 | set theState to "active." 14 | end if 15 | end tell 16 | 17 | "Toggle CaffeineCaffeine is "&theState&"" & "" 18 | -------------------------------------------------------------------------------- /Calendar/addalarms.py: -------------------------------------------------------------------------------- 1 | # name: Add alarms to ics 2 | # apps: Caffeine, Alfred 3 | # description: Adds alarms to all events in an .ics file 4 | # parameters: 5 | # _TRIGGERS: "A list of times to trigger alarms at, **default**: `['-PT5H']`" 6 | # _ACTION: "The action for the alarms, **default**: `DISPLAY`" 7 | # _SUFFIX "A suffix to append to the filename, if no out file is defined, **default**: `'-w-alarms'`" 8 | # compile: false 9 | import sys 10 | import os 11 | import icalendar 12 | from datetime import datetime 13 | 14 | # Configuration 15 | _TRIGGERS = ['-PT5H'] 16 | _ACTION = 'DISPLAY' 17 | _SUFFIX = '-w-alarms' 18 | 19 | if len(sys.argv) < 2: 20 | sys.exit("Usage: python addalarms.py input.ics output.ics") 21 | 22 | if sys.argv[1].endswith('.ics'): 23 | with open(sys.argv[1]) as ical_file: 24 | cal = icalendar.cal.Component.from_ical(ical_file.read()) 25 | 26 | n = 0 27 | a = 0 28 | for sub in cal.subcomponents: 29 | for trigger in _TRIGGERS: 30 | alarm = icalendar.cal.Alarm() 31 | alarm['trigger'] = trigger 32 | alarm['action'] = _ACTION 33 | alarm['description'] = sub['summary'] 34 | sub.add_component(alarm) 35 | a += 1 36 | n += 1 37 | 38 | if len(sys.argv) >= 3: 39 | with open(sys.argv[2], 'wb') as ical_result: 40 | ical_result.write(cal.to_ical()) 41 | else: 42 | filename, ext = os.path.splitext(sys.argv[1]) 43 | with open("%s%s.ics" % (filename, _SUFFIX), 'wb') as ical_result: 44 | ical_result.write(cal.to_ical()) 45 | 46 | print('done: added %s alarms to %s events' % (a, n)) 47 | -------------------------------------------------------------------------------- /Finder/OpenDespiteGatekeeper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | base=$(basename "$1") 3 | name=${base%.*} 4 | 5 | spctl --add --label "$name" "$1" 6 | open "$1" 7 | -------------------------------------------------------------------------------- /Finder/RandomizeFolder.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Randomize filenames 3 | apps: Finder 4 | description: > 5 | Lets you choose a folder and randomizes the order 6 | of all files in it by renaming them with NAME_PREFIX 7 | and a number. 8 | parameters: 9 | NAME_PREFIX: "A prefix to append an increasing number to, **default**: `'photo-'`" 10 | NUMBER_PADDING: "By how many zeros should the number be padded, **default**: `4`" 11 | TYPES: "A list of file extensions (without the dot) to randomize, **default**: `{'jpg', 'jpeg', 'png'}`" 12 | compile: true 13 | *) 14 | property NAME_PREFIX : "photo-" 15 | property NUMBER_PADDING : 4 16 | property TYPES : {"jpg", "jpeg", "png"} 17 | 18 | 19 | -- get the folder to check 20 | set f to choose folder 21 | 22 | -- notice the use of "entire contents" to also go through subfolders of f 23 | -- use a "whose" filter to find only the video files 24 | tell application "Finder" 25 | set allFiles to (files of entire contents of f whose name extension is in TYPES) as alias list 26 | 27 | set theNo to 1 28 | repeat while allFiles is not {} 29 | set fileCount to the count of allFiles 30 | tell current application to set pick to random number from 1 to fileCount 31 | set theFile to item pick of allFiles -- as alias 32 | 33 | -- remove theFile from list 34 | if fileCount is 1 then 35 | set allFiles to {} 36 | else if pick is 1 then 37 | set allFiles to items 2 thru fileCount of allFiles 38 | else if pick is fileCount then 39 | set allFiles to items 1 thru (fileCount - 1) of allFiles 40 | else 41 | set allFiles to (items 1 thru (pick - 1) of allFiles) & (items (pick + 1) thru fileCount of allFiles) 42 | end if 43 | 44 | set fileNumber to "0000000000" & (fileCount as string) 45 | set fileNumber to characters ((length of fileNumber) - NUMBER_PADDING + 1) thru -1 of fileNumber as string 46 | 47 | -- rename theFile 48 | set the name of file theFile to (NAME_PREFIX & fileNumber) & "." & name extension of theFile 49 | end repeat 50 | end tell 51 | -------------------------------------------------------------------------------- /Hazel/AddToEvernote.applescript: -------------------------------------------------------------------------------- 1 | set AppleScript's text item delimiters to "," 2 | set theTags to do shell script "/usr/local/bin/tag -N " & (quoted form of POSIX path of theFile) 3 | set theTags to theTags's text items 4 | 5 | tell application "Evernote" 6 | --activate 7 | create note from file theFile tags theTags 8 | delay 2 9 | end tell 10 | -------------------------------------------------------------------------------- /Hazel/CompileCommonMark.sh: -------------------------------------------------------------------------------- 1 | # Converts any markdown file to html using 2 | # CommonMark (http://commonmark.org) and copies all tags with 3 | # tag (https://github.com/jdberry/tag/). 4 | target="${1%.*}.html" 5 | /usr/local/bin/cmark -t html --safe "$file" > "$target" 6 | tags=`/usr/local/bin/tag -N "$file"` 7 | /usr/local/bin/tag --set $tags "$target" 8 | -------------------------------------------------------------------------------- /Hazel/ConvertImagesForDigitalFrame.sh: -------------------------------------------------------------------------------- 1 | # Resize image to picture frame size with ImageMagick 2 | convert $1'[800x600]' $1 3 | # Shrink filesize with jhead and ImageOptim 4 | jhead -ft "$1" 5 | /Applications/ImageOptim.app/Contents/MacOS/ImageOptim "$1" 6 | # Randomize filename with a 8 character long string 7 | RAND=$(date +%s | sha256sum | base64 | head -c 8) 8 | mv "$1" "$RAND.${1##*.}" 9 | -------------------------------------------------------------------------------- /Hazel/RandomizeFilename.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Randomize filename with a 8 character long string 4 | RAND=$(date +%s | sha256sum | base64 | head -c 8) 5 | mv "$1" "$RAND.${1##*.}" 6 | -------------------------------------------------------------------------------- /Mail/ComposeMail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Compose mail 3 | apps: Mail 4 | description: Quickly compose an email in Mail.app 5 | parameters: 6 | SUBJ: Subject line 7 | SENDR: Sending account to use 8 | RECEIPIENTS: List of recipient mails 9 | CC: List of cc mails 10 | BCC: List of bcc mails 11 | TESNIP: Abbreviation of a TextExpander snippet to use as content 12 | compile: false 13 | *) 14 | 15 | -- Subject line 16 | property SUBJ : "" 17 | -- Sending account to use. Needs to be in the format "Name " and 18 | -- exactly match the name and mail in the account settings. Leave blank to 19 | -- use the default account. 20 | property SENDR : "" 21 | -- Recipients (normal, cc and bcc) for the mail. Just enter mail adresses. 22 | property RECEIPIENTS : {""} 23 | property CC : {} 24 | property BCC : {} 25 | -- an optional TextExpander snippet to set as the content 26 | property TESNIP : "" 27 | 28 | 29 | tell application "Mail" 30 | set SNIP to "" 31 | if TESNIP is not "" then 32 | tell application "TextExpander" 33 | set allSNIPs to (every snippet in every group whose abbreviation is TESNIP) 34 | repeat with GRP in allSNIPs 35 | if (count of GRP) > 0 then set SNIP to rich text expansion of first item of GRP 36 | end repeat 37 | end tell 38 | end if 39 | 40 | set newMail to make new outgoing message with properties {subject:SUBJ, sender:SENDR, content:SNIP, visible:true} 41 | repeat with R in RECEIPIENTS 42 | make new to recipient at end of newMail's to recipients with properties {name:"", address:R} 43 | end repeat 44 | repeat with C in CC 45 | make new cc recipient at end of newMail's cc recipients with properties {name:"", address:C} 46 | end repeat 47 | repeat with B in BCC 48 | make new bcc recipient at end of newMail's bcc recipients with properties {name:"", address:B} 49 | end repeat 50 | 51 | activate 52 | end tell 53 | -------------------------------------------------------------------------------- /Mail/ExportMail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Export mail as text to a folder 3 | apps: Mail 4 | description: Use as a script in Mail.app rules to export the mail as a text file 5 | to the selected folder. 6 | parameters: 7 | DOWNLOADS: Folder to save attachments to 8 | TRASH_AFTER: Set to true to trash the mail after saving the attachments 9 | NO_SUBJECT: Used if the mails subject is empty 10 | compile: false 11 | *) 12 | property DOWNLOADS : "~/Downloads" 13 | property TRASH_AFTER : false 14 | property NO_SUBJECT : "(no subject)" 15 | 16 | using terms from application "Mail" 17 | on perform mail action with messages theMails for rule theRule 18 | tell application "Mail" 19 | repeat with aMail in theMails 20 | set theSource to source of aMail 21 | 22 | set theSubject to subject of aMail 23 | if theSubject is equal to "" then 24 | set theSubject to NO_SUBJECT 25 | else 26 | set theSubject to my escape(theSubject) 27 | end if 28 | 29 | try 30 | set theFilename to DOWNLOADS & "/" & theSubject & ".eml" 31 | do shell script "touch \"" & theFilename & "\"" 32 | 33 | set theFile to open for access theFilename with write permission 34 | write theSource to theFile 35 | close access theFile 36 | 37 | if TRASH_AFTER then delete aMail 38 | on error 39 | do shell script "rm -f \"" & theFilename & "\"" 40 | end try 41 | end repeat 42 | end tell 43 | end perform mail action with messages 44 | end using terms from 45 | 46 | on escape(t) 47 | set {tid, text item delimiters} to {text item delimiters, "/"} 48 | set t to text items of t 49 | set text item delimiters to "-" 50 | set t to t as text 51 | set text item delimiters to tid 52 | return t 53 | end escape -------------------------------------------------------------------------------- /Mail/SaveAttachment.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Save mail attachments to a folder 3 | apps: Mail 4 | description: Use as a script in Mail.app rules to save attachments to a folder. 5 | parameters: 6 | DOWNLOADS: Folder to save attachments to 7 | TRASH_AFTER: Set to true to trash the mail after saving the attachments 8 | compile: false 9 | *) 10 | property DOWNLOADS : "~/Downloads" 11 | property TRASH_AFTER : false 12 | 13 | using terms from application "Mail" 14 | on perform mail action with messages theMessages for rule theRule 15 | tell application "Mail" 16 | repeat with theMessage in theMessages 17 | repeat with theAttachment in mail attachments of theMessage 18 | try 19 | set theFile to DOWNLOADS & "/" & (name of theAttachment) 20 | tell theAttachment to save in theFile 21 | end try 22 | end repeat 23 | 24 | if TRASH_AFTER then delete aMail 25 | end repeat 26 | end tell 27 | end perform mail action with messages 28 | end using terms from -------------------------------------------------------------------------------- /Mail/VacuumIndex.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Vacuum Mail.app index 3 | apps: Mail 4 | description: Speed up Mail.app by vacuuming the Envelope Index 5 | parameters: 6 | compile: true 7 | *) 8 | 9 | (* 10 | Speed up Mail.app by vacuuming the Envelope Index 11 | Code from: http://www.hawkwings.net/2007/03/03/scripts-to-automate-the-mailapp-envelope-speed-trick/ 12 | Originally by "pmbuko" with modifications by Romulo 13 | Updated by Brett Terpstra 2012 14 | Updated by Mathias Törnblom 2015 to support V3 in El Capitan and still keep backwards compability 15 | *) 16 | 17 | tell application "Mail" to quit 18 | set os_version to do shell script "sw_vers -productVersion" 19 | set mail_version to "V2" 20 | considering numeric strings 21 | if "10.10" <= os_version then set mail_version to "V3" 22 | end considering 23 | 24 | set sizeBefore to do shell script "ls -lnah ~/Library/Mail/" & mail_version & "/MailData | grep -E 'Envelope Index$' | awk {'print $5'}" 25 | do shell script "/usr/bin/sqlite3 ~/Library/Mail/" & mail_version & "/MailData/Envelope\\ Index vacuum" 26 | 27 | set sizeAfter to do shell script "ls -lnah ~/Library/Mail/" & mail_version & "/MailData | grep -E 'Envelope Index$' | awk {'print $5'}" 28 | 29 | display dialog ("Mail index before: " & sizeBefore & return & "Mail index after: " & sizeAfter & return & return & "Enjoy the new speed!") 30 | 31 | tell application "Mail" to activate 32 | -------------------------------------------------------------------------------- /Photos/ExportFavorites.applescript: -------------------------------------------------------------------------------- 1 | property TARGET : "/Volumes/Hyrrokkin/Uploads/Photorahmen" 2 | 3 | 4 | tell application "Photos" 5 | set favs to every media item in favorites album 6 | export favs to POSIX file TARGET 7 | end tell -------------------------------------------------------------------------------- /Photos/SortPicsIntoWeeks.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Group pictures by week 3 | apps: Photos 4 | description: > 5 | Sorts pics from a particular album into weekly albums relative 6 | to a target date based on the image date. 7 | 8 | The script will sort every media item from `SOURCE_ALBUM` album 9 | into child albums of the TARGET_FOLDER by calculating how many 10 | weeks after `TARGET_DATE` it was taken. 11 | 12 | The resulting folder structure will be: 13 | 14 | ``` 15 | TARGET_FOLDER 16 | ZERO_ALBUM 17 | WEEKLY_PREFIX 1 18 | WEEKLY_PREFIX 2 19 | WEEKLY_PREFIX 3 20 | ... 21 | ``` 22 | parameters: 23 | TARGET_DATE: "Set to the target date." 24 | SOURCE_ALBUM: "Set to the album with the unsorted pics. If it is a subfolder use a path like string." 25 | TARGET_FOLDER: "Set to the target folder for the weekly albums. This folder will be the parent of the weekly albums." 26 | ZERO_ALBUM: "Set to the album for pictures without a date or with a date before the target date." 27 | WEEKLY_PREFIX: "Set to a prefix for the weekly albums." 28 | DISPLAY_DIALOG: "Set to true to display a summary dialog after everything is sorted." 29 | compile: false 30 | *) 31 | 32 | -- Set to the target date 33 | property TARGET_DATE : date "Dienstag, 22. Juli 2014 um 02:06:00" 34 | -- Set to the album with the unsorted pics. If it is a subfolder use a path like string. 35 | property SOURCE_ALBUM : "#Unsortiert/Linus Neu" 36 | -- Set to the target folder for the weekly albums. This folder will be the parent of the weekly albums. 37 | property TARGET_FOLDER : "Growing-Up/Linus" 38 | -- Set to the album for pictures without a date or with a date before the target date 39 | property ZERO_ALBUM : "Woche 0" 40 | -- Set to a prefix for the weekly albums 41 | property WEEKLY_PREFIX : "Woche " 42 | 43 | 44 | property DISPLAY_DIALOG : true 45 | 46 | 47 | -- Do some startup stuff 48 | display notification "AppleScript is busy. This might take a while." with title "SortPicsIntoWeeks" subtitle "Sorting images ..." 49 | 50 | -- Get relevant folders 51 | set theSrcAlbum to getAlbum(SOURCE_ALBUM) 52 | set theTargetFolder to getAlbum(TARGET_FOLDER) 53 | set theZeroAlbum to getAlbum(TARGET_FOLDER & "/" & ZERO_ALBUM) 54 | 55 | tell application "Photos" 56 | -- Get all images 57 | set allMedia to media items of theSrcAlbum 58 | 59 | if length of allMedia is 0 then 60 | display notification "Source folder is empty. No pictures to sort." with title "SortPicsIntoWeeks" 61 | return 62 | end if 63 | 64 | -- Sort media into folders 65 | set n to 0 66 | set f to 0 67 | repeat with aMedium in allMedia 68 | -- Get media date 69 | set mDate to date of aMedium 70 | 71 | if TARGET_DATE < mDate then 72 | -- Get week realtive to BIRTHDAY 73 | set weekNo to (mDate - TARGET_DATE) div (7 * days) + 1 74 | set weekName to WEEKLY_PREFIX & weekNo 75 | -- log "Sort medium into album " & weekName 76 | 77 | -- Get appropriate week album or create 78 | try 79 | tell theTargetFolder to set theWeekAlbum to container weekName 80 | on error 81 | set theWeekAlbum to make new album named weekName at theTargetFolder 82 | end try 83 | 84 | -- Add medium to album 85 | add {aMedium} to theWeekAlbum 86 | -- Remove from old album 87 | -- ????? 88 | 89 | log ("Sorted medium " & (filename of aMedium) & " to album " & (name of theWeekAlbum)) 90 | else 91 | -- Move to Week 0 92 | add aMedium to theZeroAlbum 93 | log ("Sorted medium " & (filename of aMedium) & " to album " & (name of theZeroAlbum)) 94 | end if 95 | set n to n + 1 96 | 97 | end repeat 98 | 99 | set msg to n & " pictures sorted." & return 100 | if f > 0 then set msg to msg & f & " pictures with errors!" & return 101 | set msg to msg & "The pictures can now be deleted from album " & quote & (name of theSrcAlbum) & quote & "." 102 | if DISPLAY_DIALOG then 103 | display dialog msg as text with title "SortPicsIntoWeeks" 104 | else 105 | display notification msg as text with title "SortPicsIntoWeeks" 106 | end if 107 | end tell 108 | 109 | on getAlbum(path) 110 | set {astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/"} 111 | set pathItems to every text item of path 112 | set AppleScript's text item delimiters to astid 113 | 114 | tell application "Photos" 115 | set c to container (first item of pathItems) 116 | set pathItems to rest of pathItems 117 | repeat with p in pathItems 118 | tell c to set c to container p 119 | end repeat 120 | end tell 121 | 122 | return c 123 | end getAlbum 124 | -------------------------------------------------------------------------------- /Photos/TagPhotosWithAlbumNames.applescript: -------------------------------------------------------------------------------- 1 | -- tag items with album:albumname 2 | tell application "Photos" 3 | set theAlbums to albums 4 | repeat with aAlbum in theAlbums 5 | --log "Tagging items in album " & (name of aAlbum as text) 6 | tell aAlbum 7 | set albumTag to "album:" & (name of aAlbum as text) 8 | set theItems to media items 9 | repeat with aItem in theItems 10 | set theKeywords to (keywords of aItem) 11 | if theKeywords is missing value then 12 | set keywords of aItem to albumTag 13 | else if theKeywords does not contain albumTag then 14 | set the end of theKeywords to albumTag 15 | set keywords of aItem to theKeywords 16 | end if 17 | end repeat 18 | end tell 19 | end repeat 20 | end tell -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osx-script-stuff 2 | 3 | A collection of scripts to automate stuff on Max OS X systems. 4 | 5 | 6 | ## Table of contents 7 | 8 | 1. [Scripts](#scripts) 9 | - [Add new task from selected mail to 2Do](#add-new-task-from-selected-mail-to-2do) 10 | - [Compose mail](#compose-mail) 11 | - [Save attachments](#save-attachments) 12 | - [Compile CommonMark](#compile-commonmark) 13 | - [Copy content](#copy-content) 14 | - [List files](#list-files) 15 | - [Copy files](#copy-files) 16 | - [Compile CommonMark to RTF](#compile-commonmark-to-rtf) 17 | - [Move files](#move-files) 18 | - [Prepend with creation date](#prepend-with-creation-date) 19 | - [Prepend with modification date](#prepend-with-modification-date) 20 | - [Get Icon](#get-icon) 21 | - [Set Caffeine state](#set-caffeine-state) 22 | - [Show Caffeine state](#show-caffeine-state) 23 | - [Randomize filenames](#randomize-filenames) 24 | - [Compose mail](#compose-mail2) 25 | - [Save attachments](#save-attachments2) 26 | - [Vacuum Mail.app index](#vacuum-mailapp-index) 27 | - [Export favorites](#export-favorites) 28 | - [Group pictures by week](#group-pictures-by-week) 29 | - [Create HTML snippets](#create-html-snippets) 30 | - [Create parentheses snippets](#create-parentheses-snippets) 31 | - [Create markdown list of current Safari session](#create-markdown-list-of-current-safari-session) 32 | - [Reindex tags of selected songs in iTunes](#reindex-tags-of-selected-songs-in-itunes) 33 | 2. [App Index](#app-index) 34 | 3. [Script Index](#script-index) 35 | 36 | ## Scripts 37 | 38 | ### Add new task from selected mail to 2Do 39 | Creates a new task in 2Dos default list with a link to the selected message in Mail. 40 | 41 | 42 | - Apps: 2Do, [Mail](https://www.apple.com/support/mac-apps/mail/) 43 | - File: [_2Do/AddTaskFromMail.applescript_](./2Do/AddTaskFromMail.applescript) 44 | - Parameters: 45 | - **TODO_TAGS**: Tags for the newly created task, **default**: `"Mail"` 46 | - **TASK_PREFIX**: Prefix for the mail subject to use in the tasks title, **default**: `"Read: "` 47 | - **INBOX_NAME**: Name of the list to add the task to, **default**: `"Inbox"` 48 | - Binary: [_2Do/AddTaskFromMail.scpt_](./2Do/AddTaskFromMail.scpt) 49 | 50 | 51 | ### Compose mail 52 | Quickly compose an email in Airmail 2 53 | 54 | - Apps: [Airmail 2](http://airmailapp.com) 55 | - File: [_Airmail/ComposeMail.applescript_](./Airmail/ComposeMail.applescript) 56 | - Parameters: 57 | - **RECEIPIENTS**: List of recipient mails 58 | - **SENDR**: Sending account to use 59 | - **SUBJ**: Subject line 60 | - **TESNIP**: Abbreviation of a TextExpander snippet to use as content 61 | - **BCC**: List of bcc mails 62 | - **CC**: List of cc mails 63 | 64 | 65 | ### Save attachments 66 | Use as a script in Airmail rules to save attachments to the selected folder. 67 | 68 | - Apps: [Airmail 2](http://airmailapp.com) 69 | - File: [_Airmail/SaveAttachment.applescript_](./Airmail/SaveAttachment.applescript) 70 | - Parameters: 71 | - **DOWNLOADS**: Folder to save attachments to 72 | 73 | 74 | ### Compile CommonMark 75 | Converts any markdown file to html using CommonMark (http://commonmark.org) and copies all tags with tag (https://github.com/jdberry/tag/). 76 | 77 | 78 | - Apps: [Alfred](http://alfredapp.com), [CommonMark](http://commonmark.org), [Markdown](https://daringfireball.net/projects/markdown/), [Tag](https://github.com/jdberry/tag/) 79 | - File: [_Alfred/CompileCommonMark.sh_](./Alfred/CompileCommonMark.sh) 80 | 81 | 82 | ### Copy content 83 | Copies the content of the selected file to the clipboard. 84 | 85 | 86 | - Apps: [Alfred](http://alfredapp.com) 87 | - File: [_Alfred/CopyContentToClipboard.sh_](./Alfred/CopyContentToClipboard.sh) 88 | 89 | 90 | ### List files 91 | Copies a list of all files in the selected folder to the clipboard. 92 | 93 | 94 | - Apps: [Alfred](http://alfredapp.com) 95 | - File: [_Alfred/CopyFileListToClipboard.sh_](./Alfred/CopyFileListToClipboard.sh) 96 | 97 | 98 | ### Copy files 99 | Copies the passed in files to `folder` 100 | 101 | - Apps: [Alfred](http://alfredapp.com) 102 | - File: [_Alfred/CopyFiles.sh_](./Alfred/CopyFiles.sh) 103 | - Parameters: 104 | - **folder**: The folder the files will be copied to, **default**: `~/Downloads` 105 | 106 | 107 | ### Compile CommonMark to RTF 108 | Converts any markdown file to rich text using CommonMark (http://commonmark.org) and copies all tags with tag (https://github.com/jdberry/tag/). 109 | 110 | 111 | - Apps: [Alfred](http://alfredapp.com), [CommonMark](http://commonmark.org), [Markdown](https://daringfireball.net/projects/markdown/), [Tag](https://github.com/jdberry/tag/) 112 | - File: [_Alfred/Markdown2Richtext.sh_](./Alfred/Markdown2Richtext.sh) 113 | 114 | 115 | ### Move files 116 | Moves the passed in files to `folder` 117 | 118 | - Apps: [Alfred](http://alfredapp.com) 119 | - File: [_Alfred/MoveFiles.sh_](./Alfred/MoveFiles.sh) 120 | - Parameters: 121 | - **folder**: The folder the files will be moved to, **default**: `~/Downloads` 122 | 123 | 124 | ### Prepend with creation date 125 | Prepends the selected filename with the creation date. 126 | 127 | 128 | - Apps: [Alfred](http://alfredapp.com) 129 | - File: [_Alfred/PrependCreationDate.sh_](./Alfred/PrependCreationDate.sh) 130 | 131 | 132 | ### Prepend with modification date 133 | Prepends the selected filename with the date of the last modification. 134 | 135 | 136 | - Apps: [Alfred](http://alfredapp.com) 137 | - File: [_Alfred/PrependModificationDate.sh_](./Alfred/PrependModificationDate.sh) 138 | 139 | 140 | ### Get Icon 141 | Shows an icon for the current page. Requires jQuery. 142 | 143 | - Apps: Safari, Chrome 144 | - File: [_Bookmarklets/geticon.js_](./Bookmarklets/geticon.js) 145 | 146 | 147 | ### Set Caffeine state 148 | Use as Alfred action to activate/deactivate Caffein or toggle the state. Pass 'activate', 'deactivate' or 'toggle' to the action. 149 | 150 | 151 | - Apps: Caffeine, [Alfred](http://alfredapp.com) 152 | - File: [_Caffeine/ToggleCaffeine.applescript_](./Caffeine/ToggleCaffeine.applescript) 153 | 154 | 155 | ### Show Caffeine state 156 | Use in Alfred script filter to show Caffeins state (active or inactive) in the action item. 157 | 158 | 159 | - Apps: Caffeine, [Alfred](http://alfredapp.com) 160 | - File: [_Caffeine/alfred_CaffeineStatus.applescript_](./Caffeine/alfred_CaffeineStatus.applescript) 161 | 162 | 163 | ### Randomize filenames 164 | Lets you choose a folder and randomizes the order of all files in it by renaming them with NAME_PREFIX and a number. 165 | 166 | 167 | - Apps: Finder 168 | - File: [_Finder/RandomizeFolder.applescript_](./Finder/RandomizeFolder.applescript) 169 | - Parameters: 170 | - **NUMBER_PADDING**: By how many zeros should the number be padded, **default**: `4` 171 | - **NAME_PREFIX**: A prefix to append an increasing number to, **default**: `'photo-'` 172 | - **TYPES**: A list of file extensions (without the dot) to randomize, **default**: `{'jpg', 'jpeg', 'png'}` 173 | - Binary: [_Finder/RandomizeFolder.scpt_](./Finder/RandomizeFolder.scpt) 174 | 175 | 176 | ### Compose mail 177 | Quickly compose an email in Mail.app 178 | 179 | - Apps: [Mail](https://www.apple.com/support/mac-apps/mail/) 180 | - File: [_Mail/ComposeMail.applescript_](./Mail/ComposeMail.applescript) 181 | - Parameters: 182 | - **RECEIPIENTS**: List of recipient mails 183 | - **SENDR**: Sending account to use 184 | - **SUBJ**: Subject line 185 | - **TESNIP**: Abbreviation of a TextExpander snippet to use as content 186 | - **BCC**: List of bcc mails 187 | - **CC**: List of cc mails 188 | 189 | 190 | ### Save attachments 191 | Use as a script in Mail.app rules to save attachments to the selected folder. 192 | 193 | - Apps: [Mail](https://www.apple.com/support/mac-apps/mail/) 194 | - File: [_Mail/SaveAttachment.applescript_](./Mail/SaveAttachment.applescript) 195 | - Parameters: 196 | - **TRASH_AFTER**: Set to true to trash the mail after saving the attachments 197 | - **DOWNLOADS**: Folder to save attachments to 198 | 199 | 200 | ### Vacuum Mail.app index 201 | Speed up Mail.app by vacuuming the Envelope Index 202 | 203 | - Apps: [Mail](https://www.apple.com/support/mac-apps/mail/) 204 | - File: [_Mail/VacuumIndex.applescript_](./Mail/VacuumIndex.applescript) 205 | - Binary: [_Mail/VacuumIndex.scpt_](./Mail/VacuumIndex.scpt) 206 | 207 | 208 | ### Export favorites 209 | Export all media marked as favorites in Photos 210 | 211 | - Apps: Photos 212 | - File: [_Photos/ExportFavorites.applescript_](./Photos/ExportFavorites.applescript) 213 | - Parameters: 214 | - **TARGET**: Set to the target folder. 215 | 216 | 217 | ### Group pictures by week 218 | Sorts pics from a particular album into weekly albums relative to a target date based on the image date. 219 | The script will sort every media item from `SOURCE_ALBUM` album into child albums of the TARGET_FOLDER by calculating how many weeks after `TARGET_DATE` it was taken. 220 | The resulting folder structure will be: 221 | ``` TARGET_FOLDER 222 | ZERO_ALBUM 223 | WEEKLY_PREFIX 1 224 | WEEKLY_PREFIX 2 225 | WEEKLY_PREFIX 3 226 | ... 227 | ``` 228 | 229 | 230 | - Apps: Photos 231 | - File: [_Photos/SortPicsIntoWeeks.applescript_](./Photos/SortPicsIntoWeeks.applescript) 232 | - Parameters: 233 | - **WEEKLY_PREFIX**: Set to a prefix for the weekly albums. 234 | - **TARGET_FOLDER**: Set to the target folder for the weekly albums. This folder will be the parent of the weekly albums. 235 | - **TARGET_DATE**: Set to the target date. 236 | - **DISPLAY_DIALOG**: Set to true to display a summary dialog after everything is sorted. 237 | - **SOURCE_ALBUM**: Set to the album with the unsorted pics. If it is a subfolder use a path like string. 238 | - **ZERO_ALBUM**: Set to the album for pictures without a date or with a date before the target date. 239 | 240 | 241 | ### Create HTML snippets 242 | Creates a set of snippets for common HTML tags. 243 | 244 | For each tag in TAGS_INLINE and TAGS_BLOCK the script will 245 | create two snippets, one with the cursor (`%|`) and one with the 246 | clipboard (`%clipboard`) between the opening and closing tags. 247 | For the `TAGS_EMPTY` empty tags (e.g. `
`) are created. 248 | 249 | As abbreviations the first `PREFIX_LENGTH` chars of the tag name 250 | are used. 251 | 252 | E.g. for the inline/block tags `em`/`blockquote` with default 253 | settings the following snippets will be created: 254 | 255 | ``` 256 | ,em %| 257 | ;em %clipboard 258 | ,block
259 | %| 260 |
261 | ;block
262 | %clipboard 263 |
264 | ``` 265 | 266 | 267 | - Apps: [TextExpander](https://smilesoftware.com/TextExpander/index.html) 268 | - File: [_TextExpander/CreateHTMLSnippets.applescript_](./TextExpander/CreateHTMLSnippets.applescript) 269 | - Parameters: 270 | - **TAGS_INLINE**: inline tags to create snippets for, **default**: `['del', 'code', 'strong', 'em']` 271 | - **TAGS_BLOCK**: block level tags to create snippets for, **default**: `['pre', 'blockquote']` 272 | - **PREFIX_CHARS**: snippet prefixes to use, **default**: `[',', ';', ',/']` 273 | - the first list item places the cursor (`%|`) between the tags 274 | - the second list item places the cursor (`%clipboard`) between the tags 275 | - the third is used for empty blocks (e.g. `
`) 276 | - **GROUP_NAME**: name of group the snippets will be created in, **default**: `'HTML'` 277 | - **PREFIX_LENGTH**: number of chars to take from the tag name for the abbreviation, **default**: `5` 278 | - **TAGS_EMPTY**: empty tags to create snippets for, **default**: `['br', 'hr']` 279 | 280 | 281 | ### Create parentheses snippets 282 | Creates a set of snippets for enclosing parentheses. 283 | 284 | For each pair of parentheses the script will create two snippets, one with 285 | the cursor (`%|`) and one with the clipboard (`%clipboard)` between the 286 | parentheses. Both snippets will be created `MAX_REPEAT` times, by repeating 287 | the opening and closing parentheses one to `MAX_REPEAT` times. 288 | 289 | E.g. for the pair `[`,`]` with default settings the following snippets will be created: 290 | 291 | ``` 292 | ,[ [%|] 293 | ;[ [%clipboard] 294 | ,2[ [[%|]] 295 | ;2[ [[%clipboard]] 296 | ,3[ [[[%|]]] 297 | ;3[ [[[%clipboard]]] 298 | ``` 299 | 300 | 301 | - Apps: [TextExpander](https://smilesoftware.com/TextExpander/index.html) 302 | - File: [_TextExpander/CreateParenthesesSnippets.applescript_](./TextExpander/CreateParenthesesSnippets.applescript) 303 | - Parameters: 304 | - **MAX_REPEAT**: maximum depth for snippets, **default**: `3` 305 | - **PAIRS**: parenthesis pairs, each item is a list with two items: the opening and closing parenthesis 306 | **default**: 307 | ``` {["'", "'"], ["\"", "\""], ["`", "`"], ["(", ")"], ["[", "]"], ["{", "}"], ["_", "_"], ["-", "-"], ["~", "~"], ["*", "*"], ["<", ">"], ["=", "="]} ``` 308 | - **PREFIX_CHARS**: snippet prefixes to use, **default**: `[',', ';']` 309 | - the first list item places the cursor (`%|`) between the tags 310 | - the second list item places the cursor (`%clipboard`) between the tags 311 | - **GROUP_NAME**: name of group the snippets will be created in, **default**: `'Parentheses'` 312 | 313 | 314 | ### Create markdown list of current Safari session 315 | Creates a markdown document from the URLs currently open in 316 | Safaris frontmost window. 317 | 318 | ``` 319 | # Safari links from 2016-02-02 10:01:02 320 | 321 | ## Tabs 322 | 323 | - [Quelltext der Seite Vorlage:OptionalProperty – Informatik-Box](http://informatik-box.de/index.php?title=Vorlage:OptionalProperty&action=edit) 324 | - [Kategorie:BibTeX Attribut – Informatik-Box](http://informatik-box.de/wiki/Kategorie:BibTeX_Attribut) 325 | - [Nicht kategorisierte Seiten – Informatik-Box](http://informatik-box.de/wiki/Spezial:Nicht_kategorisierte_Seiten) 326 | - [Nicht kategorisierte Vorlagen – Informatik-Box](http://informatik-box.de/wiki/Spezial:Nicht_kategorisierte_Vorlagen) 327 | - [InfoBox:Urheberrechte – Informatik-Box](http://informatik-box.de/wiki/InfoBox:Urheberrechte) 328 | - [Vorlage:Rating – Informatik-Box](http://informatik-box.de/wiki/Vorlage:Rating) 329 | - [Anmelden – Informatik-Box](http://informatik-box.de/index.php?title=Spezial:Anmelden&returnto=Spezial%3ABeobachtungsliste&returntoquery=&warning=watchlistanontext) 330 | - [Category:Developer documentation – semantic-mediawiki.org](https://www.semantic-mediawiki.org/wiki/Category:Developer_documentation) 331 | - [EduTech Wiki](http://edutechwiki.unige.ch/en/Main_Page) 332 | - [Extension:EditImage - MediaWiki](https://www.mediawiki.org/wiki/Extension:EditImage) 333 | ``` 334 | 335 | 336 | - Apps: [TextExpander](https://smilesoftware.com/TextExpander/index.html), Safari 337 | - File: [_TextExpander/SafariSessionMd.applescript_](./TextExpander/SafariSessionMd.applescript) 338 | - Parameters: 339 | - **PINNED**: number of pinned tabs to ignore, **default**: `4` 340 | 341 | 342 | ### Reindex tags of selected songs in iTunes 343 | Reindex the songs currently selected in iTunes. For easy use put into `~/Library/iTunes/Scripts/`. 344 | 345 | 346 | - Apps: [iTunes](https://www.apple.com/support/mac-apps/iTunes/) 347 | - File: [_iTunes/RefreshSelection.applescript_](./iTunes/RefreshSelection.applescript) 348 | - Binary: [_iTunes/RefreshSelection.scpt_](./iTunes/RefreshSelection.scpt) 349 | 350 | 351 | ## App Index 352 | 353 | - **2Do** 354 | [Add new task from selected mail to 2Do](#add-new-task-from-selected-mail-to-2do) 355 | - **Airmail 2** 356 | [Compose mail](#compose-mail), [Save attachments](#save-attachments) 357 | - **Alfred** 358 | [Compile CommonMark](#compile-commonmark), [Copy content](#copy-content), [List files](#list-files), [Copy files](#copy-files), [Compile CommonMark to RTF](#compile-commonmark-to-rtf), [Move files](#move-files), [Prepend with creation date](#prepend-with-creation-date), [Prepend with modification date](#prepend-with-modification-date), [Set Caffeine state](#set-caffeine-state), [Show Caffeine state](#show-caffeine-state) 359 | - **Caffeine** 360 | [Set Caffeine state](#set-caffeine-state), [Show Caffeine state](#show-caffeine-state) 361 | - **Chrome** 362 | [Get Icon](#get-icon) 363 | - **CommonMark** 364 | [Compile CommonMark](#compile-commonmark), [Compile CommonMark to RTF](#compile-commonmark-to-rtf) 365 | - **Finder** 366 | [Randomize filenames](#randomize-filenames) 367 | - **Mail** 368 | [Add new task from selected mail to 2Do](#add-new-task-from-selected-mail-to-2do), [Compose mail](#compose-mail2), [Save attachments](#save-attachments2), [Vacuum Mail.app index](#vacuum-mailapp-index) 369 | - **Markdown** 370 | [Compile CommonMark](#compile-commonmark), [Compile CommonMark to RTF](#compile-commonmark-to-rtf) 371 | - **Photos** 372 | [Export favorites](#export-favorites), [Group pictures by week](#group-pictures-by-week) 373 | - **Safari** 374 | [Get Icon](#get-icon), [Create markdown list of current Safari session](#create-markdown-list-of-current-safari-session) 375 | - **Tag** 376 | [Compile CommonMark](#compile-commonmark), [Compile CommonMark to RTF](#compile-commonmark-to-rtf) 377 | - **TextExpander** 378 | [Create HTML snippets](#create-html-snippets), [Create parentheses snippets](#create-parentheses-snippets), [Create markdown list of current Safari session](#create-markdown-list-of-current-safari-session) 379 | - **iTunes** 380 | [Reindex tags of selected songs in iTunes](#reindex-tags-of-selected-songs-in-itunes) 381 | 382 | ## Script Index 383 | 384 | 385 | - **A** 386 | [Add new task from selected mail to 2Do](#add-new-task-from-selected-mail-to-2do) 387 | - **C** 388 | [Compile CommonMark](#compile-commonmark), [Compile CommonMark to RTF](#compile-commonmark-to-rtf), [Compose mail](#compose-mail2), [Compose mail](#compose-mail), [Copy content](#copy-content), [Copy files](#copy-files), [Create HTML snippets](#create-html-snippets), [Create markdown list of current Safari session](#create-markdown-list-of-current-safari-session), [Create parentheses snippets](#create-parentheses-snippets) 389 | - **E** 390 | [Export favorites](#export-favorites) 391 | - **G** 392 | [Get Icon](#get-icon), [Group pictures by week](#group-pictures-by-week) 393 | - **L** 394 | [List files](#list-files) 395 | - **M** 396 | [Move files](#move-files) 397 | - **P** 398 | [Prepend with creation date](#prepend-with-creation-date), [Prepend with modification date](#prepend-with-modification-date) 399 | - **R** 400 | [Randomize filenames](#randomize-filenames), [Reindex tags of selected songs in iTunes](#reindex-tags-of-selected-songs-in-itunes) 401 | - **S** 402 | [Save attachments](#save-attachments), [Save attachments](#save-attachments2), [Set Caffeine state](#set-caffeine-state), [Show Caffeine state](#show-caffeine-state) 403 | - **V** 404 | [Vacuum Mail.app index](#vacuum-mailapp-index) 405 | -------------------------------------------------------------------------------- /TextExpander/CreateHTMLSnippets.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Create HTML snippets 3 | apps: TextExpander 4 | description: | 5 | Creates a set of snippets for common HTML tags. 6 | 7 | For each tag in TAGS_INLINE and TAGS_BLOCK the script will 8 | create two snippets, one with the cursor (`%|`) and one with the 9 | clipboard (`%clipboard`) between the opening and closing tags. 10 | For the `TAGS_EMPTY` empty tags (e.g. `
`) are created. 11 | 12 | As abbreviations the first `PREFIX_LENGTH` chars of the tag name 13 | are used. 14 | 15 | E.g. for the inline/block tags `em`/`blockquote` with default 16 | settings the following snippets will be created: 17 | 18 | ``` 19 | ,em %| 20 | ;em %clipboard 21 | ,block
22 | %| 23 |
24 | ;block
25 | %clipboard 26 |
27 | ``` 28 | parameters: 29 | GROUP_NAME: "name of group the snippets will be created in, **default**: `'HTML'`" 30 | PREFIX_LENGTH: "number of chars to take from the tag name for the abbreviation, **default**: `5`" 31 | PREFIX_CHARS: "snippet prefixes to use, **default**: `[',', ';', ',/']`\n 32 | \t\t- the first list item places the cursor (`%|`) between the tags\n 33 | \t\t- the second list item places the cursor (`%clipboard`) between the tags\n 34 | \t\t- the third is used for empty blocks (e.g. `
`)" 35 | TAGS_INLINE: "inline tags to create snippets for, **default**: `['del', 'code', 'strong', 'em']`" 36 | TAGS_BLOCK: "block level tags to create snippets for, **default**: `['pre', 'blockquote']`" 37 | TAGS_EMPTY: "empty tags to create snippets for, **default**: `['br', 'hr']`" 38 | compile: false 39 | *) 40 | 41 | -- name of group the snippets will be created in 42 | property GROUP_NAME : "HTML" 43 | -- number of chars to take from the tag name for the abbreviation 44 | property PREFIX_LENGTH : 5 45 | -- snippet prefixes to use 46 | -- the first list item places the cursor (%|) between the tags -- the second list item places the cursor (%clipboard) between the tags -- the third is used for empty blocks (e.g. "
") property PREFIX_CHARS : [",", ";", ",/"] -- inline tags to create snippets for property TAGS_INLINE : ["del", "code", "strong", "em"] -- block level tags to create snippets for property TAGS_BLOCK : ["pre", "blockquote"] -- empty tags to create snippets for property TAGS_EMPTY : ["br", "hr"] tell application "TextExpander" try set theGroup to group GROUP_NAME on error set theGroup to make new group with properties {name:GROUP_NAME} end try set noClipChar to first item of PREFIX_CHARS set clipChar to second item of PREFIX_CHARS set emptyChar to last item of PREFIX_CHARS set cnt to 0 tell theGroup -- create inline tags repeat with tag in TAGS_INLINE -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snipNoClip to "<" & tag & ">%|" set snipClip to "<" & tag & ">%clipboard" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is noClipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:noClipChar & abbrev, plain text expansion:snipNoClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & noClipChar & abbrev} set cnt to cnt + 1 end if if (not (count of (every snippet whose abbreviation is clipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:clipChar & abbrev, plain text expansion:snipClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & clipChar & abbrev} set cnt to cnt + 1 end if end repeat -- create block level tags repeat with tag in TAGS_BLOCK -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snipNoClip to "<" & tag & ">" & return & "%|" & return & "" set snipClip to "<" & tag & ">" & return & "%clipboard" & return & "" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is noClipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:noClipChar & abbrev, plain text expansion:snipNoClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & noClipChar & abbrev} set cnt to cnt + 1 end if if (not (count of (every snippet whose abbreviation is clipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:clipChar & abbrev, plain text expansion:snipClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & clipChar & abbrev} set cnt to cnt + 1 end if end repeat -- create emtpy tags repeat with tag in TAGS_EMPTY -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snip to "<" & tag & "/>" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is emptyChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:emptyChar & abbrev, plain text expansion:snip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & emptyChar & abbrev} set cnt to cnt + 1 end if end repeat display notification (cnt & " HTML snippets created in group " & GROUP_NAME as rich text) with title "CreateHTMLSnippets" end tell end tell -------------------------------------------------------------------------------- /TextExpander/CreateMediaWikiSnippets.applescript: -------------------------------------------------------------------------------- 1 | (* Creates a set of snippets for common MediaWiki tags. Note: This is a copy of te_CreateHTMLSnippets.scpt *) -- Set to name of group the snippets will be created in property GROUP_NAME : "HTML" -- number of chars to take from the tag name for the abbreviation property PREFIX_LENGTH : 5 -- snippet prefixes to use -- the first list item places the cursor (%|) between the tags -- the second list item places the cursor (%clipboard) between the tags -- the third is used for empty blocks (e.g. "
") property PREFIX_CHARS : [",", ";", ",/"] -- inline tags to create snippets for property TAGS_INLINE : ["nowiki", "includeonly", "noinclude", "onlyinclude"] -- block level tags to create snippets for property TAGS_BLOCK : ["syntaxhighlight"] -- empty tags to create snippets for property TAGS_EMPTY : ["nowiki"] tell application "TextExpander" try set theGroup to group GROUP_NAME on error set theGroup to make new group with properties {name:GROUP_NAME} end try set noClipChar to first item of PREFIX_CHARS set clipChar to second item of PREFIX_CHARS set emptyChar to last item of PREFIX_CHARS set cnt to 0 tell theGroup -- create inline tags repeat with tag in TAGS_INLINE -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snipNoClip to "<" & tag & ">%|" set snipClip to "<" & tag & ">%clipboard" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is noClipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:noClipChar & abbrev, plain text expansion:snipNoClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & noClipChar & abbrev} set cnt to cnt + 1 end if if (not (count of (every snippet whose abbreviation is clipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:clipChar & abbrev, plain text expansion:snipClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & clipChar & abbrev} set cnt to cnt + 1 end if end repeat -- create block level tags repeat with tag in TAGS_BLOCK -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snipNoClip to "<" & tag & ">" & return & "%|" & return & "" set snipClip to "<" & tag & ">" & return & "%clipboard" & return & "" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is noClipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:noClipChar & abbrev, plain text expansion:snipNoClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & noClipChar & abbrev} set cnt to cnt + 1 end if if (not (count of (every snippet whose abbreviation is clipChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:clipChar & abbrev, plain text expansion:snipClip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & clipChar & abbrev} set cnt to cnt + 1 end if end repeat -- create emtpy tags repeat with tag in TAGS_EMPTY -- create abbreviation set charCount to length of tag if charCount < PREFIX_LENGTH then set abbrev to rich text 1 through charCount of tag else set abbrev to rich text 1 through PREFIX_LENGTH of tag end if -- create snippet text set snip to "<" & tag & "/>" -- create the snippets if there is none with this abbreviation if (not (count of (every snippet whose abbreviation is emptyChar & abbrev)) is greater than 0) then make new snippet with properties {abbreviation:emptyChar & abbrev, plain text expansion:snip, content type:plain_text, abbreviation mode:match case, label:"AS Tag: " & emptyChar & abbrev} set cnt to cnt + 1 end if end repeat display notification (cnt & " HTML snippets created in group " & GROUP_NAME as rich text) with title "CreateHTMLSnippets" end tell end tell -------------------------------------------------------------------------------- /TextExpander/CreateParenthesesSnippets.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Create parentheses snippets 3 | apps: TextExpander 4 | description: | 5 | Creates a set of snippets for enclosing parentheses. 6 | 7 | For each pair of parentheses the script will create two snippets, one with 8 | the cursor (`%|`) and one with the clipboard (`%clipboard)` between the 9 | parentheses. Both snippets will be created `MAX_REPEAT` times, by repeating 10 | the opening and closing parentheses one to `MAX_REPEAT` times. 11 | 12 | E.g. for the pair `[`,`]` with default settings the following snippets will be created: 13 | 14 | ``` 15 | ,[ [%|] 16 | ;[ [%clipboard] 17 | ,2[ [[%|]] 18 | ;2[ [[%clipboard]] 19 | ,3[ [[[%|]]] 20 | ;3[ [[[%clipboard]]] 21 | ``` 22 | parameters: 23 | GROUP_NAME: "name of group the snippets will be created in, **default**: `'Parentheses'`" 24 | MAX_REPEAT: "maximum depth for snippets, **default**: `3`" 25 | PREFIX_CHARS: "snippet prefixes to use, **default**: `[',', ';']`\n 26 | \t\t- the first list item places the cursor (`%|`) between the tags\n 27 | \t\t- the second list item places the cursor (`%clipboard`) between the tags" 28 | PAIRS: "parenthesis pairs, each item is a list with two items: the 29 | opening and closing parenthesis 30 | 31 | **default**: 32 | 33 | ``` 34 | {[\x22\x27\x22, \x22\x27\x22], [\x22\x5c\x22\x22, \x22\x5c\x22\x22], [\x22\x60\x22, \x22\x60\x22], 35 | [\x22(\x22, \x22)\x22], [\x22[\x22, \x22]\x22], [\x22{\x22, \x22}\x22], [\x22_\x22, \x22_\x22], 36 | [\x22-\x22, \x22-\x22], [\x22~\x22, \x22~\x22], [\x22*\x22, \x22*\x22], [\x22<\x22, \x22>\x22], 37 | [\x22=\x22, \x22=\x22]} 38 | ```" 39 | compile: false 40 | *) 41 | 42 | -- name of group the snippets will be created in 43 | property GROUP_NAME : "Parentheses" 44 | -- maximum depth for snippets 45 | property MAX_REPEAT : 3 46 | -- snippet prefixes to use -- the first list item places the cursor (%|) between the parentheses -- the second list item places the cursor (%clipboard) between the parentheses property PREFIX_CHARS : [",", ";"] -- parenthesis pairs, each item is a list with two items: the opening and closing parenthesis 47 | property PAIRS : {["'", "'"], ["\"", "\""], ["`", "`"], ["(", ")"], ["[", "]"], ["{", "}"], ["_", "_"], ["-", "-"], ["~", "~"], ["*", "*"], ["<", ">"], ["=", "="]} 48 | tell application "TextExpander" try 49 | set theGroup to group GROUP_NAME 50 | on error 51 | set theGroup to make new group with properties {name:GROUP_NAME} 52 | end try 53 | 54 | set noClipChar to first item of PREFIX_CHARS 55 | set clipChar to last item of PREFIX_CHARS 56 | 57 | set cnt to 0 58 | 59 | tell theGroup 60 | repeat with i from 1 to MAX_REPEAT 61 | repeat with pair in PAIRS 62 | set openChar to first item of pair 63 | set closeChar to last item of pair 64 | 65 | -- add number to abbreviation 66 | if i > 1 then 67 | set abbrevNoClip to noClipChar & i & openChar 68 | set abbrevClip to clipChar & i & openChar 69 | else 70 | set abbrevNoClip to noClipChar & openChar 71 | set abbrevClip to clipChar & openChar 72 | end if 73 | 74 | -- make snippet text 75 | set snipNoClip to "%|" 76 | set snipClip to "%clipboard" 77 | repeat i times 78 | set snipNoClip to openChar & snipNoClip & closeChar 79 | set snipClip to openChar & snipClip & closeChar 80 | end repeat 81 | 82 | -- create the snippets if there is none with this abbreviation 83 | if (not (count of (every snippet whose abbreviation is abbrevNoClip)) is greater than 0) then 84 | make new snippet with properties {abbreviation:abbrevNoClip, plain text expansion:snipNoClip, content type:plain_text, abbreviation mode:match case} 85 | set cnt to cnt + 1 86 | end if 87 | if (not (count of (every snippet whose abbreviation is abbrevClip)) is greater than 0) then 88 | make new snippet with properties {abbreviation:abbrevClip, plain text expansion:snipClip, content type:plain_text, abbreviation mode:match case} 89 | set cnt to cnt + 1 90 | end if 91 | end repeat 92 | end repeat 93 | 94 | display notification (cnt & " parentheses snippets created in group " & GROUP_NAME as rich text) with title "CreateParenthesesSnippets" 95 | end tell 96 | end tell 97 | -------------------------------------------------------------------------------- /TextExpander/FindSnippet.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | Finds a snippet with the abbreviation ABRV in TextExpander 3 | 4 | *) 5 | -- abbreviation of the snippet 6 | property ABRV : ",ipsum1" 7 | 8 | tell application "TextExpander" 9 | set allSNIPs to (every snippet in every group whose abbreviation is ABRV) 10 | repeat with GRP in allSNIPs 11 | if (count of GRP) > 0 then set SNIP to rich text expansion of first item of GRP 12 | end repeat 13 | end tell -------------------------------------------------------------------------------- /TextExpander/MakeLaunchCenterList.applescript: -------------------------------------------------------------------------------- 1 | (* Creates a Launch Center Pro action to select a snippet from a list and copy it to the clipboard. *) -- set to a list of te groups to include in the list property INCLUDE_GROUPS : ["Misc", "Contact", "Date&Time", "GTD"] --property INCLUDE_GROUPS : ["Misc"] -- set to true to create a link to import the action into launch center -- (requires python for urlencoding) property GENERATE_LINK : true tell application "TextExpander" set theList to "launch://clipboard?text=[list:Snippets" repeat with aGroup in groups set theGroupName to name of aGroup if theGroupName is in INCLUDE_GROUPS then set theList to theList & "|" & theGroupName & "=[list:" & theGroupName repeat with aSnippet in snippets of aGroup set theSnippetName to label of aSnippet if theSnippetName is "" then set theSnippetName to name of aSnippet set theSnippetAbbrev to abbreviation of aSnippet set theList to theList & "|" & theSnippetName & "=[textexpander:" & theSnippetAbbrev & "]" end repeat set theList to theList & "]" end if end repeat set theList to theList & "]" if GENERATE_LINK then set theList to "launch://import?title=Snippet&description=Copy%20TextExpander%20snippet%20to%20clipboard.&url=" & (do shell script "/usr/bin/python -c 'import sys, urllib; print urllib.quote(sys.argv[1])' " & quoted form of theList) end if set the clipboard to theList display notification "Launch Center Pro action copied to clipboard." with title "MakeLaunchCenterList" end tell -------------------------------------------------------------------------------- /TextExpander/MakeLaunchClipboardAction.applescript: -------------------------------------------------------------------------------- 1 | (* Creates a Launch Center Pro clipboard action. Note: This is a copy of te_MakeLaunchCenterList.scpt *) -- set to a list of te groups to include in the list property INCLUDE_GROUPS : ["Misc", "Contact", "Date&Time", "GTD"] --property INCLUDE_GROUPS : ["Misc"] -- set to true to create a link to import the action into launch center -- (requires python for urlencoding) property GENERATE_LINK : true tell application "TextExpander" set theList to "launch://clipboard?text=[list:Clipboard|New=[prompt:Clipboard]|Show=[prompt:Clipboard=[clipboard]]|Snippet=[list:Snippets" repeat with aGroup in groups set theGroupName to name of aGroup if theGroupName is in INCLUDE_GROUPS then set theList to theList & "|" & theGroupName & "=[list:" & theGroupName repeat with aSnippet in snippets of aGroup set theSnippetName to label of aSnippet if theSnippetName is "" then set theSnippetName to name of aSnippet set theSnippetAbbrev to abbreviation of aSnippet set theList to theList & "|" & theSnippetName & "=[textexpander:" & theSnippetAbbrev & "]" end repeat set theList to theList & "]" end if end repeat set theList to theList & "]]" if GENERATE_LINK then set theList to "launch://import?title=Clipboard&description=Copy%20TextExpander%20snippet%20to%20clipboard%20and%20other%20actions.&url=" & (do shell script "/usr/bin/python -c 'import sys, urllib; print urllib.quote(sys.argv[1])' " & quoted form of theList) end if set the clipboard to theList display notification "Launch Center Pro action copied to clipboard." with title "MakeLaunchCenterList" end tell -------------------------------------------------------------------------------- /TextExpander/SafariSessionMd.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Create markdown list of current Safari session 3 | apps: TextExpander, Safari 4 | description: | 5 | Creates a markdown document from the URLs currently open in 6 | Safaris frontmost window. 7 | 8 | ``` 9 | # Safari links from 2016-02-02 10:01:02 10 | 11 | ## Tabs 12 | 13 | - [Quelltext der Seite Vorlage:OptionalProperty – Informatik-Box](http://informatik-box.de/index.php?title=Vorlage:OptionalProperty&action=edit) 14 | - [Kategorie:BibTeX Attribut – Informatik-Box](http://informatik-box.de/wiki/Kategorie:BibTeX_Attribut) 15 | - [Nicht kategorisierte Seiten – Informatik-Box](http://informatik-box.de/wiki/Spezial:Nicht_kategorisierte_Seiten) 16 | - [Nicht kategorisierte Vorlagen – Informatik-Box](http://informatik-box.de/wiki/Spezial:Nicht_kategorisierte_Vorlagen) 17 | - [InfoBox:Urheberrechte – Informatik-Box](http://informatik-box.de/wiki/InfoBox:Urheberrechte) 18 | - [Vorlage:Rating – Informatik-Box](http://informatik-box.de/wiki/Vorlage:Rating) 19 | - [Anmelden – Informatik-Box](http://informatik-box.de/index.php?title=Spezial:Anmelden&returnto=Spezial%3ABeobachtungsliste&returntoquery=&warning=watchlistanontext) 20 | - [Category:Developer documentation – semantic-mediawiki.org](https://www.semantic-mediawiki.org/wiki/Category:Developer_documentation) 21 | - [EduTech Wiki](http://edutechwiki.unige.ch/en/Main_Page) 22 | - [Extension:EditImage - MediaWiki](https://www.mediawiki.org/wiki/Extension:EditImage) 23 | ``` 24 | parameters: 25 | PINNED: "number of pinned tabs to ignore, **default**: `4`" 26 | compile: false 27 | *) 28 | property PINNED : 4 29 | property NL : " 30 | " 31 | 32 | tell application "Safari" 33 | -- set theURLs to URL of tabs of first window 34 | set theTabs to tabs of first window 35 | 36 | set theNote to "# Safari links from " & (current date) as text 37 | set theNote to theNote & NL & NL & "## Tabs" & NL 38 | 39 | set i to 0 40 | repeat with aTab in theTabs 41 | if i ≥ PINNED then 42 | try 43 | set aURL to URL of aTab 44 | set aTitle to name of aTab 45 | set theNote to theNote & NL & "- [" & aTitle & "](" & aURL & ")" 46 | end try 47 | end if 48 | 49 | set i to i + 1 50 | end repeat 51 | return theNote 52 | end tell 53 | -------------------------------------------------------------------------------- /Things/AddTask.applescript: -------------------------------------------------------------------------------- 1 | (* Adds a new task to Things. (For use with Alfredapp: alfredapp.com) Syntax: #tag1 #tag2 task name [project name/area name] ::note >duedate *) on alfred_script(q) tell application "Things" to set task to parse quicksilver input q return (name of task) end alfred_script -------------------------------------------------------------------------------- /Things/AddTaskFromAirmail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | Adds a new task to Things. (For use with Alfredapp: alfredapp.com and Arimail: airmail.com) 3 | *) 4 | property TODO_TAGS : "Mail" 5 | property TASK_PREFIX : "Act on: " 6 | 7 | on alfred_script(q) 8 | tell application "Mail" 9 | set theMail to first item of (get selection) 10 | set theSubject to subject of theMail 11 | set theMessage to "message://<" & (message id of theMail as rich text) & ">" 12 | set theSender to sender of theMail 13 | set theContent to content of theMail 14 | end tell 15 | 16 | tell application "Safari" 17 | set theURL to "twodo://x-callback-url/add?task=" & TASK_PREFIX & theSubject & "&action=url:" & theMessage & "¬e=" & theContent & "&tags=" & TODO_TAGS 18 | open location theURL 19 | -- delay 1 20 | close current tab of window 1 21 | end tell 22 | 23 | return TASK_PREFIX & theSubject 24 | end alfred_script 25 | -------------------------------------------------------------------------------- /Things/AddTaskFromMail.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | Adds a new task to Things. (For use with Alfredapp: alfredapp.com and Arimail: airmail.com) 3 | *) 4 | property TODO_TAGS : "Import,Mail" 5 | property ADD_CONTACT : true 6 | property TASK_PREFIX : "Act on: " 7 | 8 | on alfred_script(q) 9 | tell application "Mail" 10 | set theMail to first item of (get selection) 11 | set theSubject to subject of theMail 12 | set theMessage to "message://<" & (message id of theMail as rich text) & ">" 13 | set theSender to sender of theMail 14 | end tell 15 | 16 | (*if ADD_CONTACT then 17 | tell application "Contacts" 18 | set theNames to name of (people whose value of emails contains theSender) 19 | if (count theNames) is 0 then 20 | set theSender to null 21 | else 22 | set theSender to first item of theNames 23 | end if 24 | end tell 25 | else 26 | set theSender to null 27 | end if*) 28 | 29 | tell application "Things" 30 | set theTodo to make new to do with properties {name:TASK_PREFIX & theSubject, notes:theMessage & return, status:open, tag names:TODO_TAGS} at end of list "Inbox" 31 | 32 | (*if theSender is not null then 33 | set theContact to add contact named theSender 34 | move theTodo to theContact 35 | end if*) 36 | end tell 37 | 38 | return TASK_PREFIX & theSubject 39 | end alfred_script -------------------------------------------------------------------------------- /Things/Contacts.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | Adds a contact with the name q to the list of contacts in Things. 3 | If q is empty or the keyword "clean", all contacts without assigned tasks 4 | are removed from Things. 5 | *) 6 | on alfred_script(q) 7 | if q is "clean" or q is "" then 8 | tell application "Things" 9 | set theContacts to contacts 10 | repeat with aContact in theContacts 11 | set theTodos to (every to do of aContact whose status is open) 12 | if (count of theTodos) is 0 then 13 | delete aContact 14 | end if 15 | end repeat 16 | end tell 17 | return "Contacts cleaned" 18 | else 19 | tell application "Things" to set newContact to add contact named q 20 | if newContact is missing value then 21 | return "Error: No contact named " & q & " found" 22 | else 23 | return "Contact " & q & " added" 24 | end if 25 | end if 26 | end alfred_script -------------------------------------------------------------------------------- /Things/ParseQuery.applescript: -------------------------------------------------------------------------------- 1 | -- parsequery.scpt -- Author: Jonas Neugebauer -- Version: 1.0 -- log parse_query("#tag1 #tag2 My Title [Important project] ::This is very important >01.01.2012") (* Parses a query string of the form #tag1 #tag2 title [project name] ::descr >due date to a named list with - tags: a list of tags as strings - title: the title as string - project: the project name as string - descr: the description as string - due: the due date as date object Every part except the name is optional and will be null in the result list if ommited (the tags will be an empty list) *) on parse_query(q) set title to "" set tags to [] set project to null set descr to null set due to null set projMode to false set descrMode to false set AppleScript's text item delimiters to {" "} set qElems to every text item of q repeat with elem in qElems set fc to character 1 of elem set lc to character -1 of elem if fc = ">" then set descrMode to false set d to text 2 thru -1 of elem as text try set due to date d end try else if fc = "#" then set descrMode to false set tag to text 2 thru -1 of elem as text set tags to tags & [tag] else if fc = "[" then set descrMode to false set projMode to true if lc = "]" then set project to (text 2 thru -2 of elem as text) set projMode to false else set project to (text 2 thru -1 of elem as text) end if else if lc = "]" then set projMode to false set project to (project & space & (text 1 thru -2 of elem as text)) else if projMode = true then set project to (project & space & elem) else if fc = ":" and (character 2 of elem = ":") then set descrMode to true set descr to (text 3 thru -1 of elem as text) else if descrMode = true then set descr to (descr & space & elem) else if (count of title) = 0 then set title to elem else set title to (title & space & elem) end if end if end repeat return {title:title, tags:tags, project:project, descr:descr, due:due} end parse_query -------------------------------------------------------------------------------- /Things/ShowTodayTasks.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | Displays a dialog with a list of all tasks in the today list 3 | *) 4 | 5 | set grwlTitle to "0 Tasks for today" 6 | set taskList to "No tasks left for today" 7 | 8 | tell application "Things" 9 | set todayCount to (count to do of list "Today") 10 | set todayTasks to to dos of list "Today" 11 | 12 | if todayCount is greater than 0 then 13 | set grwlTitle to (todayCount & " tasks for today") as text 14 | set taskList to "" 15 | repeat with taskItem in todayTasks 16 | set taskName to name of taskItem 17 | if taskList is "No tasks left for today" then 18 | set taskList to "- " & taskName 19 | else 20 | set taskList to taskList & return & "- " & taskName 21 | end if 22 | end repeat 23 | end if 24 | end tell 25 | 26 | display dialog grwlTitle & return & taskList with title "ShowTodayTasks" 27 | -------------------------------------------------------------------------------- /Things/ShowTodayTasksCount.applescript: -------------------------------------------------------------------------------- 1 | (* Displays dialog with a list of all tasks in the today list *) set grwlTitle to "0 Tasks for today" set taskList to "No tasks left for today" set finished to 0 set unfinished to 0 tell application "Things" set todayCount to (count to do of list "Today") set todayTasks to to dos of list "Today" if todayCount is greater than 0 then set grwlTitle to (todayCount & " tasks for today") as text set taskList to "" repeat with taskItem in todayTasks set taskName to name of taskItem if taskList is "No tasks left for today" then set taskList to "- " & taskName else set taskList to taskList & return & "- " & taskName end if if status of taskItem is in [completed, canceled] then set finished to finished + 1 if status of taskItem is open then set unfinished to unfinished + 1 end repeat end if end tell display notification (unfinished & " tasks open" as text) with title grwlTitle subtitle (finished & " tasks already finished today. great job! 👍" as text) -------------------------------------------------------------------------------- /_README.md: -------------------------------------------------------------------------------- 1 | # osx-script-stuff 2 | 3 | A collection of scripts to automate stuff on Max OS X systems. 4 | -------------------------------------------------------------------------------- /build_docs.py: -------------------------------------------------------------------------------- 1 | import os, glob, re, yaml 2 | from subprocess import call 3 | 4 | GLOB = '**/*.*' # Glob pattern to use for including files 5 | TARGET = 'README.md' # Target file to generate 6 | TEMPLATE = '_README.md' # Template to include as a header 7 | MARKED = True # Generate Marked compatible IDs 8 | DEBUG = True # Print some more info for debugging 9 | 10 | TAGS = { 11 | '.applescript': ['(*', '*)'], 12 | '.sh': ['# '], 13 | '.py': ['# '], 14 | '.js': ['/*', '*/'] 15 | } 16 | APPS = { 17 | 'Alfred': 'http://alfredapp.com', 18 | 'TextExpander': 'https://smilesoftware.com/TextExpander/index.html', 19 | 'Airmail 2': 'http://airmailapp.com', 20 | 'CommonMark': 'http://commonmark.org', 21 | 'Markdown': 'https://daringfireball.net/projects/markdown/', 22 | 'Tag': 'https://github.com/jdberry/tag/', 23 | 'Mail': 'https://www.apple.com/support/mac-apps/mail/', 24 | 'iTunes': 'https://www.apple.com/support/mac-apps/iTunes/' 25 | } 26 | COMPILER = { 27 | '.applescript': { 28 | 'call': 'osacompile -x -o %s %s', 29 | 'filename': '%s.scpt' 30 | } 31 | } 32 | 33 | def parseBlockComment(file, tagOpen, tagClose): 34 | yml = '' 35 | f = open(file, 'r') 36 | try: 37 | if f.readline().startswith(tagOpen): 38 | for line in f: 39 | if line.startswith(tagClose): 40 | break; 41 | yml += line 42 | finally: 43 | f.close(); 44 | return yml 45 | 46 | 47 | def parseLineComment(file, tag): 48 | yml = '' 49 | f = open(file, 'r') 50 | try: 51 | line = f.readline() 52 | # Deal with shebangs 53 | if line.startswith('#!'): 54 | line = f.readline() 55 | if line.startswith(tag): 56 | yml += line[len(tag):] 57 | for line in f: 58 | if not line.startswith(tag): 59 | break; 60 | yml += line[len(tag):] 61 | finally: 62 | f.close(); 63 | return yml 64 | 65 | 66 | _IDS = [] 67 | def makeId(label): 68 | _id = re.sub(r'\s+', '-', label.lower()) 69 | _id = re.sub(r'\.', '', _id) 70 | 71 | __id = _id 72 | i = 1 73 | while _id in _IDS: 74 | if MARKED: 75 | if i == 1: 76 | i = 2 77 | _id = '%s%s' % (__id, i) 78 | else: 79 | _id = '%s-%s' % (__id, i) 80 | i += 1 81 | _IDS.append(_id) 82 | return _id 83 | 84 | Y = {} 85 | IDS = {} 86 | files = glob.glob(GLOB) 87 | for file in files: 88 | name, ext = os.path.splitext(file) 89 | 90 | if ext in TAGS: 91 | yml = '' 92 | if len(TAGS[ext]) == 2: 93 | yml = parseBlockComment(file, TAGS[ext][0], TAGS[ext][1]) 94 | else: 95 | yml = parseLineComment(file, TAGS[ext][0]) 96 | 97 | if not yml == '': 98 | try: 99 | yml = yaml.load(yml) 100 | if 'name' in yml and 'description' in yml: 101 | Y[file] = yml 102 | IDS[file] = makeId(yml['name']) 103 | except Exception as e: 104 | if DEBUG: 105 | print('\x1b[0;31m>\x1b[0m couldn\'t parse frontmatter for \x1b[0;35m%s\x1b[0m' % file) 106 | print('\x1b[0;31m=>\x1b[0m %s' % e) 107 | pass 108 | else: 109 | if DEBUG: 110 | print('\x1b[0;31m>\x1b[0m skipped \x1b[0;35m%s\x1b[0m, extension \x1b[0;35m%s\x1b[0m not registered' % (file, ext)) 111 | 112 | T = open(TARGET, 'w') 113 | 114 | INDEX = {} 115 | 116 | # Generate header 117 | header = open(TEMPLATE).read(); 118 | T.write(header); 119 | T.write('\n\n') 120 | print('\x1b[0;32m>\x1b[0m Added headers from \x1b[0;35m%s\x1b[0m to documentation' % TEMPLATE) 121 | 122 | # Generate TOC 123 | T.write('## Table of contents\n\n') 124 | T.write('1. [Scripts](#scripts)\n') 125 | for file, yml in iter(sorted(Y.items())): 126 | T.write('\t- [%s](#%s)\n' % (yml['name'], IDS[file])) 127 | T.write('2. [App Index](#app-index)\n') 128 | T.write('3. [Script Index](#script-index)\n') 129 | T.write('\n') 130 | print('\x1b[0;32m>\x1b[0m Created table of contents') 131 | 132 | # Generate docs 133 | T.write('## Scripts\n\n') 134 | for file, yml in iter(sorted(Y.items())): 135 | def make_link(app): 136 | if app in APPS: 137 | return '[%s](%s)' % (app, APPS[app]) 138 | else: 139 | return app 140 | apps = [a.strip() for a in yml['apps'].split(',')] 141 | for app in apps: 142 | if not app in INDEX: 143 | INDEX[app] = [file] 144 | else: 145 | INDEX[app].append(file) 146 | apps = map(make_link, apps) 147 | 148 | T.write('### %s\n' % yml['name']) 149 | T.write('%s\n\n' % yml['description']) 150 | 151 | T.write('- Apps: %s\n' % ', '.join(apps)) 152 | T.write('- File: [_%s_](./%s)\n' % (file, file)) 153 | if 'parameters' in yml and not yml['parameters'] == None and len(yml['parameters']) > 0: 154 | T.write('- Parameters:\n') 155 | for param, descr in yml['parameters'].items(): 156 | # T.write('- **%s** \n\t%s\n' % (param, descr)) 157 | T.write('\t- **%s**: %s\n' % (param, descr)) 158 | 159 | print('\x1b[0;32m>\x1b[0m Added \x1b[0;35m%s\x1b[0m to documentation' % file) 160 | 161 | name, ext = os.path.splitext(file) 162 | if 'compile' in yml and yml['compile'] == True and ext in COMPILER: 163 | newfile = COMPILER[ext]['filename'] % name 164 | call(COMPILER[ext]['call'] % (newfile, file), shell=True) 165 | T.write('- Binary: [_%s_](./%s)\n' % (newfile,newfile)) 166 | 167 | print('\x1b[0;32m=>\x1b[0m Created binary at \x1b[0;35m%s\x1b[0m' % newfile) 168 | 169 | T.write('\n\n') 170 | 171 | # Generate index 172 | T.write('## App Index\n\n') 173 | for app, files in iter(sorted(INDEX.items())): 174 | T.write('- **%s** \n\t' % app) 175 | T.write(', '.join(['[%s](#%s)' % (Y[file]['name'], IDS[file]) for file in files])) 176 | T.write('\n') 177 | T.write('\n') 178 | print('\x1b[0;32m>\x1b[0m Created application index') 179 | 180 | # Generate alphabetical script index 181 | lastChar = '' 182 | T.write('## Script Index\n\n') 183 | for file, yml in iter(sorted(Y.items(), key=lambda x: x[1]['name'])): 184 | if not yml['name'][0:1] == lastChar: 185 | lastChar = yml['name'][0:1].upper() 186 | T.write('\n- **%s** \n\t' % lastChar) 187 | T.write('[%s](#%s)' % (yml['name'], IDS[file])) 188 | else: 189 | T.write(', [%s](#%s)' % (yml['name'], IDS[file])) 190 | T.write('\n') 191 | print('\x1b[0;32m>\x1b[0m Created script index') 192 | 193 | T.close() 194 | -------------------------------------------------------------------------------- /iTunes/RefreshSelection.applescript: -------------------------------------------------------------------------------- 1 | (* 2 | name: Reindex tags of selected songs in iTunes 3 | apps: iTunes 4 | description: > 5 | Reindex the songs currently selected in iTunes. For easy 6 | use put into `~/Library/iTunes/Scripts/`. 7 | parameters: 8 | compile: true 9 | *) 10 | tell application "iTunes" 11 | set aList to selection 12 | set numberOfItems to count of aList 13 | 14 | display notification "Refreshing " & numberOfItems & " items. This may take a while.." with title "iTunes refresh Selection" 15 | refresh selection 16 | display notification "Done refreshing " & numberOfItems & " items." with title "iTunes refresh Selection" 17 | end tell 18 | -------------------------------------------------------------------------------- /iTunes/RenameMusic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | FILE="$1" 4 | 5 | # Get ID3 tags 6 | IFS=' 7 | ' 8 | TAGS=($(/usr/local/bin/exiftool -s3 -f -Artist -Band -Album -Title -Track -PartOfSet -Compilation "$FILE")) 9 | 10 | # Build new filename 11 | TITLE=${TAGS[3]} 12 | TRACK=${TAGS[4]/\/*/} 13 | if [ "$TRACK" != "-" ] ; then 14 | # Zero-pad track number to two digits 15 | TRACK=`printf "%02s\n" "$TRACK"` 16 | # if number of cds is set, check if > 1 17 | if [[ ${TAGS[5]} == *"/"* ]] ; then 18 | TOTAL="${TAGS[5]/*\//}" 19 | if [ ${TOTAL} -gt 1 ] ; then 20 | TRACK="${TAGS[5]/\/*/}-$TRACK" 21 | fi 22 | fi 23 | else 24 | TRACK="" 25 | fi 26 | NAME="$TRACK $TITLE.${FILE##*.}" 27 | 28 | # Build new path 29 | ARTIST="Unknown" 30 | ALBUM="Unknown" 31 | if [ ${TAGS[1]} != "-" ] ; then 32 | ARTIST=${TAGS[1]} 33 | else 34 | if [ ${TAGS[6]} == "Yes" -o ${TAGS[6]} == "1" ] ; then 35 | ARTIST="Compilation" 36 | else 37 | if [ ${TAGS[0]} != "-" ] ; then 38 | ARTIST=${TAGS[0]} 39 | fi 40 | fi 41 | fi 42 | if [ ${TAGS[2]} != "-" ] ; then 43 | ALBUM=${TAGS[2]} 44 | fi 45 | 46 | FL=${ARTIST//[^A-Za-z0-9]/} 47 | FL=${FL/#The/} 48 | FL=${FL:0:1} 49 | if [ -z $FL ] ; then 50 | FL="_" 51 | fi 52 | 53 | PATH="$(dirname $FILE)/$FL/$ARTIST/$ALBUM" 54 | /bin/mkdir -p "$PATH" 55 | /bin/mv -f "$FILE" "$PATH/$NAME" 56 | --------------------------------------------------------------------------------