# **************************************************************************
# *
# * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
# *
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307 USA
# *
# * All comments concerning this program package may be sent to the
# * e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************
"""
This modules handles the System management
"""
import os
import pyworkflow as pw
import pyworkflow.utils as pwutils
from .project import Project
[docs]class ProjectInfo(object):
"""Class to store some information about the project"""
def __init__(self, projName, mTime, cTime, path):
"""At least it receives the Project Name and its modification time"""
self.projName = projName
self.mTime = mTime
self.cTime = cTime
self.path = path
def __str__(self):
return "%s - %s" % (self.projName, self.path)
[docs] def getName(self):
return self.projName
[docs] def getModificationTime(self):
return self.mTime
[docs] def getCreationTime(self):
return self.cTime
[docs] def isLink(self):
return os.path.islink(self.path)
[docs] def realPath(self):
return os.path.realpath(self.path)
[docs]class Manager(object):
""" Manage all projects of a given workspace, for a given Domain.
(i.e, listing projects, creating, deleting or querying info)
"""
def __init__(self, workspace=None):
"""
Params:
workspace: path to where the user's workspace is. A subfolder
named 'projects' is expected. If workspace is None, the workspace
will be taken from the global configuration.
"""
ws = workspace or pw.Config.SCIPION_USER_DATA
self.PROJECTS = os.path.join(ws, 'projects')
[docs] def getProjectPath(self, projectName):
"""Return the project path given the name"""
return os.path.join(self.PROJECTS, projectName)
[docs] def listProjects(self, sortByDate=True):
"""Return a list with all existing projects
And some other project info
If sortByData is True, recently modified projects will be first"""
projList = []
pw.utils.makePath(self.PROJECTS)
for f in os.listdir(self.PROJECTS):
p = self.getProjectPath(f)
if os.path.isdir(p):
stat = os.stat(p)
projList.append(ProjectInfo(f, stat.st_mtime, stat.st_ctime, p))
if sortByDate:
projList.sort(key=lambda k: k.mTime, reverse=True)
return projList
[docs] def createProject(self, projectName, runsView=1,
hostsConf=None, protocolsConf=None, location=None, comment=None):
"""Create a new project.
confs dict can contain customs .conf files
for: menus, protocols, or hosts
"""
# Clean project name from undesired characters
projectName = Project.cleanProjectName(projectName)
# If location is not None create project on it (if exists)
if location is None:
projectPath = self.getProjectPath(projectName)
else:
projectPath = os.path.join(location, projectName)
# JMRT: Right now the project.create function change the current
# working dir (cwd) to the project location, let's store the cwd
# and restored after the creation
cwd = os.getcwd()
project = Project(pw.Config.getDomain(), projectPath)
project.create(runsView=runsView,
hostsConf=hostsConf,
protocolsConf=protocolsConf,
comment=comment)
# If location is not the default one create a symlink on self.PROJECTS directory
if projectPath != self.getProjectPath(projectName):
# JMRT: Let's create the link to the absolute path, since relative
# can be broken in systems with different mount points
pw.utils.createAbsLink(os.path.abspath(projectPath),
self.getProjectPath(projectName))
os.chdir(cwd) # Restore cwd before project creation
return project
[docs] def importProject(self, fromLocation, copyFiles=True, projectName=None, searchLocation=None):
""" Import a project that is somewhere else in the FS
Folder can be copied (default) or linked
Optionally a name can be specified, otherwise name will match location folder name
Project will always be created in the default project folder.
"""
# If projectName is None...
if projectName is None:
# use same name as the import location
projectName = os.path.basename(fromLocation)
projectPath = self.getProjectPath(projectName)
# If need to copyFiles
if copyFiles:
# Copy the whole folder
pw.utils.copyTree(os.path.abspath(fromLocation), os.path.abspath(projectPath))
else:
# Link the folder
pw.utils.createAbsLink(os.path.abspath(fromLocation), projectPath)
project = self.loadProject(projectName)
if searchLocation:
project.fixLinks(searchLocation)
return project
[docs] def loadProject(self, projId, **kwargs):
""" Retrieve a project object, given its id. """
project = Project(pw.Config.getDomain(), self.getProjectPath(projId))
project.load(**kwargs)
return project
[docs] def deleteProject(self, projectName):
pw.utils.cleanPath(self.getProjectPath(projectName))
[docs] def renameProject(self, oldName, newName):
os.rename(self.getProjectPath(oldName), self.getProjectPath(newName))
[docs] def hasProject(self, projectName):
"""Return True if exists a project with projectName"""
for projInfo in self.listProjects():
if projectName == projInfo.projName:
return True
return False