Default Application für alle Dateien eines Typs setzen

Ich musste für ein Skript die default Application für XML-Dateien ändern und das beim ersten Aufruf des AppleScripts….
dieser Code

on setDefaultApplication()
  set myApp to " LSHandlerRoleAll = \"com.hubionmac.makemylist\""
  set xml to "public.xml"
  set changed to false
  
  if getDefaultApplicatonFor(xml) does not contain myApp then
    do shell script "defaults write com.apple.LaunchServices LSHandlers -array-add '{LSHandlerContentType = \"public.xml\";LSHandlerRoleAll = \"com.hubionmac.makemylist\";}'"
    set changed to true
  end if
  if changed is true then
    do shell script "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user"
    display alert "XML werden nun automatisch mit MakeMyList zuerst geöffnet."
    quit
  end if
end setDefaultApplication

on getDefaultApplicatonFor(filetype2Search)
  try
    repeat with i from 0 to 5
      set thegrep to do shell script "defaults read com.apple.LaunchServices 'LSHandlers' | grep -A " & i & " '" & filetype2Search & "'"
      if last paragraph of thegrep contains "}" then
        return thegrep
      end if
    end repeat
  end try
  return ""
end getDefaultApplicatonFor

									


funktioniert soweit zwar, hat aber die entsprechende com.apple.LaunchServices.plist etwas unaufgeräumt zurückgelassen. So war nach dem Edit auf einmal für csv-Dateien ein doppelter Eintrag zu finden, das Ergebnis war also ein kleine Chaos, was dem Nutzer selbst nicht unbedingt auffallen muss.
Eine deutlich elegantere Lösung scheint da duti zu sein. Diese kleine Terminal-Programm kann einfach über die Zeile duti -s com.hubionmac.makemylist xml all das selbe erreichen. Und mit duti -x xml gibt es auch gleich Auskunft über die aktuelle Default-Application.
Also defaults write.appe LaunchServices sucks!
duit rocks!

Urlaubstage in iCal zählen

Ist ein kleines Skript um Urlaubstage zu zählen. Das Skript zählt alle All-Day-Events die das Schlüsselwort Urlaub enthalten… gezählt werden aber  alle Tage ausser Samstag und Sonntag…

##©hubionmac.com 17.02.2013 -Urlaubstage zählen
set myweekdays to {Monday, Tuesday, Wednesday, Thursday, Friday}
set triggerString to "urlaub"
set urlaubscount to 0
tell application "iCal"
  set thecal to my returntheCal()
  tell thecal
    set e to every event
    repeat with i from 1 to count of e
      set te to item i of e
      if summary of te contains triggerString then
        set s to start date of te
        set enddate to end date of te
        repeat until s ≥ enddate
          
          set currentday to weekday of s
          if currentday is in myweekdays then
            set urlaubscount to urlaubscount + 1
            
          end if
          set s to s + 86400
        end repeat
      end if
    end repeat
  end tell
  activate
  display dialog "Habe " & urlaubscount & " Ulaubstage gezählt, exklusive Samstage und Sonntage"
end tell


on returntheCal()
  tell application "iCal"
    set writeableCals to every calendar whose writable is true
    set nonWriteableCals to every calendar whose writable is false
    set writeableCalNames to {}
    set writeableCalIDs to {}
    set nonwriteableCalNames to {}
    set nonwriteableCalIDs to {}
    repeat with i from 1 to count of writeableCals
      set writeableCalNames to writeableCalNames & {(i & ": " & name of item i of writeableCals as text)}
      set writeableCalIDs to writeableCalIDs & {uid of item i of writeableCals}
    end repeat
    repeat with i from 1 to count of nonWriteableCals
      set nonwriteableCalNames to nonwriteableCalNames & {("_" & i & ": " & name of item i of nonWriteableCals as text)}
      set nonwriteableCalIDs to nonwriteableCalIDs & {uid of item i of nonWriteableCals}
    end repeat
    set thecalname to (choose from list writeableCalNames & nonwriteableCalNames) as text
    if thecalname does not start with "_" then
      set theIndex to (word 1 of thecalname) as integer
      set thecalID to item theIndex of writeableCalIDs
    else
      set thecalname to (characters 2 through -1 of thecalname) as text
      set theIndex to (word 1 of thecalname) as integer
      set thecalID to item theIndex of nonwriteableCalIDs
    end if
    set thecal to calendar id thecalID of application "iCal"
  end tell
end returntheCal
									

Bonjour-Link-Liste erstellen

Meine Remote-Desktop-Lizenz ist mal wieder abgelaufen und mal ehrlich, mehr als mal kurz einloggen und vielleicht die Zwischenablage übertragen mache ich mit dem Ding nicht. Da wäre es doch einfacher alle betreffenden Rechner als vnc.webloc abzuspeichern.
Das gleiche nur direkt als Menü macht ScreenSharingMenulet von Stefan Klieme, nur ist das nicht mehr umsonst und wenn ich damit die Clients aufrufe, kann ich so oft ich möchte das Kennwort speichern, er fragt jedes mal. Ausserdem ist die Liste einfach zu lang, wenn man sich in größeren Netzwerken aufhält =)
Das Skript hier macht also folgendes:

  • Es fragt ab nach welchem Bonjour-Services gesucht werden soll
  • listet anschließend alle Clients auf, die den gewählten Service im LAN anbieten
  • Diese können dann in einer Liste ausgewählt werden und das Skript erstellt einen entsprechenden Ordner auf dem Schreibtisch, in dem sich dann die entsprechenden Weblocs befinden.

Beim ersten Verbindung muss man vielleicht noch das Kennwort im Schlüsselbund abspeichern, aber das war es dann auch schon. Ist ein schönes Beispiel, wie man Bonjour-Informationen in der Shell verarbeiten kann.

##©hubionmac.com 2013-01-06 tested using 10.7.5
##Create webloc, afploc, vncloc files via bonjour list


## A simple Text Liste seperated with  tab
set serviceList to "Remote Desktop  _net-assistant._udp  vnc://
AFP  _afpovertcp._tcp  afp://"
set theselection to (choose from list every paragraph of serviceList) as text
if theselection ≠ "false" then
  set AppleScript's text item delimiters to "  "
  set service_name to text item 1 of theselection
  set Service_Name_Bonjour to text item 2 of theselection
  set Service_protocol to text item 3 of theselection
  
  set AppleScript's text item delimiters to ""
  
  ## get the .local hostenames of all Bonjour Clients running the selected Service
  set BonjourClientNames to return_bonjournames_running(Service_Name_Bonjour)
  if BonjourClientNames ≠ false then
    ##make a new folder at the desktop for all the weblocs  
    tell application "Finder"
      try
        set thefolder to make new folder at desktop with properties {name:service_name}
      on error
        set thefolder to folder service_name of desktop
        ## move all old weblocs into the trash
        move every item of thefolder to trash
      end try
    end tell
    ##create the weblocs (passwords can be stored in the keychain later on)
    repeat with theName in BonjourClientNames
      my makeWebloc(Service_protocol & theName & ".local", thefolder, theName)
    end repeat
  end if
end if


on return_bonjournames_running(service_name)
  ##Bonjour Namen herausfinden (die stehen im Sharing klartext mit allen Sonderzeichen)
  set myoutput to {}
  set expectCode to "
spawn -noecho dns-sd -B " & service_name & "
expect -timeout 5 eof {}
"
  set thescan to do shell script "echo " & quoted form of expectCode & "|/usr/bin/expect -f - | awk -F '" & service_name & ".' '{print $2}'"
  repeat with thescanline in every paragraph of thescan
    set thescanline to my delete_space(thescanline as text)
    if thescanline ≠ "" then
      set myoutput to myoutput & thescanline
    end if
  end repeat
  set myoutput to choose from list myoutput with multiple selections allowed
  if myoutput ≠ false then
    ##nun eigentlichen Host-Namen herausfinden, die enthalten keine Sonderzeichen bzw. können auch ganz anders lauten
    repeat with i from 1 to count of myoutput
      set expectCode to "
spawn -noecho dns-sd -L " & item i of myoutput & " " & service_name & " local
expect -timeout 1 eof {}
"
      set thescan to do shell script "echo " & quoted form of expectCode & "|/usr/bin/expect -f - | awk -F 'can be reached at ' '{print $2}'"
      repeat with theline in every paragraph of thescan
        if theline contains ".local" then
          set AppleScript's text item delimiters to ".local"
          set item i of myoutput to text item 1 of theline
          set AppleScript's text item delimiters to ""
        end if
      end repeat
      
    end repeat
  end if
  return myoutput
end return_bonjournames_running


on delete_space(thestring)
  repeat with i from 1 to count of characters of thestring
    if last character of thestring = " " then
      set thestring to (((characters 1 through -2 of thestring) as text) as text)
      set is_modified to true
    else
      exit repeat
    end if
  end repeat
  repeat with i from 1 to count of characters of thestring
    if first character of thestring = " " then
      set thestring to (((characters 2 through -1 of thestring) as text) as text)
      set is_modified to true
    else
      exit repeat
    end if
  end repeat
  return thestring
end delete_space

on makeWebloc(theURL, thefolder, theName)
  tell application "Finder" to set webloc to make new internet location file to theURL at thefolder with properties {name:theName}
end makeWebloc
									

Wenn USB Tethering nach einem iTunes Update nicht mehr funktioniert…

iTunes 10.7 scheint einen USB-Ethernet Treiber zu überschreiben und damit funktioniert USB-Tethering nicht mehr. Lösen kann man es indem man den Treiber wiederherstellt.
/System/Library/Extensions/AppleUSBEthernetHost.kext/Contents/MacOS/AppleUSBEthernetHost
Dann noch die Benutzerrechte reparieren und es soll wieder funktionieren.

Transmit: Minify js + css mit YUI-Compressor.jar

Für Textmate (zumindest für die 1er Version) gibt es ein Plug-In zum minimieren von Javascript und Stylesheet Dateien, welches auf Basis von Yahoo’s yuicompressor die Zeilenumbrüche herausfiltert…
Praktisch aber auch etwas umständlich vom handling. Und Smaller kostet gesalzene 20$.
Deshalb hier meine eigene Quick&Dirty Lösung zum Minimieren von .js und .css Dateien in Transmit:
Datei ausfwählen -> wird geladen -> minimiert und als _min. wieder ins gleiche Verzeichnis geladen.

set tmp to path to "temp"
set tmp_posix to POSIX path of tmp
set myyui to path to resource "yuicompressor-2.4.7.jar"
set myyui_posix to POSIX path of myyui
tell application "Transmit"
  tell current tab of document 1
    tell remote browser
      repeat with thisItem in selected browser items
        set currentName to name of thisItem
        download item at path (get path of thisItem) to tmp_posix with resume mode overwrite
      end repeat
    end tell
  end tell
end tell

tell application "Finder"
  set this to (item currentName of tmp) as alias
  set this_type to ""
  set this_name to name of this
  if (this_name as text) ends with ".css" then
    set this_type to "css"
    set this_name to (characters 1 through -5 of this_name) as text
  else if (this_name as text) ends with ".js" then
    set this_type to "js"
    set this_name to (characters 1 through -4 of this_name) as text
  else
    ##        display alert (this_name)
  end if
  
  if this_type ≠ "" then
    set this_posix to POSIX path of this
    set this_folder to (do shell script "dirname " & quoted form of this_posix) & "/"
    set mycommand to "java -jar " & quoted form of myyui_posix & " --nomunge --type " & this_type & " " & quoted form of this_posix & " > " & quoted form of this_folder & quoted form of this_name & "_min." & this_type
    do shell script mycommand
  end if
end tell

tell application "Transmit"
  tell current tab of document 1
    tell remote browser
      upload item at path tmp_posix & this_name & "_min." & this_type to (get root path)
    end tell
  end tell
end tell

									


Der Code ist der eines Skript-Bundles in dem sich das YUI-Compressor.jar auch befindet… am besten direkt alles laden
[Download not found]

Carbon Copy Cloner .cccerrors export

Kommt es beim Klonen einer HD mit dem Carbon Copy Cloner zu Fehlern, kann man die Liste der nicht kopierten Dateien als .cccerrors-Datei sichern. Dummerweise handelt es sich dabei um eine binär kodierte plist und das einfach Kopieren aller Dateipfade bei denen es Probleme gab, ist schlicht kein Feature der Software (so scheint es mir).
Nun, dieses Quick&Dirty-Droplet konvertiert die plist und kopiert alle DateiPfade daraus in die Zwischenablage.

on open these
  repeat with this in these
    set XMLfile to POSIX path of (this)
    if XMLfile ends with ".cccerrors" then
      set theoutput to do shell script "plutil -convert xml1 " & quoted form of XMLfile & ";cat " & quoted form of XMLfile & "| awk '/affectedItem/{getline; print}'"
      set theoutput to replace_chars(theoutput, "  ", "")
      set theoutput to replace_chars(theoutput, "<string>", "")
      set theoutput to replace_chars(theoutput, "</string>", "")
      set a to every paragraph of theoutput
      set theoutput to {}
      repeat with b in a
        if theoutput does not contain b then
          set theoutput to theoutput & b
        end if
      end repeat
      set AppleScript's text item delimiters to "
"
      set theoutput to theoutput as text
      set AppleScript's text item delimiters to ""
      set the clipboard to theoutput
      display dialog (count of every paragraph of theoutput) & " lines in the clipboard" as text
      exit repeat
    end if
  end repeat
end open
on replace_chars(this_text, search_string, replacement_string)
  if this_text contains the search_string then
    set od to AppleScript's text item delimiters
    set AppleScript's text item delimiters to the search_string
    set the item_list to every text item of this_text
    set AppleScript's text item delimiters to the replacement_string
    set this_text to the item_list as string
    set AppleScript's text item delimiters to od
  end if
  return this_text
end replace_chars

									


[Download not found]

iCal Export als Tabelle (Excel)

Roman wollte einen Export der Termin-Daten aus iCal in Excel. Hier ein einfacher Code, der einen Export alles nicht-Gantags-Events erstellt
Datum -> Bezeichnung -> Länge in min

## 27.10.2012 hubionmac.com
## Exportiert eine Liste alle (nicht Ganztags-Events) als Tab-Liste (Datum | Bezeichnung | Dauer in Minuten)
tell application "iCal"
  set chooselist to {}
  repeat with i from 1 to count of every calendar
    set chooselist to chooselist & {(i & " : " & name of calendar i) as text}
  end repeat
  set CalId to ((word 1 of ((choose from list chooselist) as text)) as integer)
  
  tell calendar CalId
    set myOutput to "Datum\tBezeichnung\tDauer(min)\n"
    repeat with calEvent in (get every event whose allday event is false)
      set myduration to (((end date of calEvent) - (start date of calEvent)) / 60 as miles) as string
      set myOutput to myOutput & my getDatestring(start date of calEvent) & tab & summary of calEvent & tab & myduration & "\n"
    end repeat
  end tell
  set the clipboard to
end tell

on getDatestring(d)
  return year of d & "-" & ((month of d) as integer) & "-" & day of d as text
end getDatestring