simple-rule34 0.1.5.4__tar.gz → 0.1.6__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.
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/PKG-INFO +3 -1
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/pyproject.toml +7 -3
- simple_rule34-0.1.6/src/SimpleRule34/Rule34.py +149 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/SimpleRule34/exceptions.py +8 -2
- simple_rule34-0.1.6/src/SimpleRule34/types.py +62 -0
- simple_rule34-0.1.6/src/__init__.py +0 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/PKG-INFO +3 -1
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/SOURCES.txt +1 -4
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/requires.txt +2 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/top_level.txt +1 -0
- simple_rule34-0.1.6/tests/test.py +40 -0
- simple_rule34-0.1.5.4/src/SimpleRule34/Rule34.py +0 -213
- simple_rule34-0.1.5.4/src/SimpleRule34/aio/ARule34.py +0 -186
- simple_rule34-0.1.5.4/src/SimpleRule34/aio/types.py +0 -98
- simple_rule34-0.1.5.4/src/SimpleRule34/setup.py +0 -26
- simple_rule34-0.1.5.4/src/SimpleRule34/types.py +0 -95
- simple_rule34-0.1.5.4/src/SimpleRule34/utils.py +0 -35
- simple_rule34-0.1.5.4/tests/test.py +0 -62
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/LICENSE +0 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/README.md +0 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/setup.cfg +0 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/SimpleRule34/__init__.py +0 -0
- {simple_rule34-0.1.5.4/src/SimpleRule34/aio → simple_rule34-0.1.6/src/SimpleRule34}/utils.py +0 -0
- {simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/dependency_links.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: simple_rule34
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Simple api wrapper of rule34.xxx for python with asynchronous support
|
|
5
5
|
Author-email: StarMan12 <author@example.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/SyperAlexKomp/simple-rule34-api
|
|
@@ -50,6 +50,8 @@ Requires-Dist: urllib3==2.0.3
|
|
|
50
50
|
Requires-Dist: yarg==0.1.9
|
|
51
51
|
Requires-Dist: yarl==1.9.2
|
|
52
52
|
Requires-Dist: zipp==3.16.2
|
|
53
|
+
Requires-Dist: aiofiles~=23.2.1
|
|
54
|
+
Requires-Dist: pydantic~=2.7.1
|
|
53
55
|
|
|
54
56
|
# rule34-simple-api
|
|
55
57
|
Simple api wrapper of rule34.xxx for python with asynchronous support
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "simple_rule34"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.6"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="StarMan12", email="author@example.com" },
|
|
10
10
|
]
|
|
@@ -16,7 +16,8 @@ classifiers = [
|
|
|
16
16
|
"License :: OSI Approved :: MIT License",
|
|
17
17
|
"Operating System :: OS Independent",
|
|
18
18
|
]
|
|
19
|
-
dependencies = [
|
|
19
|
+
dependencies = [
|
|
20
|
+
'aiohttp==3.8.4',
|
|
20
21
|
'aiosignal==1.3.1',
|
|
21
22
|
'alabaster==0.7.13',
|
|
22
23
|
'async-timeout==4.0.2',
|
|
@@ -54,7 +55,10 @@ dependencies = ['aiohttp==3.8.4',
|
|
|
54
55
|
'urllib3==2.0.3',
|
|
55
56
|
'yarg==0.1.9',
|
|
56
57
|
'yarl==1.9.2',
|
|
57
|
-
'zipp==3.16.2'
|
|
58
|
+
'zipp==3.16.2',
|
|
59
|
+
'aiofiles~=23.2.1',
|
|
60
|
+
'pydantic~=2.7.1'
|
|
61
|
+
]
|
|
58
62
|
|
|
59
63
|
[project.urls]
|
|
60
64
|
"Homepage" = "https://github.com/SyperAlexKomp/simple-rule34-api"
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
import aiohttp
|
|
5
|
+
import datetime
|
|
6
|
+
import logging
|
|
7
|
+
import xml.etree.ElementTree as ET
|
|
8
|
+
|
|
9
|
+
from .exceptions import *
|
|
10
|
+
from .types import *
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Rule34Api:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.header = {'User-Agent': 'rule34-simple-api 0.1.5.6 (Request)'}
|
|
16
|
+
async def get_post_count(self, tags: str = '') -> int:
|
|
17
|
+
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
18
|
+
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
19
|
+
f'page=dapi&s=post&q=index&tags={tags}') as response:
|
|
20
|
+
xml_data = await response.text()
|
|
21
|
+
|
|
22
|
+
xml_root = ET.fromstring(xml_data)
|
|
23
|
+
|
|
24
|
+
return int(xml_root.get('count'))
|
|
25
|
+
|
|
26
|
+
async def get_post(self, id: int) -> Post:
|
|
27
|
+
st = time.time()
|
|
28
|
+
|
|
29
|
+
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
30
|
+
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
31
|
+
f'json=1&page=dapi&s=post&q=index&id={id}') as response:
|
|
32
|
+
if response.status != 200:
|
|
33
|
+
raise ApiException(f"Api returned status code {response.status} with message"
|
|
34
|
+
f" {await response.text()}")
|
|
35
|
+
|
|
36
|
+
j = await response.json()
|
|
37
|
+
data = j[0]
|
|
38
|
+
|
|
39
|
+
data["main"] = {
|
|
40
|
+
"url": data['file_url']
|
|
41
|
+
}
|
|
42
|
+
data["preview"] = {
|
|
43
|
+
"url": data['preview_url']
|
|
44
|
+
}
|
|
45
|
+
data["tags"] = data["tags"].split(" ")
|
|
46
|
+
|
|
47
|
+
logging.debug(f"Post[{id}] where found in {time.time() - st}s")
|
|
48
|
+
|
|
49
|
+
return Post(**data)
|
|
50
|
+
|
|
51
|
+
async def get_random_post(self, tags: str = '', forbidden_tags: list[str] = []) -> Post:
|
|
52
|
+
start_time = time.time()
|
|
53
|
+
|
|
54
|
+
post_count = await self.get_post_count(tags)
|
|
55
|
+
|
|
56
|
+
page_count = post_count // 1000
|
|
57
|
+
|
|
58
|
+
if page_count > 0:
|
|
59
|
+
post_list = await self.get_post_list(page_id=random.randint(0, page_count if page_count <= 200 else 200),
|
|
60
|
+
tags=tags, limit=1000)
|
|
61
|
+
|
|
62
|
+
else:
|
|
63
|
+
post_list = await self.get_post_list(tags=tags, limit=1000)
|
|
64
|
+
|
|
65
|
+
post_list_ = []
|
|
66
|
+
|
|
67
|
+
for post in post_list:
|
|
68
|
+
if any(tag in forbidden_tags for tag in post.main.tags):
|
|
69
|
+
pass
|
|
70
|
+
else:
|
|
71
|
+
post_list_.append(post)
|
|
72
|
+
|
|
73
|
+
logging.debug(f"Random posts where found in {time.time() - start_time}s")
|
|
74
|
+
|
|
75
|
+
return post_list_[random.randint(0, len(post_list_) - 1)] if len(post_list_) > 0 else None
|
|
76
|
+
|
|
77
|
+
async def get_random_posts(self, tags: str = '', count: int = 8, forbidden_tags: list[str] = []) -> list[Post]:
|
|
78
|
+
st = time.time()
|
|
79
|
+
|
|
80
|
+
request_count = 1
|
|
81
|
+
true_count = count*20
|
|
82
|
+
|
|
83
|
+
post_list = []
|
|
84
|
+
|
|
85
|
+
if true_count > 1000:
|
|
86
|
+
request_count = true_count // 1000
|
|
87
|
+
|
|
88
|
+
post_count = await self.get_post_count(tags)
|
|
89
|
+
page_id = int(random.randint(0, int(post_count / true_count)) / 8) if post_count >= true_count else 0
|
|
90
|
+
|
|
91
|
+
for pid in range(request_count + 1):
|
|
92
|
+
post_list += await self.get_post_list(tags=tags, forbidden_tags=forbidden_tags,
|
|
93
|
+
page_id=page_id, limit=true_count if true_count <= 1000 else 1000)
|
|
94
|
+
|
|
95
|
+
getted = []
|
|
96
|
+
|
|
97
|
+
for x in range(count):
|
|
98
|
+
if len(post_list) > 0:
|
|
99
|
+
getted.append(post_list[random.randint(0, len(post_list) - 1)])
|
|
100
|
+
else:
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
logging.debug(f"{count} random posts where found in {time.time() - st}s")
|
|
104
|
+
|
|
105
|
+
return getted
|
|
106
|
+
|
|
107
|
+
async def get_post_list(self, limit: int = 1000, page_id: int = 0, tags: str = '', forbidden_tags: list[str] = [])\
|
|
108
|
+
-> list[Post]:
|
|
109
|
+
if limit > 1000:
|
|
110
|
+
raise ToBigRequestException(f"The max size of request is 1000 when you tried to request {limit}")
|
|
111
|
+
|
|
112
|
+
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
113
|
+
start_time = time.time()
|
|
114
|
+
|
|
115
|
+
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
116
|
+
f'json=1&page=dapi&s=post&q=index&limit={limit}&pid={page_id}&tags={tags}') as response:
|
|
117
|
+
if response.status != 200:
|
|
118
|
+
raise ApiException(f"Api returned status code {response.status} with message"
|
|
119
|
+
f" {await response.text()}")
|
|
120
|
+
|
|
121
|
+
data = await response.json()
|
|
122
|
+
|
|
123
|
+
logging.debug(f"Request with {limit} limit posts were done in {time.time() - start_time}s")
|
|
124
|
+
|
|
125
|
+
post_list = []
|
|
126
|
+
for post_data in data:
|
|
127
|
+
post_data["main"] = {
|
|
128
|
+
"url": post_data['file_url']
|
|
129
|
+
}
|
|
130
|
+
post_data["preview"] = {
|
|
131
|
+
"url": post_data['preview_url']
|
|
132
|
+
}
|
|
133
|
+
post_data["tags"] = post_data["tags"].split(" ")
|
|
134
|
+
|
|
135
|
+
post_list.append(Post(**post_data))
|
|
136
|
+
|
|
137
|
+
start_time = time.time()
|
|
138
|
+
|
|
139
|
+
post_list_ = []
|
|
140
|
+
|
|
141
|
+
for post in post_list:
|
|
142
|
+
if any(tag in forbidden_tags for tag in post.tags):
|
|
143
|
+
pass
|
|
144
|
+
else:
|
|
145
|
+
post_list_.append(post)
|
|
146
|
+
|
|
147
|
+
logging.debug(f"{len(post_list_)} posts where found in {time.time() - start_time}s")
|
|
148
|
+
|
|
149
|
+
return post_list_
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
class ToBigRequestException(Exception):
|
|
4
2
|
def __init__(self, msg):
|
|
5
3
|
self.msg = msg
|
|
@@ -15,3 +13,11 @@ class RequestMoreThanAvailableException(Exception):
|
|
|
15
13
|
|
|
16
14
|
def __str__(self):
|
|
17
15
|
return self.msg
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ApiException(Exception):
|
|
19
|
+
def __init__(self, msg):
|
|
20
|
+
self.msg = msg
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
return self.msg
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import typing
|
|
3
|
+
import aiofiles
|
|
4
|
+
import aiohttp
|
|
5
|
+
|
|
6
|
+
from aiofiles import os as aos
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from .exceptions import ApiException
|
|
10
|
+
from .utils import get_file_type
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class File(BaseModel):
|
|
14
|
+
url: str
|
|
15
|
+
type: str = None
|
|
16
|
+
|
|
17
|
+
def __init__(self, /, **data: typing.Any) -> None:
|
|
18
|
+
super().__init__(**data)
|
|
19
|
+
|
|
20
|
+
self.type = get_file_type(self.url)
|
|
21
|
+
|
|
22
|
+
async def download(self, path: str = r'./rule34_download') -> str:
|
|
23
|
+
try:
|
|
24
|
+
await aos.mkdir(path)
|
|
25
|
+
except:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
async with aiohttp.ClientSession() as session:
|
|
29
|
+
async with session.get(self.url) as response:
|
|
30
|
+
if response.status != 200:
|
|
31
|
+
raise ApiException(f"Api returned status code {response.status} with message"
|
|
32
|
+
f" {await response.text()}")
|
|
33
|
+
|
|
34
|
+
file_name = os.path.basename(self.url)
|
|
35
|
+
save_path = os.path.join(path, file_name)
|
|
36
|
+
|
|
37
|
+
async with aiofiles.open(save_path, 'wb') as file:
|
|
38
|
+
await file.write(await response.read())
|
|
39
|
+
|
|
40
|
+
return save_path
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Post(BaseModel):
|
|
44
|
+
directory: int
|
|
45
|
+
hash: str
|
|
46
|
+
width: int
|
|
47
|
+
height: int
|
|
48
|
+
id: int
|
|
49
|
+
change: int
|
|
50
|
+
owner: str
|
|
51
|
+
parent_id: int
|
|
52
|
+
rating: str
|
|
53
|
+
sample: bool
|
|
54
|
+
score: int
|
|
55
|
+
tags: list
|
|
56
|
+
source: str
|
|
57
|
+
status: str
|
|
58
|
+
has_notes: bool
|
|
59
|
+
comment_count: int
|
|
60
|
+
|
|
61
|
+
main: File
|
|
62
|
+
preview: File
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: simple_rule34
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Simple api wrapper of rule34.xxx for python with asynchronous support
|
|
5
5
|
Author-email: StarMan12 <author@example.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/SyperAlexKomp/simple-rule34-api
|
|
@@ -50,6 +50,8 @@ Requires-Dist: urllib3==2.0.3
|
|
|
50
50
|
Requires-Dist: yarg==0.1.9
|
|
51
51
|
Requires-Dist: yarl==1.9.2
|
|
52
52
|
Requires-Dist: zipp==3.16.2
|
|
53
|
+
Requires-Dist: aiofiles~=23.2.1
|
|
54
|
+
Requires-Dist: pydantic~=2.7.1
|
|
53
55
|
|
|
54
56
|
# rule34-simple-api
|
|
55
57
|
Simple api wrapper of rule34.xxx for python with asynchronous support
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
3
|
pyproject.toml
|
|
4
|
+
src/__init__.py
|
|
4
5
|
src/SimpleRule34/Rule34.py
|
|
5
6
|
src/SimpleRule34/__init__.py
|
|
6
7
|
src/SimpleRule34/exceptions.py
|
|
7
|
-
src/SimpleRule34/setup.py
|
|
8
8
|
src/SimpleRule34/types.py
|
|
9
9
|
src/SimpleRule34/utils.py
|
|
10
|
-
src/SimpleRule34/aio/ARule34.py
|
|
11
|
-
src/SimpleRule34/aio/types.py
|
|
12
|
-
src/SimpleRule34/aio/utils.py
|
|
13
10
|
src/simple_rule34.egg-info/PKG-INFO
|
|
14
11
|
src/simple_rule34.egg-info/SOURCES.txt
|
|
15
12
|
src/simple_rule34.egg-info/dependency_links.txt
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from SimpleRule34.src.SimpleRule34.Rule34 import Rule34Api
|
|
2
|
+
from SimpleRule34.src.SimpleRule34 import Rule34Api
|
|
3
|
+
import asyncio
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def main1():
|
|
7
|
+
|
|
8
|
+
r = Rule34Api()
|
|
9
|
+
print("=====ALL 10=====")
|
|
10
|
+
lis = await r.get_post_list(tags='', limit=10)
|
|
11
|
+
|
|
12
|
+
for x in lis:
|
|
13
|
+
print(x)
|
|
14
|
+
|
|
15
|
+
print("=====FIRST 5=====")
|
|
16
|
+
lis = await r.get_post_list(tags='brawl_stars', limit=5)
|
|
17
|
+
|
|
18
|
+
for x in lis:
|
|
19
|
+
print(x)
|
|
20
|
+
|
|
21
|
+
print("=====SECOND 5=====")
|
|
22
|
+
lis = await r.get_post_list(tags='brawl_stars', limit=5, page_id=1)
|
|
23
|
+
|
|
24
|
+
for x in lis:
|
|
25
|
+
print(x)
|
|
26
|
+
|
|
27
|
+
print("=====EDITED=====")
|
|
28
|
+
post_list_ = await r.get_post_list(tags='brawl_stars', limit=100, page_id=0,
|
|
29
|
+
forbidden_tags=['male'])
|
|
30
|
+
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
async def main():
|
|
35
|
+
r = Rule34Api()
|
|
36
|
+
p = await r.get_post_list(limit=10)
|
|
37
|
+
print(p)
|
|
38
|
+
|
|
39
|
+
if __name__ == '__main__':
|
|
40
|
+
asyncio.run(main())
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import random
|
|
2
|
-
import time
|
|
3
|
-
import typing
|
|
4
|
-
|
|
5
|
-
import requests
|
|
6
|
-
import datetime
|
|
7
|
-
import logging
|
|
8
|
-
import xml.etree.ElementTree as ET
|
|
9
|
-
|
|
10
|
-
from .exceptions import *
|
|
11
|
-
from .types import Rule34MainPost, Rule34PostData, Rule34SamplePost, Rule34PreviewPost
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def parse_result(post_element):
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
id = int(post_element.get('id'))
|
|
18
|
-
height = int(post_element.get('height'))
|
|
19
|
-
width = int(post_element.get('width'))
|
|
20
|
-
url = post_element.get('file_url')
|
|
21
|
-
|
|
22
|
-
sample_height = int(post_element.get('sample_height'))
|
|
23
|
-
sample_width = int(post_element.get('sample_width'))
|
|
24
|
-
sample_url = post_element.get('sample_url')
|
|
25
|
-
|
|
26
|
-
sample_post = Rule34SamplePost(sample_height, sample_width, sample_url, id)
|
|
27
|
-
|
|
28
|
-
preview_height = int(post_element.get('preview_height'))
|
|
29
|
-
preview_width = int(post_element.get('preview_width'))
|
|
30
|
-
preview_url = post_element.get('preview_url')
|
|
31
|
-
|
|
32
|
-
preview_post = Rule34PreviewPost(preview_height, preview_width, preview_url, id)
|
|
33
|
-
|
|
34
|
-
score = int(post_element.get('score'))
|
|
35
|
-
rating = post_element.get('rating')
|
|
36
|
-
creator_id = int(post_element.get('creator_id'))
|
|
37
|
-
tags = post_element.get('tags')
|
|
38
|
-
has_children = post_element.get('has_children') == 'true'
|
|
39
|
-
created_date = datetime.datetime.strptime(post_element.get('created_at'), "%a %b %d %H:%M:%S %z %Y")
|
|
40
|
-
status = post_element.get('status')
|
|
41
|
-
source = post_element.get('source')
|
|
42
|
-
has_notes = post_element.get('has_notes') == 'true'
|
|
43
|
-
has_comments = post_element.get('has_comments') == 'true'
|
|
44
|
-
|
|
45
|
-
main_post = Rule34MainPost(score, rating, creator_id, tags, has_children, created_date, status,
|
|
46
|
-
source, has_notes, has_comments, height, width, url, id)
|
|
47
|
-
|
|
48
|
-
return main_post, sample_post, preview_post
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class Rule34Api:
|
|
52
|
-
"""
|
|
53
|
-
Sync main api class
|
|
54
|
-
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
def __init__(self):
|
|
58
|
-
self.s = requests.Session()
|
|
59
|
-
|
|
60
|
-
def get_post_count(self, tags: str = '') -> int:
|
|
61
|
-
"""
|
|
62
|
-
This function will search amount of posts with your tags from rule34.xxx
|
|
63
|
-
|
|
64
|
-
:param tags: Tags in format 'tag1 tag2 ...'. Base ''
|
|
65
|
-
:type tags: str
|
|
66
|
-
|
|
67
|
-
:return: Amount of posts with current tags
|
|
68
|
-
:rtype: int
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
r = self.s.get(f'https://api.rule34.xxx/index.php?'
|
|
73
|
-
f'page=dapi&s=post&q=index&tags={tags}')
|
|
74
|
-
|
|
75
|
-
xml_root = ET.fromstring(r.text)
|
|
76
|
-
|
|
77
|
-
return int(xml_root.get('count'))
|
|
78
|
-
|
|
79
|
-
def get_post(self, id: int) -> typing.Optional[Rule34PostData]:
|
|
80
|
-
"""
|
|
81
|
-
This function will search post with your id from rule34.xxx
|
|
82
|
-
|
|
83
|
-
:param id: id of post
|
|
84
|
-
:type id: int
|
|
85
|
-
|
|
86
|
-
:return: On success, returns Rule34PostData object
|
|
87
|
-
:rtype: :obj: 'typing.Optional[Rule34PostData]'
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
-
r = self.s.get(f'https://api.rule34.xxx/index.php?'
|
|
91
|
-
f'page=dapi&s=post&q=index&id={id}')
|
|
92
|
-
|
|
93
|
-
try:
|
|
94
|
-
xml_root = ET.fromstring(r.text)
|
|
95
|
-
except:
|
|
96
|
-
return None
|
|
97
|
-
post_element = xml_root.find('post')
|
|
98
|
-
|
|
99
|
-
parsed = parse_result(post_element)
|
|
100
|
-
|
|
101
|
-
if parsed is None:
|
|
102
|
-
return None
|
|
103
|
-
else:
|
|
104
|
-
main_post, sample_post, preview_post = parsed
|
|
105
|
-
|
|
106
|
-
return Rule34PostData(id, main_post, sample_post, preview_post)
|
|
107
|
-
|
|
108
|
-
def get_random_post(self, tags: str = '') -> typing.Optional[Rule34PostData]:
|
|
109
|
-
"""
|
|
110
|
-
This function will search 1 random post with your tags from rule34.xxx
|
|
111
|
-
|
|
112
|
-
:param tags: Tags in format 'tag1 tag2 ...' with which post will be searching. Base ''
|
|
113
|
-
:type tags: str
|
|
114
|
-
|
|
115
|
-
:return: On success, returns Rule34PostData object
|
|
116
|
-
:rtype: :obj: 'typing.Optional[Rule34PostData]'
|
|
117
|
-
"""
|
|
118
|
-
|
|
119
|
-
post_count = self.get_post_count(tags)
|
|
120
|
-
|
|
121
|
-
page_count = post_count // 1000
|
|
122
|
-
|
|
123
|
-
if page_count > 0:
|
|
124
|
-
post_list = self.get_post_list(page_id=random.randint(0, page_count if page_count <= 200 else 200),
|
|
125
|
-
tags=tags, limit=1000)
|
|
126
|
-
|
|
127
|
-
else:
|
|
128
|
-
post_list = self.get_post_list(tags=tags, limit=1000)
|
|
129
|
-
|
|
130
|
-
return post_list[random.randint(0, len(post_list) - 1)] if len(post_list) > 0 else None
|
|
131
|
-
|
|
132
|
-
def get_random_posts(self, tags: str = '', count: int = 8) -> list[Rule34PostData]:
|
|
133
|
-
"""
|
|
134
|
-
This function will search your amount of random posts with your tags from rule34.xxx
|
|
135
|
-
|
|
136
|
-
:param tags: Tags in format 'tag1 tag2 ...' with which post will be searching. Base ''
|
|
137
|
-
:type tags: str
|
|
138
|
-
|
|
139
|
-
:param count: Amount of posts that will need to be founded. Base 8
|
|
140
|
-
:type count: int
|
|
141
|
-
|
|
142
|
-
:return: List with founded posts
|
|
143
|
-
:rtype: :obj: 'list[Rule34PostData]'
|
|
144
|
-
|
|
145
|
-
"""
|
|
146
|
-
|
|
147
|
-
st = time.time()
|
|
148
|
-
|
|
149
|
-
request_count = 1
|
|
150
|
-
|
|
151
|
-
post_list = []
|
|
152
|
-
|
|
153
|
-
if count > 1000:
|
|
154
|
-
request_count = count // 1000
|
|
155
|
-
|
|
156
|
-
for pid in range(request_count + 1):
|
|
157
|
-
post_list += self.get_post_list(tags=tags)
|
|
158
|
-
|
|
159
|
-
getted = [post_list[random.randint(0, len(post_list) - 1)] if len(post_list) > 0 else None for x in
|
|
160
|
-
range(count)]
|
|
161
|
-
|
|
162
|
-
logging.debug(f"{count} random posts where founded in {time.time() - st}")
|
|
163
|
-
|
|
164
|
-
return getted
|
|
165
|
-
|
|
166
|
-
def get_post_list(self, limit: int = 1000, page_id: int = 0, tags: str = '',
|
|
167
|
-
blocked_tags: typing.Optional[str] = None) -> list[Rule34PostData]:
|
|
168
|
-
"""
|
|
169
|
-
This function will get list of posts with your tags on page
|
|
170
|
-
|
|
171
|
-
:param limit: limit of posts in list. Base value is 1000
|
|
172
|
-
:type limit: int
|
|
173
|
-
|
|
174
|
-
:param page_id: number of page with posts. Base value is 0
|
|
175
|
-
:type page_id: int
|
|
176
|
-
|
|
177
|
-
:param tags: Tags in format 'tag1 tag2 ...' with which post will be searching. Base values is ''
|
|
178
|
-
:type tags: str
|
|
179
|
-
|
|
180
|
-
:parameter blocked_tags: Tags that will be banned from search in format 'tag1 tag2 ...'. Base values is None.
|
|
181
|
-
Can slow search
|
|
182
|
-
:type blocked_tags: str or None
|
|
183
|
-
|
|
184
|
-
:return: :obj: 'list[Rule34PostData]'
|
|
185
|
-
"""
|
|
186
|
-
|
|
187
|
-
if limit > 1000:
|
|
188
|
-
raise ToBigRequestException(f"The max size of request is 1000 when you tried to request {limit}")
|
|
189
|
-
|
|
190
|
-
start_time = time.time()
|
|
191
|
-
|
|
192
|
-
r = self.s.get(f'https://api.rule34.xxx/index.php?'
|
|
193
|
-
f'page=dapi&s=post&q=index&limit={limit}&pid={page_id}&tags={tags}')
|
|
194
|
-
|
|
195
|
-
logging.debug(f"Request with {limit}limit posts where done in {time.time() - start_time}s")
|
|
196
|
-
|
|
197
|
-
xml_root = ET.fromstring(r.text)
|
|
198
|
-
posts = xml_root.findall('post')
|
|
199
|
-
post_list = []
|
|
200
|
-
|
|
201
|
-
start_time = time.time()
|
|
202
|
-
for post_element in posts:
|
|
203
|
-
parsed = parse_result(post_element)
|
|
204
|
-
|
|
205
|
-
if parsed is None:
|
|
206
|
-
continue
|
|
207
|
-
else:
|
|
208
|
-
main_post, sample_post, preview_post = parsed
|
|
209
|
-
|
|
210
|
-
post_list.append(Rule34PostData(main_post.id, main_post, sample_post, preview_post))
|
|
211
|
-
logging.debug(f"Creating {len(posts)} objects where done in {time.time() - start_time}s")
|
|
212
|
-
|
|
213
|
-
return post_list
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import random
|
|
2
|
-
import time
|
|
3
|
-
|
|
4
|
-
import aiohttp
|
|
5
|
-
import datetime
|
|
6
|
-
import logging
|
|
7
|
-
import xml.etree.ElementTree as ET
|
|
8
|
-
|
|
9
|
-
from ..exceptions import *
|
|
10
|
-
from .types import *
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
async def parse_result(post_element):
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
id = int(post_element.get('id'))
|
|
17
|
-
height = int(post_element.get('height'))
|
|
18
|
-
width = int(post_element.get('width'))
|
|
19
|
-
url = post_element.get('file_url')
|
|
20
|
-
|
|
21
|
-
sample_height = int(post_element.get('sample_height'))
|
|
22
|
-
sample_width = int(post_element.get('sample_width'))
|
|
23
|
-
sample_url = post_element.get('sample_url')
|
|
24
|
-
|
|
25
|
-
sample_post = Rule34SamplePost(sample_height, sample_width, sample_url, id)
|
|
26
|
-
|
|
27
|
-
preview_height = int(post_element.get('preview_height'))
|
|
28
|
-
preview_width = int(post_element.get('preview_width'))
|
|
29
|
-
preview_url = post_element.get('preview_url')
|
|
30
|
-
|
|
31
|
-
preview_post = Rule34PreviewPost(preview_height, preview_width, preview_url, id)
|
|
32
|
-
|
|
33
|
-
score = int(post_element.get('score'))
|
|
34
|
-
rating = post_element.get('rating')
|
|
35
|
-
creator_id = int(post_element.get('creator_id'))
|
|
36
|
-
tags = post_element.get('tags')
|
|
37
|
-
has_children = post_element.get('has_children') == 'true'
|
|
38
|
-
created_date = datetime.datetime.strptime(post_element.get('created_at'), "%a %b %d %H:%M:%S %z %Y")
|
|
39
|
-
status = post_element.get('status')
|
|
40
|
-
source = post_element.get('source')
|
|
41
|
-
has_notes = post_element.get('has_notes') == 'true'
|
|
42
|
-
has_comments = post_element.get('has_comments') == 'true'
|
|
43
|
-
|
|
44
|
-
main_post = Rule34MainPost(score, rating, creator_id, tags, has_children, created_date, status,
|
|
45
|
-
source, has_notes, has_comments, height, width, url, id)
|
|
46
|
-
|
|
47
|
-
return main_post, sample_post, preview_post
|
|
48
|
-
|
|
49
|
-
class Rule34Api:
|
|
50
|
-
def __init__(self):
|
|
51
|
-
self.header = {'User-Agent': 'rule34-simple-api 0.1.5.3 (Request)'}
|
|
52
|
-
async def get_post_count(self, tags: str = '') -> int:
|
|
53
|
-
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
54
|
-
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
55
|
-
f'page=dapi&s=post&q=index&tags={tags}') as response:
|
|
56
|
-
xml_data = await response.text()
|
|
57
|
-
|
|
58
|
-
xml_root = ET.fromstring(xml_data)
|
|
59
|
-
|
|
60
|
-
return int(xml_root.get('count'))
|
|
61
|
-
|
|
62
|
-
async def get_post(self, id: int):
|
|
63
|
-
st = time.time()
|
|
64
|
-
|
|
65
|
-
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
66
|
-
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
67
|
-
f'page=dapi&s=post&q=index&id={id}') as response:
|
|
68
|
-
xml_data = await response.text()
|
|
69
|
-
|
|
70
|
-
try:
|
|
71
|
-
xml_root = ET.fromstring(xml_data)
|
|
72
|
-
except:
|
|
73
|
-
return None
|
|
74
|
-
|
|
75
|
-
post_element = xml_root.find('post')
|
|
76
|
-
|
|
77
|
-
parsed = await parse_result(post_element)
|
|
78
|
-
|
|
79
|
-
if parsed is None:
|
|
80
|
-
return None
|
|
81
|
-
else:
|
|
82
|
-
main_post, sample_post, preview_post = parsed
|
|
83
|
-
|
|
84
|
-
logging.info(f"Post where found in {time.time() - st}s")
|
|
85
|
-
|
|
86
|
-
return Rule34PostData(id, main_post, sample_post, preview_post)
|
|
87
|
-
|
|
88
|
-
async def get_random_post(self, tags: str = '', forbidden_tags: list[str] = []):
|
|
89
|
-
start_time = time.time()
|
|
90
|
-
|
|
91
|
-
post_count = await self.get_post_count(tags)
|
|
92
|
-
|
|
93
|
-
page_count = post_count // 1000
|
|
94
|
-
|
|
95
|
-
if page_count > 0:
|
|
96
|
-
post_list = await self.get_post_list(page_id=random.randint(0, page_count if page_count <= 200 else 200),
|
|
97
|
-
tags=tags, limit=1000)
|
|
98
|
-
|
|
99
|
-
else:
|
|
100
|
-
post_list = await self.get_post_list(tags=tags, limit=1000)
|
|
101
|
-
|
|
102
|
-
post_list_ = []
|
|
103
|
-
|
|
104
|
-
for post in post_list:
|
|
105
|
-
if any(tag in forbidden_tags for tag in post.main.tags):
|
|
106
|
-
pass
|
|
107
|
-
else:
|
|
108
|
-
post_list_.append(post)
|
|
109
|
-
|
|
110
|
-
logging.info(f"Random post where found in {time.time() - start_time}s")
|
|
111
|
-
|
|
112
|
-
return post_list_[random.randint(0, len(post_list_) - 1)] if len(post_list_) > 0 else None
|
|
113
|
-
|
|
114
|
-
async def get_random_posts(self, tags: str = '', count: int = 8, forbidden_tags: list[str] = []) -> list[Rule34PostData]:
|
|
115
|
-
st = time.time()
|
|
116
|
-
|
|
117
|
-
request_count = 1
|
|
118
|
-
true_count = count*20
|
|
119
|
-
|
|
120
|
-
post_list = []
|
|
121
|
-
|
|
122
|
-
if true_count > 1000:
|
|
123
|
-
request_count = true_count // 1000
|
|
124
|
-
|
|
125
|
-
post_count = await self.get_post_count(tags)
|
|
126
|
-
page_id = int(random.randint(0, int(post_count / true_count)) / 8) if post_count >= true_count else 0
|
|
127
|
-
|
|
128
|
-
for pid in range(request_count + 1):
|
|
129
|
-
post_list += await self.get_post_list(tags=tags, forbidden_tags=forbidden_tags,
|
|
130
|
-
page_id=page_id, limit=true_count if true_count <= 1000 else 1000)
|
|
131
|
-
|
|
132
|
-
getted = []
|
|
133
|
-
|
|
134
|
-
for x in range(count):
|
|
135
|
-
if len(post_list) > 0:
|
|
136
|
-
getted.append(post_list[random.randint(0, len(post_list) - 1)])
|
|
137
|
-
else:
|
|
138
|
-
pass
|
|
139
|
-
|
|
140
|
-
logging.info(f"{count} random posts where found in {time.time() - st}s")
|
|
141
|
-
|
|
142
|
-
return getted
|
|
143
|
-
|
|
144
|
-
async def get_post_list(self, limit: int = 1000, page_id: int = 0, tags: str = '', forbidden_tags: list[str] = [])\
|
|
145
|
-
-> list[Rule34PostData]:
|
|
146
|
-
async with aiohttp.ClientSession(headers=self.header) as session:
|
|
147
|
-
if limit > 1000:
|
|
148
|
-
raise ToBigRequestException(f"The max size of request is 1000 when you tried to request {limit}")
|
|
149
|
-
|
|
150
|
-
start_time = time.time()
|
|
151
|
-
|
|
152
|
-
async with session.get(f'https://api.rule34.xxx/index.php?'
|
|
153
|
-
f'page=dapi&s=post&q=index&limit={limit}&pid={page_id}&tags={tags}') as response:
|
|
154
|
-
xml_data = await response.text()
|
|
155
|
-
|
|
156
|
-
logging.debug(f"Request with {limit} limit posts were done in {time.time() - start_time}s")
|
|
157
|
-
|
|
158
|
-
xml_root = ET.fromstring(xml_data)
|
|
159
|
-
posts = xml_root.findall('post')
|
|
160
|
-
post_list = []
|
|
161
|
-
|
|
162
|
-
start_time = time.time()
|
|
163
|
-
|
|
164
|
-
for post_element in posts:
|
|
165
|
-
parsed = await parse_result(post_element)
|
|
166
|
-
|
|
167
|
-
if parsed is None:
|
|
168
|
-
return []
|
|
169
|
-
else:
|
|
170
|
-
main_post, sample_post, preview_post = parsed
|
|
171
|
-
|
|
172
|
-
post_list.append(Rule34PostData(main_post.id, main_post, sample_post, preview_post))
|
|
173
|
-
|
|
174
|
-
logging.debug(f"Creating {len(posts)} objects was done in {time.time() - start_time}s")
|
|
175
|
-
|
|
176
|
-
post_list_ = []
|
|
177
|
-
|
|
178
|
-
for post in post_list:
|
|
179
|
-
if any(tag in forbidden_tags for tag in post.main.tags):
|
|
180
|
-
pass
|
|
181
|
-
else:
|
|
182
|
-
post_list_.append(post)
|
|
183
|
-
|
|
184
|
-
logging.info(f"{len(post_list_)} posts where found in {time.time() - start_time}s")
|
|
185
|
-
|
|
186
|
-
return post_list_
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
import aiofiles
|
|
4
|
-
import aiohttp
|
|
5
|
-
import os
|
|
6
|
-
import datetime
|
|
7
|
-
|
|
8
|
-
from .utils import get_file_size, get_file_type
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class Rule34Post:
|
|
12
|
-
def __init__(self, height: int, width: int, url: str, id: int):
|
|
13
|
-
self.path = r'./rule34_download'
|
|
14
|
-
self.height = height
|
|
15
|
-
self.width = width
|
|
16
|
-
self.url = url
|
|
17
|
-
self.id = id
|
|
18
|
-
self.file_type = get_file_type(self.url)
|
|
19
|
-
|
|
20
|
-
def __str__(self):
|
|
21
|
-
return f"<Rule34Post(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
22
|
-
|
|
23
|
-
async def get_file_size(self) -> typing.Optional[int]:
|
|
24
|
-
async with aiohttp.ClientSession() as session:
|
|
25
|
-
file_size = await get_file_size(self.url, session)
|
|
26
|
-
return file_size
|
|
27
|
-
|
|
28
|
-
async def download(self, path=r'./rule34_download'):
|
|
29
|
-
async with aiohttp.ClientSession() as session:
|
|
30
|
-
async with session.get(self.url) as response:
|
|
31
|
-
if response.status == 200:
|
|
32
|
-
try:
|
|
33
|
-
os.mkdir(self.path)
|
|
34
|
-
except:
|
|
35
|
-
pass
|
|
36
|
-
|
|
37
|
-
file_name = os.path.basename(self.url)
|
|
38
|
-
save_path = os.path.join(path, file_name)
|
|
39
|
-
with aiofiles.open(save_path, 'wb') as file:
|
|
40
|
-
await file.write(await response.read())
|
|
41
|
-
|
|
42
|
-
return save_path
|
|
43
|
-
else:
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
async def get_bytes(self):
|
|
47
|
-
async with aiohttp.ClientSession() as session:
|
|
48
|
-
async with session.get(self.url) as response:
|
|
49
|
-
return await response.read()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class Rule34MainPost(Rule34Post):
|
|
53
|
-
def __init__(self, score: int, rating: str, creator_id: int, tags: str, has_children: bool,
|
|
54
|
-
created_date: datetime.datetime, status: str, source: str, has_notes: bool, has_comments: bool,
|
|
55
|
-
height: int, width: int, url: str, id: int):
|
|
56
|
-
super().__init__(height, width, url, id)
|
|
57
|
-
self.score = score
|
|
58
|
-
self.rating = rating
|
|
59
|
-
self.creator_id = creator_id
|
|
60
|
-
self.tags = tags.split(" ")
|
|
61
|
-
self.has_children = has_children
|
|
62
|
-
self.created_date = created_date
|
|
63
|
-
self.status = status
|
|
64
|
-
self.source = source
|
|
65
|
-
self.has_notes = has_notes
|
|
66
|
-
self.has_comments = has_comments
|
|
67
|
-
|
|
68
|
-
def __str__(self):
|
|
69
|
-
return f"<Rule34MainPost(id={self.id}, height={self.height}, width={self.width}, url={self.url}," \
|
|
70
|
-
f" score={self.score}, rating={self.rating}, creator_id={self.creator_id}," \
|
|
71
|
-
f" has_children={self.has_children}, has_notes={self.has_notes}, has_comments={self.has_comments}" \
|
|
72
|
-
f" created_date={self.created_date}, status={self.status}, tags={self.tags})>"
|
|
73
|
-
|
|
74
|
-
def format_tags(self, format: str = "#"):
|
|
75
|
-
str_tags = (format + ' ').join(self.tags)
|
|
76
|
-
return str_tags.split(" ")
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class Rule34SamplePost(Rule34Post):
|
|
80
|
-
def __str__(self):
|
|
81
|
-
return f"<Rule34SamplePost(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class Rule34PreviewPost(Rule34Post):
|
|
85
|
-
def __str__(self):
|
|
86
|
-
return f"<Rule34PreviewPost(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class Rule34PostData:
|
|
90
|
-
def __init__(self, id: int, main: Rule34MainPost, sample: Rule34SamplePost, preview: Rule34PreviewPost):
|
|
91
|
-
self.id = id
|
|
92
|
-
self.main = main
|
|
93
|
-
self.sample = sample
|
|
94
|
-
self.preview = preview
|
|
95
|
-
|
|
96
|
-
def __str__(self):
|
|
97
|
-
return f"<Rule34PostData(id={self.id}, main={str(self.main)}, sample={str(self.sample)}," \
|
|
98
|
-
f" preview={str(self.preview)})>"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
|
|
3
|
-
setup(
|
|
4
|
-
name='SimpleRule34',
|
|
5
|
-
version='0.1',
|
|
6
|
-
description='Simple api wrapper of rule34.xxx for python with asynchronous support',
|
|
7
|
-
packages=find_packages(),
|
|
8
|
-
install_requires=[
|
|
9
|
-
'aiohttp==3.8.4',
|
|
10
|
-
'aiosignal==1.3.1',
|
|
11
|
-
'async-timeout==4.0.2',
|
|
12
|
-
'attrs==23.1.0',
|
|
13
|
-
'certifi==2023.5.7',
|
|
14
|
-
'charset-normalizer==3.2.0',
|
|
15
|
-
'docopt==0.6.2',
|
|
16
|
-
'frozenlist==1.4.0',
|
|
17
|
-
'idna==3.4',
|
|
18
|
-
'multidict==6.0.4',
|
|
19
|
-
'pipreqs==0.4.13',
|
|
20
|
-
'requests==2.31.0',
|
|
21
|
-
'urllib3==2.0.3',
|
|
22
|
-
'yarg==0.1.9',
|
|
23
|
-
'yarl==1.9.2',
|
|
24
|
-
],
|
|
25
|
-
url='https://github.com/Loshok229/rule34-simple-api'
|
|
26
|
-
)
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import requests
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
from .utils import get_file_type, get_file_size
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Rule34Post:
|
|
9
|
-
def __init__(self, height: int, width: int, url: str, id: int):
|
|
10
|
-
self.path = r'./rule34_download'
|
|
11
|
-
self.s = requests.Session()
|
|
12
|
-
|
|
13
|
-
self.height = height
|
|
14
|
-
self.width = width
|
|
15
|
-
self.url = url
|
|
16
|
-
self.id = id
|
|
17
|
-
|
|
18
|
-
self.file_type = get_file_type(self.url)
|
|
19
|
-
|
|
20
|
-
def __str__(self):
|
|
21
|
-
return f"<Rule34Post(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
22
|
-
|
|
23
|
-
def get_file_size(self):
|
|
24
|
-
return get_file_size(self.url, self.s)
|
|
25
|
-
|
|
26
|
-
def download(self, path = r'./rule34_download'):
|
|
27
|
-
r = self.s.get(self.url)
|
|
28
|
-
if r.status_code == 200:
|
|
29
|
-
try:
|
|
30
|
-
os.mkdir(self.path)
|
|
31
|
-
except:
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
|
-
file_name = os.path.basename(self.url)
|
|
35
|
-
save_path = os.path.join(path, file_name)
|
|
36
|
-
with open(save_path, 'wb') as file:
|
|
37
|
-
file.write(r.content)
|
|
38
|
-
|
|
39
|
-
return save_path
|
|
40
|
-
else:
|
|
41
|
-
pass
|
|
42
|
-
|
|
43
|
-
def get_bytes(self):
|
|
44
|
-
r = self.s.get(self.url)
|
|
45
|
-
|
|
46
|
-
return r.content
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
class Rule34MainPost(Rule34Post):
|
|
50
|
-
def __init__(self, score: int, rating: str, creator_id: int, tags: str, has_children: bool,
|
|
51
|
-
created_date: datetime.datetime, status: str, source: str, has_notes: bool, has_comments: bool,
|
|
52
|
-
height: int, width: int, url: str, id: int):
|
|
53
|
-
super().__init__(height, width, url, id)
|
|
54
|
-
self.score = score
|
|
55
|
-
self.rating = rating
|
|
56
|
-
self.creator_id = creator_id
|
|
57
|
-
self.tags = tags.split(" ")
|
|
58
|
-
self.has_children = has_children
|
|
59
|
-
self.created_date = created_date
|
|
60
|
-
self.status = status
|
|
61
|
-
self.source = source
|
|
62
|
-
self.has_notes = has_notes
|
|
63
|
-
self.has_comments = has_comments
|
|
64
|
-
|
|
65
|
-
def __str__(self):
|
|
66
|
-
return f"<Rule34MainPost(id={self.id}, height={self.height}, width={self.width}, url={self.url}," \
|
|
67
|
-
f" score={self.score}, rating={self.rating}, creator_id={self.creator_id}," \
|
|
68
|
-
f" has_children={self.has_children}, has_notes={self.has_notes}, has_comments={self.has_comments}" \
|
|
69
|
-
f" created_date={self.created_date}, status={self.status}, tags={self.tags})>"
|
|
70
|
-
|
|
71
|
-
def format_tags(self, format: str = "#"):
|
|
72
|
-
str_tags = (format + ' ').join(self.tags)
|
|
73
|
-
return str_tags.split(" ")
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class Rule34SamplePost(Rule34Post):
|
|
77
|
-
def __str__(self):
|
|
78
|
-
return f"<Rule34SamplePost(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class Rule34PreviewPost(Rule34Post):
|
|
82
|
-
def __str__(self):
|
|
83
|
-
return f"<Rule34PreviewPost(id={self.id}, height={self.height}, width={self.width}, url={self.url})>"
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class Rule34PostData:
|
|
87
|
-
def __init__(self, id: int, main: Rule34MainPost, sample: Rule34SamplePost, preview: Rule34PreviewPost):
|
|
88
|
-
self.id = id
|
|
89
|
-
self.main = main
|
|
90
|
-
self.sample = sample
|
|
91
|
-
self.preview = preview
|
|
92
|
-
|
|
93
|
-
def __str__(self):
|
|
94
|
-
return f"<Rule34PostData(id={self.id}, main={str(self.main)}, sample={str(self.sample)}," \
|
|
95
|
-
f" preview={str(self.preview)})>"
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def get_file_size(url, session: requests.Session):
|
|
5
|
-
response = session.head(url, allow_redirects=True)
|
|
6
|
-
if 'Content-Length' in response.headers:
|
|
7
|
-
size = int(response.headers['Content-Length'])
|
|
8
|
-
return size
|
|
9
|
-
else:
|
|
10
|
-
return None
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def get_file_type(url):
|
|
14
|
-
file_extension = url.split('.')[-1].lower()
|
|
15
|
-
if file_extension in ['jpg', 'jpeg', 'png']:
|
|
16
|
-
return 'photo'
|
|
17
|
-
elif file_extension in ['mp4', 'avi', 'mov']:
|
|
18
|
-
return 'video'
|
|
19
|
-
elif file_extension == '.gif':
|
|
20
|
-
return 'animation'
|
|
21
|
-
else:
|
|
22
|
-
return None
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def remove_blocked_tags_posts(post_list, blocked_tags):
|
|
26
|
-
post_list_ = []
|
|
27
|
-
|
|
28
|
-
for post in post_list:
|
|
29
|
-
if blocked_tags in post.main.tags:
|
|
30
|
-
pass
|
|
31
|
-
else:
|
|
32
|
-
post_list_.append(post)
|
|
33
|
-
|
|
34
|
-
return post
|
|
35
|
-
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
from SimpleRule34.src.SimpleRule34.aio.ARule34 import Rule34Api
|
|
2
|
-
from SimpleRule34.src.SimpleRule34 import Rule34Api
|
|
3
|
-
import asyncio
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
async def main1():
|
|
7
|
-
|
|
8
|
-
r = Rule34Api()
|
|
9
|
-
print("=====ALL 10=====")
|
|
10
|
-
lis = await r.get_post_list(tags='', limit=10)
|
|
11
|
-
|
|
12
|
-
for x in lis:
|
|
13
|
-
print(x)
|
|
14
|
-
|
|
15
|
-
print("=====FIRST 5=====")
|
|
16
|
-
lis = await r.get_post_list(tags='brawl_stars', limit=5)
|
|
17
|
-
|
|
18
|
-
for x in lis:
|
|
19
|
-
print(x)
|
|
20
|
-
|
|
21
|
-
print("=====SECOND 5=====")
|
|
22
|
-
lis = await r.get_post_list(tags='brawl_stars', limit=5, page_id=1)
|
|
23
|
-
|
|
24
|
-
for x in lis:
|
|
25
|
-
print(x)
|
|
26
|
-
|
|
27
|
-
print("=====EDITED=====")
|
|
28
|
-
post_list_ = await r.get_post_list(tags='brawl_stars', limit=100, page_id=0,
|
|
29
|
-
forbidden_tags=['male'])
|
|
30
|
-
|
|
31
|
-
chunk_size = 5
|
|
32
|
-
for i in range(0, len(post_list_), chunk_size):
|
|
33
|
-
chunk = post_list_[i:i + chunk_size]
|
|
34
|
-
print(f"=====CHUNK {i}=====")
|
|
35
|
-
for x in chunk:
|
|
36
|
-
print(x)
|
|
37
|
-
i = 4
|
|
38
|
-
chunk = post_list_[i:i + chunk_size]
|
|
39
|
-
print(f"=====CHUNK {i}=====")
|
|
40
|
-
for x in chunk:
|
|
41
|
-
print(x)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
print("=====TEST=====")
|
|
45
|
-
original_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
|
|
46
|
-
|
|
47
|
-
chunk_size = 5
|
|
48
|
-
for i in range(0, len(original_list), chunk_size):
|
|
49
|
-
print(i)
|
|
50
|
-
chunk = original_list[i:i + chunk_size]
|
|
51
|
-
print(chunk)
|
|
52
|
-
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
async def main():
|
|
57
|
-
r = Rule34Api()
|
|
58
|
-
p = r.get_post(213)
|
|
59
|
-
print(p)
|
|
60
|
-
|
|
61
|
-
if __name__ == '__main__':
|
|
62
|
-
asyncio.run(main())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simple_rule34-0.1.5.4/src/SimpleRule34/aio → simple_rule34-0.1.6/src/SimpleRule34}/utils.py
RENAMED
|
File without changes
|
{simple_rule34-0.1.5.4 → simple_rule34-0.1.6}/src/simple_rule34.egg-info/dependency_links.txt
RENAMED
|
File without changes
|