Яндекс.Метрика

    Веб разработка

    Запланированная отправка постов (php, mongo, cron, regexp)

    Добрый день.

    Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.

    Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.

    Шаблон * * * * *

    После этого встал вопрос — как получить только нужные поля для отправки?

    Реклама

    TELEPORT — город-мечта для продуктивной работы на природе!



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

    Одна из них представлена ниже. Итак:

    1. Сначала смотрим презентацию про город мечты для активной работы на природе.
    2. Затем читаем под катом и комментируем.


    Реклама

    lancelist.pro — сайт для поиска фриланс-работы через Twitter

    Основная идея



    Для поиска и размещения удалённой работы достаточно пользоваться Твиттером!

    Как появилась идея


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

    Реклама

    Бесплатный видеокурс по работе с Яндекс. Директ. Часть 3

    Готова третья часть курса Яндекс.Директ. Путь Джедая.

    Теперь в HD и с нормальным звуком.


    Смотрим, обучаемся, задаем вопросы.

    Предыдущие части:
    Часть 2
    Часть 1
    Часть 0
    Анонс курса на хабре:

    Реклама

    Chronocapsule

    92 секунды сути проекта (субтитры доступны)


    Обучение

    Магистерские программы Санкт-Петербургского Академического университета (бывший АФТУ РАН)


    Повсеместный переход на Болонскую систему даёт студентам возможность сменить ВУЗ после получения диплома бакалавра. Однако немногие студенты задумываются об этом. Во многих ВУЗах магистерская программа очень «разрежена»: присутствует множество непрофильных курсов (философия, культурология и т.д.), профильных же очень мало, и для того, чтобы их сдать, достаточно просто появиться на экзамене/зачёте.
    Тех, кто ещё сохранил желание учиться, кафедра математических и информационных технологий Академического университета приглашает в магистратуру по трем специализациям:
    • теоретическая информатика,
    • разработка программного обеспечения
    • алгоритмическая биоинформатика.

    Песочница

    Как адаптировать сервис под мобильные платформы

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

    В связи с этим появились даже радикальные подходы, когда предлагается делать дизайн в первую очередь для мобильных платформ, а потом уже задумываться о большом вебе (http://www.lukew.com/resources/mobile_first.asp). Это красивая концепция, но суровая правда жизни в том, что многие сервисы уже существуют в веб варианте и им необходимо шагнуть в мобильный мир.

    Песочница

    Исследование через функциональное тестирование

    Предисловие


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

    Зачем планировать

    Вне зависимости от того, в какой среде вы работаете, будь то гибкая среда разработки (agile) или традиционные подходы, например waterfall существуют deadline в течении которго необходимо желательно закончить работу. В Scrum, например deadlinом будет являться спринт. В любом случае, команда или разработчик предоставляют обязательства перед заказчиком, и эти обязательства нужно выполнять, в противном случае штрафных санций со стороны заказчика не избежать.

    Планирование технических задач

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

    Язолъ

    Уголовное дело за брелок

    Служба безопасности Украины возбудила уголовное дело по четырем статьям уголовного кодекса:
    • ст. 201 — Контрабанда
    • ст. 15 — Покушение на преступление
    • ст. 263 — Незаконное обращение с оружием, боевыми припасами или взрывчатыми веществами
    • ст. 359 — Негласное получение информации

    … за две заказанных на dealextreme видеокамеры в виде брелока и перочинный ножик.

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

    Самое интересное, что по логике следствия, примерно у 99% украинских читателей хабры есть спецсредство в виде мобильного телефона. Будьте осторожны!

    Детали дела на distributed.org.ua/forum/index.php?showtopic=5245

    Реклама

    Нам не страшен беспредел, или уведомляем родных о неприятностях (iOS)

    После недавних выборов в ГосДуму и волны протестов, зимним вечером было создано простое, но полезное iOS приложение, которое мгновенно уведомляет родных и знакомых, что вы в опасности.

    Через несколько дней в России выборы, наверняка будет множество акций протеста и RescuePing пригодится многим гражданам.

    image

    Основная фишка приложения — отправка сообщений без разблокировки устройства, достаточно просто вытащить шнур наушников и уведомление будет отправлено.

    Реклама

    Тренинг по Symfony2 в Украине

    symfony logoХорошие новости для Symfony2 разработчиков, а так же для тех, кто хочет познакомиться с этим фреймворком поближе.
    Вскоре после открытия офиса в Украине компания KnpLabs объявила о проведении тренингов по Symfony2.

    Первые тренинги состоятся уже совсем скоро в Киеве (15-16 марта) и Харькове (29-30 марта).
    Не может не радовать и философия тренинга: Меньше разговоров — больше кода!

    Язолъ

    Google+ такой Google+

    Думаю на хабре многие пользуются google+. Я тоже пользовался им в основном для расшаривания из google reader. Но в один прекрасный момент я обнаружил, что google заблокировал мой аккаунт. Ну хорошо, я пошел почитал политику чего можно размещать. Подивился, что нельзя размещать даже для ограниченного круга лиц или для себя некоторые вещи (в соглашении про это ни слова), убрал. Нажал кнопку проверить по новой. Блок изменился и там появилась следующая информация:
    Если профиль пройдет проверку, мы снова откроем к нему доступ. Если нет – на ваш адрес электронной почты будет отправлено письмо о том, что запрос отклонен и профиль все еще заблокирован. В этом случае вам потребуется внести в него дополнительные изменения и отправить на повторное рассмотрение.

    Подождал я значит несколько дней. И профиль опять вернулся в заблокированное состояние и… собственно никакого письма я не получил. Хорошо повторил операцию три раза. Никакой реакции. Нашел кнопку google отклики. Нажал описал ситуацию. Прошла неделя. Профиль находится все в том же состоянии заблокирован, письма нет. В ответ на отклик ничего не пришло. Что еще больше из всего этого радует кнопки написать в суппорт на странице google+ нет. Хорошо идем в интернеты и ищем по этой же проблеме. Видимо что проблема имеется и как-то судя по всему не решается.

    Ну что я могу по этому поводу сказать? Отлично работаете господа из Google. Мало того что политики странные, так еще и концов не найти. А еще пытаетесь сопоставить google+ как альтернативу facebook.

    Звуки музыки

    Создание задач Redmine голосом


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

    Далее опишу основные моменты и что в итоге получилось.

    Записываем во Flac


    И так, мне потребовалось: Dot NET, Google Speech-Api, кодек Flac, Redmine API .NET.
    Использование speech-api освещается в интернетах в т.ч. и на хабре, для этого необходимо просто отправить POST запрос со звуковым файлом, в ответ получите JSON объект:

    Строка запроса:
    http://www.google.com/speech-api/v1/recognize?lang=ru&client=chromium

    Ответ:
    {status:int, id:string, hypotheses : [{utterance : string, confidence : double}]}


    Сложность заключается в записи файла такого формата, а именно – Flac, 16kHz, 16bit, mono. Получением pcm данных c wave-in интерфейса занимается (WaveLib господина Ianier Munoz) — полученные данные с буферов очереди отправляются в указанный callback, где записываются в кольцевой буфер (ring buffer), перед созданием обработчика записи создаётся тред для извлечения данных из кольцевого буфера и их отправки в кодек. Кодек я обернул в C++/CLI библиотеке, в чём помог пример, прилагающийся к libflac:

    // Обратите внимание что сэмплы для flac имеют размер в 32bit
    
    // Создаётся Енкодер
    static 
    bool InitialiseEncoder(char* filepath, FILE** _file, FLAC__StreamEncoder** _encoder, FLAC__StreamMetadata** _metadata1, FLAC__StreamMetadata** _metadata2)
    {
    	FLAC__bool ok = true;
    	FLAC__StreamEncoder *encoder = 0;
    	FLAC__StreamEncoderInitStatus init_status;
    	FLAC__StreamMetadata *metadata[2];
    
    	unsigned sample_rate = 16000;
    	unsigned channels = 1;
    	unsigned bps = 16;
    
    	/* allocate the encoder */
    	if((encoder = FLAC__stream_encoder_new()) == NULL) {
    		return false;
    	}
    
    	ok &= FLAC__stream_encoder_set_verify(encoder, true);
    	ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
    	ok &= FLAC__stream_encoder_set_channels(encoder, channels);
    	ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
    	ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
    	ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, 0);
    
    	// В этот файл будет записан выход Енкодера
    	FILE* flacfile = _wfopen((wchar_t*)filepath, L"wb");
    	// Создаём Енкодер
    	if(ok) {
    		init_status = FLAC__stream_encoder_init_FILE(encoder, flacfile, progress_callback, /*client_data=*/NULL);
    		if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
    			fprintf(stderr, "ERROR: initializing encoder: %s\n", FLAC__StreamEncoderInitStatusString[init_status]);
    			ok = false;
    		}
    	}
    	
    	*_encoder = encoder;
    	*_file = flacfile;
    
    	return ok;
    }
    // Отправка pcm данных кодеку
    static 
    bool ProcessEncoder(FLAC__StreamEncoder *encoder, FLAC__byte* _pcm, size_t need)
    {
    	// С wave-in данные приходят в 16bit на семпл
    	FLAC__bool ok = true;
    	// На вход екодеру послупают 32bit сэмплы, здесь они просто копируются соблюдая последовательности
    	for(unsigned int i = 0; i < need*1; i++) {
    		pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)_pcm[2*i+1] << 8) | (FLAC__int16)_pcm[2*i]);
    	}
    	ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, need);
    	return ok;
    }
    


    Далее был создан класс Recorder. Помимо создания экземпляра WaveInRecorder(менеджер wave-in устройства) создаётся тред для отправки pcm данных в Flac кодек из колцевого буфера:

    	private unsafe void DataArrived(IntPtr data, int size)
            {
    	    // Записываем pcm в кольцевой буфер
                cb.Upload(data.ToPointer(), size);
            }
    
            WaveLib.WaveInRecorder m_Recorder;
            VorbisEnc.FlacEncoder ve;
            VorbisEnc.CircleBuffer cb;
            IntPtr filepath;
    
            public unsafe Recorder(string tempfilepath)
            {
                cb = new VorbisEnc.CircleBuffer();
                ve = new VorbisEnc.FlacEncoder();
                ve.Initialise((sbyte*)System.Runtime.InteropServices.Marshal.StringToHGlobalUni(tempfilepath).ToPointer());
                
                // Тред для кодировщика
                System.Threading.Thread th = new System.Threading.Thread(EncodeData);
    
                WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(16000, 16, 1);
                m_Recorder = new WaveLib.WaveInRecorder(-1, fmt, 4096, 4, new WaveLib.BufferDoneEventHandler(DataArrived));
    
                th.Start();
            }
    
            bool StopThread;
            public bool AllDone = false;
            public void Stop()
            {
                m_Recorder.Dispose();
                StopThread = true;
                cb.Dispose();
            }
            unsafe void EncodeData()
            {
                IntPtr datax = System.Runtime.InteropServices.Marshal.AllocHGlobal(4096);
                sbyte* data = (sbyte*)datax.ToPointer();
                while (!StopThread)
                {
                    System.Threading.Thread.Sleep(10);
    		// Извлекаем из кольца данные, если курсор записи приблизился к курсору
    		// чтения на 4 итерации
                    while (cb.getNeedForUpdate() < 4096 * 4)
                    {
                        cb.Download(data, 4096);
                        ve.Encode(data, 4096);
                    }
                }
                System.Runtime.InteropServices.Marshal.FreeHGlobal(datax);
                ve.Close();
    	    // Данные кодированы и записаны, файл закрыт
                AllDone = true;
            }
    


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

    Аудиофайл записывается одной функцией:
                string file = Path.GetTempFileName();
                Recorder rec = new Recorder(file);
                // Просто ждём пока записывается аудиофайл
                System.Threading.Thread.Sleep(seconds * 1000);
    	    // Останавливаем запись, закрываем файл
                rec.Stop();
    

    Далее передаётся на отправку в google:
                string result = WebUpload.UploadFileEx(flacpath, 									"http://www.google.com/speech-api/v1/recognize?lang=ru&client=chromium",
                     "file", "audio/x-flac; rate=16000", parameters, null);
    

    Функция отправки файла:
                Uri uri = new Uri(url);
    
                FileStream fileStream = new FileStream(uploadfile,
                                            FileMode.Open, FileAccess.Read);
      
                HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
                if (cookies != null)
                    webrequest.CookieContainer = cookies;
    	    // Лишние заголовки необходимо убрать
                webrequest.Headers.Clear();
                webrequest.ContentLength = fileStream.Length;
                webrequest.ContentType = contenttype;
                webrequest.Method = "POST";
    
                Stream requestStream = webrequest.GetRequestStream();
                byte[] buffer = new Byte[checked((uint)Math.Min(4096,
                                         (int)fileStream.Length))];
    	    // Записываем файл в поток Http запроса
                int bytesRead = 0;
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    requestStream.Write(buffer, 0, bytesRead);
    
                fileStream.Close();
    
                WebResponse response = webrequest.GetResponse();
                Stream s = response.GetResponseStream();
                StreamReader sr = new StreamReader(s);
    
                string resps = sr.ReadToEnd();
                response.Close();
    
    	    return resps;
    


    Redmine API

    В redmine есть Rest api через который без сложностей, используя логин – пароль добавляется задача

                    RedmineManager manager = new RedmineManager(Configuration.RedmineHost,
                        Configuration.RedmineUser, Configuration.RedminePassword);
    
                    // Задача
                    var newIssue = new Issue
                    {
                        Subject = Title,
                        Description = Description,
                        Project = new IdentifiableName() { Id = ProjectId },
                        Tracker = new IdentifiableName() { Id = TrackerId }
                    };
    		// Находим id текущего пользователя
                    User thisuser = (from u in manager.GetObjectList<User>(new System.Collections.Specialized.NameValueCollection())
                                     where u.Login == Configuration.RedmineUser
                                     select u).FirstOrDefault();
                    if (thisuser != null)
                        newIssue.AssignedTo = new IdentifiableName() { Id = thisuser.Id };
    
                    manager.CreateObject(newIssue);
    


    Получение списка проектов и трекеров:
            public static Dictionary<string, int> GetProjects()
            {
                RedmineManager manager = new RedmineManager(Configuration.RedmineHost,
                    Configuration.RedmineUser, Configuration.RedminePassword);
                Dictionary<string, int> Projects = new Dictionary<string, int>();
    
                foreach (Project proj in manager.GetObjectList<Project>(new NameValueCollection()))
                {
                    Projects.Add(proj.Name, proj.Id);
                }
                return Projects;
             }
    
            public static Dictionary<string, int> GetTrackers()
            {
                RedmineManager manager = new RedmineManager(Configuration.RedmineHost,
                    Configuration.RedmineUser, Configuration.RedminePassword);
                Dictionary<string, int> Trackers = new Dictionary<string, int>();
    
                foreach (Tracker track in manager.GetObjectList<Tracker>(new NameValueCollection()))
                {
                    Trackers.Add(track.Name, track.Id);
                }
                return Trackers;
            }
    


    Кстати, всё то актуально для версий моложе 1.3 (появился список трекеров в REST API)

    Итог или заключение



    В итоге получилась форма с двумя полями для определения по голосу: название задачи, описание задачи. На время записи и распознавания все поля закрываются панелью. Запись производится с устройства, выставленного в системе для записи по умолчанию в течение 4 секунд.

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

    Источники


    Flac
    Redmine API
    WaveLib

    Ссылки


    Бинарники
    Исходники

    Песочница

    Радикальное кеширование в Joomla 1.5

    image

    Бесплатная CMS это всегда компромисс, компромисс между целым рядом очевидных факторов, перечислять которые в рамках данного ресурса смысла пожалуй нет, т.к. они всем давно известны. Безусловно, среди всего разнообразия бесплатных СМS можно выделить некоторые, которые будут лучше или хуже в каких-то отдельных номинациях, вроде скорости работы, простоты освоения новичком и т.п. Но в данной статье речь не об этом. Я просто хочу поделиться опытом успешного решения проблемы скорости генерации страниц в Joomla с помощью кеширования. Причём кеширования очень радикального, на «уровне» index.php.

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

    freelance

    Мотивация от лукавого

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

    Реклама

    [50] Еженедельный подкаст Appleinsider.ru с Алексом Пацаем (@alexmak)

    Здравствуйте, читатели Хабрахабр!

    AppleInsider.ru: Пятидесятый выпуск.

    image
    • В гостях Алекс Пацай (@Alexmak)
    • Новый iPad нам покажут 7 марта
    • Приложение AppleInsider.ru доступно для WP7
    • Google представила новый жест поиска
    • Тим Кук о выплате дивидендов акционерам Apple и дроблении акций
    • У половины владельцев iPhone 4S отношения с Siri не заладились
    • Nokia берет мегапикселями
    • Apple напоминает пользователям MobileMe о сроке миграции в iCloud
    • … и другие темы

    Подписка: iTunes | RSS | MP3
    прослушан 15 раз

    Реклама

    Простой сервис уведомлений через Twitter


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

    Песочница

    Централизованный syslog

    Привет. В виду растущего количества серверов которые админю, и всяких других девайсов (ротуреры, IP телефоны и тд.) в своей IT инфраструктуре, появилась необходимость собирать логи в одном месте и иметь более-менее читабельный интерфейс для их вывода. Возможно я изобретаю велосипед, но в то время не удалось нагуглить по-быстрому чего нибудь подходящего, да и самому захотелось что нибудь сотворить.

    Реклама

    История о Панде и iOS



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