суббота, 19 октября 2013 г.

Bookmarklet для ускорения заполнения СЕДО.

Уважаемые коллеги!

У нас на кафедре используется скриптозакладка (bookmarklet), которая позволяет в один щелчок сократить список аудиторий в выпадающем списке СЕДО до необходимого лично вам.

Для работы надо перетащить эту ссылку на вашу панель закладок в браузере. После нажатия на неё скрипт удалит лишние аудитории.

Физически ничего нигде не меняется, и если страницу обновить - всё восстановится в первозданном виде. Это разовая оптимизация без сторонних эффектов.

В этом видео показан процесс установки, настройки и использования букмарклета (занимает примерно 4 минуты), а также разобран механизм его действия и метод создания:


Удачи всем!
Кафедра ИВТ.

P.S. Оставляйте в комментариях номера корпуса и аудиторий, если у вас не получилось сделать самим - буду выкладывать готовые букмарклеты на этой же странице.

P.P.S. Для желающих провести аудит скрипта (или делать себе такие инструменты самостоятельно), ниже приведён краткий анализ этого скрипта помимо описанного в видео.

Открываем свойства закладки и берём тело скрипта:


javascript:%0D%0Arooms=[['4','(3-08|3-07|3-1[35])']];%0D%0Afunction%20my_room(room){%0D%0Avar%20i;%0D%0Afor(i=0;i<rooms.length;i++){%0D%0Abuilding=rooms[i][0];%0D%0Aroom_reg=rooms[i][1];%0D%0Aregex=new%20RegExp('%D0%BA%D0%BE%D1%80%D0%BF.*'+building+'\\D*'+room_reg+'.*');%0D%0Aif(regex.exec(room)){%0D%0Areturn%201;%0D%0A}%0D%0A}%0D%0Areturn%200;%0D%0A}%0D%0Afunction%20remove_crap(){%0D%0Afor(line=0;line<10;++line){%0D%0Aselect=document.getElementsByName('signs['+line+'][2]')[0];%0D%0Aif(!select)continue;%0D%0Avar%20kids=select.options;%0D%0Avar%20selected_index=select.selectedIndex;%0D%0Afor(i=kids.length-5;i>3;--i){%0D%0Aif(kids[i].tagName&&kids[i].tagName.toLowerCase()=='option'){%0D%0Aif(!my_room(kids[i].text)&&i!=selected_index){%0D%0Aselect.remove(i);%0D%0A}%0D%0A}%0D%0A}%0D%0A}%0D%0A}%0D%0Aremove_crap()%0D%0A 

Само тело закодировано в URL формат (вместо пробела - %20, вместо открывающей скобки - %28, и т.п.). Мы его раскодируем или с помощью сетевого инструмента, или выполнив в консоли Питона простой код:
code = "javascript:%0D%0Arooms=[['1','(1-06|1-09|2-30)'],['4',%20'(3-07|3-08|3-15|3-13)']];%0D%0Afunction%20my_room(room){%0D%0Avar%20i;%0D%0Afor(i=0;i3;--i){%0D%0Aif(kids[i].tagName&&kids[i].tagName.toLowerCase()=='option'){%0D%0Aif(!my_room(kids[i].text)&&i!=selected_index){%0D%0Aselect.remove(i);%0D%0A}%0D%0A}%0D%0A}%0D%0A}%0D%0A}%0D%0Aremove_crap()%0D%0A" 
import urllib 
print urllib.unquote(code).decode('utf-8') 
 Так или иначе, мы получим уже что-то, более читаемое:
javascript:
rooms=[['1','(1-06|1-09|2-30)'],['4', '(3-07|3-08|3-15|3-13)']];
function my_room(room){
var i;
for(i=0;i<rooms.length;i++){
building=rooms[i][0];
room_reg=rooms[i][1];
regex=new RegExp('корп.*'+building+'\D*'+room_reg+'.*');
if(regex.exec(room)){
return 1;
}
}
return 0;
}
function remove_crap(){
for(line=0;line<10;++line){
select=document.getElementsByName('signs['+line+'][2]')[0];
if(!select)continue;
var kids=select.options;
var selected_index=select.selectedIndex;
for(i=kids.length-5;i>3;--i){
if(kids[i].tagName&&kids[i].tagName.toLowerCase()=='option'){
if(!my_room(kids[i].text)&&i!=selected_index){
select.remove(i);
}
}
}
}
}
remove_crap()
Немного форматирования, и мы получаем исходник, годный для работы:

Ключевые элементы алгоритма показаны ниже:
  1. Точка входа - функция remove_crap (строка 39).
  2. В цикле мы ищем на странице все элементы с именем signs[0..9][2] - это наши выпадающие списки.
  3. Для каждого списка берём массив вариантов выбора и текущий выбор, если он уже сделан.
  4. В цикле анализируем не все варианты - исключаем из анализа первые три и последние четыре (они будут всегда).
    Цикл по убыванию, чтобы из-за удаления ненужных элементов не сбивалась нумерация элементов в начале списка.
  5. Мы оставляем уже выделенные элементы и элементы из белого списка, который проверяется функцией my_room.
  6. Белый список - это массив rooms, в каждой строке которого мы держим пару ['номер-корпуса', '(номер-аудитории-1|номер-аудитории-2|...|номер-аудитории-n)'].

Комментариев нет:

Отправить комментарий