Sunday, October 14, 2007

Питерские впечатления IV

День четвертый: Пушкин


Как и было запланировано, посещение Питерских достопримечательностей перемежалось загородными поездками, и на четвертый день нашего пребывания в северной столице мы отправились в Пушкин.

Пушкин, он же Царское Село, он же Детское село -- небольшой городок южнее Санкт-Петербурга. Как видно, за время своего существования сменил много названий, являлся летней резиденцией нескольких поколений императорской семьи.

Добирались мы до Пушкина железной дорогой со станции Купчино. Стоит отметить несколько непривычную для нас особенность местной пригородной системы поездов: проход на платформу сугубо по билетам, которые следует поднести штрих-кодом к считывающему устройству турникетов, иначе вас не пропустят. Кстати, еще раз о названии города -- билеты мы брали до станции "Пушкин", а когда подъезжали к нужной нам остановке было объявлено "Детское село". Видимо местные власти до сих пор не могут договориться, или же переименовали его обратно в "Пушкин" относительно недавно, и еще не успели обновить объявления остановок в поездах. В любом случае -- будьте внимательны, чтобы не пропустить свою остановку. ;-)

По дороге до Пушкина по левую сторону можно наблюдать "кладбище паровозов" -- довольно интересное зрелище: паровозы разных времен и конструкций ржавеют под открытым небом бессильные перед стихией.

При входе в парк

Выйдя на станции "Детское село" и испросив у местных приветливых бабулек дорогу мы направились к Екатерининскому дворцу -- истинной цели нашего "паломничества". Идти оказалось сравнительно недалеко, около 1км, и вскоре мы подошли к Екатерининскому парку. Перед дворцом выстроилась очередь на экскурсию и мы, заняв свое место, и выставив "часового" разбрелись по парку, условившись каждые 15 минут присылать сменщика. Следует отметить, что все утро моросил дождь.


Примерно через час ожидания очередь дошла до нас и мы вошли во дворец. Этот раз был одним из немногих, когда нам удалось заполучить своего экскурсовода, а не подслушивать у более организованных групп. Перед входом в помещения дворца нам выдали одноразовые пакеты голубого цвета для обуви -- чтобы не пачкать паркет. :-)


Сам дворец построен по проекту архитектора Растрелли в XVIII в. Анфилада богато украшенных залов -- его отличительная черта и "фирменный прием" Растрелли.


Сразу после войны дворец находился в плачевном состоянии -- убранство было разграблено, большинство залов выгорело, из подвалов буквально тоннами извлекали бомбы и снаряды, которыми фашисты заминировали здание. Все великолепие убранства и внешней отделки было воссоздано реставраторами
в течение второй половины XX века по немногим сохранившимся фрагментам и фотографиям. Объем и тяжесть проделанной работы просто поражает.


Знаменитая Янтарная комната также была воссоздана, т.к. оригинал был вывезен захватчиками во время войны в Германию и до настоящего времени так и не обнаружен. Фотографировать в Янтарной комнате запрещено, но желающие могут приобрести фотоальбом в лавке на выходе из дворца.

В парке

Помимо собственно дворца, в Екатерининском парке находятся несколько архитектурных сооружений вроде беседок, водных каскадов, а также статуи. В большинстве своем они сейчас находятся не в лучшем состоянии, но почти все реставрируется, что не может не радовать.


Совсем рядом с Екатерининским дворцом и парком находится Александровский дворец. В настоящее время в здании размещается одно из учреждений какого-то силового ведомства, а сам дворец и парк пришли в совершенное запущение... говорят, что когда дворец вернут государству, в нем восстановят музей и приведут здание и парк в порядок. Что ж -- хочется верить.

При входе в парк установлен не до конца понятный простым смертным запрещающий знак:

Внимание на первый рисунок ;-)

В 10 минутах езды от Пушкина находится еще одна императорская резиденция -- город Павловск, получивший свое имя от Павла I, жившего здесь до своего восшествия на престол, что случилось после кончины его матери императрицы Екатерины II.

Павел I

Парк перед дворцом в Павловске значительно обширнее Пушкинского и его, пожалуй, можно даже назвать лесом (во всяком случае дальнюю от дворца часть). В этом "лесу" водятся в достаточном количестве белки и для увеселения посетителей даже продаются кедровые орешки, которыми следует этих белок угощать. То ли белки уже наелись за день, то ли у них не было настроения с нами общаться, но так или иначе орешки нам пришлось съесть самим.

Это не белки :-)

Поскольку в Павловск мы попали к вечеру, дворец уже был закрыт, и, поснимав местные красоты, мы отправились обратно в город. Выйдя на станции Купчино мы направились в ближайший супермаркет в надежде разжиться не слишком дорогими продуктами, что нам вполне удалось. По пути мы заметили памятник бравому солдату Швейку, правда неизвестно насколько "официальный". ;-)


Увидимся!

Saturday, October 13, 2007

Launch all of your torrents!

Hi,

Recently I've wrote a small program in Ruby to manage my torrents.

UPDATE: please use the link above for an updated version.

I use it this way:

$ find . -name \*.torrent | launchtorrents -

It can read a list of .torrent files from standard input (e.g. terminal) or use command line arguments for that.

Here is the complete program listing:
#!/usr/bin/ruby
#
# launchtorrents -- a tiny program to launch multiple BitTorrent
# sessions
#
# Copyright (C) 2007 Alex Shulgin
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior
# written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
$KCODE='utf-8'

$PROGNAME = File.basename($0)
if ARGV.empty?
STDERR.puts "usage: #$PROGNAME [options] [FILE]..."
STDERR.puts "options:"
STDERR.puts " - read file list from terminal"
exit 1
end

def fatal(msg)
STDERR.puts "#$PROGNAME: #{msg}"
exit 1
end

def warning(msg)
STDERR.puts "#$PROGNAME: #{msg}"
end

(ARGV[0] == '-' ? STDIN : ARGV).each do |torrent|
torrent = torrent.chomp

# parse torrent info: file set and sizes
dirname = "."
filename = nil
files = {}
multfiles = false
IO.popen("btshowmetainfo '#{torrent}'").each do |line|
case line
when /^directory name\.*: (.+)$/:
dirname = $1
when /^file name\.*: (.+)$/:
filename = $1
files[$1] = 0
when /^file size\.*: (\d+)/:
files[filename] = $1.to_i
when /^files\.*:/:
multfiles = true
when /^\s*(.+)\s+\((\d+)\)$/:
files[$1] = $2.to_i if multfiles
end
end
fatal "cannot query torrent file: #{torrent}" if files.empty?
# p dirname
# p files

# check sizes: leech if any file is unfinished or missing, else seed
begin
pwd = Dir.pwd
Dir.chdir(File.dirname(torrent))

cmd = "seed"
files.each do |file, size|
file = "#{dirname}/#{file}"
filesize = File.exist?(file) ? File.size(file) : 0
# p file
# p filesize
if filesize < size
cmd = "leech"
elsif filesize > size
warning "file size is greater than real size: #{file}"
throw
end
end

# puts "#{cmd} #{torrent}"
basename = File.basename(torrent)
system(cmd, basename) or warning "failed to #{cmd}: #{torrent}"
rescue
next
ensure
Dir.chdir(pwd)
end
end
As one can see, the program uses two auxiliary commands: leech and seed. These are the helpers I wrote for my convenience earlier; leech is used to start or continue torrent download, seed is used on finished torrents.

Here are the listings:

leech:
#!/bin/sh
for i in $@; do
sh -c "nohup btdownloadheadless '$i' &>/dev/null &";
done
seed:
#!/bin/sh
for i in $@; do
sh -c "nohup btdownloadheadless --check_hashes 0 '$i' &>/dev/null &";
done

The BitTorrent package in use is bittornado.
Listing coloring by GNU source-highlight.

See you. :-)

PS: something's wrong with blogspot editor, so I couldn't make all the indentation look quite right...