Revision 4f78c22c

b/snf-astakos-app/Changelog
6 6
- Setting ASTAKOS_DEFAULT_ADMIN_EMAIL has been deprecated. Use ADMINS django setting instead.
7 7
- Setting ASTAKOS_DEFAULT_FROM_EMAIL has been deprecated. Use SERVER_EMAIL django setting instead.
8 8

  
9
0.7.3
10
^^^^
9
v0.7.5
10
^^^^^^
11
- Include user email in registered/activated notification mails subject
12

  
13
v0.7.4
14
^^^^^^
15
- Configurable subjects for all emails send by astakos app. Introduced settings
16
	* ASTAKOS_INVITATION_EMAIL_SUBJECT
17
	* ASTAKOS_GREETING_EMAIL_SUBJECT
18
	* ASTAKOS_FEEDBACK_EMAIL_SUBJECT
19
	* ASTAKOS_VERIFICATION_EMAIL_SUBJECT
20
	* ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT
21
	* ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT
22
	* ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT
23
	* ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT
24

  
25

  
26
v0.7.3
27
^^^^^^
28
- Use https for google webfonts
29
- Fix anonymoususer logout
30

  
31
v0.7.1
32
^^^^^^
33
- ASTAKOS_*_MESSAGES settings changed from dict to tuple lists
34
- Theme changes (new colors, new font)
35

  
36
v0.7.0
37
^^^^^^
11 38
- Rename management commands
12 39
- Optionally renew token on password change
13 40
- Preserve local password for users switched to shibboleth
14
- Send notification to DEFAULT_CONTACT_EMAIL on account activation
41
- Send notification to ASTAKOS_DEFAULT_CONTACT_EMAIL on account activation
15 42
- Fix unusable password issue
16 43
- Extend user_update command by enabling provider modification and password renewal
17 44
- Check for email absence before querying the database for retrieving the user in get menu call
18 45
- Set is_verified in profile view even if the user do not post the form
46
- New html/css theme
47
- Database updated.
48
  Use::
49
  	
50
	$ snf-manage syncdb
51
	$ snf-manage migrate
52

  
53
  to migrate your database.
19 54

  
20 55
v0.6.2
21 56
^^^^^^
b/snf-astakos-app/README
108 108

  
109 109
To update user credibility from the billing system (Aquarium), enable the queue, install snf-pithos-tools and use ``pithos-dispatcher``::
110 110

  
111
    pithos-dispatcher --exchange=aquarium --callback=astakos.im.endpoints.aquarium.consumer.on_creditevent
111
    pithos-dispatcher --exchange=aquarium --callback=astakos.im.endpoints.aquarium.consumer.on_creditevent
b/snf-astakos-app/astakos/im/context_processors.py
62 62

  
63 63

  
64 64
def custom_messages(request):
65
    EXTRA_MESSAGES_SET = bool(GLOBAL_MESSAGES or SIGNUP_MESSAGES or
66
                              LOGIN_MESSAGES or PROFILE_MESSAGES)
65
    global GLOBAL_MESSAGES, SIGNUP_MESSAGES, LOGIN_MESSAGES, PROFILE_MESSAGES
66

  
67
    # keep backwards compatibility with dict settings
68
    if type(GLOBAL_MESSAGES) == dict:
69
        GLOBAL_MESSAGES = GLOBAL_MESSAGES.items()
70
    if type(SIGNUP_MESSAGES) == dict:
71
        SIGNUP_MESSAGES = SIGNUP_MESSAGES.items()
72
    if type(LOGIN_MESSAGES) == dict:
73
        LOGIN_MESSAGES = LOGIN_MESSAGES.items()
74
    if type(PROFILE_MESSAGES) == dict:
75
        PROFILE_MESSAGES = PROFILE_MESSAGES.items()
76

  
77
    EXTRA_MESSAGES_SET = bool(GLOBAL_MESSAGES or SIGNUP_MESSAGES or \
78
            LOGIN_MESSAGES or PROFILE_MESSAGES)
79

  
67 80
    return {
68 81
        'GLOBAL_MESSAGES': GLOBAL_MESSAGES,
69 82
        'SIGNUP_MESSAGES': SIGNUP_MESSAGES,
b/snf-astakos-app/astakos/im/forms.py
55 55
                                 RECAPTCHA_PRIVATE_KEY, RECAPTCHA_ENABLED, DEFAULT_CONTACT_EMAIL,
56 56
                                 LOGGING_LEVEL
57 57
                                 )
58

  
58 59
from astakos.im.widgets import DummyWidget, RecaptchaWidget
59 60
from astakos.im.functions import send_change_email
60 61

  
......
176 177
        ro = ('email', 'username',)
177 178
        for f in ro:
178 179
            self.fields[f].widget.attrs['readonly'] = True
179

  
180
    
180 181
    def save(self, commit=True):
181 182
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
182 183
        level = user.invitation.inviter.level + 1
......
193 194
        model = AstakosUser
194 195
        fields = ("email", "first_name", "last_name",
195 196
                  "third_party_identifier", "has_signed_terms")
196

  
197
    
197 198
    def __init__(self, *args, **kwargs):
198 199
        """
199 200
        Changes the order of fields, and removes the username field.
......
218 219
                % (reverse('latest_terms'), _("the terms"))
219 220
            self.fields['has_signed_terms'].label = \
220 221
                mark_safe("I agree with %s" % terms_link_html)
221

  
222
    
222 223
    def clean_email(self):
223 224
        email = self.cleaned_data['email']
224 225
        if not email:
......
273 274
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
274 275
    additional_email = forms.CharField(
275 276
        widget=forms.HiddenInput(), label='', required=False)
276

  
277
    
277 278
    def __init__(self, *args, **kwargs):
278 279
        super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
279 280
        self.fields.keyOrder.append('additional_email')
......
282 283
        field = self.fields[name]
283 284
        self.initial['additional_email'] = self.initial.get(name,
284 285
                                                            field.initial)
285

  
286
    
286 287
    def clean_email(self):
287 288
        email = self.cleaned_data['email']
288 289
        for user in AstakosUser.objects.filter(email=email):
......
304 305
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
305 306
    recaptcha_response_field = forms.CharField(
306 307
        widget=RecaptchaWidget, label='')
307

  
308
    
308 309
    def __init__(self, *args, **kwargs):
309 310
        was_limited = kwargs.get('was_limited', False)
310 311
        request = kwargs.get('request', None)
......
322 323
        if was_limited and RECAPTCHA_ENABLED:
323 324
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
324 325
                                         'recaptcha_response_field', ])
325

  
326
    
326 327
    def clean_recaptcha_response_field(self):
327 328
        if 'recaptcha_challenge_field' in self.cleaned_data:
328 329
            self.validate_captcha()
......
340 341
        if not check.is_valid:
341 342
            raise forms.ValidationError(
342 343
                _('You have not entered the correct words'))
343

  
344
    
344 345
    def clean(self):
345 346
        super(LoginForm, self).clean()
346 347
        if self.user_cache and self.user_cache.provider not in ('local', ''):
b/snf-astakos-app/astakos/im/functions.py
195 195

  
196 196
    Raises SMTPException, socket.error
197 197
    """
198
    subject = _('Welcome to %s alpha2 testing' % SITENAME)
198
    subject = _(GREETING_EMAIL_SUBJECT)
199 199
    message = render_to_string(email_template_name, {
200 200
                               'user': user,
201 201
                               'url': urljoin(BASEURL, reverse('index')),
......
214 214

  
215 215

  
216 216
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
217
    subject = _("Feedback from %s alpha2 testing" % SITENAME)
217
    subject = _(FEEDBACK_EMAIL_SUBJECT)
218 218
    from_email = user.email
219 219
    recipient_list = [DEFAULT_CONTACT_EMAIL]
220 220
    content = render_to_string(email_template_name, {
b/snf-astakos-app/astakos/im/settings.py
69 69

  
70 70
# Messages to display on login page header
71 71
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
72
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', {})
72
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', [])
73 73

  
74 74
# Messages to display on login page header
75 75
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
76
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', {})
76
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', [])
77 77

  
78 78
# Messages to display on login page header
79 79
# e.g. {'warning': 'This warning message will be displayed on the top of profile page'}
80
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', {})
80
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', [])
81 81

  
82 82
# Messages to display on all pages
83 83
# e.g. {'warning': 'This warning message will be displayed on the top of every page'}
84
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', {})
84
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', [])
85 85

  
86 86
# messages to display as extra actions in account forms
87 87
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
......
107 107

  
108 108
# Set the billing URI
109 109
AQUARIUM_URL = getattr(settings, 'ASTAKOS_AQUARIUM_URL', '')
110

  
111
# Configurable email subjects
112
INVITATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_INVITATION_EMAIL_SUBJECT',
113
        'Invitation to %s alpha2 testing' % SITENAME)
114
GREETING_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_GREETING_EMAIL_SUBJECT',
115
        'Welcome to %s alpha2 testing' % SITENAME)
116
FEEDBACK_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_FEEDBACK_EMAIL_SUBJECT',
117
        'Feedback from %s alpha2 testing' % SITENAME)
118
VERIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_VERIFICATION_EMAIL_SUBJECT',
119
        '%s alpha2 testing account activation is needed' % SITENAME)
120
ADMIN_NOTIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT',
121
        '%s alpha2 testing account created (%%(user)s)' % SITENAME)
122
HELPDESK_NOTIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT',
123
        '%s alpha2 testing account activated (%%(user)s)' % SITENAME)
124
EMAIL_CHANGE_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT',
125
        'Email change on %s alpha2 testing' % SITENAME)
126
PASSWORD_RESET_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT',
127
        'Password reset on %s alpha2 testing' % SITENAME)
b/snf-astakos-app/astakos/im/static/im/cloudbar/README.rst
48 48

  
49 49
.. codeblock:: javascript
50 50
    
51
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
51
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
52 52
    <script>
53 53
        var CLOUDBAR_COOKIE_NAME = '_pithos2_a';
54 54
        var CLOUDBAR_ACTIVE_SERVICE = 'cloud';
55
        var CLOUDBAR_LOCATION = "http://accounts.cloud.grnet.gr/cloudbar/";
55
        var CLOUDBAR_LOCATION = "https://accounts.cloud.grnet.gr/cloudbar/";
56 56

  
57 57
        $(document).ready(function(){
58 58
            $.getScript(CLOUDBAR_LOC + 'cloudbar.js');
b/snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.js
44 44
    }
45 45

  
46 46
    var root = $('body');
47
    var bar = $('<div class="cloudbar clearfix"></div>');
47
    var bar = $('<div class="cloudbar servicesbar clearfix"></div>');
48 48
    var services = $('<ul class="services"></ul>');
49 49
    var profile = $('<div class="profile"></div>');
50 50
    
b/snf-astakos-app/astakos/im/static/im/css/modules.css
30 30
.top-msg +.mainlogo                             { margin-top:-73px;}
31 31
.top-msg .close                                 { position:absolute; bottom:20px; right:20px; font-size:1.3em; font-weight:bold; border:0 none; color:#fff; text-decoration:none;}
32 32
.top-msg .close:hover                           { color:#000;}
33
.top-msg.success                             	{ background-color:#77C596; color: #fff}
34
.top-msg.error                              	{ background-color:#EF4F54; color: #fff}
35
.top-msg.warning                                { background-color:#F6921E; color: #fff}
36
.top-msg.info                                 	{ background-color:#C3C3B9; color: #fff}
37
.top-msg.warning a                              { color: #3582AC}
38
.top-msg.info a                                 { color: #222}
33 39

  
34 40
/* container */
35 41
.container .wrapper                             { padding-bottom:100px;}
......
317 323
.billing .resource-cat-2.filter-item a:hover	{ color:#4085A5 }
318 324

  
319 325
.table_sorting tr th							{ cursor:pointer; }
326

  
320 327
.table_sorting tr th:hover						{ text-decoration:underline }
321 328

  
322 329
table.alt-style tr.tr1 td,
......
330 337
table.alt-style tr td a.open					{ background-position:-16px 0} 
331 338

  
332 339
.projects .details a.edit						{ float:right; }
333
.projects .editable form textarea				{ width:70%; height:50px; max-width:70%;}

340
.projects .editable form textarea				{ width:70%; height:50px; max-width:70%;}
b/snf-astakos-app/astakos/im/static/im/js/common.js
116 116
	$('select').dropkick();
117 117
 
118 118
    
119
    $('.top-msg .success').parents('.top-msg').css(
120
    	{
121
    		backgroundColor: '#77C596',
122
    		color: '#fff'
123
    	}
124
    );
125
    
126
    $('.top-msg .error').parents('.top-msg').css(
127
    	{
128
    		backgroundColor: '#EF4F54',
129
    		color: '#fff'
130
    	}
131
    );
132
    
133
    
134
    $('.top-msg .warning').parents('.top-msg').css(
135
    	{
136
    		backgroundColor: '#F6921E',
137
    		color: '#fff'
138
    	}
139
    );
140
    
141
    $('.top-msg .info').parents('.top-msg').css(
142
    	{
143
    		backgroundColor: '#C3C3B9',
144
    		color: '#fff'
145
    	}
146
    );
119
    $('.top-msg .success').parents('.top-msg').addClass('success');
120
    $('.top-msg .error').parents('.top-msg').addClass('error');
121
    $('.top-msg .warning').parents('.top-msg').addClass('warning');
122
    $('.top-msg .info').parents('.top-msg').addClass('info');
147 123
    
148 124
    // clouds homepage animation
149 125
    $('#animation a').hover(
......
227 203
		$('.widjets  li div').equalHeights();
228 204
	}
229 205

  
230
}); 
206
});
b/snf-astakos-app/astakos/im/templates/im/account_base.html
1 1
{% extends "im/base.html" %}
2 2

  
3
{% block extra_messages %}
4
    {% if not messages %}
5
        {% for msg_type, msg in GLOBAL_MESSAGES.items %}
6
            <div class="{{ msg_type }}">{{ msg|safe }}</div>
7
        {% endfor %}
8
        {% for msg_type, msg in PROFILE_MESSAGES.items %}
9
            <div class="{{ msg_type }}">{{ msg|safe }}</div>
10
        {% endfor %}
11
    {% endif %}
12
{% endblock %}
13

  
14 3
{% load filters %}
15 4

  
16 5
{% block page.title %}Profile{% endblock %}
b/snf-astakos-app/astakos/im/templates/im/base.html
1
<!doctype html>
1
{% load astakos_tags %}<!doctype html>
2 2
<head>
3 3
  {% block starthead %}{% endblock starthead %}
4 4
  <meta charset="UTF-8">
......
77 77

  
78 78
<body>
79 79
    <div class="container">
80
	    <div class="wrapper">       
81
	        {% if messages or EXTRA_MESSAGES_SET %}
82
	        <div class="top-msg active">
83
	            {% block extra_messages %}{% endblock %}
84
	            {% for message in messages %}
85
	            <div{% if message.tags %} 
86
	                class="msg {{ message.tags }}"{% endif %}>
87
	                {{ message|safe }}</div>
88
	            {% endfor %}
89
	            <a href="#" title="close" class="close">X</a>
90
	        </div>
91
	        {% endif %}
80
        <div class="wrapper">       
81
            
82
            {% display_messages %}
83

  
92 84
	        <div class="mainlogo">
93
	        	<a href="/im/">
85
                <a href="{% url astakos.im.views.index %}">
94 86
	        		<img src="{{ IM_STATIC_URL }}images/accounts-logo.png" alt="accounts" />
95 87
	        	</a>
96 88
	        </div>
b/snf-astakos-app/astakos/im/templates/im/login_base.html
1 1
{% extends 'im/base_two_cols.html'%}
2 2

  
3
{% block extra_messages %}
4
    {% if not messages %}
5
        {% for msg_type, msg in GLOBAL_MESSAGES.items %}
6
            <li class="{{ msg_type }}">{{ msg|safe }}</li>
7
        {% endfor %}
8
        {% for msg_type, msg in LOGIN_MESSAGES.items %}
9
            <li class="{{ msg_type }}">{{ msg|safe }}</li>
10
        {% endfor %}
11
    {% endif %}
12
{% endblock %}
13

  
14 3
{% block signup_class %}hidden{% endblock %}
15 4
{% block page.title %}{% endblock %}
16 5

  
......
58 47
	    </div>
59 48
	{% endblock body.signup %}
60 49
 
61
{% endblock body.right%}
50
{% endblock body.right%}
b/snf-astakos-app/astakos/im/templates/im/signup.html
1 1
{% extends 'im/base_two_cols.html' %}
2 2

  
3
{% block extra_messages %}
4
    {% if not messages %}
5
        {% for msg_type, msg in GLOBAL_MESSAGES.items %}
6
            <li class="{{ msg_type }}">{{ msg|safe }}</li>
7
        {% endfor %}
8
        {% for msg_type, msg in SIGNUP_MESSAGES.items %}
9
            <li class="{{ msg_type }}">{{ msg|safe }}</li>
10
        {% endfor %}
11
    {% endif %}
12
{% endblock %}
13

  
14 3
{% block page.title %}
15 4
    Signup
16 5
{% endblock %}
b/snf-astakos-app/astakos/im/templatetags/astakos_tags.py
1
from django import template
2
from django.core.urlresolvers import reverse, resolve
3
from django.conf import settings
4

  
5
register = template.Library()
6

  
7
MESSAGES_VIEWS_MAP = getattr(settings, 'ASTAKOS_MESSAGES_VIEWS_MAP', {
8
    'astakos.im.views.index': 'LOGIN_MESSAGES',
9
    'astakos.im.views.logout': 'LOGIN_MESSAGES',
10
    'astakos.im.views.login': 'LOGIN_MESSAGES',
11
    'astakos.im.views.signup': 'SIGNUP_MESSAGES',
12
    'astakos.im.views.edit_profile': 'PROFILE_MESSAGES',
13
    'astakos.im.views.change_password': 'PROFILE_MESSAGES',
14
    'astakos.im.views.invite': 'PROFILE_MESSAGES',
15
    'astakos.im.views.feedback': 'PROFILE_MESSAGES',
16
})
17

  
18
@register.tag(name='display_messages')
19
def display_messages(parser, token):
20
    return MessagesNode()
21

  
22
class DummyMessage(object):
23
    def __init__(self, type, msg):
24
        self.message = msg
25
        self.tags = type
26

  
27
    def __repr__(self):
28
        return "%s: %s" % (self.tags, self.message)
29

  
30
class MessagesNode(template.Node):
31

  
32
    def get_view_messages(self, context):
33
        messages = list(context['GLOBAL_MESSAGES'])
34
        try:
35
            view = resolve(context['request'].get_full_path())[0]
36
            view_name = "%s.%s" % (view.__module__, view.func_name)
37
            messages += context[MESSAGES_VIEWS_MAP.get(view_name)]
38
            return messages
39
        except Exception, e:
40
            return messages
41

  
42
    def render(self, context):
43
        if self not in context.render_context:
44
            messages = list(context['messages'])
45
            if context['EXTRA_MESSAGES_SET']:
46
                view_messages = self.get_view_messages(context)
47
                for msg_object in view_messages:
48
                    messages.append(DummyMessage(msg_object[0], msg_object[1]))
49

  
50
            if not messages:
51
                return ""
52

  
53
            cls = messages[-1].tags
54
            content = '<div class="top-msg active %s">' % cls
55
            for msg in messages:
56
                content += '<div class="msg %s">%s</div>' % (msg.tags, msg.message)
57

  
58
            content += '<a href="#" title="close" class="close">X</a>'
59
            content += '</div>'
60
            context.render_context[self] = content
61

  
62
        return context.render_context[self]
b/snf-astakos-app/conf/20-snf-astakos-app-settings.conf
68 68
#ASTAKOS_RE_USER_EMAIL_PATTERNS = []
69 69

  
70 70
# Messages to display on login page header
71
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
72
#ASTAKOS_LOGIN_MESSAGES = {}
71
# e.g. [('warning', 'This warning message will be displayed on the top of login page')]
72
#ASTAKOS_LOGIN_MESSAGES = []
73 73

  
74 74
# Messages to display on signup page header
75
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
76
#ASTAKOS_SIGNUP_MESSAGES = {}
75
# e.g. [('warning', 'This warning message will be displayed on the top of signup page')]
76
#ASTAKOS_SIGNUP_MESSAGES = []
77 77

  
78 78
# Messages to display on profile page header
79
# e.g. {'warning': 'This warning message will be displayed on the top of profile pages'}
80
#ASTAKOS_PROFILE_MESSAGES = {}
79
# e.g. [('warning', 'This warning message will be displayed on the top of profile pages')]
80
#ASTAKOS_PROFILE_MESSAGES = []
81 81

  
82 82
# Messages to display on global page header
83
# e.g. {'warning': 'This warning message will be displayed on the top of all pages'}
84
#ASTAKOS_GLOBAL_MESSAGES = {}
83
# e.g. [('warning', 'This warning message will be displayed on the top of all pages')]
84
#ASTAKOS_GLOBAL_MESSAGES = []
85 85

  
86 86
# messages to display as extra actions in account forms
87 87
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
88
#ASTAKOS_PROFILE_EXTRA_LINKS = {}
88
#ASTAKOS_PROFILE_EXTRA_LINKS = []
89 89

  
90 90
# The number of unsuccessful login requests per minute allowed for a specific email
91 91
#ASTAKOS_RATELIMIT_RETRIES_ALLOWED = 3
......
104 104
#ASTAKOS_QUOTA_HOLDER_URL = ''
105 105

  
106 106
# Set the billing URI
107
#ASTAKOS_AQUARIUM_URL = ''
107
#ASTAKOS_AQUARIUM_URL = ''
108

  
109
# Email subjects configuration. For admin/helper notification emails %(user)s
110
# maps to registered/activated user email.
111
#ASTAKOS_INVITATION_EMAIL_SUBJECT = 'Invitation to %s alpha2 testing' % SITENAME
112
#ASTAKOS_GREETING_EMAIL_SUBJECT = 'Welcome to %s alpha2 testing' % SITENAME
113
#ASTAKOS_FEEDBACK_EMAIL_SUBJECT = 'Feedback from %s alpha2 testing' % SITENAME
114
#ASTAKOS_VERIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account activation is needed' % SITENAME
115
#ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account created (%%(user)s)' % SITENAME
116
#ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account activated (%%(user)s)' % SITENAME
117
#ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT = 'Email change on %s alpha2 testing' % SITENAME
118
#ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT = 'Password reset on %s alpha2 testing' % SITENAME

Also available in: Unified diff