Here are the examples of the python api jasy.core.Console.info taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
46 Examples
3
Example 1
def clear(self):
"""
Removes all generated sprite files found in the base directory
"""
Console.info("Cleaning sprite files...")
Console.indent()
for dirPath, dirNames, fileNames in os.walk(self.base):
for fileName in fileNames:
if fileName.startswith("jasysprite"):
filePath = os.path.join(dirPath, fileName)
Console.debug("Removing file: %s", filePath)
os.remove(filePath)
Console.outdent()
3
Example 2
Project: jasy Source File: SpritePacker.py
def packDir(self, path='', recursive=True, autorotate=False, debug=False):
"""Pack images inside a dir into sprite sheets"""
Console.info('Packing sprites in: %s' % os.path.join(self.base, path))
Console.indent()
self.files = []
self.addDir(path, recursive=recursive)
Console.info('Found %d images' % len(self.files))
if len(self.files) > 0:
self.generate(path, autorotate, debug)
Console.outdent()
3
Example 3
def removeDir(self, dirname):
"""Removes the given directory"""
dirname = self.__session.expandFileName(dirname)
if os.path.exists(dirname):
Console.info("Deleting folder %s" % dirname)
shutil.rmtree(dirname)
3
Example 4
def removeFile(self, filename):
"""Removes the given file"""
filename = self.__session.expandFileName(filename)
if os.path.exists(filename):
Console.info("Deleting file %s" % filename)
os.remove(filename)
3
Example 5
def export(self, path):
Console.info("Writing result...")
Console.info("Target directory: %s", path)
Console.indent()
jasy.core.File.write(os.path.join(path, "jasyproject.yaml"), 'name: locale\npackage: ""\n')
count = self.__exportRecurser(self.__data, "locale", path)
Console.info("Created %s classes", count)
Console.outdent()
3
Example 6
def clean(self):
"""Clears all caches of all registered projects"""
if not self.__projects:
return
Console.info("Cleaning session...")
Console.indent()
for project in self.__projects:
project.clean()
Console.outdent()
3
Example 7
def pause(self):
"""
Pauses the session. This release cache files etc. and makes
it possible to call other jasy processes on the same projects.
"""
Console.info("Pausing session...")
for project in self.__projects:
project.pause()
3
Example 8
def resume(self):
"""Resumes the session after it has been paused."""
Console.info("Resuming session...")
for project in self.__projects:
project.resume()
3
Example 9
Project: jasy Source File: Context.py
@task
def about():
"""Print outs the Jasy about page"""
import jasy
jasy.info()
from jasy.env.Task import getCommand
Console.info("Command: %s", getCommand())
Console.info("Version: %s", jasy.__version__)
3
Example 10
Project: jasy Source File: Context.py
@task
def showapi():
"""Shows the official API available in jasyscript.py"""
from jasy.core.Inspect import generateApi
Console.info(generateApi(__api__))
3
Example 11
Project: jasy Source File: Server.py
def __init__(self, id, config):
self.id = id
self.config = config
self.host = getKey(config, "host")
self.auth = getKey(config, "auth")
self.enableDebug = getKey(config, "debug", False)
self.enableMirror = getKey(config, "mirror", False)
self.enableOffline = getKey(config, "offline", False)
if self.enableMirror:
self.mirror = Cache.Cache(os.getcwd(), ".jasy/mirror-%s" % self.id, hashkeys=True)
Console.info('Proxy "%s" => "%s" [debug:%s|mirror:%s|offline:%s]', self.id, self.host, self.enableDebug, self.enableMirror, self.enableOffline)
3
Example 12
Project: jasy Source File: Server.py
def __init__(self, id, config, mimeTypes=None):
self.id = id
self.config = config
self.mimeTypes = mimeTypes
self.root = getKey(config, "root", ".")
self.enableDebug = getKey(config, "debug", False)
Console.info('Static "%s" => "%s" [debug:%s]', self.id, self.root, self.enableDebug)
3
Example 13
def start(self):
"""
Starts the web server and blocks execution.
Note: This stops further execution of the current task or method.
"""
app = cherrypy.tree.mount(self.__root, "", self.__config)
cherrypy.process.plugins.PIDFile(cherrypy.engine, ".jasy/server-%s" % self.__port).subscribe()
cherrypy.engine.start()
Console.info("Started HTTP server at port %s... [PID=%s]", self.__port, os.getpid())
Console.indent()
cherrypy.engine.block()
Console.outdent()
Console.info("Stopped HTTP server at port %s.", self.__port)
0
Example 14
def __init__(self, session):
Console.info("Initializing assets...")
Console.indent()
# Store session reference (one asset manager per session)
self.__session = session
# Stores manager contextual asset information (like relative paths)
self.__data = {}
# Registry for profiles aka asset groups
self.__profiles = []
# Loop though all projects and merge assets
assets = self.__assets = {}
for project in self.__session.getProjects():
assets.update(project.getAssets())
self.__processSprites()
self.__processAnimations()
Console.outdent()
Console.info("Activated %s assets", len(assets))
0
Example 15
Project: jasy Source File: Manager.py
def __processSprites(self):
"""Processes jasysprite.json files to merge sprite data into asset registry"""
assets = self.__assets
configs = [fileId for fileId in assets if assets[fileId].isImageSpriteConfig()]
if configs:
Console.info("Processing %s image sprite configs...", len(configs))
sprites = []
Console.indent()
for fileId in configs:
Console.debug("Processing %s...", fileId)
asset = assets[fileId]
spriteBase = os.path.dirname(fileId)
try:
spriteConfig = asset.getParsedObject();
except ValueError as err:
raise UserError("Could not parse jasysprite.json at %s: %s" % (fileId, err))
Console.indent()
for spriteImage in spriteConfig:
spriteImageId = "%s/%s" % (spriteBase, spriteImage)
singleRelPaths = spriteConfig[spriteImage]
Console.debug("Image %s combines %s images", spriteImageId, len(singleRelPaths))
for singleRelPath in singleRelPaths:
singleId = "%s/%s" % (spriteBase, singleRelPath)
singleData = singleRelPaths[singleRelPath]
if singleId in assets:
singleAsset = assets[singleId]
else:
Console.info("Creating new asset: %s", singleId)
singleAsset = jasy.item.Asset.AssetItem(None)
assets[singleId] = singleAsset
if not spriteImageId in sprites:
spriteImageIndex = len(sprites)
sprites.append(spriteImageId)
else:
spriteImageIndex = sprites.index(spriteImageId)
singleAsset.addImageSpriteData(spriteImageIndex, singleData["left"], singleData["top"])
if "width" in singleData and "height" in singleData:
singleAsset.addImageDimensionData(singleData["width"], singleData["height"])
# Verify that sprite sheet is up-to-date
if "checksum" in singleData:
fileChecksum = singleAsset.getChecksum()
storedChecksum = singleData["checksum"]
Console.debug("Checksum Compare: %s <=> %s", fileChecksum[0:6], storedChecksum[0:6])
if storedChecksum != fileChecksum:
raise UserError("Sprite Sheet is not up-to-date. Checksum of %s differs.", singleId)
Console.outdent()
Console.debug("Deleting sprite config from assets: %s", fileId)
del assets[fileId]
Console.outdent()
self.__sprites = sprites
0
Example 16
Project: jasy Source File: Manager.py
def __processAnimations(self):
"""Processes jasyanimation.json files to merge animation data into asset registry"""
assets = self.__assets
configs = [fileId for fileId in assets if assets[fileId].isImageAnimationConfig()]
if configs:
Console.info("Processing %s image animation configs...", len(configs))
Console.indent()
for fileId in configs:
Console.debug("Processing %s...", fileId)
asset = assets[fileId]
base = os.path.dirname(fileId)
try:
config = json.loads(asset.getText())
except ValueError as err:
raise UserError("Could not parse jasyanimation.json at %s: %s" % (fileId, err))
for relPath in config:
imageId = "%s/%s" % (base, relPath)
data = config[relPath]
if not imageId in assets:
raise UserError("Unknown asset %s in %s" % (imageId, fileId))
animationAsset = assets[imageId]
if "rows" in data or "columns" in data:
rows = Util.getKey(data, "rows", 1)
columns = Util.getKey(data, "columns", 1)
frames = Util.getKey(data, "frames")
animationAsset.addImageAnimationData(columns, rows, frames)
if frames is None:
frames = rows * columns
elif "layout" in data:
layout = data["layout"]
animationAsset.addImageAnimationData(None, None, layout=layout)
frames = len(layout)
else:
raise UserError("Invalid image frame data for: %s" % imageId)
Console.debug(" - Animation %s has %s frames", imageId, frames)
Console.debug(" - Deleting animation config from assets: %s", fileId)
del assets[fileId]
Console.outdent()
0
Example 17
def deploy(self, classes, assetFolder=None):
"""
Deploys all asset files to the destination asset folder. This merges
assets from different projects into one destination folder.
"""
# Sometimes it's called with explicit None - we want to fill the default
# in that case as well.
if assetFolder is None:
assetFolder = "$prefix/asset"
assets = self.__assets
projects = self.__session.getProjects()
copyAssetFolder = self.__session.expandFileName(assetFolder)
filterExpr = self.__compileFilterExpr(classes)
Console.info("Deploying assets...")
counter = 0
length = len(assets)
for fileId in assets:
if not filterExpr.match(fileId):
length -= 1
continue
srcFile = assets[fileId].getPath()
dstFile = os.path.join(copyAssetFolder, fileId.replace("/", os.sep))
if jasy.core.File.syncfile(srcFile, dstFile):
counter += 1
Console.info("Updated %s/%s files" % (counter, length))
0
Example 18
def export(self, classes=None):
"""
Exports asset data for usage at the client side. Utilizes JavaScript
class jasy.Asset to inject data into the client at runtime.
"""
# Processing assets
assets = self.__assets
data = self.__data
result = {}
filterExpr = self.__compileFilterExpr(classes) if classes else None
for fileId in assets:
if filterExpr and not filterExpr.match(fileId):
continue
entry = {}
asset = assets[fileId]
entry["t"] = asset.getType(short=True)
assetData = asset.exportData()
if assetData:
entry["d"] = assetData
if fileId in data:
entry.update(data[fileId])
result[fileId] = entry
# Ignore empty result
if not result:
return None
Console.info("Exported %s assets", len(result))
return json.dumps({
"assets" : self.__structurize(result),
"profiles" : self.__profiles,
"sprites" : self.__sprites
}, indent=2)
0
Example 19
Project: jasy Source File: SpritePacker.py
def generate(self, path='', autorotate=False, debug=False):
"""Generate sheets/variants"""
Console.info('Generating sprite sheet variants...')
Console.indent()
sheets, count = self.packBest(autorotate)
# Write PNG files
data = {}
for pos, sheet in enumerate(sheets):
Console.info('Writing image (%dx%dpx) with %d images' % (sheet.width, sheet.height, len(sheet)))
name = 'jasysprite_%d.png' % pos
# Export
sheet.write(os.path.join(self.base, path, name), debug)
data[name] = sheet.export()
Console.outdent()
# Generate JSON/YAML
Console.info('Exporting data...')
script = os.path.join(self.base, path, 'jasysprite.%s' % self.dataFormat)
writeConfig(data, script)
0
Example 20
Project: jasy Source File: Create.py
def massFilePatcher(path, data):
# Convert method with access to local data
def convertPlaceholder(mo):
field = mo.group(1)
value = data.get(field)
# Verify that None means missing
if value is None and not data.has(field):
raise ValueError('No value for placeholder "%s"' % field)
# Requires value being a string
return str(value)
# Patching files recursively
Console.info("Patching files...")
Console.indent()
for dirPath, dirNames, fileNames in os.walk(path):
relpath = os.path.relpath(dirPath, path)
# Filter dotted directories like .git, .bzr, .hg, .svn, etc.
for dirname in dirNames:
if dirname.startswith("."):
dirNames.remove(dirname)
for fileName in fileNames:
filePath = os.path.join(dirPath, fileName)
fileRel = os.path.normpath(os.path.join(relpath, fileName))
Console.debug("Processing: %s..." % fileRel)
fileHandle = open(filePath, "r", encoding="utf-8", errors="surrogateescape")
fileContent = []
# Parse file line by line to detect binary files early and omit
# fully loading them into memory
try:
isBinary = False
for line in fileHandle:
if '\0' in line:
isBinary = True
break
else:
fileContent.append(line)
if isBinary:
Console.debug("Ignoring binary file: %s", fileRel)
continue
except UnicodeDecodeError as ex:
Console.warn("Can't process file: %s: %s", fileRel, ex)
continue
fileContent = "".join(fileContent)
# Update content with available data
try:
resultContent = fieldPattern.sub(convertPlaceholder, fileContent)
except ValueError as ex:
Console.warn("Unable to process file %s: %s!", fileRel, ex)
continue
# Only write file if there where any changes applied
if resultContent != fileContent:
Console.info("Updating: %s...", Console.colorize(fileRel, "bold"))
fileHandle = open(filePath, "w", encoding="utf-8", errors="surrogateescape")
fileHandle.write(resultContent)
fileHandle.close()
Console.outdent()
0
Example 21
Project: jasy Source File: Create.py
def create(name="myproject", origin=None, originVersion=None, skeleton=None, destination=None, session=None, **argv):
"""
Creates a new project from a defined skeleton or an existing project's root directory (only if there is a jasycreate.yaml/.json).
:param name: The name of the new created project
:type name: string
:param origin: Path or git url to the base project
:type origin: string
:param originVersion: Version of the base project from wich will be created.
:type originVersion: string
:param skeleton: Name of a defined skeleton. None for creating from root
:type skeleton: string
:param destination: Destination path for the new created project
:type destination: string
:param session: An optional session to use as origin project
:type session: object
"""
if not validProjectName.match(name):
raise UserError("Invalid project name: %s (Use lowercase characters and numbers only for broadest compabibility)" % name)
#
# Initial Checks
#
# Figuring out destination folder
if destination is None:
destination = name
destinationPath = os.path.abspath(os.path.expanduser(destination))
if os.path.exists(destinationPath):
raise UserError("Cannot create project %s in %s. File or folder exists!" % (name, destinationPath))
# Origin can be either:
# 1) None, which means a skeleton from the current main project
# 2) An repository URL
# 3) A project name known inside the current session
# 4) Relative or absolute folder path
originPath = None;
originName = None;
if origin is None:
originProject = session and session.getMain()
if originProject is None:
raise UserError("Auto discovery failed! No Jasy projects registered!")
originPath = originProject.getPath()
originName = originProject.getName()
originRevision = None
elif Repository.isUrl(origin):
Console.info("Using remote skeleton")
tempDirectory = tempfile.TemporaryDirectory()
originPath = os.path.join(tempDirectory.name, "clone")
originUrl = origin
Console.indent()
originRevision = Repository.update(originUrl, originVersion, originPath)
Console.outdent()
if originRevision is None:
raise UserError("Could not clone origin repository!")
Console.debug("Cloned revision: %s" % originRevision)
if os.path.isfile(os.path.join(originPath, "jasycreate.yaml")) or os.path.isfile(os.path.join(originPath, "jasycreate.json")) or os.path.isfile(os.path.join(originPath, "jasycreate.py")):
originProject = None
else:
originProject = getProjectFromPath(originPath)
originName = originProject.getName()
else:
originProject = session and session.getProjectByName(origin)
originVersion = None
originRevision = None
if originProject is not None:
originPath = originProject.getPath()
originName = origin
elif os.path.isdir(origin):
originPath = origin
if os.path.isfile(os.path.join(originPath, "jasycreate.yaml")) or os.path.isfile(os.path.join(originPath, "jasycreate.json")) or os.path.isfile(os.path.join(originPath, "jasycreate.py")):
originProject = None
else:
originProject = getProjectFromPath(originPath)
originName = originProject.getName()
else:
raise UserError("Invalid value for origin: %s" % origin)
# Figure out the skeleton root folder
if originProject is not None:
skeletonDir = os.path.join(originPath, originProject.getConfigValue("skeletonDir", "skeleton"))
else:
skeletonDir = originPath
if not os.path.isdir(skeletonDir):
raise UserError('The project %s offers no skeletons!' % originName)
# For convenience: Use first skeleton in skeleton folder if no other selection was applied
if skeleton is None:
if originProject is not None:
skeleton = getFirstSubFolder(skeletonDir)
else:
skeleton = skeletonDir
# Finally we have the skeleton path (the root folder to copy for our app)
skeletonPath = os.path.join(skeletonDir, skeleton)
if not os.path.isdir(skeletonPath):
raise UserError('Skeleton %s does not exist in project "%s"' % (skeleton, originName))
#
# Actual Work
#
# Prechecks done
if originName:
Console.info('Creating %s from %s %s...', Console.colorize(name, "bold"), Console.colorize(skeleton + " @", "bold"), Console.colorize(originName, "magenta"))
else:
Console.info('Creating %s from %s...', Console.colorize(name, "bold"), Console.colorize(skeleton, "bold"))
Console.debug('Skeleton: %s', Console.colorize(skeletonPath, "grey"))
Console.debug('Destination: %s', Console.colorize(destinationPath, "grey"))
# Copying files to destination
Console.info("Copying files...")
shutil.copytree(skeletonPath, destinationPath)
Console.debug("Files were copied successfully.")
# Close origin project
if originProject:
originProject.close()
# Change to directory before continuing
os.chdir(destinationPath)
# Create configuration file from question configs and custom scripts
Console.info("Starting configuration...")
config = Config()
config.set("name", name)
config.set("jasy.version", jasy.__version__)
if originName:
config.set("origin.name", originName)
config.set("origin.version", originVersion)
config.set("origin.revision", originRevision)
config.set("origin.skeleton", os.path.basename(skeletonPath))
config.injectValues(**argv)
if originProject is not None:
config.readQuestions("jasycreate", optional=True)
config.executeScript("jasycreate.py", optional=True)
# Do actual replacement of placeholders
massFilePatcher(destinationPath, config)
Console.debug("Files were patched successfully.")
# Done
Console.info('Your application %s was created successfully!', Console.colorize(name, "bold"))
0
Example 22
def on_moved(self, event):
super(JasyEventHandler, self).on_moved(event)
what = 'directory' if event.is_directory else 'file'
Console.info("Moved %s: from %s to %s", what, event.src_path, event.dest_path)
0
Example 23
def on_created(self, event):
super(JasyEventHandler, self).on_created(event)
what = 'directory' if event.is_directory else 'file'
Console.info("Created %s: %s", what, event.src_path)
0
Example 24
def on_deleted(self, event):
super(JasyEventHandler, self).on_deleted(event)
what = 'directory' if event.is_directory else 'file'
Console.info("Deleted %s: %s", what, event.src_path)
0
Example 25
def on_modified(self, event):
super(JasyEventHandler, self).on_modified(event)
what = 'directory' if event.is_directory else 'file'
Console.info("Modified %s: %s", what, event.src_path)
0
Example 26
Project: jasy Source File: Locale.py
def __init__(self, locale):
Console.info("Parsing CLDR files for %s..." % locale)
Console.indent()
splits = locale.split("_")
# Store for internal usage
self.__locale = locale
self.__language = splits[0]
self.__territory = splits[1] if len(splits) > 1 else None
# This will hold all data extracted data
self.__data = {}
# Add info section
self.__data["info"] = {
"LOCALE" : self.__locale,
"LANGUAGE" : self.__language,
"TERRITORY" : self.__territory
}
# Add keys (fallback to C-default locale)
path = "%s.xml" % os.path.join(CLDR_DIR, "keys", self.__language)
try:
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
except IOError:
path = "%s.xml" % os.path.join(CLDR_DIR, "keys", "C")
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
self.__data["key"] = {
"Short" : { key.get("type"): key.text for key in tree.findall("./keys/short/key") },
"Full" : { key.get("type"): key.text for key in tree.findall("./keys/full/key") }
}
# Add main CLDR data: Fallback chain for locales
main = os.path.join(CLDR_DIR, "main")
files = []
while True:
files.append("%s.xml" % os.path.join(main, locale))
if "_" in locale:
locale = locale[:locale.rindex("_")]
else:
break
# Extend data with root data
files.append(os.path.join(main, "root.xml"))
# Finally import all these files in order
for path in reversed(files):
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
self.__addDisplayNames(tree)
self.__addDelimiters(tree)
self.__addCalendars(tree)
self.__addNumbers(tree)
# Add supplemental CLDR data
self.__addSupplementals(self.__territory)
Console.outdent()
0
Example 27
Project: jasy Source File: Locale.py
def __addSupplementals(self, territory):
""" Converts data from supplemental folder """
supplemental = os.path.join(CLDR_DIR, "supplemental")
# Plurals
path = os.path.join(supplemental, "plurals.xml")
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
self.__data["Plural"] = {}
for item in tree.findall("plurals/pluralRules"):
attr = item.get("locales")
if attr != None:
if self.__language in attr.split(" "):
for rule in item.findall("pluralRule"):
jsPlural = pluralToJavaScript(rule.text)
self.__data["Plural"][rule.get("count").upper()] = jsPlural
# Telephone Codes
path = os.path.join(supplemental, "telephoneCodeData.xml")
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
for item in tree.findall("telephoneCodeData/codesByTerritory"):
territoryId = item.get("territory")
if territoryId == territory:
for rule in item.findall("telephoneCountryCode"):
self.__data["PhoneCode"] = {"CODE":int(rule.get("code"))}
# Respect first only
break
# Postal Codes
path = os.path.join(supplemental, "postalCodeData.xml")
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
for item in tree.findall("postalCodeData/postCodeRegex"):
territoryId = item.get("territoryId")
if territory == territoryId:
self.__data["PostalCode"] = {"CODE":item.text}
break
# Supplemental Data
path = os.path.join(supplemental, "supplementalData.xml")
Console.info("Processing %s..." % os.path.relpath(path, CLDR_DIR))
tree = xml.etree.ElementTree.parse(path)
# :: Calendar Preference
ordering = None
for item in tree.findall("calendarPreferenceData/calendarPreference"):
if item.get("territories") == "001" and ordering == None:
ordering = item.get("ordering")
elif territory in item.get("territories").split(" "):
ordering = item.get("ordering")
break
self.__data["CalendarPref"] = { "ORDERING" : ordering.split(" ") }
# :: Week Data
self.__data["Week"] = {}
weekData = tree.find("weekData")
for key in ["firstDay", "weekendStart", "weekendEnd"]:
day = None
for item in weekData.findall(key):
if item.get("territories") == "001" and day == None:
day = item.get("day")
elif territory in item.get("territories").split(" "):
day = item.get("day")
break
self.__data["Week"][camelCaseToUpper(key)] = day
# :: Measurement System
self.__data["Measurement"] = {}
measurementData = tree.find("measurementData")
for key in ["measurementSystem", "paperSize"]:
mtype = None
for item in measurementData.findall(key):
if item.get("territories") == "001" and mtype == None:
mtype = item.get("type")
elif territory in item.get("territories").split(" "):
mtype = item.get("type")
break
self.__data["Measurement"][camelCaseToUpper(key)] = mtype
0
Example 28
def __init__(self, session, assetManager=None, compressionLevel=1, formattingLevel=0):
Console.info("Initializing OutputManager...")
Console.indent()
Console.info("Formatting Level: %s", formattingLevel)
Console.info("Compression Level: %s", compressionLevel)
self.__session = session
self.__assetManager = assetManager
self.__fileManager = FileManager(session)
self.__scriptOptimization = Optimization()
self.__compressGeneratedCode = False
self.__kernelClasses = []
if compressionLevel > 0:
self.__scriptOptimization.enable("variables")
self.__scriptOptimization.enable("declarations")
self.__compressGeneratedCode = True
if compressionLevel > 1:
self.__scriptOptimization.enable("blocks")
self.__scriptOptimization.enable("privates")
self.__scriptFormatting = Formatting()
if formattingLevel > 0:
self.__scriptFormatting.enable("semicolon")
self.__scriptFormatting.enable("comma")
Console.outdent()
0
Example 29
Project: jasy Source File: OutputManager.py
def deployAssets(self, classes, assetFolder=None):
"""
Deploys assets for the given classes and all their dependencies
:param classes: List of classes to deploy assets for
:type classes: list
:param assetFolder: Destination folder of assets (defaults to $prefix/asset)
:type assetFolder: string
"""
Console.info("Deploying assets...")
Console.indent()
resolver = Resolver(self.__session)
for className in classes:
resolver.addClassName(className)
self.__assetManager.deploy(resolver.getIncludedClasses(), assetFolder=assetFolder)
Console.outdent()
0
Example 30
Project: jasy Source File: OutputManager.py
def storeKernel(self, fileName, classes=None, debug=False):
"""
Writes a so-called kernel script to the given location. This script contains
data about possible permutations based on current session values. It optionally
might include asset data (useful when boot phase requires some assets) and
localization data (if only one locale is built).
Optimization of the script is auto-enabled when no other information is given.
This method returns the classes which are included by the script so you can
exclude it from the real other generated output files.
"""
Console.info("Storing kernel...")
Console.indent()
# Use a new permutation based on debug settings and statically configured fields
self.__session.setStaticPermutation(debug=debug)
# Build resolver
# We need the permutation here because the field configuration might rely on detection classes
resolver = Resolver(self.__session)
detectionClasses = self.__session.getFieldDetectionClasses()
for className in detectionClasses:
resolver.addClassName(className)
# Jasy client side classes to hold data
resolver.addClassName("jasy.Env")
resolver.addClassName("jasy.Asset")
resolver.addClassName("jasy.Translate")
# Allow kernel level mass loading of scripts (required for source, useful for build)
resolver.addClassName("core.io.Script")
resolver.addClassName("core.io.Queue")
if classes:
for className in classes:
resolver.addClassName(className)
# Generate boot code
bootCode = "jasy.Env.setFields(%s);" % self.__session.exportFields()
if self.__compressGeneratedCode:
bootCode = packCode(bootCode)
# Sort resulting class list
sortedClasses = resolver.getSortedClasses()
self.storeCompressed(sortedClasses, fileName, bootCode)
# Remember classes for filtering in storeLoader/storeCompressed
self.__kernelClasses = set(sortedClasses)
# Reset static permutation
self.__session.resetCurrentPermutation()
Console.outdent()
0
Example 31
Project: jasy Source File: OutputManager.py
def storeCompressed(self, classes, fileName, bootCode=None):
"""
Combines the compressed result of the stored class list
:param classes: List of sorted classes to compress
:type classes: list
:param fileName: Filename to write result to
:type fileName: string
:param bootCode: Code to execute once all the classes are loaded
:type bootCode: string
"""
if self.__kernelClasses:
filtered = [ classObj for classObj in classes if not classObj in self.__kernelClasses ]
else:
filtered = classes
Console.info("Compressing %s classes...", len(filtered))
Console.indent()
result = []
if self.__assetManager:
assetData = self.__assetManager.export(filtered)
if assetData:
assetCode = "jasy.Asset.addData(%s);" % assetData
if self.__compressGeneratedCode:
result.append(packCode(assetCode))
else:
result.append(assetCode)
permutation = self.__session.getCurrentPermutation()
try:
for classObj in filtered:
result.append(classObj.getCompressed(permutation,
self.__session.getCurrentTranslationBundle(), self.__scriptOptimization, self.__scriptFormatting))
except ClassError as error:
raise UserError("Error during class compression! %s" % error)
Console.outdent()
if bootCode:
bootCode = "(function(){%s})();" % bootCode
if self.__compressGeneratedCode:
result.append(packCode(bootCode))
else:
result.append(bootCode)
if self.__compressGeneratedCode:
compressedCode = "".join(result)
else:
compressedCode = "\n\n".join(result)
self.__fileManager.writeFile(fileName, compressedCode)
0
Example 32
Project: jasy Source File: OutputManager.py
def storeLoader(self, classes, fileName, bootCode="", urlPrefix=""):
"""
Generates a source loader which is basically a file which loads the original JavaScript files.
This is super useful during development of a project as it supports pretty fast workflows
where most often a simple reload in the browser is enough to get the newest sources.
:param classes: List of sorted classes to compress
:type classes: list
:param fileName: Filename to write result to
:type fileName: string
:param bootCode: Code to execute once all classes have been loaded
:type bootCode: string
:param urlPrefix: Prepends the given URL prefix to all class URLs to load
:type urlPrefix: string
"""
if self.__kernelClasses:
filtered = [ classObj for classObj in classes if not classObj in self.__kernelClasses ]
else:
filtered = classes
Console.info("Generating loader for %s classes...", len(classes))
Console.indent()
main = self.__session.getMain()
files = []
for classObj in filtered:
path = classObj.getPath()
# Support for multi path classes
# (typically in projects with custom layout/structure e.g. 3rd party)
if type(path) is list:
for singleFileName in path:
files.append(main.toRelativeUrl(singleFileName, urlPrefix))
else:
files.append(main.toRelativeUrl(path, urlPrefix))
result = []
Console.outdent()
if self.__assetManager:
assetData = self.__assetManager.export(filtered)
if assetData:
assetCode = "jasy.Asset.addData(%s);" % assetData
if self.__compressGeneratedCode:
result.append(packCode(assetCode))
else:
result.append(assetCode)
translationBundle = self.__session.getCurrentTranslationBundle()
if translationBundle:
translationData = translationBundle.export(filtered)
if translationData:
translationCode = 'jasy.Translate.addData(%s);' % translationData
if self.__compressGeneratedCode:
result.append(packCode(translationCode))
else:
result.append(translationCode)
if self.__compressGeneratedCode:
loaderList = '"%s"' % '","'.join(files)
else:
loaderList = '"%s"' % '",\n"'.join(files)
wrappedBootCode = "function(){ %s }" % bootCode if bootCode else "null"
loaderCode = 'core.io.Queue.load([%s], %s, null, true);' % (loaderList, wrappedBootCode)
if self.__compressGeneratedCode:
result.append(packCode(loaderCode))
else:
result.append(loaderCode)
if self.__compressGeneratedCode:
loaderCode = "".join(result)
else:
loaderCode = "\n\n".join(result)
self.__fileManager.writeFile(fileName, loaderCode)
0
Example 33
def clean(self):
"""Clears the cache of the project"""
Console.info("Clearing cache of %s..." % self.__name)
self.__cache.clear()
0
Example 34
Project: jasy Source File: Session.py
def __generateTranslationBundle(self):
"""
Returns a translation object for the given language containing
all relevant translation files for the current project set.
"""
language = self.getCurrentPermutation().get("locale")
if language is None:
return None
if language in self.__translationBundles:
return self.__translationBundles[language]
Console.info("Creating translation bundle: %s", language)
Console.indent()
# Initialize new Translation object with no project assigned
# This object is used to merge all seperate translation instances later on.
combined = jasy.item.Translation.TranslationItem(None, id=language)
relevantLanguages = self.__expandLanguage(language)
# Loop structure is build to prefer finer language matching over project priority
for currentLanguage in reversed(relevantLanguages):
for project in self.__projects:
for translation in project.getTranslations().values():
if translation.getLanguage() == currentLanguage:
Console.debug("Adding %s entries from %s @ %s...", len(translation.getTable()), currentLanguage, project.getName())
combined += translation
Console.debug("Combined number of translations: %s", len(combined.getTable()))
Console.outdent()
self.__translationBundles[language] = combined
return combined
0
Example 35
def permutate(self):
""" Generator method for permutations for improving output capabilities """
Console.info("Processing permutations...")
Console.indent()
permutations = self.__generatePermutations()
length = len(permutations)
for pos, current in enumerate(permutations):
Console.info("Permutation %s/%s:" % (pos+1, length))
Console.indent()
self.__currentPermutation = current
self.__currentTranslationBundle = self.__generateTranslationBundle()
yield current
Console.outdent()
Console.outdent()
self.__currentPermutation = None
self.__currentTranslationBundle = None
0
Example 36
Project: jasy Source File: Request.py
def requestUrl(url, content_type="text/plain", headers=None, method="GET", port=None, body="", user=None, password=None):
"""Generic HTTP request wrapper with support for basic authentification and automatic parsing of response content"""
Console.info("Opening %s request to %s..." % (method, url))
parsed = urllib.parse.urlparse(url)
if parsed.scheme== "http":
request = http.client.HTTPConnection(parsed.netloc)
elif parsed.scheme== "https":
request = http.client.HTTPSConnection(parsed.netloc)
else:
raise Exception("Unsupported url: %s" % url)
if parsed.query:
request.putrequest(method, parsed.path + "?" + parsed.query)
else:
request.putrequest(method, parsed.path)
request.putheader("Content-Type", content_type)
request.putheader("Content-Length", str(len(body)))
if user is not None and password is not None:
auth = "Basic %s" % base64.b64encode(("%s:%s" % (user, password)).encode("utf-8")).decode("utf-8")
request.putheader("Authorization", auth)
request.endheaders()
if body:
Console.info("Sending data (%s bytes)..." % len(body))
else:
Console.info("Sending request...")
Console.indent()
request.send(body)
response = request.getresponse()
res_code = int(response.getcode())
res_headers = dict(response.getheaders())
res_content = response.read()
res_success = False
if res_code >= 200 and res_code <= 300:
Console.debug("HTTP Success!")
res_success = True
else:
Console.error("HTTP Failure Code: %s!", res_code)
if "Content-Type" in res_headers:
res_type = res_headers["Content-Type"]
if ";" in res_type:
res_type = res_type.split(";")[0]
if res_type in ("application/json", "text/html", "text/plain"):
res_content = res_content.decode("utf-8")
if res_type == "application/json":
res_content = json.loads(res_content)
if "error" in res_content:
Console.error("Error %s: %s", res_content["error"], res_content["reason"])
elif "reason" in res_content:
Console.info("Success: %s" % res_content["reason"])
Console.outdent()
return res_success, res_headers, res_content
0
Example 37
Project: jasy Source File: Server.py
@cherrypy.expose
@cherrypy.tools.noBodyProcess()
def default(self, *args, **query):
"""
This method returns the content of existing files on the file system.
Query string might be used for cache busting and are otherwise ignored.
"""
url = self.config["host"] + "/".join(args)
result = None
body = None
# Try using offline mirror if feasible
if self.enableMirror and cherrypy.request.method == "GET":
mirrorId = "%s[%s]" % (url, json.dumps(query, separators=(',',':'), sort_keys=True))
result = self.mirror.read(mirrorId)
if result is not None and self.enableDebug:
Console.info("Mirrored: %s" % url)
if cherrypy.request.method in ("POST", "PUT"):
body = cherrypy.request.body.fp.read()
# Check if we're in forced offline mode
if self.enableOffline and result is None:
Console.info("Offline: %s" % url)
raise cherrypy.NotFound(url)
# Load URL from remote server
if result is None:
# Prepare headers
headers = CaseInsensitiveDict()
for name in cherrypy.request.headers:
if not name in self.__blockHeaders:
headers[name] = cherrypy.request.headers[name]
# Load URL from remote host
try:
if self.enableDebug:
Console.info("Requesting: %s", url)
# Apply headers for basic HTTP authentification
if "X-Proxy-Authorization" in headers:
headers["Authorization"] = headers["X-Proxy-Authorization"]
del headers["X-Proxy-Authorization"]
# Add headers for different authentification approaches
if self.auth:
# Basic Auth
if self.auth["method"] == "basic":
headers["Authorization"] = b"Basic " + base64.b64encode(("%s:%s" % (self.auth["user"], self.auth["password"])).encode("ascii"))
# We disable verifícation of SSL certificates to be more tolerant on test servers
result = requests.request(cherrypy.request.method, url, params=query, headers=headers, data=body, verify=False)
except Exception as err:
if self.enableDebug:
Console.info("Request failed: %s", err)
raise cherrypy.HTTPError(403)
# Storing result into mirror
if self.enableMirror and cherrypy.request.method == "GET" and result.status_code == 200:
# Wrap result into mirrorable entry
resultCopy = Result(result.headers, result.content, result.status_code)
self.mirror.store(mirrorId, resultCopy)
# Copy response headers to our reponse
for name in result.headers:
if not name.lower() in self.__blockHeaders:
cherrypy.response.headers[name] = result.headers[name]
# Set the proxyed reply status to the response status
cherrypy.response.status = result.status_code
# Append special header to all responses
cherrypy.response.headers["X-Jasy-Version"] = jasyVersion
# Enable cross domain access to this server
enableCrossDomain()
return result.content
0
Example 38
Project: jasy Source File: Server.py
@cherrypy.expose
def default(self, *args, **query):
"""
This method returns the content of existing files on the file system.
Query string might be used for cache busting and are otherwise ignored.
"""
# Append special header to all responses
cherrypy.response.headers["X-Jasy-Version"] = jasyVersion
# Enable cross domain access to this server
enableCrossDomain()
# When it's a file name in the local folder... load it
if args:
path = os.path.join(*args)
else:
path = "index.html"
path = os.path.join(self.root, path)
# Check for existance first
if os.path.isfile(path):
if self.enableDebug:
Console.info("Serving file: %s", path)
# Default content type to autodetection by Python mimetype API
contentType = None
# Support overriding by extensions
extension = os.path.splitext(path)[1]
if extension:
extension = extension.lower()[1:]
if extension in self.mimeTypes:
contentType = self.mimeTypes[extension] + "; charset=" + locale.getpreferredencoding()
return cherrypy.lib.static.serve_file(os.path.abspath(path), content_type=contentType)
# Otherwise return a classic 404
else:
if self.enableDebug:
Console.warn("File at location %s not found at %s!", path, os.path.abspath(path))
raise cherrypy.NotFound(path)
0
Example 39
def __init__(self, port=8080, host="127.0.0.1", mimeTypes=None):
Console.info("Initializing server...")
Console.indent()
# Shared configuration (global/app)
self.__config = {
"global" : {
"environment" : "production",
"log.screen" : False,
"server.socket_port": port,
"server.socket_host": host,
"engine.autoreload_on" : False
},
"/" : {
"log.screen" : False
}
}
self.__port = port
# Build dict of content types to override native mimetype detection
combinedTypes = {}
combinedTypes.update(additionalContentTypes)
if mimeTypes:
combinedTypes.update(mimeTypes)
# Update global config
cherrypy.config.update(self.__config)
# Somehow this screen disabling does not work
# This hack to disable all access/error logging works
def empty(*param, **args): pass
def inspect(*param, **args):
if args["severity"] > 20:
Console.error("Critical error occoured:")
Console.error(param[0])
cherrypy.log.access = empty
cherrypy.log.error = inspect
cherrypy.log.screen = False
# Basic routing
self.__root = Static("/", {}, mimeTypes=combinedTypes)
Console.outdent()
0
Example 40
Project: jasy Source File: Server.py
def setRoutes(self, routes):
"""
Adds the given routes to the server configuration. Routes can be used
to add special top level entries to the different features of the integrated
webserver either mirroring a remote server or delivering a local directory.
The parameters is a dict where every key is the name of the route
and the value is the configuration of that route.
"""
Console.info("Adding routes...")
Console.indent()
for key in routes:
entry = routes[key]
if "host" in entry:
node = Proxy(key, entry)
else:
node = Static(key, entry, mimeTypes=self.__root.mimeTypes)
setattr(self.__root, key, node)
Console.outdent()
0
Example 41
Project: jasy Source File: Writer.py
def mergeMixin(className, mixinName, classApi, mixinApi):
Console.info("Merging %s into %s", mixinName, className)
sectionLink = ["member", "property", "event"]
for pos, section in enumerate(("members", "properties", "events")):
mixinItems = getattr(mixinApi, section, None)
if mixinItems:
classItems = getattr(classApi, section, None)
if not classItems:
classItems = {}
setattr(classApi, section, classItems)
for name in mixinItems:
# Overridden Check
if name in classItems:
# If it was included, just store another origin
if "origin" in classItems[name]:
classItems[name]["origin"].append({
"name": mixinName,
"link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
})
# Otherwise add it to the overridden list
else:
if not "overridden" in classItems[name]:
classItems[name]["overridden"] = []
classItems[name]["overridden"].append({
"name": mixinName,
"link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
})
# Remember where classes are included from
else:
classItems[name] = {}
classItems[name].update(mixinItems[name])
if not "origin" in classItems[name]:
classItems[name]["origin"] = []
classItems[name]["origin"].append({
"name": mixinName,
"link": "%s:%s~%s" % (sectionLink[pos], mixinName, name)
})
0
Example 42
def write(self, distFolder, classFilter=None, callback="apiload", showInternals=False, showPrivates=False, printErrors=True, highlightCode=True):
"""
Writes API data generated from JavaScript into distFolder
:param distFolder: Where to store the API data
:param classFilter: Tuple of classes or method to use for filtering
:param callback: Name of callback to use for loading or None if pure JSON should be used
:param showInternals: Include internal methods inside API data
:param showPrivates: Include private methods inside API data
:param printErrors: Whether errors should be printed to the console
:param highlightCode: Whether to enable code highlighting using Pygments
:type distFolder: str
:type classFilter: tuple or function
:type callback: function
:type showInternals: bool
:type showPrivates: bool
:type printErrors: bool
:type highlightCode: bool
"""
#
# Collecting
#
Console.info("Collecting API Data...")
Console.indent()
apiData = {}
highlightedCode = {}
for project in self.__session.getProjects():
classes = project.getClasses()
Console.info("Loading API of project %s: %s...", Console.colorize(project.getName(), "bold"), Console.colorize("%s classes" % len(classes), "cyan"))
Console.indent()
for className in classes:
if self.__isIncluded(className, classFilter):
data = classes[className].getApi(highlightCode)
if not data.isEmpty:
apiData[className] = data
highlightedCode[className] = classes[className].getHighlightedCode()
else:
Console.info("Skipping %s, class is empty." % className)
Console.outdent()
Console.outdent()
#
# Processing
#
Console.info("Processing API Data...")
Console.indent()
data, index, search = self.__process(apiData, classFilter=classFilter, internals=showInternals, privates=showPrivates, printErrors=printErrors, highlightCode=highlightCode)
Console.outdent()
#
# Writing
#
Console.info("Storing API data...")
Console.indent()
writeCounter = 0
extension = "js" if callback else "json"
compress = True
class JsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, set):
return list(obj)
return json.JSONEncoder.default(self, obj)
def encode(content, name):
if compress:
jsonContent = json.dumps(content, sort_keys=True, cls=JsonEncoder, separators=(',',':'))
else:
jsonContent = json.dumps(content, sort_keys=True, cls=JsonEncoder, indent=2)
if callback:
return "%s(%s,'%s');" % (callback, jsonContent, name)
else:
return jsonContent
Console.info("Saving class data (%s files)...", len(data))
Console.indent()
for className in data:
try:
classData = data[className]
if type(classData) is dict:
classExport = classData
else:
classExport = classData.export()
File.write(self.__session.expandFileName(os.path.join(distFolder, "%s.%s" % (className, extension))), encode(classExport, className))
except TypeError as writeError:
Console.error("Could not write API data of: %s: %s", className, writeError)
continue
Console.outdent()
if highlightCode:
Console.info("Saving highlighted code (%s files)...", len(highlightedCode))
Console.indent()
for className in highlightedCode:
try:
File.write(self.__session.expandFileName(os.path.join(distFolder, "%s.html" % className)), highlightedCode[className])
except TypeError as writeError:
Console.error("Could not write highlighted code of: %s: %s", className, writeError)
continue
Console.outdent()
Console.info("Writing index...")
Console.indent()
File.write(self.__session.expandFileName(os.path.join(distFolder, "meta-index.%s" % extension)), encode(index, "meta-index"))
File.write(self.__session.expandFileName(os.path.join(distFolder, "meta-search.%s" % extension)), encode(search, "meta-search"))
Console.outdent()
Console.outdent()
0
Example 43
def __process(self, apiData, classFilter=None, internals=False, privates=False, printErrors=True, highlightCode=True):
knownClasses = set(list(apiData))
#
# Attaching Links to Source Code (Lines)
# Building Docuementation Summaries
#
Console.info("Adding Source Links...")
for className in apiData:
classApi = apiData[className]
constructData = getattr(classApi, "construct", None)
if constructData is not None:
if "line" in constructData:
constructData["sourceLink"] = "source:%s~%s" % (className, constructData["line"])
for section in ("properties", "events", "statics", "members"):
sectionData = getattr(classApi, section, None)
if sectionData is not None:
for name in sectionData:
if "line" in sectionData[name]:
sectionData[name]["sourceLink"] = "source:%s~%s" % (className, sectionData[name]["line"])
#
# Including Mixins / IncludedBy
#
Console.info("Resolving Mixins...")
Console.indent()
# Just used temporary to keep track of which classes are merged
mergedClasses = set()
def getApi(className):
classApi = apiData[className]
if className in mergedClasses:
return classApi
classIncludes = getattr(classApi, "includes", None)
if classIncludes:
for mixinName in classIncludes:
if not mixinName in apiData:
Console.error("Invalid mixin %s in class %s", className, mixinName)
continue
mixinApi = apiData[mixinName]
if not hasattr(mixinApi, "includedBy"):
mixinApi.includedBy = set()
mixinApi.includedBy.add(className)
mergeMixin(className, mixinName, classApi, getApi(mixinName))
mergedClasses.add(className)
return classApi
for className in apiData:
apiData[className] = getApi(className)
Console.outdent()
#
# Checking links
#
Console.info("Checking Links...")
additionalTypes = ("Call", "Identifier", "Map", "Integer", "Node", "Element")
def checkInternalLink(link, className):
match = internalLinkParse.match(link)
if not match:
return 'Invalid link "#%s"' % link
if match.group(3) is not None:
className = match.group(3)
if not className in knownClasses and not className in apiData:
return 'Invalid class in link "#%s"' % link
# Accept all section/item values for named classes,
# as it might be pretty complicated to verify this here.
if not className in apiData:
return True
classApi = apiData[className]
sectionName = match.group(2)
itemName = match.group(5)
if itemName is None:
return True
if sectionName is not None:
if not sectionName in linkMap:
return 'Invalid section in link "#%s"' % link
section = getattr(classApi, linkMap[sectionName], None)
if section is None:
return 'Invalid section in link "#%s"' % link
else:
if itemName in section:
return True
return 'Invalid item in link "#%s"' % link
for sectionName in ("statics", "members", "properties", "events"):
section = getattr(classApi, sectionName, None)
if section and itemName in section:
return True
return 'Invalid item link "#%s"' % link
def checkLinksInItem(item):
# Process types
if "type" in item:
if item["type"] == "Function":
# Check param types
if "params" in item:
for paramName in item["params"]:
paramEntry = item["params"][paramName]
if "type" in paramEntry:
for paramTypeEntry in paramEntry["type"]:
if not paramTypeEntry["name"] in knownClasses and not paramTypeEntry["name"] in additionalTypes and not ("builtin" in paramTypeEntry or "pseudo" in paramTypeEntry):
item["errornous"] = True
Console.error('Invalid param type "%s" in %s' % (paramTypeEntry["name"], className))
if not "pseudo" in paramTypeEntry and paramTypeEntry["name"] in knownClasses:
paramTypeEntry["linkable"] = True
# Check return types
if "returns" in item:
for returnTypeEntry in item["returns"]:
if not returnTypeEntry["name"] in knownClasses and not returnTypeEntry["name"] in additionalTypes and not ("builtin" in returnTypeEntry or "pseudo" in returnTypeEntry):
item["errornous"] = True
Console.error('Invalid return type "%s" in %s' % (returnTypeEntry["name"], className))
if not "pseudo" in returnTypeEntry and returnTypeEntry["name"] in knownClasses:
returnTypeEntry["linkable"] = True
elif not item["type"] in builtinTypes and not item["type"] in pseudoTypes and not item["type"] in additionalTypes:
item["errornous"] = True
Console.error('Invalid type "%s" in %s' % (item["type"], className))
# Process doc
if "doc" in item:
def processInternalLink(match):
linkUrl = match.group(2)
if linkUrl.startswith("#"):
linkCheck = checkInternalLink(linkUrl[1:], className)
if linkCheck is not True:
item["errornous"] = True
if sectionName:
Console.error("%s in %s:%s~%s" % (linkCheck, sectionName, className, name))
else:
Console.error("%s in %s" % (linkCheck, className))
linkExtract.sub(processInternalLink, item["doc"])
Console.indent()
# Process APIs
for className in apiData:
classApi = apiData[className]
sectionName = None
constructData = getattr(classApi, "construct", None)
if constructData is not None:
checkLinksInItem(constructData)
for sectionName in ("properties", "events", "statics", "members"):
section = getattr(classApi, sectionName, None)
if section is not None:
for name in section:
checkLinksInItem(section[name])
Console.outdent()
#
# Filter Internals/Privates
#
Console.info("Filtering Items...")
def isVisible(entry):
if "visibility" in entry:
visibility = entry["visibility"]
if visibility == "private" and not privates:
return False
if visibility == "internal" and not internals:
return False
return True
def filterInternalsPrivates(classApi, field):
data = getattr(classApi, field, None)
if data:
for name in list(data):
if not isVisible(data[name]):
del data[name]
for className in apiData:
filterInternalsPrivates(apiData[className], "statics")
filterInternalsPrivates(apiData[className], "members")
#
# Connection Interfaces / ImplementedBy
#
Console.info("Connecting Interfaces...")
Console.indent()
for className in apiData:
classApi = getApi(className)
if not hasattr(classApi, "main"):
continue
classType = classApi.main["type"]
if classType == "core.Class":
classImplements = getattr(classApi, "implements", None)
if classImplements:
for interfaceName in classImplements:
interfaceApi = apiData[interfaceName]
implementedBy = getattr(interfaceApi, "implementedBy", None)
if not implementedBy:
implementedBy = interfaceApi.implementedBy = []
implementedBy.append(className)
connectInterface(className, interfaceName, classApi, interfaceApi)
Console.outdent()
#
# Merging Named Classes
#
Console.info("Merging Named Classes...")
Console.indent()
for className in list(apiData):
classApi = apiData[className]
destName = classApi.main["name"]
if destName is not None and destName != className:
Console.debug("Extending class %s with %s", destName, className)
if destName in apiData:
destApi = apiData[destName]
destApi.main["from"].append(className)
else:
destApi = apiData[destName] = Data.ApiData(destName, highlight=highlightCode)
destApi.main = {
"type" : "Extend",
"name" : destName,
"from" : [className]
}
# If there is a "main" tag found in the class use its API description
if "tags" in classApi.main and classApi.main["tags"] is not None and "main" in classApi.main["tags"]:
if "doc" in classApi.main:
destApi.main["doc"] = classApi.main["doc"]
classApi.main["extension"] = True
# Read existing data
construct = getattr(classApi, "construct", None)
statics = getattr(classApi, "statics", None)
members = getattr(classApi, "members", None)
if construct is not None:
if hasattr(destApi, "construct"):
Console.warn("Overriding constructor in extension %s by %s", destName, className)
destApi.construct = copy.copy(construct)
if statics is not None:
if not hasattr(destApi, "statics"):
destApi.statics = {}
for staticName in statics:
destApi.statics[staticName] = copy.copy(statics[staticName])
destApi.statics[staticName]["from"] = className
destApi.statics[staticName]["fromLink"] = "static:%s~%s" % (className, staticName)
if members is not None:
if not hasattr(destApi, "members"):
destApi.members = {}
for memberName in members:
destApi.members[memberName] = copy.copy(members[memberName])
destApi.members[memberName]["from"] = className
destApi.members[memberName]["fromLink"] = "member:%s~%s" % (className, memberName)
Console.outdent()
#
# Connecting Uses / UsedBy
#
Console.info("Collecting Use Patterns...")
# This matches all uses with the known classes and only keeps them if matched
allClasses = set(list(apiData))
for className in apiData:
uses = apiData[className].uses
# Rebuild use list
cleanUses = set()
for use in uses:
if use != className and use in allClasses:
cleanUses.add(use)
useEntry = apiData[use]
if not hasattr(useEntry, "usedBy"):
useEntry.usedBy = set()
useEntry.usedBy.add(className)
apiData[className].uses = cleanUses
#
# Collecting errors
#
Console.info("Collecting Errors...")
Console.indent()
for className in sorted(apiData):
classApi = apiData[className]
errors = []
if isErrornous(classApi.main):
errors.append({
"kind": "Main",
"name": None,
"line": 1
})
if hasattr(classApi, "construct"):
if isErrornous(classApi.construct):
errors.append({
"kind": "Constructor",
"name": None,
"line": classApi.construct["line"]
})
for section in ("statics", "members", "properties", "events"):
items = getattr(classApi, section, {})
for itemName in items:
item = items[itemName]
if isErrornous(item):
errors.append({
"kind": itemMap[section],
"name": itemName,
"line": item["line"]
})
if errors:
if printErrors:
Console.warn("Found errors in %s", className)
errorsSorted = sorted(errors, key=lambda entry: entry["line"])
if printErrors:
Console.indent()
for entry in errorsSorted:
if entry["name"]:
Console.warn("%s: %s (line %s)", entry["kind"], entry["name"], entry["line"])
else:
Console.warn("%s (line %s)", entry["kind"], entry["line"])
Console.outdent()
classApi.errors = errorsSorted
Console.outdent()
#
# Building Search Index
#
Console.info("Building Search Index...")
search = {}
def addSearch(classApi, field):
data = getattr(classApi, field, None)
if data:
for name in data:
if not name in search:
search[name] = set()
search[name].add(className)
for className in apiData:
classApi = apiData[className]
addSearch(classApi, "statics")
addSearch(classApi, "members")
addSearch(classApi, "properties")
addSearch(classApi, "events")
#
# Post Process (dict to sorted list)
#
Console.info("Post Processing Data...")
for className in sorted(apiData):
classApi = apiData[className]
convertTags(classApi.main)
construct = getattr(classApi, "construct", None)
if construct:
convertFunction(construct)
convertTags(construct)
for section in ("statics", "members", "properties", "events"):
items = getattr(classApi, section, None)
if items:
sortedList = []
for itemName in sorted(items):
item = items[itemName]
item["name"] = itemName
if "type" in item and item["type"] == "Function":
convertFunction(item)
convertTags(item)
sortedList.append(item)
setattr(classApi, section, sortedList)
#
# Collecting Package Docs
#
Console.info("Collecting Package Docs...")
Console.indent()
# Inject existing package docs into api data
for project in self.__session.getProjects():
docs = project.getDocs()
for packageName in docs:
if self.__isIncluded(packageName, classFilter):
Console.debug("Creating package docuementation %s", packageName)
apiData[packageName] = docs[packageName].getApi()
# Fill missing package docs
for className in sorted(apiData):
splits = className.split(".")
packageName = splits[0]
for split in splits[1:]:
if not packageName in apiData:
Console.warn("Missing package docuementation %s", packageName)
apiData[packageName] = Data.ApiData(packageName, highlight=highlightCode)
apiData[packageName].main = {
"type" : "Package",
"name" : packageName
}
packageName = "%s.%s" % (packageName, split)
# Now register all classes in their parent namespace/package
for className in sorted(apiData):
splits = className.split(".")
packageName = ".".join(splits[:-1])
if packageName:
package = apiData[packageName]
# debug("- Registering class %s in parent %s", className, packageName)
entry = {
"name" : splits[-1],
"link" : className,
}
classMain = apiData[className].main
if "doc" in classMain and classMain["doc"]:
summary = Text.extractSummary(classMain["doc"])
if summary:
entry["summary"] = summary
if "type" in classMain and classMain["type"]:
entry["type"] = classMain["type"]
if not hasattr(package, "content"):
package.content = [entry]
else:
package.content.append(entry)
Console.outdent()
#
# Writing API Index
#
Console.debug("Building Index...")
index = {}
for className in sorted(apiData):
classApi = apiData[className]
mainInfo = classApi.main
# Create structure for className
current = index
for split in className.split("."):
if not split in current:
current[split] = {}
current = current[split]
# Store current type
current["$type"] = mainInfo["type"]
# Keep information if
if hasattr(classApi, "content"):
current["$content"] = True
#
# Return
#
return apiData, index, search
0
Example 44
Project: jasy Source File: Resolver.py
def getIncludedClasses(self):
""" Returns a final set of classes after resolving dependencies """
if self.__included:
return self.__included
Console.info("Detecting class dependencies...")
Console.indent()
collection = set()
for classObj in self.__required:
self.__resolveDependencies(classObj, collection)
# Filter excluded classes
for classObj in self.__excluded:
if classObj in collection:
collection.remove(classObj)
self.__included = collection
Console.outdent()
Console.debug("Including %s classes", len(collection))
return self.__included
0
Example 45
def clean(path=None):
"""
Cleans repository from untracked files.
:param url: Path to the local repository
:type url: string
"""
old = os.getcwd()
Console.info("Cleaning repository (clean)...")
Console.indent()
if path:
os.chdir(path)
if os.path.exists(".git"):
Git.cleanRepository()
os.chdir(old)
Console.outdent()
0
Example 46
def distclean(path=None):
"""
Cleans repository from untracked and ignored files. This method
is pretty agressive in a way that it deletes all non repository managed
files e.g. external folder, uncommitted changes, unstaged files, etc.
:param url: Path to the local repository
:type url: string
"""
old = os.getcwd()
Console.info("Cleaning repository (distclean)...")
Console.indent()
if path:
os.chdir(path)
if os.path.exists(".git"):
Git.distcleanRepository()
os.chdir(old)
Console.outdent()