[limb-svn] r6966 - in syncman/trunk: . cli lib projects-example/projectA projects-example/projectB settings src/controller src/model template template/projects tests www/styles

svn at limb-project.com svn at limb-project.com
Mon Apr 28 12:06:04 MSD 2008


Author: hidrarg
Date: 2008-04-28 12:06:03 +0400 (Mon, 28 Apr 2008)
New Revision: 6966
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6966

Added:
   syncman/trunk/cli/
   syncman/trunk/cli/MigrationToConf.php
   syncman/trunk/projects-example/projectA/settings.conf.php
   syncman/trunk/projects-example/projectB/settings.conf.php
   syncman/trunk/settings/default_value.conf.php
   syncman/trunk/template/page.phtml
   syncman/trunk/template/projects/rollback.phtml
Removed:
   syncman/trunk/settings/default_value.ini
Modified:
   syncman/trunk/lib/
   syncman/trunk/src/controller/ProjectsController.class.php
   syncman/trunk/src/model/Project.class.php
   syncman/trunk/template/projects/detail.phtml
   syncman/trunk/template/projects/display.phtml
   syncman/trunk/tests/ProjectTest.class.php
   syncman/trunk/www/styles/main.css
Log:
-- limb updated to version svn.limb-project.com/3.x/trunk/limb
-- project settings moved from .ini files to .conf.php files due to more comfortable settings editing (migration script included - cli/MigrationToConf.php) 
-- new feature added: Optional deployment version history - ability to create new version each synchronization, ability to rollback to previous revision via web-interface

Added: syncman/trunk/cli/MigrationToConf.php
===================================================================
--- syncman/trunk/cli/MigrationToConf.php	                        (rev 0)
+++ syncman/trunk/cli/MigrationToConf.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,46 @@
+<?php
+
+require_once(dirname(__FILE__) . '/../setup.php');
+
+function findAllProjects()
+{
+  $projects = array();
+  foreach(scandir(SYNCMAN_PROJECTS_SETTINGS_DIR) as $item)
+  {
+    if($item{0} == '.')
+     continue;
+
+    if(!file_exists(SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $item . '/settings.ini'))
+    {
+      echo("project '$item' skip - no file exists 'settings.ini' \n");
+      continue;
+    }
+    elseif(file_exists(SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $item . '/settings.conf.php'))
+    {
+      echo("project '$item' skip - file exists 'settings.conf.php' \n");
+      continue;
+    }
+
+    $project = new lmbIni(SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $item . '/settings.ini');
+    $projects[$item] = $project;
+  }
+  return $projects;
+}
+
+function sr($str)
+{
+  return str_replace("'", "\\'", $str);
+}
+
+foreach(findAllProjects() as $name => $project)
+{
+  $text = "<?php\n\n\$conf = array(\n";
+  foreach($project as $key => $value)
+    $text .= "  " . "'" . sr($key) . "' => '" . sr($value) . "'" . ",\n";
+  $text .= ");\n";
+  $dir = SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $name . '/settings.conf.php';
+  file_put_contents($dir, $text);
+  echo("file create: '{$dir}' \n");
+}
+
+


Property changes on: syncman/trunk/lib
___________________________________________________________________
Name: svn:externals
   - limb https://svn.limb-project.com/3.x/tags/2007.4/limb/

   + limb https://svn.limb-project.com/3.x/trunk/limb


Added: syncman/trunk/projects-example/projectA/settings.conf.php
===================================================================
--- syncman/trunk/projects-example/projectA/settings.conf.php	                        (rev 0)
+++ syncman/trunk/projects-example/projectA/settings.conf.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,12 @@
+<?php
+
+$conf = array(
+  'host' => 'myhost.com',
+  'user' => 'syncman',
+  'key' => '/home/syncman/.ssh/id_dsa',
+  'repository' => 'svn://myrepos/projectA/trunk',
+  'remote_dir' => '/var/www/projectA',
+  'presync_cmd' => 'php %local_dir%/cli/pre_sync.php',
+  'postsync_cmd' => 'ssh -i %key% %user%@%host% \'php %remote_dir%/cli/post_sync.php\'',
+  'history' => false,
+);

Added: syncman/trunk/projects-example/projectB/settings.conf.php
===================================================================
--- syncman/trunk/projects-example/projectB/settings.conf.php	                        (rev 0)
+++ syncman/trunk/projects-example/projectB/settings.conf.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,21 @@
+<?php
+
+$conf = array(
+  'host' => 'myhost.com',
+  'user' => 'syncman',
+  'key' => '/home/syncman/.ssh/id_dsa',
+  'repository' => 'svn://myrepos/projectB/trunk',
+  'remote_dir' => '/var/www/projectB',
+  'presync_cmd' => 'php %local_dir%/cli/pre_sync.php',
+  'postsync_cmd' => 'ssh -i %key% %user%@%host% \'php %remote_dir%/cli/post_sync.php\'',
+  'port' => 22,
+  'password' => 'qwerty',
+  'history' => true,
+  'ssh_get_date' => "date +%F_%R",
+  'ssh_mkdir' => "mkdir -p \$dir",
+  'ssh_ln_edit' => "rm -f \$ln_path; ln -s \$new_dir \$ln_path;",
+  'ssh_cp' => "cp -pRT \$dir_of/ \$dir_in/", // для первого раза можно добавить в конце &> /dev/null
+  'ssh_ls' => "ls -F --classify -1 \$dir",
+  'ssh_preg_dir' => "/(.)+\//",
+  'ssh_readlink' => "readlink -v \$link",
+);

Added: syncman/trunk/settings/default_value.conf.php
===================================================================
--- syncman/trunk/settings/default_value.conf.php	                        (rev 0)
+++ syncman/trunk/settings/default_value.conf.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,21 @@
+<?php
+$conf = array(
+  'host' => 'localhost',
+  'category' => 'no_category',
+  'history' => false,
+  // удаленные каталоги будут называться по результату выполнения этой команды
+  'ssh_get_date' => "date +%F_%R",
+  'ssh_mkdir' => "mkdir -p \$dir",
+  // создание символьной ссылки; exp: rm /home/user/ssilka; ln -s /var/www/exp /home/user/ssilka;
+  'ssh_ln_edit' => "rm -f \$ln_path; ln -s \$new_dir \$ln_path;",
+  // копирование каталогов;
+  // Важно! команда копирования должна сохранять дату создания файла, иначе rsync будет перезаписывать весь каталог при обновлении 
+  'ssh_cp' => "cp -pRT \$dir_of/ \$dir_in/",
+  // список каталогов. Полученный каталог из этого списка впоследствии применяется для установки ссылки командой 'ssh_ln_edit'
+  'ssh_ls' => "ls -F --classify -1 \$dir",
+  // выражение для отбора каталогов из списка файлов
+  'ssh_preg_dir' => "/(.)+\//",
+  // прочитать значение симольной ссылки
+  'ssh_readlink' => "readlink -v \$link",
+  );
+

Deleted: syncman/trunk/settings/default_value.ini
===================================================================
--- syncman/trunk/settings/default_value.ini	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/settings/default_value.ini	2008-04-28 08:06:03 UTC (rev 6966)
@@ -1,2 +0,0 @@
-host=localhost
-category=no_category
\ No newline at end of file

Modified: syncman/trunk/src/controller/ProjectsController.class.php
===================================================================
--- syncman/trunk/src/controller/ProjectsController.class.php	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/src/controller/ProjectsController.class.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -7,9 +7,7 @@
 {
   function doDisplay()
   {
-    //$this->view->findChild('categories')->registerDataset(Category :: findAllCategories());
     $this->view->set('category', Category :: findAllCategories());
-    
 
     if(isset($_COOKIE['category_detail']))
       $this->view->set('category_detail', $_COOKIE['category_detail']);
@@ -19,7 +17,6 @@
 
   function doSimple()
   {
-    //$this->view->findChild('projects')->registerDataset(Project :: findAllProjects());
     $this->view->set('projects', Project :: findAllProjects());
   }
 
@@ -109,6 +106,42 @@
     }
   }
 
+  function doRollback()
+  {
+    $this->useForm('form');
+    $form_date = array();
+    $project = Project :: findProject($this->request->get('id'));
+    $this->view->set('project', $project);
+
+    if(!$project->getHistory())
+    {
+      $this->flashError("For project '{$project->getName()}' history is off!");
+      $this->redirect(array('controller' => 'projects', 'action' => 'display'));
+      return;
+    }
+
+    if($this->request->hasPost())
+    {
+      $form_date['new_current_ln'] = $this->request->get('new_current_ln');
+      if(!$project->setCurrentLn($form_date['new_current_ln']))
+      {
+        $this->flashError('Change not save!');
+      }
+      else
+        $this->flashMessage('Change save!');
+    }
+
+    $dir_list = array();
+    foreach ($project->getListHistory() as $value)
+      $dir_list[$value] = $value;
+    $this->view->set('dir_list', $dir_list);
+
+    $this->setFormDatasource($form_date);
+
+    foreach ($project->errors as $error)
+      $this->flashError($error);
+  }
+
   function notify($project, $cmd, $log)
   {
     static $cmds = array();

Modified: syncman/trunk/src/model/Project.class.php
===================================================================
--- syncman/trunk/src/model/Project.class.php	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/src/model/Project.class.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -8,27 +8,29 @@
   protected $sync_date;
   protected $sync_rev;
   protected static $default_value;
+  protected $connection;
+  public $errors=array();
 
   function __construct($name)
   {
     $this->setName($name);
 
     if(!isset(self::$default_value))
-      self::$default_value = lmbToolkit :: instance()->getConf('default_value.ini');
+      self::$default_value = lmbToolkit :: instance()->getConf('default_value.conf.php');
 
     foreach(self::$default_value as $key => $value)
-      if(!isset($this[$key]))
-        $this->set($key, $value);
+      $this->set($key, $value);
   }
 
-  static function createFromIni($name, $ini)
+  static function createFromConf($name, $conf)
   {
     $project = new Project($name);
 
-    $ini = parse_ini_file($ini);
-    foreach($ini as $key => $value)
+    $conf = new lmbConf($conf);
+    foreach($conf as $key => $value)
       $project->set($key, $value);
 
+
     return $project;
   }
 
@@ -56,6 +58,9 @@
 
       $this->_resetSyncRev();
 
+      if($this->getHistory())
+         $this->_syncHistory();
+
       $this->_execCmd($this->getSyncCmd());
 
       $this->_execCmd($this->getPostsyncCmd());
@@ -87,7 +92,7 @@
       if($item{0} == '.')
         continue;
 
-      $project = self :: createFromIni($item, SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $item . '/settings.ini');
+      $project = self :: createFromConf($item, SYNCMAN_PROJECTS_SETTINGS_DIR . '/' . $item . '/settings.conf.php');
       $projects[] = $project;
     }
     return $projects;
@@ -145,6 +150,11 @@
     return $this->_getFilled('postsync_cmd');
   }
 
+  function getRemoteDir()
+  {
+    return $this->_getRaw('remote_dir') . ($this->getHistory() ? '/current' : '');
+  }
+
   function getRemoteUserWithHost()
   {
     return $this->getUser() . '@' . $this->getHost();
@@ -287,26 +297,134 @@
     return SYNCMAN_SVN_BIN . ' diff --summarize ' . '-r' . $revision1 . ':' . $revision2 . ' ' . $this->getRepository();
   }
 
-  protected function _execCmd($cmd)
+  protected function _ssh2Connection()
   {
-    if(!$cmd)
-      return;
+    if(function_exists('ssh2_connect'))
+    {
+      $this->connection = ssh2_connect($this->getHost(), $this->getPort());
+      if(!$this->connection)
+        throw new Exception("No connection to the ssh server!");
+      if(!ssh2_auth_pubkey_file($this->connection, $this->getUser(),
+                            $this->getKey().'.pub',
+                            $this->getKey(), $this->getPassword()))
+        throw new Exception("Public Key Authentication Failed!");
+    }
+    else
+      $this->connection = true;
+  }
 
-    $proc = popen("$cmd 2>&1", 'r');
+  protected function _syncHistory()
+  {
+    if(!$this->connection)
+      $this->_ssh2Connection();
 
+
+    $new_dir = trim($this->_execCmdSsh($this->getSshGetDate()));
+
+    $new_dir = $this->_getRaw('remote_dir').'/'.$new_dir;
+    $cmd = str_replace('$dir', $new_dir, $this->getSshMkdir());
+    $this->_execCmdSsh($cmd);
+
+    $cmd = str_replace(array('$dir_of', '$dir_in'),
+                       array($this->getRemoteDir(), $new_dir),
+                       $this->getSshCp());
+    try
+    {
+      $this->_execCmdSsh($cmd);
+    }
+    catch (Exception $e)
+    {
+      $this->_writeOutputInLog("'cp' execution failed => initialization file structure", "no cmd");
+    }
+
+    $cmd = str_replace(array('$ln_path', '$new_dir'),
+                       array($this->getRemoteDir(), $new_dir),
+                       $this->getSshLnEdit());
+    $this->_execCmdSsh($cmd);
+  }
+
+  protected function _writeOutputInLog($proc, $cmd)
+  {
     $fh = fopen($this->getLogFile(), 'a');
     $log = '';
-    while(!feof($proc))
+    if(is_string($proc))
     {
-     $t_log = fread($proc, 8192);
-     $log .= $t_log;
-     fwrite($fh, $t_log);
-     if($this->listener)
-       $this->listener->notify($this, $cmd, $t_log);
+      $log = $proc;
+      fwrite($fh, $log);
+        if($this->listener)
+          $this->listener->notify($this, $cmd, $log);
     }
+    else
+    {
+      while($t_log = fgets($proc))
+      {
+        $log .= $t_log;
+        fwrite($fh, $t_log);
+        if($this->listener)
+          $this->listener->notify($this, $cmd, $t_log);
+      }
+    }
+    fclose($fh);
+    return $log;
+  }
 
+  protected function _execCmdSshNoException($cmd, &$out='')
+  {
+    try
+    {
+      if(!$this->connection)
+        $this->_ssh2Connection();
+      $out = $this->_execCmdSsh($cmd);
+      return true;
+    }
+    catch(Exception $e)
+    {
+      $this->errors[] = $e->getMessage();
+      return false;
+    }
+  }
+
+  protected function _execCmdSsh($cmd)
+  {
+    $log = '';
+    if(!$cmd)
+      return;
+    if(function_exists('ssh2_exec'))
+    {
+      if(!$this->connection)
+        throw new Exception("No connection to the ssh server!");
+      $proc = ssh2_exec($this->connection, $cmd);
+      if($proc == false)
+        throw new Exception("Ssh command '$cmd' execution failed!");
+      else
+      {
+        $err_stream = ssh2_fetch_stream($proc, 1);
+
+        stream_set_blocking($err_stream, true);
+        stream_set_blocking($proc, true);
+
+        $err_log = $this->_writeOutputInLog($err_stream, "ssh-err@:~$ ".$cmd);
+        $log = $this->_writeOutputInLog($proc, "ssh-out@:~$ ".$cmd);
+
+        if($err_log !== '')
+          throw new Exception("Ssh command '$cmd' execution failed! Out: '$err_log'");
+      }
+    }
+    else
+      $this->_execCmd(SYNCMAN_SSH_BIN . ' -i ' . $this->getKey() . " " . $this->getRemoteUserWithHost() . " " . $cmd);
+    return $log;
+  }
+
+  protected function _execCmd($cmd)
+  {
+    if(!$cmd)
+      return;
+
+    $proc = popen("$cmd 2>&1", 'r');
+
+    $log = $this->_writeOutputInLog($proc, $cmd);
+
     $res = pclose($proc);
-    fclose($fh);
 
     if($res != 0)
       throw new Exception("Command '$cmd' execution failed, return status is '$res'");
@@ -340,7 +458,7 @@
                              $this->getKey(),
                              $this->getSettingsDir(),
                              ),
-                             $str);
+                       $str);
   }
 
   protected function _removeOldLog()
@@ -360,6 +478,36 @@
     $value = parent :: _getRaw($name);
     return $this->_fillTemplate($value);
   }
+
+  function getListHistory()
+  {
+    $cmd = str_replace('$dir', $this->_getRaw('remote_dir'), $this->getSshLs());
+    if($this->_execCmdSshNoException($cmd, $ls))
+    {
+      $ls = explode("\n", $ls);
+      foreach($ls as $key => $value)
+        if(!preg_match($this->getSshPregDir(), $value))
+          unset($ls[$key]);
+      return $ls;
+    }
+    return null;
+  }
+
+  function getCurrentLn()
+  {
+    $cmd = str_replace('$link', $this->getRemoteDir(), $this->getSshReadlink());
+    if($this->_execCmdSshNoException($cmd, $current_ln))
+      return trim($current_ln);
+    return null;
+  }
+
+  function setCurrentLn($new_dir)
+  {
+    $cmd = str_replace(array('$ln_path', '$new_dir'),
+                       array($this->getRemoteDir(), $new_dir),
+                       $this->getSshLnEdit());
+    return $this->_execCmdSshNoException($cmd);
+  }
 }
 
 ?>

Added: syncman/trunk/template/page.phtml
===================================================================
--- syncman/trunk/template/page.phtml	                        (rev 0)
+++ syncman/trunk/template/page.phtml	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,40 @@
+<html>
+<head>
+  <title>{$#title} :: Syncman</title>
+  <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
+  <link rel="stylesheet" href="/styles/main.css" type="text/css" />
+  {{slot id="head" /}}
+</head>
+<body>
+
+  <div id="wrapper">
+
+    <div id="content">
+
+      <div id="head">
+        <img src="/images/logo.syncman.gif"  width='250' height='63' alt='SYNCMAN' id='logo'/>
+        <span class='version'><?php echo SYNCMAN_VERSION; ?></span>
+      </div>
+
+  <?php $flash_messages = $this->toolkit->getFlashBox()->getUnifiedList(); ?>
+
+  {{list using='$flash_messages'}}
+  {{list:item}}
+  <?php if($item['is_error']){ ?><div class="error"><b>{$item.message}</b></div><? } ?>
+  <?php if($item['is_message']){ ?><div class="message"><b>{$item.message}</b></div><? } ?>
+  {{/list:item}}
+  {{/list}}
+
+
+      {{slot id="content" /}}
+
+    </div>
+
+    <div id="footer">
+      <a href="http://www.bit-creative.com/" target="_blank" title="BIT project" id='bit'><img src="/images/bit.gif"  onMouseOut="this.src='/images/bit.gif';" onMouseOver="this.src='/images/bit_hover.gif';" alt="BIT project" width="80" height="21"/></a>
+      <a href="http://www.limb-project.com" id='limb'><img src="/images/logo.limb.gif"  width='114' height='41' alt='LIMB'/></a>
+    </div>
+
+  </div>
+</body>
+</html>

Modified: syncman/trunk/template/projects/detail.phtml
===================================================================
--- syncman/trunk/template/projects/detail.phtml	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/template/projects/detail.phtml	2008-04-28 08:06:03 UTC (rev 6966)
@@ -36,16 +36,30 @@
         <?php if (isset($project->url)) { ?>
           <dt>Project URI:</dt><dd><a href="{$project.url}" class='project' target="_blank">{$project.url}</a></dd>
         <?php } ?>
-
+        <?php if ($project->history == true) { ?>
+          <dt>History:</dt><dd>
+            YES
+            <br>ssh_get_date: {$project.ssh_get_date}
+            <br>ssh_mkdir: {$project.ssh_mkdir}
+            <br>ssh_ln_edit: {$project.ssh_ln_edit}
+            <br>ssh_cp: {$project.ssh_cp}
+            <br>ssh_ls: {$project.ssh_ls}
+            <br>ssh_preg_dir: {$project.ssh_preg_dir}
+            <br>ssh_readlink: {$project.ssh_readlink}
+          </dd>
+        <?php } ?>
       </dl>
     </td>
     <td class='actions'>
-      <?php if($project->is_locked) {?>
+      <? if($project->is_locked) {?>
         <a href="{{route_url params='action:unlock,id:{$project.name}'}}"  onclick="res = confirm('Confirm action: unlock project \'{$project.name}\'.');if(res){w = window.open(this.href, 'Unlock', 'toolbar=0,location=0,width=400px,height=400px');w.focus();};return false"><img src="/images/icon/unlock.gif" alt="Unlock" title="Force unlock"/></a>
-      <?php } else { ?>
+      <? } else { ?>
         <a href="{{route_url params='action:sync'}}?id={$project.name}" onclick="res = confirm('Confirm action: synchronize project \'{$project.name}\' with remote.');if(res){w = window.open(this.href, 'Sync!', 'toolbar=0,location=0,width=800px,height=800px');w.focus();};return false"><img src="/images/icon/sync.gif" alt="Sync!" title="Synchronize project with remote"/></a>
-      <?php } ?>
+      <? } ?>
       <a href="{{route_url params='action:diff,id:{$project.name}'}}"  onclick="w = window.open(this.href, 'Diff', 'toolbar=0,location=0,width=800px,height=800px');w.focus();return false"><img src="/images/icon/diff.gif" alt="Diff" title="Show difference"/></a>
+      <? if($project->history) { ?>
+        <a href="{{route_url params='action:rollback,id:{$project.name}'}}"><img src="/images/icon/diff.gif" alt="rollback" title="Rollback"/></a>
+      <? } ?>
     </td>
   </tr>
   {{/list:item}}

Modified: syncman/trunk/template/projects/display.phtml
===================================================================
--- syncman/trunk/template/projects/display.phtml	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/template/projects/display.phtml	2008-04-28 08:06:03 UTC (rev 6966)
@@ -1,32 +1,20 @@
-<html>
-<head>
-  <title>Syncman projects</title>
-  <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
-  <link rel="stylesheet" href="/styles/main.css" type="text/css" />
-  <script src="/shared/js/prototype.js"></script>
-  <script src="/shared/js/Limb.js"></script>
-  <script src="/shared/js/Limb/browser.js"></script>
-  <script src="/shared/js/Limb/events.js"></script>
-  <script src="/shared/js/Limb/http.js"></script>
-  <script src="/shared/js/Limb/window.js"></script>
-  <script src="/shared/js/Limb/forms.js"></script>
-  <script src="/shared/js/Limb/form_elements.js"></script>
-  <script src="/shared/js/scriptaculous/scriptaculous.js"></script>
-  <script src="/js/jquery.js"></script>
-  <script src="/js/main.js"></script>
-  <script src="/js/getDetailForCategory.js"></script>
-</head>
-<body>
-
-  <div id="wrapper">
-
-    <div id="content">
-
-      <div id="head">
-        <img src="/images/logo.syncman.gif"  width='250' height='63' alt='SYNCMAN' id='logo'/>
-        <span class='version'><?php echo SYNCMAN_VERSION; ?></span>
-      </div>
-
+<? $this->title = 'Projects' ?>
+{{insert file="page.phtml"}}
+  {{insert:into slot='head'}}
+<script src="/shared/js/prototype.js"></script>
+<script src="/shared/js/Limb.js"></script>
+<script src="/shared/js/Limb/browser.js"></script>
+<script src="/shared/js/Limb/events.js"></script>
+<script src="/shared/js/Limb/http.js"></script>
+<script src="/shared/js/Limb/window.js"></script>
+<script src="/shared/js/Limb/forms.js"></script>
+<script src="/shared/js/Limb/form_elements.js"></script>
+<script src="/shared/js/scriptaculous/scriptaculous.js"></script>
+<script src="/js/jquery.js"></script>
+<script src="/js/main.js"></script>
+<script src="/js/getDetailForCategory.js"></script>
+  {{/insert:into}}
+  {{insert:into slot='content'}}
       {{list:list using="$#category" as="$item"}}
       {{list:item}}
 
@@ -58,14 +46,5 @@
 
       {{/list:item}}
       {{/list:list}}
-
-    </div>
-
-    <div id="footer">
-      <a href="http://www.bit-creative.com/" target="_blank" title="BIT project" id='bit'><img src="/images/bit.gif"  onMouseOut="this.src='/images/bit.gif';" onMouseOver="this.src='/images/bit_hover.gif';" alt="BIT project" width="80" height="21"/></a>
-      <a href="http://www.limb-project.com" id='limb'><img src="/images/logo.limb.gif"  width='114' height='41' alt='LIMB'/></a>
-    </div>
-
-  </div>
-</body>
-</html>
+  {{/insert:into}}
+{{/insert}}
\ No newline at end of file

Added: syncman/trunk/template/projects/rollback.phtml
===================================================================
--- syncman/trunk/template/projects/rollback.phtml	                        (rev 0)
+++ syncman/trunk/template/projects/rollback.phtml	2008-04-28 08:06:03 UTC (rev 6966)
@@ -0,0 +1,45 @@
+<? $this->title = 'Rollback project' ?>
+{{insert file="page.phtml"}}
+  {{insert:into slot='content'}}
+
+{{form id='form' name='form' method='post'}}
+<div style="margin: 20px;">
+  <br>
+  <a href="{{route_url params='action:display'}}" class="category"> &#60&#60&#60 Display projects</a>
+  <br><br>
+  <table>
+  <tr>
+    <td class="field">
+    {{label for="name"}}Project name:{{/label}}
+    </td>
+    <td class="value">
+    {$#project.name}
+    </td>
+  </tr>
+  <tr>
+    <td class="field">
+    {{label for="current"}}Current 'DocumentRoot':{{/label}}
+    </td>
+    <td class="value">
+    {$#project.current_ln}
+    </td>
+  </tr>
+  <tr>
+    <td class="field">
+    {{label for="new_current_ln"}}Change current 'DocumentRoot' on:{{/label}}
+    </td>
+    <td class="value">
+    {{select id='new_current_ln' name='new_current_ln' options="$#dir_list"}}{{/select}}
+    </td>
+  </tr>
+  <tr>
+    <td>
+    <input type='submit' value='Apply'/>
+    </td>
+  </tr>
+  </table>
+
+</div>
+{{/form}}
+  {{/insert:into}}
+{{/insert}}
\ No newline at end of file

Modified: syncman/trunk/tests/ProjectTest.class.php
===================================================================
--- syncman/trunk/tests/ProjectTest.class.php	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/tests/ProjectTest.class.php	2008-04-28 08:06:03 UTC (rev 6966)
@@ -14,7 +14,7 @@
     remote_dir=/var/www/mydir
     presync_cmd=php %local_dir%/cli/pre_sync.php
     postsync_cmd=ssh -i %key% %user%@%host% 'php %remote_dir%/cli/post_sync.php'
-    sync_cmd=rsync -Cavz -e 'ssh -i %key%' %user%@%host% 
+    sync_cmd=rsync -Cavz -e 'ssh -i %key%' %user%@%host%
     ");
 
     $project = Project :: createFromIni('foo', $ini);

Modified: syncman/trunk/www/styles/main.css
===================================================================
--- syncman/trunk/www/styles/main.css	2008-04-28 04:35:25 UTC (rev 6965)
+++ syncman/trunk/www/styles/main.css	2008-04-28 08:06:03 UTC (rev 6966)
@@ -47,7 +47,7 @@
 
 /*layout*/
   #wrapper {min-height:100%;position:relative;}
-    *html #wrapper {height:100%;}
+    #html #wrapper {height:100%;}
   #content {padding:0 0 90px 0;}
   
   #head {background: #fff;margin:0 0 5px 0;}
@@ -67,5 +67,8 @@
     #limb {float:right;margin:15px 0 0 30px;}
     #bit {margin: 25px 30px 0px;float:right;}
   
-  
+  div.error {font:bold 1.4em "Trebuchet MS"; background: #ffc5c5; margin: 10px;}
+  div.message {font:bold 1.4em "Trebuchet MS"; background: #e5ffd5; margin: 10px;}
+  .field {font:bold 1.4em "Trebuchet MS"; color:#2a3f62; padding: 5px 0px 0px 0px;}
+  .value {font:1.4em "Trebuchet MS"; color:#000000; padding: 5px 0px 0px 20px;} 
   
\ No newline at end of file



More information about the limb-svn mailing list