Skip to content

Commit 52c4c0d

Browse files
committed
Lazy import loaders's dependencies
1 parent 2eeb870 commit 52c4c0d

17 files changed

+125
-68
lines changed

README-EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ git clone https://github.com/yihong0618/GitHubPoster.git
4242
## pip install
4343

4444
```
45-
pip3 install -U github_poster
45+
pip3 install -U 'github_poster[all]'
4646
```
4747

4848
## Install(Python3.6+)

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ git clone https://github.com/yihong0618/GitHubPoster.git
5454
## pip 安装
5555

5656
```
57-
pip3 install -U github_poster
57+
pip3 install -U 'github_poster[all]'
5858
```
5959

6060
## 安装(Python3.6+)

github_poster/circluar_drawer.py

-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ def _draw_circle_segment(
162162
center,
163163
key_animate,
164164
):
165-
color = self.make_color(self.poster.length_range_by_date, length)
166165
color = self.make_color(self.poster.length_range_by_date, length)
167166
r1 = rr.lower()
168167
r2 = (

github_poster/cli.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@
44

55
import argparse
66
import os
7+
import sys
78

89
from github_poster.circluar_drawer import CircularDrawer
910
from github_poster.config import TYPE_INFO_DICT
1011
from github_poster.drawer import Drawer
12+
from github_poster.err import DepNotInstalledError
1113
from github_poster.loader import LOADER_DICT
1214
from github_poster.poster import Poster
13-
from github_poster.skyline import Skyline
1415
from github_poster.utils import parse_years
1516

1617
OUT_FOLDER = os.path.join(os.getcwd(), "OUT_FOLDER")
1718

1819

19-
def main():
20+
def run():
2021
"""Handle command line arguments and call other modules as needed."""
2122
p = Poster()
2223
args_parser = argparse.ArgumentParser()
@@ -133,6 +134,14 @@ def main():
133134

134135
# generate skyline
135136
if args.with_skyline:
137+
try:
138+
from github_poster.skyline import Skyline
139+
except ImportError:
140+
raise Exception(
141+
"Skyline dependencies are not installed, "
142+
"please use 'pip3 install -U github_poster[skyline]' to install."
143+
)
144+
136145
if args.skyline_year:
137146
year = args.skyline_year
138147
else:
@@ -153,5 +162,12 @@ def main():
153162
s.make_skyline()
154163

155164

165+
def main():
166+
try:
167+
run()
168+
except DepNotInstalledError as e:
169+
print(e, file=sys.stderr)
170+
171+
156172
if __name__ == "__main__":
157173
main()

github_poster/err.py

+5
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ class CircularDrawError(BaseDrawError):
1212
"""
1313

1414
pass
15+
16+
17+
class DepNotInstalledError(Exception):
18+
def __str__(self):
19+
return self.args[0]

github_poster/loader/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from github_poster.loader.json_loader import JsonLoader
1414
from github_poster.loader.kindle_loader import KindleLoader
1515
from github_poster.loader.leetcode_loader import LeetcodeLoader
16-
from github_poster.loader.multiple_loader import MutipleLoader
16+
from github_poster.loader.multiple_loader import MultipleLoader
1717
from github_poster.loader.notion_loader import NotionLoader
1818
from github_poster.loader.nrc_loader import NRCLoader
1919
from github_poster.loader.ns_loader import NSLoader
@@ -43,7 +43,7 @@
4343
"kindle": KindleLoader,
4444
"wakatime": WakaTimeLoader,
4545
"dota2": Dota2Loader,
46-
"multiple": MutipleLoader,
46+
"multiple": MultipleLoader,
4747
"nike": NRCLoader,
4848
"notion": NotionLoader,
4949
"garmin": GarminLoader,
@@ -71,7 +71,7 @@
7171
"TwitterLoader",
7272
"WakaTimeLoader",
7373
"YouTubeLoader",
74-
"MutipleLoader",
74+
"MultipleLoader",
7575
"NotionLoader",
7676
"NRCLoader",
7777
"LOADER_DICT",

github_poster/loader/base_loader.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from http.cookies import SimpleCookie
55

66
import pendulum
7-
import pytz
87
from requests.utils import cookiejar_from_dict
98

109
from github_poster.loader.config import TIME_ZONE
@@ -33,6 +32,11 @@ def __init__(self, from_year, to_year, _type, **kwargs):
3332
self.special_number2 = None
3433
self.number_list = []
3534
self.year_list = self._make_years_list()
35+
self.try_import_deps()
36+
37+
@classmethod
38+
def try_import_deps(cls):
39+
pass
3640

3741
def _make_years_list(self):
3842
return list(range(int(self.from_year), int(self.to_year) + 1))
@@ -66,7 +70,7 @@ def make_special_number(self):
6670
self.special_number2 = number_list_set[-1 * int(number_list_set_len * 0.50)]
6771

6872
def adjust_time(self, time):
69-
tc_offset = datetime.now(pytz.timezone(self.time_zone)).utcoffset()
73+
tc_offset = datetime.now(pendulum.timezone(self.time_zone)).utcoffset()
7074
return time + tc_offset
7175

7276
@staticmethod

github_poster/loader/bilibili_loader.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import time
22
from collections import defaultdict
3-
from http.cookies import SimpleCookie
43

54
import pendulum
65
import requests

github_poster/loader/from_github_issue_loader.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pendulum
2-
from github import Github
32

3+
from github_poster.err import DepNotInstalledError
44
from github_poster.loader.base_loader import BaseLoader
55

66

@@ -12,6 +12,16 @@ def __init__(self, from_year, to_year, _type, **kwargs):
1212
# for private repo
1313
self.token = kwargs.get("github_token", "")
1414

15+
@classmethod
16+
def try_import_deps(cls):
17+
try:
18+
import github
19+
except ImportError:
20+
raise DepNotInstalledError(
21+
"GitHub dependencies are not installed, "
22+
"please use 'pip3 install -U github_poster[github]' to install."
23+
) from None
24+
1525
@classmethod
1626
def add_loader_arguments(cls, parser, optional):
1727
parser.add_argument(
@@ -45,6 +55,8 @@ def __map_func(comment):
4555
return 0
4656

4757
def get_api_data(self):
58+
from github import Github
59+
4860
if self.token:
4961
u = Github(self.token)
5062
me = u.get_user().login

github_poster/loader/garmin_loader.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from collections import defaultdict
22

3-
from garminconnect import Garmin
4-
3+
from github_poster.err import DepNotInstalledError
54
from github_poster.loader.base_loader import BaseLoader
65

76

@@ -19,6 +18,16 @@ def __init__(self, from_year, to_year, _type, **kwargs):
1918
self.is_cn = kwargs.get("cn", False)
2019
self.client = None
2120

21+
@classmethod
22+
def try_import_deps(cls):
23+
try:
24+
import garminconnect
25+
except ImportError:
26+
raise DepNotInstalledError(
27+
"Garmin dependencies are not installed, "
28+
"please use 'pip3 install -U github_poster[garmin]' to install."
29+
) from None
30+
2231
@classmethod
2332
def add_loader_arguments(cls, parser, optional):
2433
parser.add_argument(
@@ -37,6 +46,8 @@ def add_loader_arguments(cls, parser, optional):
3746
)
3847

3948
def _get_access(self):
49+
from garminconnect import Garmin
50+
4051
try:
4152
self.client = Garmin(
4253
self.garmin_user_name, self.garmin_password, is_cn=self.is_cn

github_poster/loader/gpx_loader.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import os
33
from collections import defaultdict
44

5-
import gpxpy
6-
5+
from github_poster.err import DepNotInstalledError
76
from github_poster.loader.base_loader import BaseLoader, LoadError
87
from github_poster.loader.config import GPX_ACTIVITY_NAME_TUPLE
98

@@ -18,6 +17,16 @@ def __init__(self, from_year, to_year, _type, **kwargs):
1817
self.after = None
1918
self.base_dir = kwargs.get("gpx_dir", "")
2019

20+
@classmethod
21+
def try_import_deps(cls):
22+
try:
23+
import gpxpy
24+
except ImportError:
25+
raise DepNotInstalledError(
26+
"GPX dependencies are not installed, "
27+
"please use 'pip3 install -U github_poster[gpx]' to install."
28+
) from None
29+
2130
@classmethod
2231
def add_loader_arguments(cls, parser, optional):
2332
parser.add_argument(
@@ -45,6 +54,8 @@ def _list_gpx_files(self):
4554
yield path_name
4655

4756
def __parse_gpx(self, file_name):
57+
import gpxpy
58+
4859
with open(file_name) as f:
4960
gpx = gpxpy.parse(f)
5061
try:

github_poster/loader/jike_loader.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import time
3-
from http.cookies import SimpleCookie
43
from random import randint
54
from re import compile
65

github_poster/loader/multiple_loader.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from github_poster.loader.base_loader import BaseLoader
77

88

9-
class MutipleLoader(BaseLoader):
9+
class MultipleLoader(BaseLoader):
1010
def __init__(self, from_year, to_year, _type, **kwargs):
1111
super().__init__(from_year, to_year, _type)
1212
self.types = kwargs.get("types", "")

github_poster/loader/strava_loader.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import datetime
22
from collections import defaultdict
33

4-
import stravalib
5-
4+
from github_poster.err import DepNotInstalledError
65
from github_poster.loader.base_loader import BaseLoader, LoadError
76

87

@@ -11,6 +10,8 @@ class StravaLoader(BaseLoader):
1110

1211
def __init__(self, from_year, to_year, _type, **kwargs):
1312
super().__init__(from_year, to_year, _type)
13+
import stravalib
14+
1415
self.before = None
1516
self.after = None
1617
self.number_by_date_dict = defaultdict(float)
@@ -20,6 +21,16 @@ def __init__(self, from_year, to_year, _type, **kwargs):
2021
self.refresh_token = kwargs.get("strava_refresh_token", "")
2122
self.strava_access = False
2223

24+
@classmethod
25+
def try_import_deps(cls):
26+
try:
27+
import stravalib
28+
except ImportError:
29+
raise DepNotInstalledError(
30+
"Strava dependencies are not installed, "
31+
"please use 'pip3 install -U github_poster[strava]' to install."
32+
) from None
33+
2334
@classmethod
2435
def add_loader_arguments(cls, parser, optional):
2536
parser.add_argument(

github_poster/loader/twitter_loader.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import twint
2-
1+
from github_poster.err import DepNotInstalledError
32
from github_poster.loader.base_loader import BaseLoader
43

54

@@ -9,9 +8,21 @@ class TwitterLoader(BaseLoader):
98

109
def __init__(self, from_year, to_year, _type, **kwargs):
1110
super().__init__(from_year, to_year, _type)
11+
import twint
12+
1213
self.user_name = kwargs.get("twitter_user_name", "")
1314
self.c = twint.Config()
1415

16+
@classmethod
17+
def try_import_deps(cls):
18+
try:
19+
import twint
20+
except ImportError:
21+
raise DepNotInstalledError(
22+
"Twitter dependencies are not installed, "
23+
"please use 'pip3 install -U github_poster[twitter]' to install."
24+
) from None
25+
1526
@classmethod
1627
def add_loader_arguments(cls, parser, optional):
1728
parser.add_argument(
@@ -23,6 +34,8 @@ def add_loader_arguments(cls, parser, optional):
2334
)
2435

2536
def get_api_data(self):
37+
import twint
38+
2639
self.c.Username = self.user_name
2740
self.c.Custom["tweet"] = ["id"]
2841
self.c.Custom["user"] = ["bio"]

requirements.txt

+1-13
Original file line numberDiff line numberDiff line change
@@ -1,13 +1 @@
1-
PyGithub
2-
gpxpy
3-
stravalib
4-
svgwrite
5-
pendulum
6-
requests
7-
colour
8-
# my fork from sdf
9-
sdf_fork
10-
# my fork twint for twitter loader
11-
twint_fork
12-
# for garmin connect
13-
garminconnect
1+
-e .[all]

0 commit comments

Comments
 (0)