Автоматизация управления музыкой в офисе, любая песня на заказ по ICQ


Я – офисный сотрудник. Мое рабочее место – кабинет, в котором помимо меня сидит еще 6 человек. Я давно привык, что фоном всегда играет музыка, за исключением тех рабочих процессов, в которых нужна концентрация. Слушать музыку в наушниках как-то неудобно, да и голова начинает болеть вскоре. Поэтому слушал я ее всегда так, что моим «соседям» не услышать ее было невозможно. Они меня ругали… но ругали не за то, что я мешал им самой музыкой, а за то, что слушал я неправильную музыку. Тогда у меня появилось желание угодить всем, чтобы каждый мог, не вставая со своего места, включить любую песню, даже ту, которой нет на компьютере.

Схема

На первый взгляд автоматизация должна включать следующие возможности: включение любого трека из сети онлайн, смена трека, регулировка громкости, возможность поставить проигрывание на паузу и, соответственно, снять с паузы, а также должна быть возможность включить трек, расположенный локально на компьютере. С программированием как таковым я толком не знаком, за исключением чтения мануала по AutoIT (всегда хотел уметь автоматизировать какие-либо процессы в Windows-системах). В голове сразу возникла схема: AutoIT+ICQ+Foobar+Плагин для Foobar’а, позволяющий искать и слушать музыку онлайн из социальной сети «ВКонтакте» (его окно изображено на скриншоте). Суть проста: мои коллеги шлют в определенную асю сообщения, скрипт AutoIT их «подхватывает» и, в соответствии с сообщением, выполняет манипуляции с Foobar’ом.

Реализация

Так как при работе AutoIT на экране видны все манипуляции скрипта: открытие окон, выбор трека и так далее, то изначально я планировал использовать для него виртуальную машину, но, обернувшись, увидел простаивающий компьютер недавно уволившегося сотрудника и решил, что «медиацентром» пока будет он.
image
Первым делом я зарегистрировал новый аккаунт ICQ для бота. Придумывание ника для него не заняло много времени – «Пульт». Затем установил на выбранный компьютер QIP 8095 – этот клиент я выбрал из-за того, что сообщения в нем хранятся в виде txt-файлов. Настроил его следующий образом: отключил сохранение истории сервисных сообщений (о том, что кто-то из контакт-листа вошел в сеть или вышел и прочее), также выключил все звуки, чтобы они не отвлекали от работы коллег. Затем установил Foobar с необходимым плагином и настроил его на работу с горячими клавишами. И в конце занес в контакт-лист бота себя и всех сотрудников, сидящих со мной в кабинете.

После завершения всех подготовительных работ приступил к написанию самого скрипта. Принцип его работы прост: он каждые 2 секунды должен проверять папку, в которой QIP хранит историю переписки, на наличие txt-файла, если файл находится, он читает из него сообщение, удаляет сам файл истории и, в соответствии с тем, что было написано в сообщении производит манипуляции с Foobar’ом.

Что получилось в итоге

Скрипт:

Func Terminate() ; Функция выключения скрипта так как он работает в бесконечном цикле
Exit 0
EndFunc
HotKeySet("{ESC}", "Terminate")  ; Привязывает функцию выключения к клавиши ESC
 
FileChangeDir ("C:Program FilesQIPUsersXXXXXXXXXHistory"); Изменяет рабочую директорию 
 
while 1 ; Начинает бесконечный цикл работы скрипта
$Search=FileFindFirstFile("*.txt") ; Ищет txt-файлы в рабочей директории и возвращаемое значение поиска заносим в переменную $Search
if $Search = -1 then ; Проверяет наличие файлов по содержимому переменной
Sleep(1000) ; Если файлов не найдено, ждет секунду и запускает цикл сначала
else ; Если найден txt-файл, то...
$File=FileFindNextFile($Search) ; Заносит название файла в перменную $File
$Log=FileRead ($File) ; Заносит содержимое файла в переменную $log
$Log=StringSplit ($Log, @LF) ; Так как в QIP'е одно сообщение состоит из трех строк (пометка сообщения как входящее или исходящее, имя автора/дата/время отправки сообщения и само сообщение), то делает из переменной массив, в котором каждый элемент равен одной строке
$Mess=$log[3] ; Само сообщение заносит в переменную $Mess
FileDelete($File) ; Удаляет файл истории
MsgBox ("0","", $Mess, 1) ; На секунду выводит на экран сообщение с командой, которую скрипт будет сейчас выполнять - это реализовано для отладки
WinActivate ('[REGEXPCLASS:(?i){97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}]') ; Делает активным окно Foobar'a, реализовал посредством обращения к классу, так как заголовок плеера меняется в зависимости от исполняемой композиции
WinWaitActive ('[REGEXPCLASS:(?i){97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}]') ; Ждет когда окно Foobar'a станет активным
 
$Check=StringInStr($Mess, "local") ; Проверяет вхождение слова "local" в текст сообщения
if $Check=1 then ; Если "local" находится в начале сообщения, то...
$Mess=StringTrimLeft($Mess, 6) ; "Отрезает" первые 6 символов в сообщении (слово local и последующий пробел)
Send("^f") ; Отправляет нажатие сочетания клавиш CTRL+F
WinWaitActive ('[REGEXPCLASS:(?i){483DF8E3-09E3-40d2-BEB8-67284CE3559F}]') ; Ждем пока откроется окно поиска трека
Send($Mess) ; Вводит в запрос содержимое сообщения
Sleep(500) ; Ждет полсекунды
Send("{TAB}") ; Отправляет нажатие клавиши TAB
Sleep(500) ; Ждет
Send("{TAB}") ; Отправляет нажатие клавиши TAB (делается активным элемент окна, в котором выводится результат поиска)
Sleep(500) ; Ждет
Send("{DOWN}") ; Отправляет нажатие клавиши DOWN (выделяется первый трек, найденный поиском)
Sleep(500) ; Ждет
Send("{ENTER}") ; Включает найденный трек
Sleep(500) ; Ждет
WinClose('[REGEXPCLASS:(?i){483DF8E3-09E3-40d2-BEB8-67284CE3559F}]') ; Закрывает окно поиска
continueloop ; Возвращается в начало бесеконечного цикла while
endif ; Если слова "local" в начале сообщеня нет, то скрипт продолжает чтение отсюда... 
 
$Stop=StringRegExp ($Mess, "стоп") ; ... ищет вхождение слова "стоп" в сообщении
$VolUp=StringRegExp ($Mess, "громче") ; Ищет вхождение слова "громче" в сообщении
$VolDown=StringRegExp ($Mess, "тише") ; Ищет вхождение слова "тише" в сообщении
$VolMax=StringRegExp ($Mess, "громко") ; Ищет вхождение слова "громко" в сообщении
$VolMin=StringRegExp ($Mess, "тихо") ; Ищет вхождение слова "тихо" в сообщении
 
if $Stop=1 then ; Если отправлено слово "стоп", то..
Send ("!x") ; ... отправит сочетание клавиш ALT+X, которое ставит на паузу/продолжает проигрывание
continueloop ; Возвращается в начало бесеконечного цикла while
endif
 
if $VolUp=1 then ; Если отправлено слово "громче", то...
Send ("!{UP}") ; ...
Send ("!{UP}") ; ...
Send ("!{UP}") ; ...
Send ("!{UP}") ; ...
Send ("!{UP}") ; 5 раз нажимает сочетание клавиш ALT+UP, которое чуть-чуть увеличивает громкость
continueloop ; Возвращается в начало бесеконечного цикла while
endif
 
if $VolDown=1 then ; Если отправлено слово "громче", то...
Send ("!{DOWN}") ; ...
Send ("!{DOWN}") ; ...
Send ("!{DOWN}") ; ...
Send ("!{DOWN}") ; ...
Send ("!{DOWN}") ; 5 раз нажимает сочетание клавиш ALT+DOWN, которое чуть-чуть уменьшает громкость
continueloop ; Возвращается в начало бесеконечного цикла while
endif
 
if $VolMax=1 then ; Если отправлено слово "громко", то...
Send ("!c") ; ... отправит сочетание клавиш ALT+C, которое включает максимальную громкость
continueloop ; Возвращается в начало бесеконечного цикла while
endif
 
if $VolMin=1 then ; Если отправлено слово "тихо", то...
Send ("!z") ; ... отправит сочетание клавиш ALT+Z, которое включает минимальную громкость (не выключает совсем)
continueloop ; Возвращается в начало бесеконечного цикла while
endif
 
; Если не один из выстоящих if'ов не сработал, то...
 
Send ("^q") ; Отправляет сочетание клавиш CTRL+Q, отвечающее за открытие окна плагина Foobar'a, который ищет музыку в ВКонтакте
WinWaitActive ("vk.com audio Search") ; Ждет пока окно плагина не станет активным
ControlCommand("vk.com audio Search", "", "ComboBox1", "SetCurrentSelection", 6) ; Из выпадающего списка "В каких сервисах искать" выбирает vk.com (ВКонтакте)
Sleep(500) ; Ждет полсекунды
ControlFocus("vk.com audio Search", "", "Edit1") ; Делает активным строку ввода запроса
Sleep(500) ; Ждет
Send($Mess) ; Отправляет в строку ввода содержимое сообщения из QIP'а
Sleep(5000) ; Ждет 5 секунд, пока плагин ищет трек
 
while 1 ; Не знаю как иначе реализовать то, что будет дальше, кроме как с использованием бесконечного цикла
$i=ControlListView ("vk.com audio Search", "", "SysListView321", "GetItemCount") ; Заносит в переменную $i количество найденных треков
if $i=0 then ; Если треков не найдено (плагин иногда не находит результаты с первого раза)
ControlClick("vk.com audio Search", "", "Button1") ; Нажимает на кнопку "Остановить поиск"
Sleep(500) ; Ждет
ControlClick("vk.com audio Search", "", "Button1") ; Нажимает на кнопку "Поиск"
Sleep(5000) ; Ждет
exitloop ; Выходит из внутреннего бесконечного цикла while (со второго раза всегда находит)
else
exitloop ; Если не нашел с первого раза, то, скорее всего, название трека ввели неправильно и скрипт также выходит из внутреннего бесеконечного цикла while
endif
wend
 
ControlListView ("vk.com audio Search", "", "SysListView321", "Select", 1) ; Выбирает из результата поиска второй трек (первый зачастую почему-то бывает длительностью 00:00 и не играет)
ControlClick("vk.com audio Search", "", "Button3") ; Добавляет в плейлист второй трек
WinClose("vk.com audio Search") ; Закрывает окно плагина
WinWaitActive ('[REGEXPCLASS:(?i){97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}]') ; Ждет пока окно Foobar'а станет активным
Sleep(500) ; Ждет полсекунды
Send ("{END}") ; Отправляет
Sleep(500) ; Ждет
Send ("{ENTER}") ; Отправляет нажатие клавиши ENTER, что включает трек
endif
wend ; Возвращается в начало бесеконечного цикла


Как это работает

Перед началом работы в плейлист Foobar’a необходимо добавить локальную библиотеку музыки. Если кто-то пишет просто: «metallica fade to black», то скрипт «находит» эту песню в ВКонтакте и включает ее. Если кто-то написал: «local joe satriani crowd chant», то скрипт находит трек в своем плейлисте, а затем его включает. Также доступны команды: «тихо», «громко», «тише», «громче» и «стоп».

Заключение

Делал это я несколько часов и знаю, что скрипт далеко неидеален, в нем много недоработок, например: следовало бы как-то сократить код (наверняка можно переиграть отлов команд более правильным способом) или, если человек со словом «local» запрашивает трек, которого нет в плейлисте, то его надо искать в онлайне и так далее. Я не программист совсем, поэтому, если не сложно, напишите о ошибках построения кода, буду благодарен.
Поделиться публикацией

Комментарии 36

    +12
    как сложно сделать очевидное в windows…
      0
      у фубара иконка уже давно другая.
        0
        Прошу прощения за оплошность :)
        +2
        Для винампа есть плагин gen_songrequest. Он создает для винампа мини-веб-морду с плейлистом. Там можно и сам плейлист посмотреть и следующий трек заказать.
          +1
          Я старался свести к минимуму количество действий для смены трека. Зачем смотреть плейлист если достаточно просто написать название? Хотя да, соглашусь, порой, когда не знаешь что включить, глазами бегаешь по плейлисту и находишь некогда любимые треки — если только для этого.
          –8
          А не могли бы вы выложить код без комментариев?) Тяжело мне с ними читать код. А то давно хочу сделать управление тореном удаленное. Посмотрю как у Вас сообщения отлавливаются.

          PS: На форуме AutoIt есть парочка dll и UDF для работы с ICQ/Jabber протоколом. Можете поиграться с ними)
            +16
            лучше и не беритесь, если уж для Вас удаление комментариев из кода непосильная задача.
              +11
              ну и само желание избавиться от комментариев конечно верх адекватности.
                –3
                это не верх адекватности, а просто в код AutoIt сам по себе примитивный. комментарии практически не к чему. Я ставлю только описание функций и все.
                  0
                  Да вы шутите что ли?
                  В любом текстовом редакторе, поддерживающим регулярные выражения, замените регулярное выражение "; .*" (без кавычек) на пустую строку.
                    –7
                    Да вы шутите что ли? )
                      +4
                      Какой-такой текстовый редактор?
                      cat script.txt | sed 's/;.*//'
                        +1
                        Некроссплатформенно :)
                        К тому же, если у автора есть проблема с удалением комментариев, это для него точно китайский.

                        А так да, нормальный пацанский вариант.
                          0
                          Эм, первое, что я ставлю на свежую винду — cygwin или unixutils.
                            0
                            Ну cygwin и у меня стоит. У меня и с удаление комментов проблем нет :)
                            0
                            Да, я в курсе и ждал этого комментария, но это скорее как идиома.
                  +3
                  В uTorrent есть веб-интерфейс. Все делается в 2 щелчка мыши.
                    0
                    При создании удаленного управления торрентом я бы не использовал ICQ в принципе, достаточно связки DropBox+AutoIT. То есть, находясь на работе, в определенную папку DropBox'а Вы кидаете torrent-файл, а домашний компьютер (который будет качать, как я понимаю), видя, что в этой папке появился торрент-файл, добавит его в очередь закачки торрентов автоматически.
                      0
                      … достаточно связки DropBox+AutoIT… находясь на работе, в определенную папку DropBox'а Вы кидаете torrent-файл, а домашний компьютер (который будет качать, как я понимаю), видя, что в этой папке появился торрент-файл, добавит его в очередь закачки торрентов автоматически.

                      Перечитал три раза, так и не понял, зачем здесь AutoIT. Достаточно взять торрент клиент (в наших реалиях это почти любой), который сам в состоянии «обнаружив файл, добавить его в очередь». Без костылей, которые не нужны.
                        0
                        Не знал, что торрент клиенты умеют обнаруживать торрент-файлы
                    0
                    Когда я решал подобную задачу в 2006 г., нашёл довольно простой плагин для Винампа. Искать сейчас правда лень.
                      0
                      А что, если я хочу послушать песню группы Local H, которой нет в моем плейлисте?
                        0
                        В конце статьи я написал, что скрипт неидеален и требует доработки. Тут на самом деле много «А если...», но в Вашем случае поможет пробел в начале запроса.
                          0
                          Самый главный минус я вижу в том, что в Интернете сейчас полно всевозможных ремиксов и перепевок. Хочешь, например, подшутить над коллегами и включаешь какую-нибудь Надежду Бабкину, а из колонок начинает играть, блин, ныне модный клубняк и коллеги начинают кивать головой в такт :(
                        +7
                        Юниксоиды воспользовались бы mpd.
                          +2
                          MPD и под винду есть.
                            0
                            Если кто-то будет гуглить «mpd вконтакте», не заходите по первой ссылке на лор.ру, разочаруетесь в коммьюнити.
                            –3
                            Как же круто это все в OSX из коробки работает!
                              0
                              А как? Напишите! Только не удалённое управление айтюнсом, а именно поиск и прослушивание онлайн.
                                –4
                                Удаленного поиска онлайн нет, но можно свой трек запустить по сети. В iTunes другая идеология. Твоя личная медиатека у тебя на компьюетере, а не в Сети.
                                  0
                                  Ну, значит не работает из коробки поиск и проигрываение музыки из вконтактика :)

                                  Кстати, с идеологией тоже промашка — с запуском iCloud вовсе не обязательно иметь личную медиатеку у себя на компьютере: специально сейчас проверил и запустил на другом компе iTunes с пустой медиатекой — играет музыку из моей медиатеки, но из Сети (iTunes in the Cloud).
                                  –1
                                  Да там, при желании, можно и Ваш велосипед нагородить. Причем именно что «из коробки», без установки левого софта. Там AutoIT устанавливать ненужно, там Automator в каждой Mac OS по умолчанию установлен.
                                    0
                                    Ну и за что минусуют? Хейтерам не понравилось, что в системе обнаружилось два штатных средства: Automator и AppleScript?
                                +3


                                После чего «Play to» с любого компьютера. Отдельный минус за использование AutoIt: жать по кнопочкам в интерфейсе это настолько же убого, насколько и «юникс-вей», когда программы пытаются «понять» и контроллировать UI других программ. UI — это USER interface (будь то CLI или Graphical), а для управления одних программ другими придумали такую штуку, как API (шок!).
                                  +1
                                  «С программированием как таковым я толком не знаком, за исключением чтения мануала по AutoIT...»

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое