|
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 |
|
8
|
|
|
|
|
9
|
|
|
from .. import logger |
|
|
|
|
|
|
10
|
|
|
|
|
11
|
|
|
|
|
12
|
|
|
class YamlContentReader(object): # pylint: disable=R0903; this is an abstract class |
|
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
|
|
|
def __yaml_content_by_sublime_api(self, dir_of_yaml, yaml_file): |
|
|
|
|
|
|
53
|
|
|
# try over sublimes find resources first |
|
54
|
|
|
# should handle loose and packaged version |
|
55
|
|
|
for resource in sublime.find_resources(yaml_file): |
|
56
|
|
|
if dir_of_yaml in resource: |
|
57
|
|
|
logger.info( |
|
58
|
|
|
"found sublime resource '" + dir_of_yaml + yaml_file + "' in '" + resource + "'" |
|
59
|
|
|
) |
|
60
|
|
|
return sublime.load_resource(resource) |
|
61
|
|
|
|
|
62
|
|
|
def __yaml_content_by_git_path(self, dir_of_yaml, yaml_file): |
|
|
|
|
|
|
63
|
|
|
# try over absolute paths determined from root e.g. by cloning with git |
|
64
|
|
|
rm_root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) |
|
65
|
|
|
# the dir_of_yaml comes in as foo/bar but internally python uses foo\\bar |
|
66
|
|
|
norm_dir_of_yaml = os.path.normpath(dir_of_yaml) |
|
67
|
|
|
# e.g. Rainmeter + completion/skin + metadata_section.yaml |
|
68
|
|
|
yaml_path = os.path.join(rm_root_path, norm_dir_of_yaml, yaml_file) |
|
69
|
|
|
|
|
70
|
|
|
if os.path.exists(yaml_path): |
|
71
|
|
|
logger.info("found absolute resource in '" + yaml_path + "'") |
|
72
|
|
|
with open(yaml_path, 'r') as yaml_content_stream: |
|
73
|
|
|
return yaml_content_stream.read() |
|
74
|
|
|
|
|
75
|
|
|
@staticmethod |
|
76
|
|
|
def __fail(dir_of_yaml, yaml_file): |
|
|
|
|
|
|
77
|
|
|
logger.error( |
|
78
|
|
|
"found not yaml neither via sublime resources, nor absolute pathing, " + |
|
79
|
|
|
"nor .sublime-package for '" + dir_of_yaml + yaml_file + "'." |
|
80
|
|
|
) |
|
81
|
|
|
return None |
|
82
|
|
|
|
|
83
|
|
|
def _get_yaml_content(self, dir_of_yaml, yaml_file): |
|
84
|
|
|
""" |
|
85
|
|
|
Get yaml content of a yaml file. |
|
86
|
|
|
|
|
87
|
|
|
It is located either in: |
|
88
|
|
|
* Installed Packages/Rainmeter.sublime-package |
|
89
|
|
|
* Packages/Rainmeter |
|
90
|
|
|
Parameters |
|
91
|
|
|
---------- |
|
92
|
|
|
""" |
|
93
|
|
|
return self.__yaml_content_by_sublime_api(dir_of_yaml, yaml_file) or \ |
|
94
|
|
|
self.__yaml_content_by_git_path(dir_of_yaml, yaml_file) or \ |
|
95
|
|
|
self.__yaml_content_in_package("Rainmeter", dir_of_yaml, yaml_file) or \ |
|
96
|
|
|
YamlContentReader.__fail(dir_of_yaml, yaml_file) |
|
97
|
|
|
|