เฮ้ ฮับ!
สำหรับฉัน วลีนี้คล้ายกับสวัสดีชาวโลก เนื่องจากในที่สุดฉันก็ได้ตีพิมพ์ครั้งแรก ฉันเลื่อนช่วงเวลาอันแสนวิเศษนี้ไปนานแล้ว เนื่องจากไม่มีอะไรจะเขียน และฉันก็ไม่อยากดูดสิ่งที่ถูกดูดไปหลายครั้งแล้วด้วย โดยทั่วไปแล้ว สำหรับการตีพิมพ์ครั้งแรกของฉัน ฉันต้องการสิ่งที่แปลกใหม่ มีประโยชน์สำหรับผู้อื่น และประกอบด้วยความท้าทายและการแก้ปัญหาบางอย่าง และตอนนี้ฉันสามารถแบ่งปันสิ่งนี้ได้ ตอนนี้เรามาพูดถึงทุกอย่างตามลำดับ
การเข้า
Началось все с того, что некоторое время назад я на рабочем компе накатил себе Linux Mint. Многие наверняка знают, что Pidgin с плагином Sipe вполне годная замена Microsoft Lync (сейчас называется Skype for business) для Linux систем. В силу специфики работы мне часто приходится участвовать в sip-конференциях, и в бытность виндузятника вход в конференции был элементарным: получаем приглашение по почте, кликаем на ссылку входа, готово мы внутри.
При переходе на темную сторону Linux все несколько усложнилось: вход в конференции в Pidgin конечно же тоже есть, но там для этого нужно в свойствах вашего sip-аккаунта выбрать пункт присоединения к конференции в меню и в открывшемся окне вставить ссылку на конференцию либо ввести имя организатора и conf id. И через какое-то время я начал задумываться: «а нельзя ли как-то это упростить». Ага, скажете вы, на кой черт тебе это понадобилось, сидел бы себе на винде и в ус не дул.
ขั้นตอนที่ 1: การวิจัย
“ถ้าคุณมีความปรารถนาอยู่ในหัว คุณจะไม่สามารถเอาชนะมันได้ด้วยเดิมพัน” Nekrasov กล่าวในงานของเขา “Who Lives Well in Rus'”
ดังนั้น เมื่อความคิดเข้ามาในหัวของฉัน หลังจากนั้นไม่นาน ความคิดแรกในการนำไปปฏิบัติก็เกิดขึ้น ทุกอย่างดูเหมือนง่าย - คุณต้องสกัดกั้นการเข้าถึงลิงก์ — ติดตั้งกระบวนการแอปพลิเคชันเว็บในเครื่องบนรถของคุณที่ 127.0.0.1 และใน /etc/hosts เพิ่มรายการคงที่สำหรับโดเมนบริษัทที่คุณใช้เข้าสู่การประชุม โดยชี้ไปที่ localhost ต่อไปเว็บเซิร์ฟเวอร์นี้จะต้องประมวลผลลิงก์ที่เข้ามาและถ่ายโอนไปยัง Pidgin (ฉันจะบอกทันทีว่าในขั้นตอนนี้ฉันยังไม่รู้ว่าจะมอบให้กับมันได้อย่างไร) แน่นอนว่าวิธีแก้ปัญหานั้นมีกลิ่นเหมือนไม้ค้ำยัน แต่เราเป็นโปรแกรมเมอร์ ไม้ค้ำยันไม่ได้ทำให้เรากลัวหรอก (ไร้สาระ)
จากนั้นฉันก็เปิดลิงก์คำเชิญใน Google Chrome โดยบังเอิญ (และโดยปกติฉันจะใช้ Mozilla Firefox เสมอ) และที่น่าประหลาดใจของฉันคือหน้าเว็บดูแตกต่างไปจากเดิมอย่างสิ้นเชิง - ไม่มีรูปแบบสำหรับการป้อนข้อมูลผู้ใช้และทันทีที่เข้าสู่หน้าก็มีคำขอให้เปิดบางอย่างผ่าน XDG เปิด. เพื่อความสนุก ฉันคลิก "ใช่" และข้อความแสดงข้อผิดพลาดปรากฏขึ้น - ลิงก์ lync15:confjoin?url=https://meet.company.com/user/confid ไม่สามารถเปิดได้ อืม. นี่คือ xdg-open ประเภทใด และจำเป็นอย่างไรจึงจะเปิดลิงก์ดังกล่าวได้ การอ่านเอกสารภายหลังการชันสูตรพบว่าเป็นตัวจัดการ GUI ที่ช่วยเรียกใช้แอปพลิเคชันที่เกี่ยวข้องทั้งกับโปรโตคอลสำหรับรูปแบบ uri หรือกับประเภทไฟล์เฉพาะ การเชื่อมโยงได้รับการกำหนดค่าผ่านการแมปประเภท mime ดังนั้นเราจึงเห็นว่าเรากำลังดำเนินการค้นหาแอปพลิเคชันที่ตรงกันสำหรับโครงร่าง uri ที่มีชื่อว่า ลินซี15 และลิงก์จะถูกส่งผ่านไปยัง 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 ที่เกี่ยวข้องกับแอปพลิเคชันของฉัน ทำได้โดยใช้คำสั่งง่ายๆ:
xdg-mime default lync.desktop x-scheme-handler/lync15
ซึ่งเพียงแค่แก้ไขไฟล์ ~/.config/mimeapps.list.
พยายามหมายเลข 2 ด้วยการเรียก xdg-open - และล้มเหลวอีกครั้ง ไม่มีความยากลำบากใดที่ไม่ทำให้เราหวาดกลัว แต่เพียงกระตุ้นความสนใจของเราเท่านั้น และด้วยพลังทั้งหมดของ bash (เช่น การติดตาม) เราจะดำดิ่งลงสู่การดีบักเป็นอันดับแรก สิ่งสำคัญที่ควรทราบที่นี่คือ xdg-open เป็นเพียงเชลล์สคริปต์
bash -x xdg-open $url
การวิเคราะห์ผลลัพธ์หลังจากการสืบค้นกลับจะชัดเจนขึ้นเล็กน้อยว่าการควบคุมนั้นถูกถ่ายโอนไปยัง เปิดนอก. และนี่เป็นไฟล์ไบนารี่อยู่แล้วและเป็นการยากกว่าที่จะเข้าใจว่าเหตุใดจึงส่งคืนโค้ดส่งคืนที่ไม่สำเร็จเมื่อส่งลิงก์ไปยังไฟล์นั้นในอาร์กิวเมนต์
เมื่อดูภายในของ xdg-open แล้ว ฉันพบว่ามันวิเคราะห์พารามิเตอร์สภาพแวดล้อมต่างๆ และส่งผ่านการควบคุมเพิ่มเติมไปยังเครื่องมือบางอย่างสำหรับการเปิดลิงก์ไฟล์สำหรับ DE โดยเฉพาะ หรือมีฟังก์ชันทางเลือก 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) มีตัวเลข และนิพจน์ทั่วไปจะตรวจสอบเฉพาะชุดอักขระที่ประกอบด้วย :alpha: จุดและขีดกลางเท่านั้น หลังจากปรึกษามาตรฐาน rfc3986 แล้ว ตัวระบุทรัพยากรที่สม่ำเสมอ เห็นได้ชัดว่าคราวนี้ Microsoft ไม่ได้ละเมิดอะไรเลย (แม้ว่าฉันจะมีเวอร์ชันดังกล่าวก็ตาม) เฉพาะคลาสอักขระ :alpha: ประกอบด้วยตัวอักษรละตินเท่านั้น ฉันรีบเปลี่ยนเช็คปกติเป็นตัวอักษรและตัวเลข เสร็จสิ้น คุณทำได้ยอดเยี่ยมมาก ในที่สุดทุกอย่างก็เริ่มต้นขึ้น ควบคุมหลังจากตรวจสอบแอปพลิเคชันสคริปต์ของเราแล้ว ลิงก์ของเราจะปรากฏบนคอนโซล ทุกอย่างเป็นไปตามที่ควรจะเป็น หลังจากนี้ฉันเริ่มสงสัยว่าปัญหาทั้งหมดของ exo-open นั้นเกิดจากการตรวจสอบความถูกต้องของรูปแบบลิงก์เนื่องจากตัวเลขในโครงการ เพื่อทดสอบสมมติฐาน ฉันเปลี่ยนการลงทะเบียนประเภท mime ของแอปพลิเคชันให้เป็นเพียงโครงร่าง ลินคอล์น และ voila - ทุกอย่างทำงานได้โดยไม่ต้องแทนที่ฟังก์ชัน open_xfce แต่สิ่งนี้จะไม่ช่วยเราแต่อย่างใดเพราะหน้าเว็บสำหรับการเข้าร่วมการประชุมจะสร้างลิงก์กับ lync15
การเดินทางส่วนแรกก็เสร็จสิ้นแล้ว เรารู้วิธีสกัดกั้นการเรียกลิงก์ จากนั้นมันจะต้องได้รับการประมวลผลและส่งผ่านเข้าไปใน Pidgin เพื่อให้เข้าใจวิธีการทำงานภายในเมื่อป้อนข้อมูลผ่านลิงก์ในเมนู “เข้าร่วมการประชุม” ฉันจึงโคลนพื้นที่เก็บข้อมูล Git ของโปรเจ็กต์ Sipe และเตรียมพร้อมที่จะดำดิ่งลงสู่โค้ดอีกครั้ง แต่โชคดีที่ฉันถูกดึงดูดโดยสคริปต์ในแค็ตตาล็อก มีส่วนร่วม/dbus/:
- sipe-join-conference-with-uri.pl
- sipe-join-conference-with-organizer-and-id.pl
- sipe-call-phone-number.pl
- SipeHelper.pm
ปรากฎว่าปลั๊กอิน Sipe พร้อมสำหรับการโต้ตอบผ่าน dbus (บัสเดสก์ท็อป) และภายในสคริปต์มีตัวอย่างการเข้าร่วมการประชุมผ่านลิงก์ ไม่ว่าจะผ่านชื่อของผู้จัดงานและ conf-id หรือคุณสามารถเริ่มการโทรผ่าน sip . นี่คือสิ่งที่เราขาดหายไป
ขั้นตอนที่ 2 การใช้ตัวจัดการเข้าร่วมอัตโนมัติ
เนื่องจากมีตัวอย่างสำเร็จรูปใน Pearl ฉันจึงตัดสินใจใช้ sipe-join-conference-with-uri.pl และปรับเปลี่ยนเล็กน้อยให้เหมาะกับตัวเอง ฉันสามารถเขียนเป็นภาษาเพิร์ลได้ ดังนั้นมันจึงไม่ทำให้เกิดปัญหาใดๆ เป็นพิเศษ
หลังจากทดสอบสคริปต์แยกกัน ฉันจึงเขียนการเรียกใช้สคริปต์ลงในไฟล์ lync.เดสก์ท็อป. และมันก็เป็นชัยชนะ! เมื่อเข้าสู่หน้าเข้าร่วมการประชุมและอนุญาตให้ xdg-open ทำงาน หน้าต่างป๊อปอัปการประชุมจาก Pidgin จะเปิดขึ้นโดยอัตโนมัติ ฉันดีใจแค่ไหน
ด้วยการสนับสนุนจากความสำเร็จ ฉันจึงตัดสินใจทำเช่นเดียวกันกับเบราว์เซอร์หลักของฉัน Mozilla Firefox เมื่อคุณเข้าสู่ระบบผ่าน Fox หน้าการอนุญาตจะเปิดขึ้นและที่ด้านล่างสุดจะมีปุ่ม เข้าร่วมโดยใช้เครื่องมือสื่อสารสำนักงาน. เธอคือคนที่ดึงดูดความสนใจของฉัน เมื่อคุณคลิกในเบราว์เซอร์ มันจะไปที่ที่อยู่:
conf:sip:{user};gruu;opaque=app:conf:focus:id:{conf-id}%3Frequired-media=audio
ซึ่งเขากรุณาบอกฉันว่าเขาไม่ทราบวิธีเปิดมัน และบางที ฉันไม่มีแอปพลิเคชันที่เกี่ยวข้องสำหรับโปรโตคอลดังกล่าว เราเคยผ่านเรื่องนี้มาแล้ว
ฉันลงทะเบียนแอปพลิเคชันสคริปต์ของฉันอย่างรวดเร็วสำหรับโครงร่าง uri ด้วย conf และ...ไม่มีอะไรเกิดขึ้น เบราว์เซอร์บ่นว่าไม่มีแอปพลิเคชันใดที่จัดการลิงก์ของฉัน ในกรณีนี้ การเรียก xdg-open จากคอนโซลพร้อมพารามิเตอร์ทำงานได้อย่างสมบูรณ์
“ตั้งค่าตัวจัดการโปรโตคอลแบบกำหนดเองใน Firefox” - ฉันออนไลน์พร้อมกับคำถามนี้ หลังจากผ่านการพูดคุยกันหลายครั้งเกี่ยวกับ stackoverflow (และเราจะอยู่ที่ไหนถ้าไม่มีมัน) ดูเหมือนว่าคำตอบจะถูกพบแล้ว คุณต้องสร้างพารามิเตอร์พิเศษมา about: config (แน่นอนแทนที่ foo ด้วย conf):
network.protocol-handler.expose.foo = false
เราสร้างมันขึ้นมา เปิดลิงก์และ... ไม่มีโชคเช่นนั้น เบราว์เซอร์ราวกับว่าไม่มีอะไรเกิดขึ้นบอกว่าไม่รู้จักแอปพลิเคชันของเรา
ฉันกำลังอ่านเอกสารอย่างเป็นทางการเกี่ยวกับการลงทะเบียนโปรโตคอลจาก Mozilla มีตัวเลือกในการลงทะเบียนการเชื่อมโยงในเดสก์ท็อป gnome เอง (แทนที่ 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
ฉันลงทะเบียน เปิดเบราว์เซอร์... และหนวดเคราอีกครั้ง
นี่คือบรรทัดจากเอกสารที่ดึงดูดสายตาของฉัน:
ครั้งต่อไปที่คุณคลิกลิงก์ประเภทโปรโตคอล foo คุณจะถูกถามว่าจะเปิดด้วยแอปพลิเคชันใด
— เซมยอน เซเมนิช
- อ่า
เราไม่คลิกลิงก์ แต่หน้าเว็บเพียงเปลี่ยน window.location ผ่าน javascript ฉันเขียนไฟล์ html ธรรมดาพร้อมลิงก์ไปยังโปรโตคอล conf เปิดในเบราว์เซอร์คลิกที่ลิงก์ - Yos! หน้าต่างจะเปิดขึ้นเพื่อถามว่าแอปพลิเคชันใดที่เราต้องเปิดลิงก์ และเรามีแอปพลิเคชัน Lync อยู่ในรายการแล้ว - เราลงทะเบียนแอปพลิเคชันดังกล่าวด้วยวิธีที่เป็นไปได้ทั้งหมดโดยสุจริต ในหน้าต่างจะมีช่องทำเครื่องหมาย "จดจำตัวเลือกและเปิดลิงก์ในแอปพลิเคชันของเราเสมอ" ทำเครื่องหมายคลิกตกลง และนี่คือชัยชนะครั้งที่สอง - หน้าต่างการประชุมจะเปิดขึ้น ในเวลาเดียวกัน การเปิดการประชุมไม่เพียงทำงานเมื่อคุณคลิกลิงก์เท่านั้น แต่ยังรวมถึงเมื่อย้ายจากหน้าเข้าร่วมที่เราจำเป็นต้องไปยังการประชุมด้วย
จากนั้นฉันตรวจสอบโดยลบพารามิเตอร์ network.protocol-handler.expose.conf ไม่มีผลกระทบต่อการทำงานของโปรโตคอลใน Fox แต่อย่างใด ลิงก์ยังคงทำงานต่อไป
ข้อสรุป
ฉันได้อัปโหลดงานทั้งหมดของฉันไปยังที่เก็บ GitHub แล้ว ลิงก์ไปยังแหล่งข้อมูลทั้งหมดจะอยู่ท้ายบทความ
Мне будет интересно получить обратную связь от тех кто захочет воспользоваться моими наработками. Сразу отмечу, что я все делал разработку только под свою систему Linux Mint, поэтому какие-то другие дистрибутивы или десктопы могут не заработать в том варианте. Вернее я даже почти уверен в этом, потому что я пропатчил в xdg-open только 1 функцию, относящуюся только к моему DE. Если вы захотите добавить поддержку других систем или декстопов, пишите мне пул-реквесты в гитхабе.
โครงการทั้งหมดใช้เวลาเย็น 1 คืนจึงจะเสร็จสมบูรณ์
อ้างอิง:
ที่มา: will.com
