Как скачать документ из АИС ЦГАСО

АИС ЦГАСО (104.73КиБ)

Изучаю тут самарский электронный архив, который сделан в «Эларе». Насколько я понял, продукт называется АИС ЦГАСО. Убиваю сразу двух зайцев — разбираюсь как всё работает и пытаюсь найти нужные мне документы по родственникам.

Ребята из «Элара» молодцы, делают очень нужное дело — оцифровывают бумажные архивы, это невероятный труд, но, к сожалению, интерфейс просмотра документов оставляет желать лучшего, он мне сжёг массу нервов. Решил просто выкачать нужные мне документы на компьютер и дело с концом. Написал специальную программу для скачивания документов из АИС ЦГАСО, на Гугл Гоу. Получилось довольно компактно.

Основная фишка — паралельное скачивание документов в несколько потоков. Не уверен, что это действительно работает (я не до конца понимаю как Гоу переключает свои горутины), но в теории должно. Добавлено: «полевые испытания» подтвердили, что документы действительно скачиваются параллельно. Удалось сделать крайне просто:

ch := make(chan byte, N)

for i, id := range documents {
    ch <- 1

    go func(id string, index int) {
        name := padZero5(strconv.Itoa(index)) + ".jpg"
        copyUrlToFile(strings.Replace(url, `%id`, id, 1), *dir + "/" + name)

        <-ch
    }(id, i)
}

Первой строкой в коде создаётся канал заданной размерности. С ним будут работать горутины (это такие легковесные потоки Гоу). В него можно положить только N значений, после чего следующая операция записи будет ждать его освобождения. С помещением в канал каждого нового значения, запускается горутина для скачивания одного листа документа, как только горутина отработала, она убирает из канала одно значение и цикл основного потока снова его кладёт и запускает новую горутину.

В итоге, одновременно, не будет запущено более N горутин.

Пользоваться программой просто (если кому-нибудь кроме меня это надо) — нужно в браузере (я в «Хроме» пробовал, выбирать при сохранении надо формат «веб-страница полностью») перейти на чтение документа (на снимке экрана иконка книжки рядом с каждым документом), когда загрузится первая страница документа, сохранить текущий документ браузера на диск (Ctrl+S в Винде, ⌘+S на «Маке») и скормить его программе в командной строке:

go run cgodownloader.go скачанный-файл.html

Программа обработает документ, покажет сколько страниц найдено и начнёт их скачивать в виде больших джпегов в ту же папку, показывая их имена. У меня на большом документе (около 1,5 тысяч страниц) заняло прилично времени — час с лишним.

Запуск программы (6.56КиБ)

Зато теперь просматривать удобно.

54 комментария

В интернете есть всё: котики, совушки и видео с регистраторов

Часто натыкаюсь на фразу, что в интернете собрана вся информация, доступная человечеству. Совершенно не согласен.

Странно, что эту фразу иногда повторяют и умные люди. Не иначе под влиянием эмоций. Если чуть-чуть уйти от мейнстрима, оказывается, что информации в интернете либо очень мало, либо нет вообще. Я с этим часто сталкиваюсь, потому что часто интересуюсь вещами, которые мало кому интересны.

Возможно впечатление информационного изобилия складывается из ощущения объёма всякой всячины, которой забит интернет. По моему мнению, бо́льшая часть интернета — это мусор, перепосты и бессмыслица.

У меня есть ещё и другая теория.

Как называлось село Дубовка Бавлинского района в момент основания? Как работать с Bluetooth из Пайтона на «Маке»? Где взять карту хоть какого-нибудь кладбища на территории России? Где посмотреть что входит в состав «Кока-Колы»? Где в базе документооборота «Практика» лежит поле «Исходящая дата регистрации»?

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

Так вот, другая моя теория в том, что мы привыкли в уме отфильтровывать вопросы, ответы на которые мы вряд ли найдём в интернете. Экономный ум даже не пытается подсказать нам залезть в «Гугл», потому что знает — усилия по поиску не оправдают найденного.

Мне же приходится учиться отключать эту логику, у меня есть масса вопросов (часто это касается моего хобби — составления своей родословной), где важны любые крупицы из любых источников. Отключая эту логику экономии усилий, я не отказываюсь задавать эти вопросы интернету и понимаю, что в интернете, по факту, данных очень мало. Больше ответов содержат бумажные источники и совокупный опыт специалистов, нигде не описанный (последнее, кстати — определяющая причина по которой я посещаю конференции).

17 комментариев

__defineGetter__ в массивах в JavaScript

Метод __defineGetter__ предназначался в ДжаваСкрипте когда-то для того, чтобы назначить свойству объекта геттер, сейчас он объявлен устаревшим, тем не менее, широко поддерживается — у меня на компьютере с ним работают Сафари, Хром, Фаэрфокс и «Опера».

Я тут подумал — можно ли как-то перехватить чтение не просто свойства, а элемента массива, ведь в ДжаваСкрипте широко рекламируется эквивалентность obj[’name’] и obj.name. Провёл эксперимент, оказалось — можно, в перечисленных мною браузерах получается странный эффект:

Array.prototype.__defineGetter__('0', function() {return 1});

var v = [];
alert(v); // выводит пустой массив
alert(v[0]); // выведет единицу

Такой код из разряда «happy debugging, bitch», ломает голову — массив пустой, но нулевой элемент не пуст.

Большие возможности для внедрения, кстати, в приватный код, который спрятан за замыканием — можно ведь и сеттер так же определить и считывать состояния каких-нибудь внутренних массивов. То же и с объектом Object и другими базовыми объектами.

11 комментариев

Как заставить wget игнорировать robots.txt

Я частенько пользуюсь утилитой wget, чтобы скачивать сайты, но по-умолчанию, она реагирует на robots.txt — по этому специальному урлу многие файлы размещают информацию для работов, wget тоже воспринимает эти инструкции на свой счёт.

Например, сайт может запретить роботам ходить по своим страницам, тогда wget откажется скачивать такой сайт. Чтобы попросить его наплевать на эти инструкции, нужно запустить его со следующим параметром:

wget -e robots=off url-который-надо-скачать

6 комментариев

Миронов Фёдор Тимофеевич

Одним из плюсов изучения своих родственников в том, что узнаёшь их с незнакомой ранее стороны.

Мой двоюродный дед или «великий дядя», как это раньше называлось, Фёдор Тимофеевич, 1925 года рождения, дядя Федя, как я его звал в детстве.

Часто навещал нас в моём детстве, сам он жил в Житомере, куда его занесла военная стезя (после войны он работал военным прокурором). Именно он привил мне любовь к лесу, мы с ним и с собакой Рексом часто гуляли в лесах вокруг его родной деревни. Его уже девять лет как нет, он дожил почти до 80, но старым, именно старым, немощным, я его и не помню, с первого взгляда было видно, что это человек военной выправки, несгибаемый, волевой.

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

Дядя Федя (128.66КиБ)

Вот только этот снимок, с наградами, я вчера увидел впервые, по крайней мере не припомню, чтобы видел его раньше. Мне прислали его из Житомира, дочь Фёдора Тимофеевича разбирала фотоальбом, прислала некоторые снимки. Я и знать не знал, что у дяди Феди столько наград! Он никогда ничего такого не рассказывал, а если кто-то при мне это и упоминал вскользь, то в памяти не отложилось.

Понятно, что бо́льшая часть, наверняка юбиленые, но слева явно видны два (!) Ордена Красной Звезды, остальные награды я различить не могу, не специалист и бликует сильно. В интернете есть открытая база «Подвиг народа», где можно посмотреть наградные листы за ордена и медали «За отвагу» и «За боевые заслуги» (правда, наградной листок одного из моих дедов, награждённых медалью «За отвагу», там не нашёлся).

Можно почитать за что дядя Федя получил эти ордена.

Первую награду старший сержант Фёдор Тимофеевич получил 22 октября 1944 года. В наступательных боях 5—7 ноября 1944 года в районе деревни Напюрки Бутне (Napiórki Butne) Ружанского повета Варшавского Воеводства проявил исключительное мужество и отвагу: противник, пытаясь вернуть потерянные рубежи, восемь раз бросался в контратаку, мой двоюродный дед мужественно отбил все контратаки и, в ходе этих боёв, из личного оружия уничножил шесть немецких солдат.

Первая награда (83.81КиБ)

Вторую награду дядя Федя получил седьмого февраля 1945 года, за то что в боевых действиях по уничтожению окружённой групировки противника в Восточной Пруссии 28-30 января 1945 года, не считаясь с опасностью для жизни, под сильным огнём противника исправлял повреждения на линии КП 29 Стрелкового корпуса с КП 73 стрелковой дивизии, сделав за короткий срок десять сростков, тем самым добился устойчивой связи:

Вторая награда (67.48КиБ)

И небольшая история, рассказанная уже его внуком: «ещё его однажды собака спасла, он с фронта в тыл раненый полз, автомат мешал сильно, но оружие бросать нельзя, так он, когда вообще было невмоготу, затвор вытащил и с собой его тащил, его нашёл медицинский пёс, дал аптечку, позвал помощь и дотащил до людей».

Дед минимум был трижды ранен — 14 апреля 1943 года, 19 сентября 1943 года и 4 октября 1944 года, видимо это был один из этих случаев.

10 комментариев

30 банковских дней-2

Жена попросила во вчерашнюю программу ряд улучшений внести и пожаловалась, что она на одном из компьютеров на работе запускается медленно. Ну, я решил переписать её на Гоу, раз такое дело, может быстрее стартовать будет. Кроме того, мне всегда интересно посмотреть как одна и та же программа выглядит на разных языках программирования.

package main

import (
    "encoding/json"
    "os"
    s "strconv"
    t "time"
    "net/http"
    "io/ioutil"
    "fmt"
    r "regexp"
    "bufio"
    "strings"
    fp "path/filepath"
)

type date struct {
    D byte
    M byte
    Y int
}

func CreateDate(d, m string, y int) date {
    day, _   := s.Atoi(d)
    month, _ := s.Atoi(m)

    return date{D:byte(day), M:byte(month), Y:y}
}

func (d date) FindIn(list []date) bool {
    for _, cur := range list {
        if d.D == cur.D && d.M == cur.M && (d.Y == cur.Y || cur.Y == 0) {
            return true
        }
    } 

    return false
}

func (d date) ToTime() t.Time {
    return t.Date(d.Y, t.Month(d.M), int(d.D), 0, 0, 0, 0, t.UTC)
}

func (d date) IsWeekEnd() bool {
    dw := string(d.ToTime().Weekday())

    return dw == "Saturday" || dw == "Sunday"
}


func (d date) Add(delta string) date {
    dur, _ := t.ParseDuration(delta)
    t := d.ToTime().Add(dur)

    return date{D:byte(t.Day()), M:byte(t.Month()), Y:t.Year()}
}

func (d date) String() string {
    return fmt.Sprintf("%02d.%02d.%04d", d.D, d.M, d.Y)
}

func loadCache(name string) (holidays []date) {
    f, err := os.OpenFile(name, os.O_RDONLY, 0666)

    if err != nil {
        return nil
    }

    defer f.Close()

    if err := json.NewDecoder(f).Decode(&holidays); err != nil {
        return nil
    }

    return
}

func saveCache(name string, holidays []date) bool {
    f, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)

    if err != nil {
        return false
    }

    defer f.Close()

    if err := json.NewEncoder(f).Encode(&holidays); err != nil {
        return false
    }

    return true
}

func getCurrentCalend() []byte {
    if resp, err := http.Get("http://www.calend.ru/work/"); err == nil {
        defer resp.Body.Close()

        if body, err := ioutil.ReadAll(resp.Body); err == nil {
            return body
        }
    }

    return nil
}

func getCurrentHolidays() (dates []date) {
    table, _ := r.Compile(`(?s)<table\s.+?time_of_death(.+)</table>`)
    chunk, _ := r.Compile(`(?s)<td\s+class="\S+\s+col5"\s+day="(\d+)"\s+month="(\d+)"`)

    dates = []date{}

    year := t.Now().Year()

    for _, value := range chunk.FindAllStringSubmatch(string(table.Find(getCurrentCalend())), -1) {
        dates = append(dates, CreateDate(value[1], value[2], year))
    }

    return
}

func ReadUserInput(message string) string {
    fmt.Print(message)

    input, _ := bufio.NewReader(os.Stdin).ReadString('\n')
    return input
}

func main() {
    var currentholidays []date

    year := t.Now().Year()
    cachename := s.Itoa(year) + ".json"

    // если кеш существует
    if _, e := os.Stat(cachename); e == nil {
        currentholidays = loadCache(cachename)
    } else {
        currentholidays = getCurrentHolidays()
        saveCache(cachename, currentholidays)
    }

    // загружаем другие кеши
    caches, _ := fp.Glob("*.json")
    for _, name := range caches {
        if name != cachename {
            currentholidays = append(currentholidays, loadCache(name)...)
        }
    }

    // опрашиваем пользователя
    mask, _  := r.Compile(`^(?m)(\d+)\D+(\d+)`)

    for {
        var userdate date

        for {
            d := mask.FindStringSubmatch(ReadUserInput("Enter date (dd.mm): "))
            if len(d) > 0 {
                userdate = CreateDate(d[1], d[2], year)
                break
            }
        }

        var period int

        for {
            period, _ = s.Atoi(strings.TrimRight(ReadUserInput("Enter period: "), "\r\n"))

            if period > 0 {
                break
            }
        }

        for ; period > 0; period-- {
            for {
                userdate = userdate.Add("24h")

                if !userdate.FindIn(currentholidays) && !userdate.IsWeekEnd() {
                    break
                }
            }
        }


        fmt.Printf("Result: %s\n\n", userdate)
    }
}

Меня поразил размер скомпилированной программы. Вот эта мелочь под «Маком» занимает 3,9Мб, под «Виндой» — 3,7! Жена попросила убрать гуишное окошко, поэтому я сделал программу полностью консольной. Два разочарования: в регулярных выражениях под Виндой неверно определяется конец строки (не учитывается «\r», судя по всему) и второе — в Гоу нет ничего, чтобы работать с однобайтными кодировками, а в консоли Винды до сих пор CP866. Пришлось выводить всё по-английски, писать конвертирующую функцию мне лень.

Объём увеличился, во-первых, из-за улучшений, во-вторых, мне хотелось хранить файлы кешей в каком-нибудь более-менее читаемом формате, чтобы вручную добавить в кеш татарстанские праздники, так что часть объёма (класс «date и методы работы с ним) как раз для этого.

13 комментариев

Дискурс Пелевин

Прочитал новую книгу Пелевина, болею же, что ещё делать?

Краткое содержание: дискурс, дискурс, дискурс, дискурс, дискурс, дискурс, гламур, гламур, дискурс, дискурс, баблос. Концовка подкачала, да, мало дискурса.

19 комментариев

Кот изучает мир людей

Е́жи (это наш кот) исследует помойное ведро. Он видит, что мы туда складываем какие-то штуки, но логику, по которой в ведро попадают именно эти штуки, он не может понять. Я не знаю как объяснить коту концепцию «мусора». Поэтому кот ставит эксперименты — носит и кладёт в ведро единственное, что у него есть — собственные игрушки. Если не успеть отобрать, то положит в ведро и сядет рядом, смотрит какая будет реакция.

Пытается выкинуть всё подряд — от сделанных из фольги и гороха погремушек, до покупных, достаточно дорогих. Судя по тому, что его любимая поющая электронная мышь куда-то пропала, кот её выкинул, не уследили.

Научные эксперименты это, конечно, хорошо, но накладно.

13 комментариев

30 банковских дней

Делал жене программу, чтобы отсчитывать от введёной даты 30 банковских дней в текущем году, может пригодится кому (в запускаемый файл преобразовал при помощи PyInstaller, получается один файл, очень удобно). При первом запуске программа скачивает календарь с сайта Calend.Ru и сохраняет рядом, потом берёт из него выходные и праздничные дни.

# coding: utf-8
import re
import httplib
import pickle
import ctypes
from datetime import date, datetime, timedelta

MB_OKCANCEL = 1
MB_SYSTEMMODAL = 4096
IDOK = 1
IDCANCEL = 2

def getCalend():
    h = httplib.HTTPConnection('www.calend.ru')
    h.request('GET', '/work/')
    return h.getresponse().read()

def getHolidays():
    table = re.findall(r'<table\s.+?time_of_death(.+)</table>', getCalend(), re.DOTALL)[0]
    return re.findall(r'<td\s+class="\S+\s+col5"\s+day="(\d+)"\s+month="(\d+)"', table, re.DOTALL)

def readHolidays():
    year = str(date.today().year)
    try:
        with open(year + '.cache', 'r') as f:
            holidays = pickle.load(f)
    except IOError:
        with open(year + '.cache', 'w') as f:
            holidays = tuple(getHolidays())
            pickle.dump(holidays, f)

    return [datetime(day=int(d[0]), month=int(d[1]), year=int(year)) for d in holidays]

def getStartDate():
    while 1:
        input = re.split(r'\D', raw_input("Enter start date (dd.mm): "))
        try:
            input = [int(x) for x in input]
            if len(input) == 2:
                break
        except ValueError:
            pass

    return (date.today().year, input[1], input[0])

delta = timedelta(days = 1)

holidays = readHolidays()
msgbox = ctypes.windll.user32.MessageBoxW

while 1:
    try:
        date = datetime(*getStartDate())

        for i in xrange(0, 30):
            while 1:
                date += delta

                if date not in holidays: break

    if msgbox(
            0,
            u'Получилась следующая дата: %02d.%02d.%04d' % (date.day, date.month, date.year),
            u'Ответ',
            MB_OKCANCEL | MB_SYSTEMMODAL
        ) == IDCANCEL:
        raise StopIteration
    except (KeyboardInterrupt, StopIteration):
        break

Программу написал быстро, а сложнее всего было её отправить — ГМэйл упорно не принимает запускаемые файлы, даже в архивах.

15 комментариев

С первым апреля!

Первоапрельский сайт (41.26КиБ)

Ну, первое апреля кончается, поэтому я привёл сайт к исходному виду. Если кто не застал, то сайт у меня сегодня выглядел как на скриншоте сверху — я поменял фотку и вступительный текст, пустил псевдотатарский орнамент справа и «перевёл» весь сайт на татарский (весь, кроме пояснительного поста).

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

После чего я написал пару функций, через которые пропускался весь контент моего сайта, а они заменяли русские слова на татарские слова той же длины по несложному алгоритму. Описывать не буду, лучше процитирую, думаю, там всё понятно:

function RuTatHelper($m) {
    static $dict = null;
    
    if ($dict === null) {
        $dict = unserialize(file_get_contents("compress.zlib://ru-tat.txt.gz"));
    }

    $len = mb_strlen($m[0], 'utf-8');
    if (isset($dict[$len])) {
        $n = sprintf('%u', crc32($m[0])) % count($dict[$len]);

        $word = $dict[$len][$n];

        if (preg_match('/^\p{Lu}/u', $m[0])) {
            $word = mb_strtoupper(mb_substr($word, 0, 1, 'utf-8'), 'utf-8') . mb_substr($word, 1, $len - 1, 'utf-8');
        }

        return $word;
    } else {
        return $m[0];
    }
}

function RuTat($text) {
    return preg_replace_callback('/\p{Cyrillic}+/u', 'RuTatHelper', $text);
}

С татарскими словами просочились и русские (в татарской речи очень много русских слов), особенно забавно было, что «Поиск» у меня превратился в «Путин». Не знаю, успели ли повеселиться татары, там настоящая тарабарщина написана была, например, вместо «блог» слово «призрак» по-татарски.

14 комментариев

Родная речь

Примерно полтора года назад я переехал из Москвы в Татарстан, в Казань. Всё это время я старательно изучал татарский язык, а чтобы изучение происходило более успешно, я много читал и переводил с татарского и обратно.

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

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

Дополнение: первое апреля кончается, выключаю шутку, попозже напишу пост о ней, чтобы осталась на память. А пока пошёл лечиться — я острый бронхит заработал.

36 комментариев

Лошадиная сила

Расчёты Уатта относились к мощности лошади, усреднённой за большое время. Кратковременно лошадь может развивать мощность около 1000 кгс·м/с, что соответствует 9,8 кВт или 33 475 BTU/ч (котловая лошадиная сила). По другим данным — до 15 л. с. в пике.

Я, конечно, понимал, что «лошадиная сила» — это какое-то среднее значение, но что лошадь в некоторые моменты может выдать 15 лошадиных сил — не ожидал.

5 комментариев

Число π в Библии

Оказывается, в Библии есть упоминание числа Пи. Не напрямую, конечно, но вычислить его можно. В третьей книге Царств, 7:23 написано:

И сотвори море лiяно десять лакотъ от края до края его, кругло окрестъ его: пять лакотъ высота его, и объятiе его тридесять лактей окружаше е окрестъ.

Я специально привёл церковнославянский перевод, потому что синодальный для меня менее понятный.

Давайте вспомним что такое число Пи. В этом нам поможет замечательная картинка из «Википедии»:

Число Пи (116.43КиБ)

Если взять окружность диаметром в единицу, то длина этой окружности и будет числом Пи. Соответственно, если взять окружность диаметром в десять локтей, то длина окружности должна быть 10×π.

Таким образом, чтобы найти библейское число Пи надо поделить длину окружности (тридцать локтей) на диаметр (десять локтей).

Отсюда πбиблеское = 3.

Погрешность довольно существенная, надо сказать. Пи ≈ 3,1415926535897932384626433832795…, получается, что в длине окружности «море лiяно» потеряло почти полтора локтя, то есть примерно 70 сантиметров.

13 комментариев

Октябрьский октябрь

У Лебедева в «Идиотеке» сегодня ижевский дорожный указатель «Октябрьский октябрь». Сама ситуация мне напоминает ставшей уже расхожей шутку «у программиста — отлаживать, у лингвиста — откладывать, причём программист понимает, в чём здесь шутка, а лингвист — нет».

Я был в Ижевске и хорошо помню, что Ижевск — столица Удмуртии. А это значит, что у них на территории распространён не только русский, но и удмуртский язык. Вряд ли ошибусь, если предположу, что там два государственных языка — русский и удмуртский (как у нас в Татарстане русский и татарский), следовательное многое дублируется на двух языках.

Когда я посмотрел на этот указатель, я сразу понял в чём дело, только подумал, что в подписи Татарстан будет указан. Это обычная ситуация с дорожными указателями в республиках, где больше одного государственного языка. На указателях пишут два названия — по-русски и на втором языке. «Октябрьский» — русское название населённого пункта, «Октябрь» — удмуртское.

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

6 комментариев

Какие графические форматы поддерживает ваш браузер?

Скриншоты браузеров Opera, Chrome, IE, Safari, Firefox и IE на Nokia Lumia 920: список поддерживаемых форматов изображений (JPEG, PNG, GIF и др.) с пометкой «Done».
Форматы, поддерживаемые браузерами

Я тут скрипт накидал, который проверяет какие графические форматы поддерживает ваш браузер. Проверяется JPEG, GIF, PNG, XMB, WebP, BMP, SVG, JPEG XR, TIFF, PDF, EMF, WMF, WBMP (Wireless BMP), JPEG-2000, ICO, APNG и MNG.

Тестируется поддержка в теге IMG.

Любопытно, что «Сафари» до сих пор поддерживает JPEG-2000, а «Опера» — WBMP (как единственный десктопный браузер, поддерживающий WAP, где WBMP и применяется).

Дополнение: оказывается, SVG в моем тесте был не до конца верный (я его просто сконвертировал из гифа 1×1 какой-то программой), так что скриншоты теста в браузерах верны не до конца, «Хром» и «Сафари» (т. е. браузеры на вебките) не поняли мой SVG.

19 комментариев

Александра Никаноровна Стрелкова

Дубовка (91.58КиБ)

Тут случилось небольшое чудо.

Сначала предыстория. В 1999 году у меня умерла прабабушка, Евдокия Никаноровна Стрелкова, несколько месяцев до 97 лет не дожила. В детстве мне одномоментно стало интересно поисследовать своё дерево и я расспросил всех бабушек и её в том числе, о тех предках, кого они помнили. А когда два года назад я заинтересовался деревом более серьёзно, то перенёс это всё в электронный вид. Некоторое время назад я показывал это дерево своей двоюродной бабушке, её дочери и маме, которая приходится ей внучкой и оказалось, что прабабушка мне назвала не маму, а мачеху. Как звали маму она то ли не помнила, то ли не посчитала нужным сказать. Т. е. как звали мою родную прапрабабушку с этой стороны я не знал.

Я заказал повторные свидетельства о смерти прабабушки и её папы и выяснил, что родились они в деревне Мирная Дубовка (ныне — Дубовка Бугульминского района), я как-то писал об этом.

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

А сегодня работники Национального Архива Республики Татарстан нашли запись о рождении прабабушки в архивах села Рыково, оно же Рычково (на картах зелёная стрелка), сейчас носит название Ключёвка. В записи о рождении записана её мама — Александра Никоноровна. Чудо в том, что работники Архива вообще посмотрели в бумаги по этому селу, вот что значит люди хорошо делают свою работу! Что приятно, по этому селу есть масса записей, мой сканер их нашёл. Почему прапрадед повёз дочку крестить не в ближайшее село непонятно, но пара версий у меня есть.

Первая, самая вероятная — в этом селе жили какие-то родственники, думаю со стороны матери. Версия подтверждается тем, что в крёстные взяли уроженку того же села, а в крёсные, как правило, брали близких родственников (например, двоюродных).

Вторая версия — Евдокия Никаноровна крестилась 15 марта (по новому стилю), сегодня 27 марта, а за окном снег и слякоть. Может быть в Потапову Тумбалу просто было не проехать, а в Рыково дорога была более-менее.

Крестили, наверное, в храме Петра и Павла (вероятный год постройки — 1809), который сейчас в полуразрушенном состоянии. Само село Рыково основано купцом Рыковом в 1808 году, который переехал в те места из Вятки, в селе было около трёхсот дворов, занимались там выделкой овчин, земледелием, разведением скота, леплей горшков, красили, сапожничали. До 1860 года жители относились к категории удельных крестьян. После революции село было переименовано в Пушкино, но название не прижилось: к Пушкину оно отношения не имело, в 20-30-х годах переименовали в Ключёвку, так как вокруг много ключей.

Я специально нашёл в социальных сетях уроженку этого села, чтобы проверить как оно в реальности называется — Ключёвка или Клю́чевка. Оказалось с буквой «ё». Почему её не пишут на карте с настоящим названием— загадка.

И небольшая историческая справка по Дубовке, родине моей прабабушки. Деревня основана в первой половине 19-го века, первоначально называлась Мирная Дубовка. До 1860-х годов крестьяне относились к категории государственных крестьян, занимались земледелием, разведением скота. В источниках 1940-50 годов деревня фигурирует как М. Дубовка, вероятно своё прилагательное потеряло позже. Число жителей в 1859 году — 145, в 1926 — 369, на 2010-й год — 11 жителей (русские и чуваши). С 2005 года входит в Потапово-Тумбралинское сельское поселение. Родина Героя Советского Союза Ивана Дмитриевича Зиновьева.

2 комментария

Чудны́ дела твои, PHP!

Может быть кто-то заметил, что у меня аватары в комментариях отваливались, я довольно долго не мог найти время и посмотреть что происходит, а вчера, вот, поправил. Дело оказалось в том, что мой хостер выставил директиву open_basedir и копирование аватара с интернета на файловую систему отвалилось.

Я делал это функцией copy, первом аргументом передавал УРЛ, вторым — путь на файловой системе. В логах, после изменения конфигурации, ПХП ругался, что «http:» — это неправильное начало для разрешённого пути. Удивительно, но стоило заменить copy// на её, фактически, эквивалент, как всё заработало:

if ($fin = fopen($url, 'rb') and $fout = fopen($file, 'wb')) {
    stream_copy_to_stream($fin, $fout);

    fclose($fout);
    fclose($fin);

    return true;
} else {
    return false;
}

Такое поведение больше похоже на баг, ПХП у меня не последний (5.3.21 сейчас), может поправили уже.

2 комментария

Отчаянные четырнадцатые

Сегодняшний путь (81.54КиБ)

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

Конечно, это отечественный автопром, комфорта на порядки меньше, чем на «Лексусе» (однажды, в такси «Везёт» ко мне на обычный вызов прислали «Лексус»), но свои плюсы, видите, есть. С другой стороны, четырнадцатые, обычно, не такие разбитые внутри и замотанные изолентой, как пятёрки-шестёрки. Разумный баланс.

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

♭♯♪♫♪♬♩

Удивительно (потому что меня это самого удивляет), но в последнее время я не слушаю музыку. Это как-то постепенно сошло на нет. Я помню времена, когда музыка была со мной всегда. В детстве я ставил и гонял целые кассеты кругами, пока домашние не начинали выть от повторения (спасибо музыкальному центру, который сам умел менять сторону кассеты). Мне тяжело было без музыки делать что угодно. Сейчас я её не слушаю.

Нет, бывает я нахожу какие-то новые песни и время от времени их ставлю, но так чтобы постоянно что-то играло — нет, мне мешает. Может быть, я просто хочу тишины? Помню, когда жил в Москве, её иногда нехватало до физического дискомфорта.

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

Когда я работал в «Яндексе», с моим одним другом мы часто разговаривали о роли ностальгии в восприятии музыки. Смысл в том, что музыка из детства, какая бы плохая она не была, всё равно человеку нравится, потому что возвращает его в детство, туда, куда многие стремятся. Я уже тогда понял, что начисто лишён этой ностальгии и песни той поры мне в голову не приходит слушать. Я иногда их пою, но то исполнение кажется мне пресным или примитивным.

Я подумал, может это и есть разгадка — я не сохраняю воспоминания, связанные с музыкой и слушаю песню, пока она мне не надоест, а потом выкидываю её навсегда? Ведь причин её слушать больше нет. Ну у меня есть свои любимчики, но часто я их слушать не могу, и их недостаточно, чтобы заполнить музыкой хотя бы какую-то заметную мою часть дня.

11 комментариев