Mailinator Update

Mailinator hat eine neue Funktion eingeführt und die möchte ich kurz vorstellen. In Diesem Artikel haben wir ja bereits über Bugmenot und Mailinator gesprochen.

Das Problem bei einem Mailinator-Account war bisher gewesen, dass jeder, der deine Emailadresse kennt, auch deine Emails lesen kann (ziemlich gravierend, oder? :)

funkensturm@mailinator.com brauchte man nur auf www.mailinator.com eingeben:

mailinator funkensturm login

Und man konnte die Mails lesen:

Um das zu verhindern, sieht man jetzt klein im obigen Bild:
“Alternate Address for this Inbox: M8R-9rdddd@mailinator.com”

Wie hier erklärt, handelt es sich dabei um eine Art Hash-Wert für das Wort “funkensturm”. Das heißt, man gibt in Zukunft nur noch die Adresse M8R-9rdddd@mailinator.com weiter und keiner weiß, dass sich der Account “funkensturm” dahinter verbirgt.

Banana bread

Ist zwar off-topic, aber einfach viel zu wichtig, um nicht veröffentlicht zu werden. Jeder sollte wissen, wie man Banana Bread macht.

Banana Bread Rezept

  • 300 g Mehl
  • 2 TL Natron
  • 1 Prise Salz
  • 3 ÜBERREIFE Bananen
  • 100 g Margarine
  • 250 ml Zucker
  • 3 EL Milch
  • 1 Ei
  • 200 g gehackte Nüsse (Wal- oder Haselnuss)
  • Bei 175 Grad 1 Stunde Backen

Nützliche Terminal Befehle

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!

IE5, IE6, IE7 unter Mac OS X installieren (Tiger und Leopard)

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.

Flickrvision

http://flickrvision.com/maps/show_3d

Könnt’ ich den ganzen Tag vorsitzen. Twittervision gibt’s auch.

Apple Cube

funkensturm.de
Macbook Air
Apple Cube New York :)

dsc09251_500.jpg

Mysql on Leopard: Startupitem, Prefpane, LaunchDemon

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

FINALLY! RailsICalendar ical ics publish with ruby on rails

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:
bild-1.png

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']] += '&nbsp; ' + 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;">&nbsp;</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' + ' &raquo;', :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'

Apple Mail.app+PGP, E-Mailadresse eines PGP-Key ändern, Safari “Firebug”

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.

http://www.agenturblog.de/2007-11/der-safari-web-inspector/

cap deploy “permission denied” nach upgrade auf capistrano 2.1

Hier habe ich endlich gefunden wieso aus heiterem Himmel bei einem cap deploy mit ssh und svn (und public key authentication) immer folgender Fehler auftrat:

** [err] Permission denied, please try again.
** [err] Permission denied, please try again.
** [err] Permission denied (publickey,password).
** [err] svn: Netzwerkverbindung wurde unerwartet geschlossen

In die /config/deploy.rb muss folgende Option mit aufgenommen werden:

default_run_options[:pty] = true

Wenn ihr wissen wollt wieso, müsst ihr im original Beitrag nachschauen. Es hat mit den Rechten bei der shell zu tun und jetzt werden auch die user profile auf dem server vorher geladen.