Compare commits

..

2 Commits

7 changed files with 354 additions and 944 deletions

View File

@ -8,7 +8,7 @@ REGISTRATION_ENABLED = True
DEFAULT_TIMEZONE = 'Europe/Budapest'
DEBUG = False
TESTING = True
TESTING=True
SQLALCHEMY_DATABASE_URI = 'sqlite:///'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = 'WeAreTesting'

View File

@ -31,7 +31,7 @@ from wtforms.widgets import TextArea
from calsocial.models import EventVisibility, EVENT_VISIBILITY_TRANSLATIONS
class UsernameAvailable: # pylint: disable=too-few-public-methods
class UsernameAvailable(object): # pylint: disable=too-few-public-methods
"""Checks if a username is available
"""
@ -62,7 +62,7 @@ class UsernameAvailable: # pylint: disable=too-few-public-methods
raise StopValidation(message)
class EmailAvailable: # pylint: disable=too-few-public-methods
class EmailAvailable(object): # pylint: disable=too-few-public-methods
"""Checks if an email address is available
"""
@ -408,6 +408,5 @@ class ProfileForm(FlaskForm):
})
FlaskForm.__init__(self, *args, **kwargs)
self.builtin_avatar.choices = [(name, name)
for name in current_app.config['BUILTIN_AVATARS']]
self.builtin_avatar.choices = [(name, name) for name in current_app.config['BUILTIN_AVATARS']]
self.profile = profile

View File

@ -70,6 +70,18 @@ class NotificationAction(Enum):
#: A user has been invited to an event
invite = 2
def __hash__(self):
return Enum.__hash__(self)
def __eq__(self, other):
if isinstance(other, str):
return self.name.lower() == other.lower() # pylint: disable=no-member
if isinstance(other, (int, float)):
return self.value == other
return Enum.__eq__(self, other)
NOTIFICATION_ACTION_MESSAGES = {
NotificationAction.follow: (_('%(actor)s followed you'), _('%(actor)s followed %(item)s')),
@ -101,7 +113,7 @@ class ResponseType(Enum):
return self.name.lower() == other.lower() # pylint: disable=no-member
if isinstance(other, (int, float)):
return self.value == other # pylint: disable=comparison-with-callable
return self.value == other
return Enum.__eq__(self, other)
@ -123,6 +135,80 @@ EVENT_VISIBILITY_TRANSLATIONS = {
}
class ResponseVisibility(Enum):
"""Enumeration for response visibility
"""
#: The response is only visible to the invitee
private = 0
#: The response is only visible to the event organisers
organisers = 1
#: The response is only visible to the event attendees
attendees = 2
#: The response is visible to the invitees friends (ie. mutual follows)
friends = 3
#: The response is visible to the invitees followers
followers = 4
#: The response is visible to anyone
public = 5
RESPONSE_VISIBILITY_TRANSLATIONS = {
ResponseVisibility.private: _('Visible only to myself'),
ResponseVisibility.organisers: _('Visible only to event organisers'),
ResponseVisibility.attendees: _('Visible only to event attendees'),
ResponseVisibility.friends: _('Visible only to my friends'),
ResponseVisibility.followers: _('Visible only to my followers'),
ResponseVisibility.public: _('Visible to anyone'),
}
class EventAvailability(Enum):
"""Enumeration of event availabilities
"""
free = 0
busy = 1
def __hash__(self):
return Enum.__hash__(self)
def __eq__(self, other):
if isinstance(other, str):
return self.name.lower() == other.lower() # pylint: disable=no-member
if isinstance(other, (int, float)):
return self.value == other
return Enum.__eq__(self, other)
class UserAvailability(Enum):
"""Enumeration of user availabilities
"""
free = 0
busy = 1
tentative = 2
def __hash__(self):
return Enum.__hash__(self)
def __eq__(self, other):
if isinstance(other, str):
return self.name.lower() == other.lower() # pylint: disable=no-member
if isinstance(other, (int, float)):
return self.value == other
return Enum.__eq__(self, other)
class SettingsProxy:
"""Proxy object to get settings for a user
"""
@ -404,6 +490,45 @@ class Profile(db.Model): # pylint: disable=too-few-public-methods
return notification
def is_following(self, profile):
"""Check if this profile is following ``profile``
"""
try:
UserFollow.query.filter(UserFollow.follower == self).filter(UserFollow.followed == profile).one()
except NoResultFound:
return False
return True
def is_friend_of(self, profile):
"""Check if this profile is friends with ``profile``
"""
reverse = db.aliased(UserFollow)
try:
UserFollow.query \
.filter(UserFollow.follower == self) \
.join(reverse, UserFollow.followed_id == reverse.follower_id) \
.filter(UserFollow.follower_id == reverse.followed_id) \
.one()
except NoResultFound:
return False
return True
def is_attending(self, event):
"""Check if this profile is attending ``event``
"""
try:
Response.query.filter(Response.profile == self).filter(Response.event == event).one()
except NoResultFound:
return False
return True
class Event(db.Model):
"""Database model for events
@ -791,8 +916,56 @@ class Response(db.Model): # pylint: disable=too-few-public-methods
#: The response itself
response = db.Column(db.Enum(ResponseType), nullable=False)
#: The visibility of the response
visibility = db.Column(db.Enum(ResponseVisibility), nullable=False)
class AppState(app_state_base(db.Model)): # pylint: disable=too-few-public-methods,inherit-non-class
def visible_to(self, profile):
"""Checks if the response can be visible to ``profile``.
:param profile: the profile looking at the response. If None, it is viewed as anonymous
:type profile: Profile, None
:returns: ``True`` if the response should be visible, ``False`` otherwise
:rtype: bool
"""
if self.profile == profile:
return True
if self.visibility == ResponseVisibility.private:
return False
if self.visibility == ResponseVisibility.organisers:
return profile == self.event.profile
if self.visibility == ResponseVisibility.attendees:
return profile is not None and \
(profile.is_attending(self.event) or \
profile == self.event.profile)
# From this point on, if the event is not public, only attendees can see responses
if self.event.visibility != EventVisibility.public:
return profile is not None and \
(profile.is_attending(self.event) or
profile == self.event.profile)
if self.visibility == ResponseVisibility.friends:
return profile is not None and \
(profile.is_friend_of(self.profile) or \
profile.is_attending(self.event) or \
profile == self.event.profile or \
profile == self.profile)
if self.visibility == ResponseVisibility.followers:
return profile is not None and \
(profile.is_following(self.profile) or \
profile.is_attending(self.event) or \
profile == self.event.profile or \
profile == self.profile)
return self.visibility == ResponseVisibility.public
class AppState(app_state_base(db.Model)): # pylint: disable=too-few-public-methods
"""Database model for application state values
"""

View File

@ -35,15 +35,6 @@ class AnonymousUser(BaseAnonymousUser):
return current_app.timezone
@property
def profile(self):
"""The profile of the anonymous user
Always evaluates to ``None``
"""
return None
@user_logged_in.connect
def login_handler(app, user): # pylint: disable=unused-argument

View File

@ -1,462 +0,0 @@
# Translations template for Calendar.social.
# Copyright (C) 2018 Sylke Vicious
# This file is distributed under the same license as the Calendar.social project.
# Sylke Vicious <silkevicious@layer8.space>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: gergely@polonkai.eu\n"
"POT-Creation-Date: 2018-07-31 09:55+0200\n"
"PO-Revision-Date: 2018-07-31 09:56+0200\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n"
"X-Generator: Poedit 2.0.9\n"
"Last-Translator: Sylke Vicious <silkevicious@layer8.space>\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"Language: it\n"
#: calsocial/account.py:227
msgid "Cant invalidate your current session"
msgstr "Non puoi revocare la tua sessione corrente"
#: calsocial/forms.py:57
msgid "This username is not available"
msgstr "Questo nome utente non è disponibile"
#: calsocial/forms.py:88
msgid "This email address can not be used"
msgstr "Questo indirizzo email non può essere usato"
#: calsocial/forms.py:100
msgid "Username"
msgstr "Nome utente"
#: calsocial/forms.py:101
msgid "Email address"
msgstr "Indirizzo email"
#: calsocial/forms.py:102
msgid "Password"
msgstr "Password"
#: calsocial/forms.py:103
msgid "Password, once more"
msgstr "Ripeti la password"
#: calsocial/forms.py:112
msgid "The two passwords must match!"
msgstr "Le due password devono corrispondere!"
#: calsocial/forms.py:219
msgid "Title"
msgstr "Titolo"
#: calsocial/forms.py:220 calsocial/forms.py:260
msgid "Time zone"
msgstr "Fuso orario"
#: calsocial/forms.py:221
msgid "Start time"
msgstr "Ora d'inizio"
#: calsocial/forms.py:222
msgid "End time"
msgstr "Ora di fine"
#: calsocial/forms.py:223
msgid "All day"
msgstr "Tutto il giorno"
#: calsocial/forms.py:224
msgid "Description"
msgstr "Descrizione"
#: calsocial/forms.py:225
msgid "Visibility"
msgstr "Visibilità"
#: calsocial/forms.py:253
msgid "End time must be later than start time!"
msgstr ""
#: calsocial/forms.py:284
msgid "Username or email"
msgstr "Nome utente o email"
#: calsocial/forms.py:372
msgid "User is already invited"
msgstr "L'utente è già invitato"
#: calsocial/forms.py:382 calsocial/forms.py:396
msgid "Display name"
msgstr "Mostra nome"
#: calsocial/forms.py:385
msgid ""
"This will be shown to other users as your name. You can use your real "
"name, or any nickname you like."
msgstr "Questo sarà mostrato agli altri utenti come tuo nome. Puoi usare il tuo vero "
"nome, o qualsiasi altro soprannome che preferisci."
#: calsocial/forms.py:387
msgid "Your time zone"
msgstr "Il tuo fuso orario"
#: calsocial/forms.py:389
msgid "The start and end times of events will be displayed in this time zone."
msgstr "L'ora di inizio e di fine degli eventi sarà mostrata con questo fuso orario"
#: calsocial/forms.py:397
msgid "Use a built-in avatar"
msgstr "Usa un avatar predefinito"
#: calsocial/forms.py:398
msgid "Lock profile"
msgstr "Blocca profilo"
#: calsocial/models.py:75
#, python-format
msgid "%(actor)s followed you"
msgstr "%(actor)s ti segue"
#: calsocial/models.py:75
#, python-format
msgid "%(actor)s followed %(item)s"
msgstr "%(actor)s segue %(item)s"
#: calsocial/models.py:76
#, python-format
msgid "%(actor)s invited you to %(item)s"
msgstr "%(actor)s ti ha invitato a %(item)s"
#: calsocial/models.py:121
msgid "Visible only to attendees"
msgstr "Visibile solo ai partecipanti"
#: calsocial/models.py:122
msgid "Visible to everyone"
msgstr "Visibile a tutti"
#: calsocial/models.py:542
#, python-format
msgid "%(user)s logged in"
msgstr "%(user)s ha effettuato l'accesso"
#: calsocial/models.py:543
#, python-format
msgid "%(user)s failed to log in"
msgstr "%(user)s non è riuscito ad accedere"
#: calsocial/models.py:544
#, python-format
msgid "%(user)s logged out"
msgstr "%(user)s si è disconnesso"
#: calsocial/models.py:561
#, python-format
msgid "UNKNOWN RECORD \"%(log_type)s\" for %(user)s"
msgstr "RECORD SCONOSCIUTO \"%(log_type)s\" per %(user)s"
#: calsocial/calendar_system/gregorian.py:31
msgid "Gregorian"
msgstr "Gregoriano"
#: calsocial/calendar_system/gregorian.py:39
msgid "January"
msgstr "Gennaio"
#: calsocial/calendar_system/gregorian.py:40
msgid "February"
msgstr "Febbraio"
#: calsocial/calendar_system/gregorian.py:41
msgid "March"
msgstr "Marzo"
#: calsocial/calendar_system/gregorian.py:42
msgid "April"
msgstr "Aprile"
#: calsocial/calendar_system/gregorian.py:43
msgid "May"
msgstr "Maggio"
#: calsocial/calendar_system/gregorian.py:44
msgid "June"
msgstr "Giugno"
#: calsocial/calendar_system/gregorian.py:45
msgid "July"
msgstr "Luglio"
#: calsocial/calendar_system/gregorian.py:46
msgid "August"
msgstr "Agosto"
#: calsocial/calendar_system/gregorian.py:47
msgid "September"
msgstr "Settembre"
#: calsocial/calendar_system/gregorian.py:48
msgid "October"
msgstr "Ottobre"
#: calsocial/calendar_system/gregorian.py:49
msgid "November"
msgstr "Novembre"
#: calsocial/calendar_system/gregorian.py:50
msgid "December"
msgstr "Dicembre"
#: calsocial/calendar_system/gregorian.py:54
msgid "Monday"
msgstr "Lunedì"
#: calsocial/calendar_system/gregorian.py:55
msgid "Tuesday"
msgstr "Martedì"
#: calsocial/calendar_system/gregorian.py:56
msgid "Wednesday"
msgstr "Mercoledì"
#: calsocial/calendar_system/gregorian.py:57
msgid "Thursday"
msgstr "Giovedì"
#: calsocial/calendar_system/gregorian.py:58
msgid "Friday"
msgstr "Venerdì"
#: calsocial/calendar_system/gregorian.py:59
msgid "Saturday"
msgstr "Sabato"
#: calsocial/calendar_system/gregorian.py:60
msgid "Sunday"
msgstr "Domenica"
#: calsocial/templates/base.html:29 calsocial/templates/login.html:9
#: calsocial/templates/login.html:24 calsocial/templates/welcome.html:9
#: calsocial/templates/welcome.html:16
msgid "Login"
msgstr "Accedi"
#: calsocial/templates/base.html:32
#, python-format
msgid "Logged in as %(username)s"
msgstr "Effettuato l'accesso come %(username)s"
#: calsocial/templates/base.html:36
msgid "Calendar view"
msgstr "Vista calendario"
#: calsocial/templates/base.html:37
msgid "Notifications"
msgstr "Notifiche"
#: calsocial/templates/account/settings-base.html:8
#: calsocial/templates/account/user-settings.html:5
#: calsocial/templates/base.html:38
msgid "Settings"
msgstr "Impostazioni"
#: calsocial/templates/base.html:39
msgid "Logout"
msgstr "Disconnettiti"
#: calsocial/templates/base.html:48
msgid "About this instance"
msgstr "A proposito di questa istanza"
#: calsocial/templates/event-details.html:5
#, python-format
msgid ""
"This event is organised in the %(timezone)s time zone, in which it "
"happens between %(start_time)s and %(end_time)s"
msgstr ""
"Questo evento è organizzato nel fuso orario %(timezone)s, nel quale "
"avverrà tra le %(start_time)s e le %(end_time)s"
#: calsocial/templates/event-details.html:29
msgid "Invited users"
msgstr "Utenti invitati"
#: calsocial/templates/event-details.html:41
#: calsocial/templates/event-details.html:47
msgid "Invite"
msgstr "Invita"
#: calsocial/templates/account/first-steps.html:25
#: calsocial/templates/account/profile-edit.html:20
#: calsocial/templates/account/user-settings.html:18
#: calsocial/templates/event-edit.html:24
msgid "Save"
msgstr "Salva"
#: calsocial/templates/index.html:4
#, python-format
msgid "Welcome to Calendar.social, %(username)s!"
msgstr "Benvenuto su Calendar.social, %(username)s!"
#: calsocial/templates/index.html:10
msgid "Add event"
msgstr "Crea evento"
#: calsocial/templates/profile-details.html:10
#: calsocial/templates/profile-details.html:11
msgid "locked profile"
msgstr "profilo bloccato"
#: calsocial/templates/profile-details.html:17
msgid "Follow"
msgstr "Segui"
#: calsocial/templates/profile-details.html:21
msgid "Follows"
msgstr "Seguendo"
#: calsocial/templates/profile-details.html:29
msgid "Followers"
msgstr "Seguito da"
#: calsocial/templates/welcome.html:20
msgid "Or"
msgstr "O"
#: calsocial/templates/welcome.html:22
msgid "Register an account"
msgstr "Registra un account"
#: calsocial/templates/welcome.html:26
msgid "What is Calendar.social?"
msgstr "Cos'è Calendar.social"
#: calsocial/templates/welcome.html:28
msgid ""
"Calendar.social is a calendar app based on open protocols and free, open "
"source software."
msgstr ""
"Calendar.social è un'app calendario basata su protocolli aperti e software "
"open source."
#: calsocial/templates/welcome.html:29
msgid "It is decentralised like one of its counterparts, email."
msgstr "È decentralizzato come una delle sue controparti, l'email"
#: calsocial/templates/welcome.html:33
msgid "Go to your calendar"
msgstr "Vai al tuo calendario"
#: calsocial/templates/welcome.html:37
msgid "Peek inside"
msgstr "Uno sguardo all'interno"
#: calsocial/templates/welcome.html:43
msgid "Built with users in mind"
msgstr "Creato pensando agli utenti"
#: calsocial/templates/welcome.html:45
msgid ""
"From planning your appointments to organising large scale events "
"Calendar.social can help with all your scheduling needs."
msgstr ""
"Dalla pianificazione dei tuoi appuntamenti all'organizzazione di eventi su larga scala "
"Calendar.social ti può aiutare con tutte le tue esigenze di organizzazione."
#: calsocial/templates/welcome.html:54
msgid "user"
msgid_plural "users"
msgstr[0] "utente"
msgstr[1] "utenti"
#: calsocial/templates/welcome.html:60
msgid "event"
msgid_plural "events"
msgstr[0] "evento"
msgstr[1] "eventi"
#: calsocial/templates/welcome.html:67
msgid "Built for people"
msgstr "Creato per le persone"
#: calsocial/templates/welcome.html:69
msgid "Calendar.social is not a commercial network."
msgstr "Calendar.social non è una rete commerciale."
#: calsocial/templates/welcome.html:70
msgid "No advertising, no data mining, no walled gardens."
msgstr "No pubblicità, no analisi dei dati, no restrizioni proprietarie"
#: calsocial/templates/welcome.html:71
msgid "There is no central authority."
msgstr "Non esiste un'amministrazione centrale"
#: calsocial/templates/welcome.html:77
msgid "Administered by"
msgstr "Amministrato da"
#: calsocial/templates/account/active-sessions.html:4
#: calsocial/templates/account/settings-base.html:9
msgid "Active sessions"
msgstr "Sessioni attive"
#: calsocial/templates/account/active-sessions.html:10
msgid "Invalidate"
msgstr "Revoca"
#: calsocial/templates/account/first-steps.html:5
msgid "First steps"
msgstr "Primi passi"
#: calsocial/templates/account/first-steps.html:7
msgid "Welcome to Calendar.social!"
msgstr "Benvenuto su Calendar.social!"
#: calsocial/templates/account/first-steps.html:10
msgid ""
"These are the first steps you should make before you can start using the "
"site."
msgstr ""
"Questi sono i primi passi che dovresti fare prima di iniziare ad usare "
"il sito."
#: calsocial/templates/account/follow-requests.html:4
msgid "Follow requests"
msgstr "Richieste di seguirti"
#: calsocial/templates/account/follow-requests.html:10
msgid "Accept"
msgstr "Accetta"
#: calsocial/templates/account/follow-requests.html:15
msgid "No requests to display."
msgstr "Nessuna richiesta da mostrare."
#: calsocial/templates/account/follow-requests.html:19
msgid "Your profile is not locked."
msgstr "Il tuo profilo non è bloccato."
#: calsocial/templates/account/follow-requests.html:20
msgid "Anyone can follow you without your consent."
msgstr "Chiunque può seguirti senza chiederti il permesso."
#: calsocial/templates/account/notifications.html:7
msgid "Nothing to show."
msgstr "Niente da mostrare."
#: calsocial/templates/account/profile-edit.html:5
#: calsocial/templates/account/settings-base.html:7
msgid "Edit profile"
msgstr "Modifica profilo"
#: calsocial/templates/account/registration.html:17
msgid "Register"
msgstr "Registrati"

View File

@ -1,466 +0,0 @@
# Polish template for Calendar.social.
# Copyright (C) 2018 Marcin Mikołajczak
# This file is distributed under the same license as the Calendar.social project.
# Marcin Mikołajczak <me@m4sk.in>, 2018.
#
msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: gergely@polonkai.eu\n"
"POT-Creation-Date: 2018-07-30 22:05+0200\n"
"PO-Revision-Date: 2018-07-30 22:23+0200\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.6.0\n"
"X-Generator: Poedit 2.0.9\n"
"Last-Translator: Marcin Mikołajczak <me@m4sk.in>\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"Language: pl\n"
#: calsocial/account.py:227
msgid "Cant invalidate your current session"
msgstr "Nie udało się unieważnić obecnej sesji"
#: calsocial/forms.py:57
msgid "This username is not available"
msgstr "Ta nazwa użytkownika nie jest dostepna"
#: calsocial/forms.py:88
msgid "This email address can not be used"
msgstr "Nie można użyć tego adresu e-mail"
#: calsocial/forms.py:100
msgid "Username"
msgstr "Nazwa użytkownika"
#: calsocial/forms.py:101
msgid "Email address"
msgstr "Adres e-mail"
#: calsocial/forms.py:102
msgid "Password"
msgstr "Hasło"
#: calsocial/forms.py:103
msgid "Password, once more"
msgstr "Potwórz hasło"
#: calsocial/forms.py:112
msgid "The two passwords must match!"
msgstr "Hasła muszą do siebie pasować!"
#: calsocial/forms.py:219
msgid "Title"
msgstr "Tytuł"
#: calsocial/forms.py:220 calsocial/forms.py:260
msgid "Time zone"
msgstr "Strefa czasowa"
#: calsocial/forms.py:221
msgid "Start time"
msgstr "Czas rozpoczęcia"
#: calsocial/forms.py:222
msgid "End time"
msgstr "Czas zakończenia"
#: calsocial/forms.py:223
msgid "All day"
msgstr "Cały dzień"
#: calsocial/forms.py:224
msgid "Description"
msgstr "Opis"
#: calsocial/forms.py:225
msgid "Visibility"
msgstr "Widoczność"
#: calsocial/forms.py:253
msgid "End time must be later than start time!"
msgstr "Czas zakończenia musi nastąpić po czasie rozpoczęcia!"
#: calsocial/forms.py:284
msgid "Username or email"
msgstr "Nazwa użytkownika lub adres e-mail"
#: calsocial/forms.py:372
msgid "User is already invited"
msgstr "Użytkownik został już zaproszony"
#: calsocial/forms.py:382 calsocial/forms.py:396
msgid "Display name"
msgstr "Nazwa wyświetlana"
#: calsocial/forms.py:385
msgid ""
"This will be shown to other users as your name. You can use your real name, "
"or any nickname you like."
msgstr ""
"Będzie widoczna dla innych użytkowników jako Twoja nazwa. Może to być Twoje "
"imię i nazwisko lub dowolny pseudonim."
#: calsocial/forms.py:387
msgid "Your time zone"
msgstr "Twoja strefa czasowa"
#: calsocial/forms.py:389
msgid "The start and end times of events will be displayed in this time zone."
msgstr ""
"Czas rozpoczęcia i zakończenia wydarzeń będą widoczne w tej strefie czasowej."
#: calsocial/forms.py:397
msgid "Use a built-in avatar"
msgstr "Użyj wbudowanego awatara"
#: calsocial/forms.py:398
msgid "Lock profile"
msgstr "Zablokuj konto"
#: calsocial/models.py:75
#, python-format
msgid "%(actor)s followed you"
msgstr "%(actor)s zaczął Cię śledzić"
#: calsocial/models.py:75
#, python-format
msgid "%(actor)s followed %(item)s"
msgstr "%(actor)s zaczął śledzić %(item)s"
#: calsocial/models.py:76
#, python-format
msgid "%(actor)s invited you to %(item)s"
msgstr "%(actor)s zaprosił Cię na %(item)s"
#: calsocial/models.py:121
msgid "Visible only to attendees"
msgstr "Widoczne tylko dla uczestników"
#: calsocial/models.py:122
msgid "Visible to everyone"
msgstr "Widoczne dla wszystkich"
#: calsocial/models.py:542
#, python-format
msgid "%(user)s logged in"
msgstr "%(user)s zalogował się"
#: calsocial/models.py:543
#, python-format
msgid "%(user)s failed to log in"
msgstr "nie udało się zalogować %(user)s"
#: calsocial/models.py:544
#, python-format
msgid "%(user)s logged out"
msgstr "%(user)s wylogował się"
#: calsocial/models.py:561
#, python-format
msgid "UNKNOWN RECORD \"%(log_type)s\" for %(user)s"
msgstr "NIEZNANY WPIS \"%(log_type)s\" dla %(user)s"
#: calsocial/calendar_system/gregorian.py:31
msgid "Gregorian"
msgstr "Gregoriański"
#: calsocial/calendar_system/gregorian.py:39
msgid "January"
msgstr "Styczeń"
#: calsocial/calendar_system/gregorian.py:40
msgid "February"
msgstr "Luty"
#: calsocial/calendar_system/gregorian.py:41
msgid "March"
msgstr "Marzec"
#: calsocial/calendar_system/gregorian.py:42
msgid "April"
msgstr "Kwiecień"
#: calsocial/calendar_system/gregorian.py:43
msgid "May"
msgstr "Maj"
#: calsocial/calendar_system/gregorian.py:44
msgid "June"
msgstr "Czerwiec"
#: calsocial/calendar_system/gregorian.py:45
msgid "July"
msgstr "Lipiec"
#: calsocial/calendar_system/gregorian.py:46
msgid "August"
msgstr "Sierpień"
#: calsocial/calendar_system/gregorian.py:47
msgid "September"
msgstr "Wrzesień"
#: calsocial/calendar_system/gregorian.py:48
msgid "October"
msgstr "Październik"
#: calsocial/calendar_system/gregorian.py:49
msgid "November"
msgstr "Listopad"
#: calsocial/calendar_system/gregorian.py:50
msgid "December"
msgstr "Grudzień"
#: calsocial/calendar_system/gregorian.py:54
msgid "Monday"
msgstr "Poniedziałek"
#: calsocial/calendar_system/gregorian.py:55
msgid "Tuesday"
msgstr "Wtorek"
#: calsocial/calendar_system/gregorian.py:56
msgid "Wednesday"
msgstr "Środa"
#: calsocial/calendar_system/gregorian.py:57
msgid "Thursday"
msgstr "Czwartek"
#: calsocial/calendar_system/gregorian.py:58
msgid "Friday"
msgstr "Piątek"
#: calsocial/calendar_system/gregorian.py:59
msgid "Saturday"
msgstr "Sobota"
#: calsocial/calendar_system/gregorian.py:60
msgid "Sunday"
msgstr "Niedziela"
#: calsocial/templates/base.html:29 calsocial/templates/login.html:9
#: calsocial/templates/login.html:24 calsocial/templates/welcome.html:9
#: calsocial/templates/welcome.html:16
msgid "Login"
msgstr "Zaloguj się"
#: calsocial/templates/base.html:32
#, python-format
msgid "Logged in as %(username)s"
msgstr "Zalogowano jako %(username)s"
#: calsocial/templates/base.html:36
msgid "Calendar view"
msgstr "Widok kalendarza"
#: calsocial/templates/base.html:37
msgid "Notifications"
msgstr "Powiadomienia"
#: calsocial/templates/account/settings-base.html:8
#: calsocial/templates/account/user-settings.html:5
#: calsocial/templates/base.html:38
msgid "Settings"
msgstr "Ustawienia"
#: calsocial/templates/base.html:39
msgid "Logout"
msgstr "Wyloguj się"
#: calsocial/templates/base.html:48
msgid "About this instance"
msgstr "O tej instancji"
#: calsocial/templates/event-details.html:5
#, python-format
msgid ""
"This event is organised in the %(timezone)s time zone, in which it happens "
"between %(start_time)s and %(end_time)s"
msgstr ""
"To wydarzenie jest organizowane w strefie czasowej %(timezone)s, w której "
"wydarzy się ono pomiędzy %(start_time)s a %(end_time)s"
#: calsocial/templates/event-details.html:29
msgid "Invited users"
msgstr "Zaproszeni użytkownicy"
#: calsocial/templates/event-details.html:41
#: calsocial/templates/event-details.html:47
msgid "Invite"
msgstr "Zaproś"
#: calsocial/templates/account/first-steps.html:25
#: calsocial/templates/account/profile-edit.html:20
#: calsocial/templates/account/user-settings.html:18
#: calsocial/templates/event-edit.html:24
msgid "Save"
msgstr "Zapisz"
#: calsocial/templates/index.html:4
#, python-format
msgid "Welcome to Calendar.social, %(username)s!"
msgstr "Witaj na Calendar.social, %(username)s!"
#: calsocial/templates/index.html:10
msgid "Add event"
msgstr "Dodaj wydarzenie"
#: calsocial/templates/profile-details.html:10
#: calsocial/templates/profile-details.html:11
msgid "locked profile"
msgstr "profil zablokowany"
#: calsocial/templates/profile-details.html:17
msgid "Follow"
msgstr "Obserwuj"
#: calsocial/templates/profile-details.html:21
msgid "Follows"
msgstr "Obserwacje"
#: calsocial/templates/profile-details.html:29
msgid "Followers"
msgstr "Obserwujący"
#: calsocial/templates/welcome.html:20
msgid "Or"
msgstr "Lub"
#: calsocial/templates/welcome.html:22
msgid "Register an account"
msgstr "Zarejestruj się"
#: calsocial/templates/welcome.html:26
msgid "What is Calendar.social?"
msgstr "Czym jest Calendar.social?"
#: calsocial/templates/welcome.html:28
msgid ""
"Calendar.social is a calendar app based on open protocols and free, open "
"source software."
msgstr ""
"Calendar.social jest aplikacją kalendarza opartą na otwartych protokołach i "
"wolnym, otwartoźródłowym oprogramowaniu."
#: calsocial/templates/welcome.html:29
msgid "It is decentralised like one of its counterparts, email."
msgstr ""
"Jest zdecentralizowana tak, jak jak jeden z jej odpowiedników e-mail."
#: calsocial/templates/welcome.html:33
msgid "Go to your calendar"
msgstr "Przejdź do swojego kalendarza"
#: calsocial/templates/welcome.html:37
msgid "Peek inside"
msgstr "Zajrzyj do środka"
#: calsocial/templates/welcome.html:43
msgid "Built with users in mind"
msgstr "Stworzony z myślą o użytkownikach"
#: calsocial/templates/welcome.html:45
msgid ""
"From planning your appointments to organising large scale events Calendar."
"social can help with all your scheduling needs."
msgstr ""
"Calendar.social może pomóc w każdej potrzebie związanej z planowaniem, od "
"planowania spotkań do organizowania wydarzeń na większą skalę."
#: calsocial/templates/welcome.html:54
msgid "user"
msgid_plural "users"
msgstr[0] "użytkownik"
msgstr[1] "użytkowników"
msgstr[2] "użytkowników"
#: calsocial/templates/welcome.html:60
msgid "event"
msgid_plural "events"
msgstr[0] "wydarzenia"
msgstr[1] "wydarzenia"
msgstr[2] "wydarzeń"
#: calsocial/templates/welcome.html:67
msgid "Built for people"
msgstr "Zbudowany dla ludzi"
#: calsocial/templates/welcome.html:69
msgid "Calendar.social is not a commercial network."
msgstr "Calendar.social nie jest komercyjną siecią."
#: calsocial/templates/welcome.html:70
msgid "No advertising, no data mining, no walled gardens."
msgstr "Brak reklam, zbierania danych i ograniczeń."
#: calsocial/templates/welcome.html:71
msgid "There is no central authority."
msgstr "Brak centralnej władzy."
#: calsocial/templates/welcome.html:77
msgid "Administered by"
msgstr "Administrowane przez"
#: calsocial/templates/account/active-sessions.html:4
#: calsocial/templates/account/settings-base.html:9
msgid "Active sessions"
msgstr "Aktywne sesje"
#: calsocial/templates/account/active-sessions.html:10
msgid "Invalidate"
msgstr "Unieważnij"
#: calsocial/templates/account/first-steps.html:5
msgid "First steps"
msgstr "Pierwsze kroki"
#: calsocial/templates/account/first-steps.html:7
msgid "Welcome to Calendar.social!"
msgstr "Witamy na Calendar.social!"
#: calsocial/templates/account/first-steps.html:10
msgid ""
"These are the first steps you should make before you can start using the "
"site."
msgstr ""
"Oto pierwsze kroki, które powinieneś wykonać, zanim zaczniesz używać tej "
"strony."
#: calsocial/templates/account/follow-requests.html:4
msgid "Follow requests"
msgstr "Prośby o możliwość obserwacji"
#: calsocial/templates/account/follow-requests.html:10
msgid "Accept"
msgstr "Zaakceptuj"
#: calsocial/templates/account/follow-requests.html:15
msgid "No requests to display."
msgstr "Brak próśb do wyświetlenia."
#: calsocial/templates/account/follow-requests.html:19
msgid "Your profile is not locked."
msgstr "Twój profil nie jest zablokowany."
#: calsocial/templates/account/follow-requests.html:20
msgid "Anyone can follow you without your consent."
msgstr "Każdy może Cię zaobserwować bez Twojego zezwolenia."
#: calsocial/templates/account/notifications.html:7
msgid "Nothing to show."
msgstr "Nie ma nic do pokazania."
#: calsocial/templates/account/profile-edit.html:5
#: calsocial/templates/account/settings-base.html:7
msgid "Edit profile"
msgstr "Edytuj profil"
#: calsocial/templates/account/registration.html:17
msgid "Register"
msgstr "Zarejestruj się"

View File

@ -0,0 +1,175 @@
# Calendar.social
# Copyright (C) 2018 Gergely Polonkai
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""Profile related tests for Calendar.social
"""
from datetime import datetime
from calsocial.models import db, Event, EventVisibility, Profile, Response, ResponseType, \
ResponseVisibility, UserFollow
from helpers import database
def test_response_visibility(database):
"""Test response visibility in different scenarios
"""
test_data = (
# Third element value descriptions:
# none=not logged in
# unknown=completely unrelated profile
# follower=spectator is following respondent
# friend=spectator and respondent are friends (mutual follow)
# attendee=spectator is an attendee of the event
# respondent=spectator is the respondent
(EventVisibility.public, ResponseVisibility.public, 'anon', True),
(EventVisibility.public, ResponseVisibility.public, 'unknown', True),
(EventVisibility.public, ResponseVisibility.public, 'follower', True),
(EventVisibility.public, ResponseVisibility.public, 'friend', True),
(EventVisibility.public, ResponseVisibility.public, 'attendee', True),
(EventVisibility.public, ResponseVisibility.public, 'organiser', True),
(EventVisibility.public, ResponseVisibility.public, 'respondent', True),
(EventVisibility.public, ResponseVisibility.followers, 'anon', False),
(EventVisibility.public, ResponseVisibility.followers, 'unknown', False),
(EventVisibility.public, ResponseVisibility.followers, 'follower', True),
(EventVisibility.public, ResponseVisibility.followers, 'friend', True),
(EventVisibility.public, ResponseVisibility.followers, 'attendee', True),
(EventVisibility.public, ResponseVisibility.followers, 'organiser', True),
(EventVisibility.public, ResponseVisibility.followers, 'respondent', True),
(EventVisibility.public, ResponseVisibility.friends, 'anon', False),
(EventVisibility.public, ResponseVisibility.friends, 'unknown', False),
(EventVisibility.public, ResponseVisibility.friends, 'follower', False),
(EventVisibility.public, ResponseVisibility.friends, 'friend', True),
(EventVisibility.public, ResponseVisibility.friends, 'attendee', True),
(EventVisibility.public, ResponseVisibility.friends, 'organiser', True),
(EventVisibility.public, ResponseVisibility.friends, 'respondent', True),
(EventVisibility.public, ResponseVisibility.attendees, 'anon', False),
(EventVisibility.public, ResponseVisibility.attendees, 'unknown', False),
(EventVisibility.public, ResponseVisibility.attendees, 'follower', False),
(EventVisibility.public, ResponseVisibility.attendees, 'friend', False),
(EventVisibility.public, ResponseVisibility.attendees, 'attendee', True),
(EventVisibility.public, ResponseVisibility.attendees, 'organiser', True),
(EventVisibility.public, ResponseVisibility.attendees, 'respondent', True),
(EventVisibility.public, ResponseVisibility.organisers, 'anon', False),
(EventVisibility.public, ResponseVisibility.organisers, 'unknown', False),
(EventVisibility.public, ResponseVisibility.organisers, 'follower', False),
(EventVisibility.public, ResponseVisibility.organisers, 'friend', False),
(EventVisibility.public, ResponseVisibility.organisers, 'attendee', False),
(EventVisibility.public, ResponseVisibility.organisers, 'organiser', True),
(EventVisibility.public, ResponseVisibility.organisers, 'respondent', True),
(EventVisibility.public, ResponseVisibility.private, 'anon', False),
(EventVisibility.public, ResponseVisibility.private, 'unknown', False),
(EventVisibility.public, ResponseVisibility.private, 'follower', False),
(EventVisibility.public, ResponseVisibility.private, 'friend', False),
(EventVisibility.public, ResponseVisibility.private, 'attendee', False),
(EventVisibility.public, ResponseVisibility.private, 'organiser', False),
(EventVisibility.public, ResponseVisibility.private, 'respondent', True),
(EventVisibility.private, ResponseVisibility.public, 'anon', False),
(EventVisibility.private, ResponseVisibility.public, 'unknown', False),
(EventVisibility.private, ResponseVisibility.public, 'follower', False),
(EventVisibility.private, ResponseVisibility.public, 'friend', False),
(EventVisibility.private, ResponseVisibility.public, 'attendee', True),
(EventVisibility.private, ResponseVisibility.public, 'organiser', True),
(EventVisibility.private, ResponseVisibility.public, 'respondent', True),
(EventVisibility.private, ResponseVisibility.followers, 'anon', False),
(EventVisibility.private, ResponseVisibility.followers, 'unknown', False),
(EventVisibility.private, ResponseVisibility.followers, 'follower', False),
(EventVisibility.private, ResponseVisibility.followers, 'friend', False),
(EventVisibility.private, ResponseVisibility.followers, 'attendee', True),
(EventVisibility.private, ResponseVisibility.followers, 'organiser', True),
(EventVisibility.private, ResponseVisibility.followers, 'respondent', True),
(EventVisibility.private, ResponseVisibility.friends, 'anon', False),
(EventVisibility.private, ResponseVisibility.friends, 'unknown', False),
(EventVisibility.private, ResponseVisibility.friends, 'follower', False),
(EventVisibility.private, ResponseVisibility.friends, 'friend', False),
(EventVisibility.private, ResponseVisibility.friends, 'attendee', True),
(EventVisibility.private, ResponseVisibility.friends, 'organiser', True),
(EventVisibility.private, ResponseVisibility.friends, 'respondent', True),
(EventVisibility.private, ResponseVisibility.attendees, 'anon', False),
(EventVisibility.private, ResponseVisibility.attendees, 'unknown', False),
(EventVisibility.private, ResponseVisibility.attendees, 'follower', False),
(EventVisibility.private, ResponseVisibility.attendees, 'friend', False),
(EventVisibility.private, ResponseVisibility.attendees, 'attendee', True),
(EventVisibility.private, ResponseVisibility.attendees, 'organiser', True),
(EventVisibility.private, ResponseVisibility.attendees, 'respondent', True),
(EventVisibility.private, ResponseVisibility.organisers, 'anon', False),
(EventVisibility.private, ResponseVisibility.organisers, 'unknown', False),
(EventVisibility.private, ResponseVisibility.organisers, 'follower', False),
(EventVisibility.private, ResponseVisibility.organisers, 'friend', False),
(EventVisibility.private, ResponseVisibility.organisers, 'attendee', False),
(EventVisibility.private, ResponseVisibility.organisers, 'organiser', True),
(EventVisibility.private, ResponseVisibility.organisers, 'respondent', True),
(EventVisibility.private, ResponseVisibility.private, 'anon', False),
(EventVisibility.private, ResponseVisibility.private, 'unknown', False),
(EventVisibility.private, ResponseVisibility.private, 'follower', False),
(EventVisibility.private, ResponseVisibility.private, 'friend', False),
(EventVisibility.private, ResponseVisibility.private, 'attendee', False),
(EventVisibility.private, ResponseVisibility.private, 'organiser', False),
(EventVisibility.private, ResponseVisibility.private, 'respondent', True),
)
for evt_vis, resp_vis, relation, exp_ret in test_data:
organiser = Profile(display_name='organiser')
event = Event(profile=organiser, visibility=evt_vis, title='Test Event', time_zone='UTC', start_time=datetime.utcnow(), end_time=datetime.utcnow())
respondent = Profile(display_name='Respondent')
response = Response(event=event, visibility=resp_vis, profile=respondent, response=ResponseType.going)
db.session.add_all([event, response])
if relation is 'anon':
spectator = None
elif relation == 'respondent':
spectator = respondent
elif relation == 'organiser':
spectator = organiser
else:
spectator = Profile(display_name='Spectator')
db.session.add(spectator)
if relation == 'follower' or relation == 'friend':
follow = UserFollow(follower=spectator, followed=respondent)
db.session.add(follow)
if relation == 'friend':
follow = UserFollow(follower=respondent, followed=spectator)
db.session.add(follow)
if relation == 'attendee':
att_response = Response(profile=spectator,
event=event,
response=ResponseType.going,
visibility=ResponseVisibility.public)
db.session.add(att_response)
db.session.commit()
notvis = ' not' if exp_ret else ''
assert_message = f'Response is{notvis} visible to {spectator} ({evt_vis}, {resp_vis}, {relation})'
assert response.visible_to(spectator) is exp_ret, assert_message