Прывітанне, Хабр!
Для мяне гэтая фраза падобна hello world, бо я дабраўся нарэшце да сваёй першай публікацыі. Доўга адкладаў гэты выдатны момант, бо і пісаць не было пра што, а абсмоктваць тое, што ўжо па кучы разоў абсмактаць, таксама не хацелася. Наогул для сваёй першай публікацыі хацелася нешта арыгінальнае, карыснае іншым і якое змяшчае нейкі челленж і рашэнне праблем. І вось я ўжо магу падзяліцца гэтым. Цяпер аб усім па парадку.
Уступленне
Пачалося ўсё з таго, што некаторы час назад я на працоўным кампе накаціў сабе Linux Mint. Многія напэўна ведаюць, што Pidgin з убудовай Sipe суцэль прыдатная замена Microsoft Lync (цяпер завецца Skype for business) для Linux сістэм. У сілу спецыфікі працы мне часта даводзіцца ўдзельнічаць у sip-канферэнцыях, і ў бытнасць віндузятніка ўваход у канферэнцыі быў элементарным: атрымліваем запрашэнне па пошце, клікаем на спасылку ўваходу, гатова мы ўсярэдзіне.
Пры пераходзе на цёмны бок Linux усё некалькі ўскладнілася: уваход у канферэнцыі ў Pidgin вядома ж таксама ёсць, але там для гэтага трэба ва ўласцівасцях вашага sip-акаунта абраць пункт далучэння да канферэнцыі ў меню і ў якое адкрылася акне ўставіць спасылку на канферэнцыю або ўвесці імя арганізатара і conf id. І праз нейкі час я пачаў задумвацца: "а ці нельга неяк гэта спрасціць". Ага, скажаце вы, на які чорт табе гэта спатрэбілася, сядзеў бы сабе на віндзе і ў вус не дзьмуў.
Крок 1. Даследаванне
«Уцяміцца ў галаву якая блазнота — калом яе адтуль не выб'еш» — так казаў Някрасаў у сваім творы «Каму на Русі жыць добра».
Такім чынам, раз ужо думка патрапіла ў галаву, то праз нейкі час узнікла і першая ідэя для рэалізацыі. Здавалася ўсё проста - трэба перахапляць зварот да спасылак
Потым выпадкова я неяк адкрыў спасылку на запрашэнне ў Google Chrome (а звычайна я заўсёды выкарыстоўваю Mozilla Firefox). І на маё здзіўленне вэб-старонка выглядала зусім інакш - не было формы ўводу карыстацкіх дадзеных і адразу пасля ўваходу на старонку выходзіў запыт на адкрыццё чагосьці праз XDG адкрыць. Дзеля цікавасці націскаю "так" і выходзіць паведамленне пра памылку - спасылка lync15:confjoin?url=https://meet.company.com/user/confid не можа быць адкрыта. Хмм. Што гэта за xdg-open такі і што яму трэба для таго, каб такія спасылкі адчыняліся? Выкрыццё чытанне дакументацыі паказала, што гэта апрацоўшчык графічнай абалонкі, які дапамагае запускаць асацыіраваныя прыкладанні альбо з пратаколамі для uri scheme, альбо з вызначанымі тыпамі файлаў. Асацыяцыі наладжваюцца праз супастаўленне mime-type. Такім чынам, мы бачым, што ў нас запускаецца пошук супастаўленага дадатку для uri scheme з імем lync15 і спасылка перадаецца ў xdg-open, які далей па ідэі павінен перадаць яе нейкаму з дадаткам, якое адказвае за дадзены тып спасылак. Якога ў нас, вядома, у сістэме няма. А раз не, то як паступаюць у свеце апенсорсу? Правільна, мы напішам яго самі.
Далейшае апусканне ў свет Linux і асабліва ў вывучэнне таго, як працуе графічная абалонка (desktop environment, DE), дарэчы ў мяне гэта Xfce у Linux Mint, паказала што прыкладанні і асацыіраваны з ім mime-type прапісваецца звычайна прама ў файлах цэтлікаў з пашырэннем .desktop. Ну а чаму б і не, ствараю просты цэтлік прыкладання, які павінен проста запусціць баш-скрыпт і вывесці перададзены яму аргумент на кансоль, прыводжу толькі сам файл цэтліка:
[Desktop Entry]
Name=Lync
Exec=/usr/local/bin/lync.sh %u
Type=Application
Terminal=false
Categories=Network;InstantMessaging;
MimeType=x-scheme-handler/lync15;
запускаю xdg-open з кансолі з перадачай той жа спасылкі, якая ідзе з браўзэра і… аблом. Ізноў кажа што не можа апрацаваць спасылку.
Як аказалася я не абнавіў каталог асацыіраваных mime-type з маім дадаткам. Робіцца гэта простай камандай:
xdg-mime default lync.desktop x-scheme-handler/lync15
якая проста рэдагуе файл ~/.config/mimeapps.list.
Спроба нумар 2 з выклікам xdg-open - і зноў няўдача. Нічога, цяжкасці нас не палохаюць, а толькі падаграваюць цікавасць. І узброіўшыся ўсёй моцай баша (г.зн. трасіроўкай) ныраем з галавой у адладку. Тут важна адзначыць, што xdg-open з'яўляецца проста шелл-скрыптам.
bash -x xdg-open $url
Аналізуючы выснову пасля трасіроўкі становіцца крыху зразумела, што далей кіраванне перадаецца ў exo-open. А гэта ўжо бінарны файл і разбірацца, чаму ён вяртае няўдалы код вяртання пры перадачы яму спасылкі ў аргуменце ўжо складаней.
Прабегшы па вантробах xdg-open я высветліў, што ён аналізуе розныя параметры асяроддзя і перадае кіраванне далей альбо нейкім прыладам для адчынення файлаў спасылак спецыфічных для пэўнага DE, альбо ў яго маецца fallback у выглядзе функцыі open_generic
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
}
Хутка ўпілоўваю сюды невялікі хак з аналізам перададзенага аргумента і калі тамака знаходзіцца наша спецыфічная падрадка lync15:, то перадаем адразу кіраванне ў функцыю open_generic.
Спроба нумар 3 і вы думаеце зарабіла? Ага, зараз, як жа. Але паведамленне пра памылку ўжо памянялася, гэта ўжо прагрэс - зараз ён мне казаў што файл не знойдзены і ў выглядзе файла пісаў мне тую самую спасылку, перададзеную ў выглядзе аргумента.
На гэты раз справа апынулася ў функцыі is_file_url_or_path, якая аналізуе перададзена на ўваход спасылка на файл file:// альбо шлях да файла ці нешта іншае. І праверка не працавала дакладна з-за таго, што наш прэфікс (url scheme) мае лічбы, а рэгулярны выраз правяраецца толькі набор знакаў, які складаецца з :alpha: кропкі і працяжнік. Пасля кансультацыя са стандартам rfc3986 для uniform resource identifier стала зразумела што на гэты раз Майкрасофт нічога не парушае (хоць у мяне была такая версія). Проста клас сімвалаў :alpha: змяшчае толькі літары лацінскага алфавіту. Хутка мяняю праверку па рэгулярцы на alphanumeric. Гатова, вы цудоўныя, усё нарэшце запускаецца, кіраванне пасля ўсіх праверак аддаецца ў наш скрыпт-дадатак, на кансоль выводзіцца наша спасылка, усё як належыць. Пасля гэтага пачынаю падазраваць, што ўсе праблемы ў exo-open таксама з-за валідацыі фармату спасылкі з-за лічбаў у схеме. Для праверкі гіпотэзы змяняю рэгістрацыю mime-type у дадатку на проста схему lync і вуаля - усё працуе і без перавызначэння функцыі open_xfce. Але нам гэта ніяк не дапаможа, бо вэб-старонка для ўваходу ў канферэнцыю стварае менавіта спасылку з lync15.
Такім чынам, першая частка шляху пройдзена. Мы ўмеем перахапляць выклік спасылкі і далей яе трэба неяк апрацаваць і перадаць унутр Pidgin. Для таго каб зразумець як яно працуе ўсярэдзіне пры ўводзе дадзеных па спасылцы ў меню «далучэння да канферэнцыі» я схіліраваў гіт рэпазітар праекту Sipe і падрыхтаваўся зноў ныраць у код. Але тут мяне да шчасця прыцягнулі скрыпты ў каталогу contrib/dbus/:
- sipe-join-conference-with-uri.pl
- sipe-join-conference-with-organizer-and-id.pl
- sipe-call-phone-number.pl
- SipeHelper.pm
Аказваецца плягін Sipe даступны для ўзаемадзеяння праз dbus (desktop bus) і ўсярэдзіне скрыптоў прама ёсць прыклады далучэння ў канферэнцыю па спасылцы, або праз імя арганізатара і conf-id, або можна ініцыяваць званок праз sip. Гэта ж якраз тое чаго нам не хапала.
Крок 2. Рэалізацыя апрацоўшчыка для аўтаджойна
Раз ужо ёсць гатовыя прыклады на пэрл, то я вырашыў проста выкарыстоўваць sipe-join-conference-with-uri.pl і крыху дапрацаваць пад сябе. Пісаць на пэрл я ўмею, таму асаблівых складанасцяў гэта не даставіла.
Пасля тэставання скрыпту асобна, я ўпісаў яго выклік у файл lync.desktop. І гэта была перамога! Пры ўваходзе на старонку далучэння да канферэнцыі і дазволу запуску xdg-open ўсплывальнае акно канферэнцыі з Pidgin адчынялася аўтаматычна. Як жа я радаваўся.
Натхнёны поспехам, я вырашыў зрабіць тое ж самае і для свайго асноўнага браўзэра Mozilla Firefox. Пры ўваходзе праз лісу адчыняецца старонка для аўтарызацыі і яшчэ ў самым нізе ёсць кнопка join using office communicator. Яна-то і прыцягнула маю ўвагу. Пры кліку на яе ў браўзэры адбываецца пераход па адрасе:
conf:sip:{user};gruu;opaque=app:conf:focus:id:{conf-id}%3Frequired-media=audio
на што ён мне ветліва кажа, што не ведае як яе адкрыць і, магчыма, у мяне няма асацыяванага дадатку для такога пратакола. Ну, гэта мы ўжо праходзілі.
Хуценька рэгіструю сваё прыкладанне-скрыпт яшчэ і для uri-схемы конф і… нічога не адбываецца. Браўзэр працягвае скардзіцца, што няма прыкладання, якое апрацоўвае мае спасылкі. Пры гэтым выклік з кансолі xdg-open з параметрамі працуе цудоўна.
"Set custom protocol handler in firefox" – з гэтым пытаннем я выйшаў у Інтэрнэт. Прашэрсціўшы некалькі абмеркаванняў на stackoverflow (а куды ж без яго), накшталт адказ знайшоўся. Трэба стварыць спецыяльны параметр у about: config (вядома замяніўшы foo на conf):
network.protocol-handler.expose.foo = false
Ствараем, адчыняем спасылку і… не тут-то было. Браўзэр як ні ў чым ні хаджала кажа што не ведае наша дадатак.
Чытаю афіцыйную дакументацыю па рэгістрацыі пратакола ў Mozilla, ёсць варыянт прапісаць асацыяцыі ў самім gnome desktop (замяніўшы вядома foo на conf):
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
Рэгіструю, адкрываю браўзэр… і зноў барада.
Тут на вочы трапляецца радок з дакументацыі:
Next time you click a link of protocol-type foo you will be asked which application to open it with.
- Сямён Сямёныч
- Ааа
Мы ж не клікаем па спасылцы, а проста вэб-старонка робіць змену window.location праз javascript. Пішу просты html файл са спасылкай на conf пратакол, адкрываю ў браўзэры, клікаю па спасылцы - Yos! Адкрываецца акно з пытаннем у якім дадатку трэба адкрыць нашу спасылку і там у спісе ў нас ужо ёсць наша дадатак Lync - мы ж яго сапраўды зарэгістравалі ўсімі магчымымі спосабамі. Там жа ў акенцы ёсць галачка "запомніць выбар і заўсёды адкрываць спасылкі ў нашым дадатку", адзначаем, націскаем ок. І гэта другая перамога – акно канферэнцыі адчыняецца. Пры гэтым ужо адкрыццё канферэнцый працуе і не толькі пры зграі на спасылку, а і пры пераходзе з патрэбнай нам старонкі далучэння ў канферэнцыю.
Потым я праверыў, выдаленне параметраў network.protocol-handler.expose.conf ніяк не пацягнула на працу пратаколу ў лісе. Спасылкі працягвалі працаваць.
Заключэнне
Я заліў усе свае напрацоўкі ў рэпазітар на гітхаб, спасылкі на ўсе рэсурсы будуць у канцы артыкула.
Мне будзе цікава атрымаць зваротную сувязь ад тых, хто захоча скарыстацца маімі напрацоўкамі. Адразу адзначу, што я ўсё рабіў распрацоўку толькі пад сваю сістэму Linux Mint, таму нейкія іншыя дыстрыбутывы ці дэсктопы могуць не зарабіць у тым варыянце. Дакладней я нават амаль упэўнены ў гэтым, таму што я прапатчыў у xdg-open толькі 1 функцыю, якая адносіцца толькі да майго DE. Калі вы захочаце дадаць падтрымку іншых сістэм ці дэкстопаў, пішыце мне пул-рэквесты ў гітхабе.
Рэалізацыя ўсяго праекту заняла 1 вечар.
спасылкі:
Крыніца: habr.com