Hallo Habr!
Für mich ähnelt dieser Satz der Hallo-Welt, da ich endlich zu meiner ersten Veröffentlichung gekommen bin. Ich habe diesen wunderbaren Moment für lange Zeit verschoben, da es nichts zu schreiben gab, aber ich wollte auch nicht an dem saugen, was schon oft gesaugt wurde. Im Allgemeinen wollte ich für meine erste Veröffentlichung etwas Originelles, das für andere nützlich ist und eine Art Herausforderung und Problemlösung enthält. Und jetzt kann ich das teilen. Nun, das Wichtigste zuerst.
Eintrag
Alles begann damit, dass ich mir vor einiger Zeit Linux Mint auf einem funktionierenden Computer gerollt habe. Viele wissen wahrscheinlich, dass Pidgin mit dem Sipe-Plugin ein vollständig geeigneter Ersatz für Microsoft Lync (jetzt Skype for Business) für Linux-Systeme ist. Aufgrund der Besonderheiten der Arbeit muss ich oft an Schluckkonferenzen teilnehmen, und als der Bäcker anwesend war, war der Zugang zur Konferenz elementar: Wir erhalten eine Einladung per Post, klicken auf den Login-Link, wir sind drinnen fertig.
Beim Wechsel zur
dunklen Seite von Linux wurde es etwas komplizierter: Es gibt natürlich einen Pidgin-Eintrag zur Konferenz, aber dazu müssen Sie in den Eigenschaften Ihres SIP-Kontos die Option auswählen, an der Konferenz teilzunehmen, und im Fenster, das sich öffnet, einen Link zur Konferenz einfügen oder den Namen des Veranstalters eingeben und conf id. Und nach einiger Zeit begann ich zu denken: "Ist es möglich, das irgendwie zu vereinfachen?" Ja, du sagst, warum zum Teufel hast du es gebraucht, würde auf Windows sitzen und keinen Schnurrbart blasen.
Schritt 1. Forschung
"Was für eine Laune - es wird kopfüber gehen - du wirst sie nicht schlagen", sagte Nekrasov in seiner Arbeit "Wer kann in Russland gut leben?".
Da der Gedanke den Kopf traf, entstand nach einiger Zeit die erste Idee zur Umsetzung. Alles schien einfach zu sein - Sie müssen den Aufruf
abrufen, um die Links zu
meet.company.com/user/confid abzurufen - den lokalen Prozess der Webanwendung auf 127.0.0.1 in Ihrer Schubkarre platzieren und den statischen Eintrag für die Unternehmensdomäne eingeben, über die in / etc / hosts in einer Konferenz, die auf localhost zeigt. Außerdem sollte dieser Webserver den Link verarbeiten, der zu ihm gelangt ist, und ihn irgendwie in Pidgin übertragen (ich sage sofort, dass ich zu diesem Zeitpunkt überhaupt keine Ahnung hatte, wie ich ihn ihm geben soll). Die Lösung riecht natürlich nach Krücken, aber wir sind Programmierer, Krücken machen uns keine Angst (Quietschen).
Dann habe ich zufällig einen Link zu einer Einladung zu Google Chrome geöffnet (und normalerweise verwende ich immer Mozilla Firefox). Und zu meiner Überraschung sah die Webseite völlig anders aus - es gab kein Formular zur Eingabe von Benutzerdaten und unmittelbar nach dem
Aufrufen der Seite wurde die Aufforderung
angezeigt, etwas über
xdg-open zu öffnen . Zum Spaß klicke ich auf "Ja" und eine Fehlermeldung wird angezeigt - der Link lync15: confjoin? Url = https: //meet.company.com/user/confid kann nicht geöffnet werden. Hmm Was für ein xdg-open ist das und was braucht es, um solche Links zu öffnen?
Eine Autopsie in der Dokumentation ergab, dass es sich um einen grafischen Shell-Handler handelt, mit dem zugeordnete Anwendungen entweder mit den Protokollen für das Uri-Schema oder mit bestimmten Dateitypen gestartet werden können. Zuordnungen werden durch eine Zuordnung vom MIME-Typ konfiguriert. Wir sehen also, dass wir die Suche nach einer zugeordneten Anwendung für das
Uri- Schema mit dem Namen
lync15 starten und der Link an xdg-open übergeben wird, der theoretisch an eine Anwendung übergeben werden sollte, die für diese Art von Links verantwortlich ist. Was wir natürlich nicht im System haben. Und wenn nicht, wie machen sie es in der Open Source-Welt? Das stimmt, wir werden es selbst schreiben.
Ein weiteres Eintauchen in die Linux-Welt und insbesondere in die Untersuchung der Funktionsweise der grafischen Shell (Desktop-Umgebung, DE), wie ich sie in Linux Mint Xfce habe, zeigte, dass Anwendungen und der damit verbundene MIME-Typ normalerweise direkt in Verknüpfungsdateien mit der Erweiterung geschrieben werden .desktop. Nun, warum nicht, ich erstelle eine einfache Anwendungsverknüpfung, die einfach das Bash-Skript ausführen und das an sie übergebene Argument an die Konsole ausgeben soll. Ich werde nur die Verknüpfungsdatei selbst angeben:
[Desktop Entry] Name=Lync Exec=/usr/local/bin/lync.sh %u Type=Application Terminal=false Categories=Network;InstantMessaging; MimeType=x-scheme-handler/lync15;
Ich starte xdg-open von der Konsole aus mit demselben Link, der vom Browser kommt und ... Mist. Wieder sagt er, dass er den Link nicht verarbeiten kann.
Wie sich herausstellte, habe ich das Verzeichnis des zugehörigen MIME-Typs mit meiner Anwendung nicht aktualisiert. Dies geschieht mit einem einfachen Befehl:
xdg-mime default lync.desktop x-scheme-handler/lync15
Dadurch wird einfach die Datei ~ / .config / mimeapps.list bearbeitet.
Versuch Nummer 2 mit xdg-open call - und erneut fehlgeschlagen. Nichts, Schwierigkeiten machen uns keine Angst, sondern schüren nur das Interesse. Und mit der ganzen Kraft der Bash (d. H. Nachverfolgung) bewaffnet, tauchen wir kopfüber in das Debuggen ein. Hierbei ist zu beachten, dass xdg-open nur ein Shell-Skript ist.
bash -x xdg-open $url
Bei der Analyse der Ausgabe nach dem Tracing wird ein wenig klar, dass die weitere Kontrolle auf
Exo-Open übertragen wird . Und dies ist bereits eine Binärdatei, und es ist bereits schwieriger zu verstehen, warum sie einen erfolglosen Rückkehrcode zurückgibt, wenn in einem Argument ein Link dazu übergeben wird.
Nachdem ich die Innenräume von xdg-open durchlaufen hatte, stellte ich fest, dass es verschiedene Umgebungsparameter analysiert und die Steuerung entweder an einige Tools zum Öffnen von Dateien / Links
weitergibt, die für eine bestimmte DE spezifisch sind, oder dass es einen Fallback in Form der Funktion
open_generic gibt open_xfce() { if exo-open --help 2>/dev/null 1>&2; then exo-open "$1" elif gio help open 2>/dev/null 1>&2; then gio open "$1" elif gvfs-open --help 2>/dev/null 1>&2; then gvfs-open "$1" else open_generic "$1" fi if [ $? -eq 0 ]; then exit_success else exit_failure_operation_failed fi }
Ich habe hier mit der Analyse des übergebenen Arguments schnell einen kleinen Hack gemacht, und wenn unser spezifischer Teilstring
lync15 vorhanden ist , übergeben wir die Kontrolle sofort an die Funktion
open_generic .
Versuchen Sie Nummer 3 und Sie denken, es hat funktioniert? Ja, jetzt wie. Aber die Fehlermeldung hat sich bereits geändert, dies ist bereits ein Fortschritt - jetzt sagte er mir, dass die Datei nicht gefunden wurde und schrieb mir in Form einer Datei genau den Link, der als Argument übergeben wurde.
Diesmal stellte sich heraus, dass es sich um die Funktion
is_file_url_or_path handelt , die den Link zur Datei: // file oder den Pfad zur Datei oder etwas anderes analysiert. Und die Prüfung hat nicht richtig funktioniert, da unser Präfix (URL-Schema) Zahlen enthält und der reguläre Ausdruck nur für einen Zeichensatz geprüft wird, der aus folgenden Elementen besteht: Alpha: Punkte und Bindestriche. Nach Rücksprache mit dem Standard rfc3986 für eine
einheitliche Ressourcenkennung wurde klar, dass Microsoft diesmal nichts verletzt hat (obwohl ich eine solche Version hatte). Nur eine Zeichenklasse: Alpha: Enthält nur Buchstaben des lateinischen Alphabets. Ich ändere die reguläre Prüfung schnell auf alphanumerisch. Fertig, Sie sind entzückend, alles startet endlich, Kontrolle, nachdem alle Überprüfungen unserer Skriptanwendung durchgeführt wurden, unser Link wird auf der Konsole angezeigt, alles ist wie es sollte. Danach vermute ich, dass alle Probleme mit exo-open auch auf die Validierung des Linkformats aufgrund der Zahlen im Diagramm zurückzuführen sind. Um die Hypothese zu testen, ändere ich die
MIME -Typ-Registrierung der Anwendung nur auf das
Lync- Schema und Voila - alles funktioniert, ohne die Funktion open_xfce neu zu definieren. Dies hilft uns jedoch in keiner Weise, da die Webseite für die Teilnahme an der Konferenz den Link zu lync15 genau erstellt.
Damit ist der erste Teil des Pfades abgeschlossen. Wir können den Link-Aufruf abfangen und müssen ihn dann irgendwie verarbeiten und in Pidgin weiterleiten. Um zu verstehen, wie es intern funktioniert, wenn Daten über den Link im Menü „An der Konferenz teilnehmen“ eingegeben werden, habe ich das Sipe-Projekt-Repository geklont und mich darauf vorbereitet, erneut in den Code einzutauchen. Aber hier hat mich zum Glück die Skripte im Verzeichnis
contrib / dbus / angezogen:
- sipe-join-conference-with-uri.pl
- sipe-join-conference-with-organizer-and-id.pl
- sipe-call-phone-number.pl
- Sipehelp.pm
Es stellt sich heraus, dass das Sipe-Plugin für die Interaktion über den dbus (Desktop-Bus) verfügbar ist. In den Skripten finden Sie direkte Beispiele für die Teilnahme an der Konferenz über einen Link, entweder über den Namen und die Confid-ID des Veranstalters, oder Sie können einen Anruf über sip einleiten. Genau das hat uns gefehlt.
Schritt 2. Implementieren eines Handlers für die automatische Verknüpfung
Da es fertige Beispiele für die Perle gibt, habe ich mich entschieden, einfach
sipe-join-conference-with-uri.pl zu verwenden und es ein wenig für mich selbst zu modifizieren. Ich kann in Perlen schreiben, daher hat dies keine besonderen Schwierigkeiten verursacht.
Nachdem ich das Skript separat getestet hatte, gab ich seinen Aufruf in die Datei
lync.desktop ein . Und es war ein Sieg! Wenn Sie die Seite für die Teilnahme an der Konferenz aufrufen und den Start von xdg-open zulassen, wird das Popup-Fenster der Konferenz von Pidgin automatisch geöffnet. Wie ich mich freute.
Durch den Erfolg ermutigt, entschied ich mich, dasselbe für meinen Hauptbrowser Mozilla Firefox zu tun. Beim Betreten durch den Fuchs wird eine Seite zur Autorisierung geöffnet, und ganz unten befindet sich eine Schaltfläche zum
Verbinden mit Office Communicator . Sie zog auch meine Aufmerksamkeit auf sich. Wenn Sie im Browser darauf klicken, geht der Link zu:
conf:sip:{user};gruu;opaque=app:conf:focus:id:{conf-id}%3Frequired-media=audio
zu dem er mir freundlicherweise sagt, dass er nicht weiß, wie er es öffnen soll, und vielleicht habe ich keine zugehörige Anwendung für ein solches Protokoll. Nun, wir haben es schon bestanden.
Schnelle Registrierung meiner Skriptanwendung auch für das Uri-Schema
conf und ... nichts passiert. Der Browser beschwert sich weiterhin darüber, dass es keine Anwendung gibt, die meine Links verarbeitet. Gleichzeitig funktioniert der Aufruf von der xdg-open-Konsole mit Parametern einwandfrei.
"Benutzerdefinierten Protokollhandler in Firefox einstellen" - mit dieser Frage ging ich online. Nach einigen Diskussionen über den Stackoverflow (und wo ohne) scheint die Antwort gefunden worden zu sein. Sie müssen einen speziellen Parameter in
about: config erstellen (natürlich ersetzen Sie foo durch conf):
network.protocol-handler.expose.foo = false
Wir erstellen, öffnen den Link und ... es war nicht da. Der Browser sagt, als wäre nichts passiert, dass er unsere Anwendung nicht kennt.
Ich habe die offizielle Dokumentation zur Registrierung des Protokolls bei Mozilla gelesen. Es gibt eine Option zum Registrieren von Assoziationen auf dem Gnome-Desktop selbst (wobei natürlich foo durch conf ersetzt wird):
gconftool-2 -s /desktop/gnome/url-handlers/foo/command '/path/to/app %s' --type String gconftool-2 -s /desktop/gnome/url-handlers/foo/enabled --type Boolean true
Ich registriere mich, öffne den Browser ... und wieder den Bart.
Hier fällt eine Zeile aus der Dokumentation auf:
Wenn Sie das nächste Mal auf einen Link vom Protokolltyp foo klicken, werden Sie gefragt, mit welcher Anwendung Sie ihn öffnen möchten.
- Samen Semenych
- Ahh
Wir klicken nicht auf den Link, sondern einfach auf der Webseite ändert sich die Position des Fensters durch Javascript. Ich schreibe eine einfache HTML-Datei mit einem Link zum conf-Protokoll, öffne sie in einem Browser und klicke auf den Link - Yos! Ein Fenster mit der Frage, in welcher Anwendung Sie unseren Link öffnen müssen, wird geöffnet. Dort haben wir bereits unsere Lync-Anwendung in der Liste - wir haben sie auf alle möglichen Arten ehrlich registriert. Im Fenster "Merken Sie sich die Auswahl und öffnen Sie immer Links in unserer Anwendung" befindet sich ein Häkchen. Beachten Sie, klicken Sie auf OK. Und dies ist der zweite Sieg - das Konferenzfenster öffnet sich. Gleichzeitig funktioniert das Öffnen von Konferenzen bereits nicht nur, wenn Sie auf den Link klicken, sondern auch, wenn Sie von der gewünschten Seite zur Konferenz wechseln.
Dann habe ich überprüft, dass das Löschen der
Parameter network.protocol-handler.expose.conf die Protokolloperation im Fuchs in keiner Weise beeinflusst. Links funktionierten weiter.
Fazit
Ich habe alle meine Erfolge in das Github-Repository hochgeladen. Links zu allen Ressourcen finden Sie am Ende des Artikels.
Es wird für mich interessant sein, Feedback von denen zu erhalten, die meine Best Practices anwenden möchten. Ich muss sofort sagen, dass ich alles nur für mein Linux Mint-System getan habe, sodass einige andere Distributionen oder Desktops in dieser Version möglicherweise nicht funktionieren. Vielmehr bin ich mir dessen sogar fast sicher, da ich in xdg-open nur eine Funktion gepatcht habe, die sich nur auf meine DE bezieht. Wenn Sie Unterstützung für andere Systeme oder dekstopov hinzufügen möchten, schreiben Sie mir eine Poolanfrage in github.
Die Umsetzung des gesamten Projekts dauerte 1 Abend.
Referenzen: