SVN Commands

Weil ich sie immer wieder suche, hier eine Liste von SVN Befehlen, einfach erklärt und mit schönen Beispielen. Besonders svn:ignore benutzt man immer wieder. Auch wenn ich gerade git installiere, der ein oder andere versteht SVN sicher besser mit diesem Dokument.

– SVN PROPERTIES –

ANZEIGEN

Properties des aktuellen Verzeichnisses anzeigen
svn pl

Zeige alle Änderungen für den nächsten commit, ignorierte Dateien sollen trotzdem angezeigt werden:
svn st –no-ignore

Alle Properties rekursiv anzeigen
svn pl -R
Merke: “Properties on ‘config’: svn:ignore” bedeutet nicht, dass “config” ignoriert wird, sondern dass im Verzeichnis config, gewisse Objekte ignoriert werden. “config” ist in gewisser Weise nur der Träger der Eigenschaft, die Werte widerrum sind die Inhalte in config, welche ignoriert werden.

Alle svn:ignore Properties rekursiv anzeigen
svn pg svn:ignore -R

Details über ein Property erhalten
svn pg PROPVAL PATH –strict
Beispiele:
Welche Objekte werden im aktuellen Verzeichnis ignoriert?
svn pg svn:ignore . –strict

SETZEN

Property des aktuellen Verzeichnisses setzen
svn ps PROPNAME PROPVAL PATH
Merke: Der aktuelle Wert des Properties wird dabei überschrieben! Möchte man ihn behalten, muss man ihn neu mit hinzufügen.
Merke: PROPVAL für z. B. svn:ignore ist ein Objekt je Zeile. Das wird mit z. b. “objekt1[RETURN]objekt2″ erreicht.
Merke: Ein mit “svn mkdir” erstelltes Verzeichnis kann nicht direkt ignoriert werden. Verzeichnisse die ignoriert werden sollen, müssen manuell erstellt werden und können anschließend ignoriert werden.
Beispiele:
Das Verzeichnis test im aktuellen Verzeichnis ignorieren
svn ps svn:ignore test .
Das Verzeichnis test im Unterverzeichnis public/images ignorieren
svn ps svn:ignore test public/images
Die Verzeichnisse test1 und test2 im aktuellen Verzeichnis ignorieren
svn ps svn:ignore “test1[RETURN]test2″ .
Alle *.log Dateien im Unterverzeichnis log ignorieren (Das hat keine Auswirkung auf das Verzeichnis log an sich, sondern nur die Dateien dort drin)
svn ps svn:ignore *.log log

LÖSCHEN

Property PROPNAME von PATH löschen
svn pd PROPNAME [PATH]
Merke: Wieder hat das keine Auswirkung auf das Verzeichnis PATH, nur auf dessen Inhalte! (Es sei denn natürlich PATH ist eine Datei)
Merke: Wird PATH weggelassen, wird das Property vom aktuellen Verzeichnis gelöscht
Beispiele:
Alle Objekte im aktuellen Verzeichnis sollen nicht mehr ignoriert werden
svn pd svn:ignore
Alle Objekte im Verzeichnis public/images sollen nicht mehr ignoriert werden
svn pd svn:ignore public/images

– LEGENDE –

PROPNAME ist ein Property
z. B. svn:ignore oder svn:executable

PROPVAL Wert eines Properties
Die Belegung des Properties mit z. B. dem Namen eines Unterverzeichnisses

PATH Verzeichnis zu einem Verzeichnis oder einer Datei usw.
z. B. dir/subdir oder .

[RETURN] Entertaste
Ist ein Zeilensprung mit der Returntaste

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/