funread 1.1.2__tar.gz → 1.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {funread-1.1.2/src/funread.egg-info → funread-1.1.4}/PKG-INFO +1 -1
- {funread-1.1.2 → funread-1.1.4}/pyproject.toml +1 -1
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/download/base.py +57 -50
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/download/rss.py +5 -2
- funread-1.1.4/src/funread/legado/manage/rss.py +93 -0
- {funread-1.1.2 → funread-1.1.4/src/funread.egg-info}/PKG-INFO +1 -1
- {funread-1.1.2 → funread-1.1.4}/src/funread.egg-info/SOURCES.txt +1 -0
- {funread-1.1.2 → funread-1.1.4}/LICENSE +0 -0
- {funread-1.1.2 → funread-1.1.4}/README.md +0 -0
- {funread-1.1.2 → funread-1.1.4}/setup.cfg +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/download/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/download/book.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/download/generate.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/utils/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/legado/manage/utils/core.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/scripts/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/scripts/command.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/page/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/page/video.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/page/video_list.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/parse/__init__.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/parse/base.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread/web/parse/video.py +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread.egg-info/dependency_links.txt +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread.egg-info/requires.txt +0 -0
- {funread-1.1.2 → funread-1.1.4}/src/funread.egg-info/top_level.txt +0 -0
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
|
-
from datetime import datetime
|
|
4
3
|
import traceback
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
5
6
|
import pandas as pd
|
|
6
7
|
import requests
|
|
7
8
|
from funfile import pickle, funos
|
|
8
9
|
from funfile.compress import tarfile
|
|
9
10
|
from funread.legado.manage.utils import url_to_hostname
|
|
10
11
|
from funsecret import get_md5_str
|
|
12
|
+
from funutil import getLogger
|
|
11
13
|
from tqdm import tqdm
|
|
12
14
|
|
|
15
|
+
logger = getLogger('funread')
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
class DownloadSource(object):
|
|
15
19
|
def __init__(self, path="./funread-hub", cate1="rss", *args, **kwargs):
|
|
@@ -29,26 +33,11 @@ class DownloadSource(object):
|
|
|
29
33
|
funos.makedirs(self.path_bok)
|
|
30
34
|
funos.makedirs(self.path_pkl)
|
|
31
35
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
if os.path.exists(self.pkl_url):
|
|
35
|
-
df = pd.read_pickle(self.pkl_url, compression="infer")
|
|
36
|
-
self.url_map = {k: v for k, v in df.values}
|
|
37
|
-
else:
|
|
38
|
-
self.url_map = {"https://farfarfun.github.com": 100000}
|
|
39
|
-
self.current_id = max(self.url_map.values())
|
|
40
|
-
if os.path.exists(self.pkl_md5):
|
|
41
|
-
df = pd.read_pickle(self.pkl_md5, compression="infer")
|
|
42
|
-
self.md5_set = {info["md5"]: info for info in df.to_dict(orient="records")}
|
|
43
|
-
|
|
44
|
-
def dumps(self):
|
|
45
|
-
print("dumps")
|
|
36
|
+
def loader(self):
|
|
37
|
+
raise NotImplementedError
|
|
46
38
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
df = pd.DataFrame(self.md5_set.values())
|
|
51
|
-
df.to_pickle(self.pkl_md5, compression="infer")
|
|
39
|
+
def source_format(self, source):
|
|
40
|
+
raise NotImplementedError
|
|
52
41
|
|
|
53
42
|
def url_index(self, url):
|
|
54
43
|
if url in self.url_map:
|
|
@@ -58,8 +47,30 @@ class DownloadSource(object):
|
|
|
58
47
|
self.url_map[url] = self.current_id
|
|
59
48
|
return self.current_id
|
|
60
49
|
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
@staticmethod
|
|
51
|
+
def add_source_to_candidate(md5, fpath, source, url_info=None):
|
|
52
|
+
url_info = url_info or {}
|
|
53
|
+
if os.path.exists(fpath):
|
|
54
|
+
data = json.loads(open(fpath, "r").read())
|
|
55
|
+
else:
|
|
56
|
+
data = {
|
|
57
|
+
"available": True,
|
|
58
|
+
"merged": [],
|
|
59
|
+
"candidate": [],
|
|
60
|
+
"url_id": url_info["url_id"],
|
|
61
|
+
"hostname": url_info["hostname"],
|
|
62
|
+
}
|
|
63
|
+
md5_list = []
|
|
64
|
+
[
|
|
65
|
+
[md5_list.extend(md5["md5_list"]) for md5 in data[key]]
|
|
66
|
+
for key in ("merged", "candidate")
|
|
67
|
+
if key in data
|
|
68
|
+
]
|
|
69
|
+
if md5 not in md5_list:
|
|
70
|
+
data["candidate"].append({"md5_list": [md5], "source": source})
|
|
71
|
+
|
|
72
|
+
with open(fpath, "w") as fw:
|
|
73
|
+
fw.write(json.dumps(data, sort_keys=True, indent=4))
|
|
63
74
|
|
|
64
75
|
def add_source(self, source, *args, **kwargs):
|
|
65
76
|
md5 = get_md5_str(json.dumps(source))
|
|
@@ -99,33 +110,7 @@ class DownloadSource(object):
|
|
|
99
110
|
try:
|
|
100
111
|
self.add_source(source, *args, **kwargs)
|
|
101
112
|
except Exception as e:
|
|
102
|
-
|
|
103
|
-
# print(e)
|
|
104
|
-
pass
|
|
105
|
-
|
|
106
|
-
def add_source_to_candidate(self, md5, fpath, source, url_info=None):
|
|
107
|
-
url_info = url_info or {}
|
|
108
|
-
if os.path.exists(fpath):
|
|
109
|
-
data = json.loads(open(fpath, "r").read())
|
|
110
|
-
else:
|
|
111
|
-
data = {
|
|
112
|
-
"available": True,
|
|
113
|
-
"merged": [],
|
|
114
|
-
"candidate": [],
|
|
115
|
-
"url_id": url_info["url_id"],
|
|
116
|
-
"hostname": url_info["hostname"],
|
|
117
|
-
}
|
|
118
|
-
md5_list = []
|
|
119
|
-
[
|
|
120
|
-
[md5_list.extend(md5["md5_list"]) for md5 in data[key]]
|
|
121
|
-
for key in ("merged", "candidate")
|
|
122
|
-
if key in data
|
|
123
|
-
]
|
|
124
|
-
if md5 not in md5_list:
|
|
125
|
-
data["candidate"].append({"md5_list": [md5], "source": source})
|
|
126
|
-
|
|
127
|
-
with open(fpath, "w") as fw:
|
|
128
|
-
fw.write(json.dumps(data, sort_keys=True, indent=4))
|
|
113
|
+
logger.error(f"error: {e},traceback: {traceback.format_exc()}")
|
|
129
114
|
|
|
130
115
|
def export_sources(self, size=1000):
|
|
131
116
|
file_list = []
|
|
@@ -151,6 +136,27 @@ class DownloadSource(object):
|
|
|
151
136
|
dd = []
|
|
152
137
|
yield dd
|
|
153
138
|
|
|
139
|
+
def loads(self):
|
|
140
|
+
logger.info("loads")
|
|
141
|
+
|
|
142
|
+
if os.path.exists(self.pkl_url):
|
|
143
|
+
df = pd.read_pickle(self.pkl_url, compression="infer")
|
|
144
|
+
self.url_map = {k: v for k, v in df.values}
|
|
145
|
+
else:
|
|
146
|
+
self.url_map = {"https://farfarfun.github.com": 100000}
|
|
147
|
+
self.current_id = max(self.url_map.values())
|
|
148
|
+
if os.path.exists(self.pkl_md5):
|
|
149
|
+
df = pd.read_pickle(self.pkl_md5, compression="infer")
|
|
150
|
+
self.md5_set = {info["md5"]: info for info in df.to_dict(orient="records")}
|
|
151
|
+
|
|
152
|
+
def dumps(self):
|
|
153
|
+
logger.info("dumps")
|
|
154
|
+
df = pd.DataFrame([{"url": k, "url_id": v} for k, v in self.url_map.items()])
|
|
155
|
+
df.to_pickle(self.pkl_url, compression="infer")
|
|
156
|
+
|
|
157
|
+
df = pd.DataFrame(self.md5_set.values())
|
|
158
|
+
df.to_pickle(self.pkl_md5, compression="infer")
|
|
159
|
+
|
|
154
160
|
def loads_zip(self, zip_file=None):
|
|
155
161
|
funos.delete(self.path_pkl)
|
|
156
162
|
funos.delete(self.path_bok)
|
|
@@ -158,7 +164,7 @@ class DownloadSource(object):
|
|
|
158
164
|
files = os.listdir(self.path_bak)
|
|
159
165
|
files.sort(key=lambda x: x)
|
|
160
166
|
zip_file = os.path.join(self.path_bak, files[-1])
|
|
161
|
-
|
|
167
|
+
logger.info(f"load zip file from {zip_file}")
|
|
162
168
|
with tarfile.open(zip_file, "r") as tar:
|
|
163
169
|
tar.extractall(self.path_rot)
|
|
164
170
|
self.loads()
|
|
@@ -166,6 +172,7 @@ class DownloadSource(object):
|
|
|
166
172
|
def dumps_zip(self):
|
|
167
173
|
self.dumps()
|
|
168
174
|
zip_file = f"{self.path_bak}/{self.cate1}-{datetime.now().strftime('%Y%m%d-%H%M%S')}.tar.xz"
|
|
175
|
+
logger.info(f"dump zip file to {zip_file}")
|
|
169
176
|
with tarfile.open(zip_file, "w|xz") as tar:
|
|
170
177
|
tar.add(self.path_pkl, arcname=os.path.basename(self.path_pkl))
|
|
171
178
|
tar.add(self.path_bok, arcname=os.path.basename(self.path_bok))
|
|
@@ -3,12 +3,14 @@ import os
|
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
|
+
from funfake.headers import Headers
|
|
6
7
|
from funfile import funos
|
|
7
|
-
from funread.legado.manage.download.base import DownloadSource
|
|
8
8
|
from funsecret import get_md5_str
|
|
9
9
|
from funutil import getLogger
|
|
10
10
|
from tqdm import tqdm
|
|
11
11
|
|
|
12
|
+
from funread.legado.manage.download.base import DownloadSource
|
|
13
|
+
|
|
12
14
|
logger = getLogger("funread")
|
|
13
15
|
|
|
14
16
|
|
|
@@ -62,6 +64,7 @@ class RSSSourceDownload(DownloadSource):
|
|
|
62
64
|
return RSSSourceFormat(source).run()
|
|
63
65
|
|
|
64
66
|
def rss_download(self):
|
|
67
|
+
faker = Headers()
|
|
65
68
|
urls = [
|
|
66
69
|
"https://jt12.de/SYV2_4/2024/03/04/20/48/54/170955653465e5c33680046.json",
|
|
67
70
|
"https://jt12.de/SYV2/2023/03/17/0/02/42/167898256264133da2869d4.json",
|
|
@@ -81,7 +84,7 @@ class RSSSourceDownload(DownloadSource):
|
|
|
81
84
|
if index > size and os.path.exists(file):
|
|
82
85
|
continue
|
|
83
86
|
try:
|
|
84
|
-
data = json.dumps(requests.get(url).json())
|
|
87
|
+
data = json.dumps(requests.get(url, headers=faker.generate()).json())
|
|
85
88
|
with open(file, "w") as fw:
|
|
86
89
|
fw.write(data)
|
|
87
90
|
except Exception as e:
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from fundrive import GithubDrive
|
|
5
|
+
from funfake.headers import Headers
|
|
6
|
+
from funtask import Task
|
|
7
|
+
|
|
8
|
+
faker = Headers()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UpdateRssTask(Task):
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self.drive = GithubDrive()
|
|
14
|
+
self.drive.login("farfarfun/funread-cache")
|
|
15
|
+
super(UpdateRssTask, self).__init__()
|
|
16
|
+
|
|
17
|
+
def random_icon(self):
|
|
18
|
+
url = "https://api.thecatapi.com/v1/images/search?size=full"
|
|
19
|
+
response = requests.get(url, headers=faker.generate()).json()
|
|
20
|
+
return response[0]["url"]
|
|
21
|
+
|
|
22
|
+
def update_book(self, dir_path="funread/legado/snapshot/lasted"):
|
|
23
|
+
dl = []
|
|
24
|
+
for dir_info in self.drive.get_dir_list(dir_path):
|
|
25
|
+
dl.append(
|
|
26
|
+
{
|
|
27
|
+
"title": dir_info["name"],
|
|
28
|
+
"pic": self.random_icon(),
|
|
29
|
+
"url": f"https://farfarfun.github.io/funread-cache/{dir_info['path']}/index.html",
|
|
30
|
+
"description": "this is content",
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
dl.append(
|
|
35
|
+
{
|
|
36
|
+
"title": "源仓库(新)",
|
|
37
|
+
"url": "https://link3.cc/yckceo",
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
dl.append({"title": "开源阅读-语雀文档", "url": "https://www.yuque.com/legado"})
|
|
42
|
+
dl.append({"title": "喵公子书源", "url": "http://yuedu.miaogongzi.net/gx.html"})
|
|
43
|
+
dl.append({"title": "「阅读」APP 源-aoaostar", "url": "https://legado.aoaostar.com/"})
|
|
44
|
+
dl.append({"title": "yiove", "url": "https://shuyuan.yiove.com/"})
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
for line in dl:
|
|
48
|
+
if "pic" not in line:
|
|
49
|
+
line["pic"] = self.random_icon()
|
|
50
|
+
if "time" not in line:
|
|
51
|
+
line["time"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
52
|
+
|
|
53
|
+
data1 = {
|
|
54
|
+
"name": "test",
|
|
55
|
+
"next": "https://gitee.com/farfarfun/funread-cache/raw/master/funread/legado/snapshot/lasted/funread.json",
|
|
56
|
+
"list": dl,
|
|
57
|
+
}
|
|
58
|
+
self.drive.upload_file(git_path=f"{dir_path}/source.json", content=data1)
|
|
59
|
+
|
|
60
|
+
def update_main(self):
|
|
61
|
+
rss = {
|
|
62
|
+
"源": "https://gitee.com/farfarfun/funread-cache/raw/master/funread/legado/snapshot/lasted/source.json",
|
|
63
|
+
"源(备)": "https://github.com/farfarfun/funread-cache/raw/master/funread/legado/snapshot/lasted/source.json",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
data2 = [
|
|
67
|
+
{
|
|
68
|
+
"lastUpdateTime": int(datetime.now().timestamp()),
|
|
69
|
+
"sourceName": "funread",
|
|
70
|
+
"sourceIcon": self.random_icon(),
|
|
71
|
+
"sourceUrl": "https://github.com/farfarfun",
|
|
72
|
+
"loadWithBaseUrl": False,
|
|
73
|
+
"singleUrl": False,
|
|
74
|
+
"sortUrl": "\n".join([f"{k}::{v}" for k, v in rss.items()]),
|
|
75
|
+
"ruleArticles": "$.list[*]",
|
|
76
|
+
"ruleNextArticles": "$.next",
|
|
77
|
+
"ruleTitle": "$.title",
|
|
78
|
+
"rulePubDate": "⏰{{$.time}}",
|
|
79
|
+
"ruleImage": "$.pic",
|
|
80
|
+
"ruleLink": "$.url",
|
|
81
|
+
"sourceGroup": "VIP",
|
|
82
|
+
"customOrder": -9999999,
|
|
83
|
+
"enabled": True,
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
self.drive.upload_file(git_path="funread/legado/snapshot/lasted/funread.json", content=data2)
|
|
87
|
+
|
|
88
|
+
def run(self):
|
|
89
|
+
self.update_book()
|
|
90
|
+
self.update_main()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
UpdateRssTask().run()
|
|
@@ -9,6 +9,7 @@ src/funread.egg-info/requires.txt
|
|
|
9
9
|
src/funread.egg-info/top_level.txt
|
|
10
10
|
src/funread/legado/__init__.py
|
|
11
11
|
src/funread/legado/manage/__init__.py
|
|
12
|
+
src/funread/legado/manage/rss.py
|
|
12
13
|
src/funread/legado/manage/download/__init__.py
|
|
13
14
|
src/funread/legado/manage/download/base.py
|
|
14
15
|
src/funread/legado/manage/download/book.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|