Implement detail page for experiments

This commit is contained in:
Eike Foken
2011-09-14 05:44:20 +02:00
parent 92e45e8033
commit a4f41fd392
6 changed files with 473 additions and 133 deletions

View File

@@ -1,6 +1,6 @@
<?php
<?php defined('BASEPATH') || exit('No direct script access allowed');
/*
* Copyright (c) 2011 Karsten Heiken <karsten@disposed.de>
* Copyright (c) 2011 Karsten Heiken, Eike Foken
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -38,6 +38,7 @@ class Experiments extends CI_Controller {
$this->load->model('parameter');
$this->load->model('program');
$this->load->model('experiment');
$this->load->model('job');
}
/**
@@ -131,6 +132,64 @@ class Experiments extends CI_Controller {
$this->load->view('experiments/new', $data);
}
/**
* Copies an experiment.
*
* @param string $experimentId
*/
public function copy($experimentId = '') {
$experiment = $this->experiment->getByID($experimentId);
if (isset($experiment['project_id'])) {
redirect('experiments/create/' . $experiment['project_id'] . '/' . $experimentId);
} else {
show_404();
}
}
/**
* Shows detailed informations about a specific experiment.
*
* @param string $experimentId
*/
public function detail($experimentId = '') {
$experiment = $this->experiment->getByID($experimentId);
if (empty($experimentId) || !isset($experiment['id'])){
show_404();
}
$this->load->helper('typography');
$data['experiment'] = $experiment;
$data['job'] = $this->job->getByExperimentId($experiment['id']);
$data['project'] = $this->project->getById($experiment['project_id']);
$this->load->view('experiments/detail', $data);
}
/**
* Allows users to delete an experiment.
*
* @param string $experimentId
*/
public function delete($experimentId = '') {
// TODO: Check user rights
$experiment = $this->experiment->getByID($experimentId);
if (empty($experimentId) || !isset($experiment['id'])){
show_404();
}
$this->load->helper('file');
$experimentPath = FCPATH . 'uploads/' . $experiment['project_id'] . '/' . $experiment['id'] . '/';
if (delete_files($experimentPath, true)) {
rmdir($experimentPath);
}
$this->experiment->delete($experimentId);
redirect('projects/detail/' . $experiment['project_id'], 303);
}
}
/* End of file experiments.php */

View File

@@ -48,9 +48,9 @@ if ( ! function_exists('mysql_now'))
* @param string $end
* @return array
*/
if ( ! function_exists('time_diff'))
if ( ! function_exists('time_diff'))
{
function time_diff($start, $end)
function time_diff($start, $end)
{
$uts['start'] = strtotime($start);
$uts['end'] = strtotime($end);
@@ -73,27 +73,27 @@ if ( ! function_exists('time_diff'))
* @param boolean $includeseconds should seconds be appended to the string?
* @return string
*/
if ( ! function_exists('prettyTime'))
if ( ! function_exists('prettyTime'))
{
function prettyTime($secs, $includeseconds = false)
function prettyTime($secs, $includeseconds = false)
{
if(!defined('SECOND')) define("SECOND", 1);
if(!defined('MINUTE')) define("MINUTE", 60 * SECOND);
if(!defined('HOUR')) define("HOUR", 60 * MINUTE);
if(!defined('DAY')) define("DAY", 24 * HOUR);
if(!defined('MONTH')) define("MONTH", 30 * DAY);
$days = intval($secs / 86400);
$hours = intval($secs / 3600 % 24);
$minutes = intval($secs / 60 % 60);
$seconds = intval($secs % 60);
$d = sprintf(ngettext('%d day', '%d days', $days), $days);
$h = sprintf(ngettext('%d hour', '%d hours', $hours), $hours);
$m = sprintf(ngettext('%d minute', '%d minutes', $minutes), $minutes);
$s = sprintf(ngettext('%d second', '%d seconds', $seconds), $seconds);
$output = "";
if($days > 0) {
$output .= $d;
@@ -107,7 +107,39 @@ if ( ! function_exists('prettyTime'))
if($includeseconds || empty($output)) {
$output .= !empty($output) ? ", ". $s : "". $s;
}
return $output;
}
}
/**
* Parses any english textual datetime description into a relative date string.
*
* @author Eike Foken <kontakt@eikefoken.de>
* @param string $date
* @param boolean $show_seconds
* @return string
*/
if (!function_exists('relative_time')) {
function relative_time($date, $show_seconds = false) {
$diff = time() - strtotime($date);
if ($diff < 120 && !$show_seconds) {
$output = _('just now');
} else if ($diff < 60 && $show_seconds) {
$output = sprintf(ngettext('%d second ago', '%d seconds ago', $diff), $diff);
} else if (($diff = round($diff / 60)) < 60) {
$output = sprintf(ngettext('%d minute ago', '%d minutes ago', $diff), $diff);
} else if (($diff = round($diff / 60)) < 24) {
$output = sprintf(ngettext('%d hour ago', '%d hours ago', $diff), $diff);
} else if (($diff = round($diff / 24)) < 7) {
$output = sprintf(ngettext('%d day ago', '%d days ago', $diff), $diff);
} else if (($diff = round($diff / 7)) < 4) {
$output = sprintf(ngettext('%d week ago', '%d weeks ago', $diff), $diff);
} else {
$output = _('on') . ' ' . strftime('%B %Y', strtotime($date));
}
return $output;
}
}

View File

@@ -1,6 +1,6 @@
<?php defined('BASEPATH') || exit('No direct script access allowed');
/*
* Copyright (c) 2011 Karsten Heiken <karsten@disposed.de>
* Copyright (c) 2011 Karsten Heiken, Eike Foken
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,14 +25,15 @@
* Experiments are used to store different variations of the same project.
*
* @author Karsten Heiken <karsten@disposed.de>
* @author Eike Foken <kontakt@eikefoken.de>
*/
class Experiment extends CI_Model {
/**
* Create a new experiment.
* Creates a new experiment.
*
* @param array $data The data of the new experiment
* @return boolean Was the insert successful?
* @return boolean Returns TRUE if the insert was successful.
*/
public function create($data) {
if (!isset($data['project_id'])) {
@@ -51,13 +52,26 @@ class Experiment extends CI_Model {
}
/**
* Deletes a experiment.
* Updates an experiment.
*
* @param array $data
* @param string $experimentId
* @return boolean Returns TRUE if the update was successful.
*/
public function update($data, $experimentId) {
$this->db->update('experiments', $data, array('id' => $experimentId));
return $this->db->affected_rows() == 1;
}
/**
* Deletes an experiment.
*
* @param string $experimentId The experiments ID to delete
* @return boolean Was the deletion successful?
* @return boolean Returns TRUE if the deletion was successful.
*/
public function delete($experimentId) {
return $this->db->delete('experiments', array('id' => $experimentId));
$this->db->delete('experiments', array('id' => $experimentId));
return $this->db->affected_rows() == 1;
}
/**
@@ -99,14 +113,15 @@ class Experiment extends CI_Model {
}
/**
* Gets an experiment by ID.
* Gets an experiment by ID (kept for backwards compatibility).
*
* @deprecated 14-09-2011
* @see Experiment::getById()
* @param string $experimentId The experiment to get
* @return array The experiment
*/
public function get($experimentId) {
$query = $this->db->get_where('experiments', array('id' => $experimentId));
return $query->row_array();
return $this->getById($experimentId);
}
/**
@@ -142,4 +157,7 @@ class Experiment extends CI_Model {
return $results;
}
}
}
/* End of file group.php */
/* Location: ./application/controllers/group.php */

View File

@@ -66,6 +66,22 @@ class Job extends CI_Model {
return $this->db->where('id', $job_id)->update('jobs', $data);
}
/**
* Gets a specific job.
*
* @param string $experimentId
* @return array The job data
*/
public function getByExperimentId($experimentId) {
$this->db->select('jobs.*, users.username, users.firstname, users.lastname');
$this->db->join('users', 'jobs.started_by = users.id', 'left');
$this->db->where('experiment_id', $experimentId);
$query = $this->db->get('jobs');
return $query->row_array();
}
/**
* Gets a list of recent jobs.
*

View File

@@ -0,0 +1,70 @@
<?php $this->load->view('header');?>
<div id="content">
<div class="title">
<h2><?=anchor('projects', _('Projects'));?> &raquo; <?=anchor('projects/detail/' . $project['id'], $project['name']);?> &raquo; <?=$experiment['name'];?></h2>
</div>
<div class="box">
<h3><?=_('Description');?></h3>
<div class="editInPlace"><?=auto_typography($experiment['description']);?></div>
<p></p>
<h3>Actions</h3>
<p>
<?php
if (isset($job['id'])):
?>
<a class="button disabled job_start"><?=_('Start job');?></a>
<?php
else:
?>
<a href="<?=site_url('jobs/start/' . $experiment['id']);?>" class="button job_start"><?=_('Start job');?></a>
<?php
endif;
?>
<a href="<?=site_url('experiments/copy/' . $experiment['id']);?>" class="button left copy"><?=_('Copy experiment');?>
</a><a href="javascript:deleteConfirm('<?=site_url('experiments/delete/' . $experiment['id']);?>');" class="button right delete"><?=_('Delete experiment');?></a>
</p>
</div>
<?php
if (isset($job['id'])):
?>
<div class="box">
<h3><?=_('Job details');?></h3>
<p>
<strong><?=_('Date started');?>:</strong> <?=relative_time($job['started_at']);?><br />
<strong><?=_('Starter');?>:</strong> <?=anchor('users/profile/' . urldecode($job['username']), $job['firstname'] . ' ' . $job['lastname']);?><br />
<strong><?=_('Server');?>:</strong> <?=(!empty($job['server'])) ? anchor('admin/servers/detail/' . urldecode($job['server']), $job['server']) : _('Not yet picked');?>
<div class="progress_bar" style="width: 300px;">
<strong><?=$job['progress']?>%</strong>
<span style="width: <?=$job['progress']?>%;">&nbsp;</span>
</div>
</p>
<?php
if ($job['finished_at'] != '0000-00-00 00:00:00'):
?>
<p><a href="<?=site_url('results/show/' . $experiment['id']);?>" class="button results"><?=_('Show results');?></a></p>
<?php
endif;
?>
</div>
<?php
endif;
?>
</div>
<script>
$('.editInPlace').editInPlace({
url: BASE_URL + 'ajax/update_experiment/' + '<?=$experiment['id']?>',
saving_image: SITE_URL + 'assets/images/ajax-loader.gif',
update_value: 'description',
value_required: true
});
</script>
<?php $this->load->view('footer');?>