Revision 2ce0636e

b/snf-app/setup.py
203 203
         'snf-cloud = synnefo.tools.cloud:main',
204 204
         ],
205 205
     'synnefo': [
206
         'settings = synnefo.app_settings',
207
         'apps = synnefo.app_settings:getapps',
206
         'default_settings = synnefo.app_settings.default',
207
         'web_apps = synnefo.app_settings:synnefo_web_apps',
208
         'web_middleware = synnefo.app_settings:synnefo_web_middleware',
209
         'urls = synnefo.app_settings.urls:urlpatterns',
208 210
         ]
209 211
      },
210 212
    )
b/snf-app/synnefo/__init__.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
1 34
# this is a namespace package
2 35
try:
3 36
    import pkg_resources
b/snf-app/synnefo/app_settings/__init__.py
1
from synnefo.app_settings.default import *
1
synnefo_web_apps = [
2
    'synnefo.aai',
3
    'synnefo.admin',
4
    'synnefo.api',
5
    'synnefo.ui',
6
    'synnefo.db',
7
    'synnefo.logic',
8
    'synnefo.invitations',
9
    'synnefo.helpdesk',
10
    'synnefo.plankton',
11
    'synnefo.ui.userdata',
12
]
2 13

  
3
def getapps():
4
    return INSTALLED_APPS
14
synnefo_web_middleware = [
15
    {'after': 'django.middleware.locale.LocaleMiddleware', 'insert': [
16
        'synnefo.aai.middleware.SynnefoAuthMiddleware',
17
        'synnefo.api.middleware.ApiAuthMiddleware',
18
        'synnefo.helpdesk.middleware.HelpdeskMiddleware'
19
        ]
20
    }
21
]
b/snf-app/synnefo/app_settings/default/__init__.py
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34
from synnefo.app_settings.default.admins import *
35
from synnefo.app_settings.default.apps import *
36
from synnefo.app_settings.default.deploy import *
37
from synnefo.app_settings.default.logging import *
38
from synnefo.app_settings.default.site import *
39 34
from synnefo.app_settings.default.backend import *
40
from synnefo.app_settings.default.database import *
41 35
from synnefo.app_settings.default.queues import *
42 36
from synnefo.app_settings.default.api import *
43 37
from synnefo.app_settings.default.plankton import *
b/snf-app/synnefo/app_settings/default/aai.py
1 1
# -*- coding: utf-8 -*-
2
from synnefo.util.entry_points import extend_list_from_entry_point
2 3
#
3 4
# AAI configuration
4 5
#####################
......
23 24

  
24 25
# Urls that bypass Shibboleth authentication
25 26
AAI_SKIP_AUTH_URLS = ['/api', '/plankton', '/invitations/login']
27
AAI_SKIP_AUTH_URLS = extend_list_from_entry_point(AAI_SKIP_AUTH_URLS, \
28
        'synnefo', 'web_skip_urls')
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Admin names and email addresses
4
##################################
5

  
6
ADMINS = (
7
    # ('Your Name', 'your_email@domain.com'),
8
)
9

  
10
MANAGERS = ADMINS
11

  
12
# Email configuration
13
EMAIL_HOST = "127.0.0.1"
14
EMAIL_HOST_USER = ""
15
EMAIL_HOST_PASSWORD = ""
16
EMAIL_SUBJECT_PREFIX = "[email-subject-prefix] "
17
DEFAULT_CHARSET = 'utf-8'
18

  
19
# Address to use for outgoing emails
20
DEFAULT_FROM_EMAIL = "~okeanos <no-reply@grnet.gr>"
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Core Django settings
4
##################################
5

  
6
INSTALLED_APPS = (
7
    'django.contrib.contenttypes',
8
    'django.contrib.sessions',
9
    'django.contrib.sites',
10
    'django.contrib.messages',
11
    'django.contrib.admin',
12
    'synnefo.aai',
13
    'synnefo.admin',
14
    'synnefo.api',
15
    'synnefo.ui',
16
    'synnefo.db',
17
    'synnefo.logic',
18
    'synnefo.invitations',
19
    'synnefo.helpdesk',
20
    'synnefo.plankton',
21
    'synnefo.ui.userdata',
22
    'south'
23
)
24

  
25
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
26

  
27
# List of callables that know how to import templates from various sources.
28
TEMPLATE_LOADERS = (
29
    'django.template.loaders.filesystem.Loader',
30
    'django.template.loaders.app_directories.Loader',
31
#     'django.template.loaders.eggs.Loader',
32
)
33

  
34
TEMPLATE_CONTEXT_PROCESSORS = (
35
    'django.core.context_processors.request',
36
    'django.core.context_processors.i18n',
37
    'django.contrib.auth.context_processors.auth',
38
    'django.core.context_processors.media'
39
)
40

  
41
MIDDLEWARE_CLASSES = (
42
    'django.contrib.sessions.middleware.SessionMiddleware',
43
    'synnefo.aai.middleware.SynnefoAuthMiddleware',
44
    'synnefo.api.middleware.ApiAuthMiddleware',
45
    'synnefo.helpdesk.middleware.HelpdeskMiddleware',
46
    'django.middleware.locale.LocaleMiddleware',
47
    'django.middleware.common.CommonMiddleware',
48
    'django.contrib.messages.middleware.MessageMiddleware'
49
)
50

  
51
ROOT_URLCONF = 'synnefo.urls'
52

  
53
TEMPLATE_DIRS = (
54
    # Put strings here, like "/home/html/django_templates"
55
    # or "C:/www/django/templates".
56
    # Always use forward slashes, even on Windows.
57
    # Don't forget to use absolute paths, not relative paths.
58
)
59

  
60
LANGUAGES = (
61
  #('el', u'Ελληνικά'),
62
  ('en', 'English'),
63
)
64

  
65
# Local time zone for this installation. Choices can be found here:
66
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
67
# although not all choices may be available on all operating systems.
68
# On Unix systems, a value of None will cause Django to use the same
69
# timezone as the operating system.
70
# If running in a Windows environment this must be set to the same as your
71
# system time zone.
72
TIME_ZONE = 'UTC'   # Warning: The API depends on the TIME_ZONE being UTC
73

  
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Database settings
4
####################
5

  
6
import os
7

  
8
DEFAULT_DB_PATH = '/usr/share/synnefo/'
9
DATABASES = {
10
    'default': {
11
        # 'postgresql_psycopg2', 'postgresql','mysql', 'sqlite3' or 'oracle'
12
        'ENGINE': 'sqlite3',
13
         # ATTENTION: This *must* be the absolute path if using sqlite3.
14
         # See: http://docs.djangoproject.com/en/dev/ref/settings/#name
15
        'NAME': os.path.join(DEFAULT_DB_PATH, 'database.sqlite'),
16
        'USER': '',                      # Not used with sqlite3.
17
        'PASSWORD': '',                  # Not used with sqlite3.
18
        # Set to empty string for localhost. Not used with sqlite3.
19
        'HOST': '',
20
        # Set to empty string for default. Not used with sqlite3.
21
        'PORT': '',
22
    }
23
}
24

  
25
if DATABASES['default']['ENGINE'].endswith('mysql'):
26
    DATABASES['default']['OPTIONS'] = {
27
            'init_command': 'SET storage_engine=INNODB; ' +
28
                'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
29
    }
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Deployment
4
##################################
5

  
6
DEBUG = True
7
TEMPLATE_DEBUG = DEBUG
8

  
9
# Top-level URL for deployment. Numerous other URLs depend on this.
10
APP_INSTALL_URL = "https://host:port"
11

  
12
# Make this unique, and don't share it with anybody.
13
SECRET_KEY = 'ly6)mw6a7x%n)-e#zzk4jo6f2=uqu!1o%)2-(7lo+f9yd^k^bg'
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Logging configuration
4
##################################
5

  
6
LOGGING = {
7
    'version': 1,
8
    'disable_existing_loggers': True,
9
    
10
    'formatters': {
11
        'simple': {
12
            'format': '%(message)s'
13
        },
14
        'verbose': {
15
            'format': '%(asctime)s [%(levelname)s] %(message)s'
16
        },
17
        'django': {
18
            'format': '[%(asctime)s] %(levelname)s %(message)s',
19
            'datefmt': '%d/%b/%Y %H:%M:%S'
20
        },
21
    },
22
    
23
    'handlers': {
24
        'null': {
25
            'class': 'logging.NullHandler',
26
        },
27
        'console': {
28
            'class': 'logging.StreamHandler',
29
            'formatter': 'django'
30
        },
31
        'syslog': {
32
            'class': 'logging.handlers.SysLogHandler',
33
            'address': '/dev/log',
34
#            'address': ('localhost', 514),
35
            'facility': 'daemon',
36
            'formatter': 'verbose',
37
            'level': 'INFO',
38
        },
39
    },
40
    
41
    'loggers': {
42
        'synnefo': {
43
            'handlers': ['syslog'],
44
            'level': 'INFO'
45
        },
46
        'synnefo.admin': {
47
            'level': 'INFO',
48
            'propagate': 1
49
        },
50
        'synnefo.api': {
51
            'level': 'INFO',
52
            'propagate': 1
53
        },
54
        'synnefo.db': {
55
            'level': 'INFO',
56
            'propagate': 1
57
        },
58
        'synnefo.logic': {
59
            'level': 'INFO',
60
            'propagate': 1
61
        },
62
    }    
63
}
64

  
65

  
66
DISPATCHER_LOGGING = {
67
    'version': 1,
68
    'disable_existing_loggers': True,
69
    
70
    'formatters': {
71
        'verbose': {
72
            'format': '%(asctime)s [%(levelname)s] %(message)s'
73
        },
74
    },
75
    
76
    'handlers': {
77
        'console': {
78
            'class': 'logging.StreamHandler',
79
            'formatter': 'verbose'
80
        },
81
        'file': {
82
            'class': 'logging.handlers.WatchedFileHandler',
83
            'filename': '/var/log/synnefo/dispatcher.log',
84
            'formatter': 'verbose',
85
            'level': 'DEBUG'
86
        },
87
    },
88
    
89
    'loggers': {
90
        'synnefo': {'propagate': 1}
91
    },
92
    
93
    'root': {
94
        'handlers': ['console', 'file'],
95
        'level': 'DEBUG',
96
    }
97
}
98

  
99

  
100
SNFADMIN_LOGGING = {
101
    'version': 1,
102
    'disable_existing_loggers': True,
103
    
104
    'formatters': {
105
        'verbose': {
106
            'format': '%(asctime)s [%(levelname)s] %(message)s'
107
        },
108
    },
109
    
110
    'handlers': {
111
        'console': {
112
            'class': 'logging.StreamHandler',
113
            'formatter': 'verbose'
114
        },
115
    },
116
    
117
    'loggers': {
118
        'synnefo': {'propagate': 1}
119
    },
120
    
121
    'root': {
122
        'handlers': ['console'],
123
        'level': 'DEBUG',
124
    }
125
}
/dev/null
1
# -*- coding: utf-8 -*-
2
#
3
# Site-specific Django conf
4
##################################
5

  
6
# Language code for this installation. All choices can be found here:
7
# http://www.i18nguy.com/unicode/language-identifiers.html
8
LANGUAGE_CODE = 'en-us'
9

  
10
# FIXME?
11
SITE_ID = 1
12

  
13
# If you set this to False, Django will make some optimizations so as not
14
# to load the internationalization machinery.
15
USE_I18N = True
16

  
17
# If you set this to False, Django will not format dates, numbers and
18
# calendars according to the current locale
19
USE_L10N = True
20

  
21
# Absolute path to the directory that holds media.
22
# Example: "/home/media/media.lawrence.com/"
23
MEDIA_ROOT = ''
24

  
25
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
26
# trailing slash if there is a path component (optional in other cases).
27
# Examples: "http://media.lawrence.com", "http://example.com/media/"
28
MEDIA_URL = '/static/'
29

  
30
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
31
# trailing slash.
32
# Examples: "http://foo.com/media/", "/media/".
33
ADMIN_MEDIA_PREFIX = '/media/'
34

  
35
# app/directory static files map, used by link_static command to create
36
# appropriate symlinks for static files
37
STATIC_FILES = {
38
    'synnefo.ui': '',
39
    'synnefo.admin': 'admin',
40
}
b/snf-app/synnefo/app_settings/default/ui.py
3 3
# UI settings
4 4
###################
5 5

  
6
from admins import *
7
from site import *
6
from synnefo.webproject.settings.default.site import *
7
from synnefo.settings.default.admins import *
8 8

  
9 9
# base url for ui static files
10 10
# if not set, defaults to MEDIA_URL + 'snf-<latest_ui_version>/'
11
UI_MEDIA_URL = MEDIA_URL + 'snf/'
11
UI_MEDIA_URL = '/ui/static/' + 'snf/'
12 12

  
13 13
# UI requests to the API layer time out after that many milliseconds
14 14
TIMEOUT = 10 * 1000
b/snf-app/synnefo/app_settings/urls.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
from django.conf.urls.defaults import *
35

  
36
urlpatterns = patterns('',
37
    (r'^ui/', include('synnefo.ui.urls')),
38
    (r'^admin/', include('synnefo.admin.urls')),
39
    (r'^api/', include('synnefo.api.urls')),
40
    (r'^helpdesk/?', include('synnefo.helpdesk.urls')),
41
    (r'^plankton/', include('synnefo.plankton.urls')),
42
    (r'^invitations/?', include('synnefo.invitations.urls')),
43
)
44

  
/dev/null
1
#!/usr/bin/env python
2

  
3
from django.core.management import ManagementUtility, setup_environ, \
4
BaseCommand, LaxOptionParser, handle_default_options
5

  
6
from optparse import Option, make_option
7
from synnefo.version import get_dist_version
8

  
9
import sys
10
import os
11

  
12
class SynnefoManagementUtility(ManagementUtility):
13
    """
14
    Override django ManagementUtility to allow us provide a custom
15
    --settings-dir option for synnefo application.
16

  
17
    Most of the following code is a copy from django.core.management module
18
    """
19

  
20
    def execute(self):
21
        """
22
        Given the command-line arguments, this figures out which subcommand is
23
        being run, creates a parser appropriate to that command, and runs it.
24
        """
25

  
26
        # --settings-dir option
27
        # will remove it later to avoid django commands from raising errors
28
        option_list = BaseCommand.option_list + (
29
            make_option('--settings-dir',
30
                action='store',
31
                dest='settings_dir',
32
                default=None,
33
                help='Load *.conf files from directory as settings'),)
34

  
35
        # Preprocess options to extract --settings and --pythonpath.
36
        # These options could affect the commands that are available, so they
37
        # must be processed early.
38
        parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
39
                                 version=get_dist_version('snf-app'),
40
                                 option_list=option_list)
41
        self.autocomplete()
42
        try:
43
            options, args = parser.parse_args(self.argv)
44
            handle_default_options(options)
45
        except:
46
            pass # Ignore any option errors at this point.
47

  
48
        # user provides custom settings dir
49
        # set it as environmental variable and remove it from self.argv
50
        if options.settings_dir:
51
            os.environ['SYNNEFO_SETTINGS_DIR'] = options.settings_dir
52
            for arg in self.argv:
53
                if arg.startswith('--settings-dir'):
54
                    self.argv.remove(arg)
55

  
56
        try:
57
            subcommand = self.argv[1]
58
        except IndexError:
59
            subcommand = 'help' # Display help if no arguments were given.
60

  
61
        if subcommand == 'help':
62
            if len(args) > 2:
63
                self.fetch_command(args[2]).print_help(self.prog_name, args[2])
64
            else:
65
                parser.print_lax_help()
66
                sys.stdout.write(self.main_help_text() + '\n')
67
                sys.exit(1)
68
        # Special-cases: We want 'django-admin.py --version' and
69
        # 'django-admin.py --help' to work, for backwards compatibility.
70
        elif self.argv[1:] == ['--version']:
71
            # LaxOptionParser already takes care of printing the version.
72
            pass
73
        elif self.argv[1:] in (['--help'], ['-h']):
74
            parser.print_lax_help()
75
            sys.stdout.write(self.main_help_text() + '\n')
76
        else:
77
            self.fetch_command(subcommand).run_from_argv(self.argv)
78

  
79
def main():
80
    # no need to run setup_environ
81
    # we already know our project
82
    os.environ['DJANGO_SETTINGS_MODULE'] = os.environ.get('DJANGO_SETTINGS_MODULE',
83
                                                          'synnefo.settings')
84
    mu = SynnefoManagementUtility(sys.argv)
85
    mu.execute()
86

  
87
if __name__ == "__main__":
88
    main()
/dev/null
1
# vim: ts=4 sts=4 et ai sw=4 fileencoding=utf-8
2
#
3
# Copyright © 2010 Greek Research and Technology Network
4
#
5

  
6
import re
7

  
8
_strip_url_re = re.compile(r'^https?://[^/]+')
9

  
10
class StripURLMiddleware(object):
11
    """
12
    At least some Cloud Servers API clients tend to use full URLs as request
13
    paths, contrary to all RFCs.
14

  
15
    This is a) wrong, b) incompatible with Django's urlconf.
16

  
17
    This middleware attempts to strip such URLs so that the URL dispatcher can
18
    process it normally.
19

  
20
    It should be inserted as early as possible in MIDDLEWARE_CLASSES
21
    """
22

  
23
    def process_request(self, request):
24
        request.path = re.sub(_strip_url_re, '', request.path)
25
        request.path_info = re.sub(_strip_url_re, '', request.path_info)
/dev/null
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
from django.conf.urls.defaults import *
35

  
36

  
37
urlpatterns = patterns('',
38
    (r'^', include('synnefo.ui.urls')),
39
    (r'^admin', include('synnefo.admin.urls')),
40
    (r'^api/', include('synnefo.api.urls')),
41
    (r'^helpdesk/?', include('synnefo.helpdesk.urls')),
42
    (r'^plankton/', include('synnefo.plankton.urls')),
43
    (r'^invitations/?', include('synnefo.invitations.urls')),
44
    (r'^lang/$', 'synnefo.ui.i18n.set_language')
45
)
b/snf-common/synnefo/settings/__init__.py
42 42
from synnefo.settings.default import *
43 43

  
44 44
# autodetect default settings provided by synnefo applications
45
extend_settings('synnefo', __name__)
45
extend_settings(__name__, 'synnefo')
46 46

  
47 47
# extend default settings with settings provided within *.conf user files
48 48
# located in directory specified in the SYNNEFO_SETTINGS_DIR
......
55 55
        try:
56 56
            execfile(os.path.abspath(f))
57 57
        except Exception as e:
58
            print >>sys.stderr, "Failed to read settings file: %s" % \
59
                                os.path.abspath(f)
58
            print >>sys.stderr, "Failed to read settings file: %s [%s]" % \
59
                                (os.path.abspath(f), e)
60 60

  
61 61

  
b/snf-common/synnefo/settings/default/__init__.py
1
from synnefo.settings.default.admins import *
2
from synnefo.settings.default.logging import *
3
from synnefo.settings.default.database import *
4

  
b/snf-common/synnefo/settings/default/admins.py
1
# -*- coding: utf-8 -*-
2
#
3
# Admin names and email addresses
4
##################################
5

  
6
ADMINS = (
7
    # ('Your Name', 'your_email@domain.com'),
8
)
9

  
10
MANAGERS = ADMINS
11

  
12
# Email configuration
13
EMAIL_HOST = "127.0.0.1"
14
EMAIL_HOST_USER = ""
15
EMAIL_HOST_PASSWORD = ""
16
EMAIL_SUBJECT_PREFIX = "[email-subject-prefix] "
17
DEFAULT_CHARSET = 'utf-8'
18

  
19
# Address to use for outgoing emails
20
DEFAULT_FROM_EMAIL = "~okeanos <no-reply@grnet.gr>"
b/snf-common/synnefo/settings/default/database.py
1
# -*- coding: utf-8 -*-
2
#
3
# Database settings
4
####################
5

  
6
import os
7

  
8
DEFAULT_DB_PATH = '/usr/share/synnefo/'
9
DATABASES = {
10
    'default': {
11
        # 'postgresql_psycopg2', 'postgresql','mysql', 'sqlite3' or 'oracle'
12
        'ENGINE': 'sqlite3',
13
         # ATTENTION: This *must* be the absolute path if using sqlite3.
14
         # See: http://docs.djangoproject.com/en/dev/ref/settings/#name
15
        'NAME': os.path.join(DEFAULT_DB_PATH, 'database.sqlite'),
16
        'USER': '',                      # Not used with sqlite3.
17
        'PASSWORD': '',                  # Not used with sqlite3.
18
        # Set to empty string for localhost. Not used with sqlite3.
19
        'HOST': '',
20
        # Set to empty string for default. Not used with sqlite3.
21
        'PORT': '',
22
    }
23
}
24

  
25
if DATABASES['default']['ENGINE'].endswith('mysql'):
26
    DATABASES['default']['OPTIONS'] = {
27
            'init_command': 'SET storage_engine=INNODB; ' +
28
                'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
29
    }
b/snf-common/synnefo/settings/default/logging.py
1
# -*- coding: utf-8 -*-
2
#
3
# Logging configuration
4
##################################
5

  
6
LOGGING = {
7
    'version': 1,
8
    'disable_existing_loggers': True,
9
    
10
    'formatters': {
11
        'simple': {
12
            'format': '%(message)s'
13
        },
14
        'verbose': {
15
            'format': '%(asctime)s [%(levelname)s] %(message)s'
16
        },
17
        'django': {
18
            'format': '[%(asctime)s] %(levelname)s %(message)s',
19
            'datefmt': '%d/%b/%Y %H:%M:%S'
20
        },
21
    },
22
    
23
    'handlers': {
24
        'null': {
25
            'class': 'logging.NullHandler',
26
        },
27
        'console': {
28
            'class': 'logging.StreamHandler',
29
            'formatter': 'django'
30
        },
31
        'syslog': {
32
            'class': 'logging.handlers.SysLogHandler',
33
            'address': '/dev/log',
34
#            'address': ('localhost', 514),
35
            'facility': 'daemon',
36
            'formatter': 'verbose',
37
            'level': 'INFO',
38
        },
39
    },
40
    
41
    'loggers': {
42
        'synnefo': {
43
            'handlers': ['syslog'],
44
            'level': 'INFO'
45
        },
46
        'synnefo.admin': {
47
            'level': 'INFO',
48
            'propagate': 1
49
        },
50
        'synnefo.api': {
51
            'level': 'INFO',
52
            'propagate': 1
53
        },
54
        'synnefo.db': {
55
            'level': 'INFO',
56
            'propagate': 1
57
        },
58
        'synnefo.logic': {
59
            'level': 'INFO',
60
            'propagate': 1
61
        },
62
    }    
63
}
64

  
65

  
66
DISPATCHER_LOGGING = {
67
    'version': 1,
68
    'disable_existing_loggers': True,
69
    
70
    'formatters': {
71
        'verbose': {
72
            'format': '%(asctime)s [%(levelname)s] %(message)s'
73
        },
74
    },
75
    
76
    'handlers': {
77
        'console': {
78
            'class': 'logging.StreamHandler',
79
            'formatter': 'verbose'
80
        },
81
        'file': {
82
            'class': 'logging.handlers.WatchedFileHandler',
83
            'filename': '/var/log/synnefo/dispatcher.log',
84
            'formatter': 'verbose',
85
            'level': 'DEBUG'
86
        },
87
    },
88
    
89
    'loggers': {
90
        'synnefo': {'propagate': 1}
91
    },
92
    
93
    'root': {
94
        'handlers': ['console', 'file'],
95
        'level': 'DEBUG',
96
    }
97
}
98

  
99

  
100
SNFADMIN_LOGGING = {
101
    'version': 1,
102
    'disable_existing_loggers': True,
103
    
104
    'formatters': {
105
        'verbose': {
106
            'format': '%(asctime)s [%(levelname)s] %(message)s'
107
        },
108
    },
109
    
110
    'handlers': {
111
        'console': {
112
            'class': 'logging.StreamHandler',
113
            'formatter': 'verbose'
114
        },
115
    },
116
    
117
    'loggers': {
118
        'synnefo': {'propagate': 1}
119
    },
120
    
121
    'root': {
122
        'handlers': ['console'],
123
        'level': 'DEBUG',
124
    }
125
}
b/snf-common/synnefo/util/entry_points.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
1 34
import sys
2 35
import pkg_resources
3 36
import inspect
37
import types
4 38

  
5 39

  
6
def get_entry_ponts(ns, name):
40
def get_entry_points(ns, name):
7 41
    for entry_point in pkg_resources.iter_entry_points(group=ns):
8 42
        if entry_point.name == name:
9 43
            yield entry_point
10 44

  
11 45

  
12
def extend_settings(ns, module_name):
46
def extend_module(module_name, attrs):
47
    module = sys.modules[module_name]
48
    for k,v in attrs.iteritems():
49
        setattr(module, k, v)
50

  
51

  
52
def entry_point_to_object(ep):
53
    object_or_func = ep.load()
54

  
55
    # user defined entry point is a function
56
    # get the return value
57
    obj = object_or_func
58
    if hasattr(object_or_func, '__call__'):
59
        obj = object_or_func()
60

  
61
    if type(obj) == types.ModuleType:
62
        dct = {}
63
        for k in dir(obj):
64
            if k.startswith("__"):
65
                continue
66
            dct[k] = getattr(obj, k)
67

  
68
        obj = dct
69

  
70
    return obj
71

  
72

  
73
def extend_module_from_entry_point(module_name, ns):
13 74
    """
14
    Extend module from entry_point hooks
75
    Extend a settings module from entry_point hooks
15 76
    """
16
    settings = sys.modules[module_name]
17
    # apps hook
18
    app_entry_points = get_entry_ponts(ns, 'apps')
19
    # settings hook
20
    settings_entry_points = get_entry_ponts(ns, 'settings')
21

  
22
    # extend INSTALLED_APPS setting
23
    NEW_INSTALLED_APPS = list(getattr(settings, 'INSTALLED_APPS', []));
24

  
25
    # if failed to execute app hook as function parse it as string
26
    # synnefo.app:get_additional_apps or app1,app2,app3
27
    for e in app_entry_points:
28
        try:
29
            NEW_INSTALLED_APPS = list(e.load()())
30
        except Exception, ex:
31
            NEW_INSTALLED_APPS = NEW_INSTALLED_APPS + \
32
                    e.module_name.split(",")
33

  
34
    # extend additional settings
35
    # TODO: existing settings logic ??
36
    for e in settings_entry_points:
37
        module = e.load()
38
        for k in dir(module):
39
            if k == k.upper():
40
                setattr(settings, k, getattr(module, k))
41

  
42
    setattr(settings, 'INSTALLED_APPS', NEW_INSTALLED_APPS)
77
    for e in get_entry_points(ns, 'default_settings'):
78
        extend_module(module_name, entry_point_to_object(e))
79

  
80

  
81
def extend_dict_from_entry_point(settings_object, ns, entry_point_name):
82
    for e in get_entry_points(ns, entry_point_name):
83
        settings_object.update(entry_point_to_object(e))
84

  
85
    return settings_object
86

  
87

  
88
def extend_list_from_entry_point(settings_object, ns, entry_point_name,
89
        unique=True):
90
    settings_object = list(settings_object)
91
    for e in get_entry_points(ns, entry_point_name):
92
        obj = entry_point_to_object(e)
93
        for row in obj:
94
            if type(row) == dict and (row.get('before', False) or \
95
                    row.get('after', False)):
96
                if row.get('before', False):
97
                    position = settings_object.index(row.get('before'))
98
                    insert_at = position - 1
99
                else:
100
                    position = settings_object.index(row.get('after'))
101
                    insert_at = position + 1
102

  
103
                if insert_at < 0:
104
                    insert_at = 0
105

  
106
                inserts = row.get('insert', [])
107
                if not type(inserts) == list:
108
                    inserts  = [inserts]
109

  
110
                for entry in inserts:
111
                    if not entry in settings_object:
112
                        settings_object.insert(insert_at, entry)
113
                        insert_at = insert_at + 1
114
            else:
115
                settings_object.append(row)
116

  
117
    return settings_object
118

  
119
def extend_settings(mname, ns):
120
    extend_module_from_entry_point(mname, ns)
121

  
122
def extend_urls(patterns, ns):
123
    for e in get_entry_points(ns, 'urls'):
124
        patterns += e.load()
125

  
126
    return patterns
43 127

  
b/snf-okeanos-site/okeanos_site/__init__.py
1
synnefo_web_apps = ['okeanos_site']
2
synnefo_static_files = {'okeanos_site': ''}
3
synnefo_skip_urls = ['/about', '/intro', '/okeanos_static']
b/snf-okeanos-site/okeanos_site/settings.py
1
# extend specific synnefo default settings
2
from synnefo.app_settings import *
3

  
4
# extend static files map
5
STATIC_FILES['okeanos_site'] = ''
6

  
7
# append okeanos_site application to django installed apps
8
INSTALLED_APPS = list(INSTALLED_APPS) + ['okeanos_site']
9

  
10
# invitations only, no login page exists
11
# redirect client to the intro page
12
LOGIN_URL = "http://okeanos.grnet.gr/intro"
13

  
14
# redirect to login url (intro) on user logout
15
LOGOUT_URL = LOGIN_URL
16

  
17
# bypass Shibboleth authentication for /okeanos and /intro pages
18
# (they should be available to the public)
19
AAI_SKIP_AUTH_URLS = list(AAI_SKIP_AUTH_URLS) + ['/about', '/intro', '/okeanos_static']
20

  
21
# change django url configuration
22
# okeanos_site.urls includes and extends/modifies synnefo.urls
23
# based on the needs of okeanos aplha release
24
ROOT_URLCONF = 'okeanos_site.urls'
25

  
26 1
# the url that is linked with okenaos_site.views.index view
27 2
OKEANOS_SITE_URL = "/about"
28 3

  
......
50 25
#
51 26
# flowplayer.controls swf should be placed on the same url as flowplayer swf
52 27
OKEANOS_VIDEO_FLOWPLAYER_URL = "http://okeanos.grnet.gr/intro_video/flowplayer-3.2.1.swf"
28

  
b/snf-okeanos-site/okeanos_site/urls.py
3 3
from django.conf.urls.defaults import *
4 4
from django.conf import settings
5 5

  
6
from synnefo.urls import urlpatterns as synnefo_urls
7

  
8 6
urlpatterns = patterns('',
9 7

  
10 8
    # change app url from root (/) to (/ui)
......
17 15

  
18 16
    # video/info page
19 17
    url(r'^about$', 'okeanos_site.views.index', name='okeanos_index'),
20

  
21 18
)
22 19

  
23

  
24
urlpatterns += synnefo_urls
25

  
26 20
urlpatterns += patterns('',
27 21
    url(r'^okeanos_static/(.*)$', 'django.views.static.serve',
28 22
    {'document_root': os.path.join(os.path.dirname(__file__), 'static/okeanos_static')}),
b/snf-okeanos-site/setup.py
62 62

  
63 63
    entry_points = {
64 64
        'synnefo': [
65
            'settings = okeanos_site.settings',
66
            'apps = okeanos_site'
65
            'default_settings = okeanos_site.settings',
66
            'web_apps = okeanos_site:synnefo_web_apps',
67
            'web_static = okeanos_site:synnefo_static_files',
68
            'urls = okeanos_site.urls:urlpatterns'
67 69
        ]
68 70
    },
69 71

  
b/snf-webproject/Changelog
1
Changelog
2
=========
b/snf-webproject/README
1
Synnefo web project
2
===================
3

  
4
A synnefo helper package to ease up the deployment of synnefo components.
5

  
6
The package wraps a django project which extends itself (urls, default_settings, 
7
installed_apps, middleware_classes) based on the synnefo components/packages 
8
installed on the system.
9

  
10
The extending mechanism is based on the python setuptools `entry_points`. So
11
if an application (synnefo component) wants to plug additional configuration
12
to the django project it should define within its setup.py file the 'synnefo'
13
appropriate entry_points.
14

  
15
For usage example please take a look how snf-app package defines its entry
16
points in:
17

  
18
    - snf-app/setup.py
19
    - snf-app/app_settings/__init__.py
20

  
b/snf-webproject/distribute_setup.py
1
#!python
2
"""Bootstrap distribute installation
3

  
4
If you want to use setuptools in your package's setup.py, just include this
5
file in the same directory with it, and add this to the top of your setup.py::
6

  
7
    from distribute_setup import use_setuptools
8
    use_setuptools()
9

  
10
If you want to require a specific version of setuptools, set a download
11
mirror, or use an alternate download directory, you can do so by supplying
12
the appropriate options to ``use_setuptools()``.
13

  
14
This file can also be run as a script to install or upgrade setuptools.
15
"""
16
import os
17
import sys
18
import time
19
import fnmatch
20
import tempfile
21
import tarfile
22
from distutils import log
23

  
24
try:
25
    from site import USER_SITE
26
except ImportError:
27
    USER_SITE = None
28

  
29
try:
30
    import subprocess
31

  
32
    def _python_cmd(*args):
33
        args = (sys.executable,) + args
34
        return subprocess.call(args) == 0
35

  
36
except ImportError:
37
    # will be used for python 2.3
38
    def _python_cmd(*args):
39
        args = (sys.executable,) + args
40
        # quoting arguments if windows
41
        if sys.platform == 'win32':
42
            def quote(arg):
43
                if ' ' in arg:
44
                    return '"%s"' % arg
45
                return arg
46
            args = [quote(arg) for arg in args]
47
        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
48

  
49
DEFAULT_VERSION = "0.6.10"
50
DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
51
SETUPTOOLS_FAKED_VERSION = "0.6c11"
52

  
53
SETUPTOOLS_PKG_INFO = """\
54
Metadata-Version: 1.0
55
Name: setuptools
56
Version: %s
57
Summary: xxxx
58
Home-page: xxx
59
Author: xxx
60
Author-email: xxx
61
License: xxx
62
Description: xxx
63
""" % SETUPTOOLS_FAKED_VERSION
64

  
65

  
66
def _install(tarball):
67
    # extracting the tarball
68
    tmpdir = tempfile.mkdtemp()
69
    log.warn('Extracting in %s', tmpdir)
70
    old_wd = os.getcwd()
71
    try:
72
        os.chdir(tmpdir)
73
        tar = tarfile.open(tarball)
74
        _extractall(tar)
75
        tar.close()
76

  
77
        # going in the directory
78
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
79
        os.chdir(subdir)
80
        log.warn('Now working in %s', subdir)
81

  
82
        # installing
83
        log.warn('Installing Distribute')
84
        if not _python_cmd('setup.py', 'install'):
85
            log.warn('Something went wrong during the installation.')
86
            log.warn('See the error message above.')
87
    finally:
88
        os.chdir(old_wd)
89

  
90

  
91
def _build_egg(egg, tarball, to_dir):
92
    # extracting the tarball
93
    tmpdir = tempfile.mkdtemp()
94
    log.warn('Extracting in %s', tmpdir)
95
    old_wd = os.getcwd()
96
    try:
97
        os.chdir(tmpdir)
98
        tar = tarfile.open(tarball)
99
        _extractall(tar)
100
        tar.close()
101

  
102
        # going in the directory
103
        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
104
        os.chdir(subdir)
105
        log.warn('Now working in %s', subdir)
106

  
107
        # building an egg
108
        log.warn('Building a Distribute egg in %s', to_dir)
109
        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
110

  
111
    finally:
112
        os.chdir(old_wd)
113
    # returning the result
114
    log.warn(egg)
115
    if not os.path.exists(egg):
116
        raise IOError('Could not build the egg.')
117

  
118

  
119
def _do_download(version, download_base, to_dir, download_delay):
120
    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
121
                       % (version, sys.version_info[0], sys.version_info[1]))
122
    if not os.path.exists(egg):
123
        tarball = download_setuptools(version, download_base,
124
                                      to_dir, download_delay)
125
        _build_egg(egg, tarball, to_dir)
126
    sys.path.insert(0, egg)
127
    import setuptools
128
    setuptools.bootstrap_install_from = egg
129

  
130

  
131
def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
132
                   to_dir=os.curdir, download_delay=15, no_fake=True):
133
    # making sure we use the absolute path
134
    to_dir = os.path.abspath(to_dir)
135
    was_imported = 'pkg_resources' in sys.modules or \
136
        'setuptools' in sys.modules
137
    try:
138
        try:
139
            import pkg_resources
140
            if not hasattr(pkg_resources, '_distribute'):
141
                if not no_fake:
142
                    _fake_setuptools()
143
                raise ImportError
144
        except ImportError:
145
            return _do_download(version, download_base, to_dir, download_delay)
146
        try:
147
            pkg_resources.require("distribute>="+version)
148
            return
149
        except pkg_resources.VersionConflict:
150
            e = sys.exc_info()[1]
151
            if was_imported:
152
                sys.stderr.write(
153
                "The required version of distribute (>=%s) is not available,\n"
154
                "and can't be installed while this script is running. Please\n"
155
                "install a more recent version first, using\n"
156
                "'easy_install -U distribute'."
157
                "\n\n(Currently using %r)\n" % (version, e.args[0]))
158
                sys.exit(2)
159
            else:
160
                del pkg_resources, sys.modules['pkg_resources']    # reload ok
161
                return _do_download(version, download_base, to_dir,
162
                                    download_delay)
163
        except pkg_resources.DistributionNotFound:
164
            return _do_download(version, download_base, to_dir,
165
                                download_delay)
166
    finally:
167
        if not no_fake:
168
            _create_fake_setuptools_pkg_info(to_dir)
169

  
170
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
171
                        to_dir=os.curdir, delay=15):
172
    """Download distribute from a specified location and return its filename
173

  
174
    `version` should be a valid distribute version number that is available
175
    as an egg for download under the `download_base` URL (which should end
176
    with a '/'). `to_dir` is the directory where the egg will be downloaded.
177
    `delay` is the number of seconds to pause before an actual download
178
    attempt.
179
    """
180
    # making sure we use the absolute path
181
    to_dir = os.path.abspath(to_dir)
182
    try:
183
        from urllib.request import urlopen
184
    except ImportError:
185
        from urllib2 import urlopen
186
    tgz_name = "distribute-%s.tar.gz" % version
187
    url = download_base + tgz_name
188
    saveto = os.path.join(to_dir, tgz_name)
189
    src = dst = None
190
    if not os.path.exists(saveto):  # Avoid repeated downloads
191
        try:
192
            log.warn("Downloading %s", url)
193
            src = urlopen(url)
194
            # Read/write all in one block, so we don't create a corrupt file
195
            # if the download is interrupted.
196
            data = src.read()
197
            dst = open(saveto, "wb")
198
            dst.write(data)
199
        finally:
200
            if src:
201
                src.close()
202
            if dst:
203
                dst.close()
204
    return os.path.realpath(saveto)
205

  
206
def _no_sandbox(function):
207
    def __no_sandbox(*args, **kw):
208
        try:
209
            from setuptools.sandbox import DirectorySandbox
210
            if not hasattr(DirectorySandbox, '_old'):
211
                def violation(*args):
212
                    pass
213
                DirectorySandbox._old = DirectorySandbox._violation
214
                DirectorySandbox._violation = violation
215
                patched = True
216
            else:
217
                patched = False
218
        except ImportError:
219
            patched = False
220

  
221
        try:
222
            return function(*args, **kw)
223
        finally:
224
            if patched:
225
                DirectorySandbox._violation = DirectorySandbox._old
226
                del DirectorySandbox._old
227

  
228
    return __no_sandbox
229

  
230
def _patch_file(path, content):
231
    """Will backup the file then patch it"""
232
    existing_content = open(path).read()
233
    if existing_content == content:
234
        # already patched
235
        log.warn('Already patched.')
236
        return False
237
    log.warn('Patching...')
238
    _rename_path(path)
239
    f = open(path, 'w')
240
    try:
241
        f.write(content)
242
    finally:
243
        f.close()
244
    return True
245

  
246
_patch_file = _no_sandbox(_patch_file)
247

  
248
def _same_content(path, content):
249
    return open(path).read() == content
250

  
251
def _rename_path(path):
252
    new_name = path + '.OLD.%s' % time.time()
253
    log.warn('Renaming %s into %s', path, new_name)
254
    os.rename(path, new_name)
255
    return new_name
256

  
257
def _remove_flat_installation(placeholder):
258
    if not os.path.isdir(placeholder):
259
        log.warn('Unkown installation at %s', placeholder)
260
        return False
261
    found = False
262
    for file in os.listdir(placeholder):
263
        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
264
            found = True
265
            break
266
    if not found:
267
        log.warn('Could not locate setuptools*.egg-info')
268
        return
269

  
270
    log.warn('Removing elements out of the way...')
271
    pkg_info = os.path.join(placeholder, file)
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff