2013-08-04

Встречайте BibleTools

После довольно долгого времени я наконец собрался воплотить свой давний замысел. А именно: набирая текст в GEdit, через сочетание клавиш разворачивать библейские ссылки типа "Ин.3:16" в полный текст. Вообще планы по развитию утилиты большие, но то, ради чего всё затевалось, уже можно использовать. Прогресс будет описываться на этой странице, и возможно, пока вы читаете этот пост, версия уже обновилась :) В составе синодальный перевод и консольная утилита, которую можно использовать так:

$ bibletools --link "Ин.3:16-18"

Далее. Чтобы прикрутить к GEdit, нужно активировать плагин "Внешние инструменты", и добавить свой. Основные пути:

Edit > Preferences > Plugins > External Tools
Tools > Manage External Tools

Добавленный инструмент может выглядеть примерно так:


Пишем текст в редакторе, выделяем ссылку, жмём Alt+1 и получаем текст Писания. Пока это всё, жду заинтересованных откликов!

P.S. А интересен ли вам вот такой функционал?

2013-07-30

IntelliJ Idea и автоматизация конвертации SCSS в CSS, а CSS в minify-версию

Для того, чтобы автоматизировать работу с определёнными категориями файлов, нужно установить плагин File Watchers. В нём есть несколько предустановленных механизмов, однако они требуют для своей работы сторонние скрипты. Например, чтобы автоматически конвертировать SCSS-файлы в CSS, нужно установить ruby-gem sass, а для сжатия CSS и JS нужен компрессор. В Ubuntu это всё можно сделать одной командой bash:

sudo apt-get install ruby-sass yui-compressor

Настройка File Watcher выглядит тривиально. Вот так:

2013-07-29

Неожиданное применение автоматического тестирования

У всех в работе бывают косяки. Я не исключение, поэтому однажды, при написании довольно сложной формы допустил очень неочевидную ошибку, в результате чего, прежде чем я успел этому помешать, несколько сотен раз пользователи сохранили неверные данные.

Когда форма была исправлена, встал вопрос: что делать? Вопрос "Кто виноват", понятное дело, не стоял. Исправление можно было произвести двумя путями: один - это писать скрипт, учитывающий все условия формы и прогонять сохранённые данные через него. Можно, но времени разбираться на этот момент не было (форма всё-таки и правда не тривиальная была). Второй способ - это заставить пользователей снова открывать форму для редактирования и пересохранить данные, т.е. просто открыть страницу с определённым URL и нажать кнопку "Сохранить". Конечно, они в этом не виноваты, и страдать не должны. Делать это мне? Ещё дольше, чем скрипт писать!

А почему бы не поручить это кому-нибудь, у кого много свободного времени, кто не будет возражать и способен делать рутинную работу без всякого ропота? Среди людей таких нет. Тогда обратимся к роботам.

Ну и тут, как вы догадались, Selenium спешит на помощь. Буквально несколько минут, и готов тестовый скрипт, который займётся всей работой. Запускаем Selenium server ...


java -jar selenium-server-standalone-2.33.0.jar

... и наш скрипт ...


python test.py

... и наблюдаем, как человек-невидимка открывает браузер, переходит по ссылкам и нажимает кнопки. Что нам и нужно было.

А вот, собственно, скрипт.


#!/usr/bin/env python
#coding:utf8

from selenium import webdriver
import unittest
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Wd(unittest.TestCase):
 def setUp(self):
  self.driver = webdriver.Remote(
   command_executor='http://0.0.0.0:4444/wd/hub',
   desired_capabilities=DesiredCapabilities.FIREFOX)
  self.driver.implicitly_wait(30)
  self.base_url = "http://my.address.ru"

 def test_saveButtonClick(self):
  driver = self.driver
  for id in [222706,426061,441101]:
   url = "%s/edit_page_%d" % (self.base_url,id)
   driver.get(url)
   driver.find_element_by_id("saveform").click()

 def tearDown(self):
  self.driver.quit()

if __name__ == "__main__":
 unittest.main()

2013-07-22

Использование оператора for в Twig: итератор

Некоторое время пользуюсь шаблонизатором Twig, где циклы в шаблонах задаются практически только с использованием оператора for:

{% for item in some_array %}
 {{ item }}
{% endfor %}

При обходе массива (что и делается в большинстве случаев) вопросов не возникало. Но тут приспичило мне сделать цикл типа while. То есть подразумевалось нечто вроде

{% while item = some_array.next() %}
 {{ item }}
{% endwhile %}
однако, while не реализован в Twig.

Недолгий гуглёж привёл меня (внезапно!) на страницу документации Twig, где черным по английскому написано: "A sequence can be either an array or an object implementing the Traversable interface." Итак, решается задачка таким образом: создаётся объект, имплементирующий методы стандартного PHP-интерфейса Iterator, подаётся в оператор for и всё работает. Как-то так:


class SomeItems implements Iterator{
 private $position = 0;
 private $items = [];

 public function add($item){
  $this->items[] = $item;
 }

 public function current() {
  return $this->items[$this->position];
 }
 public function key() {
  return $this->position;
 }
 public function valid() {
  return isset($this->items[$this->position]);
 }
 public function rewind() {
  $this->position = 0;
 }
 public function next(){
  ++$this->position;
 }
}

$items = new SomeItems();
$items->add('One');
$items->add('Two');
$twig->display('page.twig', ['items'=>$items]);

На странице page.twig используем обычную конструкцию:

{% for item in items %}
 {{ item }}
{% endfor %}
В результате на странице выведены слова "One" и "Two".

2013-05-15

IntelliJ Idea + Solarized Color Schemes

Стал пользоваться IntelliJ Idea для всех проектов. Совершенно невероятно продуманная IDE, но речь не об этом. Захотелось сразу же прикрутить туда популярные цветовые схемы Solarized, к которым я уже привык. Делается это несложно. А именно:
cd ~/.IntelliJIdea12/config/colors/
wget https://raw.github.com/altercation/solarized/master/intellij-colors-solarized/Solarized%20Dark.xml
wget https://raw.github.com/altercation/solarized/master/intellij-colors-solarized/Solarized%20Light.xml
Заускаем Idea, в настройках находим список цветовых схем, а в них - Solarized Dark и Light.