Pull to refresh
1
0
Олег Гракело @killest

User

Send message

О размере экрана, пикселя и элемента

Reading time9 min
Views196K


Привет, username. Свой первый пост я хочу посвятить актуальной проблеме, связанной с появлением большого количества новых форматов дисплеев и непрекращающейся гонкой за плотностью пикселей. В свете появления таких устройств, как очки дополненной реальности, смартчасов, 4к-мониторов и еще более широкого спектра планшетов и ноутбуков, возникает вопрос: какой размер графического элемента/текста следует считать оптимальным и в чем его измерять. Android-разработчики, несомненно, тут же воскликнут: «Да, конечно, в dp!». Но практика показывает, что дела обстоят несколько сложнее.
Читать дальше →

Как мы написали helpdesk

Reading time6 min
Views123K
Есть продукты, которые можно взять и использовать, но с небольшой модификацией «под себя». Так вот система заявок или helpdesk как раз к таким вещам не относится. Точнее, мы для себя не нашли подходящий продукт и решили сделать сами.


Читать дальше →

Правильный подход к использованию API Вконтакте

Reading time5 min
Views99K
Привет, Хабр!

В своё время, бороздя просторы интернета на предмет рационального использования API Вконтакте, я не смог найти чего-то вразумительного, единственные библиотеки, которые были найдены мной были реализованы без использования каких-либо общепринятых практик и без красивого кода. Я решил исправить, сложившееся недоразумение и написал свою библиотеку для работы с API Вконтакте.
Животрепещущие подробности и подходы под хабракатом.
Читать дальше →

Работа с usb видеокамерой в Linux. Часть 1

Reading time4 min
Views37K
   По популярности видеокамера, сегодня, стоит в одном ряду с микрофоном и наушниками. Она используется в различных направлениях, таких как распознавание объектов, дополненная реальность, видеоконференции и множество других. Но что же скрыто под капотом этих сложнейших программ? Как мы получаем картинку с видеокамеры? Этот цикл статей позволит взглянуть на простоту работы с видеокамерой на низком уровне, обработку полученного изображения.
Читать дальше →

Очень простой способ обработки ajax запросов в MODx Revolution

Reading time3 min
Views31K
Все привет, много уже было написано про обработку ajax запросов на фронтенд части сайта в MODx Revolution, есть даже несколько готовых дополнений.
В свою очередь, я хочу предложить ещё один, очень простой способ обработки ajax запросов в MODx Revolution.
И так, приступим

Как сверстать веб-страницу. Часть 2 — Bootstrap

Reading time19 min
Views699K

Введение


Уважаемый читатель, эта статья является второй частью цикла статей, посвященных вёрстке.

В первой части мы верстали шаблон Corporate Blue от студии Pcklaboratory с помощью стандартных средств на чистом HTML и CSS. В данной статье мы попробуем сверстать этот же шаблон, но с помощью CSS фреймворка Bootstrap 3.
Читать дальше →

Компонент Tickets — пользовательские страницы и комментарии

Reading time3 min
Views17K
Давно не писал ничего на Хабре — был по уши занят. За это время многое сделано, но еще больше в планах. А вот вчера выпустил новый компонент Tickets, для создания системы техподдержки. Понятно, только в MODX Revolution.

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

В процессе работы оказалось, что систему, в общем-то, можно использовать и для сайтов с user-generated content, типа простенького LiveStreet (видео с демонстрацией работы в конце поста).
Читать дальше →

Обзор бесплатных сервисов для веб-разработки

Reading time4 min
Views144K
Пост является личной подборкой полезных и нужных онлайн сервисов, которые позволяют бесплатно (или условно бесплатно) создавать действительно крутые вещи и разворачивать их в Сети. Не претендую на новизну или на полноту, но буду счастлив, если кому пригодится.

Всем нам иногда хочется попробовать новую идею, запилить какой-нибудь сайтик про манулов, но чтоб обязательно на node.js, хайлоад реди, с мемкешем, монго, фейловером и с претензией на мировое господство. У меня для Вас хорошие новости: благодаря щедрости проклятых западных капиталистов всё это можно получить совершенно бесплатно.
Читать дальше →

Резервное копирование веб-проектов на Яндекс.Диск

Reading time14 min
Views38K
В далекие детские годы я не понимал важность резервного копирования данных. Но, как говорится, понимание приходит с опытом. Зачастую опыт бывает очень горький. В моем случае хостинг два раза убивал базу сайта MathInfinity, созданного еще в студенческие годы.

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

Идея создания архивов на сервисах вроде Dropbox, Ubuntu One, Яндекс Диск, Диск Google и др. уже давно притягивала мое внимание. Десятки гигабайт бесплатного места, которое теоретически можно использовать для резервирования данных.

Теперь эта идея получила мое первое воплощение. В качестве сервиса для создания архивов был выбран Яндекс Диск.
Читать дальше →

Набор социальных иконок

Reading time1 min
Views133K


Доброго времени суток! Сегодня я хочу поделиться шестью наборами социальных иконок ICON.PACK, которые отрисовал на днях. Все иконки разбиты на 6 групп, отличающихся по форме.
Лицезреть иконки

60 FPS? Легко! pointer-events:none!

Reading time2 min
Views99K


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

.hover .element:hover {
  box-shadow: 1px 1px 1px #000;
}
Читать дальше →

Сервис для логов за 5 минут

Reading time2 min
Views15K
Во время разработки под мобильные устройства появилась проблема наблюдать и сравнивать несколько характеристик производительности и параметров на разных устройствах. (iPad/Samasung Galaxy Note 10.1/Nexus и т.д.). Можно было бы просто записывать логи в файл, потом свести их воедино, но хочется, чтобы информация с устройств поступала сразу после отладки в единую таблицу, да и не все устройства находятся у разработчиков на руках.

Единственным быстрым решением, приходящим на ум, был небольшой сервис на flask/bottle, но для этого пришлось бы поднять хранилище данных. Сказать честно, даже использование облачных решений на Azure/Heroku/AWS — это небольшая кучка дополнительных проблем для такой простой задачи: пароли, пути, зависимости и т.д. Нам же надо вести одну небольшую таблицу с несколькими параметрами, которые поступают с устройств. К тому же, данная утилита требовалась исключительно для удобства разработки, а не для продуктивного использования с тысячами пользователей.

Я постоянно записываю в свою базу знаний в Evernote различные хаки для повседневных задач, и недавно нашел там пример кода из какого-то open source проекта, где идет обращение с формой Google Docs через post запросы. И понеслось.
Читать дальше →

Памятка пользователям ssh

Reading time13 min
Views1.6M
abstract: В статье описаны продвинутые функций OpenSSH, которые позволяют сильно упростить жизнь системным администраторам и программистам, которые не боятся шелла. В отличие от большинства руководств, которые кроме ключей и -L/D/R опций ничего не описывают, я попытался собрать все интересные фичи и удобства, которые с собой несёт ssh.

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

Оглавление:
  • управление ключами
  • копирование файлов через ssh
  • Проброс потоков ввода/вывода
  • Монтирование удалённой FS через ssh
  • Удалённое исполнение кода
  • Алиасы и опции для подключений в .ssh/config
  • Опции по-умолчанию
  • Проброс X-сервера
  • ssh в качестве socks-proxy
  • Проброс портов — прямой и обратный
  • Реверс-сокс-прокси
  • туннелирование L2/L3 трафика
  • Проброс агента авторизации
  • Туннелирование ssh через ssh сквозь недоверенный сервер (с большой вероятностью вы этого не знаете)
Читать дальше →

Перенос Google Chrome на RAM-диск в Linux

Reading time3 min
Views84K
Опишу простой способ переноса кеша, настроек и прочих локальных данных Google Chrome на RAM-диск в Linux. Это ускорит скорость работы браузера и исключит насилие над диском (что особенно критично, если у вас SSD).

Статья не содержит ничего интересного для более-менее продвинутых пользователей Unix-like систем. Совсем ничего.

Читать дальше →

Продающий дизайн интернет-магазина. Часть 2. Элементы интерфейса

Reading time7 min
Views74K
Вторая часть статьи из цикла «Продающий дизайн интернет-магазина». Для тех, кто пропустил первую, её можно прочитать тут: «Продающий дизайн интернет-магазина. Часть 1. Аналитика». Сегодня я расскажу про разные части интерфейсов магазинов, которые важны для конверсии и продаж. Постараюсь обозначить какие элементы должны быть в шапке и футере сайта, на главной странице, на странице каталога и многое другое.

Логотипы крупнейших интернет-магазинов
Читать дальше →

Готовая сборка интернет-магазина на MODX Revolution

Reading time10 min
Views109K
Часто, когда разработчик выбирает движок для очередного магазина, он обычно оценивает этот вопрос по нескольким критериям:
  • Платный/бесплатный (если платный, то сколько).
  • Какой функционал есть «из коробки».
  • Насколько легко докрутить какой-то свой функционал.
  • Как много он потянет товаров, чтобы на хостинг не разориться.
  • Насколько гибкие политики безопасности, чтобы обеспечить совместную работу различных отделов.
  • Какие платежные системы поддерживаются.

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

В конце статьи видео с кратким обзором движка и двумя способами установки

Важно!!! Забыл сказать: кто поленится посмотреть видео, но развернет у себя сборку, логин/пароль в админку по умолчанию: admin/admin.


Демо-сайт.


Прежде чем читать дальше, советую покликать демо-версию сборки.

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

Основа движка (а так же довольно большая предыстория)


За основу был взят фреймворк MODX Revolution. Только не торопитесь плеваться и закрывать страницу. Это не в точности тот MODX, с которым вам возможно приходилось встречаться. Я с MODX работаю с начала 2009-го года, и знаю его вдоль и поперек. И да, я как и многие сталкивался со многими его минусами (типа шаблонов и чанков в базе данных, тормоза и т.п.). Плюс к этому до знакомства с MODX много работал с различными самописками и другими движками, и на MODX-е я остался именно за его гибкость. Да, мне не все в нем нравится, но он позволяет с легкостью многое в нем изменить, при этом не трогая самого ядра. В процессе у меня появилось несколько компонентов, которые дополняют или меняют определенный функционал MODX-а. Вот парочка наиболее важных из них:
phpTemplates — позволяет статические MODX-шаблоны вызывать как обычные php-файлы.
modxSmarty — Подключает для фронта шаблонизатор Smarty и дополняет его некоторыми плюшками, обеспечивая тесное взаимодействие с самим MODX-ом.
shopModx — модуль для разработки интернет-магазинов.

В итоге MODX обретает не только полноценную шаблонизацию, но и гораздо бОльшую производительность. Сайты с десятками тысяч документов работают с откликом 0,02 — 0,6 секунд. Плюс к этому можно практически полностью забить на синтаксис самого MODX-а, и если вы умеете программировать на php и знаете Smarty — то здесь в разработке у вас никаких проблем не возникнет.

Но одна из самых важных вещей в MODX-е, которая точно меня держит цепями — это система пакетов (модулей для MODX-а). Она реально классная. Я даже написал модуль, который позволяет создавать свои собственные репозитории пакетов. Это особенно полезно различным веб-студиям и активным разработчикам. При этом самая вкусняшка заключается в том, что упаковывать можно не только отдельные модули, но и вообще все что угодно на сайте, хоть целиком, хоть по отдельности, хоть весь сайт вообще. Так появились снапшоты MODX-сайтов. Изначально это было реализовано только на самом modxcloud.com (официальный хостинг от разработчиков MODX-а), но совершенно без документации и каких-либо релизов ими был выложен скрипт vapor, который предназначался для того, чтобы любой мог сделать снимок своего сайта и закинуть его на modxcloud.com. При этом обратная связь как бы и не подразумевалась (то есть брать снимки с modxcloud.com и разворачивать на любом своем хостинге). Не буду вдаваться в подробности, но я взял этот vapor, модифицировал его и добавил ему еще один скрипт (import.php). Теперь с помощью этого скрипта можно как делать снимки сайтов, так и разворачивать их поверх чистого сайта. Скачать мой vapor можно из официального репозитория. И вот как раз с этим вапором я взял курс не только на отдельные модули, но и на готовые сборки сайтов.

В чем смысл таких сборок?

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

Что уже есть в этой сборке?


  • Добавлен компонент Billing. На этом модуле завязано все, что связано с заказами, оплатой и т.п.
  • Корзина перестала существовать отдельно. Теперь Корзина — это еще не оформленный Заказ (Order). Теперь даже не оформленные заказы хранятся в базе данных, что как минимум позволяет видеть кого что интересует, а так же определять реальный процент конверсии и выявлять возможные ошибки.
  • Компонент Basket (Корзина) остался, но почти все, что связано с самими заказами, перенесено в Billing. Basket и дальше останется отдельным модулем, а в Billing-е будет только необходимый минимум логики. Рассчет на то, что сам механизм заказа, оплаты и т.п. можно будет реализовывать в любых сторонних модулях, которые будут взаимодействовать с биллингом.
  • Добавлен и сверстан новый шаблон по умолчанию с использованием bootstrap. Много всяких аджаксовых плюшек и полноценное JS-API.
  • Добавлен табличный редактор документов.
  • Добавлено управление заказами.
  • Добавлен личный кабинет пользователя, регистрация, смена пароля, восстановление пароля и т.п.
  • Настроена регистрация через Login, смена/восстановление пароля и т.п.
  • Добавлен модуль modHybridAuth (авторизация через социальные сети). Пока четко проверены Twitter, Facebook и Google, но должны и другие работать.
  • Подключен сервис оплаты Robokassa.
  • Настроены политики безопасности:
    • Контент-менеджер;
    • Администратор магазина;
    • Менеджер магазина;
    • Продвинутый менеджер магазина.



Что дальше делать с этим сайтом после установки?


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

Пример, как добавлять еще платежные системы

Вот у нас есть оплата через робокассу, и стоит задача прикрутить еще какой-нибудь способ оплаты. Посмотрим, как это делается.

Это базовый процессор для любых типов оплаты.
<?php

/*
    Абстрактный класс на проведение оплаты.
    Его нельзя вызывать напрямую, чтобы исключить случаи инжекта оплаты. 
    Этот класс должен расширяться другим классом конкретной платежной системы,
    чтобы использовать методы проверки платежа самой платежной системы
*/

abstract class modWebPaymentsCreateProcessor extends modObjectCreateProcessor{
    public $classKey = 'Payment';
    
    protected $BillingProcessorsPath;
    
    public function checkPermissions() {
        
        // Проверяем подпись платежной системы
        $ok = $this->checkSignature();
        if($ok !== true){
            $this->error($ok);
            return false;
        }
        
        return parent::checkPermissions();
    }
    
    public function initialize(){
        
        $this->BillingProcessorsPath = MODX_CORE_PATH . 'components/billing/processors/';
        
        $this->setDefaultProperties(array(
            'currency_id'  => $this->modx->getOption('shopmodx.default_currency'),
        ));
        
        if(!$this->getProperty('paysystem_id')){
            return $this->error("Не был получен ID платежной системы");
        }
        
        return parent::initialize();
    }
    
    public function beforeSet(){
        
        $this->setProperties(array(
            "createdby" => $this->modx->user->id ? $this->modx->user->id : null,
            "date"      => time(),
        ));
        
        return parent::beforeSet();
    }
    
    public function beforeSave(){
        if(
            !$currency_id = (int)$this->getProperty('currency_id')
            OR !$currency = $this->modx->getObject('modResource', $currency_id)
            OR ! $currency instanceof ShopmodxResourceCurrency
        ){
            return $this->error("Не был получен объект валюты");
        }
        
        if(
            !$paysystem_id = (int)$this->getProperty('paysystem_id')
            OR !$paysystem = $this->modx->getObject('Paysystem', $paysystem_id)
            OR ! $paysystem instanceof Paysystem
        ){
            return $this->error("Не был получен объект платежной системы");
        }
        
        // Проверяем, если указан счет платежной системы, то надо убедиться, что 
        // он еще не числится в биллинге
        if($paysys_invoice_id = $this->object->get('paysys_invoice_id')){
            if($this->modx->getCount($this->classKey, array(
                'paysys_invoice_id' => $paysys_invoice_id,
                'paysystem_id'      => $paysystem_id,
            ))){
                return $this->error("Данный счет уже создан в системе.");
            }
        }
        
        $this->object->addOne($currency);
        $this->object->addOne($paysystem);
        
        return parent::beforeSave();
    }
    
    /*
        Обязательно надо прописывать метод, в котором будет выполняться проверка 
        подписи с сервера платежной системы
    */
    abstract protected function checkSignature();
    
    protected function log($msg, $level = null){
        if($level === null){
            $level = xPDO::LOG_LEVEL_INFO;
        }
        $this->modx->log($level, "[Basket - ".__CLASS__."] {$msg}");
        $this->modx->log($level, print_r($this->getProperties(), true));
        return $msg;
    }
    
    protected function error($msg){
        return $this->log($msg, xPDO::LOG_LEVEL_ERROR);
    }
    
    /*
        Логируем все ошибки процессора, на всякий случай
    */
    public function failure($msg = '',$object = null) {
        $this->error($msg);
        if(!empty($this->object) && is_object($this->object)){
            $this->error(print_r($this->object->toArray(), true));
        }
        return parent::failure($msg,$object);
    }
    
    public function cleanup() {
        /*
            // Если оплата прошла успешно, то обновляем статус заказа
        */
        if($order_id = $this->object->get('order_id')){
            $this->modx->runProcessor('mgr/orders/status/pay', array(
                'order_id'  => $order_id,
            ), array(
                'processors_path' => $this->BillingProcessorsPath,    
            ));
            // На всякий случай сбрасываем счетчик ошибок, если вдруг в вызываемом
            // процессоре были ошибки
            $this->modx->error->reset();
        }
        
        return $this->success($this->getSuccessMessage(), $this->object);
    }
    
    protected function getSuccessMessage(){
        return '';
    }
}

return 'modWebPaymentsCreateProcessor';


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

А вот расширяющий процессор конкретно для робокассы:
<?php
/*
    Проводка платежа от робокассы
*/

require_once dirname(dirname(__FILE__)). '/create.class.php';

class modWebPaymentsRobokassaCreateProcessor extends modWebPaymentsCreateProcessor{
    
    public function initialize(){
        
        $this->setProperties(array(
            "paysystem_id"  => $this->modx->getOption('robokassa.bill_serv_id'),
        ));
        
        return parent::initialize();
    }
    
    /*
        Проверяем подпись с робокассы
    */
    protected function checkSignature(){
        
        $mrh_pass2 = $this->modx->getOption('robokassa.mrh_pass2');

        // Параметры, передаваемые в запросе от робокассы
        $crc        = mb_strtoupper($this->getProperty('SignatureValue'));
        $out_sum    = $this->getProperty('OutSum');
        $inv_id     = $this->getProperty('InvId');
        $shp_aid    = $this->getProperty('shp_aid'); 
        $shp_order  = $this->getProperty('shp_order', null);
        $shp_trff   = $this->getProperty('shp_trff');
        $shp_uid    = $this->getProperty('shp_uid');
         
        $my_crc = mb_strtoupper(md5("{$out_sum}:{$inv_id}:{$mrh_pass2}:shp_aid={$shp_aid}:shp_order={$shp_order}:shp_trff={$shp_trff}:shp_uid={$shp_uid}"));
        
        $this->modx->log(xPDO::LOG_LEVEL_INFO, "[Robokassa - robokassa.payResult]", print_r($_REQUEST, true));
        
        // проверка корректности подписи
        if ($my_crc !=$crc){
            $error = "[Robokassa - robokassa.payResult] - Неверная подпись. Получена: '{$crc}'. Должна быть: '{$my_crc}'";
            $this->modx->log(xPDO::LOG_LEVEL_ERROR, $error);
            return "bad sign";
        } 
        
        // else
        $this->setProperties(array(
            "sum"               => $out_sum,  
            "order_id"          => $shp_order,  
            "owner"             => $shp_uid,
            "paysys_invoice_id" => $inv_id,
        ));
        
        return true;
    }
    
    protected function getSuccessMessage(){
        return 'OK'.$this->getProperty('InvId');
    }    
}


Как видно, это всего 60 строчек кода. Но в результате не только будет проведена оплата с учетом кто платил, через что, сколько и т.п., но и будет автоматически изменен статус заказа на Оплачен. И вот прикрутить еще какой-нибудь способ оплаты — это всего несколько десятков строк.

Итоги


В итоге, получился на самом деле очень не плохой движок. Сразу скажу, что помимо гибкости, производительность у него тоже весьма не плохая. Как раз недавно наткнулся на топик, в котором народ рассуждал, что даже 40 000 товаров уже напрягает не хило их магазины. Я делал магазины на shopModx с десятками тысяч товаров без всяких особых ухищрений, и все нормально работает. И даже если товаров будут сотни тысяч (я уже делал один на 150 000 товаров), то с небольшими доработками магазин и столько потянет.

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

И напоследок видео с кратким обзором движка и двумя способами установки.
Читать дальше →

PickMeUp — хороший jQuery datepicker plugin

Reading time13 min
Views101K

Проблема


Начиная работу над очередным сайтом понадобился datepicker. Самый известный такой datepicker — в jQuery UI, но так как jQuery UI в проекте не использовался — тянуть даже его часть не хотелось, принялся за поиски достойной альтернативы.

Требования следующие:
  • Выбор даты, нескольких дат, интервала
  • Простота настройки внешнего вида
  • Желательно без каких-либо зависимостей кроме jQuery

Требования вполне логичные, ничего сверх естественного.
Каково было мое удивление, когда просмотрев десятка два плагинов я не нашел подходящего.

Для любопытных — сразу демо того, что получилось в результате.
Читать дальше →

Превращаем статический сайт в мобильное приложение с помощью jQuery Mobile и PhoneGap

Reading time5 min
Views114K

После приобретения телефона на базе Android, возникла задача сделать из сайта brainexer мобильное приложение. Выбор пал на jQuery Mobile и PhoneGap. До этого никаких познаний в обрасти мобильной разработки не было, поэтому пришлось осознать некий пласт новой информации, выжимкой из которого я бы и хотел поделиться. В итоге статья представляет из себя небольшой quick start — как из пачки html файлов получить приложение опубликованное в Google Play.
Читать дальше →

Отправка уведомлений о пропущенных звонках из Asterisk

Reading time5 min
Views40K
В данном посте я расскажу вам о возможностях отправки уведомлений о пропущенных звонках с помощью Asterisk. Я постараюсь привести простые примеры конфигурации и подробнее раскрыть данную тему, далее вы можете экспериментировать по своему усмотрению или потребностям. Asterisk предлагает довольно широкие возможности для решения различных задач, поэтому одну и ту же задачу можно решать по разному, главное результат — стабильная работа ваших сервисов.

Отправка отчета о пропущенном звонке на email



Что имеем:
Входящая многоканальная линия с номером +7 (495) 1234567, IVR, 4 оператора в очереди вызова.

Задачи:
1. Отправлять отчет о пропущенном звонке, с указанием номера звонящего, времени поступления звонка и времени ожидания на линии.
2. Если абонент ждал на линии более 10 секунд и по какой-либо причине положил трубку, не дождавшись ответа оператора — отправляем отчет о пропущенном звонке.
3. Заносить в БД (в текущем примере MySQL) данные о том, какой оператор в очереди ответил звонок и фиксируем время в которое разговор был завершен.

Читать дальше →

Пишем модуль для авторизации в VK API

Reading time5 min
Views94K
На днях возникла необходимость сохранить все фотографии из своего фотоальбома ВКонтакте на жесткий диск. Естественно, вариант, с сохранением фотографий по одной, меня не устроил. Тут вспомнилось, что у ВКонтакте есть API. Пять минут чтения мануалов, и все нужные функции найдены. Единственная проблема – не существует нормального способа, для получения доступа к API. В документации сказано следующее:
Процесс авторизации приложения состоит из 3-х шагов:
  1. Открытие окна браузера для аутентификации пользователя на сайте ВКонтакте.
  2. Разрешение пользователем доступа к своим данным.
  3. Передача в приложение ключа access_token для доступа к API.


На первый взгляд, набросать простенький портабельный скрипт не получится. Хотя, что мешает нам притвориться браузером?
Читать дальше →

Information

Rating
Does not participate
Date of birth
Registered
Activity