Esempio n. 1
0
import appengine_config
from common import caching
from models import config
from models import models
from models.counters import PerfCounter

import gae_mini_profiler.profiler
import gae_mini_profiler.templatetags

# max size for in-process jinja template cache
MAX_GLOBAL_CACHE_SIZE_BYTES = 8 * 1024 * 1024

# this cache used to be memcache based; now it's in-process
CAN_USE_JINJA2_TEMPLATE_CACHE = config.ConfigProperty(
    'gcb_can_use_jinja2_template_cache',
    bool,
    safe_dom.Text(
        'Whether jinja2 can cache bytecode of compiled templates in-process.'),
    default_value=True)


def finalize(x):
    """A finalize method which will correctly handle safe_dom elements."""
    if isinstance(x, safe_dom.Node) or isinstance(x, safe_dom.NodeList):
        return jinja2.utils.Markup(x.sanitized)
    return x


def js_string_raw(data):
    """Escape a string so that it can be put in a JS quote."""
    if not isinstance(data, basestring):
        return data
    def build(cls, name, label, desc, max_size_bytes, ttl_sec, dao_class):
        """Build the family of classes for a process-scoped Entity cache.

        Args:
          name: Name under which cache is registered.  This should be in the
              lower_case_and_underscores naming style
          label: Label for the course-level setting enabling/disabling
              process-level caching for this entity type.
          desc: Description to add to the course-level setting
              enabling/disabling process level caching for this entity type.
          max_size_bytes: Largest size the cache may take on.  If adding
              an item to the cache would make it exceed this size, items
              are LRU'd out until the item fits.
          ttl_sec: Number of seconds after which cached entries are
              considered stale and a (lazy) refresh is performed.
          dao_class: The class of an DAO in the Entity/DTO/DAO scheme
              common for Course Builder data access.  Used for itself
              and also for its references to its matching DTO, Entity
              classes.
        Returns:
          A ResourceCacheFactory entry containing the constellation of
          objects that interoperate to form a cche.
        """

        if name in cls._CACHES:
            return cls._CACHES[name]

        config_property = config.ConfigProperty(
            'gcb_can_use_%s_in_process_cache' % name,
            bool,
            desc,
            label=label,
            default_value=True)

        class EntityCache(caching.ProcessScopedSingleton):
            """This class holds in-process global cache of objects."""
            @classmethod
            def get_cache_len(cls):
                # pylint: disable=protected-access
                return len(cls.instance()._cache.items.keys())

            @classmethod
            def get_cache_size(cls):
                # pylint: disable=protected-access
                return cls.instance()._cache.total_size

            def __init__(self):
                self._cache = caching.LRUCache(max_size_bytes=max_size_bytes)
                self._cache.get_entry_size = self._get_entry_size

            def _get_entry_size(self, key, value):
                if not value:
                    return 0
                return sys.getsizeof(key) + sys.getsizeof(value)

            @property
            def cache(self):
                return self._cache

        class CacheEntry(caching.AbstractCacheEntry):
            """Cache entry containing an entity."""
            def __init__(self, entity):
                self.entity = entity
                self.created_on = datetime.datetime.utcnow()

            def getsizeof(self):
                return (dao_class.ENTITY.getsizeof(self.entity) +
                        sys.getsizeof(self.created_on))

            def has_expired(self):
                age = (datetime.datetime.utcnow() -
                       self.created_on).total_seconds()
                return age > ttl_sec

            def is_up_to_date(self, key, update):
                if update and self.entity:
                    return update.updated_on == self.entity.updated_on
                return not update and not self.entity

            def updated_on(self):
                if self.entity:
                    return self.entity.updated_on
                return None

            @classmethod
            def externalize(cls, key, entry):
                entity = entry.entity
                if not entity:
                    return None
                return dao_class.DTO(entity.key().id_or_name(),
                                     transforms.loads(entity.data))

            @classmethod
            def internalize(cls, key, entity):
                return cls(entity)

        class CacheConnection(caching.AbstractCacheConnection):

            PERSISTENT_ENTITY = dao_class.ENTITY
            CACHE_ENTRY = CacheEntry

            @classmethod
            def init_counters(cls):
                caching.AbstractCacheConnection.init_counters()

            @classmethod
            def is_enabled(cls):
                return config_property.value

            def __init__(self, namespace):
                caching.AbstractCacheConnection.__init__(self, namespace)
                self.cache = EntityCache.instance().cache

            def get_updates_when_empty(self):
                """Load in all ResourceBundles when cache is empty."""
                q = self.PERSISTENT_ENTITY.all()
                for entity in caching.iter_all(q):
                    self.put(entity.key().name(), entity)
                    self.CACHE_UPDATE_COUNT.inc()

                # we don't have any updates to apply; all items are new
                return {}

        class ConnectionManager(caching.RequestScopedSingleton):
            """Class that provides access to in-process Entity cache.

            This class only supports get() and does not intercept
            put() or delete() and is unaware of changes to
            Entities made in this very process.  When
            entites change, the changes will be picked up
            when new instance of this class is created. If you are
            watching perfomance counters, you will see EVICT and
            EXPIRE being incremented, but not DELETE or PUT.
            """
            def __init__(self):
                # Keep a separate CacheConnection for each namespace that
                # makes a get() request.
                self._conns = {}

            def _conn(self, ns):
                connected = self._conns.get(ns)
                if not connected:
                    logging.debug(
                        'CONNECTING a CacheConnection for namespace "%s",', ns)
                    connected = CacheConnection.new_connection(ns)
                    self._conns[ns] = connected
                return connected

            @classmethod
            def _ns(cls, app_context):
                if app_context:
                    return app_context.get_namespace_name()
                return namespace_manager.get_namespace()

            def _get(self, key, namespace):
                found, stream = self._conn(namespace).get(key)
                if found and stream:
                    return stream
                with utils.Namespace(namespace):
                    entity = dao_class.ENTITY_KEY_TYPE.get_entity_by_key(
                        dao_class.ENTITY, str(key))
                if entity:
                    self._conn(namespace).put(key, entity)
                    return dao_class.DTO(entity.key().id_or_name(),
                                         transforms.loads(entity.data))
                self._conn(namespace).CACHE_NOT_FOUND.inc()
                self._conn(namespace).put(key, None)
                return None

            def _get_multi(self, keys, namespace):
                return [self._get(key, namespace) for key in keys]

            @classmethod
            def get(cls, key, app_context=None):
                # pylint: disable=protected-access
                return cls.instance()._get(key, cls._ns(app_context))

            @classmethod
            def get_multi(cls, keys, app_context=None):
                # pylint: disable=protected-access
                return cls.instance()._get_multi(keys, cls._ns(app_context))

        cache_len = counters.PerfCounter(
            'gcb-models-%sCacheConnection-cache-len' %
            dao_class.ENTITY.__name__, 'Total number of items in the cache')
        cache_len.poll_value = EntityCache.get_cache_len

        cache_size = counters.PerfCounter(
            'gcb-models-%sCacheConnection-cache-bytes' %
            dao_class.ENTITY.__name__, 'Total number of bytes in the cache.')
        cache_size.poll_value = EntityCache.get_cache_size

        CacheConnection.init_counters()

        entry = CacheFactoryEntry(EntityCache, CacheEntry, CacheConnection,
                                  ConnectionManager, config_property,
                                  cache_len, cache_size)
        cls._CACHES[name] = entry
        return entry
Esempio n. 3
0
from models import counters
from models import courses
from models import custom_modules
from models import jobs
from models import transforms

from google.appengine.api import namespace_manager
from google.appengine.api import search
from google.appengine.ext import db

MODULE_NAME = 'Full Text Search'

CAN_INDEX_ALL_COURSES_IN_CRON = config.ConfigProperty(
    'gcb_can_index_automatically', bool, safe_dom.Text(
        'Whether the search module can automatically index the course daily '
        'using a cron job. If enabled, this job would index the course '
        'incrementally so that only new items or items which have not been '
        'recently indexed are indexed.'),
    default_value=False)
SEARCH_QUERIES_MADE = counters.PerfCounter(
    'gcb-search-queries-made',
    'The number of student queries made to the search module.')
SEARCH_RESULTS_RETURNED = counters.PerfCounter(
    'gcb-search-results-returned',
    'The number of search results returned across all student queries.')
SEARCH_FAILURES = counters.PerfCounter(
    'gcb-search-failures',
    'The number of search failure messages returned across all student '
    'queries.')

INDEX_NAME = 'gcb_search_index'
Esempio n. 4
0
import time

from Crypto.Cipher import AES

import appengine_config
from common import utils
from models import config

from google.appengine.api import users

XSRF_SECRET_LENGTH = 20

XSRF_SECRET = config.ConfigProperty(
    'gcb_xsrf_secret', str, (
        'Text used to encrypt tokens, which help prevent Cross-site request '
        'forgery (CSRF, XSRF). You can set the value to any alphanumeric text, '
        'preferably using 16-64 characters. Once you change this value, the '
        'server rejects all subsequent requests issued using an old value for '
        'this variable.'),
    'course builder XSRF secret')

ENCRYPTION_SECRET_LENGTH = 48

ENCRYPTION_SECRET = config.ConfigProperty(
    'gcb_encryption_secret', str, (
        'Text used to encrypt messages.  You can set this to any text at all, '
        'but the value must be exactly ' + str(ENCRYPTION_SECRET_LENGTH) +
        ' characters long.  If you change this value, the server will be '
        'unable to understand items encrypted under the old key.'),
    'default value of CourseBuilder encryption secret',
    validator=config.ValidateLength(ENCRYPTION_SECRET_LENGTH).validator)
Esempio n. 5
0
import logging
import urllib2
import json

from common.schema_fields import SchemaField
from models import config
from models import courses
from models import custom_modules
from modules.programming_assignments import base
from modules.programming_assignments import evaluator
from modules.programming_assignments import result
from modules.programming_assignments import settings
from modules.mooshak import mooshak

MOOSHAK_STATELESS_TARGET = config.ConfigProperty(
    'mooshak_stateless_target', str,
    'The Mooshak stateless target to send code to evaluate. ex: mooshak.example.com or'
    ' 127.0.0.0', '')

MOOSHAK_STATELESS_SERVER = 'mooshak_stateless_server'


class MooshakStatelessEvaluator(mooshak.MooshakEvaluator):
    @classmethod
    def send_request(cls,
                     mooshak_ip,
                     code,
                     program_name,
                     pa_id,
                     filename,
                     tests,
                     lang,
Esempio n. 6
0
import os
import re
from xml.etree import cElementTree

import html5lib
import safe_dom
import webapp2

import appengine_config
from common import schema_fields
from models import config

CAN_USE_DYNAMIC_TAGS = config.ConfigProperty(
    'gcb_can_use_dynamic_tags',
    bool,
    safe_dom.Text(
        'Whether lesson content can make use of custom HTML tags such as '
        '<gcb-youtube videoid="...">. If this is enabled some legacy content '
        'may be rendered differently. '),
    default_value=True)

DUPLICATE_INSTANCE_ID_MESSAGE = (
    'Error processing custom HTML tag: duplicate tag id')
INVALID_HTML_TAG_MESSAGE = 'Invalid HTML tag'


class BaseTag(object):
    """Base class for the custom HTML tags."""
    @classmethod
    def name(cls):
        return cls.__name__
Esempio n. 7
0
_REST_URL_BASE = '/rest/balancer/v1'
_REST_URL_PROJECT = _REST_URL_BASE + '/project'
_REST_URL_TASK = _REST_URL_BASE
_STATUS = 'status'
_USER_ID = 'user_id'
_WORKER_DEADLINE_SECONDS = 5
_WORKER_ID = 'worker_id'
_WORKER_LOCKED = 'Worker locked'
_WORKER_LOCKED_MAX_RETRIES = 3

_LOG = logging.getLogger('modules.balancer.balancer')
logging.basicConfig()

EXTERNAL_TASK_BALANCER_REST_ENABLED = config.ConfigProperty(
    'gcb_external_task_balancer_rest_enabled',
    bool,
    messages.SITE_SETTINGS_TASK_BALANCER_REST,
    default_value=False,
    label='Task Balancer REST')
EXTERNAL_TASK_BALANCER_WORKER_URL = config.ConfigProperty(
    'gcb_external_task_balancer_worker_url',
    str,
    messages.SITE_SETTINGS_TASK_BALANCER_URL,
    default_value='',
    label='Task Balancer URL')


class Error(Exception):
    """Base error class."""


class NotFoundError(Exception):
Esempio n. 8
0
from common import messages
from common import schema_fields
from models import config

_LXML_AVAILABLE = False
try:
    import lxml.html
    _LXML_AVAILABLE = True
except ImportError:
    if appengine_config.PRODUCTION_MODE:
        raise

CAN_USE_DYNAMIC_TAGS = config.ConfigProperty(
    'gcb_can_use_dynamic_tags',
    bool,
    messages.SITE_SETTINGS_DYNAMIC_TAGS,
    default_value=True,
    label='Dynamic Tags')

DUPLICATE_INSTANCE_ID_MESSAGE = (
    'Error processing custom HTML tag: duplicate tag id')
INVALID_HTML_TAG_MESSAGE = 'Invalid HTML tag'


class BaseTag(object):
    """Base class for the custom HTML tags."""
    @classmethod
    def name(cls):
        return cls.__name__

    @classmethod
Esempio n. 9
0
from controllers import sites
from models import config
from models import courses
from models import roles
from models import transforms

from google.appengine.api import namespace_manager
from google.appengine.api import taskqueue
from google.appengine.api import urlfetch
from google.appengine.ext import deferred

_INSTALLATION_IDENTIFIER = config.ConfigProperty(
    'gcb_report_usage_identifier', str, (
        'Randomized string used to identify this installation of '
        'CourseBuilder when reporting usage statistics.  This value '
        'has no intrinsic meaning, and no relation to any data or '
        'course setting; it is just used to correlate the weekly '
        'reports from this installation.'),
    default_value='A random value will be picked when the first report is '
    'sent.', label='Usage report ID',
    )

# Name of the item in the course settings dictionary which contains the
# randomly-generated identifier for the course.  (This name needs to be
# defined here to prevent circular inclusion problems with this module
# versus 'config')
USAGE_REPORTING_FIELD_ID = 'usage_reporting_id'

# Usage reporting is turned off on dev, but this flag overrides that, to
# enable testing of messaging and UI.
ENABLED_IN_DEV_FOR_TESTING = False
Esempio n. 10
0
logging.basicConfig()

VERSION_1_0 = '1.0'
VERSION_1_1 = '1.1'
VERSION_1_2 = '1.2'
VERSIONS = frozenset([
    VERSION_1_0,
    VERSION_1_1,
    VERSION_1_2,
])

COURSES_CAN_ENABLE_LTI_PROVIDER = config.ConfigProperty(
    'gcb_courses_can_enable_lti_provider',
    bool,
    ('Whether or not to allow courses to enable the LTI provider for their '
     'content. If True, courses can enable a setting to allow outside parties '
     'to embed their content via the LTI protocol. If False, the control on '
     'the course page to enable the LTI provider will be present, but it will '
     'have no effect.'),
    default_value=True)


class Error(Exception):
    """Base error."""


class InvalidVersionError(Exception):
    """Raised when an invalid LTI version is specified."""


def _get_runtime(app_context):
Esempio n. 11
0
_WIDGET_URL = '%s/widget' % _BASE_URL

_CONFIG_YAML_ADMINS_NAME = 'admins'
_CONFIG_YAML_ENABLED_NAME = 'enabled'
_CONFIG_YAML_PATH = os.path.join(_RESOURCES_DIR, 'config.yaml')

_TEMPLATES_DIR = os.path.join(_BASE_PATH, 'templates')
_BRANDING_TEMPLATE_PATH = 'branding.html'
_SIGN_OUT_TEMPLATE_PATH = 'signout.html'
_WIDGET_TEMPLATE_PATH = 'widget.html'

_LOG = logging.getLogger('modules.gitkit.gitkit')

_BROWSER_API_KEY = config.ConfigProperty(
    'gcb_modules_gitkit_browser_api_key', str,
    ('Browser API Key from the Google Developer console. This field is found '
     'under Key from browser applications > API key. See %s for instructions') %
        'https://developers.google.com/identity/toolkit/web/configure-service',
    default_value='')
_CLIENT_ID = config.ConfigProperty(
    'gcb_modules_gitkit_client_id', str,
    ('Client ID from the Google Developer console. This field is found under '
     'Client ID for web application > Client ID. See %s for instructions') %
        'https://developers.google.com/identity/toolkit/web/configure-service',
    default_value='')
_SERVER_API_KEY = config.ConfigProperty(
    'gcb_modules_gitkit_server_api_key', str,
    ('Server API key from the Google Developer console. This field is found '
     'under Key for server applications > API key. See %s for instructions') %
        'https://developers.google.com/identity/toolkit/web/configure-service',
    default_value='')
_SERVICE_ACCOUNT_JSON = config.ConfigProperty(
Esempio n. 12
0
from modules.usage_reporting import constants


def _on_change_report_allowed(config_property, unused_old_value):
    """Callback to report externally when value of REPORT_ALLOWED changes."""
    messaging.Message.send_instance_message(
        messaging.Message.METRIC_REPORT_ALLOWED,
        config_property.value,
        source=messaging.Message.ADMIN_SOURCE)


REPORT_ALLOWED = config.ConfigProperty(
    'gcb_report_usage_permitted',
    bool,
    safe_dom.Template(
        jinja_utils.get_template('message.html', [constants.TEMPLATES_DIR],
                                 default_locale=None)),
    after_change=_on_change_report_allowed,
    default_value=False,
    label='Usage reporting')


def set_report_allowed(value):
    with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
        entity = config.ConfigPropertyEntity.get_by_key_name(
            REPORT_ALLOWED.name)
        if not entity:
            entity = config.ConfigPropertyEntity(key_name=REPORT_ALLOWED.name)
        entity.value = str(value)
        entity.is_draft = False
        entity.put()
Esempio n. 13
0
            m_list = list(message)
            m_list.reverse()
            return ''.join(m_list)

        def encrypt(self, message):
            return self._reverse(message)

        def decrypt(self, message):
            return self._reverse(message)


XSRF_SECRET_LENGTH = 20

XSRF_SECRET = config.ConfigProperty('gcb_xsrf_secret',
                                    str,
                                    messages.SITE_SETTINGS_XSRF_SECRET,
                                    default_value='Course Builder XSRF Secret',
                                    label='XSRF secret')

ENCRYPTION_SECRET_LENGTH = 48

ENCRYPTION_SECRET = config.ConfigProperty(
    'gcb_encryption_secret',
    str,
    messages.SITE_SETTINGS_ENCRYPTION_SECRET,
    default_value='default value of CourseBuilder encryption secret',
    label='Encryption Secret',
    validator=config.ValidateLength(ENCRYPTION_SECRET_LENGTH).validator)


class EncryptionManager(object):
Esempio n. 14
0
_LOG = logging.getLogger('modules.embed.embed')

_TEMPLATES_DIR_V1 = os.path.join(_BASE_DIR, 'templates', _V1)
_DEMO_HTML_PATH = os.path.join(_TEMPLATES_DIR_V1, 'demo.html')
_GLOBAL_ERRORS_DEMO_HTML_PATH = os.path.join(
    _TEMPLATES_DIR_V1, 'global_errors.html')
_LOCAL_ERRORS_DEMO_HTML_PATH = os.path.join(
    _TEMPLATES_DIR_V1, 'local_errors.html')
_TEMPLATES_ENV = jinja_utils.create_jinja_environment(
    jinja2.FileSystemLoader([_TEMPLATES_DIR_V1]))


# TODO(johncox): remove after security audit of embed module.
_MODULE_HANDLERS_ENABLED = config.ConfigProperty(
    'gcb_modules_embed_handlers_enabled', bool,
    ('Whether or not to enable the embed module handlers. You must enable this '
     'property to use Course Builder embeds'), default_value=False,
    label='Enable embed module handlers')


class AbstractEnrollmentPolicy(object):
    """Abstract parent for business logic run during resource dispatch."""

    @classmethod
    def apply(cls, unused_handler):
        raise NotImplementedError(
            'You must set a concrete enrollment policy on your embed')


class AutomaticEnrollmentPolicy(AbstractEnrollmentPolicy):
    """Policy that registers the current user in a course automatically."""
Esempio n. 15
0
    def get(self):
        if not GQL_SERVICE_ENABLED.value:
            self.error(404)
            return

        query_str = self.request.get('q')
        expanded_gcb_tags = self.request.get('expanded_gcb_tags')
        response_dict = self._get_response_dict(query_str, expanded_gcb_tags)
        status_code = 400 if response_dict['errors'] else 200
        self._send_response(status_code, response_dict)


GQL_SERVICE_ENABLED = config.ConfigProperty(
    'gcb_gql_service_enabled',
    bool,
    'Enable the GraphQL REST endpoint.',
    default_value=True,
    label='GraphQL')


def register_module():

    global_routes = [(GraphQLRestHandler.URL, GraphQLRestHandler)]

    namespaced_routes = []

    global custom_module  # pylint: disable=global-statement
    custom_module = custom_modules.Module(
        'GraphQL', 'Handles queries for Course Builder in GraphQL.',
        global_routes, namespaced_routes)
Esempio n. 16
0
import json

from google import protobuf

from common.schema_fields import SchemaField
from models import config
from models import courses
from models import custom_modules
from modules.nsjail.proto import request_pb2
from modules.programming_assignments import base
from modules.programming_assignments import evaluator
from modules.programming_assignments import result
from modules.programming_assignments import settings

NSJAIL_TARGET = config.ConfigProperty(
    'nsjail_target', str,
    'The Nsjail target to send code to evaluate. ex: nsjail.example.com or'
    ' 127.0.0.0', '')

NSJAIL_SERVER = 'nsjail_server'

ERROR_LIST = {
    request_pb2.CodeReply.MEMORY_LIMIT_EXCEEDED: 'Memory Limit Exceeded',
    request_pb2.CodeReply.TIME_LIMIT_EXCEEDED: 'Time Limit Exceeded',
    request_pb2.CodeReply.RUNTIME_ERROR: 'Runtime Error',
    request_pb2.CodeReply.WRONG_ANSWER: 'Wrong Answer',
    request_pb2.CodeReply.PRESENTATION_ERROR: 'Presentation Error',
    request_pb2.CodeReply.COMPILATION_ERROR: 'Compilation Error'
}


class NsjailEvaluator(evaluator.ProgramEvaluator):
Esempio n. 17
0
from models import jobs
from models import services
from models import transforms
from modules.dashboard import dashboard

from google.appengine.api import namespace_manager
from google.appengine.api import search
from google.appengine.ext import db

MODULE_NAME = 'Full Text Search'

DEPRECATED = config.ConfigProperty(
    'gcb_can_index_automatically',
    bool,
    safe_dom.Text(
        'This property has been deprecated; it is retained so that we '
        'will not generate no-such-variable error messages for existing '
        'installations that have this property set.'),
    default_value=False,
    label='Automatically index search',
    deprecated=True)
SEARCH_QUERIES_MADE = counters.PerfCounter(
    'gcb-search-queries-made',
    'The number of student queries made to the search module.')
SEARCH_RESULTS_RETURNED = counters.PerfCounter(
    'gcb-search-results-returned',
    'The number of search results returned across all student queries.')
SEARCH_FAILURES = counters.PerfCounter(
    'gcb-search-failures',
    'The number of search failure messages returned across all student '
    'queries.')
Esempio n. 18
0
 def add_setting(deprecated):
     return config.ConfigProperty(
         'gcb_test_property', bool, 'doc string',
         label='Test Property Label', deprecated=deprecated)
Esempio n. 19
0
import appengine_config

from common import caching
from common import messages
from models import config
from models import models
from models import transforms
from models.counters import PerfCounter

# max size for in-process jinja template cache
MAX_GLOBAL_CACHE_SIZE_BYTES = 8 * 1024 * 1024

# this cache used to be memcache based; now it's in-process
CAN_USE_JINJA2_TEMPLATE_CACHE = config.ConfigProperty(
    'gcb_can_use_jinja2_template_cache',
    bool,
    messages.SITE_SETTINGS_CACHE_TEMPLATES,
    default_value=True,
    label='Cache Templates')


def finalize(x):
    """A finalize method which will correctly handle safe_dom elements."""
    if isinstance(x, safe_dom.SafeDom):
        return jinja2.utils.Markup(x.sanitized)
    return x


def js_string_raw(data):
    """Escape a string so that it can be put in a JS quote."""
    if not isinstance(data, basestring):
        return data
Esempio n. 20
0
_REST_URL_PROJECT = _REST_URL_BASE + '/project'
_REST_URL_TASK = _REST_URL_BASE
_STATUS = 'status'
_USER_ID = 'user_id'
_WORKER_DEADLINE_SECONDS = 5
_WORKER_ID = 'worker_id'
_WORKER_LOCKED = 'Worker locked'
_WORKER_LOCKED_MAX_RETRIES = 3

_LOG = logging.getLogger('modules.balancer.balancer')
logging.basicConfig()

EXTERNAL_TASK_BALANCER_REST_ENABLED = config.ConfigProperty(
    'gcb_external_task_balancer_rest_enabled',
    bool,
    ('Whether or not to enable the REST endpoints for the external task '
     'balancer module. You must also set gcb_external_task_balancer_worker_url '
     'to use this feature.'),
    default_value=False)
EXTERNAL_TASK_BALANCER_WORKER_URL = config.ConfigProperty(
    'gcb_external_task_balancer_worker_url',
    str,
    'URL for the worker pool used by the external task balancer module.',
    default_value='')


class Error(Exception):
    """Base error class."""


class NotFoundError(Exception):
Esempio n. 21
0

def _on_change_report_allowed(config_property, unused_old_value):
    """Callback to report externally when value of REPORT_ALLOWED changes."""
    messaging.Message.send_instance_message(
        messaging.Message.METRIC_REPORT_ALLOWED,
        config_property.value,
        source=messaging.Message.ADMIN_SOURCE)


REPORT_ALLOWED = config.ConfigProperty(
    'gcb_report_usage_permitted',
    bool,
    'Whether anonymized per-course usage statistics should be sent to the '
    'CourseBuilder team.  The report contains randomly chosen identifiers '
    'for the installation and course (to correlate reports) '
    'hour-by-hour data on enrollments/unenrollments, and current number of '
    'students.  This report is sent once a week.',
    after_change=_on_change_report_allowed,
    default_value=False,
    label='Usage reporting')


def set_report_allowed(value):
    with common_utils.Namespace(appengine_config.DEFAULT_NAMESPACE_NAME):
        entity = config.ConfigPropertyEntity.get_by_key_name(
            REPORT_ALLOWED.name)
        if not entity:
            entity = config.ConfigPropertyEntity(key_name=REPORT_ALLOWED.name)
        entity.value = str(value)
        entity.is_draft = False
Esempio n. 22
0
import urllib2

from common.schema_fields import SchemaField
from models import config
from models import courses
from models import custom_modules
from modules.programming_assignments import base
from modules.programming_assignments import evaluator
from modules.programming_assignments import result
from modules.programming_assignments import settings

from xml.dom import minidom
from xml.parsers.expat import ExpatError

MOOSHAK_TARGET = config.ConfigProperty(
    'mooshak_target', str,
    'The Mooshak target to send code to evaluate. ex: mooshak.example.com or'
    ' 127.0.0.0', '')

MOOSHAK_SERVER = 'mooshak_server'


class MultiPartForm(object):
    """Accumulate the data to be used when posting a form."""
    def __init__(self):
        self.form_fields = []
        self.files = []
        self.boundary = mimetools.choose_boundary()
        return

    def get_content_type(self):
        return 'multipart/form-data; boundary=%s' % self.boundary
Esempio n. 23
0
from common import utils as common_utils
from models import config
from models import models
from models import roles
from models import transforms
from models import messages as models_messages
from controllers import utils
from modules.explorer import constants
from modules.explorer import messages
from modules.drive import dashboard_handler
from modules.oeditor import oeditor

GCB_ENABLE_COURSE_EXPLORER_PAGE = config.ConfigProperty(
    'gcb_enable_course_explorer_page',
    bool,
    messages.SITE_SETTINGS_COURSE_EXPLORER,
    default_value=False,
    label='Course Explorer',
    multiline=False,
    validator=None)

COURSE_EXPLORER_SETTINGS = config.ConfigProperty('course_explorer_settings',
                                                 str,
                                                 '',
                                                 label='Site settings',
                                                 show_in_site_settings=False)


def make_logo_url(mime_type, bytes_base64):
    return 'data:{};base64,{}'.format(mime_type, bytes_base64)

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Settings for the Guide module."""

__author__ = [
    '[email protected] (Davy Risso)',
]

from models import config

from modules.guide import messages

GCB_ENABLE_GUIDE_PAGE = config.ConfigProperty('gcb_enable_guide_page',
                                              bool,
                                              messages.SITE_SETTINGS_GUIDE,
                                              default_value=True,
                                              label='Guide',
                                              multiline=False,
                                              validator=None)

namespaced_routes = []