Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

""" 

    marvin 

    ~~~~~~ 

 

    This is the main entry point to marvin, the API endpoints for streamr. 

""" 

 

# pylint: disable=invalid-name,superfluous-parens 

from . import utils 

from .security import before_request_authentication 

 

from celery import Celery 

from flask import Flask 

from flask.ext.principal import Principal 

from flask.ext.sqlalchemy import SQLAlchemy 

from logging import getLogger 

from sqlalchemy_defaults import make_lazy_configured 

from os import path, environ 

 

import logging.config 

import sqlalchemy 

import yaml 

 

 

api = utils.ApiBase() 

db = SQLAlchemy() 

principal = Principal() 

 

_logger = getLogger('marvin') 

 

 

def create_app(config_file=None, **extra_config): 

    """ Creates a WSGI app. 

 

    :param config_file: Load config from this file. 

    :param extra_config: Extra configuration values to pass to the WSGI object. 

    """ 

    app = Flask(__name__) 

 

    _configure_app(app, config_file, **extra_config) 

    _configure_logging(app) 

    _connect_extensions(app) 

 

    # Configure lazy models 

    make_lazy_configured(sqlalchemy.orm.mapper) 

 

    _connect_blueprints(app) 

    _connect_api_endpoints() 

    _connect_utilities(app) 

 

    # Import modules that connect to signals 

    from . import permissions as _ 

 

    return app 

 

 

def _configure_app(app, config_file=None, **extra_config): 

    # Load the core settings 

    core_settings = path.abspath(path.join(path.dirname(__file__), 'settings.py')) 

    app.config.from_pyfile(core_settings) 

 

    # Load from specified config file 

    if config_file is not None: 

        app.config.from_pyfile(config_file) 

 

    # Load from environment specified config 

    if 'MARVIN_CONFIG_FILE' in environ: 

        print("Loading config from %s..." % environ['MARVIN_CONFIG_FILE']) 

        app.config.from_envvar('MARVIN_CONFIG_FILE') 

 

    # Override with any kwargs given 

    app.config.update(extra_config) 

 

 

def _configure_logging(app): 

    """ Configures log handlers for the app, if necessary. Log config can be ignored if TESTING=True or DEBUG=True. """ 

    log_conf_path = app.config.get('LOG_CONF_PATH') 

    if log_conf_path: 

        print("Loading log config from %s" % log_conf_path) 

        _init_logging(log_conf_path) 

    else: 

        ignore_absent_logging = app.config.get('DEBUG') or app.config.get('TESTING') 

        if not ignore_absent_logging: 

            raise ValueError('ERROR: LOG_CONF_PATH not found in config, terminating.') 

 

 

def _connect_extensions(app): 

    db.init_app(app) 

    api.init_app(app) 

    principal.init_app(app) 

 

 

def _connect_blueprints(app): 

    # Import views (must be done down here to avoid circular imports) 

    from .views import stats 

    from .views import promo 

 

    app.register_blueprint(stats.mod) 

    app.register_blueprint(promo.mod) 

 

 

def _connect_api_endpoints(): 

    # Import views (must be done down here to avoid circular imports) 

    from .views import movies 

    from .views import streams 

    from .views import entries 

    from .views import users 

 

    api.add_resource(movies.AllMoviesView, '/movies') 

    api.add_resource(movies.MovieDetailView, '/movies/<int:movie_id>') 

    api.add_resource(streams.CreateStreamView, '/movies/<int:movie_id>/createStream') 

    api.add_resource(streams.StreamDetailView, '/streams/<int:stream_id>') 

    api.add_resource(streams.StreamEntryView, '/streams/<int:stream_id>/entries') 

    api.add_resource(streams.PublishStreamView, '/streams/<int:stream_id>/publish') 

    api.add_resource(streams.UnpublishStreamView, '/streams/<int:stream_id>/unpublish') 

    api.add_resource(entries.CreateEntryView, '/streams/<int:stream_id>/createEntry') 

    api.add_resource(entries.EntryDetailView, '/entries/<int:entry_id>') 

    api.add_resource(users.CreateUserView, '/users') 

    api.add_resource(users.UserDetailView, '/users/<int:user_id>') 

    api.add_resource(users.LoginView, '/login') 

 

 

def _connect_utilities(app): 

    # Error handler 

    app.register_error_handler(500, utils.error_handler) 

 

    # Connect before and after request handlers 

    app.before_request(before_request_authentication) 

    app.teardown_appcontext(utils.teardown_appcontext) 

 

 

def _init_logging(log_conf_path): 

    """ Configure logging with the config given. """ 

    with open(log_conf_path) as log_conf_file: 

        log_conf = yaml.load(log_conf_file) 

    logging.config.dictConfig(log_conf) 

 

 

def make_celery(): 

    """ Creates a celery object. 

 

    Requires that create_app() can be called without arguments, so MARVIN_CONFIG_FILE should 

    probably point to the config file you want to use. 

    """ 

    app = create_app() 

    celery = Celery(app.import_name, broker=app.config['CELERY_BROKER_URL']) 

    celery.conf.update(app.config) 

    TaskBase = celery.Task 

    class ContextTask(TaskBase): 

        """ Wraps the base task to make sure it's run in an app context. """ 

 

        abstract = True 

 

        def __call__(self, *args, **kwargs): 

            with app.app_context(): 

                return TaskBase.__call__(self, *args, **kwargs) 

    celery.Task = ContextTask 

    return celery