ifuse 0.3.6__py3-none-any.whl

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.
anomlib/__init__.py ADDED
File without changes
anomlib/argparser.py ADDED
@@ -0,0 +1,315 @@
1
+ """Parse command line arguments.
2
+
3
+ Sub commands are supported by arglib.
4
+ Nested sub commands for arglib are not planned yet."""
5
+
6
+ # Note: This code was vibe-coded as i got bored
7
+ # I had paramparser that worked, but dont wanna play parsing anymore
8
+ # I promise i will replace these vibes with blood, sweat and tears
9
+ import argparse
10
+
11
+ import anomlib.confman
12
+
13
+ # DATA = anomlib.confman.Conflock("params/anomtool.toml").load()
14
+
15
+
16
+ # Compatibility with optparse-style type names.
17
+ TYPE_NAMES = {
18
+ "string": str,
19
+ "int": int,
20
+ "integer": int,
21
+ "float": float,
22
+ }
23
+
24
+ # Default structure to support arguments
25
+ ARGS = {
26
+ "class": "arg",
27
+ "nargs": "*",
28
+ "type": "string",
29
+ "help": "Input files and other positional arguments",
30
+ }
31
+
32
+ DRAFTS = {
33
+ "diff": {
34
+ "patch": {
35
+ "class": "flag",
36
+ "shorts": "pu",
37
+ "help": "Generate patch",
38
+ "default": True,
39
+ },
40
+ "output": {
41
+ "class": "value",
42
+ "shorts": "o",
43
+ "keys": ["file"],
44
+ "type": "string",
45
+ "help": "Write output to a file",
46
+ }
47
+ },
48
+ }
49
+
50
+
51
+ class ArgParser:
52
+ "ArgParser handles one sub command"
53
+ def __init__(self, command, drafts=None, parser=None):
54
+ self.command = command
55
+ self.drafts = DRAFTS if drafts is None else drafts
56
+ self.parser = (
57
+ parser
58
+ if parser is not None
59
+ else argparse.ArgumentParser()
60
+ )
61
+ self.build()
62
+
63
+ def build(self):
64
+ try:
65
+ self.params = self.drafts[self.command]
66
+ # Support all args
67
+ self.params["args"] = ARGS
68
+ except KeyError:
69
+ print(self.drafts)
70
+ raise ValueError(
71
+ f"Unknown command: {self.command!r}"
72
+ )
73
+
74
+ for name, config in self.params.items():
75
+ self.add_option(name, config)
76
+
77
+ return self
78
+
79
+ def add_option(self, name, params):
80
+ """
81
+ Dispatch an option or positional argument to its handler.
82
+
83
+ Supported classes:
84
+
85
+ "flag" Boolean option
86
+ "value" Option that accepts a value
87
+ "arg" Positional argument
88
+ """
89
+ params = dict(params)
90
+ option_class = params.pop("class", "value")
91
+
92
+ handler = getattr(
93
+ self,
94
+ f"add_{option_class}",
95
+ None,
96
+ )
97
+
98
+ if handler is None:
99
+ raise ValueError(
100
+ f"Unsupported option class: {option_class!r}"
101
+ )
102
+
103
+ return handler(name, params)
104
+
105
+ def add_flag(self, name, params):
106
+ """
107
+ Add a Boolean option and its negative aliases.
108
+
109
+ Example:
110
+
111
+ --patch
112
+ --no-patch
113
+ --non-patch
114
+ """
115
+ params = dict(params)
116
+
117
+ shorts = params.pop("shorts", "")
118
+ keys = params.pop("keys", [])
119
+ dest = params.setdefault("dest", name)
120
+
121
+ positive_params = dict(params)
122
+ positive_params.update({
123
+ "action": "count",
124
+ "dest": dest,
125
+ })
126
+
127
+ self._add_option_argument(
128
+ name=name,
129
+ shorts=shorts,
130
+ keys=keys,
131
+ params=positive_params,
132
+ )
133
+
134
+ # SUPPRESS prevents the negative option from replacing the
135
+ # default defined by the positive option.
136
+ self.parser.add_argument(
137
+ f"--no-{name}",
138
+ f"--non-{name}",
139
+ action="store_false",
140
+ dest=dest,
141
+ default=argparse.SUPPRESS,
142
+ )
143
+
144
+ return self
145
+
146
+ def add_value(self, name, params):
147
+ """
148
+ Add an option that accepts a value.
149
+
150
+ Example:
151
+
152
+ --output changes.diff
153
+ -o changes.diff
154
+ """
155
+ params = dict(params)
156
+
157
+ shorts = params.pop("shorts", "")
158
+ keys = params.pop("keys", [])
159
+
160
+ self._convert_type(params)
161
+
162
+ return self._add_option_argument(
163
+ name=name,
164
+ shorts=shorts,
165
+ keys=keys,
166
+ params=params,
167
+ )
168
+
169
+ def add_arg(self, name, params):
170
+ """
171
+ Add a positional argument.
172
+
173
+ Example configuration:
174
+
175
+ "args": {
176
+ "class": "arg",
177
+ "nargs": "*",
178
+ }
179
+
180
+ This allows:
181
+
182
+ program file1.txt --output result.diff file2.txt
183
+ """
184
+ params = dict(params)
185
+
186
+ # These settings apply to options, not positional arguments.
187
+ params.pop("shorts", None)
188
+ params.pop("keys", None)
189
+
190
+ self._convert_type(params)
191
+
192
+ self.parser.add_argument(
193
+ name,
194
+ **params,
195
+ )
196
+
197
+ return self
198
+
199
+ def _add_option_argument(
200
+ self,
201
+ name,
202
+ shorts="",
203
+ keys=None,
204
+ params=None,
205
+ ):
206
+ """
207
+ Add an optional argument with short and long aliases.
208
+
209
+ A string such as "pu" becomes:
210
+
211
+ -p
212
+ -u
213
+ """
214
+ keys = [] if keys is None else keys
215
+ params = {} if params is None else params
216
+
217
+ option_strings = [
218
+ *(f"-{short}" for short in shorts),
219
+ f"--{name}",
220
+ *(
221
+ key if key.startswith("-") else f"--{key}"
222
+ for key in keys
223
+ ),
224
+ ]
225
+
226
+ self.parser.add_argument(
227
+ *option_strings,
228
+ **params,
229
+ )
230
+
231
+ return self
232
+
233
+ @staticmethod
234
+ def _convert_type(params):
235
+ """
236
+ Convert type names such as "string" and "int" into
237
+ callables accepted by argparser.
238
+ """
239
+ value_type = params.get("type")
240
+
241
+ if not isinstance(value_type, str):
242
+ return
243
+
244
+ try:
245
+ params["type"] = TYPE_NAMES[value_type]
246
+ except KeyError:
247
+ raise ValueError(
248
+ f"Unsupported option type: {value_type!r}"
249
+ )
250
+
251
+ def parse_args(self, args=None):
252
+ """
253
+ Parse options and interspersed positional arguments.
254
+
255
+ Unlike regular parse_args(), parse_intermixed_args() allows
256
+ positional arguments to appear before, between, and after
257
+ optional arguments.
258
+ """
259
+ try:
260
+ namespace = self.parser.parse_intermixed_args(args)
261
+ except AttributeError:
262
+ raise RuntimeError(
263
+ "Intermixed argument parsing requires Python 3.7 "
264
+ "or newer."
265
+ )
266
+
267
+ return vars(namespace)
268
+
269
+ def merge_parser_arguments(self, source):
270
+ """Add arguments from source to target unless target already defines them."""
271
+
272
+ target_dests = {
273
+ action.dest
274
+ for action in self.parser._actions
275
+ if action.dest != "help"
276
+ }
277
+
278
+ target_options = {
279
+ option
280
+ for action in self.parser._actions
281
+ for option in action.option_strings
282
+ }
283
+
284
+ for action in source._actions:
285
+ if action.dest == "help":
286
+ continue
287
+
288
+ # A has redefined this argument
289
+ if action.dest in target_dests:
290
+ continue
291
+
292
+ # Avoid option-string collisions too
293
+ if any(option in target_options for option in action.option_strings):
294
+ continue
295
+
296
+ self.parser._add_action(action)
297
+
298
+ target_dests.add(action.dest)
299
+ target_options.update(action.option_strings)
300
+
301
+
302
+ def test_argparser(command, *args, **kwargs):
303
+ parser = ArgParser(command, *args, **kwargs)
304
+
305
+ # values = parser.parse_args(["1", "-s", "foo", "bye"])
306
+ # print(values)
307
+
308
+ values = parser.parse_args()
309
+ print(values)
310
+
311
+
312
+ # if __name__ == "__main__":
313
+ # test_argparser("diff")
314
+ # # test_argparser("pull", drafts=DATA)
315
+ # # test_argparser("master", drafts=DATA)
File without changes
anomlib/builtin/do.py ADDED
@@ -0,0 +1,69 @@
1
+ "4g-with is a REPL command that allows calling commands in a loop while changing only args for it."
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ import subprocess, re
7
+ import sys, tarfile, stat
8
+ import hashlib, time
9
+
10
+
11
+ import logging, os, sys
12
+
13
+ import anomlib.shell
14
+ import anomlib.pillow
15
+
16
+ home = Path.home()
17
+
18
+ anomtoolDoCache = home / ".cache/anomtool/do"
19
+ anomtoolDoHistory = anomtoolDoCache / "history"
20
+ anomtoolDoLog = anomtoolDoCache / "do.log"
21
+
22
+
23
+ anomlib.pillow.mkdirs(str(anomtoolDoCache))
24
+ anomlib.pillow.mkdirs(str(anomtoolDoHistory))
25
+
26
+
27
+ # Configure logging
28
+
29
+ logging.basicConfig(filename=anomtoolDoLog, level=logging.DEBUG)
30
+
31
+ # Log messages
32
+
33
+
34
+ def inputline(
35
+ color = "Yellow",
36
+ prompt = "% ",
37
+ history = "",
38
+ readline = "rlwrap",
39
+ args = sys.argv[1:]
40
+ ):
41
+ """Wrapper around readline tool (the rlwrap, a wrapper around gnu-readline in C)
42
+
43
+ i can use any readline library when i figure out how to do it.
44
+ Why so many wrappers? First make it work! Then make it beautiful!"""
45
+ _history = history if history else " ".join(args)
46
+ _history = anomtoolDoHistory / f"{_history}_history"
47
+ return anomlib.shell.read_command(f"{readline} -p{color} -S '{prompt}' -H '{_history}' -o cat")
48
+
49
+
50
+ ## Do will support params, but they needs to be added via --param=key=<value> or --param=flag, etc.
51
+ ## each --param call will update params dictionary.
52
+
53
+ def do_repl(*args, **kwargs):
54
+ command = " ".join(kwargs["args"])
55
+ print("kwargs:", kwargs)
56
+ "main function for 'anomtool do'"
57
+ while True:
58
+ cmd = inputline(**kwargs)
59
+ print(cmd)
60
+ if cmd == "exit":
61
+ logging.debug(f"at-do: exiting command: {kwargs["args"]}")
62
+ break
63
+ elif not cmd:
64
+ logging.debug(f'at-do: do nothing in this command: {kwargs["args"]}')
65
+ # Do nothing if cmd is empty
66
+ pass
67
+
68
+ anomlib.shell.runcmd(f"{command} {cmd}")
69
+ logging.debug(f'at-do: command: {command} {cmd};')
@@ -0,0 +1,83 @@
1
+ import hashlib, os, sys
2
+ from pathlib import Path
3
+
4
+ import anomlib.pillow
5
+
6
+ home = Path.home()
7
+
8
+ ggHome = home / "Pictures/gg"
9
+ ggType = "jpeg"
10
+ anomlib.pillow.mkdirs(str(ggHome))
11
+
12
+
13
+
14
+ def num_to_index(start, stop, end, url_begin="", urlend=""):
15
+ fixture = len(str(end)) - len(str(start))
16
+ # Fix url_begin if the number's power is weak
17
+ url_begin += '0' * fixture
18
+ request = f'{url_begin}[{start}-{stop}]{urlend}'
19
+ return request
20
+
21
+
22
+ def get_range(numbers, fixture):
23
+ fixture -= len(str(numbers[0])) - 1
24
+ patch = '0' * fixture
25
+ start = numbers[0]
26
+ stop = numbers[-1]
27
+ return start, stop
28
+
29
+ def get_ranges(start, stop):
30
+ stop += 1
31
+ fixture = len(str(stop)) - len(str(start))
32
+ result = []
33
+ powers = {}
34
+ for i in [str(i) for i in range(start, stop)]:
35
+ if str(len(i)) not in powers:
36
+ powers[str(len(i))] = []
37
+ powers[str(len(i))] += [i]
38
+ for power, numbers in powers.items():
39
+ result += [get_range(numbers, fixture)]
40
+ return result
41
+
42
+ def curlRange(start, stop, url_begin="file_", urlend=".jpg"):
43
+ result = []
44
+ # stop += 1
45
+ for a, b in get_ranges(start, stop):
46
+ print ("a,b:", a, b)
47
+ result += [num_to_index(a, b, stop, url_begin, urlend)]
48
+ return result
49
+
50
+
51
+ def getGallery(start, stop, url_begin="file_", urlend=".jpg",
52
+ ggHome=ggHome, ggType=ggType):
53
+ hash = anomlib.pillow.hashedString(url_begin + urlend)
54
+ print(hash)
55
+ requests = curlRange(start, stop, url_begin, urlend)
56
+
57
+ ggDir = Path(ggHome) / hash
58
+
59
+ # Do not proceed if dir alr exist
60
+ if os.path.isdir(ggDir):
61
+ print(f"The {hash} Files are already downloaded")
62
+ return
63
+
64
+ # Fixme: Check that dir does not exist and then proceed
65
+ anomlib.pillow.mkdirs(str(ggDir))
66
+
67
+ # Fixme: Change directory to current working directory
68
+ os.chdir(ggDir)
69
+
70
+ print(requests)
71
+ for request in requests:
72
+ print(f"curl '{request}' -o 'local2-#1.{ggType}'")
73
+ anomlib.shell.runcmd(f"curl {request} -o 'local-#1.{ggType}'")
74
+
75
+
76
+
77
+ # print()
78
+ # # print(getGallery(1, 900, "file", ".png"))
79
+ # # print(getGallery(1, 90, "file-", ".jpeg"))
80
+ # print(getGallery(1, 23, "https://image.hdporncomics.com/uploads/disguised-lust-0", ".jpg"))
81
+ # # print(getGallery(1, 5, "https://image.hdporncomics.com/uploads/angel-x-stitch-00", ".jpg"))
82
+ # # print(getGallery(1, 11, "https://im.hdporncomics.com/uploads/560facf644dc7837b5bd6f2a726c6582/she-s-not-little-anymore-0", ".jpg"))
83
+
anomlib/builtin/u2.py ADDED
@@ -0,0 +1,26 @@
1
+ """ Y2 is a Youtube parser for fun.
2
+ I will try to call invidious and/or youtube and play with their stuff they give me.
3
+ The more info we reach the more stuff we can do with it.
4
+ """
5
+
6
+ import requests
7
+ from bs4 import BeautifulSoup
8
+
9
+ # Fetch the page directly
10
+ url = "https://www.youtube.com/playlist?list=PLRBp0Fe2Gpgn8Y9qI-p0aTxVtw8onBSFj"
11
+ # url = "https://inv.nadeko.net/playlist?list=PLRBp0Fe2Gpgn8Y9qI-p0aTxVtw8onBSFj"
12
+ html = requests.get(url).text
13
+
14
+ # Parse the HTML with BeautifulSoup + lxml
15
+ soup = BeautifulSoup(html, "lxml")
16
+
17
+ # Extract the title and all links
18
+ print(soup.title.get_text())
19
+
20
+ for link in soup.select("a[href]"):
21
+ print(link["href"])
22
+
23
+
24
+ # We will try different stratagies such us using different sites.
25
+ # We will cache requests over to minimise the calls to google.
26
+
@@ -0,0 +1,39 @@
1
+ "Library wrapped around yt-dlp"
2
+
3
+ from pathlib import Path
4
+ import sys,os
5
+
6
+ import anomlib.shell
7
+ import anomlib.pillow
8
+
9
+
10
+ # You can group videos by categories. e.g. Linux, NSFW, Memes, Movies, Music, How2 etc.
11
+ # by default videos are stored in Unknown group.
12
+ # Feel free to move it into another group manually.
13
+ group = "Unknown/%(channel_id)s"
14
+ output = "%(title)s [%(id)s].%(ext)s".
15
+
16
+ home = Path.home()
17
+
18
+ # anomtool-youtube's home directory
19
+ youtube = home / "Videos/Youtube/ytool"
20
+ # Ytool is a command that is wrapped around anomtool-youtube builtin command
21
+ videos = youtube / group
22
+
23
+ video = videos / output
24
+
25
+ ## how to use manually:
26
+ # >>> print(f"{dest}/{output}" % {'title': "a", 'id': "b", 'ext': "c"})
27
+ # >>> str(video) % {'title':'video','id':'1','ext':'mp4'}
28
+ # Note: check 'man yt-dlp' to know more about "available fields".
29
+
30
+ pillow.mkdirs(videos)
31
+
32
+ # Current youtube-dl tool
33
+ yt_dl = "yt-dlp"
34
+
35
+ def yt(args=[], options='--all-subs'):
36
+ f"{yt_dl} {options} -- {' '.join(args)}"
37
+
38
+ yt(sys.argv[1:])
39
+
File without changes
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env python3
2
+ # This file is part of 4g, the forge client. (coding: utf-8)
3
+ # License: GNU Lesser GPL version 3, see the file "AUTHORS" for details.
4
+
5
+ # =====================
6
+ # This file originally got inspiration from ranger's main python script.
7
+ # ranger.py can be executed as python but also sourced in bash which is majestic.
8
+
9
+ # =====================
10
+ # This embedded bash script can be executed by sourcing this file.
11
+ # It will cd to ranger's last location after you exit it.
12
+ # The first argument specifies the command to run ranger, the
13
+ # default is simply "ranger". (Not this file itself!)
14
+ # The other arguments are passed to ranger.
15
+ """":
16
+ anomtool="${1:-./4g}"
17
+ if [ -n "$1" ]; then
18
+ shift
19
+ fi
20
+ "$anomtool" "${@:-$PWD}"
21
+ return "$?"
22
+ """
23
+
24
+ # import optparse
25
+ # import subprocess
26
+ # import textwrap
27
+ # import argparse
28
+ # import getopt
29
+ # import logging
30
+
31
+ import os
32
+ import sys
33
+
34
+ import anomlib.builtin.do
35
+ import anomlib.builtin.picload
36
+ import anomlib.pillow
37
+ import anomlib.prmparser
38
+ from anomlib.prmparser import ParamParser
39
+
40
+ CONF = "params/anomtool.toml"
41
+ CONF = os.path.abspath(CONF)
42
+ print(CONF)
43
+
44
+ # Fourgy's sub-Commands
45
+
46
+
47
+ def anomtool_hash(p: ParamParser):
48
+ "main function of anomtool-hash"
49
+ name = p.options["all"]["source"]
50
+ hashTool = p.options["all"]["hash"]
51
+ for url in p.args["all"]:
52
+ print(anomlib.pillow.hashFourgySource(
53
+ url, name=name, hashTool=hashTool))
54
+
55
+
56
+ def anomtool_do(p: ParamParser):
57
+ "main function for 4g do"
58
+
59
+ anomlib.builtin.do.do_repl(
60
+ args=p.args["all"],
61
+ history=p.options["all"]["history"],
62
+ readline=p.options["all"]["readline"],
63
+ prompt=p.options["all"]["prompt"],
64
+ color=p.options["all"]["color"])
65
+
66
+
67
+ def anomtool_picload(p: ParamParser):
68
+ "main function for anomtool picload"
69
+
70
+ start = p.options["all"]["start"]
71
+ stop = p.options["all"]["stop"]
72
+ urlend = p.options["all"]["ending"]
73
+ ggType = p.options["all"]["type"]
74
+ p.options["all"]["home"] = os.path.expanduser(p.options["all"]["home"])
75
+ ggHome = p.options["all"]["home"]
76
+ for url_begin in p.args["all"]:
77
+ anomlib.builtin.picload.getGallery(
78
+ start, stop, url_begin, urlend,
79
+ ggType=ggType, ggHome=ggHome,
80
+ )
81
+ # # print(getGallery(1, 90, "file-", ".jpeg"))
82
+
83
+
84
+ def main():
85
+ "Main function of anomtool command"
86
+ print(sys.argv[1:])
87
+ print(CONF)
88
+ p = ParamParser(toml=CONF)
89
+ return 0
90
+
91
+ # match p.command:
92
+ # case "hash":
93
+ # anomtool_hash(p)
94
+ # case "picload":
95
+ # anomtool_picload(p)
96
+ # case "do":
97
+ # anomtool_do(p)
98
+ # # case "install":
99
+ # # anomtool.foGive.install()
100
+
101
+
102
+ if __name__ == '__main__':
103
+ sys.exit(main())
File without changes