Как написать свою систему учета рабочего времени

в 9:10, , рубрики: Google Chrome, Анализ и проектирование систем, Блог компании Kickidler, контроль сотрудников, Программирование, разработка под windows, разработка систему учета, система контроля сотрудников, система учета рабочего времени, учёт рабочего времени

Как написать свою систему учета рабочего времени - 1

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

Некоторым везёт и из под их пера клавиатуры выходит нечто очень востребованное типа MASQRD. Но прикольных идей и возможностей для их реализации на всех, увы, не хватает.

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

На мой взгляд, создать свою систему учета — весьма неплохой бизнес потому что:

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

Предвижу следующие возражения...

  • «Да я лучше всю жизнь наёмным программером буду работать, чем сделаю систему, которая людей контролирует». Работайте, лично я не против :) Сам такой. А есть люди, которые очень хотят свой бизнес, пусть маленький, но свой. И учет рабочего времени — не самый плохой рынок.
  • «Контролировать сотрудников непорядочно».Хочу напомнить, что системы учета контролем не занимаются. Они больше дают лишь базовую информацию о поведении сотрудников. Поэтому служба безопасности купить себе что-то более функциональное.
  • «Этих систем на рынке уже так много, что моя не будет продаваться». Народ, вы представляете себе бабку, которая пришла продавать яблоки на рынке, увидела, что там уже 10 бабок стоят, развернулась и пошла домой? Всё может продаваться, даже Офисметрика продаётся, а она уж совсем непонятно из чего и как сделана, интерфейс образца 2000, нормальной поддержки нет. И всё равно кто-то да покупает!
  • «У меня нет опыта продвижения и продажи софта». Угу, а когда-то не было опыта программирования. И ничего, пришел опыт. Про само продвижение напишу кратко чуть ниже, а если будет интерес, то опрошу наших продвижение и сделаю отдельный пост.

Очень кратко (и спорно) о продвижении

  • Делаете сайт. Посмотрите на сайт существующих систем — они все похожи как братья близнецы. Понятно почему — функционала почти нет, остается только рассказывать о пользе для клиента. Разве вы (или недорогой копирайтер) такое же не сможет написать?
  • Поддержку осуществляете по электронной почте и форуме без отрыва от основной работы время.
  • Появятся свободные деньги — вложите их в рекламу (лучше Adwords)

Для начала немного теории

Система учета рабочего времени (далее СУРВ) решает следующие задачи:

  1. определяет в каких сайтах и программах работал пользователь на ПК;
  2. категоризует затраченное на эти активности время как продуктивное или непродуктивное;
  3. предоставляет собранную информацию в виде отчетов сотруднику или его руководителю.

СУРВ состоит из следующих компонентов:

  • Агент — компактный код, устанавливается на каждый компьютер в организации. Занимается сбором информации и отправкой её на сервер. Обычно скрыт для пользователя, но в некоторых случаях выполняет активные действия, такие как запрет на открытие определенный web-сайтов или просьбу указать чем сотрудник занимался во время простоя ПК.
  • Сервер — выполняет две основные функции: получает данные от агентов и формирует web-интерфейс для отображения отчётов. Сервер может быть расположен в облаке или внутри организации. Облачный сервер обслуживает большое количество клиентов.
  • База данных — хранит собранные сервером данные и предоставляет из серверу же для генерации отчетов. Для ускорения формирования отчётов данные периодически пресуммируются. Обычно используются классические SQL RDBMS, но в редких случаях разработчики экспериментируют с NoSQL (обычно MongoDB).
  • Административная консоль

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

Активная программа / сайт — означает, что в данный промежуток времени именно это окно программы / браузера было активным на рабочем столе сотрудника и человек в указанный промежуток выполнял какие-либо действия: нажимал на клавиши или двигал мышкой.
То есть мы не считаем рабочим время, когда человек открыл программу и ушёл гулять.

Активность определяется очень просто. После действия пользователя (мышь или клавиатура) в течении ХХ секунд (обычно 60-300), считается что он был активен. если по истечении этого времени других действий не было произведено, то устанавливается состояние неактивности.

Как передавать собранные данных

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

Плюсы REST заключаются в простоте реализации. С помощью того же Swagger можно без лишних усилий и интерфейс спроектировать и скелет кода получить. Учитывая, что с агента на сервер передаются небольшие объемы данных (учет рабочего времени не контроль сотрудников, файлы не перехватывает и видео не передаёт), то JSON для этой цели замечательно подходит. К тому же https как транспорт для REST пройдёт через файрволы и прокси к облачному серверу.

Тем не менее, большинство разработчиков СУРВ предпочитает тратить силы и время изобретая собственные протоколы, прикручивая к ним шифрование и аутентификацию. Ну да ладно, каждому своё.

Какие данные должны передаваться с агента на сервер?

Поскольку вся категоризация рабочего времени и агрегация промежуточных результатов происходят на сервере, то агент достаточно передавать информацию об одном-единственном типе события: с ХХ часов ХХ минут по с ХХ часов ХХ минут для пользователя NNN активной была программа YYY / сайт ZZZ.

И это всё. Нет, правда всё. Остальное считается на сервере. Мне кажется, ровно с этого момента должно придти понимание, что весь этот учет времени — это очень просто. Что если все ваши будущие «конкуренты», перечисленные в обзоре в самом начале статьи (как и три десятка не перечисленных), сделали свои системы «на коленке», то и вы сможете. Что тут нет никаких секретов и тайных практик.

Как работает агент

Переходим к самому интересному. Можно создать мощный сервер с карамельно-ванильным интерфейсом отчётов, но если агент тормозит и вешает компьютеры сотрудников, то продукт пойдёт единственно возможным путём — в топку. (Лично знаю несколько таких систем на данном рынке, которые бодро начали и в корчах померли именно по этой причине).

Итак, агент должен определять четыре вещи:

  1. Системное имя текущего пользователя.
  2. Активен ли сейчас пользователь.
  3. В какой программе работает пользователь (имя запускаемого файла и заголовок). Если это браузер, то...
  4. На каком сайте сейчас пользователь.

Имя пользователя передаётся потому что на одном ПК может работать несколько человек, а нам нужно учитывать активность конкретного сотрудника, а не компьютера.
Делаем так:

#include <windows.h>
#include <Lmcons.h>

char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);

Активность выясняется просто. На мышь и клавиатуру вешается глобальный хук (неплохой пример использования, например, здесь).
После срабатывания хука флаг активности устанавливается в true и запускается таймер на ХХ секунд. По срабатыванию таймера флаг активности сбрасывается в false.

Теперь получаем информацию о заголовке активного окна и exe-файле его породившем.
Заголовок можно получить так (пример полностью здесь):

#include <windows.h>
#include <string>
using std::string;

string GetActiveWindowTitle()
{
 char wnd_title[256];
 HWND hwnd=GetForegroundWindow(); // get handle of currently active window
 GetWindowText(hwnd,wnd_title,sizeof(wnd_title));
 return wnd_title;
}

А наименование процесса получаем так (пример полностью здесь):

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
 
BOOL GetProcessName( DWORD processID, TCHAR* szProcessName)
{
    BOOL bRC = FALSE;
    // Get a handle to the process. 
    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );
    // Get the process name.
    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;
        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName, MAX_PATH );
            bRC = TRUE;
        }
    }
    CloseHandle( hProcess ); 
    return bRC;
}

Сложнее всего получить информацию о текущей активной странице в браузере. И вот почему.

Изо все браузеров, только Internet Explorer / Edge имеет API, показывающее информацию о текущем URL. Так что в случае с осликом всё было легко и просто — только функцию вызвать.
Но давно ушли времена, когда IE был главным браузером на ПК, теперь на большинстве компьютеров властвует Google Chrome вместе с Firefox / Opera / много кто ещё. А у них API отсутсвует, вызывать нечего… Как быть?

Самые простые программы обратили свой взор к браузерному файлу истории. Парсили его и сопоставляли время и URL. Работало так себе…

Потом создатели более продвинутых систем учета времени пытались обращаться напрямую к элементам управления окна браузера, находить там поле ввода URL и извлекать оттуда информацию. Всё шло хорошо, пока Google не переписал движок Chrome (на котором помимо самого Хрома, основан ряд других браузеров). Теперь никаких системных полей ввода не используется, все элементы управления реализует сам движок. Снова тупик…

И тут на помощь самым продвинутым пришла подсистема помощи людям с ограниченными возможностями. Стандартная подсистема Windows умеет моделировать голос и прочитывать слабовидящим содержимое различных полей на экране. В том числе… да, поля ввода URL. А значит информацию из этого поля можно получить с помощью Accesibility API.

Лучший из существующих примеров реализации этого подхода написан на AutoHotKey, но портировать его на C++ сможет каждый.

Как работает сервер

Стоп… У нас с вами получился уже достаточно объемный текст. Поэтому про сервер мы поговорим в следующий раз (начнём именно с этого места ;) )

Автор: Kickidler

Источник

Поделиться

* - обязательные к заполнению поля