from __future__ import absolute_import
import os
import json
from . import config
from mylinux import view
from mylinux.libs.decorator import ClassProperty
from mylinux.constants import error as ERR
from mylinux.libs import AppErr
[docs]class Files:
"""This is main Files class.
This class is responsible for all general side effects on mylinux filesystem.
For example multiple package searching, creation of new package etc...
Args:
mainPath (str): Path to folder where is located mylinux file structure.
Attributes:
__inited (boo): Was class allready inited?
__chmodOfNewPackage (str): chmod code of created package data.
__chmodOfInitFolderStructure (str): Set this chmod code to new init folder.
__mainPath (str): Save mainPath from args.
__packages (arr-ins): Package class instances array.
__scripts (arr-ins): All script instances.
__installed (ins): Instance of installed class.
Raises:
AppErr.developer: If class was allready inited.
Other Parameters:
Update __installed attribute with data.
Update __packages att. with data.
Update __scripts att. with data
"""
__inited = False
# Owner (rwx), Else (r)
__chmodOfNewPackage = '744'
__relInstalledPath = '/installed.json'
__relScriptsPath = '/scripts'
__relPackagesPath = '/packages'
@ClassProperty
@classmethod
def chmodOfNewPackage(cls):
return cls.__chmodOfNewPackage
def __init__(self, mainPath):
if not Files.__inited:
Files.__inited = True
self.__mainPath = mainPath
self.__packages = None
self.__scripts = None
self.__installed = None
self.__updateInstalled()
self.__updatePackages()
self.__updateScripts()
else:
raise AppErr.developer(ERR.singletone)
@property
def scriptsPath(self):
"""
Return:
Absolute path to scripts folder.
"""
return self.__mainPath + Files.__relScriptsPath
@property
def packagesPath(self):
"""
Return:
Absolute path to packages folder.
"""
return self.__mainPath + Files.__relPackagesPath
@property
def installedPath(self):
"""
Return:
Absolute path to installed file.
"""
return self.__mainPath + Files.__relInstalledPath
@property
def mainPath(self):
"""
Return:
__mainPath
"""
return self.__mainPath
@property
def installed(self):
"""
Return:
__installed
"""
return self.__installed
@property
def packages(self):
"""
Return:
__packages
"""
return self.__packages
def __updateScripts(self):
"""
Update __scripts variable.
"""
self.__scripts = []
for root, dirs, files in os.walk(self.scriptsPath):
for file in files:
script = config.Script(name=file, path=self.scriptsPath + '/' + file)
self.__scripts.append(script)
break
def __updatePackages(self):
"""
Update __packages variable.
"""
self.__packages = []
for root, dirs, files in os.walk(self.packagesPath):
for dir in dirs:
package = config.Package(name=dir, path=self.packagesPath + '/' + dir)
self.__packages.append(package)
break
def __updateInstalled(self):
"""
Update __installed instance.
"""
self.__installed = config.Installed(path=self.installedPath)
[docs] def createPackage(self, name='newPackageName', info={}, scripts={}):
"""Create new package.
Args:
name (str): Name of new package.
info (dic): Info data of new package.
scripts (dic): Scripts folder structure and data of new package.
Other Parameters:
Check required data in info.
Check if name is accepted.
If pre checks fail show error report.
Make new project structure.
"""
error = []
newPath = self.packagesPath + '/' + name
for requiredDataKey in config.Info.requiredDataKeys:
if not requiredDataKey in info:
error.append(['FAIL', 'Info key', ERR.Format.keyMissingIn(requiredDataKey, info)])
for acceptedName in config.Package.requiredScriptNames:
if not acceptedName in scripts:
error.append(['FAIL', 'Script key', ERR.Format.keyMissingIn(acceptedName, scripts)])
if error:
view.Tli.raiseError(
AppErr.developer,
'{0} in {1}'.format(self.createPackage.__name__,__name__),
error
)
else:
os.makedirs(newPath)
os.makedirs(newPath + config.Package.relScriptsPath)
with open(newPath + config.Package.relInfoPath, 'w') as f:
json.dump(info, f, indent=4)
for scriptName in scripts:
with open(newPath + config.Package.relScriptsPath + '/' + scriptName, 'w') as f:
f.write(scripts[scriptName])
for root, dirs, files in os.walk(newPath):
for ele in dirs + files:
os.chmod(os.path.join(root, ele), int(Files.__chmodOfNewPackage, 8))
[docs] def getScript(self, name):
for script in self.__scripts:
if script.name == name:
return script
view.Tli.raiseError(
AppErr.model,
self.scriptsPath + '/' + name,
['ERROR', 'Main script', ERR.Format.notFoundIn(name, 'Main script folder')]
)
[docs] def getPackages(self, names):
"""Get packages instances
Args:
names (arr-str): Required package names.
Return:
Array of packages instances
"""
return [package for package in self.__packages if package.name in names]
[docs] def getModules(self):
"""Get sorted by name module values from package info data.
Return:
Array of sorted and unique of all package module names.
"""
return sorted(list(set([package.info['module'] for package in self.__packages])))
[docs] def getClasses(self):
"""Get sorted by name class values from package info data.
Return:
Array of sorted and unique of all package class names.
"""
return sorted(list(set([package.info['class'] for package in self.__packages])))
[docs] def getPackageNames(self):
"""Get all package names.
Return:
Sorted array of all packages names.
"""
return sorted([package.name for package in self.__packages])
[docs] def getInfoValues(self):
"""Get all info values from info data.
Return:
Array of all package info values.
"""
return [package.info['info'] for package in self.__packages]