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
|
|
|
@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
|
|
|
|