docs: Fix spelling errors caught by codespell.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2020-08-10 16:47:44 -07:00 committed by Tim Abbott
parent 2928bbc8bd
commit 60a25b2721
46 changed files with 64 additions and 64 deletions

View File

@ -18,7 +18,7 @@ jobs:
steps:
# We get workflow IDs from GitHub API so we don't have to maintain
# a hard-coded list of IDs which need to be updated when a workflow
# is added or removed. And, workflow IDs are diffrent for other forks
# is added or removed. And, workflow IDs are different for other forks
# so this is required.
- name: Get workflow IDs.
id: workflow_ids

View File

@ -617,7 +617,7 @@ def estimate_annual_recurring_revenue_by_realm() -> Dict[str, int]: # nocoverag
# During realm deactivation we instantly downgrade the plan to Limited.
# Extra users added in the final month are not charged. Also used
# for the cancelation of Free Trial.
# for the cancellation of Free Trial.
def downgrade_now(realm: Realm) -> None:
plan = get_current_plan_by_realm(realm)
if plan is None:

View File

@ -151,7 +151,7 @@ So `{1: 'a', 2: 'b', 3: 'c'}` will be printed as `{int: str, ...}`.
## Using @overload to accurately describe variations
Sometimes, a function's type is most precisely expressed as a few
possibilites, and which possibility can be determined by looking at
possibilities, and which possibility can be determined by looking at
the arguments. You can express that idea in a way mypy understands
using `@overload`. For example, `check_list` returns a `Validator`
function that verifies that an object is a list, raising an exception

View File

@ -169,7 +169,7 @@ run_test("has_unconverted_data", () => {
items: () => [{user_id: 99}],
};
// Our pill is complete and all items containt user_id, so
// Our pill is complete and all items contain user_id, so
// we do NOT have unconverted data.
assert.equal(compose_pm_pill.has_unconverted_data(), false);

View File

@ -467,7 +467,7 @@ run_test("redundancies", () => {
assert(filter.can_bucket_by("is-private", "not-pm-with"));
});
run_test("canonicalizations", () => {
run_test("canonicalization", () => {
assert.equal(Filter.canonicalize_operator("Is"), "is");
assert.equal(Filter.canonicalize_operator("Stream"), "stream");
assert.equal(Filter.canonicalize_operator("Subject"), "topic");

View File

@ -237,7 +237,7 @@ run_test("emoji", () => {
assert(called);
// Set page paramaters back so that test run order is independent
// Set page parameters back so that test run order is independent
page_params.emojiset = "apple";
});

View File

@ -92,7 +92,7 @@ run_test("finding_related_objects", () => {
update_message_emoji("foo.png");
assert.equal(emoji.attr("src"), "foo.png");
// Sometimes you want to deliberatly test paths that do not find an
// Sometimes you want to deliberately test paths that do not find an
// element. You can pass 'false' as the result for those cases.
emoji.set_find_results(".random", false);
assert.equal(emoji.find(".random").length, 0);

View File

@ -22,7 +22,7 @@ class CommonUtils {
// pseudo selector to actually wait for typeahead item that
// is visible; there can be typeahead item with this selector
// that is invisible because it is meant for something else
// e.g. private message input typeahead is diffrent from topic
// e.g. private message input typeahead is different from topic
// input typeahead but both can be present in the dom.
await page.waitForFunction(() => {
const selector = ".typeahead-menu .active a:visible";
@ -198,7 +198,7 @@ class CommonUtils {
await page.goto(this.realm_url);
const menu_selector = "#settings-dropdown";
const logout_selector = 'a[href="#logout"]';
console.log("Loggin out");
console.log("Logging out");
await page.waitForSelector(menu_selector, {visible: true});
await page.click(menu_selector);
await page.waitForSelector(logout_selector);

View File

@ -108,7 +108,7 @@ async function test_user_filter_ui(
await page.waitForSelector(cordelia_checkbox, {hidden: true});
await page.waitForSelector(othello_checkbox, {visible: true});
// Filter shouln't affect streams.
// Filter shouldn't affect streams.
await page.waitForSelector(scotland_checkbox, {visible: true});
await page.waitForSelector(rome_checkbox, {visible: true});

View File

@ -87,7 +87,7 @@ def generate_secrets(development: bool = False) -> None:
if need_secret(name):
add_secret(name, random_token())
# These secrets are exclusive to a Zulip develpment environment.
# These secrets are exclusive to a Zulip development environment.
# We use postgres peer authentication by default in production,
# and initial_password_salt is used to generate passwords for the
# test/development database users. See `manage.py

View File

@ -517,7 +517,7 @@ exports.get_stream_topic_data = (hacky_this) => {
const opts = {};
const message_row = hacky_this.$element.closest(".message_row");
if (message_row.length === 1) {
// we are editting a message so we try to use it's keys.
// we are editing a message so we try to use it's keys.
const msg = message_store.get(rows.id(message_row));
if (msg.type === "stream") {
opts.stream = msg.stream;

View File

@ -96,7 +96,7 @@ const DropdownListWidget = function (opts) {
});
dropdown_toggle.on("focus", (e) => {
// On opening a Bootstrap Dropdown, the parent element recieves focus.
// On opening a Bootstrap Dropdown, the parent element receives focus.
// Here, we want our search input to have focus instead.
e.preventDefault();
search_input.trigger("focus");

View File

@ -7,7 +7,7 @@ const DEFAULTS = {
};
// ----------------------------------------------------
// This function describes (programatically) how to use
// This function describes (programmatically) how to use
// the list_render widget.
// ----------------------------------------------------

View File

@ -87,7 +87,7 @@ function get_topic_key(stream_id, topic) {
}
exports.process_messages = function (messages) {
// FIX: Currently, we do a complete_rerender everytime
// FIX: Currently, we do a complete_rerender every time
// we process a new message.
// While this is inexpensive and handles all the cases itself,
// the UX can be bad if user wants to scroll down the list as
@ -516,7 +516,7 @@ exports.change_focused_element = function (e, input_key) {
// Note: current_focus_elem can be different here, so we just
// set current_focus_elem to the input box, we don't want .trigger("focus") on
// it since it is already focused.
// We only do this for search beacuse we don't want the focus to
// We only do this for search because we don't want the focus to
// go away from the input box when `revive_current_focus` is called
// on rerender when user is typing.
current_focus_elem = $("#recent_topics_search");

View File

@ -5,7 +5,7 @@ const moment = require("moment");
/*
rendered_markdown
This module provies a single function 'update_elements' to
This module provides a single function 'update_elements' to
update any renamed users/streams/groups etc. and other
dynamic parts of our rendered messages.

View File

@ -32,7 +32,7 @@ class SettingsPanelMenu {
this.main_elem.show();
const section = this.current_tab();
if (two_column_mode()) {
// In one colum mode want to show the settings list, not the first settings section.
// In one column mode want to show the settings list, not the first settings section.
this.activate_section_or_default(section);
}
this.curr_li.trigger("focus");

View File

@ -146,7 +146,7 @@ No changes; feature level used for Zulip 3.0 release.
* [`GET users/me`](/api/get-own-user): Added `avatar_version`, `is_guest`,
`is_active`, `timezone`, and `date_joined` fields to the User objects.
* [`GET users/me`](/api/get-own-user): Removed `client_id` and `short_name`
from the reponse to this endpoint. These fields had no purpose and
from the response to this endpoint. These fields had no purpose and
were inconsistent with other API responses describing users.
**Feature level 9**

View File

@ -16,6 +16,6 @@ for working in a dark space.
The default is **Automatic**, which detects which theme to use based
on the color scheme used by your operating system.
You can also specifc **Night mode** or **Day mode** if you'd like
You can also specify **Night mode** or **Day mode** if you'd like
Zulip to use the same color scheme regardless of your operating system
configuration.

View File

@ -164,7 +164,7 @@ def build_recipient_and_subscription(
# For streams
# Initial recipients correspond to intitial streams
# Initial recipients correspond to initial streams
# We enumerate all streams, and build a recipient for each
# Hence 'recipient_id'=n corresponds to 'stream_id'=n
for stream in zerver_stream:

View File

@ -4192,7 +4192,7 @@ def do_update_mobile_push_notification(message: Message,
#
# A perfect implementation would also support updating the message
# in a sent notification if a message was edited to mention a
# group rather than a user (or vise versa), though it is likely
# group rather than a user (or vice versa), though it is likely
# not worth the effort to do such a change.
if not message.is_stream_message():
return

View File

@ -229,7 +229,7 @@ NON_EXPORTED_TABLES = {
# Fillstate will require some cleverness to do the right partial export.
'analytics_fillstate',
# These are for unfinished features; we'll want to add them ot the
# These are for unfinished features; we'll want to add them to the
# export before they reach full production status.
'zerver_defaultstreamgroup',
'zerver_defaultstreamgroup_streams',

View File

@ -130,7 +130,7 @@ def add_flair(paragraphs: List[str], gens: Dict[str, Any]) -> List[str]:
def add_md(mode: str, text: str) -> str:
# mode means: bold, italic, etc.
# to add a list at the end of a paragraph, * iterm one\n * item two
# to add a list at the end of a paragraph, * item one\n * item two
# find out how long the line is, then insert the mode before the end

View File

@ -73,7 +73,7 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
continue
if 'oneOf' in return_values[return_value]:
# For elements using oneOf there are two descriptions. The first description
# should be at level with the oneOf and should containg the basic non-specific
# should be at level with the oneOf and should contain the basic non-specific
# description of the endpoint. Then for each element of oneOf there is a
# specialized description for that particular case. The description used
# right below is the main description.
@ -115,7 +115,7 @@ class APIReturnValuesTablePreprocessor(Preprocessor):
' {event_type} {op}</h3></p></div> \n{description}\n\n\n')
for events in events_dict['oneOf']:
# `id` is present in every event so it will be redundant to display
# it everytime. So remove it from the dictionary.
# it every time. So remove it from the dictionary.
events['properties'].pop('id')
event_type: Dict[str, Any] = events['properties'].pop('type')
event_type_str: str = event_type['enum'][0]

View File

@ -191,7 +191,7 @@ class ZulipTestCase(TestCase):
url, query_data = self.extract_api_suffix_url(url)
if len(query_data) != 0:
# In some cases the query parameters are defined in the url itself. In such cases
# The `data` argument of our function is not used. Hence get `data` arguement
# The `data` argument of our function is not used. Hence get `data` argument
# from url.
data = query_data
response_validated = validate_against_openapi_schema(content, url, method, str(result.status_code))

View File

@ -42,7 +42,7 @@ def check_full_name(full_name_raw: str) -> str:
raise JsonableError(_("Invalid characters in name!"))
# Names ending with e.g. `|15` could be ambiguous for
# sloppily-written parsers of our markdown syntax for mentioning
# users with ambigious names, and likely have no real use, so we
# users with ambiguous names, and likely have no real use, so we
# ban them.
if re.search(r"\|\d+$", full_name_raw):
raise JsonableError(_("Invalid format!"))

View File

@ -378,14 +378,14 @@ def to_non_negative_int(s: str, max_int_size: int=2**32-1) -> int:
return x
def to_positive_or_allowed_int(allowed_integer: int) -> Callable[[str], int]:
def convertor(s: str) -> int:
def converter(s: str) -> int:
x = int(s)
if x == allowed_integer:
return x
if x == 0:
raise ValueError("argument is 0")
return to_non_negative_int(s)
return convertor
return converter
def check_string_or_int_list(var_name: str, val: object) -> Union[str, List[int]]:
if isinstance(val, str):

View File

@ -25,10 +25,10 @@ class Command(ZulipBaseCommand):
help='Path to a markdown-format body for the email.')
parser.add_argument('--subject',
type=str,
help='Subject for the email. It can be declarated in markdown file in headers')
help='Subject for the email. It can be declared in markdown file in headers')
parser.add_argument('--from-name',
type=str,
help='From line for the email. It can be declarated in markdown file in headers')
help='From line for the email. It can be declared in markdown file in headers')
parser.add_argument('--reply-to',
type=str,
help='Optional reply-to line for the email')

View File

@ -18,7 +18,7 @@ VIDEO_CHAT_PROVIDERS = {
def remove_google_hangouts_provider(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None:
# We are removing the Google Hangout integration because Google has
# removed the Hangouts brand. All the realms that used Hangouts as
# their video chat provided are now setted to the default, jitsi.
# their video chat provided are now set to the default, jitsi.
Realm = apps.get_model('zerver', 'Realm')
Realm.objects.filter(video_chat_provider=VIDEO_CHAT_PROVIDERS['google_hangouts']['id']).update(
video_chat_provider=VIDEO_CHAT_PROVIDERS['jitsi_meet']['id']

View File

@ -1131,7 +1131,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
ROLE_ID_TO_NAME_MAP = {
ROLE_REALM_OWNER: _("Organization owner"),
ROLE_REALM_ADMINISTRATOR: _("Organization adminstrator"),
ROLE_REALM_ADMINISTRATOR: _("Organization administrator"),
ROLE_MEMBER: _("Member"),
ROLE_GUEST: _("Guest"),
}

View File

@ -49,7 +49,7 @@ class OpenAPISpec():
self.last_update = os.path.getmtime(self.path)
def create_regex_dict(self) -> None:
# Alogrithm description:
# Algorithm description:
# We have 2 types of endpoints
# 1.with path arguments 2. without path arguments
# In validate_against_openapi_schema we directly check
@ -200,7 +200,7 @@ def fix_events(content: Dict[str, Any]) -> None:
only zulip.yaml changes and minimal other changes. It should be removed
as soon as `/events` documentation is complete.
"""
# 'user' is deprecated so remove its occurences from the events array
# 'user' is deprecated so remove its occurrences from the events array
for event in content['events']:
event.pop('user', None)

View File

@ -321,7 +321,7 @@ paths:
The email of the user.
**Deprecated**: This field will be removed in a future
release as it is redunant with the `user_id`.
release as it is redundant with the `user_id`.
deprecated: true
timezone:
type: string
@ -883,7 +883,7 @@ paths:
The email of the user.
**Deprecated**: This field will be removed in a future
release as it is redunant with the `user_id`.
release as it is redundant with the `user_id`.
deprecated: true
server_timestamp:
type: number
@ -894,7 +894,7 @@ paths:
type: object
description: |
An object contatining a set of objects which describe the
the user's presence on various platfroms.
the user's presence on various platforms.
additionalProperties:
$ref: "#/components/schemas/Presence"
additionalProperties: false
@ -2037,7 +2037,7 @@ paths:
- update_message_flags
operation:
description: |
Whether the flags are added or rmeoved.
Whether the flags are added or removed.
type: string
enum:
- add
@ -2082,7 +2082,7 @@ paths:
operation:
type: string
description: |
Whether the flags are added or rmeoved.
Whether the flags are added or removed.
enum:
- remove
flag:
@ -2144,7 +2144,7 @@ paths:
additionalProperties: false
description: |
Event sent to all users in a Zulip organization
when a propety of a user group is changed.
when a property of a user group is changed.
properties:
id:
type: integer
@ -5868,7 +5868,7 @@ paths:
stream_id:
type: integer
description: |
The id of the stream to which the messsage was sent.
The id of the stream to which the message was sent.
message_ids:
type: array
description: |
@ -5891,7 +5891,7 @@ paths:
type: string
description: |
A string containing the ids of all users in the huddle(group PMs)
seperated by commas(,). Example: "1,2,3".
separated by commas(,). Example: "1,2,3".
message_ids:
type: array
description: |
@ -7131,7 +7131,7 @@ paths:
description: |
A unique, table, machine-readable name for the authentication method,
intended to be used by clients with special behavior for specific
authenatication methods to correctly identify the method.
authentication methods to correctly identify the method.
display_name:
type: string
description: |

View File

@ -8,8 +8,8 @@
"stripped_subject": ""
},
{
"original_subject": "Re: Fwd: Re: Sofware",
"stripped_subject": "Sofware"
"original_subject": "Re: Fwd: Re: Software",
"stripped_subject": "Software"
},
{
"original_subject": "Fwd : Re : Re: Many",

View File

@ -14,7 +14,7 @@
{"type":"direct_channel","direct_channel":{"members":["ron","harry"],"favorited_by":null,"header":""}}
{"type":"direct_channel","direct_channel":{"members":["ron","harry", "ginny"],"favorited_by":null,"header":""}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry"],"user":"ron","message":"hey harry","create_at":1566376137676,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry"],"user":"harry","message":"whats up","create_at":1566376318568,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry"],"user":"harry","message":"what's up","create_at":1566376318568,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry","ginny"],"user":"ginny","message":"Who is going to Hogesmead this weekend?","create_at":1566376226493,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry","ginny"],"user":"harry","message":"I am going.","create_at":1566376311350,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}
{"type":"direct_post","direct_post":{"channel_members":["ron","harry","ginny"],"user":"ron","message":"I am going as well","create_at":1566376286363,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}

View File

@ -30,7 +30,7 @@ class TestIntegrationsDevPanel(ZulipTestCase):
self.assertEqual(ujson.loads(response.content), expected_response)
# Intention of this test looks like to trigger keyError
# so just testing KeyError is printed along wth Traceback in logs
# so just testing KeyError is printed along with Traceback in logs
self.assertTrue("KeyError" in logs.output[0])
self.assertTrue("Traceback (most recent call last)" in logs.output[0])
self.assertEqual(logs.output[1], "ERROR:django.request:Internal Server Error: /api/v1/external/airbrake")

View File

@ -1229,7 +1229,7 @@ class MarkdownTest(ZulipTestCase):
content = """Hello, everyone. Prod deployment has been completed
And this is a new line
to test out how markdown convert this into something line ending splitted array
to test out how markdown convert this into something line ending split array
and this is a new line
last"""
render(msg, content)
@ -2156,7 +2156,7 @@ class MarkdownErrorTests(ZulipTestCase):
self.send_stream_message(self.example_user("othello"), "Denmark", message)
def test_ultra_long_rendering(self) -> None:
"""A rendered message with an ultra-long lenght (> 10 * MAX_MESSAGE_LENGTH)
"""A rendered message with an ultra-long length (> 10 * MAX_MESSAGE_LENGTH)
throws an exception"""
msg = 'mock rendered message\n' * MAX_MESSAGE_LENGTH

View File

@ -150,7 +150,7 @@ class OpenAPIToolsTest(ZulipTestCase):
# Check that validate_against_openapi_schema correctly
# descends into 'deep' objects and arrays. Test 1 should
# pass, Test 2 has a 'deep' extraneous key and Test 3 has a
# 'deep' opaque object. Also the parameters are a heterogenous
# 'deep' opaque object. Also the parameters are a heterogeneous
# mix of arrays and objects to verify that our descent logic
# correctly gets to the the deeply nested objects.
with open(os.path.join(os.path.dirname(OPENAPI_SPEC_PATH),
@ -480,7 +480,7 @@ do not match the types declared in the implementation of {function.__name__}.\n"
# checked in the view code.
#
# Meanwhile `profile_data` in /users/{user_id}: GET is
# taken as array of objects. So treat them seperately.
# taken as array of objects. So treat them separately.
schema = element["content"]["application/json"]["schema"]
json_params[name] = schema_type(schema)
continue

View File

@ -817,7 +817,7 @@ class TestCleaningArchive(ArchiveMessagesTestingBase):
class TestGetRealmAndStreamsForArchiving(ZulipTestCase):
def fix_ordering_of_result(self, result: List[Tuple[Realm, List[Stream]]]) -> None:
"""
This is a helper for giving the struture returned by get_realms_and_streams_for_archiving
This is a helper for giving the structure returned by get_realms_and_streams_for_archiving
a consistent ordering.
"""
# Sort the list of tuples by realm id:

View File

@ -34,7 +34,7 @@ def register_development_user(request: HttpRequest) -> HttpResponse:
activation_url = create_confirmation_link(prereg,
Confirmation.USER_REGISTRATION)
key = activation_url.split('/')[-1]
# Need to add test data to POST request as it doesnt originally contain the required parameters
# Need to add test data to POST request as it doesn't originally contain the required parameters
modify_postdata(request, key=key, full_name=name, password='test', terms='true')
return accounts_register(request)
@ -50,7 +50,7 @@ def register_development_realm(request: HttpRequest) -> HttpResponse:
activation_url = create_confirmation_link(prereg,
Confirmation.REALM_CREATION)
key = activation_url.split('/')[-1]
# Need to add test data to POST request as it doesnt originally contain the required parameters
# Need to add test data to POST request as it doesn't originally contain the required parameters
modify_postdata(request, key=key, realm_name=realm_name, full_name=name, password='test',
realm_subdomain=realm_name, terms='true')

View File

@ -36,7 +36,7 @@ def upload_icon(request: HttpRequest, user_profile: UserProfile) -> HttpResponse
@require_realm_admin
def delete_icon_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
# We don't actually delete the icon because it might still
# be needed if the URL was cached and it is rewrited
# be needed if the URL was cached and it is rewritten
# in any case after next update.
do_change_icon_source(user_profile.realm, user_profile.realm.ICON_FROM_GRAVATAR, acting_user=user_profile)
gravatar_url = realm_icon_url(user_profile.realm)

View File

@ -36,7 +36,7 @@ def upload_logo(request: HttpRequest, user_profile: UserProfile,
def delete_logo_backend(request: HttpRequest, user_profile: UserProfile,
night: bool=REQ(validator=check_bool)) -> HttpResponse:
# We don't actually delete the logo because it might still
# be needed if the URL was cached and it is rewrited
# be needed if the URL was cached and it is rewritten
# in any case after next update.
do_change_logo_source(user_profile.realm, user_profile.realm.LOGO_DEFAULT, night, acting_user=user_profile)
return json_success()

View File

@ -64,7 +64,7 @@ def get_zoom_sid(request: HttpRequest) -> str:
csrf.get_token(request)
# Use 'mark_sanitized' to cause Pysa to ignore the flow of user controlled
# data out of this function. 'request.META' is indeed user controlled, but
# post-HMAC ouptut is no longer meaningfully controllable.
# post-HMAC output is no longer meaningfully controllable.
return mark_sanitized(
""
if getattr(request, "_dont_enforce_csrf_checks", False)

View File

@ -347,7 +347,7 @@ EVENT_HANDLER_MAP = {
} # type Dict[str, Optional[Callable[..., List[Dict[str, str]]]]]
def get_event_handler(eventkey: str) -> Callable[..., List[Dict[str, str]]]:
# The main reason for this function existance is because of mypy
# The main reason for this function existence is because of mypy
handler: Any = EVENT_HANDLER_MAP.get(eventkey)
if handler is None:
raise UnexpectedWebhookEventType("BitBucket Server", eventkey)

View File

@ -240,7 +240,7 @@ def linkified_id(object_id: str, lower: bool=False) -> str:
# Undocumented :|
'py': ('Payment', 'payments'),
'pyr': ('Refund', 'refunds'), # Psuedo refunds. Not fully tested.
'pyr': ('Refund', 'refunds'), # Pseudo refunds. Not fully tested.
# Connect, Fraud, Orders, etc not implemented
}

View File

@ -369,7 +369,7 @@ class ConfirmationEmailWorker(QueueProcessingWorker):
@assign_queue('user_activity', queue_type="loop")
class UserActivityWorker(LoopQueueProcessingWorker):
"""The UserActivity queue is perhaps our highest-traffic queue, and
requires some care to ensure it performes adequately.
requires some care to ensure it performs adequately.
We use a LoopQueueProcessingWorker as a performance optimization
for managing the queue. The structure of UserActivity records is

View File

@ -1197,7 +1197,7 @@ def social_associate_user_helper(backend: BaseAuth, return_data: Dict[str, Any],
return_data["full_name"] = full_name
else:
# Some authentications methods like Apple and SAML send
# first name and last name as seperate attributes. In that case
# first name and last name as separate attributes. In that case
# we construct the full name from them.
return_data["full_name"] = f"{first_name or ''} {last_name or ''}".strip() # strip removes the unnecessary ' '

View File

@ -366,7 +366,7 @@ SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # 2 weeks
# For frontend (JavaScript) tracebacks
#BROWSER_ERROR_REPORTING = False
# Controls the DSN used to report erors to Sentry.io
# Controls the DSN used to report errors to Sentry.io
#SENTRY_DSN = 'https://bbb@bbb.ingest.sentry.io/1235'
# If True, each log message in the server logs will identify the