Memory alias between inherited and super classes in Python - class

I build an inherited class (Folder) which creates an instance of itself. The problem is: the new instance which it creates copies the super class memory. I don't want this to enable recursive folder exploration. Let's say:
class FileOperator():
__dir = '.'
def __init__(self, dir:str):
self.__dir = dir
def get_dir(self):
return self.__dir
class Folder(FileOperator):
__sub_folders = {}
__files = {}
def __init__(self, dir:str):
super().__init__(dir)
def new_folder(self, name:str):
new_dir = self.get_dir() + name + '/'
folder = Folder(new_dir)
self.__sub_folders[name] = folder
return folder
def get_folder(self, name:str)
return self.__sub_folders[name]
This way we want to build new folders with same names under different folders and each instance would have different list of folders. Such as:
f = folder.get_folder('Data1').get_folder('subData1').get_folder('Data1')
When we do:
folder = Folder('./demo_data/')
sub_folder = folder.new_folder('demo_sub')
it creates a new sub_folder which has the same subfolders with its super's. sub_folder includes itself in its __sub_folders dictionary. When we try to reach a specific folder (e.g.: under categoryA, itemB), it confuses the other files and folders with same name in the dictionary. What it should do is to distinguish the two different subfolders with same name in different root folder.
So, we are not able to separate different sub folders when we access them with their names in the dictionary because each instance has the same list of subfolders generated so far. Therefore it confuses the names of different folder instances.
We need separated instances to access different folders with same name.
Should we use deepcopy here? (if yes, how?) Or should we have another meta class that controls the system with IoC (inversion of control)?

Related

Access resources inside library

I have a project L which is published as a library.
Inside L, there is a resources folder and a snippet of code that access the content.
I created a second module in L to add a main as a test, and it works.
Now when I include L into my other project, it doesnt find the folder located inside the resources of L.
in all the below path is equal to folder_i_am_looking_for and I generate varieties with /$path, $path/, $path and /$path/. ( I am desperate at this point )
I tried:
getClass.getClassLoader.getResource(path).getPath,
getClass.getClassLoader.getResource(path).toExternalForm,
getClass.getResource(path).getPath,
getClass.getResource(path).toExternalForm,
as well as
val location: URL = this.getClass.getProtectionDomain.getCodeSource.getLocation
Paths
.get(location.toURI)
.resolve("../classes/" + path)
.normalize()
.toFile
.getAbsoluteFile
.toString
from https://stackoverflow.com/a/54142960
and for each generated path, I've tried to :
input ::
input.split('!').last ::
input.split("file:/").last ::
input.split("file:").last ::
Nil
from https://stackoverflow.com/a/5346020
each time , i get path that looks like :
/path/to/projectFolder/jar:file:/path/to/library/lib_2.11-version.jar!/folder
I let you imagine all the variety of different path I get with all the above operations.
None of them find the directory.
I am testing all path simultaneously with ZIO.validateFirstPar so if you have any idea, I can add more to test.
Thank you.

Dynamically Fill Jenkins Job Parameter with Github Directory Files

I'm aware of the Dynamic Parameter and Dynamic Extended Choice Parameter plugins. I'm looking for a way to list of text files in a directory in github as drop down list parameter. is there a groovy script or similar that can populate the dropdown with file names?
You can use the github api to fetch a list of files for a given path on a given repo.
So for example, to look inside the ratpack-groovy/src/main/java/ratpack/groovy folder of the ratpack project on github, you can do:
import groovy.json.*
def contents = new JsonSlurper().parse('https://api.github.com/repos/ratpack/ratpack/contents/ratpack-groovy/src/main/java/ratpack/groovy'.toURL())
.sort { it.type } // Directories first
.collect { it.name + (it.type == 'dir' ? '/' : '') } // Put a slash on the end of directories
assert contents = ['handling/',
'internal/',
'render/',
'script/',
'server/',
'sql/',
'template/',
'Groovy.java',
'GroovyRatpackMain.java',
'package-info.java']
Obviously you can only make 60 requests per hour

Using resource files (CultureInfo) in C# class file

I need a help with using resource files in C# class files.
My code:
class errorMessages
{
private static ResourceManager LocRM = new ResourceManager("Project1.languageFile", typeof(errorMessages).Assembly);
public static void XMLParseError(String msg)
{
MessageBox.Show(LocRM.GetString("XMLParseError") + "\n" + msg, LocRM.GetString("error"),
MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}
}
+ created 2 .resx files named languageFile.en.resx and languageFile.pl-PL.resx in main Project1 folder
Now I want to use String from languageFile, in my class errorMessages, specified to localization which was set before. How can I do it?
I tried to add my Strings to WinForm .resx file, but that's clearing my data with any edit of WinForm.
I found answer for my question by myself, so I will write that solution, I hope it will help somebody.
Default resources file is located in [projectName]/Properties. I you want to add manually localizable resource files, you need to do that this way:
right click on Project in Solution Explorer -> Add new item -> resource file
Then set the name of file to Resources.[language].resx - in my case that are two files, Resources.pl-PL.resx and Resources.en.resx. After file is created, move it to Properties directory.
Now you can add your resources and use it this way:
MessageBox.Show(Project1.Properties.Resources.XMLParseError, Project1.Properties.Resources.information,
MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
Now chosen String will be in language setted in CultureInfo, or, if there is no that resource, default Resource file will be used.
source: MSDN - How to: Create a Localized Version of a Resource File

How to get paths for relocatable schemas in Gio.Settings?

In Gio.Settings I can list relocatable schemas using
Gio.Settings.list_relocatable_schemas()
and I can use
Gio.Settings.new_with_path(schema_id, path)
to get a Gio.Settings instance. But how can I get all value for path that are currently used for a given schema_id?
Normally, a schema has as fixed path that determines where the
settings are stored in the conceptual global tree of settings.
However, schemas can also be ‘relocatable’, i.e. not equipped with a
fixed path. This is useful e.g. when the schema describes an
‘account’, and you want to be able to store a arbitrary number of
accounts.
Isn't the new_with_path just for that? You have to store the schemas somewhere associated with accounts, but that is not the responsibility of the Settings system. I think new_with_path is for the case where your schemas depend on accounts.
I think you can find more information with GSettingsSchemas - this is an example in the Description for a case where the Schema is part of a plugin.
Unfortunately you cannot do it from Gio.Settings.
I see two options here:
Keep separate gsetting to store paths of relocatable schemas
Utilize dconf API, which is a low-level configuration system. Since there is no Python binding (guessing it's Python question) I suggest using ctypes for binding with C.
If you know the root path of your relocatable schemas you can use below snippet list them.
import ctypes
from ctypes import Structure, POINTER, byref, c_char_p, c_int, util
from typing import List
class DconfClient:
def __init__(self):
self.__dconf_client = _DCONF_LIB.dconf_client_new()
def list(self, directory: str) -> List[str]:
length_c = c_int()
directory_p = c_char_p(directory.encode())
result_list_c = _DCONF_LIB.dconf_client_list(self.__dconf_client, directory_p, byref(length_c))
result_list = self.__decode_list(result_list_c, length_c.value)
return result_list
def __decode_list(self, list_to_decode_c, length):
new_list = []
for i in range(length):
# convert to str and remove slash at the end
decoded_str = list_to_decode_c[i].decode().rstrip("/")
new_list.append(decoded_str)
return new_list
class _DConfClient(Structure):
_fields_ = []
_DCONF_LIB = ctypes.CDLL(util.find_library("dconf"))
_DCONF_LIB.dconf_client_new.argtypes = []
_DCONF_LIB.dconf_client_new.restype = POINTER(_DConfClient)
_DCONF_LIB.dconf_client_new.argtypes = []
_DCONF_LIB.dconf_client_list.argtypes = [POINTER(_DConfClient), c_char_p, POINTER(c_int)]
_DCONF_LIB.dconf_client_list.restype = POINTER(c_char_p)
You can't, at least not for an arbitrary schema, and this is by definition of what a relocatable schema is: a schema that can have multiple instances, stored in multiple arbitrary paths.
Since a relocatable schema instance can be stored basically anywhere inside DConf, gsettings has no way to list their paths, it does not keep track of instances. And dconf can't help you either, as it has no notion of schemas at all, it only knows about paths and keys. It can list the subpaths of a given path, but that's about it.
It's up for the application, when creating multiple instances of a given relocatable schema, to store each instance in a sensible, easily discoverable path, such as a subpath of the (non-relocatable) application schema. Or store the instance paths (or suffixes) as a list key in such schema.
Or both, like Gnome Terminal does with its profiles:
org.gnome.Terminal.ProfilesList is a non-relocatable, regular schema, stored at DConf path /org/gnome/terminal/legacy/profiles:/
That schema has 2 keys, a default string with a single UUID, and a list list of strings containing UUIDs.
Each profile is an instance of the relocatable schema org.gnome.Terminal.Legacy.Profile, and stored at, you guess... /org/gnome/terminal/legacy/profiles:/:<UUID>/!
This way a client can access all instances using either gsettings, reading list and building the paths from the UUIDs, or from dconf, by directly listing the subpaths of /org/gnome/terminal/legacy/profiles:/.
And, of course, for non-relocatable schemas you can always get their paths with:
gsettings list-schemas --print-paths

TypeLite generate external modules?

I am trying to generate external modules rather than a type definition file. I believe I need to do the following:
Change the extension of the file to .ts instead of .d.ts.
Generate one file per module.
Add the key word "Export" in front of each interface and enum.
I was easily able to change the extension of the file by changing the "output extension" setting in the tt file.
I cannot figure out how to split the modules into separate files.
I cannot figure out how to add the Export key word to each interface.
TypeLITE doesn't support generating multiple files. This feature has been requested by several users, but I am not aware of a simple way to generate multiple files from the single tt file.
export keyword can't be added without changing source code of the library (TsGenerator.cs). This is very specific requirement, so I probably won't add it to the library.
TypeLite is a good project but lacking in Documentation and examples, it's open source so anyone can contribute and make it better.
As for creating a file per class i solved it using the code below.
private static void GenerateTypeScriptContracts(string assemblyFile, string outputPath)
{
// Clean TS Folder
System.IO.DirectoryInfo di = new DirectoryInfo(outputPath);
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
// --
var assembly = Assembly.LoadFrom(assemblyFile);
// If you want a subset of classes from this assembly, filter them here
var models = assembly.GetTypes();
foreach (var model in models)
{
var generator = new TypeScriptFluent()
.WithConvertor<Guid>(c => "string")
.WithMemberFormatter((identifier) => Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1));
generator.ModelBuilder.Add(model);
// Generate TS interface definitions
var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);
File.WriteAllText(Path.Combine(outputPath, "I" + model.FullName.Replace("ProjectName.DtoModels.", "") + ".ts"), tsClassDefinitions);
}
}