Веб разработка →
Запланированная отправка постов (php, mongo, cron, regexp)
Добрый день.
Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.
Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.
Шаблон * * * * *
После этого встал вопрос — как получить только нужные поля для отправки?
Недавно мне пришлось писать страницу отправки постов на стены социальных сетей. Была поставлена задача постить на стену в определенное время а не сразу.
Я написал страницу с полями для выбора соц сетей, текстом сообщения и самим полем для ввода времени отправки. Кроме обычного календаря с выбором даты и времени отправки, я добавил еще одно поле с вводом критерия отправки по правилу cron.
Шаблон * * * * *
После этого встал вопрос — как получить только нужные поля для отправки?
07.03.2012 19:16+0400
Реклама →
TELEPORT — город-мечта для продуктивной работы на природе!
В свободное от безделья время в голову начали приходить утопические идеи.
Одна из них представлена ниже. Итак:
- Сначала смотрим презентацию про город мечты для активной работы на природе.
- Затем читаем под катом и комментируем.
07.03.2012 15:11+0400
Реклама →
lancelist.pro — сайт для поиска фриланс-работы через Twitter
Основная идея
Для поиска и размещения удалённой работы достаточно пользоваться Твиттером!
Как появилась идея
После публикации этого топика, в голове засела идея: Все фрилансеры, просто действуя по определённым правилами, с помощью имеющихся в наличии средств, могут построить самоорганизующуюся систему поиска и размещения удалённой работы.
06.03.2012 12:30+0400
Реклама →
Бесплатный видеокурс по работе с Яндекс. Директ. Часть 3
Готова третья часть курса Яндекс.Директ. Путь Джедая.
Теперь в HD и с нормальным звуком.
Смотрим, обучаемся, задаем вопросы.
Предыдущие части:
Часть 2
Часть 1
Часть 0
Анонс курса на хабре:
Теперь в HD и с нормальным звуком.
Смотрим, обучаемся, задаем вопросы.
Предыдущие части:
Часть 2
Часть 1
Часть 0
Анонс курса на хабре:
06.03.2012 11:02+0400
Реклама →
Chronocapsule
06.03.2012 10:10+0400
Обучение →
Магистерские программы Санкт-Петербургского Академического университета (бывший АФТУ РАН)
Повсеместный переход на Болонскую систему даёт студентам возможность сменить ВУЗ после получения диплома бакалавра. Однако немногие студенты задумываются об этом. Во многих ВУЗах магистерская программа очень «разрежена»: присутствует множество непрофильных курсов (философия, культурология и т.д.), профильных же очень мало, и для того, чтобы их сдать, достаточно просто появиться на экзамене/зачёте.
Тех, кто ещё сохранил желание учиться, кафедра математических и информационных технологий Академического университета приглашает в магистратуру по трем специализациям:
- теоретическая информатика,
- разработка программного обеспечения
- алгоритмическая биоинформатика.
05.03.2012 21:12+0400
Песочница →
Как адаптировать сервис под мобильные платформы
С тем, что мобильный и планшетный рынки является одними из самых быстрорастущих, сегодня не будет спорить никто. Это хороший момент, у многих есть шанс переломить ситуацию и выиграть второй раунд, а для многих нерасторопных есть все шансы остаться только в большом вебе.
В связи с этим появились даже радикальные подходы, когда предлагается делать дизайн в первую очередь для мобильных платформ, а потом уже задумываться о большом вебе (http://www.lukew.com/resources/mobile_first.asp). Это красивая концепция, но суровая правда жизни в том, что многие сервисы уже существуют в веб варианте и им необходимо шагнуть в мобильный мир.
В связи с этим появились даже радикальные подходы, когда предлагается делать дизайн в первую очередь для мобильных платформ, а потом уже задумываться о большом вебе (http://www.lukew.com/resources/mobile_first.asp). Это красивая концепция, но суровая правда жизни в том, что многие сервисы уже существуют в веб варианте и им необходимо шагнуть в мобильный мир.
04.03.2012 22:55+0400
Песочница →
Исследование через функциональное тестирование
Предисловие
Очень часто разработчик встречается с задачами, которые подразумевают изменение существуюещего функционала системы, либо же добавление нового, который переиспользует существующий функционал. В этой статье я хочу обсудить некоторые подходы к определению объема работ, которые необходимо будет сделать разработчику, чтобы корректно запланировать задачи.
Зачем планировать
Вне зависимости от того, в какой среде вы работаете, будь то гибкая среда разработки (agile) или традиционные подходы, например waterfall существуют deadline в течении которго
Планирование технических задач
В данной статье я опущу методики планирования задач для систем, которые пишутся с нуля, а сосредоточусь на изменениях которые необходимо сделать в существующих приложениях.
Все подходы, которые я собираюсь описать, я использовал сам в той или иной мере.
04.03.2012 12:41+0400
Язолъ →
Уголовное дело за брелок
Служба безопасности Украины возбудила уголовное дело по четырем статьям уголовного кодекса:
… за две заказанных на dealextreme видеокамеры в виде брелока и перочинный ножик.
Системный администратор с годовалым ребенком на руках может отправиться за решетку на добрый десяток лет, как матерый уголовник.
Самое интересное, что по логике следствия, примерно у 99% украинских читателей хабры есть спецсредство в виде мобильного телефона. Будьте осторожны!
Детали дела на distributed.org.ua/forum/index.php?showtopic=5245
- ст. 201 — Контрабанда
- ст. 15 — Покушение на преступление
- ст. 263 — Незаконное обращение с оружием, боевыми припасами или взрывчатыми веществами
- ст. 359 — Негласное получение информации
… за две заказанных на dealextreme видеокамеры в виде брелока и перочинный ножик.
Системный администратор с годовалым ребенком на руках может отправиться за решетку на добрый десяток лет, как матерый уголовник.
Самое интересное, что по логике следствия, примерно у 99% украинских читателей хабры есть спецсредство в виде мобильного телефона. Будьте осторожны!
Детали дела на distributed.org.ua/forum/index.php?showtopic=5245
02.03.2012 21:21+0400
Реклама →
Нам не страшен беспредел, или уведомляем родных о неприятностях (iOS)
После недавних выборов в ГосДуму и волны протестов, зимним вечером было создано простое, но полезное iOS приложение, которое мгновенно уведомляет родных и знакомых, что вы в опасности.
Через несколько дней в России выборы, наверняка будет множество акций протеста и RescuePing пригодится многим гражданам.
Основная фишка приложения — отправка сообщений без разблокировки устройства, достаточно просто вытащить шнур наушников и уведомление будет отправлено.
Через несколько дней в России выборы, наверняка будет множество акций протеста и RescuePing пригодится многим гражданам.
Основная фишка приложения — отправка сообщений без разблокировки устройства, достаточно просто вытащить шнур наушников и уведомление будет отправлено.
02.03.2012 16:53+0400
Реклама →
Тренинг по Symfony2 в Украине
Хорошие новости для Symfony2 разработчиков, а так же для тех, кто хочет познакомиться с этим фреймворком поближе.
Вскоре после открытия офиса в Украине компания KnpLabs объявила о проведении тренингов по Symfony2.
Первые тренинги состоятся уже совсем скоро в Киеве (15-16 марта) и Харькове (29-30 марта).
Не может не радовать и философия тренинга: Меньше разговоров — больше кода!
Вскоре после открытия офиса в Украине компания KnpLabs объявила о проведении тренингов по Symfony2.
Первые тренинги состоятся уже совсем скоро в Киеве (15-16 марта) и Харькове (29-30 марта).
Не может не радовать и философия тренинга: Меньше разговоров — больше кода!
02.03.2012 13:31+0400
Язолъ →
Google+ такой Google+
Думаю на хабре многие пользуются google+. Я тоже пользовался им в основном для расшаривания из google reader. Но в один прекрасный момент я обнаружил, что google заблокировал мой аккаунт. Ну хорошо, я пошел почитал политику чего можно размещать. Подивился, что нельзя размещать даже для ограниченного круга лиц или для себя некоторые вещи (в соглашении про это ни слова), убрал. Нажал кнопку проверить по новой. Блок изменился и там появилась следующая информация:
Подождал я значит несколько дней. И профиль опять вернулся в заблокированное состояние и… собственно никакого письма я не получил. Хорошо повторил операцию три раза. Никакой реакции. Нашел кнопку google отклики. Нажал описал ситуацию. Прошла неделя. Профиль находится все в том же состоянии заблокирован, письма нет. В ответ на отклик ничего не пришло. Что еще больше из всего этого радует кнопки написать в суппорт на странице google+ нет. Хорошо идем в интернеты и ищем по этой же проблеме. Видимо что проблема имеется и как-то судя по всему не решается.
Ну что я могу по этому поводу сказать? Отлично работаете господа из Google. Мало того что политики странные, так еще и концов не найти. А еще пытаетесь сопоставить google+ как альтернативу facebook.
Если профиль пройдет проверку, мы снова откроем к нему доступ. Если нет – на ваш адрес электронной почты будет отправлено письмо о том, что запрос отклонен и профиль все еще заблокирован. В этом случае вам потребуется внести в него дополнительные изменения и отправить на повторное рассмотрение.
Подождал я значит несколько дней. И профиль опять вернулся в заблокированное состояние и… собственно никакого письма я не получил. Хорошо повторил операцию три раза. Никакой реакции. Нашел кнопку google отклики. Нажал описал ситуацию. Прошла неделя. Профиль находится все в том же состоянии заблокирован, письма нет. В ответ на отклик ничего не пришло. Что еще больше из всего этого радует кнопки написать в суппорт на странице google+ нет. Хорошо идем в интернеты и ищем по этой же проблеме. Видимо что проблема имеется и как-то судя по всему не решается.
Ну что я могу по этому поводу сказать? Отлично работаете господа из Google. Мало того что политики странные, так еще и концов не найти. А еще пытаетесь сопоставить google+ как альтернативу facebook.
02.03.2012 08:15+0400
Звуки музыки →
Создание задач 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
Ссылки
Бинарники
Исходники
01.03.2012 23:21+0400
Песочница →
Радикальное кеширование в Joomla 1.5
Бесплатная CMS это всегда компромисс, компромисс между целым рядом очевидных факторов, перечислять которые в рамках данного ресурса смысла пожалуй нет, т.к. они всем давно известны. Безусловно, среди всего разнообразия бесплатных СМS можно выделить некоторые, которые будут лучше или хуже в каких-то отдельных номинациях, вроде скорости работы, простоты освоения новичком и т.п. Но в данной статье речь не об этом. Я просто хочу поделиться опытом успешного решения проблемы скорости генерации страниц в Joomla с помощью кеширования. Причём кеширования очень радикального, на «уровне» index.php.
Хочу сразу отметить, что сие повествование не является каким-то принципиальным новшеством, и я не претендую на какие-либо лавры. Надеюсь, моё решение поможет хотя бы кому-то продлить «малой кровью» жизнь старого проекта на Joomla.
01.03.2012 13:45+0400
freelance →
Мотивация от лукавого
На сегодняшний момент, мой рабочий процесс построен на двух взаимодействующих между собой потоках, один для души другой для тела.
01.03.2012 00:28+0400
Реклама →
[50] Еженедельный подкаст Appleinsider.ru с Алексом Пацаем (@alexmak)
Здравствуйте, читатели Хабрахабр!
Подписка: iTunes | RSS | MP3
AppleInsider.ru: Пятидесятый выпуск.
- В гостях Алекс Пацай (@Alexmak)
- Новый iPad нам покажут 7 марта
- Приложение AppleInsider.ru доступно для WP7
- Google представила новый жест поиска
- Тим Кук о выплате дивидендов акционерам Apple и дроблении акций
- У половины владельцев iPhone 4S отношения с Siri не заладились
- Nokia берет мегапикселями
- Apple напоминает пользователям MobileMe о сроке миграции в iCloud
- … и другие темы
Подписка: iTunes | RSS | MP3
прослушан 15 раз
29.02.2012 21:32+0400
Реклама →
Простой сервис уведомлений через Twitter
Twitter уже для многих людей стал повседневным средством общения и получения информации. Лично я каждый день открываю его по несколько раз с телефона, да и на десктопе клиент запущен постоянно.
Возникла идея, что неплохо бы получать через него какие-то напоминания, раз уж я пользуюсь им каждый день.
За вечер был написан небольшой бот для напоминаний.
29.02.2012 16:11+0400
Песочница →
Централизованный syslog
Привет. В виду растущего количества серверов которые админю, и всяких других девайсов (ротуреры, IP телефоны и тд.) в своей IT инфраструктуре, появилась необходимость собирать логи в одном месте и иметь более-менее читабельный интерфейс для их вывода. Возможно я изобретаю велосипед, но в то время не удалось нагуглить по-быстрому чего нибудь подходящего, да и самому захотелось что нибудь сотворить.
28.02.2012 19:49+0400
Реклама →
История о Панде и iOS
Идея
Идея создания игры нам с коллегой пришла еще в конце 2009 года. Даже не идея, а желание создать игру под мобильную платформу. Так сказать попробовать силы создать законченный продукт и продать его.
28.02.2012 19:21+0400
Язолъ →
Страница логина в админку сайта горсовета Днепропетровска
Программистам не доплатили?
28.02.2012 18:50+0400