Commit 7f340739 authored by Ozzieisaacs's avatar Ozzieisaacs

Merge branch 'master' into Develop

# Conflicts:
#	cps/web.py
#	readme.md
parents b75b9160 6661be91
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
try: try:
from pydrive.auth import GoogleAuth from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive from pydrive.drive import GoogleDrive
from pydrive.auth import RefreshError from pydrive.auth import RefreshError, InvalidConfigError
from apiclient import errors from apiclient import errors
gdrive_support = True gdrive_support = True
except ImportError: except ImportError:
...@@ -166,7 +166,10 @@ def getDrive(drive=None, gauth=None): ...@@ -166,7 +166,10 @@ def getDrive(drive=None, gauth=None):
# Save the current credentials to a file # Save the current credentials to a file
return GoogleDrive(gauth) return GoogleDrive(gauth)
if drive.auth.access_token_expired: if drive.auth.access_token_expired:
try:
drive.auth.Refresh() drive.auth.Refresh()
except RefreshError as e:
web.app.logger.error("Google Drive error: " + e.message)
return drive return drive
def listRootFolders(): def listRootFolders():
...@@ -454,6 +457,10 @@ def getChangeById (drive, change_id): ...@@ -454,6 +457,10 @@ def getChangeById (drive, change_id):
except (errors.HttpError) as error: except (errors.HttpError) as error:
web.app.logger.info(error.message) web.app.logger.info(error.message)
return None return None
except Exception as e:
web.app.logger.info(e)
return None
# Deletes the local hashes database to force search for new folder names # Deletes the local hashes database to force search for new folder names
def deleteDatabaseOnChange(): def deleteDatabaseOnChange():
......
...@@ -427,6 +427,8 @@ def delete_book(book, calibrepath, book_format): ...@@ -427,6 +427,8 @@ def delete_book(book, calibrepath, book_format):
def get_book_cover(cover_path): def get_book_cover(cover_path):
if ub.config.config_use_google_drive: if ub.config.config_use_google_drive:
try: try:
if not web.is_gdrive_ready():
return send_from_directory(os.path.join(os.path.dirname(__file__), "static"), "generic_cover.jpg")
path=gd.get_cover_via_gdrive(cover_path) path=gd.get_cover_via_gdrive(cover_path)
if path: if path:
return redirect(path) return redirect(path)
...@@ -434,7 +436,7 @@ def get_book_cover(cover_path): ...@@ -434,7 +436,7 @@ def get_book_cover(cover_path):
web.app.logger.error(cover_path + '/cover.jpg not found on Google Drive') web.app.logger.error(cover_path + '/cover.jpg not found on Google Drive')
return send_from_directory(os.path.join(os.path.dirname(__file__), "static"), "generic_cover.jpg") return send_from_directory(os.path.join(os.path.dirname(__file__), "static"), "generic_cover.jpg")
except Exception as e: except Exception as e:
web.app.logger.error("Error Message: "+e.message) web.app.logger.error("Error Message: " + e.message)
web.app.logger.exception(e) web.app.logger.exception(e)
# traceback.print_exc() # traceback.print_exc()
return send_from_directory(os.path.join(os.path.dirname(__file__), "static"),"generic_cover.jpg") return send_from_directory(os.path.join(os.path.dirname(__file__), "static"),"generic_cover.jpg")
......
...@@ -31,14 +31,18 @@ ...@@ -31,14 +31,18 @@
</label> </label>
</div> </div>
{% else %} {% else %}
{% if show_authenticate_google_drive and g.user.is_authenticated %} {% if show_authenticate_google_drive and g.user.is_authenticated and content.config_use_google_drive %}
<div class="form-group required"> <div class="form-group required">
<a href="{{ url_for('authenticate_google_drive') }}" class="btn btn-primary">{{_('Authenticate Google Drive')}}</a> <a href="{{ url_for('authenticate_google_drive') }}" class="btn btn-primary">{{_('Authenticate Google Drive')}}</a>
</div> </div>
{% else %} {% else %}
{% if show_authenticate_google_drive and not g.user.is_authenticated %} {% if show_authenticate_google_drive and g.user.is_authenticated and not content.config_use_google_drive %}
<div >{{_('Please hit submit to continue with setup')}}</div>
{% endif %}
{% if not g.user.is_authenticated %}
<div >{{_('Please finish Google Drive setup after login')}}</div> <div >{{_('Please finish Google Drive setup after login')}}</div>
{% endif %} {% endif %}
{% if g.user.is_authenticated %}
{% if not show_authenticate_google_drive %} {% if not show_authenticate_google_drive %}
<div class="form-group required"> <div class="form-group required">
<label for="config_google_drive_folder">{{_('Google Drive Calibre folder')}}</label> <label for="config_google_drive_folder">{{_('Google Drive Calibre folder')}}</label>
...@@ -60,6 +64,7 @@ ...@@ -60,6 +64,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %}
</div> </div>
</div> </div>
</div> </div>
......
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.
...@@ -72,7 +72,6 @@ class Updater(threading.Thread): ...@@ -72,7 +72,6 @@ class Updater(threading.Thread):
r = requests.get(self._get_request_path(), stream=True) r = requests.get(self._get_request_path(), stream=True)
r.raise_for_status() r.raise_for_status()
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
self.status = 2 self.status = 2
z = zipfile.ZipFile(BytesIO(r.content)) z = zipfile.ZipFile(BytesIO(r.content))
self.status = 3 self.status = 3
...@@ -189,8 +188,9 @@ class Updater(threading.Thread): ...@@ -189,8 +188,9 @@ class Updater(threading.Thread):
# destination files # destination files
old_list = list() old_list = list()
exclude = ( exclude = (
'vendor' + os.sep + 'kindlegen.exe', 'vendor' + os.sep + 'kindlegen', os.sep + 'app.db', os.sep + 'app.db', os.sep + 'calibre-web.log1', os.sep + 'calibre-web.log2', os.sep + 'gdrive.db',
os.sep + 'vendor', os.sep + 'calibre-web.log') os.sep + 'vendor', os.sep + 'calibre-web.log', os.sep + '.git', os.sep +'client_secrets.json',
os.sep + 'gdrive_credentials', os.sep + 'settings.yaml')
for root, dirs, files in os.walk(destination, topdown=True): for root, dirs, files in os.walk(destination, topdown=True):
for name in files: for name in files:
old_list.append(os.path.join(root, name).replace(destination, '')) old_list.append(os.path.join(root, name).replace(destination, ''))
...@@ -237,7 +237,7 @@ class Updater(threading.Thread): ...@@ -237,7 +237,7 @@ class Updater(threading.Thread):
return False return False
def _stable_version_info(self): def _stable_version_info(self):
return {'version': '0.6.0'} # Current version return {'version': '0.6.1'} # Current version
def _nightly_available_updates(self, request_method): def _nightly_available_updates(self, request_method):
tz = datetime.timedelta(seconds=time.timezone if (time.localtime().tm_isdst == 0) else time.altzone) tz = datetime.timedelta(seconds=time.timezone if (time.localtime().tm_isdst == 0) else time.altzone)
......
...@@ -83,6 +83,8 @@ from flask_dance.contrib.google import make_google_blueprint, google ...@@ -83,6 +83,8 @@ from flask_dance.contrib.google import make_google_blueprint, google
from flask_dance.consumer import oauth_authorized, oauth_error from flask_dance.consumer import oauth_authorized, oauth_error
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
from oauth import OAuthBackend from oauth import OAuthBackend
import hashlib
>>>>>>> master
try: try:
from googleapiclient.errors import HttpError from googleapiclient.errors import HttpError
...@@ -1008,11 +1010,9 @@ def get_email_status_json(): ...@@ -1008,11 +1010,9 @@ def get_email_status_json():
# example SELECT * FROM @TABLE WHERE 'abcdefg' LIKE Name; # example SELECT * FROM @TABLE WHERE 'abcdefg' LIKE Name;
# from https://code.luasoftware.com/tutorials/flask/execute-raw-sql-in-flask-sqlalchemy/ # from https://code.luasoftware.com/tutorials/flask/execute-raw-sql-in-flask-sqlalchemy/
def check_valid_domain(domain_text): def check_valid_domain(domain_text):
# result = session.query(Notification).from_statement(text(sql)).params(id=5).all()
#ToDo: check possible SQL injection
domain_text = domain_text.split('@',1)[-1].lower() domain_text = domain_text.split('@',1)[-1].lower()
sql = "SELECT * FROM registration WHERE '%s' LIKE domain;" % domain_text sql = "SELECT * FROM registration WHERE :domain LIKE domain;"
result = ub.session.query(ub.Registration).from_statement(text(sql)).all() result = ub.session.query(ub.Registration).from_statement(text(sql)).params(domain=domain_text).all()
return len(result) return len(result)
...@@ -1777,7 +1777,12 @@ def delete_book(book_id, book_format): ...@@ -1777,7 +1777,12 @@ def delete_book(book_id, book_format):
@login_required @login_required
@admin_required @admin_required
def authenticate_google_drive(): def authenticate_google_drive():
try:
authUrl = gdriveutils.Gauth.Instance().auth.GetAuthUrl() authUrl = gdriveutils.Gauth.Instance().auth.GetAuthUrl()
except gdriveutils.InvalidConfigError:
flash(_(u'Google Drive setup not completed, try to deactivate and activate Google Drive again'),
category="error")
return redirect(url_for('index'))
return redirect(authUrl) return redirect(authUrl)
...@@ -1865,7 +1870,7 @@ def on_received_watch_confirmation(): ...@@ -1865,7 +1870,7 @@ def on_received_watch_confirmation():
app.logger.debug(response) app.logger.debug(response)
if response: if response:
dbpath = os.path.join(config.config_calibre_dir, "metadata.db") dbpath = os.path.join(config.config_calibre_dir, "metadata.db")
if not response['deleted'] and response['file']['title'] == 'metadata.db' and response['file']['md5Checksum'] != md5(dbpath): if not response['deleted'] and response['file']['title'] == 'metadata.db' and response['file']['md5Checksum'] != hashlib.md5(dbpath):
tmpDir = tempfile.gettempdir() tmpDir = tempfile.gettempdir()
app.logger.info('Database file updated') app.logger.info('Database file updated')
copyfile(dbpath, os.path.join(tmpDir, "metadata.db_" + str(current_milli_time()))) copyfile(dbpath, os.path.join(tmpDir, "metadata.db_" + str(current_milli_time())))
...@@ -3015,6 +3020,8 @@ def configuration_helper(origin): ...@@ -3015,6 +3020,8 @@ def configuration_helper(origin):
content.config_calibre_dir = to_save["config_calibre_dir"] content.config_calibre_dir = to_save["config_calibre_dir"]
db_change = True db_change = True
# Google drive setup # Google drive setup
if not os.path.isfile(os.path.join(config.get_main_dir, 'settings.yaml')):
content.config_use_google_drive = False
if "config_use_google_drive" in to_save and not content.config_use_google_drive and not gdriveError: if "config_use_google_drive" in to_save and not content.config_use_google_drive and not gdriveError:
if filedata: if filedata:
if filedata['web']['redirect_uris'][0].endswith('/'): if filedata['web']['redirect_uris'][0].endswith('/'):
...@@ -3174,7 +3181,8 @@ def configuration_helper(origin): ...@@ -3174,7 +3181,8 @@ def configuration_helper(origin):
gdrive=gdriveutils.gdrive_support, goodreads=goodreads_support, gdrive=gdriveutils.gdrive_support, goodreads=goodreads_support,
rarfile_support=rar_support, title=_(u"Basic Configuration")) rarfile_support=rar_support, title=_(u"Basic Configuration"))
try: try:
if content.config_use_google_drive and is_gdrive_ready() and not os.path.exists(config.config_calibre_dir + "/metadata.db"): if content.config_use_google_drive and is_gdrive_ready() and not \
os.path.exists(os.path.join(content.config_calibre_dir, "metadata.db")):
gdriveutils.downloadFile(None, "metadata.db", config.config_calibre_dir + "/metadata.db") gdriveutils.downloadFile(None, "metadata.db", config.config_calibre_dir + "/metadata.db")
if db_change: if db_change:
if config.db_configured: if config.db_configured:
...@@ -3206,7 +3214,7 @@ def configuration_helper(origin): ...@@ -3206,7 +3214,7 @@ def configuration_helper(origin):
app.logger.info('Reboot required, restarting') app.logger.info('Reboot required, restarting')
if origin: if origin:
success = True success = True
if is_gdrive_ready() and gdriveutils.gdrive_support == True and config.config_use_google_drive == True: if is_gdrive_ready() and gdriveutils.gdrive_support == True: # and config.config_use_google_drive == True:
gdrivefolders=gdriveutils.listRootFolders() gdrivefolders=gdriveutils.listRootFolders()
else: else:
gdrivefolders=list() gdrivefolders=list()
......
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