Commit 1b2124aa authored by cbartondock's avatar cbartondock

Merge branch 'master' of https://github.com/janeczku/calibre-web

parents b35483ed bd4fde9e
......@@ -287,7 +287,7 @@ def list_users():
for user in users:
if user.default_language == "all":
user.default = _("all")
user.default = _("All")
else:
user.default = LC.parse(user.default_language).get_language_name(get_locale())
......@@ -985,11 +985,14 @@ def _config_string(to_save, x):
def _configuration_gdrive_helper(to_save):
gdrive_error = None
gdrive_secrets = {}
if not os.path.isfile(gdriveutils.SETTINGS_YAML):
config.config_use_google_drive = False
gdrive_secrets = {}
gdrive_error = gdriveutils.get_error_text(gdrive_secrets)
if gdrive_support:
gdrive_error = gdriveutils.get_error_text(gdrive_secrets)
if "config_use_google_drive" in to_save and not config.config_use_google_drive and not gdrive_error:
with open(gdriveutils.CLIENT_SECRETS, 'r') as settings:
gdrive_secrets = json.load(settings)['web']
......@@ -1254,7 +1257,7 @@ def _configuration_result(error_flash=None, gdrive_error=None, configured=True):
gdrivefolders = []
if gdrive_error is None:
gdrive_error = gdriveutils.get_error_text()
if gdrive_error:
if gdrive_error and gdrive_support:
log.error(gdrive_error)
gdrive_error = _(gdrive_error)
else:
......@@ -1414,7 +1417,7 @@ def _handle_edit_user(to_save, content, languages, translations, kobo_support):
except IntegrityError as ex:
ub.session.rollback()
log.error("An unknown error occurred while changing user: {}".format(str(ex)))
flash(_(u"An unknown error occurred."), category="error")
flash(_(u"An unknown error occurred. Please try again later."), category="error")
except OperationalError:
ub.session.rollback()
log.error("Settings DB is not Writeable")
......@@ -1465,7 +1468,7 @@ def update_mailsettings():
elif to_save.get("gmail"):
try:
config.mail_gmail_token = services.gmail.setup_gmail(config.mail_gmail_token)
flash(_(u"G-Mail Account Verification Successful"), category="success")
flash(_(u"Gmail Account Verification Successful"), category="success")
except Exception as ex:
flash(str(ex), category="error")
log.error(ex)
......
......@@ -367,7 +367,7 @@ def render_edit_book(book_id):
cc = calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
book = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
if not book:
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
return redirect(url_for("web.index"))
for lang in book.languages:
......@@ -448,6 +448,9 @@ def edit_book_series_index(series_index, book):
# Add default series_index to book
modif_date = False
series_index = series_index or '1'
if not series_index.replace('.', '', 1).isdigit():
flash(_("%(seriesindex)s is not a valid number, skipping", seriesindex=series_index), category="warning")
return False
if book.series_index != series_index:
book.series_index = series_index
modif_date = True
......@@ -510,6 +513,8 @@ def edit_cc_data_value(book_id, book, c, to_save, cc_db_value, cc_string):
to_save[cc_string] = None
elif c.datatype == 'bool':
to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0
elif c.datatype == 'comments':
to_save[cc_string] = Markup(to_save[cc_string]).unescape()
elif c.datatype == 'datetime':
try:
to_save[cc_string] = datetime.strptime(to_save[cc_string], "%Y-%m-%d")
......@@ -735,7 +740,7 @@ def edit_book(book_id):
# Book not found
if not book:
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
return redirect(url_for("web.index"))
meta = upload_single_file(request, book, book_id)
......@@ -781,7 +786,7 @@ def edit_book(book_id):
# Add default series_index to book
modif_date |= edit_book_series_index(to_save["series_index"], book)
# Handle book comments/description
modif_date |= edit_book_comments(to_save["description"], book)
modif_date |= edit_book_comments(Markup(to_save['description']).unescape(), book)
# Handle identifiers
input_identifiers = identifier_list(to_save, book)
modification, warning = modify_identifiers(input_identifiers, book.identifiers, calibre_db.session)
......
......@@ -29,7 +29,7 @@ def get_fb2_info(tmp_file_path, original_file_extension):
'l': 'http://www.w3.org/1999/xlink',
}
fb2_file = open(tmp_file_path)
fb2_file = open(tmp_file_path, encoding="utf-8")
tree = etree.fromstring(fb2_file.read().encode())
authors = tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:author', namespaces=ns)
......
......@@ -122,9 +122,12 @@ def formatfloat(value, decimals=1):
@jinjia.app_template_filter('formatseriesindex')
def formatseriesindex_filter(series_index):
if series_index:
if int(series_index) - series_index == 0:
return int(series_index)
else:
try:
if int(series_index) - series_index == 0:
return int(series_index)
else:
return series_index
except ValueError:
return series_index
return 0
......
......@@ -62,7 +62,7 @@ def remote_login():
ub.session_commit()
verify_url = url_for('remotelogin.verify_token', token=auth_token.auth_token, _external=true)
log.debug(u"Remot Login request with token: %s", auth_token.auth_token)
return render_title_template('remote_login.html', title=_(u"login"), token=auth_token.auth_token,
return render_title_template('remote_login.html', title=_(u"Login"), token=auth_token.auth_token,
verify_url=verify_url, page="remotelogin")
......
......@@ -65,7 +65,7 @@ def get_sidebar_config(kwargs=None):
"show_text": _('Show unread'), "config_show": False})
sidebar.append({"glyph": "glyphicon-random", "text": _('Discover'), "link": 'web.books_list', "id": "rand",
"visibility": constants.SIDEBAR_RANDOM, 'public': True, "page": "discover",
"show_text": _('Show random books'), "config_show": True})
"show_text": _('Show Random Books'), "config_show": True})
sidebar.append({"glyph": "glyphicon-inbox", "text": _('Categories'), "link": 'web.category_list', "id": "cat",
"visibility": constants.SIDEBAR_CATEGORY, 'public': True, "page": "category",
"show_text": _('Show category selection'), "config_show": True})
......
......@@ -227,3 +227,14 @@ th {
.dark-theme .overlay {
background-color: rgba(0, 0, 0, 0.8);
}
/* Hide scrollbar for Chrome, Safari and Opera */
.disabled-scrollbar::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.disabled-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
\ No newline at end of file
......@@ -69,7 +69,9 @@ var settings = {
rotateTimes: 0,
fitMode: kthoom.Key.B,
theme: "light",
direction: 0 // 0 = Left to Right, 1 = Right to Left
direction: 0, // 0 = Left to Right, 1 = Right to Left
nextPage: 0, // 0 = Reset to Top, 1 = Remember Position
scrollbar: 1 // 0 = Hide Scrollbar, 1 = Show Scrollbar
};
kthoom.saveSettings = function() {
......@@ -282,6 +284,7 @@ function updatePage() {
}
$("body").toggleClass("dark-theme", settings.theme === "dark");
$("#mainContent").toggleClass("disabled-scrollbar", settings.scrollbar === 0);
kthoom.setSettings();
kthoom.saveSettings();
......@@ -439,6 +442,9 @@ function showPrevPage() {
currentImage++;
} else {
updatePage();
if (settings.nextPage === 0) {
$("#mainContent").scrollTop(0);
}
}
}
......@@ -449,6 +455,9 @@ function showNextPage() {
currentImage--;
} else {
updatePage();
if (settings.nextPage === 0) {
$("#mainContent").scrollTop(0);
}
}
}
......@@ -650,6 +659,9 @@ function init(filename) {
$("#thumbnails").on("click", "a", function() {
currentImage = $(this).data("page") - 1;
updatePage();
if (settings.nextPage === 0) {
$("#mainContent").scrollTop(0);
}
});
// Fullscreen mode
......
......@@ -145,7 +145,7 @@
</div>
{% if config.config_allow_reverse_proxy_header_login %}
<div class="row">
<div class="col-xs-6 col-sm-7">{{_('Reverse proxy header name')}}</div>
<div class="col-xs-6 col-sm-7">{{_('Reverse Proxy Header Name')}}</div>
<div class="col-xs-6 col-sm-5">{{ config.config_reverse_proxy_login_header_name }}</div>
</div>
{% endif %}
......
......@@ -161,7 +161,7 @@
value="{% if book['custom_column_' ~ c.id][0].value %}{{book['custom_column_' ~ c.id][0].value|formatdate}}{% endif %}"
{% endif %}>
<span class="input-group-btn">
<button type="button" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
<button type="button" id="{{ 'custom_column_' ~ c.id }}_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
{% endif %}
......
......@@ -50,7 +50,7 @@
{{ text_table_row('authors', _('Enter Authors'),_('Authors'), true, true) }}
{{ text_table_row('tags', _('Enter Categories'),_('Categories'), false, true) }}
{{ text_table_row('series', _('Enter Series'),_('Series'), false, true) }}
<th data-field="series_index" id="series_index" data-visible="{{visiblility.get('series_index')}}" data-edit-validate="{{ _('This Field is Required') }}" data-sortable="true" {% if g.user.role_edit() %} data-editable-type="number" data-editable-placeholder="1" data-editable-step="0.01" data-editable-min="0" data-editable-url="{{ url_for('editbook.edit_list_book', param='series_index')}}" data-edit="true" data-editable-title="{{_('Enter title')}}"{% endif %}>{{_('Series Index')}}</th>
<th data-field="series_index" id="series_index" data-visible="{{visiblility.get('series_index')}}" data-edit-validate="{{ _('This Field is Required') }}" data-sortable="true" {% if g.user.role_edit() %} data-editable-type="number" data-editable-placeholder="1" data-editable-step="0.01" data-editable-min="0" data-editable-url="{{ url_for('editbook.edit_list_book', param='series_index')}}" data-edit="true" data-editable-title="{{_('Enter Title')}}"{% endif %}>{{_('Series Index')}}</th>
{{ text_table_row('languages', _('Enter Languages'),_('Languages'), false, true) }}
<!--th data-field="pubdate" data-type="date" data-visible="{{visiblility.get('pubdate')}}" data-viewformat="dd.mm.yyyy" id="pubdate" data-sortable="true">{{_('Publishing Date')}}</th-->
{{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, true) }}
......
......@@ -12,7 +12,7 @@
<label for="mail_server_type">{{_('Choose Server Type')}}</label>
<select name="mail_server_type" id="config_email_type" class="form-control" data-control="email-settings">
<option value="0" {% if content.mail_server_type == 0 %}selected{% endif %}>{{_('Use Standard E-Mail Account')}}</option>
<option value="1" {% if content.mail_server_type == 1 %}selected{% endif %}>{{_('Gmail Account with OAuth2 Verfification')}}</option>
<option value="1" {% if content.mail_server_type == 1 %}selected{% endif %}>{{_('Gmail Account with OAuth2 Verification')}}</option>
</select>
</div>
<div data-related="email-settings-1">
......
......@@ -157,6 +157,24 @@
<label for="rightToLeft"><input type="radio" id="rightToLeft" name="direction" value="1" /> {{_('Right to Left')}}</label>
</div>
</td>
</tr>
<tr>
<th>{{_('Next Page')}}:</th>
<td>
<div class="inputs">
<label for="resetToTop"><input type="radio" id="resetToTop" name="nextPage" value="0" /> {{_('Reset to Top')}}</label>
<label for="rememberPosition"><input type="radio" id="rememberPosition" name="nextPage" value="1" /> {{_('Remember Position')}}</label>
</div>
</td>
</tr>
<tr>
<th>{{_('Scrollbar')}}:</th>
<td>
<div class="inputs">
<label for="showScrollbar"><input type="radio" id="showScrollbar" name="scrollbar" value="1" /> {{_('Show')}}</label>
<label for="hideScrollbar"><input type="radio" id="hideScrollbar" name="scrollbar" value="0" /> {{_('Hide')}}</label>
</div>
</td>
</tr>
</tbody>
</table>
......
......@@ -17,22 +17,22 @@
</div>
<div class="row">
<div class="form-group col-sm-6">
<label for="Publishstart">{{_('Published Date From')}}</label>
<label for="publishstart">{{_('Published Date From')}}</label>
<div class="input-group">
<input type="text" style="position: static;" class="datepicker form-control" name="Publishstart" id="Publishstart" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_Publishstart" value="">
<input type="text" style="position: static;" class="datepicker form-control" name="publish_start" id="publishstart" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_publishstart" value="">
<span class="input-group-btn">
<button type="button" id="pubstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
<button type="button" id="publishstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
<div class="form-group col-sm-6">
<label for="Publishend">{{_('Published Date To')}}</label>
<label for="publishend">{{_('Published Date To')}}</label>
<div class="input-group ">
<input type="text" style="position: static;" class="datepicker form-control" name="Publishend" id="Publishend" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_Publishend" value="">
<input type="text" style="position: static;" class="datepicker form-control" name="publishend" id="publishend" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_publishend" value="">
<span class="input-group-btn">
<button type="button" id="pubend_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
<button type="button" id="publishend_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
......@@ -181,7 +181,7 @@
<input type="text" style="position: static;" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}_start" id="{{ 'custom_column_' ~ c.id }}_start" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_{{ 'custom_column_' ~ c.id }}_start" value="">
<span class="input-group-btn">
<button type="button" id="pubstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
<button type="button" id="{{ 'custom_column_' ~ c.id }}_start_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
......@@ -191,7 +191,7 @@
<input type="text" style="position: static;" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}_end" id="{{ 'custom_column_' ~ c.id }}_end" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_{{ 'custom_column_' ~ c.id }}_end" value="">
<span class="input-group-btn">
<button type="button" id="pubend_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
<button type="button" id="{{ 'custom_column_' ~ c.id }}_end_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
......
......@@ -143,7 +143,7 @@
{{ user_checkbox_row("sidebar_view", "sidebar_random", _('Show random books'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_author", _('Show author selection'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_best_rated", _('Show Top Rated Books'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_read_and_unread", _('Show random books'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_read_and_unread", _('Show Random Books'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_publisher", _('Show publisher selection'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_rating", _('Show ratings selection'), visiblility, sidebar_settings)}}
{{ user_checkbox_row("sidebar_view", "sidebar_format", _('Show file formats selection'), visiblility, sidebar_settings)}}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1080,10 +1080,10 @@ def adv_search_custom_columns(cc, term, q):
custom_end = term.get('custom_column_' + str(c.id) + '_end')
if custom_start:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value >= custom_start))
func.datetime(db.cc_classes[c.id].value) >= func.datetime(custom_start)))
if custom_end:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value <= custom_end))
func.datetime(db.cc_classes[c.id].value) <= func.datetime(custom_end)))
else:
custom_query = term.get('custom_column_' + str(c.id))
if custom_query != '' and custom_query is not None:
......@@ -1254,8 +1254,8 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
author_name = term.get("author_name")
book_title = term.get("book_title")
publisher = term.get("publisher")
pub_start = term.get("Publishstart")
pub_end = term.get("Publishend")
pub_start = term.get("publishstart")
pub_end = term.get("publishend")
rating_low = term.get("ratinghigh")
rating_high = term.get("ratinglow")
description = term.get("comment")
......@@ -1310,9 +1310,9 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
if book_title:
q = q.filter(func.lower(db.Books.title).ilike("%" + book_title + "%"))
if pub_start:
q = q.filter(db.Books.pubdate >= pub_start)
q = q.filter(func.datetime(db.Books.pubdate) > func.datetime(pub_start))
if pub_end:
q = q.filter(db.Books.pubdate <= pub_end)
q = q.filter(func.datetime(db.Books.pubdate) < func.datetime(pub_end))
q = adv_search_read_status(q, read_status)
if publisher:
q = q.filter(db.Books.publishers.any(func.lower(db.Publishers.name).ilike("%" + publisher + "%")))
......@@ -1442,20 +1442,20 @@ def register():
return redirect(url_for('web.index'))
if not config.get_mail_server_configured():
flash(_(u"E-Mail server is not configured, please contact your administrator!"), category="error")
return render_title_template('register.html', title=_(u"register"), page="register")
return render_title_template('register.html', title=_("Register"), page="register")
if request.method == "POST":
to_save = request.form.to_dict()
nickname = to_save["email"].strip() if config.config_register_email else to_save.get('name')
if not nickname or not to_save.get("email"):
flash(_(u"Please fill out all fields!"), category="error")
return render_title_template('register.html', title=_(u"register"), page="register")
return render_title_template('register.html', title=_("Register"), page="register")
try:
nickname = check_username(nickname)
email = check_email(to_save["email"])
except Exception as ex:
flash(str(ex), category="error")
return render_title_template('register.html', title=_(u"register"), page="register")
return render_title_template('register.html', title=_("Register"), page="register")
content = ub.User()
if check_valid_domain(email):
......@@ -1474,17 +1474,17 @@ def register():
except Exception:
ub.session.rollback()
flash(_(u"An unknown error occurred. Please try again later."), category="error")
return render_title_template('register.html', title=_(u"register"), page="register")
return render_title_template('register.html', title=_("Register"), page="register")
else:
flash(_(u"Your e-mail is not allowed to register"), category="error")
log.warning('Registering failed for user "%s" e-mail address: %s', nickname, to_save["email"])
return render_title_template('register.html', title=_(u"register"), page="register")
return render_title_template('register.html', title=_("Register"), page="register")
flash(_(u"Confirmation e-mail was send to your e-mail account."), category="success")
return redirect(url_for('web.login'))
if feature_support['oauth']:
register_user_with_oauth()
return render_title_template('register.html', config=config, title=_(u"register"), page="register")
return render_title_template('register.html', config=config, title=_("Register"), page="register")
@web.route('/login', methods=['GET', 'POST'])
......@@ -1553,7 +1553,7 @@ def login():
if url_for("web.logout") == next_url:
next_url = url_for("web.index")
return render_title_template('login.html',
title=_(u"login"),
title=_(u"Login"),
next_url=next_url,
config=config,
oauth_check=oauth_check,
......@@ -1614,8 +1614,8 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations,
log.debug(u"Profile updated")
except IntegrityError:
ub.session.rollback()
flash(_(u"Found an existing account for this e-mail address."), category="error")
log.debug(u"Found an existing account for this e-mail address.")
flash(_(u"Found an existing account for this e-mail address"), category="error")
log.debug(u"Found an existing account for this e-mail address")
except OperationalError as e:
ub.session.rollback()
log.error("Database error: %s", e)
......@@ -1658,8 +1658,8 @@ def profile():
def read_book(book_id, book_format):
book = calibre_db.get_filtered_book(book_id)
if not book:
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
log.debug(u"Error opening eBook. File does not exist or file is not accessible")
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
return redirect(url_for("web.index"))
# check if book has bookmark
......@@ -1693,8 +1693,8 @@ def read_book(book_id, book_format):
log.debug(u"Start comic reader for %d", book_id)
return render_title_template('readcbr.html', comicfile=all_name, title=_(u"Read a Book"),
extension=fileExt)
log.debug(u"Error opening eBook. File does not exist or file is not accessible")
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error")
return redirect(url_for("web.index"))
......@@ -1764,6 +1764,7 @@ def show_book(book_id):
reader_list=reader_list,
page="book")
else:
log.debug(u"Error opening eBook. File does not exist or file is not accessible")
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")
flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"),
category="error")
return redirect(url_for("web.index"))
This diff is collapsed.
# GDrive Integration
gevent>20.6.0,<21.2.0
greenlet>=0.4.17,<1.1.0
httplib2>=0.9.2,<0.18.0
greenlet>=0.4.17,<1.2.0
httplib2>=0.9.2,<0.20.0
oauth2client>=4.0.0,<4.1.4
uritemplate>=3.0.0,<3.1.0
pyasn1-modules>=0.0.8,<0.3.0
pyasn1>=0.1.9,<0.5.0
PyDrive2>=1.3.1,<1.8.0
PyDrive2>=1.3.1,<1.9.0
PyYAML>=3.12
rsa>=3.4.2,<4.1.0
six>=1.10.0,<1.15.0
rsa>=3.4.2,<4.8.0
six>=1.10.0,<1.17.0
# Gdrive and Gmail integration
google-api-python-client>=1.7.11,<2.1.0
......@@ -26,7 +26,7 @@ python-ldap>=3.0.0,<3.4.0
Flask-SimpleLDAP>=1.4.0,<1.5.0
#oauth
Flask-Dance>=1.4.0,<4.1.0
Flask-Dance>=2.0.0,<5.1.0
SQLAlchemy-Utils>=0.33.5,<0.38.0
# extracting metadata
......@@ -34,7 +34,7 @@ lxml>=3.8.0,<4.7.0
rarfile>=2.7
# other
natsort>=2.2.0,<7.1.0
natsort>=2.2.0,<7.2.0
comicapi>= 2.2.0,<2.3.0
#Kobo integration
......
Babel>=1.3, <2.9
Babel>=1.3, <3.0
Flask-Babel>=0.11.1,<2.1.0
Flask-Login>=0.3.2,<0.5.1
Flask-Principal>=0.3.2,<0.5.1
backports_abc>=0.4
Flask>=1.0.2,<1.2.0
Flask>=1.0.2,<2.0.0
iso-639>=0.4.5,<0.5.0
PyPDF3>=1.0.0,<1.0.4
pytz>=2016.10
requests>=2.11.1,<2.25.0
SQLAlchemy>=1.3.0,<1.4.0 # oauth fails on 1.4+ due to import problems in flask_dance
SQLAlchemy>=1.3.0,<1.5.0
tornado>=4.1,<6.2
Wand>=0.4.4,<0.7.0
unidecode>=0.04.19,<1.2.0
unidecode>=0.04.19,<1.3.0
......@@ -34,35 +34,38 @@ console_scripts =
[options]
include_package_data = True
install_requires =
Babel>=1.3, <2.9
Babel>=1.3, <3.0
Flask-Babel>=0.11.1,<2.1.0
Flask-Login>=0.3.2,<0.5.1
Flask-Principal>=0.3.2,<0.5.1
backports_abc>=0.4
Flask>=1.0.2,<1.2.0
Flask>=1.0.2,<2.1.0
iso-639>=0.4.5,<0.5.0
PyPDF3>=1.0.0,<1.0.4
pytz>=2016.10
requests>=2.11.1,<2.25.0
SQLAlchemy>=1.3.0,<1.4.0
SQLAlchemy>=1.3.0,<1.5.0
tornado>=4.1,<6.2
Wand>=0.4.4,<0.7.0
unidecode>=0.04.19,<1.2.0
unidecode>=0.04.19,<1.3.0
[options.extras_require]
gdrive =
google-api-python-client>=1.7.11,<1.13.0
google-api-python-client>=1.7.11,<2.1.0
gevent>20.6.0,<21.2.0
greenlet>=0.4.17,<1.1.0
httplib2>=0.9.2,<0.18.0
greenlet>=0.4.17,<1.2.0
httplib2>=0.9.2,<0.20.0
oauth2client>=4.0.0,<4.1.4
uritemplate>=3.0.0,<3.1.0
pyasn1-modules>=0.0.8,<0.3.0
pyasn1>=0.1.9,<0.5.0
PyDrive2>=1.3.1,<1.8.0
PyDrive2>=1.3.1,<1.9.0
PyYAML>=3.12
rsa>=3.4.2,<4.1.0
six>=1.10.0,<1.15.0
rsa>=3.4.2,<4.8.0
six>=1.10.0,<1.17.0
gmail =
google-auth-oauthlib>=0.4.3,<0.5.0
google-api-python-client>=1.7.11,<2.1.0
goodreads =
goodreads>=0.3.2,<0.4.0
python-Levenshtein>=0.12.0,<0.13.0
......@@ -70,14 +73,14 @@ ldap =
python-ldap>=3.0.0,<3.4.0
Flask-SimpleLDAP>=1.4.0,<1.5.0
oauth =
Flask-Dance>=1.4.0,<3.1.0
SQLAlchemy-Utils>=0.33.5,<0.37.0
Flask-Dance>=2.0.0,<5.1.0
SQLAlchemy-Utils>=0.33.5,<0.38.0
metadata =
lxml>=3.8.0,<4.7.0
rarfile>=2.7
comics =
natsort>=2.2.0,<7.1.0
comicapi>= 2.1.3,<2.2.0
natsort>=2.2.0,<7.2.0
comicapi>= 2.2.0,<2.3.0
kobo =
jsonschema>=3.2.0,<3.3.0
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment