Skip to content
GitLab
Explorer
Connexion
Navigation principale
Rechercher ou aller à…
Projet
lektor
Gestion
Activité
Membres
Labels
Programmation
Tickets
Tableaux des tickets
Jalons
Code
Requêtes de fusion
Dépôt
Branches
Validations
Étiquettes
Graphe du dépôt
Comparer les révisions
Compilation
Pipelines
Jobs
Planifications de pipeline
Artéfacts
Aide
Aide
Support
Documentation de GitLab
Comparer les forfaits GitLab
Forum de la communauté GitLab
Contribuer à GitLab
Donner votre avis
Raccourcis clavier
?
Extraits de code
Groupes
Projets
Afficher davantage de fils d'Ariane
Kubat
lektor
Validations
de280848
Vérifiée
Valider
de280848
rédigé
16 mai 2021
par
Krocoh
Validation de
Kubat
28 juin 2021
Parcourir les fichiers
Options
Téléchargements
Correctifs
Plain Diff
KAGARI: Add option to download multiple files at once
parent
a969060b
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion
!161
Kagari update
Modifications
1
Afficher les modifications d'espaces
En ligne
Côte à côte
Affichage de
1 fichier modifié
utils/scripts/kagari.py
+122
-92
122 ajouts, 92 suppressions
utils/scripts/kagari.py
avec
122 ajouts
et
92 suppressions
utils/scripts/kagari.py
+
122
−
92
Voir le fichier @
de280848
...
@@ -25,8 +25,9 @@ def create_parser():
...
@@ -25,8 +25,9 @@ def create_parser():
usage
=
"
kagari [-h] (dl [dl options] | search [search options])
"
usage
=
"
kagari [-h] (dl [dl options] | search [search options])
"
desc
=
"""
Client to interact with the Kurisu API. Two main modes:
desc
=
"""
Client to interact with the Kurisu API. Two main modes:
-dl: downloads the specified file, or a tar file of the entire database
-search: searches the database with filters for info on the files
-search: searches the database with filters for info on the files
"""
-dl: downloads the target file with an ID, or multiple files with filters
To download the entire database, use neither ID nor filters
"""
parser
=
argparse
.
ArgumentParser
(
parser
=
argparse
.
ArgumentParser
(
usage
=
usage
,
usage
=
usage
,
...
@@ -52,7 +53,7 @@ def create_parser():
...
@@ -52,7 +53,7 @@ def create_parser():
"
-i
"
,
"
-i
"
,
"
--id
"
,
"
--id
"
,
help
=
'
In
"
dl
"
mode, if specified, downloads target video file.
'
help
=
'
In
"
dl
"
mode, if specified, downloads target video file.
'
+
"
\n
If absent in this mode,
downloads the tar of the whole base
.
"
+
"
\n
If absent in this mode,
filter arguments are used instead
.
"
+
'
\n
In
"
search
"
mode, returns info of the target file.
\n
'
,
+
'
\n
In
"
search
"
mode, returns info of the target file.
\n
'
,
)
)
...
@@ -70,32 +71,32 @@ def create_parser():
...
@@ -70,32 +71,32 @@ def create_parser():
"
--check
"
,
"
--check
"
,
action
=
"
store_true
"
,
action
=
"
store_true
"
,
help
=
'
In
"
dl
"
mode, first displays info on the targeted
'
help
=
'
In
"
dl
"
mode, first displays info on the targeted
'
+
"
\n
file, and asks for confirmation before downloading.
\n
"
,
+
"
\n
file
(s)
, and asks for confirmation before downloading.
\n
"
,
)
)
parser
.
add_argument
(
parser
.
add_argument
(
"
-a
"
,
"
-a
"
,
"
--author
"
,
"
--author
"
,
help
=
'
In
"
search
"
mode, filters by author. (case insensitive)
'
help
=
'
In
either
mode, filters by author. (case insensitive)
'
,
)
)
parser
.
add_argument
(
parser
.
add_argument
(
"
-c
"
,
"
-c
"
,
"
--category
"
,
"
--category
"
,
dest
=
"
cat
"
,
dest
=
"
cat
"
,
help
=
'
In
"
search
"
mode, filters by category.
\n
'
,
help
=
'
In
either
mode, filters by category.
\n
'
,
)
)
parser
.
add_argument
(
parser
.
add_argument
(
"
-t
"
,
"
--type
"
,
help
=
'
In
"
search
"
mode, filters by type.
\n
'
"
-t
"
,
"
--type
"
,
help
=
'
In
either
mode, filters by type.
\n
'
)
)
parser
.
add_argument
(
parser
.
add_argument
(
"
-s
"
,
"
-s
"
,
"
--string
"
,
"
--string
"
,
dest
=
"
search
"
,
dest
=
"
search
"
,
help
=
'
In
"
search
"
mode, filters on the names of sources and songs
'
help
=
'
In
either
mode, filters on the names of sources and songs
'
+
"
\n
matching the given string. (case insensitive)
\n
"
+
"
\n
matching the given string. (case insensitive)
\n
"
,
)
)
parser
.
add_argument
(
parser
.
add_argument
(
...
@@ -110,7 +111,7 @@ def create_parser():
...
@@ -110,7 +111,7 @@ def create_parser():
"
-j
"
,
"
-j
"
,
"
--json
"
,
"
--json
"
,
action
=
"
store_true
"
,
action
=
"
store_true
"
,
help
=
'
In
"
search
"
mode, output the result as a json.
'
help
=
'
In
"
search
"
mode, output the result as a json.
'
,
)
)
return
parser
return
parser
...
@@ -132,6 +133,44 @@ def make_request(url):
...
@@ -132,6 +133,44 @@ def make_request(url):
return
response
return
response
def
search_query
(
args
):
"
Searches the database with ID or filters, and returns the response json
"
url
=
"
https://kurisu.iiens.net/api
"
url_values
=
dict
()
# If ID, it's the only parameter needed
if
args
.
id
:
url_values
[
"
id
"
]
=
args
.
id
# No ID, building the query parameters
else
:
for
arg_name
in
[
"
author
"
,
"
cat
"
,
"
type
"
,
"
search
"
,
"
random
"
]:
arg
=
getattr
(
args
,
arg_name
)
if
arg
:
url_values
[
arg_name
]
=
arg
url_args
=
urlencode
(
url_values
)
if
url_args
:
url
+=
"
?
"
+
url_args
response
=
make_request
(
url
)
try
:
kara_json
=
json
.
loads
(
response
.
read
().
decode
(
"
utf-8
"
))
except
ValueError
:
emsg
=
"
The response JSON could not be loaded.
"
print
(
emsg
)
sys
.
exit
(
1
)
# Handling an error json
if
"
error
"
in
kara_json
:
default_emsg
=
"
An unknown error happened when searching the database.
"
emsg
=
kara_json
.
get
(
"
message
"
,
default_emsg
)
print
(
emsg
)
sys
.
exit
(
1
)
return
kara_json
def
build_kara_name
(
data
):
def
build_kara_name
(
data
):
"
Builds the name of the file from the response dictionary
"
"
Builds the name of the file from the response dictionary
"
src_name
=
data
[
"
source_name
"
]
src_name
=
data
[
"
source_name
"
]
...
@@ -148,9 +187,13 @@ def build_kara_name(data):
...
@@ -148,9 +187,13 @@ def build_kara_name(data):
return
kara_name
,
kara_additional
return
kara_name
,
kara_additional
def
kara_prompt
(
kara_string
):
def
kara_prompt
(
kara_string
=
""
,
kara_nbr
=
0
):
"
Simple yes/no prompt to confirm the download or not
"
"
Simple yes/no prompt to confirm the download or not
"
prompt_str
=
"
You are about to download
"
+
kara_string
prompt_str
=
"
You are about to download
"
if
kara_string
:
prompt_str
+=
kara_string
else
:
prompt_str
+=
f
"
{
kara_nbr
}
files
"
prompt_str
+=
"
\n
Do you want to proceed ? ([y]/n)
"
prompt_str
+=
"
\n
Do you want to proceed ? ([y]/n)
"
answers
=
{
"
y
"
:
True
,
"
n
"
:
False
,
"
ye
"
:
True
,
"
yes
"
:
True
,
"
no
"
:
False
}
answers
=
{
"
y
"
:
True
,
"
n
"
:
False
,
"
ye
"
:
True
,
"
yes
"
:
True
,
"
no
"
:
False
}
...
@@ -162,49 +205,38 @@ def kara_prompt(kara_string):
...
@@ -162,49 +205,38 @@ def kara_prompt(kara_string):
ans
=
"
y
"
ans
=
"
y
"
except
KeyboardInterrupt
:
except
KeyboardInterrupt
:
ans
=
"
n
"
ans
=
"
n
"
print
(
"
\n
"
)
print
(
""
)
except
EOFError
:
except
EOFError
:
ans
=
"
y
"
ans
=
"
y
"
return
answers
[
ans
]
return
answers
[
ans
]
def
dl_mode
(
args
):
def
dl_mode
(
args
,
kara_json
):
"
Downloads
ei
the
r the whole database as a tar, or a single video
file
"
"
Downloads the
targeted
file
s
"
# No ID, download the tar of the database
kara_id
=
None
if
not
args
.
id
:
kara_string
=
""
url
=
"
https://kurisu.iiens.net/kara.tar
"
kara_nbr
=
0
path
=
args
.
path
if
args
.
path
else
os
.
getcwd
()
filename
=
path
+
"
/kara.tar
"
print
(
f
'
Downloading and writing archive as
"
{
filename
}
"'
)
if
len
(
kara_json
)
==
1
:
response
=
make_request
(
url
)
if
type
(
kara_json
)
is
list
:
kara_json
=
kara_json
[
0
]
# Writing the tar file
kara_name
,
kara_additional
=
build_kara_name
(
kara_json
)
with
open
(
filename
,
'
wb
'
)
as
out_file
:
kara_string
=
'"'
+
kara_name
+
'"'
+
kara_additional
try
:
kara_id
=
kara_json
[
"
id
"
]
shutil
.
copyfileobj
(
response
,
out_file
)
except
KeyboardInterrupt
:
print
(
"
\n
Download interrupted by user input.
"
)
else
:
print
(
"
All done !
"
)
# An ID, download target file
else
:
else
:
search_url
=
f
"
https://kurisu.iiens.net/api?id=
{
args
.
id
}
"
kara_nbr
=
len
(
kara_json
)
search
=
make_request
(
search_url
)
kara_data
=
json
.
loads
(
search
.
read
().
decode
(
"
utf-8
"
))
kara_name
,
kara_additional
=
build_kara_name
(
kara_data
)
# If asked for check, display the prompt
# If asked for check, display the prompt
if
args
.
check
:
if
args
.
check
:
kara_string
=
'"'
+
kara_name
+
'"'
+
kara_additional
prompt
=
kara_prompt
(
kara_string
,
kara_nbr
)
prompt
=
kara_prompt
(
kara_string
)
if
not
prompt
:
if
not
prompt
:
print
(
"
Download cancelled.
"
)
print
(
"
Download cancelled.
"
)
return
return
url
=
f
"
https://kurisu.iiens.net/api/download/
{
args
.
id
}
"
if
kara_id
:
url
=
f
"
https://kurisu.iiens.net/api/download/
{
kara_id
}
"
path
=
args
.
path
if
args
.
path
else
os
.
getcwd
()
path
=
args
.
path
if
args
.
path
else
os
.
getcwd
()
filename
=
path
+
"
/
"
+
kara_name
+
"
.mkv
"
filename
=
path
+
"
/
"
+
kara_name
+
"
.mkv
"
...
@@ -212,71 +244,64 @@ def dl_mode(args):
...
@@ -212,71 +244,64 @@ def dl_mode(args):
response
=
make_request
(
url
)
response
=
make_request
(
url
)
# Writing the video file
# Writing the video file
with
open
(
filename
,
'
wb
'
)
as
out_file
:
with
open
(
filename
,
"
wb
"
)
as
out_file
:
try
:
shutil
.
copyfileobj
(
response
,
out_file
)
shutil
.
copyfileobj
(
response
,
out_file
)
except
KeyboardInterrupt
:
print
(
"
\n
Download interrupted by user input.
"
)
else
:
print
(
"
All done !
"
)
def
search_mode
(
args
):
"
Performs a search request on the database and returns the answer
"
url
=
"
https://kurisu.iiens.net/api
"
url_values
=
dict
()
# If ID, it's the only parameter needed
if
args
.
id
:
url_values
[
"
id
"
]
=
args
.
id
# No ID, building the query parameters
else
:
else
:
for
arg_name
in
[
"
author
"
,
"
cat
"
,
"
type
"
,
"
search
"
,
"
random
"
]:
print
(
f
"
Download in progress: 0/
{
kara_nbr
}
"
,
end
=
""
)
arg
=
getattr
(
args
,
arg_name
)
sys
.
stdout
.
flush
(
)
if
arg
:
for
curr_nbr
,
kara
in
enumerate
(
kara_json
)
:
url_values
[
arg_name
]
=
ar
g
kara_id
=
k
ar
a
[
"
id
"
]
kara_name
,
_
=
build_kara_name
(
kara
)
url_args
=
urlencode
(
url_values
)
url
=
f
"
https://kurisu.iiens.net/api/download/
{
kara_id
}
"
if
url_args
:
path
=
args
.
path
if
args
.
path
else
os
.
getcwd
()
url
+
=
"
?
"
+
url_args
filename
=
path
+
"
/
"
+
kara_name
+
"
.mkv
"
response
=
make_request
(
url
)
response
=
make_request
(
url
)
try
:
# Writing the video file
kara_json
=
json
.
loads
(
response
.
read
().
decode
(
"
utf-8
"
))
with
open
(
filename
,
"
wb
"
)
as
out_file
:
except
ValueError
:
shutil
.
copyfileobj
(
response
,
out_file
)
emsg
=
"
The response JSON could not be loaded.
"
print
(
f
"
\r
Download in progress:
{
curr_nbr
+
1
}
/
{
kara_nbr
}
"
,
end
=
""
)
print
(
emsg
)
sys
.
stdout
.
flush
()
sys
.
exit
(
1
)
print
(
""
)
print
(
"
All done !
"
)
def
search_mode
(
args
,
kara_json
):
"
Performs a search request on the database and returns the answer
"
if
args
.
json
:
if
args
.
json
:
pretty_output
=
json
.
dumps
(
kara_json
,
indent
=
4
,
ensure_ascii
=
False
)
pretty_output
=
json
.
dumps
(
kara_json
,
indent
=
4
,
ensure_ascii
=
False
)
pretty_output
+=
"
\n
"
else
:
else
:
pretty_output
=
""
pretty_output
=
""
for
res
in
kara_json
:
for
res
in
kara_json
:
new_kara
=
(
"
NEW!
"
if
res
[
'
is_new
'
]
==
"
1
"
else
""
)
new_kara
=
"
NEW!
"
if
res
[
"
is_new
"
]
==
"
1
"
else
""
output_string
=
build_kara_name
(
res
)
output_info
=
build_kara_name
(
res
)
output_string
=
f
"
[
{
res
[
'
id
'
]
}
]
{
output_string
[
0
]
}
\n
"
+
\
output_string
=
(
f
"
{
output_string
[
1
]
}
in
{
res
[
'
author_year
'
]
}{
new_kara
}
\n
"
+
\
f
"
[
{
res
[
'
id
'
]
}
]
{
output_info
[
0
]
}
\n
"
f
"
Size:
{
res
[
'
size
'
]
}
Kio
\n
"
+
f
"
{
output_info
[
1
]
}
in
{
res
[
'
author_year
'
]
}{
new_kara
}
\n
"
+
f
"
Size:
{
res
[
'
size
'
]
}
Kio
\n
"
)
pretty_output
+=
output_string
pretty_output
+=
output_string
if
res
[
'
popularity
'
]:
if
res
[
"
popularity
"
]:
pretty_output
+=
"
Popularity:
"
+
res
[
'
popularity
'
]
+
"
\n
"
pretty_output
+=
"
Popularity:
"
+
res
[
"
popularity
"
]
+
"
\n
"
if
res
[
'
upload_comment
'
]:
if
res
[
"
upload_comment
"
]:
for
comment_line
in
wrap
(
res
[
'
upload_comment
'
],
fix_sentence_endings
=
True
):
for
comment_line
in
wrap
(
res
[
"
upload_comment
"
],
fix_sentence_endings
=
True
):
pretty_output
+=
"
"
+
comment_line
+
"
\n
"
pretty_output
+=
"
"
+
comment_line
+
"
\n
"
pretty_output
+=
"
\n
"
pretty_output
+=
"
\n
"
# Displaying the received JSON, or writing it to a file
# Displaying the received JSON, or writing it to a file
if
not
args
.
path
:
if
not
args
.
path
:
print
(
pretty_output
,
end
=
''
)
print
(
pretty_output
,
end
=
""
)
else
:
else
:
try
:
try
:
with
open
(
args
.
path
,
"
w
"
)
as
output_file
:
with
open
(
args
.
path
,
"
w
"
)
as
output_file
:
output_file
.
write
(
pretty_output
)
output_file
.
write
(
pretty_output
)
except
OSError
as
err
:
except
OSError
as
err
:
emsg
=
"
Cannot create/open the search output file:
"
emsg
=
"
Cannot create/open the search output file:
"
emsg
+=
err
emsg
+=
str
(
err
)
print
(
emsg
)
print
(
emsg
)
sys
.
exit
(
1
)
sys
.
exit
(
1
)
...
@@ -286,10 +311,15 @@ def run():
...
@@ -286,10 +311,15 @@ def run():
parser
=
create_parser
()
parser
=
create_parser
()
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
kara_json
=
search_query
(
args
)
if
args
.
mode
==
"
dl
"
:
if
args
.
mode
==
"
dl
"
:
dl_mode
(
args
)
try
:
dl_mode
(
args
,
kara_json
)
except
KeyboardInterrupt
:
print
(
"
\n
Download interrupted by user input.
"
)
elif
args
.
mode
==
"
search
"
:
elif
args
.
mode
==
"
search
"
:
search_mode
(
args
)
search_mode
(
args
,
kara_json
)
else
:
else
:
print
(
f
'
Unknown mode
"
{
args
.
mode
}
"
. Use either
"
dl
"
or
"
search
"
.
'
)
print
(
f
'
Unknown mode
"
{
args
.
mode
}
"
. Use either
"
dl
"
or
"
search
"
.
'
)
sys
.
exit
(
1
)
sys
.
exit
(
1
)
...
...
Ce diff est replié.
Cliquez pour l'agrandir.
Aperçu
0%
Chargement en cours
Veuillez réessayer
ou
joindre un nouveau fichier
.
Annuler
You are about to add
0
people
to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Enregistrer le commentaire
Annuler
Veuillez vous
inscrire
ou vous
se connecter
pour commenter