План 2019

На прощедшей в Азии выставке TechFest компания Microsoft продемонстрировала потрясную визуализацию того, как сейчас видится 2019 год. Короткая презентация, призванная привлечь посетителей к секции микрософта, была уже выложена на хабре.. Полные презентации, которые были показаны уже на выставке и которые более подробно расказывают о жизни человека в новом мире, можно, и даже нужно(!) смотреть под катом. И читайте надписи в видео!

Банковское обслуживание:

Розничная торговля

Производство:

Здравохранение

Источник - KZero

Метки: ,   Категории:AugmentedReality | trend | microsoft


Окупится ли?

Сегодня интернет обсасывает интервью с СЕО Твиттера и два главных вопроса - "Печему твиттер стал популярным?" и "Отобьет ли он инвестиции?". После просмотра я сделал для себя вывод, что ответ на первый вопрос - это скорость сообщений. Та скорость, которой не хватает почти всем web2.0 проектам. Что и говорить, проекты, включающие в себя все инварианты web3.0, будут работать в сегодняшнем понимании еще медленнее.

Ответ на второй вопрос так озвучен и не был. На хабре приводят интервью с соучредителем фонда, профинансировавшего Твиттер, в котором он уверяет всех, что способы монетизации есть, но озвучивать их пока рано. Я же уверен, что таких способов нет, либо они их еще не придумали. Но чтобы Вы стали говорить на их месте? Уж только не то, что потратили деньги, стали обладателем крупного популярного проекта, а теперь не знаете что с ним делать. "Конечно Вы знаете, но сказать пока не можете". До кризиса лучшим способом отбить деньги было для них продаться, как мы помним, Фейсбуку, но при нормальных условиях, а не за часть акций, как было предложено.

Bonus: Очень интересная программа для анонимности в сети - OperaTor. Если она работает так, как написано (передает травик от одного клиента к другому по принципу p2p, а так же автоматически использует набор анонимных проксей), то уже нет смысла администраторам на вашей работе закрывать Вам доступ к определенным сайтам - вы всеравно прорветесь.

Метки:   Категории:news


Блоги и Кризис

Сегодня, в "прощеное воскресенье" сам Артемий признался в блоге о сиськах и прочей фигне в том, что сосет пишет платные посты. Для тех, кто давно работает с рекламой в блогосфере, это не стало открытием. Давно известны следующие цифры, что за пост Лебедев кладет себе в карман 3000у.е., в то время как посредник - представитель рекламного агенства - продает это рекламодателю более чем за 5000у.е.

Также сегодня прошла 7я встреча стартаперов - видео тут. Мое мнение - красиво, занятно, но ничего перспективного.

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

Среди станддалонов в лидерах падения идет xeus.ru потерявший в яндексе более 500 пунктов. Примерно такой же результат у программиста с zhilinsky.ru и сеошника disdain.ru. Примечательно, что журнал coolidea.ru, пищуший интересные идеи для бизнеса и socvestnik.ru - социальные новости, упали на 350 и 250 позиций соответственно.
Среди ЖЖшников переставший писать Лукьяненко (doctor-livsy.livejournal.com) выдал экспоненциально 600 позиций вниз. Также по непонятным причинам http://katechkina.livejournal.com/ успела скатиться на 350 пунктов, напару с чьим-то тролем - http://users.livejournal.com/_nimfetka_girl_.
Среди Ярушников заметил только Долбоеба dolboeb66.ya.ru - скатившегося на 250 позиций, думаю, что и его основной блог скоро начнет заметно падать ввиду отсутствия должной активности.
Сподвижки в первой сотне яндекса приведены на картинке. Величина падения с начала года в четвертой колонке:

Метки:   Категории:Analytics | trend | news


PDF / DOC to TXT

При индексировании архива офисных файлов мне понадобилось извлекать текстовую информацию из различных файлов таких как DOC или PDF. Решение несложное, достаточно воспользоваться несколькими библиотеками. Для PDF - это PDFBox, портированный с Java на CSharp. Для DOC - это Microsoft.Office.Interop.Word.dll из набора OfficeAPI. Для удобства, необходимые библиотеки можно скачать одним архивов по ссылке

Под катом я приведу код, показывающего как с ними работать.
Начнем с PDF, подключим имена:
Copy Source | Copy HTML
using org.pdfbox.pdmodel;//PDF library
using org.pdfbox.util;
После этого документ можно преобразовать в текст 3мя строчками:
Copy Source | Copy HTML
PDDocument pdfFile = PDDocument.load(onefile);
PDFTextStripper stripper = new PDFTextStripper();
String innertext = stripper.getText(pdfFile);

Для DOC больше кода, поэтому я вынес все в отдельный класс, производя конвертирование как innertext = ConvertDoc.GetDocText(onefile);
Copy Source | Copy HTML
using Microsoft.Office.Interop.Word;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
 
/// <summary>
/// объект для операция с Вордовыми документами
/// </summary>    
public class ConvertDoc
{
    // Объект отвечающий за результат конвертации.
    // Ставим .txt - текстовый в досовской кодировке
    static ConvConfig tmpItem = new ConvConfig(".txt", WdSaveFormat.wdFormatDOSText);
 
    /// <summary>
    /// Получение текста из доковского файла
    /// </summary>
    /// <param name="file">Ссылка на документ</param>
    /// <returns>Текст документа</returns>
    public static String GetDocText(String inFileName)
    {
        String retText = String.Empty;
        //создаем объекты для дальнейшей передачи в вордовые функции
        object fileName = inFileName;
        object fileSaveName = Path.GetTempFileName() + tmpItem.itemExtension; //случайное уникальное имя + .txt;
        object vk_read_only = true;
        object vk_visible = false;
        object vk_true = true;
        object vk_false = false;
        object vk_dynamic = 2;
        object vk_saveformat = tmpItem.itemWord;
 
        object missing = Missing.Value;//все параметры, которые мы пропустим
        /////
        object vk_range = missing;
        object vk_to = missing;
        object vk_from = missing;
        /////
        // создаем класс для работы с вордом
        ApplicationClass vk_word_app = new ApplicationClass();
 
        Document aDoc = null;
        try
        {
            // вызываем скрытое открытие документа 
            aDoc = vk_word_app.Documents.Open(
                     ref fileName, ref missing,
                     ref vk_read_only, ref vk_false,
                     ref missing, ref missing,
                     ref missing, ref missing,
                     ref missing, ref missing,
                     ref missing, ref vk_visible,
                     ref missing, ref missing,
                     ref missing);
 
            //Сохраняем в файл в заданном формате
            aDoc.SaveAs(ref fileSaveName, ref vk_saveformat,
                 ref missing, ref missing, ref missing, ref missing,
                 ref missing, ref missing, ref missing, ref missing,
                 ref missing, ref missing, ref missing, ref missing,
                 ref missing, ref missing);
            //корректно закрывает все открытое
            if (aDoc != null)
            {
                aDoc.Close(ref vk_false, ref missing, ref missing);
            }
            //читаем из временного файла в досовской кодировке и удаляем его
            retText = File.ReadAllText(fileSaveName.ToString(), Encoding.GetEncoding(866));
            File.Delete(fileSaveName.ToString());
        }
        catch (Exception err)
        {
            Debug.WriteLine("Ошибка чтения файла: " + inFileName + " - " + err.Message);
        }
        finally
        {
            vk_word_app.Quit(ref vk_false, ref missing, ref missing);
        }
        return retText;
    }
}
 
/// <summary>
/// Настройки для конвертации
/// </summary>
public class ConvConfig
{
    //расширение
    public String itemExtension;
    //тип объекта на выдаче
    public Object itemWord;
 
    //The constructors
    public ConvConfig() { }
 
    public ConvConfig(String inExtension, Object inWordType)
    {
        // This allows us to set the properties 
        itemExtension = inExtension;
        itemWord = inWordType;
    }
}
 

Метки:   Категории:Csharp | Code


Back to blogging

Давно не писал, поэтому пробегусь кратко по основным техническим событиям интернета
  1. На днях почти полдня был недоступен Gmail. Примечательно, что это вызвало меньше паники в Рунете, чем недоступность ICQ в январе.
  2. Добавил виджет комментирования от FriendsConnect на проект s-c.me - все работает и мне нравится. А вот точно такойже код для ya.topbot.ru почему-то не пашет, придется еще подумать.
  3. Появились подробности Gazelle - нового браузера от Микрософта, который они планируют выпускать независимо от InternetExplorer'a. А также новый скрины от MicrosotftVisualStudio2010
  4. Из юмора рекомендую почитать темку про Китайскую социальную сеть, которая круче Facebook
  5. Сегодня вечером иду на секретное обсуждение "Плана Обамы" и "Плана Путина", если что умного узнаю, то поделюсь. Отмечу лишь, что я продал баксы, закупился йеной и жду обвала Европы =).
  6. 1го марта пройдет 7я встреча стартаперов от StartupPoint.ru . Пользы думаю будет мало, но сходить погулять не помешает.

Метки:   Категории:S-c.me | news | life


Социореклама

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

Но с другой стороны, зная специфику русского офисного планктона, да и по собственным чувствам, когда смотришь ролик, то про себя произносишь "Да", после каждого вопроса =). Получается примерно так: "Тебе нужны только деньги? - Ага, а все остальное куплю. Тебе плеваь на страну? - Ага, поэтому сбережения в валюте. Ты тупая скотина? - Ага, пойду напишу об этом в блоге."
Другой интересный пример - антиалкогольная реклама, что крутят по телевизору. Показывают кишки и говорят, что все кто пьет - скоро умрут. На это смотрящий отвечает Да я гавно, да я скоро сдохну, но что мне еще остается на зарплату учителя при такой инфляции? Лучше уж выпью и забуду, что я гавно.
Такое вот неправильное отношение к людям проявляется в России повсеместно. Подход "Ты гавно - иди работай!" изжил себя с падением монархии. Правильный подход капитализма: "Стань лучше - сделай то-то!". Для той же антиалкогольной компании это звучало бы так: "Хочешь здоровую семью, понимания на работе и хорошей жизни - откажись от выпивки!".


Метки:   Категории:news | life


1tv - пропаганда

На выходных имел возможность убить часть времи перед телевизором. Поразило, что в одной передаче ведущая очередного тупого шоу произнесла слово "Негр" и это не отфильтровали защитники толлерантности. Видимо даже на толлерантность деньги кончились.
Заценил еще новейший российский фильм "20 сигарет". Весь фильм - нарезка сцен, где герои курят в перемешку с короткими диалогами, а иногда на экране показывается компьютер с mail.ru. Герои не выпускают сигарет ни на крыше дома, ни в машине, ни в туалете, ни во время секса. Сплошная реклама нездорового образа жизни, несчитая mail.ru. С такой открытой пропогандой по основным каналам мне становится понятно, почему у нас 63% россиян заядлые курильщики.

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

Offtopic:
  1. Интересная инструкция по созданию сообществ на Твитере
  2. Добавил в профиле больше информации

Метки: , ,   Категории:news | life


Вопросы-ответы.Яндекс

Сегодня яндекс запустил сервис, работающий по принципу Гугл-Вопросов, только называющийся Яндекс.Ответы. Сервис стал 42м из серии небольших проектов "Яндекс.Нано".

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

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

Метки:   Категории:trend | news


S-c.me: Вставка кода на твиттер и хабр.

Раскажу Вам о проекте s-c.me, который расшифровывается как "source-code(for)me", и который я открыл в конце 2008 года и не рекламировал никому. Исполькозал лишь для своих потребностей и постов.

Сайт позволяет подсвечивать исходные тексты, как в виде html, так и в виде css. Основной упор сделан для Csharp, xml, php - как языки, на которых пишу сам.
Пример подсветки и публикации кода - http://s-c.me/3V

Из последних нововведений:
1) Короткие ссылки для вставки в твиттер
2) Оптимизация подсветки, чтобы не было подряд идущих одинаковых тэгов подсветки.
3) Добавлена подсветка для языка Python.
4) Автотэгирование по именам объектов.

Готов выслушать замечания и предложения.

PS: Недели 2 назад Adam Ostrow написал в Mashable про подобный проект, которому судя по whois было 2 дня и весь функционал которого, на тот момент, ограничивался возможностями бесплатной библиотеки GeSHi и громкого заголовка "для твиттера". Это меня разозлило и сподвигло на дальнейшую разработку.

Метки:   Категории:S-c.me | news


User Feedback

На днях задумался о целенаправленном сборе пользовательского фидбека (мнений, замечаний) с некоторых моих сайтов, которыми (на мое удивление) регулярно пользуюсь не только я. Для работы с пользователями сайта есть несколько решений

1) Размещение на сайте популярной на западе кнопки от http://uservoice.com/, у них есть как бесплатный, так и платный функционал. Однако для оставления комментариев посетителям пришлось бы региться у них на сайте, кроме того на сайте появился бы логотип от Uservoice, что не есть хорошо.

2) С другой стороны месяца 2 назад был в рунете стартап с аналогичным функционалом, правда сейчас я их найти не смог. Минус решения, как и первого, заключается в том, что посетителям сайта предлагается голосовать за видвинутые ими же предложения по улучшению сайта. То есть вас начнут мучить требованиями реализовать на сайте, что-то типа "летающего розового слона" (мне вот, до сих пор регулярно присылают требования поместить их запись в ТОП), который никому не нужен, но тупое большинство решило, что было бы прикольно. Конечно будут и полезные предложения, но они будут вам и так очевидны, а лишнего времени для их реализации у вас не появится, да и голосование за них - лишний функционал.

3) Более логичным кажется помещение на сайте виджета от F*Connect, где пользователи используют привычные им аккаунты и просто оставляют комментарии. Минус лишь в том, что не понятно, что лучше FacebookConnect или FriendConnect, каждый из которых частично ограничивает область используемых пользователями аккаунтов.

4) И буквально на днях прибежали туземцы появился http://comments.li.ru, позволяющий организовать комментирование к любой странице вашего сайта, если он работает на PHP, что также не подходит моим проектам на asp.net.

В заключение скажу, что я остановлюсь на 3), как только появится время.

Метки: ,   Категории:Analytics | trend


.Net - Контексный поиск с учетом русской и английской морфологии

Подведу итог моим экспериментам с библиотекой Lucene.Net, под катом немало кода.

Для чего это: Поиск документов по словам с учетом морфологических модификаций в большой базе документов
Программный язык: CSharp.
Потрачено времени: Двое суток
Использованные продукты: MSVS, Lucene.Net, Lemmanizer с дополнительным английским словарем.
Ограничения и лицензии: Apache2.0 для Lucene и 250y.e. за Lemmanizer или бесплатная демо до конца года.
Дополнительно: Немало полезного есть на CodeProject, а также пример простого поиска описывали в RSDN

Начну с результатов
1) Индекс на 1530 текстовых документов занял 40минут, и 1,4мегабайта на диске. Если отключить морфологию, то те же действия выполняются за 1 минуту.
2) Иллюстрация поиска, который выполняется почти моментально

Видно, что по слову authority и authorities найдено одинаковое число документов, при отключении морфологии их число разнится
Одинаковое число документов для Бандитко и Чичваркина вызвано тем, что в xml настройке для SynonymFilter я указал эти слова в качестве синонимов.


Итак, наша задача при написании контекстного поиска с учетом морфологии с использованием Lucene.Net сводиться к описанию класса по разбору текста и вставлению в него всех слов, которые как-то коррелируют с текущим. Я написал следующий класс
Copy Source | Copy HTML
  1. namespace Lucene.Net.Analysis.Morphology
  2. {
  3.     using System;
  4.     using System.Data;
  5.     using System.Configuration;
  6.     using System.Web;
  7.     using System.IO;
  8.     using System.Web.Security;
  9.     using System.Web.UI;
  10.     using System.Web.UI.WebControls;
  11.     using System.Web.UI.WebControls.WebParts;
  12.     using System.Web.UI.HtmlControls;
  13.     using Lucene.Net.Analysis.Standard;
  14.     using Lucene.Net.SynonymEngine;
  15.  
  16.     /// <summary>
  17.     /// Анализатор текста для Lucene.Net с использованием морфологического анализа и словаря синонимов
  18.     /// </summary>
  19.     public class MorphologyAnalyzer : Analyzer
  20.     {
  21.         public MorphologyAnalyzer(ISynonymEngine engine)
  22.         {
  23.             //запомнили откуда брать синонимы
  24.             SynonymEngine = engine;
  25.             isSearchQuery = false;
  26.             //грузим словари
  27.             Morph = new MorphENRU();
  28.         }
  29.  
  30.         private MorphENRU Morph;
  31.         private ISynonymEngine _SynonymEngine;
  32.         private Boolean isSearchQuery;
  33.  
  34.         /// <summary>
  35.         /// Объект для перечисления синонимов слова
  36.         /// </summary>
  37.         public ISynonymEngine SynonymEngine {
  38.             get {
  39.                 return _SynonymEngine;
  40.             }
  41.             private set
  42.             {
  43.                 _SynonymEngine = value;
  44.             }
  45.         }
  46.  
  47.         /// <summary>
  48.         /// Выключаем проверку синонимов
  49.         /// </summary>
  50.         /// <returns></returns>
  51.         public MorphologyAnalyzer SetQuerySynonym()
  52.         {
  53.             this.isSearchQuery = true;
  54.             return this;
  55.         }
  56.  
  57.         /// <summary>
  58.         /// Анализуем текст и возвращаем в виде нобора слов для помещения в индекс и подсчета частот
  59.         /// </summary>
  60.         /// <param name="fieldName">Имя индексируемого файла</param>
  61.         /// <param name="reader">Поток для чтнения файла</param>
  62.         /// <returns>TokenStream</returns>
  63.         public override TokenStream TokenStream(string fieldName, TextReader reader)
  64.         {
  65.             //создаем обход слов
  66.             TokenStream result = new StandardTokenizer(reader);
  67.  
  68.             //преобразуем исходную строчку
  69.             result = new StandardFilter(result); // выделение слов при помощи StandardTokenizer
  70.             result = new LowerCaseFilter(result);// Приведение к нижнему регистру
  71.  
  72.             // простой фильтр английских местоимений,
  73.             // русских, к сожалению нету
  74.             result = new StopFilter(result, StopAnalyzer.ENGLISH_STOP_WORDS);
  75.             result = new MorphFilter(result, Morph); // вставляем морфологическую модификацию
  76.             result = new SynonymFilter(result, SynonymEngine, this.isSearchQuery); // вставляем синонимы
  77.  
  78.             //возвращаем набор токенов для помещения в индекс
  79.             return result;
  80.         }
  81.     }
  82.  
  83. }

Видно, что кроме стандартных фильтров, я добавил MorphFilter - вставка морфологических модификаций и SynonymFilter - для вставки синонимов. Класс MorphENRU используется для работы со словарями морфологии на базе библиотеки Lemmanizer и идет ниже
Copy Source | Copy HTML
  1. namespace Lucene.Net.Analysis.Morphology
  2. {
  3.     using LEMMATIZERLib;//морфология
  4.     using System;
  5.     using System.Collections.Generic;
  6.     using System.Configuration;
  7.     using System.Data;
  8.     using System.Diagnostics;
  9.     using System.IO;
  10.     using System.Text;
  11.     using System.Text.RegularExpressions;
  12.     using System.Web;
  13.     using System.Web.Security;
  14.     using System.Web.UI;
  15.     using System.Web.UI.WebControls;
  16.     using System.Web.UI.WebControls.WebParts;
  17.     using System.Web.UI.HtmlControls;
  18.  
  19.     /// <summary>
  20.     /// Работа с морфологией для анг. и русского языка
  21.     /// </summary>
  22.     public class MorphENRU
  23.     {
  24.         /// <summary>
  25.         /// Регулярное выражение для определения английских слов
  26.         /// </summary>
  27.         private Regex rWordEn = new Regex(@"[a-z0-9]+", RegexOptions.Singleline | RegexOptions.Compiled
  28.             | RegexOptions.ExplicitCapture);
  29.  
  30.         /// <summary>Анализатор английских слов</summary>
  31.         private ILemmatizer Lemmatizer_en;
  32.  
  33.         /// <summary>
  34.         /// Анализатор русских слов
  35.         /// </summary>
  36.         private ILemmatizer Lemmatizer_ru;
  37.  
  38.  
  39.         public MorphENRU()
  40.         {
  41.             //в конструкторе нужно загрузить морфологию
  42.             try
  43.             {
  44.                 Lemmatizer_ru = new LemmatizerRussianClass();
  45.                 Lemmatizer_ru.LoadDictionariesRegistry();
  46.                 Lemmatizer_en = new LemmatizerEnglishClass();
  47.                 Lemmatizer_en.LoadDictionariesRegistry();
  48.                 Debug.WriteLine("Загрузка морфологи успешно завершена.");
  49.             }
  50.             catch (Exception e)
  51.             {
  52.                 Debug.WriteLine("Ошибка при открытиии морфологического словаря: " + e.Message);
  53.                 //ошибка может быть по многим причинам - например,
  54.                 //кто-то удалил файлы словарей или истекла лицензия,
  55.                 //тогда игнорируем морфологию
  56.                 Lemmatizer_ru = null;
  57.                 Lemmatizer_en = null;
  58.             }
  59.         }
  60.  
  61.         /// <summary>
  62.         /// Делаем слово морфологически инвариантным
  63.         /// </summary>
  64.         /// <param name="word"></param>
  65.         /// <returns></returns>
  66.         public List<string> NormalizeWord(string word)
  67.         {
  68.             List<string> WordList = null;
  69.             if (Lemmatizer_ru != null &&
  70.     Lemmatizer_en != null)
  71.             {
  72.                 //если ошибка в словарях, то пропускаем обработку
  73.                 int weight = -1;
  74.                 bool isEng = this.rWordEn.Match(word).Success;//английское или русское слово
  75.                 // ищем варианты в словаре
  76.                 IParadigmCollection ParadigmCollection =
  77.                     isEng ?
  78.                     Lemmatizer_en.CreateParadigmCollectionFromForm(word, 1, 1) :
  79.                     Lemmatizer_ru.CreateParadigmCollectionFromForm(word, 1, 1);
  80.                 // выбираем наиболее тяжелое по весу
  81.                 for (int j = 0; j < ParadigmCollection.Count; j++)
  82.                 {
  83.                     if (ParadigmCollection[j].WordWeight > weight)
  84.                     {
  85.                         if (ParadigmCollection[j].Norm == "ДЛИТЬ") continue;
  86.                         //будем брать всего одно самое весовое слово для морфологии
  87.                         if (WordList == null)
  88.                         {
  89.                             WordList = new List<string>();
  90.                             WordList.Add(ParadigmCollection[j].Norm.ToLower());
  91.                         }
  92.                         else
  93.                         {
  94.                             WordList[0] = ParadigmCollection[j].Norm.ToLower();
  95.                         }
  96.                         weight = ParadigmCollection[j].WordWeight;
  97.                         //графемы нам не нужны
  98.                         //gramma = this.ParadigmCollection[j].SrcAncode;
  99.                     }
  100.                 }
  101.             }
  102.             return WordList;
  103.         }
  104.     }
  105. }


В функции NormalizeWord видно, что для каждого слова мы берем только ту его морфологическую модификацию, которая имеет наибольший вес. Можно было бы брать больше слов, но тогда размер индекса сильно бы увеличился. Кроме того, на этапе фильтра MorphFilter мы игнорируем все слова с длинною меньше 4х символов, чтобы ускорить работу. Сам класс MorphFilter приведен ниже
Copy Source | Copy HTML
  1. namespace Lucene.Net.Analysis.Morphology
  2. {
  3.     using System;
  4.     using System.Data;
  5.     using System.Configuration;
  6.     using System.Collections.Generic;
  7.     using System.Web;
  8.     using System.Web.Security;
  9.     using System.Web.UI;
  10.     using System.Web.UI.WebControls;
  11.     using System.Web.UI.WebControls.WebParts;
  12.     using System.Web.UI.HtmlControls;
  13.     using Lucene.Net.Analysis;
  14.  
  15.     /// <summary>
  16.     /// Обход набора слов и вставка морфологических модификаций
  17.     /// </summary>
  18.     public class MorphFilter : TokenFilter
  19.     {
  20.         private Queue<Token> morphTokenQueue
  21.             = new Queue<Token>();
  22.  
  23.         private MorphENRU _MorphEngine;
  24.         public MorphENRU MorphEngine { get { return _MorphEngine; } private set { _MorphEngine = value; } }
  25.  
  26.         public MorphFilter(TokenStream input, MorphENRU morphEngine)
  27.             : base(input)
  28.         {
  29.             if (morphEngine == null)
  30.                 throw new ArgumentNullException("morphEngine");
  31.  
  32.             MorphEngine = morphEngine;
  33.         }
  34.  
  35.         public override Token Next()
  36.         {
  37.             // Если есть слова в очереди, то надо их поместить в поток прежде чем одти дальше
  38.             if (morphTokenQueue.Count > 0)
  39.             {
  40.                 return morphTokenQueue.Dequeue();
  41.             }
  42.  
  43.             //Берем след. слово из текста
  44.             Token t = input.Next();
  45.  
  46.             //если пусто, то конец потока
  47.             if (t == null)
  48.                 return null;
  49.  
  50.             //разбор морфологии только для слов длинною более 4х символов
  51.             if (t.TermText().Length > 4)
  52.             {
  53.  
  54.                 //получение актуальных морфологий
  55.                 IEnumerable<string> mWords = MorphEngine.NormalizeWord(t.TermText());
  56.  
  57.                 //если нет слов то вернем слово просто
  58.                 if (mWords != null)
  59.                 {
  60.                     //Переберем все морфологические формы которые более употребляемы
  61.                     foreach (string word in mWords)
  62.                     {
  63.                         //убедимся, что не дублируем слово
  64.                         if (!t.TermText().Equals(word))
  65.                         {
  66.                             //делаем морфологический токен
  67.                             Token mToken = new Token(word, t.StartOffset(), t.EndOffset(), "<MORPH>");
  68.  
  69.                             // устанавливаем относительное смещение в 0,
  70.                             // это нужно, чтобы отразить то, что добавляемое слово соответствует
  71.                             // старому месту в изначальном тексте
  72.                             mToken.SetPositionIncrement(0);
  73.  
  74.                             //помещаем в очередь на помещение в поток
  75.                             morphTokenQueue.Enqueue(mToken);
  76.                         }
  77.                     }
  78.                 }
  79.             }
  80.             //
  81.             return t;
  82.         }
  83.     }
  84.  
  85. }
Теперь можно использовать объект MorphologyAnalyzer в качестве аргумента для стандартных функций индексации и поиска Lucene.Net библиотеки. Пример, стандартного использования Lucene.Net находится по ссылке на RSDN в начале поста.


Метки: , ,   Категории:Csharp | Code


Разработка OpenID+OAuth и общие мысли

На днях Andrew Arnott, известный своим полезным для web-разработчиков проектом DotNetOpenId (библиотека для реализации интерфейсов OpenID в среде .Net), анонсировал в марте этого года выход третьей версии, которая будет включать функционал OAuth. Напомню, что OAuth - это протокол для безопасной передачи своих данных третьим сайтам. От OpenID его отличает лишь то, что все операции с данными проходят с минимальным участием пользователя и данные эти могут быть произвольными, а не только частью профиля пользователя, жестко связанным с его OpenID.
Кроме того Andrew пишет, что в связи с ростом проекта ему нужны деньги на новый хостинг и просит всех не безразличных перечислить сколько не жалко на PayPal. На мой взгляд, читателей у его блога маловато и средства он врядли таким способом соберет.
Примечательно, что с того момента, как модное слово OpenID растащили по своим доменам крупные пользовательские сервисы,
потерялось общее направление в развитии OpenID. Даже должность исполнительного директора в OpenID Foundation до сих пор пустует. Начали совершенствоваться средства по обучению этих глупых пользователей пользоваться новой технологией (речь про F*Connect и различные интеграции сервисов между собою). Обучение, конечно, никак не обойти, но не пора ли задуматься о переходе с простой переброски данных между серверами на расшаривание функционала над данными в хранилище? Как мы знаем, распределенная идентификация - это один из 9 механизмов составляющих семантический веб. Поэтому развитие OpenID нужно вести в ключе скорой интеграции с еще недостаточно разработанными 4мя (Combiner, Mediator, Monitor, Ontology). Итак, каждый OpenID идентификатор должен включать ИмяПользователя(OralIdentifier), Мыло(ElectronicIdentifier), Аватарку(VisialIdentifier) и полное XML(+public RDF)-описание объекта (FullSocialObjectDescription). Без ограничения общности, все это хостится на информационном ресурсе, подключенном к семантической сети, и все приходящие запросы должны быть выполнены не как сейчас "для данного пользователя дайте-ка такое-то поле", а "выполните такой-то SPARQL запрос над данными такого пользователя и верните ответ". Такой подход обусловлен тем, что любые данные в интернете имеют социальную привязку, а значит, возможно, что все новые данные будут выкладываться в таком социальном контексте. Кроме того, меняется RDF-понятие описания ресурса с данными с описания всех ресурсов домена на описание ресурсов одного автора, зарегистрированного на домене, что более абстрагирует нас от физического доменного носителя.

Метки: , ,   Категории:trend | news | OpenID


Завершая месяц

1) Несколько дней буду недоступен в связи с отъездами и пропавшим дома интернетом.
2) Начинаю разбираюсь с библиотекой полнетекстового поиска портированную на Csharp: lucene.net. Очень много разработано для этой библиотеки, почти что полноценный десктопный поисковик написать можно. Очень волнует скорость добавления информации в индекс - может у кого есть опыт работы с ней? Надеюсь с помощью библиотеки покрыть часть функционала тематического поиска, как у продаваемого IBM решения для корпораций, где одна лицензия стоит под 100килобаксов.
3) Опробовал по совету Mads'a плагин для VisialStudio StyleCop 4.3, правда восторга, как у него у меня не появилось. Плагин позволяет следить за правильным оформлением вашего кода. Из полезного могу отметить только возможность проверки правильности составления документации, что все параметры функций описаны и не пусты. Остальное, как проверка на отсутствие двойных пробелов, на наличие копирайтов и т.п. - черезчур.
4) Интересное решение спам проблемы в ЖЖ предлагает Лугастик - как бы лично выступая в роли абуз теам и инспектируя ботов. Проблемой может стать ограничение на размер бан листа в ЖЖ =), а также то, что число ботов в ЖЖ регистрируется за день примерно в 1000раз больше, чем автор успевает просматривать.

Метки:   Категории:Code | life


Анонс топовых блогопостов

Пропиарю запущенную сегодня на твитере ленту топовых постов блогосферы по версии Яндекса. Посмотрим много ли людей заинтересуется. В качестве источника постов я беру записи из RSS-ленты сайта http://topbot.ru/, поэтому ссылки в твитах ведут на этот блог. Как я писал ранее, анонсирование постов - одно из популярных и логичных применений твитера.
Вначале я хотел быстренько написать свою win-службу для копирования RSS в твиттер, но обнаружил весьма удобный ресурс - http://twitterfeed.com/. Сервис позволяет обновлять аккаунт твитера не чаще чем раз в 30 минут. Подробная инструкция по организации трансляций выложена на английском по ссылке. Существует немало и других подобных сервисов, которые легко нагуглить.
Отмеченные минусы трансляции - нет возможности вставить в твиттер, заданное поле из RSS, кроме заголовка и содержания поста (мне хотелось бы указывать в твите автора топового поста). И второе, сейчас вот смотрю и понимаю, что ссылка "http://tinyurl.com/be49wz" - это почти 6 избыточных знаков, от которых можно было бы избавиться, если написать свою трансляцию RSS в твиттер.

Метки: ,   Категории:topbot | idea


Widgets или про воскресенье

В выходные посетил многообещающее мероприятие, организованное StartupPoint, и посвященное некоторым интернет проектам ищущим инвестиций второго круга. Еще раз убедился, что основной способ монетизации стартапа - это привлечение инвестора =) и так далее по принципу пирамиды. Далее отмечу лишь заслужившее моего внимания:

1) liveexperts.ru - мне кажеться у них есть шансы продвинуться дальше, чем Ашманов или Гугл-вопросы. Последние достаточно долго пытались повторить успех проекта топового сайта about.com в части предоставления пользователям человеческих ответов на жизненные вопросы, но оказались нежизнеспособными. Отчасти провал был вызван бесконечными попытками собрать "экспертов во всем". Хорошо было бы реализовать liveexperts.ru на базе видео-чатов(видео-виджет), которые продвигает компания Spirit. А также им стоит подумать над технологией API для того, чтобы каждое уже сформировавшееся в интернете тематическое сообщество могло интегрироваться с их экспертной системе без переманивания пользователей, что было бы грубой ошибкой.

2) toolwi.com . Огорчило, что не удалось узнать относительно их дальнейших планов по разработке виджетов для блогов, скрывают. Единственное, что говорят, так это сделают бесполезную публикацию настроений (likes), а в дальнейшем планируют просто "лечь" под крупный блогохостинг и заняться выполнением задач под конкретные потребности, что поставит на сервисе крест, но даст им денег. Еще раз повторюсь, что я считаю крайне важным создание для блогосферы виджетов тупо дублирующих функционал F*Connect (например, опросы), и в перспективе универсальный виджет для публикации профиля блогера. Но тут, как всегда, хромает монетизация.

3) Чел прочитал лекцию про создание стартапов. Общий вывод - прототип нужен как можно скорее, для апробации модели бизнеса. Это еще раз наталкивает меня на мысли о том, чтобы выложить разработки годовой давности для всех, может какой фидбэк будет...


Метки: ,   Категории:trend | life


toolwi test

Пост для тестирования виджета от toolwi, российского стартапа, который занимается созданием виджетов для помещения всякой фигни в блоги.
В частности, ниже я выложил довольно редкий китайский рэп, стилизованный под оперу. Посмотрим как будет работать во всех блогах.
Забавно, что идея создания виджетов примитивная и запросто может быть изничтожана любым из блогогигантов, но видимо вся беда в монетизации и пока этим никто всерьез не занялся. Вот и у toolwi 2 основных направления монетизации, которые они сейчас импользуют - это пожертвования и партнерские ссылки на системы рекламы в блогах.

Метки:   Категории:bugs | trend


Идеи для фантастической книги

Сидел, пил кофе и думал - "а чтобы мне не подойти к кофейному автомату и не разломать его, чтобы больше не пить кофе такого плохого качества?". Так родилась идея, что было бы прикольно, если бы у нас у всех было 2 жизни. Проживаешь первую, начинается вторая, кончается вторая - все смерть. То есть после первой смерти из тела уходит какой-то дух, который не позволяет пережить вторую смерть. И каждый делает выбор как ему жить, толи вначале вести безбашенную жизнь, а потом тихо мирно работать и растить потомство, толи наоборот. Как бы Вы выбрали? Можно конечно 2 раза прохить одинаково, но я сомневаюсь, что кто-нить так сделал.
И весь мир таким образом делился бы на тех, кто хочет жить подольше и тех кто хочет жить повеселее.
Как раз хватит на трилогию. В первой книге герой вел простой образ жизни, но какой-то урод его убивает, он становится плохим и познает плохие стороны жизни пытаясь найти убийцу (но так и не находит). Во второй книге, героиня пресытившись плохой жизнью долго думает как лучше умереть, потом умирает и пытается вести хорошую жизнь, но ей все мешают. А в третьей книге нужно написать что-нить про книгу судьбы, в которой предначертано какой путь человек выберет в первой жизни и за эту книгу будут весьти борьбу хорошие и плохие.
Может уже кто-то реализовал подобное в какой-нить фантастике, думаю было бы занятно почитать.

Метки:   Категории:idea | life


icq: war is not over

Сегодня перестали работать вне не родные клиенты ICQ. Вываливается следующее сообщение:
=============================
Системное сообщение
=============================
ICQ не поддерживает используемую вами версию. Скачайте бесплатную авторизованную версию ICQ с официального web-сайта ICQ.
=============================
System Message
=============================
The version you are using is not supported by ICQ. Download a free authorized ICQ version from ICQ's official website.

Способов побороть это пока не найдено. Родного клиента я уж точно ставить не буду. На Хабре уже 5 тем и до сих пор решения нет.
PS: Поэтому прошелся по ним и проминусовал карму =).

Метки:   Категории:bugs | news


Дополненая Реальность: Еще 2 года

Сегодня хочу поделиться мыслями возникшими по прочтению большого и познавательного интервью с Robert Rice'ом, который руководит фирмой Neogence, занимающейся разработкой программного сопровождения(SDK, tools) для дополненной реальности. Кроме того, я просмотрел уже половину киберпанковского аниме Denno Coil (subbed NOT dubbed как и рекомендуют) и включил в пост, некоторые "истинные знания" вынесенные из мультика.
1) Во-первых, порадовало, что Роберт считает, что до прорыва в области AR осталось менее 2х лет, то есть в 2010 году мы - простые пользователи - что-то обретем или увидим. Сам же Роберт планирует примерно через 6 месяцев выложить на YouTube демонстрацию ихнего прототипа.
2) Во-вторых, построение AR должна возглавить одна фирма, в задачи, которой станет реализация инфраструктуры доступности и работоспособности очков AR в большой части города. Частично эта фирма будет строить сеть своих точек доступа частично покупая или арендуя сети у уже имеющихся операторов того же WiFi или сотовой связи. Все зависит от нужной пропускной способности. Далее вся территория покрытая AR сдается в аренду различным фирмам, которым предоставляется заранее разработанный SDK и tools для создания виртуальных объектов.
3) Роберт называет одной из основных проблем - спам. Поэтому все приложения, которые становятся доступны пользователям проходят предварительную модерацию перед помещением в каталог, на подобии AppleStore. Иначе, по улицам у нас будут летать виртуальные члены.
4) Из аниме я понял, что обязательно, чтобы на очках была внешняя лампочка, которая бы сигнализировала пользователю или окружающим его людям, что есть виртуальные объекты, с которыми идет взаимодействие или требуется пользовательское действие. Это нужно для выведения пользователя из AFK'a, а также для уменьшения недопонимания между людьми без очков и людьми с очками. Это как с BlueTooth наушником для телефона, окружающим может показаться, что вы говорите сами с собою, свет светодиода может их остановить от вызова скорой.
5) Сомнительным видится возможность управления очками при помощи глаз (Например, два моргания обоими глазами как Enter). Для взаимодействия с AR объектами придется одеть трехпальцевые перчатки с сенсорами на концах пальцев. В частности перемещение по осям должно быть по аналогии с увеличением изображений на iPhone. С учетом правила буравчика, соединение среднего с большим пальцем должно давать перемещение изображение по оси Z и т.п. А если сильно повезет, то поднесение буквы V из двух пальцев ко лбу позволит стрелять лучем виртуального света =).
6) Как AR будет монетизирована? Роберт назвал 3 способа, я добавлю еще 2: Микротранзакции (очки - фактически электронный кошелек, который всегда с вами, замена телефона и КПК, позволит его использовать для платежей); Виртуальное представительства компаний (это замена созданию сайтов); Реклама(все рекламные щиты сквозь очки вы будете видеть по особому, вам будет крутиться другая реклама, более интерактивная); Продажа виртуальных вещей и услуг(не все способны создавать виртуальные вещи, поэтому появятся целые бизнесы по их производству, как в Second Life)
7) Как будет зваться новый виртуальный мир? Роберт отвергает примитивные варианты “augmented reality”, “mixed reality”, “matrix”, “metaverse”. Кроме того все доменные имена с metaverse уже заняты. Я бы предложил имя “RealmA“, просто нравится как звучит. Но сам, между делом, занял доменное имя - a-r.me, как сокращение от Augmented-Reality(for)ME. Может года через 4 буду там торговать виртуальной кармой для хабралюдей со скидкой. =).
8) Как привлечь в виртуальный мир пользователей? Наиболее простой способ - раздача виртуальных питомцем. А за хорошее поведение в виртуальном миру и за помощь в его развитие выдавать дополнительные бонусы. Это должно выглядеть как игра - хочешь играй, а хочешь нет. При этом таких ловушек разума нужно создать несколько.

И в завершение видео одного из уже существующих в Японии "петов" - Гейша. Рекомендую отключить звук, а то анимешные крики заполнят вашу комнату:

Метки: ,   Категории:AugmentedReality | trend | news


.Net: Программная печать документов MS Office

На днях решил поменять в одной программе печать документов с простого "webBrowser.ShowPrintDialog();" в браузере, на полноценное открытие MS Word с дальнейшей печатью. Но речь пойдет не о создании простого процесса winword.exe с передачей ему в качестве параметра нужного документа, а о библиотеках, которые созданы для разработчиков предусмотрительным Microsoft'ом. Заявлено, что решение работает под Office2003/2007, WinXP+, MSVS2005+. Краткое описание по работе с библиотекой приводит один из индийских девелоперов, номинированный как MVP (Microsoft Most Valuable Professional). Однако после строчек кода:
Copy Source | Copy HTML
  1. Object true = true;
  2. Object false = false;
...я почувствовал, что все шутки на баше про индийских программистов не были надуманными.
Далее я приведу шаги, с помощью которых, мне удалось осуществить задуманное и кусок кода. Итак, скачайте указанный выше архив с библиотеками. Внутри него будет также инструкция по интеграции этих библиотек в MSVS, но я рекомендую просто подключить нужную библиотеку, в моем случае это "Microsoft.Office.Interop.Word.dll", потому как я работаю только с MSWord, как Refference в проект. Далее, так как я хочу выводить на печать содержимое окна браузера, то я создал наследника от класса WebBrowser. Обратите внимание на функцию OpenInWord. Она создает вначале приложение офиса Application, потом сам документ, с которым работаем, загружая его из файла. Когда загрузка завершена, то делаем отображение самого офиса, выставляя значение Visible в true, так как по умолчанию офис будет работать спрятан:
Copy Source | Copy HTML
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Text.RegularExpressions;// регулярные выражения
  9. using System.IO;//работа с файлами
  10.  
  11. namespace BestApplicationEvah
  12. {
  13.     public partial class WebBrowser_I : WebBrowser
  14.     {
  15.         public WebBrowser_I()
  16.         {
  17.             InitializeComponent();
  18.         }
  19.  
  20.         /// <summary>
  21.         /// Временная директория в которую складываются все файлы отправляемые на печать.
  22.         /// </summary>
  23.         private string printdirectory = "Rprint";
  24.  
  25.         /// <summary> Временная директория в которую складываются все файлы отправляемые на печать. </summary>
  26.         public string PrintDir { get { return printdirectory; } set { printdirectory = value; } }
  27.  
  28.         /// <summary>
  29.         /// Функция преобразования html в правильный формат для показа в doc
  30.         /// </summary>
  31.         /// <param name="file">Название файла. Желательно с расширением doc</param>
  32.         /// <param name="HTML">Html для преобразований</param>
  33.         /// <returns></returns>
  34.         private string HtmlToDocFile(ref string file, string HTML)
  35.         {
  36.             /*** много кода ***/
  37.         }
  38.  
  39.         /// <summary>
  40.         /// Функция сохраняет текущую страницу, как указанный файл и открывает его
  41.         /// </summary>
  42.         /// <param name="file">Имя создаваемого файла, должно иметь расширение DOC</param>
  43.         public void OpenAsDoc(string file)
  44.         {
  45.             this.OpenAsDoc(file, false);
  46.         }
  47.  
  48.         /// <summary>
  49.         /// Функция сохраняет текущую страницу, как указанный файл и открывает его
  50.         /// </summary>
  51.         /// <param name="file">Имя создаваемого файла, должно иметь расширение DOC</param>
  52.         /// <param name="newWindow">Открыть файл в новом окне?</param>
  53.         public void OpenAsDoc(string file, bool newWindow)
  54.         {
  55.             string err = this.HtmlToDocFile(ref file, this.DocumentText);
  56.             if (!String.IsNullOrEmpty(err))
  57.             {
  58.                 //вывод сообщения об ошибке
  59.                 MessageBox.Show(err, "Ошибка");
  60.             }
  61.  
  62.             //и отображаем доковский файл в браузере
  63.             this.Navigate(Directory.GetCurrentDirectory() + "/"+ this.printdirectory + "/" + file,newWindow);
  64.         }
  65.  
  66.         /// <summary>
  67.         /// Открытие HTML в MS Word...
  68.         /// </summary>
  69.         /// <param name="file">Название файла для сохранения информации</param>
  70.         public void OpenInWord(string file){
  71.             //создадим из контента файл
  72.             string err = this.HtmlToDocFile(ref file, this.DocumentText);
  73.             if (!String.IsNullOrEmpty(err))
  74.             {
  75.                 //вывод сообщения об ошибке
  76.                 MessageBox.Show(err, "Ошибка");
  77.             }
  78.  
  79.             try
  80.             {
  81.                 //Create an object for missing values. This will be passed whenever we don’t want to pass value
  82.                 Object missing = System.Reflection.Missing.Value;
  83.                 //Objects for true and false to be used in the word document for passing true or false.
  84.                 //Object true = true;
  85.                 //Object false = false;
  86.                 //Creating objects of word and document
  87.                 Microsoft.Office.Interop.Word.Application oWord = new Microsoft.Office.Interop.Word.Application();
  88.                 Microsoft.Office.Interop.Word.Document oWordDoc = new Microsoft.Office.Interop.Word.Document();
  89.                 object fileName = Directory.GetCurrentDirectory() + "/" + this.printdirectory + "/" + file;
  90.                 // You can keep it true if you want to open the file in readonly mode
  91.                 object readOnly = false;
  92.                 // we can keep it false if you want to open the file but not make it invisible
  93.                 object isVisible = true;
  94.                 //открытие файла
  95.                 oWordDoc = oWord.Documents.Open(ref fileName, ref missing, ref
  96.                   readOnly, ref missing, ref missing, ref missing, ref
  97.                   missing, ref missing, ref missing, ref missing, ref
  98.                   missing, ref isVisible, ref missing, ref missing, ref
  99.                   missing);
  100.                 //делаемся видимыми
  101.                 oWord.Application.Visible = true;
  102.                 //oWord.ShowMe();//смысл функции остался неизвестным
  103.                 //автопечать
  104.                 //oWord.PrintOut(ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
  105.                 // ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
  106.                 // ref missing, ref missing);
  107.             }
  108.             catch(Exception WordExc)
  109.             {
  110.                 MessageBox.Show(WordExc.Message, "Ошибка при работа с MS Word");
  111.             }
  112.         }
  113.     }
  114. }
И когда мы всетаки завершим работать с офисом, важно закрыть объекты, иначе процесс winword может остаться висеть:
Copy Source | Copy HTML
  1. //Closing the file
  2. oWordDoc.Close(ref oFalse, ref missing, ref missing);
  3. //Quitting the word application to release the memory.
  4. oWord.Quit(ref missing, ref missing, ref missing);

Остальные возможности работы в документами содержаться в многочисленных методах объекта oWord и требуют дополнительных экспериментов.

Метки: , ,   Категории:Code


Кто я?

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

Последние комментарии

Не отображать

Topbot at FeedsBurner

Облако тэгов

Мои Твиты

Twitter сентября 25, 02:06
Танцы человека с роботом http://dlvr.it/QlGVN0

Twitter сентября 25, 02:06
Конец эры бесплатного SSL http://dlvr.it/QlGVPP

Twitter сентября 25, 01:02
В Твиттере начался обвал фолловеров http://dlvr.it/QlGJbX

Twitter сентября 24, 21:14
Суммарная капитализация криптовалют http://dlvr.it/QlFZdK

Twitter сентября 24, 13:02
Рейтинг каналов и ботов Телеграм http://dlvr.it/QlCBqg

Twitter сентября 24, 13:02
Короткометражка про Еду http://dlvr.it/QlCBqK https://twitter.com/f1ashr/status/1044210510885904384/photo/1

Twitter сентября 24, 13:02
Разбор сериала Туман или 4 всадника Апокалипсиса http://dlvr.it/QlCBpp https://twitter.com/f1ashr/status/1044210505798172672/photo/1

Twitter сентября 23, 14:03
Designing for Scale with Windows Azure Storage http://dlvr.it/Ql6TP9

Twitter сентября 23, 14:03
Причуды http://Blogs.Mail.Ru http://dlvr.it/Ql6TLw

Twitter сентября 23, 14:03
Google Wave for Internet Explorer http://dlvr.it/Ql6TNK

Twitter сентября 23, 13:31
Про Европу в парламенте http://dlvr.it/Ql6MPm

Twitter сентября 23, 13:31
one link http://dlvr.it/Ql6MN0

Twitter сентября 23, 13:31
BE Themes contest http://dlvr.it/Ql6MNv

Twitter сентября 23, 13:31
Киберпанковское кино http://dlvr.it/Ql6MMK

Twitter сентября 23, 12:59
magic mushrooms - погода в москве http://dlvr.it/Ql6FDL https://twitter.com/f1ashr/status/1043847359614971904/photo/1

Twitter сентября 23, 12:59
Футубра http://dlvr.it/Ql6FDC

Twitter сентября 23, 12:59
Инстаграм борется со спамом в комментах http://dlvr.it/Ql6FDJ

Twitter сентября 20, 21:20
Человечество станет межпланетной цивилизацией http://dlvr.it/Qks8d8 https://twitter.com/f1ashr/status/1042886283117260800/photo/1

Twitter сентября 14, 17:50
Цвет настроения черный http://dlvr.it/QkCWGn https://twitter.com/f1ashr/status/1040659099577282561/photo/1

Twitter сентября 13, 01:55
.Net - Контексный поиск с учетом русской и английской морфологии http://dlvr.it/Qk1GLz

Мой твиттер

Копирайт

Все мысли, высказанные в блоге, являются моим мнением и за это мнение меня никто не забанит! Кроме того, никто не имеет право копировать материалы блога без использования ctrl+C/V!

© Copyright 2008