Changeset fd6da93 in OpenWorkouts-current
- Timestamp:
- Feb 26, 2019, 11:11:43 AM (5 years ago)
- Branches:
- current, feature/docs, master
- Children:
- a4e4799
- Parents:
- d411dae
- Location:
- ow
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
ow/models/user.py
rd411dae rfd6da93 37 37 self.picture = kw.get('picture', None) # blob 38 38 self.timezone = kw.get('timezone', 'UTC') 39 self.locale = kw.get('locale', 'en') 39 40 self.__password = None 40 41 self.last_workout_id = 0 -
ow/schemas/user.py
rd411dae rfd6da93 4 4 5 5 from ow.schemas.blob import FieldStorageBlob 6 from ow.utilities import get_available_locale_names 6 7 7 8 _ = TranslationStringFactory('OpenWorkouts') … … 76 77 whitelist=['jpg', 'jpeg', 'png', 'gif']) 77 78 timezone = validators.OneOf(common_timezones, if_missing='UTC') 79 locale = validators.OneOf( 80 [locale[0] for locale in get_available_locale_names()], 81 if_missing='en' 82 ) 78 83 79 84 -
ow/static/css/main.css
rd411dae rfd6da93 605 605 border-radius: 4px; 606 606 border: 1px solid #e1e1e1; 607 } 608 .ow-forms select { 609 width: 100%; 607 610 } 608 611 /* Generic button */ -
ow/static/less/ui/form.less
rd411dae rfd6da93 47 47 border: 1px solid @color-main-light; 48 48 } 49 select { 50 width: 100%; 51 } 49 52 } -
ow/templates/edit_profile.pt
rd411dae rfd6da93 46 46 <div> 47 47 <tal:c tal:condition="getattr(context, 'picture', None)"> 48 49 48 <label for="current_picture" i18n:translate=""> 50 49 Current picture:</label> … … 101 100 ${form.textarea('bio', rows=10, cols=50)} 102 101 </p> 103 <div> 104 <label for="timezone" i18n:translate="">Timezone:</label> 105 <small i18n:translate=""> 102 <div class="input-container ly-flex ly-2 has-gap"> 103 <div> 104 <label for="timezone" i18n:translate="">Timezone:</label> 105 <p> 106 <small i18n:translate=""> 106 107 All dates and times will be formatted for this timezone 107 </small> 108 </small> 109 </p> 110 ${form.errorlist('timezone')} 111 ${form.select('timezone', timezones)} 112 </div> 113 <div> 114 <label for="locale" i18n:translate="">Language:</label> 115 <p> 116 <small i18n:translate=""> 117 All texts in the user interface will appear in this language 118 </small> 119 </p> 120 ${form.errorlist('locale')} 121 ${form.select('locale', available_locale_names, selected_value=current_locale)} 122 </div> 108 123 </div> 109 ${form.errorlist('timezone')}110 ${form.select('timezone', timezones)}111 124 </fieldset> 112 125 -
ow/tests/views/test_user.py
rd411dae rfd6da93 20 20 from PIL import Image 21 21 22 from pytz import common_timezones 23 22 24 from ow.models.root import OpenWorkouts 23 25 from ow.models.user import User 24 26 from ow.models.workout import Workout 25 27 from ow.views.renderers import OWFormRenderer 28 from ow.utilities import get_available_locale_names 26 29 import ow.views.user as user_views 27 30 … … 51 54 def dummy_request(self, root): 52 55 request = DummyRequest() 56 request.registry.settings = { 57 'pyramid.default_locale_name': 'en' 58 } 53 59 request.root = root 54 60 return request … … 561 567 assert rem.called 562 568 assert response.location == request.resource_url(john) 569 # the response headers contain the proper set_cookie for the default 570 # locale 571 default_locale_name = request.registry.settings[ 572 'pyramid.default_locale_name'] 573 expected_locale_header = '_LOCALE_=' + default_locale_name + '; Path=/' 574 assert response.headers['Set-Cookie'] == expected_locale_header 575 576 @patch('ow.views.user.remember') 577 def test_login_post_ok_set_locale(self, rem, dummy_request, john): 578 # same as the previous test, but this time the user has set a 579 # locale different than the default one 580 request = dummy_request 581 request.method = 'POST' 582 request.POST['submit'] = True 583 request.POST['email'] = 'john.doe@example.net' 584 request.POST['password'] = 's3cr3t' 585 # verify the user first 586 john.verified = True 587 # set the locale 588 john.locale = 'es' 589 response = user_views.login(request.root, request) 590 assert isinstance(response, HTTPFound) 591 assert rem.called 592 assert response.location == request.resource_url(john) 593 # the response headers contain the proper set_cookie for the user 594 # locale setting 595 expected_locale_header = '_LOCALE_=es; Path=/' 596 assert response.headers['Set-Cookie'] == expected_locale_header 563 597 564 598 @patch('ow.views.user.forget') … … 569 603 assert forg.called 570 604 assert response.location == request.resource_url(request.root) 605 # the response headers contain the needed Set-Cookie header that 606 # invalidates the _LOCALE_ cookie, preventing problems with users 607 # sharing the same web browser (one locale setting being set for 608 # another user) 609 expected_locale_header = '_LOCALE_=; Max-Age=0; Path=/; expires=' 610 assert expected_locale_header in response.headers['Set-Cookie'] 571 611 572 612 extensions = ('png', 'jpg', 'jpeg', 'gif') … … 639 679 # loaded user profile 640 680 data = ['firstname', 'lastname', 'email', 'nickname', 'bio', 641 'birth_date', 'height', 'weight', 'gender', 'timezone'] 681 'birth_date', 'height', 'weight', 'gender', 'timezone', 682 'locale'] 642 683 assert list(response['form'].data.keys()) == data 643 684 # and check the email to see data is properly loaded 644 685 assert response['form'].data['email'] == 'john.doe@example.net' 686 assert response['timezones'] == common_timezones 687 assert response[ 688 'available_locale_names'] == get_available_locale_names() 689 assert response['current_locale'] == request.registry.settings[ 690 'pyramid.default_locale_name'] 645 691 646 692 def test_edit_profile_post_ok(self, profile_post_request, john): … … 654 700 assert response.location == request.resource_url(user, 'profile') 655 701 assert user.bio == bio 702 703 def test_edit_profile_post_ok_change_locale( 704 self, profile_post_request, john): 705 request = profile_post_request 706 user = john 707 # Update the locale 708 request.POST['locale'] = 'es' 709 response = user_views.edit_profile(user, request) 710 assert isinstance(response, HTTPFound) 711 assert response.location == request.resource_url(user, 'profile') 712 assert user.locale == 'es' 713 714 def test_edit_profile_post_ok_invalid_locale( 715 self, profile_post_request, john): 716 request = profile_post_request 717 user = john 718 # Update the locale with an invalid option 719 request.POST['locale'] = 'XX' 720 response = user_views.edit_profile(user, request) 721 assert isinstance(response['form'], OWFormRenderer) 722 # as an error happened, the current_locale had not changed 723 assert response['form'].errors == { 724 'locale': "Value must be one of: en; es (not 'XX')"} 725 assert user.locale == 'en' 656 726 657 727 def test_edit_profile_post_missing_required( -
ow/utilities.py
rd411dae rfd6da93 296 296 if value[0] <= dt.hour <= value[1]: 297 297 return key 298 299 300 def get_available_locale_names(): 301 """ 302 Return a list of tuples with info about available locale/language 303 names. 304 305 The locale codes and names in this list match the available translations 306 under ow/locale for the UI elements 307 """ 308 return [ 309 ('en', _('English')), 310 ('es', _('Spanish')) 311 ] -
ow/views/user.py
rd411dae rfd6da93 22 22 from ..models.root import OpenWorkouts 23 23 from ..views.renderers import OWFormRenderer 24 from ..utilities import timedelta_to_hms, get_verification_token 24 from ..utilities import ( 25 timedelta_to_hms, 26 get_verification_token, 27 get_available_locale_names 28 ) 25 29 from ..mail import send_verification_email 26 30 … … 76 80 password = request.POST.get('password', None) 77 81 if password is not None and user.check_password(password): 82 # look for the value of locale for this user, to set the 83 # LOCALE cookie, so the UI appears on the pre-selected lang 84 default_locale = request.registry.settings.get( 85 'pyramid.default_locale_name') 86 locale = getattr(user, 'locale', default_locale) 87 request.response.set_cookie('_LOCALE_', locale) 88 # log in the user and send back to the place he wanted to 89 # visit 78 90 headers = remember(request, str(user.uid)) 91 request.response.headers.extend(headers) 79 92 redirect_url = return_to or request.resource_url(user) 80 return HTTPFound(location=redirect_url, headers=headers) 93 return HTTPFound(location=redirect_url, 94 headers=request.response.headers) 81 95 else: 82 96 message = _('Wrong password') … … 100 114 @view_config(context=OpenWorkouts, name='logout') 101 115 def logout(context, request): 116 request.response.delete_cookie('_LOCALE_') 102 117 headers = forget(request) 103 return HTTPFound(location=request.resource_url(context), headers=headers) 118 request.response.headers.extend(headers) 119 return HTTPFound(location=request.resource_url(context), 120 headers=request.response.headers) 104 121 105 122 … … 319 336 renderer='ow:templates/edit_profile.pt') 320 337 def edit_profile(context, request): 338 default_locale = request.registry.settings.get( 339 'pyramid.default_locale_name') 340 available_locale_names = get_available_locale_names() 341 current_locale = request.cookies.get('_LOCALE_', default_locale) 321 342 # if not given a file there is an empty byte in POST, which breaks 322 343 # our blob storage validator. … … 340 361 # reindex 341 362 request.root.reindex(context) 363 # set the cookie for the locale/lang 364 request.response.set_cookie('_LOCALE_', form.data['locale']) 365 current_locale = form.data['locale'] 342 366 # Saved, send the user to the public view of her profile 343 return HTTPFound(location=request.resource_url(context, 'profile')) 367 return HTTPFound(location=request.resource_url(context, 'profile'), 368 headers=request.response.headers) 344 369 345 370 # prevent crashes on the form … … 348 373 349 374 return {'form': OWFormRenderer(form), 350 'timezones': common_timezones} 375 'timezones': common_timezones, 376 'available_locale_names': available_locale_names, 377 'current_locale': current_locale} 351 378 352 379
Note: See TracChangeset
for help on using the changeset viewer.