1 | """This module is about reading YAML files for Rainmeter related definition files.""" |
||
2 | |||
3 | |||
4 | import os.path |
||
5 | import zipfile |
||
6 | |||
7 | import sublime |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
8 | |||
9 | from .. import logger |
||
0 ignored issues
–
show
|
|||
10 | |||
11 | |||
12 | class YamlContentReader(object): # pylint: disable=R0903; this is an abstract class |
||
0 ignored issues
–
show
|
|||
13 | """ |
||
14 | Use this to read the content of yamls inside of sublime text packages. |
||
15 | |||
16 | supports multiple ways to access them: |
||
17 | * .sublime-package |
||
18 | * .zip |
||
19 | * folder |
||
20 | """ |
||
21 | |||
22 | @classmethod |
||
23 | def __get_zip_content(cls, path_to_zip, resource): |
||
24 | if not os.path.exists(path_to_zip): |
||
25 | return None |
||
26 | |||
27 | ret_value = None |
||
28 | |||
29 | with zipfile.ZipFile(path_to_zip) as zip_file: |
||
30 | namelist = zip_file.namelist() |
||
31 | if resource in namelist: |
||
32 | ret_value = zip_file.read(resource) |
||
33 | return ret_value.decode("utf-8") |
||
34 | |||
35 | logger.error("no zip content with resource '" + resource + "' found in .") |
||
36 | |||
37 | return ret_value |
||
38 | |||
39 | def __yaml_content_in_package(self, package, dir_of_yaml, yaml_file): |
||
40 | # try searching in Installed Packages e.g. if packaged in .sublime-package |
||
41 | packages_path = sublime.installed_packages_path() |
||
42 | sublime_package = package + ".sublime-package" |
||
43 | rm_package_path = os.path.join(packages_path, sublime_package) |
||
44 | if os.path.exists(rm_package_path): |
||
45 | logger.info("found packaged resource in '" + rm_package_path + "'") |
||
46 | resource = dir_of_yaml + yaml_file |
||
47 | |||
48 | return self.__get_zip_content(rm_package_path, resource) |
||
49 | |||
50 | return None |
||
51 | |||
52 | @classmethod |
||
53 | def __yaml_content_by_sublime_api(cls, dir_of_yaml, yaml_file): |
||
54 | # try over sublimes find resources first |
||
55 | # should handle loose and packaged version |
||
56 | for resource in sublime.find_resources(yaml_file): |
||
57 | if dir_of_yaml in resource: |
||
58 | logger.info( |
||
59 | "found sublime resource '" + dir_of_yaml + yaml_file + "' in '" + resource + "'" |
||
60 | ) |
||
61 | return sublime.load_resource(resource) |
||
62 | |||
63 | @classmethod |
||
64 | def __yaml_content_by_git_path(cls, dir_of_yaml, yaml_file): |
||
65 | # try over absolute paths determined from root e.g. by cloning with git |
||
66 | rm_root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
||
67 | # the dir_of_yaml comes in as foo/bar but internally python uses foo\\bar |
||
68 | norm_dir_of_yaml = os.path.normpath(dir_of_yaml) |
||
69 | # e.g. Rainmeter + completion/skin + metadata_section.yaml |
||
70 | yaml_path = os.path.join(rm_root_path, norm_dir_of_yaml, yaml_file) |
||
71 | |||
72 | if os.path.exists(yaml_path): |
||
73 | logger.info("found absolute resource in '" + yaml_path + "'") |
||
74 | with open(yaml_path, 'r') as yaml_content_stream: |
||
75 | return yaml_content_stream.read() |
||
76 | |||
77 | @staticmethod |
||
78 | def __fail(dir_of_yaml, yaml_file): |
||
79 | logger.error( |
||
80 | "found not yaml neither via sublime resources, nor absolute pathing, " + |
||
81 | "nor .sublime-package for '" + dir_of_yaml + yaml_file + "'." |
||
82 | ) |
||
83 | return None |
||
84 | |||
85 | def _get_yaml_content(self, dir_of_yaml, yaml_file): |
||
86 | """ |
||
87 | Get yaml content of a yaml file. |
||
88 | |||
89 | It is located either in: |
||
90 | * Installed Packages/Rainmeter.sublime-package |
||
91 | * Packages/Rainmeter |
||
92 | Parameters |
||
93 | ---------- |
||
94 | """ |
||
95 | return self.__yaml_content_by_sublime_api(dir_of_yaml, yaml_file) or \ |
||
96 | self.__yaml_content_by_git_path(dir_of_yaml, yaml_file) or \ |
||
97 | self.__yaml_content_in_package("Rainmeter", dir_of_yaml, yaml_file) or \ |
||
98 | YamlContentReader.__fail(dir_of_yaml, yaml_file) |
||
99 |