AnjLab Blog

В этом разделе транслируются сообщения, которые участники команды размещают на своих персональных блогах.


Mechanize и кодировки

Для скинскрепинга мы используем mechanize. В mechainizе все просто замечательно, если парсить сайты, которые отдают контент в ASCII или UTF-8 кодировках. Но если, попробовать отпарсить сайт в windows-1251 кодировке, то mechanize/nokogiri лажают.

Например, если сделать запрос к kinopoisk.ru,  то получим непонятный результат:
Код:
1 2 3 4 5 6 7 8 9 10 11 12
#encoding: utf-8
require 'mechanize'

KINOPOISK_SEARCH_URL = 'http://kinopoisk.ru/index.php?kp_query='
query = 'терминатор'

agent = Mechanize.new
agent.get "#{KINOPOISK_SEARCH_URL}#{query.encode("windows-1251")}"

agent.page.search("td.news[width]").map do |section|
  puts section.at(".all").content
end
результат:
1 2 3 4 5 6 7
Òåðìèíàòîð
Òåðìèíàòîð: Äà ïðèä¸ò ñïàñèòåëü
Òåðìèíàòîð 2: Ñóäíûé äåíü
Òåðìèíàòîð 3: Âîññòàíèå ìàøèí
Òåðìèíàòîð: Áèòâà çà áóäóùåå (ñåðèàë)
Òåðìèíàòîð 2 - 3D

Решения в гугле найти не получилось, пробовали всяки манкипатчи, но как-то не очень красиво получалось :( 
В итоге выкрутились через Mechanize#post_connect_hooks:
Добавили MechanizeEncodingHook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#encoding: utf-8
require 'mechanize'

class MechanizeEncodingHook
  def call(params)
    return if params[:response].nil? || params[:response_body].nil?

    response = params[:response]
    content_type = response['Content-Type']

    internal_encoding = (Encoding::default_internal || "utf-8").to_s.downcase

    charset = 'windows-1251'
    return if content_type.nil? ||
        (charset = content_type[/charset=(?<charset>.*)/, "charset"]).nil?

    content_type = content_type.sub(/charset=.*/,
                                    "charset=#{internal_encoding}")
    response['Content-Type'] = content_type

    response_body = params[:response_body].
                    force_encoding(charset).
                    encode(internal_encoding)
    response_body[/#{charset}/] = internal_encoding
    params[:response_body] = response_body
  end
end

KINOPOISK_SEARCH_URL = "http://kinopoisk.ru/index.php?kp_query="
query = 'терминатор'

agent = Mechanize.new
agent.post_connect_hooks << MechanizeEncodingHook.new
agent.get "#{KINOPOISK_SEARCH_URL}#{query.encode("windows-1251")}"

agent.page.search("td.news[width]").map do |section|
  puts section.at(".all").content
end
И в итоге получаем нормальный результат:
1 2 3 4 5 6 7
Терминатор
Терминатор: Да придёт спаситель
Терминатор 2: Судный день
Терминатор 3: Восстание машин
Терминатор: Битва за будущее (сериал)
Терминатор 2 - 3D


Read more [Yury Korolev Blog]

AnjLab.FX Scheduler for ASP.NET

If you need simple yet easy configurable scheduler in your ASP.NET application, AnjLab.FX Scheduler might be your choise.

To use AnjLab.FX Scheduler you need to do 3 simple steps:


  1. Get the latest version of AnjLab.FX from github, make a build and add AnjLab.FX.dll as a reference to your project;

  2. Implement AnjLab.FX.Sys.ICommand interface on your task workers, like this:
    by Lorenzo Bettini
    http://www.lorenzobettini.it
    http://www.gnu.org/software/src-highlite -->
    public class HelloWorldTask : ICommand
    {
    private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(HelloWorldTask));

    public void Execute()
    {
    Log.Info("Hello World!");
    }
    }

  3. Configure tasks schedule in web.config. To do this you need to:

    1. add the following line to web.config/configuration/configSections:
      by Lorenzo Bettini
      http://www.lorenzobettini.it
      http://www.gnu.org/software/src-highlite -->
      <?xml version="1.0" encoding="UTF-8"?>
      <configuration>
      <configSections>
      ...
      <section name="triggers" type="AnjLab.FX.Tasks.Scheduling.SchedulerConfigSection, AnjLab.FX"/>
      ...

    2. define triggers section:
      by Lorenzo Bettini
      http://www.lorenzobettini.it
      http://www.gnu.org/software/src-highlite -->
      <configuration>
      ...
      <triggers>
      <!--
      <daily tag='restoreDB' timeOfDay='23:00'/>
      <weekly tag='backupDB' timeOfDay='01:30' weekDays='monday,friday'/>
      <hourly tag='delTempFiles' minutes='30'/>
      <interval tag='dumpLog' interval='00:05:00'/>
      <once tag='upgradeDB' dateTime='01/15/2007 23:00'/>
      <monthly tag='archiveDB' monthDay='29' timeOfDay='23:00'/>
      -->
      <interval tag='helloworld-task' interval='00:00:10'/>
      </triggers>
      ...
      </configuration>

      Here we defined named trigger "helloworld-task" to be triggered every 10 seconds.


  4. Map trigger names to your task workers and start up the scheduler.

    To map your task workers you create instance of KeyedFactory and register your tasks. We propose you do this in Global.asax Application_Start method:

    by Lorenzo Bettini
    http://www.lorenzobettini.it
    http://www.gnu.org/software/src-highlite -->
    protected void Application_Start(object sender, EventArgs e)
    {
    // Map trigger names to task workers

    var factory = new KeyedFactory<string, ICommand>();
    factory.RegisterType<HelloWorldTask>("helloworld-task");

    // Start up scheduler

    var scheduler = new Scheduler<ICommand>(factory);

    var triggers = (List<ITrigger>)ConfigurationManager.GetSection("triggers");

    scheduler.RegisterTriggers(triggers.ToArray());

    scheduler.Start();
    }


Thats it!

Resources:


P.S.
By the way, you can also use this API to schedule your tasks in Windows.Forms applications as well.

P.P.S.
AnjLab.FX is a framework we built during development of our projects. Its continue evolving and you can use it in your applications without any restrictions.

Read more [Dmitry Gusev Blog]

МОДИФИКАЦИЯ АЛГОРИТМА ТОРБЕНА ДЛЯ ПОИСКА МЕДИАНЫ В БОЛЬШОМ ОДНОМЕРНОМ МАССИВЕ

Выкладываю статью, как и обещал в предыдущем посте.

МОДИФИКАЦИЯ АЛГОРИТМА ТОРБЕНА ДЛЯ ПОИСКА МЕДИАНЫ В БОЛЬШОМ ОДНОМЕРНОМ МАССИВЕ
Гусев Д.И.
Владимирский государственный университет

Аннотация
В статье предлагается алгоритм поиска медианы, основанный на известном алгоритме Торбена. Особенностью обоих алгоритмов является то, что при поиске медианы они не требует изменения исходного массива и позволяют читать весь массив последовательно. Приводятся характеристики предлагаемого алгоритма, которые при определенных параметрах показывают производительность более 40% относительно алгоритма Торбена.

Скачать: Текст статьи (241 КБ)


Read more [Dmitry Gusev Blog]

C#: RefreshSection method of ConfigurationManager is not refreshing sections under debug mode

RefreshSection method of ConfigurationManager is not refreshing sections when you run application at Visual Studio. Try to run application without VS.


Read more [Nikolay Zhebrun Blog]

XML feed