Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
douban-api-proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
douban-api-proxy
Commits
46197d82
Commit
46197d82
authored
May 24, 2020
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Edit and Upload books refactored
parent
e4eab175
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
126 additions
and
111 deletions
+126
-111
db.py
cps/db.py
+13
-11
editbooks.py
cps/editbooks.py
+110
-97
isoLanguages.py
cps/isoLanguages.py
+3
-3
No files found.
cps/db.py
View file @
46197d82
...
@@ -437,20 +437,22 @@ class CalibreDB(threading.Thread):
...
@@ -437,20 +437,22 @@ class CalibreDB(threading.Thread):
for
cc_id
in
cc_ids
:
for
cc_id
in
cc_ids
:
if
(
cc_id
[
1
]
==
'bool'
)
or
(
cc_id
[
1
]
==
'int'
)
or
(
cc_id
[
1
]
==
'float'
):
if
(
cc_id
[
1
]
==
'bool'
)
or
(
cc_id
[
1
]
==
'int'
)
or
(
cc_id
[
1
]
==
'float'
):
setattr
(
Books
,
'custom_column_'
+
str
(
cc_id
[
0
]),
relationship
(
cc_classes
[
cc_id
[
0
]],
setattr
(
Books
,
primaryjoin
=
(
'custom_column_'
+
str
(
cc_id
[
0
]),
Books
.
id
==
cc_classes
[
cc_id
[
0
]]
.
book
),
relationship
(
cc_classes
[
cc_id
[
0
]],
backref
=
'books'
))
primaryjoin
=
(
Books
.
id
==
cc_classes
[
cc_id
[
0
]]
.
book
),
backref
=
'books'
))
else
:
else
:
setattr
(
Books
,
'custom_column_'
+
str
(
cc_id
[
0
]),
relationship
(
cc_classes
[
cc_id
[
0
]],
setattr
(
Books
,
secondary
=
books_custom_column_links
[
cc_id
[
0
]],
'custom_column_'
+
str
(
cc_id
[
0
]),
backref
=
'books'
))
relationship
(
cc_classes
[
cc_id
[
0
]],
secondary
=
books_custom_column_links
[
cc_id
[
0
]],
backref
=
'books'
))
# global session
Session
=
scoped_session
(
sessionmaker
(
autocommit
=
False
,
Session
=
scoped_session
(
sessionmaker
(
autocommit
=
False
,
autoflush
=
False
,
autoflush
=
False
,
bind
=
self
.
engine
))
bind
=
self
.
engine
))
self
.
session
=
Session
()
self
.
session
=
Session
()
return
True
return
True
...
...
cps/editbooks.py
View file @
46197d82
...
@@ -314,15 +314,59 @@ def edit_book_ratings(to_save, book):
...
@@ -314,15 +314,59 @@ def edit_book_ratings(to_save, book):
changed
=
True
changed
=
True
return
changed
return
changed
def
edit_book_tags
(
tags
,
book
):
input_tags
=
tags
.
split
(
','
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
# if input_tags[0] !="": ??
return
modify_database_object
(
input_tags
,
book
.
tags
,
db
.
Tags
,
calibre_db
.
session
,
'tags'
)
def
edit_book_languages
(
to_save
,
book
):
input_languages
=
to_save
[
"languages"
]
.
split
(
','
)
def
edit_book_series
(
series
,
book
):
input_series
=
[
series
.
strip
()]
input_series
=
[
x
for
x
in
input_series
if
x
!=
''
]
return
modify_database_object
(
input_series
,
book
.
series
,
db
.
Series
,
calibre_db
.
session
,
'series'
)
def
edit_book_series_index
(
series_index
,
book
):
# Add default series_index to book
modif_date
=
False
series_index
=
series_index
or
'1'
#if series_index == '':
# series_index = '1'
if
book
.
series_index
!=
series_index
:
book
.
series_index
=
series_index
modif_date
=
True
return
modif_date
# Handle book comments/description
def
edit_book_comments
(
comments
,
book
):
modif_date
=
False
if
len
(
book
.
comments
):
if
book
.
comments
[
0
]
.
text
!=
comments
:
book
.
comments
[
0
]
.
text
=
comments
modif_date
=
True
else
:
if
comments
:
book
.
comments
.
append
(
db
.
Comments
(
text
=
comments
,
book
=
book
.
id
))
modif_date
=
True
return
modif_date
def
edit_book_languages
(
languages
,
book
,
upload
=
False
):
input_languages
=
languages
.
split
(
','
)
unknown_languages
=
[]
unknown_languages
=
[]
input_l
=
isoLanguages
.
get_language_codes
(
get_locale
(),
input_languages
,
unknown_languages
)
input_l
=
isoLanguages
.
get_language_codes
(
get_locale
(),
input_languages
,
unknown_languages
)
for
l
in
unknown_languages
:
for
l
in
unknown_languages
:
log
.
error
(
'
%
s is not a valid language'
,
l
)
log
.
error
(
'
%
s is not a valid language'
,
l
)
flash
(
_
(
u"
%(langname)
s is not a valid language"
,
langname
=
l
),
category
=
"error"
)
flash
(
_
(
u"
%(langname)
s is not a valid language"
,
langname
=
l
),
category
=
"warning"
)
return
modify_database_object
(
list
(
input_l
),
book
.
languages
,
db
.
Languages
,
calibre_db
.
session
,
'languages'
)
# ToDo: Not working correct
if
upload
and
len
(
input_l
)
==
1
:
# If the language of the file is excluded from the users view, it's not imported, to allow the user to view
# the book it's language is set to the filter language
if
input_l
[
0
]
!=
current_user
.
filter_language
()
and
current_user
.
filter_language
()
!=
"all"
:
input_l
[
0
]
=
calibre_db
.
session
.
query
(
db
.
Languages
)
.
\
filter
(
db
.
Languages
.
lang_code
==
current_user
.
filter_language
())
.
first
()
return
modify_database_object
(
input_l
,
book
.
languages
,
db
.
Languages
,
calibre_db
.
session
,
'languages'
)
def
edit_book_publisher
(
to_save
,
book
):
def
edit_book_publisher
(
to_save
,
book
):
...
@@ -559,33 +603,21 @@ def edit_book(book_id):
...
@@ -559,33 +603,21 @@ def edit_book(book_id):
else
:
else
:
flash
(
error
,
category
=
"error"
)
flash
(
error
,
category
=
"error"
)
if
book
.
series_index
!=
to_save
[
"series_index"
]:
# Add default series_index to book
book
.
series_index
=
to_save
[
"series_index"
]
modif_date
|=
edit_book_series_index
(
to_save
[
"series_index"
],
book
)
modif_date
=
True
# Handle book comments/description
# Handle book comments/description
if
len
(
book
.
comments
):
modif_date
|=
edit_book_comments
(
to_save
[
"description"
],
book
)
if
book
.
comments
[
0
]
.
text
!=
to_save
[
"description"
]:
book
.
comments
[
0
]
.
text
=
to_save
[
"description"
]
modif_date
=
True
else
:
if
to_save
[
"description"
]:
book
.
comments
.
append
(
db
.
Comments
(
text
=
to_save
[
"description"
],
book
=
book
.
id
))
modif_date
=
True
# Handle identifiers
# Handle identifiers
input_identifiers
=
identifier_list
(
to_save
,
book
)
input_identifiers
=
identifier_list
(
to_save
,
book
)
modif_date
|=
modify_identifiers
(
input_identifiers
,
book
.
identifiers
,
calibre_db
.
session
)
modif_date
|=
modify_identifiers
(
input_identifiers
,
book
.
identifiers
,
calibre_db
.
session
)
# Handle book tags
# Handle book tags
input_tags
=
to_save
[
"tags"
]
.
split
(
','
)
modif_date
|=
edit_book_tags
(
to_save
[
'tags'
],
book
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
modif_date
|=
modify_database_object
(
input_tags
,
book
.
tags
,
db
.
Tags
,
calibre_db
.
session
,
'tags'
)
# Handle book series
# Handle book series
input_series
=
[
to_save
[
"series"
]
.
strip
()]
modif_date
|=
edit_book_series
(
to_save
[
"series"
],
book
)
input_series
=
[
x
for
x
in
input_series
if
x
!=
''
]
modif_date
|=
modify_database_object
(
input_series
,
book
.
series
,
db
.
Series
,
calibre_db
.
session
,
'series'
)
if
to_save
[
"pubdate"
]:
if
to_save
[
"pubdate"
]:
try
:
try
:
...
@@ -599,7 +631,7 @@ def edit_book(book_id):
...
@@ -599,7 +631,7 @@ def edit_book(book_id):
modif_date
|=
edit_book_publisher
(
to_save
,
book
)
modif_date
|=
edit_book_publisher
(
to_save
,
book
)
# handle book languages
# handle book languages
modif_date
|=
edit_book_languages
(
to_save
,
book
)
modif_date
|=
edit_book_languages
(
to_save
[
'languages'
]
,
book
)
# handle book ratings
# handle book ratings
modif_date
|=
edit_book_ratings
(
to_save
,
book
)
modif_date
|=
edit_book_ratings
(
to_save
,
book
)
...
@@ -664,6 +696,7 @@ def upload():
...
@@ -664,6 +696,7 @@ def upload():
if
request
.
method
==
'POST'
and
'btn-upload'
in
request
.
files
:
if
request
.
method
==
'POST'
and
'btn-upload'
in
request
.
files
:
for
requested_file
in
request
.
files
.
getlist
(
"btn-upload"
):
for
requested_file
in
request
.
files
.
getlist
(
"btn-upload"
):
try
:
try
:
modif_date
=
False
# create the function for sorting...
# create the function for sorting...
calibre_db
.
update_title_sort
(
config
)
calibre_db
.
update_title_sort
(
config
)
calibre_db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
'uuid4'
,
0
,
lambda
:
str
(
uuid4
()))
calibre_db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
'uuid4'
,
0
,
lambda
:
str
(
uuid4
()))
...
@@ -690,9 +723,6 @@ def upload():
...
@@ -690,9 +723,6 @@ def upload():
return
Response
(
json
.
dumps
({
"location"
:
url_for
(
"web.index"
)}),
mimetype
=
'application/json'
)
return
Response
(
json
.
dumps
({
"location"
:
url_for
(
"web.index"
)}),
mimetype
=
'application/json'
)
title
=
meta
.
title
title
=
meta
.
title
authr
=
meta
.
author
authr
=
meta
.
author
tags
=
meta
.
tags
series
=
meta
.
series
series_index
=
meta
.
series_id
if
title
!=
_
(
u'Unknown'
)
and
authr
!=
_
(
u'Unknown'
):
if
title
!=
_
(
u'Unknown'
)
and
authr
!=
_
(
u'Unknown'
):
entry
=
calibre_db
.
check_exists_book
(
authr
,
title
)
entry
=
calibre_db
.
check_exists_book
(
authr
,
title
)
...
@@ -702,16 +732,32 @@ def upload():
...
@@ -702,16 +732,32 @@ def upload():
+
Markup
(
render_title_template
(
'book_exists_flash.html'
,
entry
=
entry
)),
category
=
"warning"
)
+
Markup
(
render_title_template
(
'book_exists_flash.html'
,
entry
=
entry
)),
category
=
"warning"
)
# handle authors
# handle authors
is_author
=
calibre_db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
authr
)
.
first
()
input_authors
=
authr
.
split
(
'&'
)
if
is_author
:
# handle_authors(input_authors)
db_author
=
is_author
input_authors
=
list
(
map
(
lambda
it
:
it
.
strip
()
.
replace
(
','
,
'|'
),
input_authors
))
authr
=
is_author
.
name
# we have all author names now
else
:
if
input_authors
==
[
''
]:
db_author
=
db
.
Authors
(
authr
,
helper
.
get_sorted_author
(
authr
),
""
)
input_authors
=
[
_
(
u'Unknown'
)]
# prevent empty Author
calibre_db
.
session
.
add
(
db_author
)
sort_authors_list
=
list
()
db_author
=
None
for
inp
in
input_authors
:
stored_author
=
calibre_db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
inp
)
.
first
()
if
not
stored_author
:
if
not
db_author
:
db_author
=
db
.
Authors
(
inp
,
helper
.
get_sorted_author
(
inp
),
""
)
calibre_db
.
session
.
add
(
db_author
)
calibre_db
.
session
.
commit
()
sort_author
=
helper
.
get_sorted_author
(
inp
)
else
:
if
not
db_author
:
db_author
=
stored_author
sort_author
=
stored_author
.
sort
sort_authors_list
.
append
(
sort_author
)
# helper.get_sorted_author(sort_author))
sort_authors
=
' & '
.
join
(
sort_authors_list
)
title_dir
=
helper
.
get_valid_filename
(
title
)
title_dir
=
helper
.
get_valid_filename
(
title
)
author_dir
=
helper
.
get_valid_filename
(
authr
)
author_dir
=
helper
.
get_valid_filename
(
db_author
.
name
)
filepath
=
os
.
path
.
join
(
config
.
config_calibre_dir
,
author_dir
,
title_dir
)
filepath
=
os
.
path
.
join
(
config
.
config_calibre_dir
,
author_dir
,
title_dir
)
saved_filename
=
os
.
path
.
join
(
filepath
,
title_dir
+
meta
.
extension
.
lower
())
saved_filename
=
os
.
path
.
join
(
filepath
,
title_dir
+
meta
.
extension
.
lower
())
...
@@ -738,78 +784,45 @@ def upload():
...
@@ -738,78 +784,45 @@ def upload():
else
:
else
:
has_cover
=
1
has_cover
=
1
# handle series
db_series
=
None
is_series
=
calibre_db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
name
==
series
)
.
first
()
if
is_series
:
db_series
=
is_series
elif
series
!=
''
:
db_series
=
db
.
Series
(
series
,
""
)
calibre_db
.
session
.
add
(
db_series
)
# add language actually one value in list
input_language
=
meta
.
languages
db_language
=
None
if
input_language
!=
""
:
input_language
=
isoLanguages
.
get
(
name
=
input_language
)
.
part3
hasLanguage
=
calibre_db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
lang_code
==
input_language
)
.
first
()
if
hasLanguage
:
db_language
=
hasLanguage
else
:
db_language
=
db
.
Languages
(
input_language
)
calibre_db
.
session
.
add
(
db_language
)
# If the language of the file is excluded from the users view, it's not imported, to allow the user to view
# the book it's language is set to the filter language
if
db_language
!=
current_user
.
filter_language
()
and
current_user
.
filter_language
()
!=
"all"
:
db_language
=
calibre_db
.
session
.
query
(
db
.
Languages
)
.
\
filter
(
db
.
Languages
.
lang_code
==
current_user
.
filter_language
())
.
first
()
# combine path and normalize path from windows systems
# combine path and normalize path from windows systems
path
=
os
.
path
.
join
(
author_dir
,
title_dir
)
.
replace
(
'
\\
'
,
'/'
)
path
=
os
.
path
.
join
(
author_dir
,
title_dir
)
.
replace
(
'
\\
'
,
'/'
)
# Calibre adds books with utc as timezone
# Calibre adds books with utc as timezone
db_book
=
db
.
Books
(
title
,
""
,
db_author
.
sort
,
datetime
.
utcnow
(),
datetime
(
101
,
1
,
1
),
db_book
=
db
.
Books
(
title
,
""
,
sort_authors
,
datetime
.
utcnow
(),
datetime
(
101
,
1
,
1
),
series_index
,
datetime
.
utcnow
(),
path
,
has_cover
,
db_author
,
[],
db_language
)
'1'
,
datetime
.
utcnow
(),
path
,
has_cover
,
db_author
,
[],
""
)
db_book
.
authors
.
append
(
db_author
)
if
db_series
:
modif_date
|=
modify_database_object
(
input_authors
,
db_book
.
authors
,
db
.
Authors
,
calibre_db
.
session
,
db_book
.
series
.
append
(
db_series
)
'author'
)
if
db_language
is
not
None
:
db_book
.
languages
.
append
(
db_language
)
# Add series_index to book
file_size
=
os
.
path
.
getsize
(
saved_filename
)
modif_date
|=
edit_book_series_index
(
meta
.
series_id
,
db_book
)
db_data
=
db
.
Data
(
db_book
,
meta
.
extension
.
upper
()[
1
:],
file_size
,
title_dir
)
# add languages
modif_date
|=
edit_book_languages
(
meta
.
languages
,
db_book
,
upload
=
True
)
# handle tags
# handle tags
input_tags
=
tags
.
split
(
','
)
modif_date
|=
edit_book_tags
(
meta
.
tags
,
db_book
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
if
input_tags
[
0
]
!=
""
:
# handle series
modify_database_object
(
input_tags
,
db_book
.
tags
,
db
.
Tags
,
calibre_db
.
session
,
'tags'
)
modif_date
|=
edit_book_series
(
meta
.
series
,
db_book
)
# flush content, get db_book.id available
# flush content, get db_book.id available
file_size
=
os
.
path
.
getsize
(
saved_filename
)
db_data
=
db
.
Data
(
db_book
,
meta
.
extension
.
upper
()[
1
:],
file_size
,
title_dir
)
db_book
.
data
.
append
(
db_data
)
db_book
.
data
.
append
(
db_data
)
# Comments needs book id therfore only possiblw after flush
modif_date
|=
edit_book_comments
(
Markup
(
meta
.
description
)
.
unescape
(),
db_book
)
calibre_db
.
session
.
add
(
db_book
)
calibre_db
.
session
.
add
(
db_book
)
calibre_db
.
session
.
flush
()
calibre_db
.
session
.
flush
()
# add comment
book_id
=
db_book
.
id
book_id
=
db_book
.
id
upload_comment
=
Markup
(
meta
.
description
)
.
unescape
()
if
upload_comment
!=
""
:
calibre_db
.
session
.
add
(
db
.
Comments
(
upload_comment
,
book_id
))
# save data to database, reread data
error
=
helper
.
update_dir_stucture
(
book_id
,
config
.
config_calibre_dir
,
input_authors
[
0
])
calibre_db
.
session
.
commit
()
calibre_db
.
update_title_sort
(
config
)
# Reread book. It's important not to filter the result, as it could have language which hide it from
# current users view (tags are not stored/extracted from metadata and could also be limited)
book
=
calibre_db
.
get_book
(
book_id
)
# upload book to gdrive if nesseccary and add "(bookid)" to folder name
if
config
.
config_use_google_drive
:
gdriveutils
.
updateGdriveCalibreFromLocal
()
error
=
helper
.
update_dir_stucture
(
book
.
id
,
config
.
config_calibre_dir
)
# move cover to final directory, including book id
# move cover to final directory, including book id
if
has_cover
:
if
has_cover
:
try
:
try
:
new_coverpath
=
os
.
path
.
join
(
filepath
+
' ({})'
.
format
(
book_id
)
,
"cover.jpg"
)
new_coverpath
=
os
.
path
.
join
(
config
.
config_calibre_dir
,
db_book
.
path
,
"cover.jpg"
)
copyfile
(
meta
.
cover
,
new_coverpath
)
copyfile
(
meta
.
cover
,
new_coverpath
)
os
.
unlink
(
meta
.
cover
)
os
.
unlink
(
meta
.
cover
)
except
OSError
as
e
:
except
OSError
as
e
:
...
@@ -817,7 +830,13 @@ def upload():
...
@@ -817,7 +830,13 @@ def upload():
flash
(
_
(
u"Failed to Move Cover File
%(file)
s:
%(error)
s"
,
file
=
new_coverpath
,
flash
(
_
(
u"Failed to Move Cover File
%(file)
s:
%(error)
s"
,
file
=
new_coverpath
,
error
=
e
),
error
=
e
),
category
=
"error"
)
category
=
"error"
)
# save data to database, reread data
calibre_db
.
session
.
commit
()
calibre_db
.
session
.
commit
()
calibre_db
.
setup_db
(
config
,
ub
.
app_DB_path
)
# Reread book. It's important not to filter the result, as it could have language which hide it from
# current users view (tags are not stored/extracted from metadata and could also be limited)
book
=
calibre_db
.
get_book
(
book_id
)
if
config
.
config_use_google_drive
:
if
config
.
config_use_google_drive
:
gdriveutils
.
updateGdriveCalibreFromLocal
()
gdriveutils
.
updateGdriveCalibreFromLocal
()
if
error
:
if
error
:
...
@@ -826,18 +845,12 @@ def upload():
...
@@ -826,18 +845,12 @@ def upload():
worker
.
add_upload
(
current_user
.
nickname
,
worker
.
add_upload
(
current_user
.
nickname
,
"<a href=
\"
"
+
url_for
(
'web.show_book'
,
book_id
=
book
.
id
)
+
"
\"
>"
+
uploadText
+
"</a>"
)
"<a href=
\"
"
+
url_for
(
'web.show_book'
,
book_id
=
book
.
id
)
+
"
\"
>"
+
uploadText
+
"</a>"
)
# create data for displaying display Full language name instead of iso639.part3language
if
db_language
is
not
None
:
book
.
languages
[
0
]
.
language_name
=
_
(
meta
.
languages
)
author_names
=
[]
for
author
in
db_book
.
authors
:
author_names
.
append
(
author
.
name
)
if
len
(
request
.
files
.
getlist
(
"btn-upload"
))
<
2
:
if
len
(
request
.
files
.
getlist
(
"btn-upload"
))
<
2
:
if
current_user
.
role_edit
()
or
current_user
.
role_admin
():
if
current_user
.
role_edit
()
or
current_user
.
role_admin
():
resp
=
{
"location"
:
url_for
(
'editbook.edit_book'
,
book_id
=
db_
book
.
id
)}
resp
=
{
"location"
:
url_for
(
'editbook.edit_book'
,
book_id
=
book
.
id
)}
return
Response
(
json
.
dumps
(
resp
),
mimetype
=
'application/json'
)
return
Response
(
json
.
dumps
(
resp
),
mimetype
=
'application/json'
)
else
:
else
:
resp
=
{
"location"
:
url_for
(
'web.show_book'
,
book_id
=
db_
book
.
id
)}
resp
=
{
"location"
:
url_for
(
'web.show_book'
,
book_id
=
book
.
id
)}
return
Response
(
json
.
dumps
(
resp
),
mimetype
=
'application/json'
)
return
Response
(
json
.
dumps
(
resp
),
mimetype
=
'application/json'
)
except
OperationalError
as
e
:
except
OperationalError
as
e
:
calibre_db
.
session
.
rollback
()
calibre_db
.
session
.
rollback
()
...
...
cps/isoLanguages.py
View file @
46197d82
...
@@ -57,12 +57,12 @@ def get_language_name(locale, lang_code):
...
@@ -57,12 +57,12 @@ def get_language_name(locale, lang_code):
def
get_language_codes
(
locale
,
language_names
,
remainder
=
None
):
def
get_language_codes
(
locale
,
language_names
,
remainder
=
None
):
language_names
=
set
(
x
.
strip
()
.
lower
()
for
x
in
language_names
if
x
)
language_names
=
set
(
x
.
strip
()
.
lower
()
for
x
in
language_names
if
x
)
languages
=
list
()
for
k
,
v
in
get_language_names
(
locale
)
.
items
():
for
k
,
v
in
get_language_names
(
locale
)
.
items
():
v
=
v
.
lower
()
v
=
v
.
lower
()
if
v
in
language_names
:
if
v
in
language_names
:
languages
.
append
(
k
)
language_names
.
remove
(
v
)
language_names
.
remove
(
v
)
yield
k
if
remainder
is
not
None
:
if
remainder
is
not
None
:
remainder
.
extend
(
language_names
)
remainder
.
extend
(
language_names
)
return
languages
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment