Skip to content

Commit

Permalink
Merge ef0cc65 into b49ad4a
Browse files Browse the repository at this point in the history
  • Loading branch information
naoyak committed May 27, 2020
2 parents b49ad4a + ef0cc65 commit aeab224
Show file tree
Hide file tree
Showing 54 changed files with 182 additions and 273 deletions.
6 changes: 2 additions & 4 deletions .travis.yml
Expand Up @@ -2,8 +2,6 @@ language: python

jobs:
include:
- os: linux
python: 2.7
- os: linux
python: 3.6
- os: linux
Expand Down Expand Up @@ -34,8 +32,8 @@ before_install:
- source activate testenv
# Pin R to 3.6.3 for now
- conda install -c conda-forge r-base=3.6.3 r-knitr
# Install regex through conda to avoid issues with Linux 2.7 and Mac wheels
- if [[ "$TRAVIS_OS_NAME" == "osx" || "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
# Install regex through conda to avoid issues with Mac wheels
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
conda install -c conda-forge regex;
fi
install:
Expand Down
15 changes: 9 additions & 6 deletions appveyor.yml
Expand Up @@ -2,13 +2,16 @@ build: false

environment:
matrix:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.8"
PYTHON_ARCH: "32"
MINICONDA: C:\Miniconda

- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.6"
PYTHON_VERSION: "3.6.10"
PYTHON_ARCH: "64"
MINICONDA: C:\Miniconda3
- PYTHON: "C:\\Python37-x64"
PYTHON_VERSION: "3.7.7"
PYTHON_ARCH: "64"
MINICONDA: C:\Miniconda3
- PYTHON: "C:\\Python38-x64"
PYTHON_VERSION: "3.8.3"
PYTHON_ARCH: "64"
MINICONDA: C:\Miniconda3

Expand Down
4 changes: 1 addition & 3 deletions docs/requirements.txt
@@ -1,5 +1,3 @@
future
enum34
pyyaml
markdown
pygments
Expand All @@ -18,4 +16,4 @@ werkzeug>=1.0
gunicorn
inflection
pillow
weasyprint<=0.42.3
weasyprint
6 changes: 2 additions & 4 deletions knowledge_repo/_version.py
Expand Up @@ -18,8 +18,6 @@
# should be defined elsewhere.
__dependencies__ = [
# Knowledge Repository Dependencies
'future', # Python 2/3 support
'enum34', # Python 3.4+ enum object used for Post status
'pyyaml', # Yaml parser and utilities
'markdown', # Markdown conversion utilities
'pygments', # Code highlighting support in markdown
Expand All @@ -41,13 +39,13 @@
'gunicorn', # Deployed webserver
'inflection', # String transformation library
'pillow', # Image thumbnailing
'weasyprint<=0.42.3', # Post PDF download option. Pinned to maintain compatibility with Python 2
'weasyprint', # Post PDF download option
]

__optional_dependencies__ = {
# ipynb notebook conversion suport
'ipynb': [
'nbformat<5.0.0',
'nbformat',
'nbconvert[execute]',
'traitlets'
],
Expand Down
2 changes: 0 additions & 2 deletions knowledge_repo/app/__init__.py
@@ -1,4 +1,2 @@
from __future__ import absolute_import

from . import auth_providers
from .app import KnowledgeFlask
18 changes: 10 additions & 8 deletions knowledge_repo/app/app.py
@@ -1,14 +1,12 @@
from __future__ import absolute_import

import os
import imp
import importlib
import sys
import logging
import traceback
import math
import uuid
import mimetypes

import six
from flask import Flask, current_app, render_template, request, session
from flask_login import LoginManager, user_loaded_from_request
from flask_mail import Mail
Expand Down Expand Up @@ -52,8 +50,12 @@ def __init__(self, repo, db_uri=None, debug=None, config=None, **kwargs):

# Load configuration from file or provided object
if config:
if isinstance(config, six.string_types):
config = imp.load_source('knowledge_server_config', os.path.abspath(config))
if isinstance(config, str):
module_name = 'knowledge_server_config'
spec = importlib.util.spec_from_file_location(module_name, os.path.abspath(config))
config = importlib.util.module_from_spec(spec)
sys.modules[module_name] = config
spec.loader.exec_module(config)
self.config.from_object(config)

# Add configuration passed in as keyword arguments
Expand All @@ -75,7 +77,7 @@ def __init__(self, repo, db_uri=None, debug=None, config=None, **kwargs):
# Configure database
if db_uri:
self.config['SQLALCHEMY_DATABASE_URI'] = db_uri
logger.debug(u"Using database: {}".format(self.config['SQLALCHEMY_DATABASE_URI']))
logger.debug("Using database: {}".format(self.config['SQLALCHEMY_DATABASE_URI']))

# Register database schema with flask app
sqlalchemy_db.init_app(self)
Expand Down Expand Up @@ -235,7 +237,7 @@ def modify_query(**new_values):
for key, value in new_values.items():
args[key] = value

return u'{}?{}'.format(request.path, url_encode(args))
return '{}?{}'.format(request.path, url_encode(args))

@self.template_global()
def pagination_pages(current_page, page_count, max_pages=5, extremes=True):
Expand Down
4 changes: 1 addition & 3 deletions knowledge_repo/app/auth_provider.py
@@ -1,16 +1,14 @@
from abc import abstractmethod
from builtins import object

from flask_principal import identity_changed, Identity
from flask_login import login_user
from future.utils import with_metaclass
from flask import redirect, current_app, Blueprint, url_for, session

from .utils.auth import prepare_user
from ..utils.registry import SubclassRegisteringABCMeta


class KnowledgeAuthProvider(with_metaclass(SubclassRegisteringABCMeta, object)):
class KnowledgeAuthProvider(object, metaclass=SubclassRegisteringABCMeta):
_registry_keys = None

@classmethod
Expand Down
5 changes: 2 additions & 3 deletions knowledge_repo/app/auth_providers/oauth2.py
@@ -1,9 +1,8 @@
import posixpath
import json

import six
from flask import request, redirect
from six.moves.urllib.parse import urljoin
from urllib.parse import urljoin

from ..models import User
from ..auth_provider import KnowledgeAuthProvider
Expand Down Expand Up @@ -158,7 +157,7 @@ def extract_from_dict(d, key):
key = key[0]
else:
return extract_from_dict(d[key[0]], key[1:])
if isinstance(key, six.string_types):
if isinstance(key, str):
return d[key]
raise RuntimeError("Invalid key type: {}.".format(key))

Expand Down
24 changes: 11 additions & 13 deletions knowledge_repo/app/deploy/common.py
Expand Up @@ -4,9 +4,7 @@
import sys
import textwrap
from abc import abstractmethod
from future.utils import with_metaclass

import six
import knowledge_repo
from knowledge_repo.utils.registry import SubclassRegisteringABCMeta

Expand All @@ -21,16 +19,16 @@ def get_app():
return get_app


class KnowledgeDeployer(with_metaclass(SubclassRegisteringABCMeta, object)):
class KnowledgeDeployer(object, metaclass=SubclassRegisteringABCMeta):

def __init__(self,
knowledge_builder,
host='0.0.0.0',
port=7000,
workers=4,
timeout=60):
assert isinstance(knowledge_builder, six.string_types + (types.FunctionType, )), \
u"Unknown builder type {}".format(type(knowledge_builder))
assert isinstance(knowledge_builder, str + (types.FunctionType, )), \
"Unknown builder type {}".format(type(knowledge_builder))
self.knowledge_builder = knowledge_builder
self.host = host
self.port = port
Expand All @@ -57,17 +55,17 @@ def builder_str(self):
if isinstance(self.knowledge_builder, types.FunctionType):
out = []
for nl, cell in zip(self.knowledge_builder.__code__.co_freevars, self.knowledge_builder.__closure__):
if isinstance(cell.cell_contents, six.string_types):
out.append(u'{} = "{}"'.format(nl, cell.cell_contents.replace('"', '\\"')))
if isinstance(cell.cell_contents, str):
out.append('{} = "{}"'.format(nl, cell.cell_contents.replace('"', '\\"')))
else:
out.append(u'{} = {}'.format(nl, cell.cell_contents))
out.append('{} = {}'.format(nl, cell.cell_contents))
out.append(textwrap.dedent(inspect.getsource(self.knowledge_builder)))
return u'\n'.join(out)
return '\n'.join(out)
return self.knowledge_builder

@property
def builder_func(self):
if isinstance(self.knowledge_builder, six.string_types):
if isinstance(self.knowledge_builder, str):
knowledge_builder = 'def get_app():\n\t' + self.knowledge_builder.replace('\n', '\t') + '\n\treturn app'
namespace = {}
exec(knowledge_builder, namespace)
Expand All @@ -91,16 +89,16 @@ def write_temp_files(self):

out = []
out.append('import sys')
out.append(u'sys.path.insert(0, "{}")'.format(kr_path))
out.append('sys.path.insert(0, "{}")'.format(kr_path))
out.append('import knowledge_repo')

out.append(self.builder_str)
if not isinstance(self.knowledge_builder, six.string_types):
if not isinstance(self.knowledge_builder, str):
out.append('app = %s()' % self.knowledge_builder.__name__)
out.append('app.start_indexing()')

with open(tmp_path, 'w') as f:
f.write(u'\n'.join(out))
f.write('\n'.join(out))

return tmp_dir

Expand Down
4 changes: 1 addition & 3 deletions knowledge_repo/app/deploy/gunicorn.py
Expand Up @@ -5,8 +5,6 @@
Adapted from example in http://docs.gunicorn.org/en/stable/custom.html.
"""

from __future__ import absolute_import

from gunicorn.app.base import BaseApplication

from .common import KnowledgeDeployer
Expand All @@ -30,7 +28,7 @@ def load_config(self):

# Update the configuration with the options specified via KnowledgeDeployer
options = {
'bind': u'{}:{}'.format(self.host, self.port),
'bind': '{}:{}'.format(self.host, self.port),
'workers': self.workers,
'timeout': self.timeout,
}
Expand Down
8 changes: 4 additions & 4 deletions knowledge_repo/app/deploy/uwsgi.py
Expand Up @@ -12,7 +12,7 @@ class uWSGIDeployer(KnowledgeDeployer):

_registry_keys = ['uwsgi']

COMMAND = u"uwsgi {protocol} --plugin python --wsgi-file {{path}} --callable app --master --processes {{processes}} --threads {{threads}}"
COMMAND = "uwsgi {protocol} --plugin python --wsgi-file {{path}} --callable app --master --processes {{processes}} --threads {{threads}}"

def run(self):
if not self.app.check_thread_support():
Expand All @@ -21,7 +21,7 @@ def run(self):
tmp_dir = self.write_temp_files()

options = {
'socket': u'{}:{}'.format(self.host, self.port),
'socket': '{}:{}'.format(self.host, self.port),
'processes': self.workers,
'threads': 2,
'timeout': self.timeout,
Expand All @@ -36,8 +36,8 @@ def run(self):
self.COMMAND = self.COMMAND.format(protocol="--http {socket}")

try:
cmd = u"cd {};".format(tmp_dir) + self.COMMAND.format(**options)
logger.info("Starting server with command: %s", u" ".join(cmd))
cmd = "cd {};".format(tmp_dir) + self.COMMAND.format(**options)
logger.info("Starting server with command: %s", " ".join(cmd))
subprocess.check_output(cmd, shell=True)
finally:
shutil.rmtree(tmp_dir)
15 changes: 6 additions & 9 deletions knowledge_repo/app/index.py
@@ -1,10 +1,7 @@
from __future__ import absolute_import

import logging
import multiprocessing
import os
import time
from builtins import str

from .proxies import db_session, current_repo, current_app
from .models import ErrorLog, Post, IndexMetadata
Expand Down Expand Up @@ -160,12 +157,12 @@ def update_index(check_timeouts=True, force=False, reindex=False):
# If UUID has changed, check if we can find it elsewhere in the repository, and if so update index path
if post.uuid and ((post.path not in kr_dir) or (post.uuid != kr_dir[post.path].uuid)):
if post.uuid in kr_uuids:
logger.info(u'Updating location of post: {} -> {}'.format(post.path, kr_uuids[post.uuid].path))
logger.info('Updating location of post: {} -> {}'.format(post.path, kr_uuids[post.uuid].path))
post.path = kr_uuids[post.uuid].path

# If path of post no longer in directory, mark as unpublished
if post.path not in kr_dir:
logger.info(u'Recording unpublished status for post at {}'.format(post.path))
logger.info('Recording unpublished status for post at {}'.format(post.path))
post.status = current_repo.PostStatus.UNPUBLISHED
continue

Expand All @@ -177,17 +174,17 @@ def update_index(check_timeouts=True, force=False, reindex=False):
# Update metadata of post if required
if reindex or (kp.revision > post.revision or not post.is_published or kp.uuid != post.uuid):
if kp.is_valid():
logger.info(u'Recording update to post at: {}'.format(kp.path))
logger.info('Recording update to post at: {}'.format(kp.path))
post.update_metadata_from_kp(kp)
else:
logger.warning(u'Update to post at "{}" is corrupt.'.format(kp.path))
logger.warning('Update to post at "{}" is corrupt.'.format(kp.path))

# Add the new posts that remain in kr_dir
for kp_path, kp in kr_dir.items():
if not kp.is_valid():
logger.warning(u'New post at "{}" is corrupt.'.format(kp.path))
logger.warning('New post at "{}" is corrupt.'.format(kp.path))
continue
logger.info(u'creating new post from path {}'.format(kp_path))
logger.info('creating new post from path {}'.format(kp_path))
post = Post()
db_session.add(post)
db_session.flush() # (matthew) Fix groups logic so this is not necessary
Expand Down
1 change: 0 additions & 1 deletion knowledge_repo/app/migrations/env.py
@@ -1,4 +1,3 @@
from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig
Expand Down
14 changes: 6 additions & 8 deletions knowledge_repo/app/models.py
Expand Up @@ -3,8 +3,6 @@
import datetime
import logging
import traceback
from builtins import str
from future.utils import raise_with_traceback
from flask import current_app, request
from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
Expand Down Expand Up @@ -124,9 +122,9 @@ def from_exception(cls, e):
filename = os.path.relpath(filename, os.path.join(os.path.dirname(__file__), '..'))
return ErrorLog(
function=function,
location=u'{}:{}'.format(filename, linenumber),
message=u'{}: {}'.format(e.__class__.__name__, u"; ".join(str(a) for a in e.args)),
traceback=u"\n".join(traceback.format_tb(tb))
location='{}:{}'.format(filename, linenumber),
message='{}: {}'.format(e.__class__.__name__, "; ".join(str(a) for a in e.args)),
traceback="\n".join(traceback.format_tb(tb))
)

@classmethod
Expand All @@ -138,7 +136,7 @@ def wrapped(*args, **kwargs):
db_session.rollback()
db_session.add(ErrorLog.from_exception(e))
db_session.commit()
raise_with_traceback(e)
raise e.with_traceback()
return wrapped


Expand Down Expand Up @@ -340,7 +338,7 @@ class Tag(db.Model):
def description(self):
if self._description:
return self._description
return u"All posts with tag '{}'.".format(self.name)
return "All posts with tag '{}'.".format(self.name)

@description.expression
def description(self):
Expand Down Expand Up @@ -407,7 +405,7 @@ def authors(self, authors):

@hybrid_property
def authors_string(self):
return u', '.join([author.format_name for author in self.authors])
return ', '.join([author.format_name for author in self.authors])

@authors_string.expression
def authors_string(self):
Expand Down

0 comments on commit aeab224

Please sign in to comment.