redmine

Added few services

... ... @@ -2,12 +2,87 @@
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Api/AbstractApi.php";
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Api/SimpleXMLElement.php";
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Api/User.php";
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Api/Issue.php";
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Api/Attachment.php";
require_once "lib/3rdparty/php-redmine-api/lib/Redmine/Client.php";
require_once "config.php";
/*
$user_redmine
Array
(
[user] => Array
(
[id] => 17
[login] => AAAnikeyev
[firstname] => Артем
[lastname] => Аникеев
[mail] => AAAnikeyev@mephi.ru
[created_on] => 2014-03-05T06:25:14Z
[last_login_on] => 2014-07-17T11:10:01Z
[api_key] => xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[status] => 1
[custom_fields] => Array
(
[0] => Array
(
[id] => 19
[name] => Отчество
[value] => Андреевич
)
)
[groups] => Array
(
[0] => Array
(
[id] => 7
[name] => отдел юникс-технологий
)
[1] => Array
(
[id] => 55
[name] => группа HPC
)
)
[memberships] => Array
(
[0] => Array
(
[id] => 777
[project] => Array
(
[id] => 102
[name] => *nix hosting request
)
[roles] => Array
(
[0] => Array
(
[id] => 4
[name] => Разработчик
[inherited] => 1
)
)
)
)
)
)
*/
function _tempdir_cleanup($dir) {
# system('rm -rf "'.$dir.'"');
}
... ... @@ -47,6 +122,9 @@ function body_parse($body) {
return $body;
}
$custom_fields = NULL;
$custom_fields_keys = array();
switch ($_GET['file']) {
case 'request/vpn':
$project_id = 1;
... ... @@ -57,21 +135,93 @@ switch ($_GET['file']) {
$memo_subject = 'Запрос на доступ к VLAN через vpn.mephi.ru';
break;
case 'request/nix-hosting':
$project_id = 1;
$project_id = 102;
$memo_subject = 'Заявка на предоставление nix-хостинга';
break;
case 'request/win-hosting':
$project_id = 1;
$memo_subject = 'Заявка на предоставление win-хостинга';
break;
case 'request/voip-softphone':
$project_id = 18;
$memo_subject = 'Заявка на создание учётной записи к softphone';
break;
case 'request/voip3':
$project_id = 124;
$memo_subject = 'Заявка на доступ к систему «Биллинг» IP-телефонии';
break;
case 'request/cps':
$project_id = 109;
// $project_id = 1;
$memo_subject = 'Заявка на доступ к системе учёта рабочего времени';
break;
case 'request/hpc':
$project_id = NULL; //38;
$memo_subject = 'Запрос на учётную запись к vpn.mephi.ru';
// $project_id = NULL; //38;
$project_id = 38;
$memo_subject = 'Запрос на учётную запись к HPC-кластерам';
$custom_fields_keys = array(2 => 'hdd-amount', 3 => 'cpu-amount', 4 => 'subdivision', 5 => 'scientific-director', 6 => 'ram-amount', 7 => 'preffered-login', 8 => 'ic-bandwidth', 16 => 'contact-email');
break;
case 'request/vacation':
$project_id = 118;
$memo_subject = 'Заявление на отпуск';
switch($_GET['vacation-type']) {
case 'main':
$_GET['vacation-type'] = 'ежегодный основной оплачиваемый отпуск';
$_GET['of-vacation'] = 'ежегодного основного оплачиваемого отпуска';
break;
case 'educational':
$_GET['vacation-type'] = 'учебный отпуск';
$_GET['of-vacation'] = 'учебного отпуска';
break;
case 'free':
$_GET['vacation-type'] = 'отпуск без сохранения заработной платы';
$_GET['of-vacation'] = 'отпуска без сохранения заработной платы';
break;
case 'parental':
$_GET['vacation-type'] = 'отпуск по уходу за ребёнком до достижения им возраста трёх лет';
$_GET['of-vacation'] = 'отпуска по уходу за ребёнком до достижения им возраста трёх лет';
break;
}
$time_from = strtotime($_GET['days-from']);
$time_to = strtotime($_GET['days-to']);
$time_diff = $time_from - $time_to;
$days_diff = floor(($time_diff / (3600*24)) + 0.5);
$_GET['days-count'] = ($days_diff + 1);
break;
case 'request/voip-transfer-equipment':
$project_id = 1;//18;
$memo_subject = 'Заявка на передачу телефонных аппаратов в ОСП';
break;
default:
die('unknown memo-type');
}
switch ($_GET['file']) {
case 'request/voip3':
case 'request/cps':
if (empty($_GET['subdiv-code'])) {
if (!empty($_SERVER['HTTP_REFERER'])) {
header('Location: '.$_SERVER['HTTP_REFERER'].'?errmsg='.urlencode('Не указан код подразделения'));
exit(0);
} else
die('"subdiv-code" is not set');
}
$subdivs = json_decode(file_get_contents('https://cps.mephi.ru/?cmd=getsubdivinfo&s_code='.$_GET['subdiv-code']));
$subdiv = $subdivs->result->s0;
$_GET['subdiv-name'] = $subdiv->name;
break;
}
foreach($custom_fields_keys as $id => $key)
$custom_fields[] = array('id' => $id, 'value' => empty($_GET[$key]) ? '0' : $_GET[$key]);
$tempdir = tempdir();
if ($tempdir === FALSE)
... ... @@ -80,62 +230,170 @@ if ($tempdir === FALSE)
exec('cp -a /var/www/ut.mephi.ru/ut-tex/mephimemo "'.$tempdir.'/"');
chdir($tempdir.'/mephimemo');
file_put_contents("request.get", print_r($_GET, true));
ob_start();
print_r($_GET);
$_GET_print_r = ob_get_clean();
#ob_start();
#print_r($_GET);
#$_GET_print_r = ob_get_clean();
$text = '';
$redmine = new Redmine\Client('https://redmine.ut.mephi.ru', REDMINE_LOGIN, REDMINE_PASSWORD);
$redmine_admin = new Redmine\Client('https://redmine.ut.mephi.ru', REDMINE_LOGIN, REDMINE_PASSWORD);
if (!is_null($project_id)) {
$issue = $redmine->api('issue')->create(
array(
'project_id' => $project_id,
'subject' => $memo_subject,
'description' => $_GET_print_r,
/*
if (empty($_GET['date-end']))
$_GET['date-end'] = (date('Y')+1).'-12-31';
*/
foreach (array('fullname' => 40, 'phonenumber' => 20, 'email' => 30, 'appointment' => 40, 'pgp-id' => 12) as $key => $space) {
if (empty($_GET['signer-'.$key]))
$_GET['signer-'.$key] = str_pad('', $space, '_');
if (empty($_GET['user-'.$key]))
$_GET['user-'.$key] = str_pad('', $space, '_');
if (empty($_GET['contact-'.$key]))
$_GET['contact-'.$key] = $_GET['user-'.$key];
}
foreach (array('work-date-end' => 'Срок окончания работ') as $key => $descr) {
$_GET[$key.'-descr'] = $descr.': '.
(
isset($_GET['no-'.$key]) ?
'Бессрочно' :
(isset ($_GET['work-date-end']) ?
$_GET['work-date-end'] :
'__.__.____'
)
);
).'.';
}
foreach (array('ram-amount' => 'GB', 'hdd-amount' => 'GB', 'ic-bandwidth' => 'Gbps') as $key => $descr) {
$_GET[$key.'-descr'] = empty($_GET[$key]) ? '' : $_GET[$key].' '.$descr;
}
$issue_id = $issue->id;
} else {
$issue_id = $_GET['issue-id'];
foreach ($_GET as $key => &$value) {
if (substr($key, -12) == "-other-value")
if ($_GET[substr($key, 0, strlen($key)-12)] == "other")
$_GET[substr($key, 0, strlen($key)-12)] = $value;
$value = str_replace('_', '\_', $value);
}
if (!isset($_GET['date-end']))
$_GET['date-end'] = (date('Y')+1).'-12-31';
if (isset($_GET['user-serialized'])) {
$user_drupal_serialized = base64_decode($_GET['user-serialized']);
$hash = $_GET['user-signature'];
$good_signature = 0;
foreach ($SIGNKEYS as $key) {
if (sha1($user_drupal_serialized.$key) === $hash) {
$good_signature = 1;
break;
}
}
if ($good_signature == 0)
die('Bad signature');
foreach (array('fullname', 'phonenumber', 'email') as $key)
if (!isset($_GET['contact-'.$key]))
$_GET['contact-'.$key] = $_GET['user-'.$key];
$user_drupal = unserialize($user_drupal_serialized);
foreach ($_GET as $key => &$value)
$value = str_replace('_', '\_', $value);
$user_redmine = NULL;
foreach ($redmine_admin->api('user')->all(array('name' => split('@', $user_drupal->user_id)[0]))['users'] as &$_user) {
if (strtolower($_user['login']).'@mephi.ru' == strtolower($user_drupal->user_id)) {
$user_redmine = $redmine_admin->api('user')->show($_user['id']);
break;
}
}
if (is_null($user_redmine))
die('Cannot find user "'.$user_drupal->name.'" in Redmine');
$api_key = $user_redmine['user']['api_key'];
// file_put_contents("/tmp/user", print_r($user_redmine)); die();
$redmine = new Redmine\Client('https://redmine.ut.mephi.ru', $api_key);
} else
$redmine = &$redmine_admin;
$body_template = file_get_contents('template/'.$_GET['file'].'.tex');
$body = body_parse($body_template);
file_put_contents('header.tex', '\mmheader{Начальнику управления информатизации}{Н. Н. Романову}');
switch ($_GET['file']) {
case 'request/vacation':
$header = '\mmheader{Начальнику отдела кадров НИЯУ МИФИ}{}';
break;
case 'request/voip-transfer-equipment':
$header = '\mmfullheader{'.$_GET['subdiv-name'].'}{Начальнику управления информатизации}{Романову Н.Н.}';
break;
default:
$header = '\mmheader{Начальнику управления информатизации}{Н. Н. Романову}';
}
file_put_contents('header.tex', $header);
file_put_contents('body.tex', $body);
file_put_contents('footer.tex', '\mmfooter{'.$_GET['signer-appointment'].'}{'.$_GET{'signer-fullname'}.'}');
file_put_contents('responsible.tex', '\mmresponsible{'.$_GET['contact-fullname'].'}{'.$_GET{'contact-phonenumber'}.'}{'.$_GET['contact-email'].'}');
file_put_contents('responsible.tex', '\mmresponsibleskip');
if (!is_null($project_id)) {
file_put_contents('urlqr.tex', '');
exec('make');
exec('pdftotext memo.pdf');
$text = file_get_contents('memo.txt');
unlink('memo.pdf');
$issue_props =
array(
'project_id' => $project_id,
'subject' => $memo_subject,
'description' => $text,
);
if (!is_null($custom_fields))
$issue_props['custom_fields'] = $custom_fields;
$issue = $redmine->api('issue')->create($issue_props);
$issue_id = $issue->id;
} else {
$issue_id = $_GET['issue-id'];
}
file_put_contents('urlqr.tex', '\mmredmineurlqr{'.$issue_id.'}');
if (isset($user_redmine['user']['id']))
$redmine_admin->api('issue')->addWatcher($issue_id, $user_redmine['user']['id']);
switch ($_GET['file']) {
case 'request/cps':
case 'request/voip3':
case 'request/voip-softphone':
$redmine_admin->api('issue')->addWatcher($issue_id, USERID_NNROMANOV);
$redmine_admin->api('issue')->addWatcher($issue_id, USERID_DYOKUNEV);
break;
case 'request/voip-transfer-equipment':
case 'request/vacation':
break;
default:
file_put_contents('responsible.tex', '\mmresponsible{'.$_GET['contact-fullname'].'}{'.$_GET{'contact-phonenumber'}.'}{'.$_GET['contact-email'].'}');
}
exec('make');
$pdf_content = file_get_contents('memo.pdf');
$pdf_upload = json_decode( $redmine->api('attachment')->upload($pdf_content) );
$pdf_upload = json_decode( $redmine_admin->api('attachment')->upload($pdf_content) );
$redmine->api('issue')->attach(
$redmine_admin->api('issue')->attach(
$issue_id,
array(
'token' => $pdf_upload->upload->token,
'filename' => 'memorandum.pdf',
'description' => 'Memorandum',
'filename' => 'sluzhebnaya_zapiska.pdf',
'description' => 'Служебная записка',
'content_type'=> 'application/pdf'
)
);
header('Content-type: application/pdf');
print $pdf_content;
if (preg_match('/Firefox/i', $_SERVER['HTTP_USER_AGENT'])) {
system('convert -density 200 memo.pdf memo.png');
system('convert -density 200 memo.png memo_png.pdf');
print file_get_contents('memo_png.pdf');
} else {
print $pdf_content;
}
?>
... ...
... ... @@ -9,6 +9,7 @@
\usepackage{enumitem} % needed for example only
\begin{document}
\begin{sloppypar}
\input{header.tex}
\input{body.tex}
... ... @@ -16,5 +17,5 @@
\input{footer.tex}
\input{responsible.tex}
\input{urlqr.tex}
\end{sloppypar}
\end{document}
... ...
... ... @@ -28,8 +28,56 @@
\usepackage{indentfirst} % indent first paragraph in section
\usepackage{textcomp} % allow ligatures and special symbols
\usepackage[none]{hyphenat}
\pagestyle{empty}
% memorandum NRNU MEPhI header
\newcommand{\mmnrnumephi} {
\begin{center}
Министерство образования и науки Российской Федерации
\end{center}
\begin{center}
Федеральное государственное автономное образовательное учреждение высшего профессионального образования «Национальный исследовательский ядерный университет «МИФИ»
\end{center}
}
% memorandum "from external subdivision"
% #1 - subdivision name
\newcommand{\mmorgfrom}[1] {
\begin{center}
{\bfseries {#1}}
\end{center}
}
\newcommand{\mmstartmemo} {
\begin{center}
Служебная записка
\end{center}
}
% memorandum recipient (while inter-organization communication)
% #1 - position
% #2 - name
\newcommand{\mmorgrecipient}[2]{
\hspace*{0.5\linewidth}
\begin{minipage}{0.5\linewidth}
\begin{flushleft}
{#1}\\
{#2}
\end{flushleft}
\end{minipage}
}
\newcommand{\mmfullheader}[3] {
\mmnrnumephi
\mmorgfrom{{#1}}
\vspace{1em}
\mmorgrecipient{{#2}}{{#3}}
\vspace{1em}
\mmstartmemo
}
% memorandum header
% #1 - position
% #2 - name
... ... @@ -40,9 +88,7 @@
\end{flushright}
\vspace{5em}
\begin{center}
Служебная записка
\end{center}
\mmstartmemo
}
% memorandum footer
... ... @@ -63,7 +109,7 @@
\newcommand{\mmresponsible}[3]{
\begin{flushleft}
\small{
Ответственное лицо:\\
Контактное лицо:\\
\vspace{0.2cm}
ФИО: {#1}\\
телефон: {#2}\\
... ... @@ -71,14 +117,17 @@
}
\end{flushleft}
}
\newcommand{\mmresponsibleskip}[0]{
\vspace{4cm}
}
% memorandum's responsible person
% #1 - position
% #2 - name
\newcommand{\mmredmineurlqr}[1]{
\begin{flushright}
\parbox{2.1cm}{
\psbarcode{{https://redmine.ut.mephi.ru/issues/#1}}{}{qrcode}
\parbox{3.2cm}{
\psbarcode{{https://redmine.ut.mephi.ru/issues/#1}}{eclevel=L width=1.2 height=1.2}{qrcode}
}
\\
\tiny https://redmine.ut.mephi.ru/issues/#1
... ...
Прошу предоставить мне доступ в систему учёта рабочего времени НИЯУ МИФИ для обработки данных по подразделению №[{subdiv-code}] «[{subdiv-name}
... ...
Прошу предоставить [{user-appointment}] [{user-fullname}] доступ к ресурсам высокопроизводительного вычислительного центра НИЯУ МИФИ для [{reason-for}].
Прошу предоставить [{user-appointment}] [{user-fullname}] доступ к ресурсам высокопроизводительного вычислительного центра НИЯУ МИФИ для проведения работ по тематике «[{work-topic}.
Предпочитаемое имя пользователя: [{preffered-login}].
\vspace{0.7em}
Срок окончания работ: [{date-end}]
\begin{tabular}{ l r }
Предпочитаемое имя пользователя: & [{preffered-login}] \\
Идентификатор PGP-ключа: & [{user-pgp-id}] \\
Количество ядер CPU: & [{cpu-amount}] \\
Объём ОЗУ: & [{ram-amount-descr}] \\
Объём HDD: & [{hdd-amount-descr}] \\
Пропускная способность interconnect: & [{ic-bandwidth-descr}] \\
\end{tabular}
\vspace{1em}
[{work-date-end-descr}]
Научный руководитель: [{scientific-director}]
... ...
Прошу предоставить хостинг на базе «[{os}]» для размещения ресурса «[{domainnames}
Прошу предоставить хостинг на базе ОС «[{os}]» для размещения информационного ресурса «[{sitename}
\\
\\
Месяц для проведения ежегодных профилактических работ (обновление ПО и т.п.): [{preventivework-month}]
\\
\\
\begin{tabular}{ l l }
Дата старта проекта: & [{project-start}] \\
Дата окончания проекта: & [{project-end}] \\
Доменные имена: & [{domainnames}] \\
Уровень контроля: & [{controllevel}] \\
Система контроля версиями (VCS): & [{vcs}] \\
Исходящие соединения: & [{net}] \\
Web frontend сервер: & [{httpd-frontend}] \\
Web backend сервер: & [{httpd-backend}] \\
Интерпретатор кода для web сервера: & [{webcodeinterpreter}] \\
\end{tabular}
... ...
Прошу предоставить мне [{vacation-type}] на [{days-count}] к/дней с [{days-from}] по [{days-to}].
Ходатайствую о предоставлении [{of-vacation}] с [{days-from}] на [{days-count}] календарных дней.
Руководитель подразделения: \_\_\_\_\_\_\_\_\_\_\_
... ...
Прошу предоставить мне учётную запись к корпоративной IP-телефонии НИЯУ МИФИ для [{reason-for}].
... ...
Прошу выделить [{tel-amount}] [{tel-descr}] для оперативной связи со службами Университета.
... ...
Прошу предоставить мне доступ в систему «Биллинг» IP-телефонии НИЯУ МИФИ для обработки данных по подразделению №[{subdiv-code}] «[{subdiv-name}
... ...