SMS senden leicht gemacht (Orange)

Gibt es was mühsameres, als die unsäglichen Browser-SMS-Versende-Dienste unserer Mobilfunkanbieter? Naja, wahrscheinlich gibt es schlimmeres, aber verbessern kann man es ja trotzdem. Das Ziel ist, möglichst einfach SMS zu versenden, also schreiben wir doch ein Script, welches als Parameter Nummer und Text entgegennimmt und versendet.

Ist eigentlich ganz einfach, Mechanize mimt einen Browser und macht genau das, was auch ein Mensch tun würde, also anmelden, Formularfelder ausfüllen und abschicken:

#!/usr/bin/ruby
require 'mechanize'

username = 'mirkostocker'
password = 'XXXXXXXXXXXX'
number   = ARGV.shift
message  = ARGV * " "

if message.length > 144 || message.length < 1
  $stderr.puts "Nachricht zu lang oder zu kurz.."
  exit 1
end

def find_form_with_field(page, fieldname)
  page.forms.each do |form|
    if form.fields.find{|f| f.name == fieldname}
      yield form
    end
  end
end

WWW::Mechanize.new do |agent|

  agent.get('https://www.orange.ch/footer/login') do |page|

    find_form_with_field(page, 'username') do |f|
      f.username = username
      f.password = password
      f.submit
    end
  end

  agent.get('https://www.orange.ch/myorange/sms') do |page|

    find_form_with_field(page, 'messageInput') do |f|
      f.destinationNumberInput = number
      f.messageInput = message
      f.wui_target_id = 'sendButton'
      f.wui_event_id = 'onclick'
      f.submit
    end
  end
end


find_form_with_field musste ich schreiben, da die Formulare keine Namen besitzen, und fragt mich nicht, weshalb ich wui_target_id und wui_event_id setzen muss, im echten Browser wird das per Javascript gemacht und ist anscheinend wichtig. Hat auch gleich die Projektdauer um 50% verlängert, auf rund 1.5 Stunden.

So, und wer kümmert sich um die Swisscom und Sunrise?

Guido: Wie du siehst habe ich einen netten Weg gefunden, bunten Code zu bloggen, der beste Editor der Welt hat nämlich eine TOhtml Funktion.

6 comments »

Shell: ssh

Ich hab schon lange nichts mehr hierüber geschrieben, die “einfachen” Themen sind ja auch schon durch. Eines der wohl nützlichsten Tools neben den coreutils ist für mich ssh, da man damit extrem flexibel ist. Von überall her ist man ohne grossen Aufwand auf einem beliebigen Rechner und arbeitet damit genau gleich, als wäre man lokal am Gerät. Ok, das wissen die meisten wohl bereits. Es gibt aber noch ein paar Dinge, die einem das Leben mit ssh noch einfacher machen, davon soll dieser Beitrag handeln.

Authentifizerung mit Public-Key (in 2 Schritten)

Als erstes braucht man natürlich ein Schlüsselpaar, dies erstellt man mit ssh-keygen Wer mutig ist kann das Passwort auch einfach leer lassen. Für jeden Rechner, an dem man sich nun damit anmelden will, ist nur noch folgendes zu tun: ssh $host "mkdir -p .ssh; cat >> .ssh/authorized_keys" < .ssh/id_rsa.pubDabei wird auf dem Server das entsprechende Verzeichnis erstellt, falls es noch nicht existiert und danach unseren Public-Key angehängt. Das wars schon! Wenn man das Passwort (für den Schlüssel) nicht jedes Mal eintippen will, dann lohnt es sich, den "ssh agent" einzusetzen. Da dessen Konfiguration jedoch Distributionsabhängig ist, verzichte ich auf eine Erläuterung.

Konfiguration pro Host

Leider kann man sich den Usernamen, den man auf einem Rechner hat, nicht immer aussuchen. Natürlich könnte man sich immer mit user@host verbinden, aber das ist eigentlich unnötig, viel eleganter ist es, die Host-Spezifische Konfiguration in .ssh/config einzutragen. Bei mir sieht die Beispielsweise so aus:
Host dnd
HostName dnd.ch
User mstocker

Host r2
HostName r2.ifs.hsr.ch

Sollte eigentlich selbsterklärend sein. Für die Verbindung reicht nun ein 'ssh dnd' oder 'ssh r2'.

Tunnels

Wenn man einen mühsamen Admin hat, der einem alle möglichen Ports zumacht, kann man dies ziemlich einfach umgehen, und zwar mit local port forwarding.

Nehmen wir an, wir haben einen Laptop im HSR-Netz und würden gerne auf server1:8080 verbinden. Zuhause haben wir einen Rechner stehen, den wir per ssh erreichen können, und welcher auch server1:8080 errreicht. Mit folgendem Befehl wird nun ein Tunnel über den Server zu Hause nach server1:8080 erstellt: ssh -L 80:server1:8080 server_zu_hauseIm Browser über localhost:80 ist server1 nun erreichbar. Ist doch eigentlich ganz einfach! :)

Mit ssh kann man noch viel wildere Dinge tun, wie z.B. Reverse-Tunnels, mit denen man beispielsweise von zu Hause aus auf den PC im Büro zugreifen kann. Und seit OpenSSH 4.3 sind sogar ganze VPNs möglich...

No comment »

Shell: cd

The cd utility shall change the working directory of the current shell execution environment …

So beginnt die man-Page zum Befehl “cd”, und das wichtigste ist damit eigentlich auch schon fast gesagt. Cd ist wohl ein Befehl, der jeder schon mal gebrauch hat, aber wohl meistens in der Form “cd $Verzeichnis”. Man kann allerdings noch viel mehr damit machen:

  • “cd” ohne Argument bringt einem zurück nach $HOME
  • “cd -” bringt einem in das vorherige Verzeichnis zurück

Noch ein Tipp für *zsh*-User: Mit den folgenden Einträgen (falls noch nicht vorhanden) in der .zshrc lässt sich mit “cd -[Tab]” die Liste der zuletzt besuchten Verzeichnisse durchgehen:

setopt auto_pushd
zstyle ':completion:*' menu select=1
autoload -Uz compinit; compinit

Noch was ganz abgefahrenes: Mit der Umgebungsvariable CDPATH lassen sich, separiert mit einem Doppelpunkt, Verzeichnisse angeben, in deren Unterverzeichnisse man direkt mit cd $Unterverzeichnis wechseln kann. Hm, keine Ahnung ob man das jetzt versteht, machen wir am besten ein Beispiel:

export CDPATH=$HOME:/var/www/localhost/htdocs/

Ich befinde mich in /, der Inhalt von $HOME ist:

files  incoming  rssimap

und von /var/www/localhost/htdocs:

awstats  cacti

Mit cd [Tab] erscheint nun folgende Liste, welche alle Unterverzeichnisse der 3 Verzeichnisse beinhaltet:

awstats/   cacti/     files/     lib/       portage/   rssimap/   tmp/
bin/       dev/       home/      mnt/       proc/      sbin/      usr/
boot/      etc/       incoming/  opt/       root/      sys/       var/

Cool, nicht?

1 comment »

Shell: Befehle Wiederholen / History, Teil 2

Im letzten Teil ging es ja bereits darum, möglichst einfach Befehle zu wiederholen. Sehr oft will man jedoch bloss ein Argument “wiederverwenden”, also beispielsweise einen Pfad.

Um das letzte Argument (wenns kein Argument hatte dann auch einfach den Befehl) zu wiederholen, tippt man stattdessen einfach das etwas kryptisch aussehende
!$ Es gibt noch einen ganzen Haufen von Möglichkeiten auf spezifische Elemente zuzugreifen, also etwa das 2. Argument des vorletzten Befehls, aber die Syntax dazu kann ich mir nie recht merken.

Wenn man auf die letzten Argumente von weiter zurückliegenden Befehlen zugreifen will, kann man sich auch mit Alt^. recht komfortabel durchwühlen.

Mir geschieht es häufig, dass ich vergesse, gewisse Optionen anzugeben (-r beim Kopieren beispielsweise, oder -rf beim Löschen). Dafür habe ich mir die folgende Funktion (einfach nach .zshrc kopieren) geschrieben, welche den vorherigen Befehl holt, an den Anfang der Zeile springt, ein Wort nach vorne geht und auch schon vorsorglich rechts einen Abstand einfügt:

previous_line_after_first_word () {
        zle up-line-or-history
        zle beginning-of-line
        zle vi-forward-word
        RBUFFER=" $RBUFFER"
}
zle -N previous_line_after_first_word
bindkey ^O previous_line_after_first_word

Das ganze habe ich auf Ctrl^O gelegt.

1 comment »

Shell: Befehle Wiederholen / History

Im letzten Beitrag ging es um die Navigation auf der aktuellen Eingabezeile, heute weiten wir das aus auf die gesamte History.

Mit dem Befehl $ history lassen sich, je nach Konfiguration, die letzten x-hundert ausgeführten Befehle anzeigen, jeweils mit einer Nummer versehen:

konsole_history.png

Möchte man nun einen Befehl nochmals ausführen, beispielsweise “kcmshell style”, genügt es, folgendes zu schreiben:
$ !487

Wenn man die ZShell benützt, kann man mit Tab den Befehl auch schon mal vervollständigen.

Mal unter uns, ich nutze die History so eigentlich nicht sehr oft, denn viel einfacher ist es, einfach darin zu suchen. Mit Ctrl^R leitet man die Suche ein, dann einen Teil des Befehls den man sucht eintippen und mit Enter ausführen. Falls der Falsche, also ein neuerer Befehl, auch auf das Suchmuster zutrifft und man nicht noch mehr tippen möchte, kann man mit erneutem Ctrl^R durch die Suchresultate blättern (und mit Ctrl^S übrigens auch wieder noch vorne).

Wenn ich also Beispielsweise an meinem Webserver arbeite, ab und zu eine Konfigurationsdatei verändere und immer mal wieder den Apache neustarten muss, dann reicht es meistens, Ctrl^R res zu tippen und fertig.

1 comment »

Shell: Navigation und Editieren der aktuellen Zeile

Ich hätte nicht gedacht, dass sich so viele auf meinen Aufruf melden würden, anscheinend ist wirklich ein Bedürfnis und Interesse da, was mich natürlich freut. Ich hoffe, ich habe nicht allzu grosse Erwartungen geweckt. Es werden bestimmt auch ein paar Leute mitlesen, die viel mehr Wissen als ich, wenn etwas also mal noch einfacher geht oder nicht ganz korrekt ist, bitte ich darum korrigiert zu werden.

Vielleicht zuerst noch was zum Thema Shell: Ich selbst benutze Zsh, da sie sehr viele praktische Features bietet, die ich z.B. von der Bash nicht kenne. Ich möchte aber keine Flamewars zu dem Thema lostreten, eine schöne Liste von Vorteilen findet man hier. Wer nur deshalb die Bash benutzt, weil die einfach schon als Standardshell eingerichtet ist, dem empfehle ich einfach mal auf die Zsh zu wechseln:

$ sudo aptitude install zsh
oder
$ sudo emerge zsh
als default setzen:
$ chsh -s /bin/zsh #oder wo auch immer zsh liegt

Achtung, falls Einstellungen (z.B. Aliasse) in .bashrc gemacht wurden, müssen diese nach .zshrc migriert werden, die Syntax ist meistens ziemlich gleich. Ausserdem wird beim ersten Start ein Wizard der Zsh starten, wer Lust und Zeit sollte ruhig mal ein bisschen damit rumspielen.

Ok, nun aber zurück zum Hauptthema: Navigation. Dass man mit Cursor-Up die vorherigen Befehle “holen” kann ist (hoffentlich) allen klar. Vielleicht hat man einen Tippfehler gemacht oder ein sudo vergessen und muss noch was ändern. Natürlich kann man dazu die Cursortasten nehmen, an den Anfang der Zeile kommt man aber am einfachsten mit Ctrl^A (Achtung, das ist eigenltich ein kleines a, also ohne Shift). Ans Ende wiederum mit Ctrl^E (man muss sich aber nicht am Ende der Zeile befinden, um einen Befehl abzusetzen). Natürlich kann man das gleiche auch mit den Home und End-Tasten erreichen.

Nützlicher ist die Navigation mit Alt^B sowieo Alt^F, damit springt der Cursor vor (bzw. nach) das letzte (bzw. das nächste) Leerzeichen. Mit Ctrl^B und F bewegt man den Cursor bloss um ein Zeichen, was ich nicht besonders nützlich finde, deshalb habe ich diese Tasten mit der gleichen Funktion wie Alt^B / F belegt:

#In .zshrc
bindkey ^F forward-word
bindkey ^B backward-word

Nun können wir uns also schon ganz gut bewegen, allerdings wollen wir häufig auch noch was ändern. Mit Ctrl^W löscht man von der Cursorposition bis zum vorherigen Leerzeichen, das Umgekehrte, also “nach vorne” löschen geschieht mit Alt^D. Mit Ctrl^U löscht man gleich bis zum Anfang und mit Ctrl^K bis ans Ende der Zeile.

Machen wir doch ein Beispiel. Wir haben zuvor folgenden Befehl ausgeführt:
$ less /etc/apache2/httpd.conf
Nun wollen wir die Datei bearbeiten, dazu drücken wir einfach Cursor-Up (oder Ctrl^P), Ctrl^BW (oder Ctrl^AFW, Ctrl^A Alt^D): “less” ist weg und kann mit einem anderen Befehl ersetzt werden.

Ziemlich simpel, aber einiges schneller als Zeichen-für-Zeichen zu navigieren. Einfach immer, wenn man sich dabei ertappt wie man ein dutzend Mal auf die Cursortasten haut, kurz an die paar Shortcuts erinnern und anwenden. Auch wenn man so zu Beginn vielleicht nicht schneller ist, wird man das mit der Zeit wieder rausholen. Ist im Prinzip dasselbe wie mit Vi :) .

[ratings]

2 comments »