misc/class
lib/jquery_pnotify, lib/moment, lib/lodash, misc/notification, site/engine, misc/social
if( $.browser.msie && $.browser.version <= 8 ) include('lib/respond'); $._social.__cfg = {"init":[{"service":"basic"},{"fb_app_id":"1997094873850041","service":"fb"},{"vk_app_id":"2978320","service":"vk"},{"service":"twi"}],"like":[{"service":"fb"},{"service":"vk"},{"via":"","channel":"","hash_tag":"","service":"twi"}]}; window._SiteEngine = new classes.SiteEngine( { user_id: 0, controller: 'homepage', action: 'index', content_css_version: '1459538664', social_enabled: 0} );

Faiwer

Блог web-программиста

Прочее Бесплатная версия Lightworks

5 марта 2016

В поисках замены для OpenShot я наткнулся на Lightworks. В статьях про это ПО указывается, что есть и FREE версия, с урезанным функционалом. Причём без деталей о том, в чём именно этот функционал урезан. Проставил, покопался, склепал элементарный ролик, теперь знаю. Это невозможность экспорта никуда, за исключением прямой заливки видео на Youtube или Vimeo. Т.е. сохранить файл на диск нельзя.

По сути я могу это трактовать только как отсутствие бесплатной версии. Потому что такой вот use case нафиг никому не нужен. Рассматривать Lightworks можно только как альтернативу другим платным профессиональным инструментам. Так что прекратите размещать его в свои обзоры бесплатных видеоредакторов.

Некоторое время назад я попробовал воспльзоваться действительно бесплатным редактором ― Shotcut. Но оказалось, что за красивой обёрткой скрывается ― ничего. Этот редактор не умеет практически ничего. Это даже не редактор, это какое-то недоразумение (ИМХО), если честно. Уж на что OpenShot кажется топорным, но Shotcut переплюнул и его :)

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

IT CLI-скрипты и stdout

5 марта 2016

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

Стандартная библиотека предоставляет ряд методов для запуска сторонних программ. Я перебрал несколько из них, но всё как-то мимо. К примеру при ручном перенаправлении spawn-а за счёт pipe в process.stdout выдачи я не добился. При ручной обработке on('data', нет цветной выдачи и затирания уже отрисованного текста. Ну и т.д. 

Как обычно великий stackoverflow помог:

require('child_process').spawn('ffmpeg',
	[
		'-i', fname,
		'-f', ext,
		'-vcodec', vcodec,
		'-acodec', acodec,
		'-ss', fromS,
		'-to', endS,
		result
	], { stdio: 'inherit' });

Весь рецепт в третьем параметре ― { stdio: 'inherit' }

UPD0. Помимо цветного вывода и затирания текста прекрасно работает пользовательский ввод (пример: ffmpeg спрашивает перезаписать ли сущ-ий файл). Получается, что stdin тоже пробрасывается.

IT IE8 и babel

3 марта 2016

В одном из проектов требуется на уровне ТЗ поддержка Internet Explorer 8. Спасибо, что не 7 :) Дошли руки до перевода кодовой базы на es6. Воткнул как обычно preset es2015, потестил, вроде всё работает, но дёрнул меня чёрт проверить и в старом ослике. Подохло там всё. Причём глюк настолько странный, что я невольно задвигал бровями. Перейду сразу к сути:

function init(){ console.log(1); }
var a = { init: function(){ console.log(2); } };
init();

Результат, конечно же, 1. Однако babel превратит сий код в:

"use strict";

function init() {
  console.log(1);
}
var a = { init: function init() {
    console.log(2);
  } };
init();

Ключевое отличие ― именование метода. Теперь он тоже init. Зачем? Не ко мне вопрос. Может быть для упрощения отладки. Но с этого момента старый ишак возвращает 2. Оказывается это старый баг тогдашнего jscript-а.

Лечение: добавляем: plugins: ["transform-jscript"] к настройкам babel-я. Ну и соответственно тащим этот плагин. С этого момента babel будет генерировать вот таких вот монстров:

"use strict";

function init() {
  console.log(1);
}
var a = { init: function() {
    function init(){ console.log(2); }
    init();
  } };
init();

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

Полёты Чемпионат России и Чемпионат Казахстана 2015

28 января 2016

Запоздало выкладываю небольшой миск моего участия в Чемпионатах России и Казахстана 2015г.

IT Загрузка binary-файла

28 января 2016

Возникла задача ― загрузить с сервера XLSX-файл. Запрос ― POST. Файл, понятное дело, бинарный. На проекте уже подключена jQuery, и, первым делом, я решил воспользоваться её стандартным $.ajax. Сколько не бился ― так и не удалось получить blob-результат от запроса. Использовать же решение через iframe-ы и form-ы тоже не хотелось. Во-первых уж больно костыльно (привет 90-ые). во-вторых нужно будет ещё чудить с передачей параметров POST-запроса (content-type: json). Гуглил-гуглил, но ни одного вменяемого решения (которое не стыдно было бы утащить в проект) я так и не нашёл. Но, т.к. интересует поддержка только последних версий современных браузеров, удалось найти и применить более изящное и функциональное решение. Итак…

  1. Забудем про jQuery и воспользуемся нативным XMLHttpRequest-ом
  2. Указав ему responseType = 'blob'.
  3. Получившийся результат (blob) загоняем в URL.createObjectURL.
  4. В результате получим псевдо-URL ссылку, начинающуюся с "blob:".

Ну а дальше уже по-желанию. Я генерирую новый <a/>-тег, задаю ему нужные аттрибуты download и href (та самая blob-ссылка), вызываю у ссылки .click(). Апосля ссылку удаляю. Проверял в Firefox-е и Chrome-е.

Небольшая заготовка:

function loadBlob(params, data)
{
	return new Promise((resolve, reject) =>
		{
			const xhr = _.assign(new XMLHttpRequest(),
				{
					onload(){ resolve(xhr.response); },
					onerror(e){ reject(e.target.status); }
				});
			xhr.open(params.method || 'POST', params.url);
			xhr.responseType = 'blob';

			const contentType = params.contentType || 'application/json';
			xhr.setRequestHeader('content-type', contentType);

			if(contentType === 'application/json')
				data = JSON.stringify(data);
			xhr.send(data);
		});
}

подробности…