






Archive for the 'mac os x' Category
Download AirPortClown as pure Cocoa for Mac OS X 10.6.4 (64 bit)
Update: I made a Cocoa App for this. The AppleScript is obsolete.
So I found Ryans Automator to do this at iamthekiller but it was not 100% perfect, so I added some of JosteinB’s suggestions from his blog and out came an AppleScript Application called AirPortClown, which you can download here:
And it looks something like this:

The source code is of course included in the download. MacDaddyX didn’t work for me and aaspoof is Shareware.
Update: If you look though the comments you will see that there is still some development going on, this version up here is for OS X 10.6.3 and 10.6.4 but you can download the version for OS X 10.6.2 here. Make sure your Airport is turned ON first when using the latest version.
Manchmal möchte man seine Ruby-on-Rails-Applikation im Passenger manuell neu starten. Sprich eine Datei my_app/tmp/restart.txt anlegen. Ich habe ein kleines Command-Skript für TextMate dafür geschrieben. Wenn man es ausführt (in diesem Beispiel mit APFEL+R), wird beim nächsten Browseraufruf alles neu geladen. Praktisch wenn man Plugins entwickelt :)
Hier der Command in TextMate:

Und hier der Code dafür
18 19 20 21 22 23 24 | #!/usr/bin/env ruby require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/rails_bundle_tools.rb" f = File.open File.join(RailsPath.new.rails_root, "tmp", "restart.txt"), "w" f.close puts "Rails Application will be reloaded!" |
Gleich vorweg: Es kostet dich deine Apple-TV-Garantie und ein 2,5″ externes Festplattengehäuse (IDE, oder neu-deutsch: PATA). Aber: Es war’s wert.
Denn plötzlich war iTunes leer (lange Geschichte) und das einzige Backup war… der Apple TV! Der wurde natürlich sofort ausgesteckt, weil der sich sonst wieder synchronisiert hätte und dort auch alles futsch gewesen wäre.
1. Festplatte vom Apple TV ausbauen
Dafür hätte ich nicht einmal eine der zahlreichen Anleitungen benötigt, denn die acht Schrauben (T8 und T10) stellten kein sonderliches Problem dar :) Natürlich musste ich zuerst die aufgekleisterte Gummi-Bodenplatte abmachen. Das ging jedoch ohne Sauerei und man kann die wieder ankleben. Aber vorsicht: Die reißt sehr schnell ;)
2. Externes Gehäuse für 2,5 Zoll IDE (=PATA) kaufen
Schnell gemacht. Kostet 12 Euro ;)
3. Apple TV Festplatte einbauen und am Mac anschließen
Die Platte soll natürlich nicht von Spotlight indiziert werden! Dafür hält man sich ganz ganz schnell folgende zwei Terminal-Befehle bereit und feuert sie ab, sobald die Platte (und ihre beiden Partitionen Media und OSBoot) erkannt wurde.
touch /volumes/Media/.metadata_never_index
touch /volumes/OSBoot/.metadata_never_index
Wichtig: Platte abklemmen und wieder anklemmen, Spotlight wird seine Änderungen die er in den ersten Sekunden gemacht hat wieder rückgängig machen.
4. Drag’n'Drop der AppleTV Media Files in iTunes
Die Dateien auf dem Apple TV haben zwar die gleiche Struktur wie das iTunes Verzeichnis eines jeglichen Macs, jedoch sind die Dateinamen alle nur ein paar kryptische Buchstaben á la DDHX.mp3, NKKZ.mp3 usw. Das ist iTunes beim Import zum Glück egal, denn alle Metainformationen (inkl. Cover) sollten IN den einzelnen Dateien enthalten sein.
5. Apple TV wieder zusammen bauen, anklemmen, synchronisieren, läuft.
PS: Bei der Gelegenheit fragt man sich natürlich, ob es nicht so schwer sein könnte, einfach eine größere Festplatte in den Apple TV einzubauen ;)
Ich wollte mal das Spiele programmieren anfangen. Matthias schlug C++ vor, so sollte es C++ sein. Dank dieser Anleitung habe ich dann auch schon angefangen diese Tutorials durchzugehen. Das macht auch sehr viel Spaß.
Nun benutze ich g++ und nicht Xcode. Damit ich das kompilieren auch schön in Textmate automatisiert ist, habe ich mir zwei Bundles dafür geschrieben (bzw. angepasst).
Man öffnet also in TextMate den BundleEditor und dupliziet den C++ Command namens “Compile Single File to Tool”, nennt die Kopie in z. B. “Datei kompilieren” um und passt die letzten Zeilen so an, dass sie so aussehen:
1 2 | puts %x{ "#{cc}" -o "#{FileNoExtension}".bin "$TM_FILEPATH" -lSDL -lSDLmain -framework cocoa} puts "Successfully created #{FileNoExtension}.bin" unless $CHILD_STATUS != 0 |
Dann legt noch einen schönen Shortcut fest, z. B. Apfel + E:
Damit wird die aktuelle Datei die wir bearbeiten in dateiname.bin kompiliert, sobald wir Apfel + E drücken.
Dann machen wir noch eine Kopie von diesem Command und nennen diese z. B. “Kompilierte Datei ausführen” und die letzten Zeilen sollen so aussehen:
1 2 | puts %x{ "./#{FileNoExtension}.bin" } puts "Yeah!" unless $CHILD_STATUS != 0 |
Dann machen wir das z. B. auf Apfel + R (vorsicht, dass ist der Build-Befehl wenn man XCode verwendet.)
Jetzt braucht man beim programmieren nur noch APFEL + E und dann APFEL + R drücken.
Naja, und dann taste ich mich doch erst mal hier ran ;)
Hier soll eine Liste mit nützlichen Terminal Befehlen entstehen, da man so manche einfach jedes mal vergisst und dann suchen muss.
Nameserver einer Domain herausfinden
nslookup funkensturm.de
MX Record einer Domain herausfinden
nslookup -query=mx funkensturm.de
DNS Cache flushen
dscacheutil -flushcache
Prozesse (zu einem Command) mit PID’s herausfinden
ps aux | grep -i ruby
| grep -i command nur wenn man die Prozesse zu einem Command haben will
Prozesse beenden
kill -9 PID
killall command
mit den zwei fang ich mal an. Wird aber immer schön erweitert. Wenn ihr welche habt einfach in die Comments!
Update: Eigentlich hat sich der Post erledigt, aus historischen Gründen lass ich ihn stehen.
Um IE’s zu testen, nutze ich jetzt http://meineipadresse.de/netrenderer/.
_________________
Es gibt zwar Bootcamp und Parallels aber manchmal will man ja vielleicht nur kurz schauen, ob die Webseite auch im IE irgendwie so aussieht, wie sie das soll. Dafür neu zu booten oder sich von Parallels den Ram auffressen lassen, ist dann nicht immer der super Weg. Deshalb habe ich mich mal ein bisschen umgeschaut und bin auch fündig geworden. Das gute ist, man hat nicht nur den IE6 oder IE7 sondern jede IE Version die man gerne haben möchte. Wie irgendwo auf der Webseite zu lesen ist: “Versuch das mal unter Windows richtig hin zu bekommen…”
Wichtig: das ganze geht leider nur mit Intel Macs.
ies4osx
Ein Besuch auf der Webseite genügt eigentlich, denn da ist schon super erklärt, wie alles geht aber ich schreib hier noch mal kurz zusammen, was zu tun ist.
1. X11 installieren. Ich glaube bei Leopard ist das schon dabei, die anderen müssen auf der Tiger Install Disk 1 “Installiere sonstige Bundles” ausführen und da dann durch klicken (keine Sorge ihr könnt später auswählen, was ihr wirklich installieren wollt) und da dann irgendwann X11 auswählen und installieren.
2. Darwine downloaden und installieren (auch hier gibt es ne schöne Erklärung mit Bildern)
3. ies4osx downloaden und installieren und die benötigten IE’s auswählen. Die Sachen für die IE’s müssen runter geladen werden, deshalb dauert es ein bisschen aber dann is es auch schon fertig.
4. den entsprechenden Internet Explorer im Application Folder oder über Quicksilver starten und glücklich sein.
Das ganze ist jetzt nicht wirklich zum surfen mit dem IE unter Mac gedacht sondern mehr zum CSS und JS check.
Es hat sich doch komplizierter als erwartet rausgestellt, MySQL auf Mac OS X Leopard beim booten aktiviert zu bekommen. Deshalb hier kurz der Bericht.
StartUpItems ist von Apple als “nicht empfohlen” eingestuft worden und hat bei mir auch nie funktioniert. Der PrefPane hatte nie funktioniert, es sei denn ich setze die Rechte für /usr/local/mysql auf mich selbst. Das hat wieder dazu geführt, dass launchd (also der “empfohlene” autostart von Leopard” nicht mehr klappte!
Fehlermeldung der Konsole:
1 2 3 4 5 6 7 8 9 10 | com.mysql.mysqld[4994] 080212 16:02:35 [Warning] Can't create test file /usr/local/mysql-5.0.45-osx10.4-powerpc/data/future.lower-test com.mysql.mysqld[4994] 080212 16:02:35 [Warning] Can't create test file /usr/local/mysql-5.0.45-osx10.4-powerpc/data/future.lower-test com.mysql.mysqld[4994] 080212 16:02:35 InnoDB: Operating system error number 13 in a file operation. com.mysql.mysqld[4994] InnoDB: The error means mysqld does not have the access rights to com.mysql.mysqld[4994] InnoDB: the directory. com.mysql.mysqld[4994] InnoDB: File name ./ibdata1 com.mysql.mysqld[4994] InnoDB: File operation call: 'open'. com.mysql.mysqld[4994] InnoDB: Cannot continue operation. com.apple.launchd[1] (com.mysql.mysqld[4994]) Exited with exit code: 1 com.apple.launchd[1] (com.mysql.mysqld) Throttling respawn: Will start in 10 seconds |
UPDATE Mit diesem Tool kann man sehr einfach und sehr schnell alle Autostart Einträge sehen, bearbeiten und eigene erstellen.
Also, erstmal die Rechte wieder korrigieren. Dabei darauf achten, dass man nicht die Rechte vom Alias “mysql” in /usr/local korrigiert, sondern die von dem “echten” mysql verzeichnis. Also z. B. “mysql-5.0.45-osx10.4-powerpc” wäre in dem Fall VERZEICHNIS_BEI_DIR.
1 2 3 | cd /urs/local ls -la sudo chown -R mysql:mysql VERZEICHNIS_BEI_DIR |
Jetzt kann wie gewohnt der Launchd eingerichtet werden:
Eine Datei namens com.mysql.mysqld.plist in /Library/LaunchDaemons erstellen mit dem Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | < ?xml version="1.0" encoding="UTF-8"?> < !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <false /> <key>GroupName</key> <string>_mysql</string> <key>KeepAlive</key> <true /> <key>Label</key> <string>com.mysql.mysqld</string> <key>Program</key> <string>/usr/local/mysql/bin/mysqld</string> <key>ProgramArguments</key> <array> <string>--user=_mysql</string> </array> <key>RunAtLoad</key> <true /> <key>Umask</key> <integer>7</integer> <key>UserName</key> <string>_mysql</string> <key>WorkingDirectory</key> <string>/usr/local/mysql</string> </dict> </plist> |
Dann folgende Befehle im Terminal eingeben:
1 2 3 4 5 | cd /Library/LaunchDaemons sudo chown root com.mysql.mysqld.plist sudo chgrp wheel com.mysql.mysqld.plist sudo chmod 644 com.mysql.mysqld.plist sudo launchctl load com.mysql.mysqld.plist |
Das hat echt was Nerven gekostet, aber ich bin mehr als zufrieden mit dem Resultat.
Ich darf vorstellen: Wenn man seinen Kalender in Mac OS X (z. B. per Webdav) auf seinen Server lädt (bzw. synchronisiert) und auf diesem Server auch Ruby on Rails läuft, dann kann man seinen Kalender jetzt auf seiner Webseite veröffentlichen.
In fact I just realize I should better speak english, because someone’s German might be somewhat rusty :)
So again: You have ics files on your server (e.g. via webdav) and Ruby on Rails is running? Great, let’s publish your calendar. The idea came from the great PHPicalendar script.
This is what it will somewhat look like:
![]()
I am sorry to not have made a plugin out of this yet, but, hey, the basics are there, help yourself :) If you have any questions feel free to comment.
Requirements:
- Vpim plugin with
sudo gem install vpim
Features:
- Read several ICS files from a directory on the server
- Parse all the ical events in them
- Cache the current calendar in yaml files
- (The cache will be refreshed when a ICS file was updated meanwhile)
- HTML will be presented for the calendar
- Currently you can only choose a date and see the next X days
A word on recurrence of events
- It does do most of the recurrence rules!
- Specifically: All that VPIM supports
- PLUS: EXDATE is also supported!
The Code
Initializer (config/initializers/any_filename.rb)
1 2 3 4 5 | # Path to icalendar *.ics files on your server PATH_ICS = "#{RAILS_ROOT}/private/calendars/" PATH_ICS_CACHE = "#{RAILS_ROOT}/tmp/calendars/" FileUtils::mkdir_p(PATH_ICS) unless File.exists?(PATH_ICS) FileUtils::mkdir_p(PATH_ICS_CACHE) unless File.exists?(PATH_ICS_CACHE) |
Controller (app/controllers/calendars_controller.rb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | require 'vpim' class CalendarsController < ApplicationController def index # Load parameters if submitted session[:date_year] = params[:options]["date(1i)"] if !params[:options].blank? && !params[:options]["date(1i)"].empty? session[:date_month] = params[:options]["date(2i)"] if !params[:options].blank? && !params[:options]["date(2i)"].empty? session[:date_day] = params[:options]["date(3i)"] if !params[:options].blank? && !params[:options]["date(3i)"].empty? # Load standard if nothing submitted session[:date_year] = Time.now.year if session[:date_year].blank? session[:date_month] = Time.now.month if session[:date_month].blank? session[:date_day] = Time.now.day if session[:date_day].blank? # Set variables @scope = 7 @events = [] @today = Time.gm(session[:date_year], session[:date_month], session[:date_day]) cachefile = File.join(PATH_ICS_CACHE, "#{@today.to_s(:ical)}_#{@scope}.yml") # Kill cache if outdated if File.exists?(cachefile) killcache = false Dir.glob(File.join(PATH_ICS, '*.ics')).each do |file| killcache = true if File.mtime(file) > File.mtime(cachefile) end if killcache Dir.glob(File.join(PATH_ICS_CACHE, '*.*')).each do |file| File.delete(file) end end end # Load calendar from cache if File.exists?(cachefile) @events = YAML.load_file cachefile else # No cache, parse each icalendar *.ics file in PATH_ICS and check for event occurences Dir.glob(File.join(PATH_ICS, '*.ics')).each do |file| category = File.basename(file, '.ics') Vpim::Icalendar.decode(File.open(file)).each do |calendar| calendar.components do |event| for day in 0..@scope if start = event.occurs_in?(@today+(60*60*24*day), @today+(60*60*24)+(60*60*24*day)) myend = start + (event.dtend - event.dtstart) @events < < { 'category' => category, 'day' => day, 'start' => start, 'duration' => ((event.dtend - event.dtstart) / 60).round, # In minutes 'end' => myend, 'allday' => start.hour == 0 && start.min == 0 && start.sec == 0 && myend.hour == 0 && myend.min == 0 && myend.sec == 0, 'data' => event } end end end end end @events = @events.uniq # Just in case :) # Save cache File.open(cachefile, 'w') { |f| YAML.dump(@events, f) } end end end |
Single View (view/calendars/index.html.erb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | < %
width = 110 # Width of one day
height = 6 # height of 15 minutes in pixels
buffer = 28 # free space for dates in day column (at top of each day)
minh = 20 # Minimum of event height
cutmornings = 120 # I don't have events between 0:00 and 6:00, cut these pixels off
%>
<div id="action">
< % for day in 0...@scope + 1 do
today = (@today+(60*60*24*day))
case today.wday
when 0
dayclass = 'class="sunday"'
when 6
dayclass = 'class="saturday"'
else
dayclass = 'class="otherday"'
end
%>
<div id="ical_day" <%= dayclass %>
style=" width: < %= width %>px;
height: < %= height*96 + buffer - cutmornings %>px;
left: < %= day*width + day*10 %>px;">
< % if today.year == Time.now.year && today.month == Time.now.month && today.day == Time.now.day %>
<b>< %= 'Today' %></b>
< % else %>
< %= _(today.strftime("%a")) +', '+ today.to_s(:date) %>
< % end %>
</div>
< % end %>
< % tops = Array.new(@scope + 1, '')
@events.each do |event|
# Exclude recurrence rule hack
today = (@today+(60*60*24*event['day']))
exme = false
event['data'].propvaluearray('EXDATE').each do |exdate|
exdate = exdate.to_time
exme = true if today.year == exdate.year && today.mon == exdate.mon && today.day == exdate.day
end
next if exme # Skip this event
if event['allday']
# All-day events will be inserted later
tops[event['day']] += ' ' + event['data'].summary.to_s + '<br/>'
else
eventheight = ((event['duration']/15)*height).round
eventheight = minh if eventheight < minh
%>
<div id="ical_event"
style=" background: #<%= eventcolor(event['category']) %>;
width: < %= width-2 %>px;
height: < %= eventheight.to_s %>px;
top: < %= event['start'].hour*height*4 + (event['start'].min/15)*6 + buffer - cutmornings %>px;
left: < %= event['day']*width + event['day']*10 %>px;">
< %= '<b>'+ event['start'].to_s(:time) +' - '+ event['end'].to_s(:time) +'<br />' %>
< %= event['data'].summary %>
</div>
< % end %>
< % end %>
< % tops.each_with_index do |top, day| %>
<div id="ical_event_top"
style=" width: <%= width-2 %>px;
height: < %= height %>px;
top: < %= buffer %>px;
left: < %= day * width + day * 10 %>px;">
< %= top %>
</div>
< % end %>
<div id="vertical_spacer" style="height: <%= height*96 + buffer*2 - cutmornings %>px;"> </div>
</div> |
Layout View (views/layouts/calendars.html.erb)
< % form_tag :controller => 'calendars', :action => nil, :id => nil do |f| %> < %= date_select("options", "date", :default => @today, :order => [:day, :month, :year]) %> < %= submit_tag 'Show' + ' »', :class => 'date_button' %> < % end %> |
Helper (for coloring events) (app/helpers/calendar_helper.rb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | module CalendarsHelper def eventcolor(category) case category when 'Wichtig' # This is the name of the .ics file return 'f66' when 'Sonstiges' return '4f4' when 'Studium' return 'fb4' when 'Privat' return '77f' when 'Freunde' return 'f4f' else return 'fb4' end end end |
Stylesheet (public/stylesheets/calendar.css)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /**************** DIVs ***************************/ div#action { position: absolute; margin-left: 10px; margin-top: 10px; padding: 4px; border-left: 0px; } div#ical_day { position: absolute; padding-top: 5px; text-align: center; font-size: 10px; } .otherday { background: #ddd; } .sunday { background: #fdd; } .saturday { background: #ddf; } #ical_event { position: absolute; border: 1px #555 solid; background: #fb4; font-size: 8px; text-align: left; } #ical_event_top { position: absolute; border: 0px; font-size: 9px; font-weight: bold; text-align: left; } /**************** Fonts ***************************/ #title { float:right; color: #ddd; margin-top: 30px; margin-right: 10px; line-height: 11px; font-size: 16px; text-align: right; } #title .description { color: #777; font-size: 10px; margin: 0; } |
Routes (could be optional) (config/routes.rb)
1 2 | # CALENDAR Controllers map.connect 'calendar', :controller => 'calendars' |
Ich bin auf ein paar Artikel gestoßen die wirklich interessant für Mac-User sind. Ich habe Mail.app und Safari.app völlig unterschätzt.
Zum einen möchte ich auf drei Artikel von Dirk Einecke hinweisen. Sie beschreiben sehr ausführlich und sehr leicht verständlich, wie PGP mit Mail.app zusammenarbeitet. Ich bin von Thunderbird sofort auf Mail.app umgestiegen, weil ich es bisher, wie gesagt, unterschätzt habe:
http://blog.dirkeinecke.de/2008/01/apple-mail-und-pgp.html
Des Weiteren beschreibt er, wie man von einem Key den man mal erstellt hat, die Emailadresse usw. ändern kann. Sehr schön beschrieben:
http://blog.dirkeinecke.de/2008/01/e-mail-adresse-pgp-gpg-key-hinzufuegen.html
Und dann noch eine Anleitung zum Backup seiner Keys. Alles mit tollen Bildchen dokumentiert :)
http://blog.dirkeinecke.de/2008/01/pgp-gpg-schluessel-backup.html
Und hier ein weiteres richtiges Schmuckstück. Der integrierte Safari Web Inspector. Es handelt sich um eine Art “Firebug” (das ist ein Firefox-Plugin) für Safari 3.0 – nur built-in. Damit kann man seine Webseiten debuggen, analysieren usw.





Ich heiße Captain Future und meine Leidenschaft ist es die Brücke zwischen Menschen und Technik zu schlagen.