mirror of
https://github.com/zulip/zulip.git
synced 2025-11-01 12:33:40 +00:00
Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bb22d2535 | ||
|
|
c93cef91e8 | ||
|
|
0c227217b2 | ||
|
|
b5c7a79bdf | ||
|
|
7e991c8c7e | ||
|
|
974c98a45a | ||
|
|
5784bdd0ed | ||
|
|
e10ea15aa9 | ||
|
|
d860242220 | ||
|
|
b2c3f5e510 | ||
|
|
232fe495be | ||
|
|
c20afad828 | ||
|
|
3fad49a9c1 | ||
|
|
cc95aac176 | ||
|
|
1b27ec9fae | ||
|
|
ebd74239a2 | ||
|
|
8dcb1e489d | ||
|
|
4e7419e168 | ||
|
|
8567e19fff | ||
|
|
9aa7c19891 | ||
|
|
4fdbf274ac | ||
|
|
218eca14b8 | ||
|
|
08efebbaff | ||
|
|
1c819208d0 | ||
|
|
8424649c70 | ||
|
|
33d8c190d8 | ||
|
|
0213b811ec | ||
|
|
c27324927e | ||
|
|
c087ed4c26 | ||
|
|
ffc1f81cde | ||
|
|
90b6fe2c6e | ||
|
|
36cebad4c0 | ||
|
|
f33fbb527c | ||
|
|
134a8d4301 | ||
|
|
a07f64a463 | ||
|
|
e9af26df6e | ||
|
|
7f6b423532 | ||
|
|
d95fb34ba7 | ||
|
|
5ff759d35c | ||
|
|
a0d1074212 | ||
|
|
2e1e2b08f1 | ||
|
|
b44a1b68f6 | ||
|
|
c3adbcea13 | ||
|
|
e088b343b3 | ||
|
|
1d559bbffa | ||
|
|
cb24f93bba | ||
|
|
868180a25d | ||
|
|
20fc1f651a | ||
|
|
0d79d6735a | ||
|
|
45568a08c0 | ||
|
|
22152a0662 | ||
|
|
9bbb336441 | ||
|
|
3d966f1af9 | ||
|
|
ab98f3801f | ||
|
|
ddca8a7f9a | ||
|
|
c1c3dfced5 | ||
|
|
2d3f505505 | ||
|
|
d3573af95c | ||
|
|
859d88f76c | ||
|
|
9a0fb497a4 | ||
|
|
7ea4ad75af | ||
|
|
ae000bfdba | ||
|
|
551b387164 | ||
|
|
720d16e809 | ||
|
|
f338ff64c3 | ||
|
|
98610c984c | ||
|
|
ab965e5892 | ||
|
|
7a03827047 | ||
|
|
5954e622bc | ||
|
|
687db48ea8 | ||
|
|
399391c3aa | ||
|
|
cd5eec5eea | ||
|
|
e7d48c0c10 | ||
|
|
023dfc01ba | ||
|
|
5d9285fff3 | ||
|
|
53f353ec26 | ||
|
|
245c87c567 | ||
|
|
26aa4d57e3 | ||
|
|
bee225782a | ||
|
|
4a6e69357a | ||
|
|
3e6d3810d4 | ||
|
|
bc21dde235 | ||
|
|
182ce488e2 | ||
|
|
bd557a9a13 | ||
|
|
7e8ead7325 | ||
|
|
8fa783f13d | ||
|
|
11924f4b66 | ||
|
|
f01cbba0ce | ||
|
|
31050be173 | ||
|
|
56d857ca89 | ||
|
|
d587252ddb | ||
|
|
eadefdf2f5 | ||
|
|
c05bbd0fd4 | ||
|
|
deedda2c18 | ||
|
|
9bec6bb5eb | ||
|
|
634b6ea97b | ||
|
|
10583bdb32 | ||
|
|
ebb6a92f71 | ||
|
|
80b7df1b0d | ||
|
|
7b6cee1164 | ||
|
|
99cc5598ac | ||
|
|
d23778869f | ||
|
|
6ba333c2ff | ||
|
|
3cf07d1671 | ||
|
|
1b4832a703 | ||
|
|
af5958e407 | ||
|
|
a659944fe3 | ||
|
|
19db2fa773 | ||
|
|
b303477e86 | ||
|
|
5c01e23776 |
12
.github/workflows/production-suite.yml
vendored
12
.github/workflows/production-suite.yml
vendored
@@ -68,22 +68,22 @@ jobs:
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /srv/zulip-npm-cache
|
||||
key: v1-yarn-deps-${{ github.job }}-${{ hashFiles('package.json') }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: v1-yarn-deps-${{ github.job }}
|
||||
key: v1-yarn-deps-bionic-${{ hashFiles('package.json') }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: v1-yarn-deps-bionic
|
||||
|
||||
- name: Restore python cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /srv/zulip-venv-cache
|
||||
key: v1-venv-${{ github.job }}-${{ hashFiles('requirements/dev.txt') }}
|
||||
restore-keys: v1-venv-${{ github.job }}
|
||||
key: v1-venv-bionic-${{ hashFiles('requirements/dev.txt') }}
|
||||
restore-keys: v1-venv-bionic
|
||||
|
||||
- name: Restore emoji cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /srv/zulip-emoji-cache
|
||||
key: v1-emoji-${{ github.job }}-${{ hashFiles('tools/setup/emoji/emoji_map.json') }}-${{ hashFiles('tools/setup/emoji/build_emoji') }}-${{ hashFiles('tools/setup/emoji/emoji_setup_utils.py') }}-${{ hashFiles('tools/setup/emoji/emoji_names.py') }}-${{ hashFiles('package.json') }}
|
||||
restore-keys: v1-emoji-${{ github.job }}
|
||||
key: v1-emoji-bionic-${{ hashFiles('tools/setup/emoji/emoji_map.json') }}-${{ hashFiles('tools/setup/emoji/build_emoji') }}-${{ hashFiles('tools/setup/emoji/emoji_setup_utils.py') }}-${{ hashFiles('tools/setup/emoji/emoji_names.py') }}-${{ hashFiles('package.json') }}
|
||||
restore-keys: v1-emoji-bionic
|
||||
|
||||
- name: Do Bionic hack
|
||||
run: |
|
||||
|
||||
@@ -34,10 +34,10 @@ def render_confirmation_key_error(
|
||||
request: HttpRequest, exception: ConfirmationKeyException
|
||||
) -> HttpResponse:
|
||||
if exception.error_type == ConfirmationKeyException.WRONG_LENGTH:
|
||||
return render(request, "confirmation/link_malformed.html")
|
||||
return render(request, "confirmation/link_malformed.html", status=404)
|
||||
if exception.error_type == ConfirmationKeyException.EXPIRED:
|
||||
return render(request, "confirmation/link_expired.html")
|
||||
return render(request, "confirmation/link_does_not_exist.html")
|
||||
return render(request, "confirmation/link_expired.html", status=404)
|
||||
return render(request, "confirmation/link_does_not_exist.html", status=404)
|
||||
|
||||
|
||||
def generate_key() -> str:
|
||||
@@ -143,9 +143,9 @@ class ConfirmationType:
|
||||
|
||||
|
||||
_properties = {
|
||||
Confirmation.USER_REGISTRATION: ConfirmationType("check_prereg_key_and_redirect"),
|
||||
Confirmation.USER_REGISTRATION: ConfirmationType("get_prereg_key_and_redirect"),
|
||||
Confirmation.INVITATION: ConfirmationType(
|
||||
"check_prereg_key_and_redirect", validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS
|
||||
"get_prereg_key_and_redirect", validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS
|
||||
),
|
||||
Confirmation.EMAIL_CHANGE: ConfirmationType("confirm_email_change"),
|
||||
Confirmation.UNSUBSCRIBE: ConfirmationType(
|
||||
@@ -155,7 +155,7 @@ _properties = {
|
||||
Confirmation.MULTIUSE_INVITE: ConfirmationType(
|
||||
"join", validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS
|
||||
),
|
||||
Confirmation.REALM_CREATION: ConfirmationType("check_prereg_key_and_redirect"),
|
||||
Confirmation.REALM_CREATION: ConfirmationType("get_prereg_key_and_redirect"),
|
||||
Confirmation.REALM_REACTIVATION: ConfirmationType("realm_reactivation"),
|
||||
}
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ different.
|
||||
mkdir -p /var/lib/zulip/certbot-webroot/
|
||||
# if nginx running this will fail and you need to run `service nginx stop`
|
||||
/home/zulipdev/zulip/scripts/setup/setup-certbot \
|
||||
hostname.example.com --no-zulip-conf \
|
||||
hostname.example.com \
|
||||
--email=username@example.com --method=standalone
|
||||
```
|
||||
|
||||
|
||||
@@ -7,6 +7,109 @@ up-to-date list of raw changes.
|
||||
|
||||
## Zulip 4.x series
|
||||
|
||||
## Zulip 4.10 -- 2022-02-25
|
||||
|
||||
- CVE-2022-21706: Reusable invitation links could be improperly used
|
||||
for other organizations.
|
||||
- CVE-2021-3967: Enforce that regenerating an API key must be done
|
||||
with an API key, not a cookie. Thanks to nhiephon
|
||||
(twitter.com/_nhiephon) for their responsible disclosure of this
|
||||
vulnerability.
|
||||
- Fixed a bug with the `reindex-textual-data` tool, where it would
|
||||
sometimes fail to find the libraries it needed.
|
||||
- Pin PostgreSQL to 10.19, 11.14, 12.9, 13.5 or 14.1 to avoid a
|
||||
regression which caused deploys with PGroonga enabled to
|
||||
unpredictably fail database queries with the error `variable not
|
||||
found in subplan target list`.
|
||||
- Fix ARM64 support; however, the wal-g binary is not yet supported on
|
||||
ARM64 (zulip/zulip#21070).
|
||||
|
||||
## Zulip 4.9 -- 2022-01-24
|
||||
|
||||
- CVE-2021-43799: Remote execution of code involving RabbitMQ.
|
||||
- Closed access to RabbitMQ port 25672; initial installs tried to
|
||||
close this port, but failed to restart RabbitMQ for the
|
||||
configuration.
|
||||
- Removed the `rabbitmq.nodename` configuration in `zulip.conf`; all
|
||||
RabbitMQ instances will be reconfigured to have a nodename of
|
||||
`zulip@localhost`. You can remove this setting from your
|
||||
`zulip.conf` configuration file, if it exists.
|
||||
- Added missing support for the Camo image proxy in the Docker
|
||||
image. This resolves a longstanding issue with image previews, if
|
||||
enabled, appearing as broken images for Docker-based installs.
|
||||
- Fixed a bug which allowed a user to edit a message to add a wildcard
|
||||
mention when they did not have permissions to send such messages
|
||||
originally.
|
||||
- Fixed a bug in the tool that corrects database corruption caused by
|
||||
updating the operating system hosting PostgreSQL, which previously
|
||||
omitted some indexes from its verification. If you updated the
|
||||
operating system of your Zulip instance from Ubuntu 18.04 to 20.04,
|
||||
or from Debian Stretch to Debian Buster, you should run the tool,
|
||||
even if you did so previously; full details and instructions are
|
||||
available in the previous blog post.
|
||||
- Began routing requests from the Camo image proxy through a
|
||||
non-Smokescreen proxy, if one is configured; because Camo includes
|
||||
logic to deny access to private subnets, routing its requests
|
||||
through Smokescreen is generally not necessary.
|
||||
- Fixed a bug where changing the Camo secret required running
|
||||
`zulip-puppet-apply`.
|
||||
- Fixed `scripts/setup/compare-settings-to-template` to be able to run
|
||||
from any directory.
|
||||
- Switched Let's Encrypt renewal to use its own timer, rather than our
|
||||
custom cron job. This fixes a bug where occasionally `nginx` would
|
||||
not reload after getting an updated certificate.
|
||||
- Updated documentation and tooling to note that installs using
|
||||
`upgrade-zulip-from-git` require 3 GB of RAM, or 2 GB and at least 1
|
||||
GB of swap.
|
||||
|
||||
## Zulip 4.8 -- 2021-12-01
|
||||
|
||||
- CVE-2021-43791: Zulip could fail to enforce expiration dates
|
||||
on confirmation keys, allowing users to potentially use expired
|
||||
invitations, self-registrations, or realm creation links.
|
||||
- Began installing Smokescreen to harden Zulip against SSRF attacks by
|
||||
default. Zulip has offered Smokescreen as an option since Zulip
|
||||
4.0. Existing installs which configured an outgoing proxy which is
|
||||
not on `localhost:4750` will continue to use that; all other
|
||||
installations will begin having a Smokescreen installation listening
|
||||
on 127.0.0.1, which Zulip will proxy traffic through. The version of
|
||||
Smokescreen was also upgraded.
|
||||
- Replaced the camo image proxy with go-camo, a maintained
|
||||
reimplementation that also protects against SSRF attacks. This
|
||||
server now listens only on 127.0.0.1 when it is deployed as part of
|
||||
a standalone deployment.
|
||||
- Began using camo for images displayed in URL previews. This improves
|
||||
privacy and also resolves an issue where an image link to a third
|
||||
party server with an expired or otherwise invalid SSL certificate
|
||||
would trigger a confusing pop-up window for Zulip Desktop users.
|
||||
- Fixed a bug which could cause Tornado to shut down improperly
|
||||
(causing an immediate full-page reload for their clients) when
|
||||
restarting a heavily loaded Zulip server.
|
||||
- Updated Python dependencies.
|
||||
- Truncated large “remove” mobile notification events so that marking
|
||||
hundreds of private messages or other notifiable messages as read at
|
||||
once won’t exceed Apple’s 4 KB notification size limit.
|
||||
- Slack importer improvements:
|
||||
- Ensured that generated fake email addresses for Slack bots are
|
||||
unique.
|
||||
- Added support for importing Slack exports from a directory, not
|
||||
just a .zip file.
|
||||
- Provided better error messages with invalid Slack tokens.
|
||||
- Added support for non-ASCII Unicode folder names on Windows.
|
||||
- Add support for V3 Pagerduty webhook.
|
||||
- Updated documentation for Apache SSO, which now requires additional
|
||||
configuration now that Zulip uses a C extension (the `re2` module).
|
||||
- Fixed a bug where an empty name in a SAML response would raise an
|
||||
error.
|
||||
- Ensured that `deliver_scheduled_emails` and
|
||||
`deliver_scheduled_messages` did not double-deliver if run on
|
||||
multiple servers at once.
|
||||
- Extended Certbot troubleshooting documentation.
|
||||
- Fixed a bug in soft deactivation catch-up code, in cases where a
|
||||
race condition had created multiple subscription deactivation
|
||||
entries for a single user and single stream in the audit log.
|
||||
- Updated translations, including adding a Sinhala translation.
|
||||
|
||||
### 4.7 -- 2021-10-04
|
||||
|
||||
- CVE-2021-41115: Prevent organization administrators from affecting
|
||||
@@ -197,7 +300,7 @@ up-to-date list of raw changes.
|
||||
major release.
|
||||
|
||||
[docker-zulip-manual]: https://github.com/zulip/docker-zulip#manual-configuration
|
||||
[smokescreen]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
[update-settings-docs]: ../production/upgrade-or-modify.html#updating-settings-py-inline-documentation
|
||||
|
||||
#### Full feature changelog
|
||||
|
||||
@@ -206,28 +206,19 @@ behind reverse proxies.
|
||||
|
||||
[using-http]: ../production/deployment.html#configuring-zulip-to-allow-http
|
||||
|
||||
## Using an outgoing HTTP proxy
|
||||
## Customizing the outgoing HTTP proxy
|
||||
|
||||
Zulip supports routing all of its outgoing HTTP and HTTPS traffic
|
||||
through an HTTP `CONNECT` proxy, such as [Smokescreen][smokescreen];
|
||||
this includes outgoing webhooks, image and website previews, and
|
||||
mobile push notifications. You may wish to enable this feature to
|
||||
provide a consistent egress point, or enforce access control on URLs
|
||||
to prevent [SSRF][ssrf] against internal resources.
|
||||
To protect against [SSRF][ssrf], Zulip 4.8 and above default to
|
||||
routing all outgoing HTTP and HTTPS traffic through
|
||||
[Smokescreen][smokescreen], an HTTP `CONNECT` proxy; this includes
|
||||
outgoing webhooks, website previews, and mobile push notifications.
|
||||
By default, the Camo image proxy will be automatically configured to
|
||||
use a custom outgoing proxy, but does not use Smokescreen by default
|
||||
because Camo includes similar logic to deny access to private
|
||||
subnets. You can [override][proxy.enable_for_camo] this default
|
||||
configuration if desired.
|
||||
|
||||
To use Smokescreen:
|
||||
|
||||
1. Add `, zulip::profile::smokescreen` to the list of `puppet_classes`
|
||||
in `/etc/zulip/zulip.conf`. A typical value after this change is:
|
||||
|
||||
```ini
|
||||
puppet_classes = zulip::profile::standalone, zulip::profile::smokescreen
|
||||
```
|
||||
|
||||
1. Optionally, configure the [smokescreen ACLs][smokescreen-acls]. By
|
||||
default, Smokescreen denies access to all [non-public IP
|
||||
addresses](https://en.wikipedia.org/wiki/Private_network), including
|
||||
127.0.0.1.
|
||||
To use a custom outgoing proxy:
|
||||
|
||||
1. Add the following block to `/etc/zulip/zulip.conf`, substituting in
|
||||
your proxy's hostname/IP and port:
|
||||
@@ -238,20 +229,30 @@ To use Smokescreen:
|
||||
port = 4750
|
||||
```
|
||||
|
||||
1. If you intend to also make the Smokescreen install available to
|
||||
other hosts, set `listen_address` in the same block. Note that you
|
||||
must control access to the Smokescreen port if you do this, as
|
||||
failing to do so opens a public HTTP proxy!
|
||||
|
||||
1. As root, run
|
||||
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This
|
||||
will compile and install Smokescreen, reconfigure services to use
|
||||
it, and restart Zulip.
|
||||
will reconfigure and restart Zulip.
|
||||
|
||||
If you would like to use an already-installed HTTP proxy, omit the
|
||||
first step, and adjust the IP address and port in the second step
|
||||
accordingly.
|
||||
If you have a deployment with multiple frontend servers, or wish to
|
||||
install Smokescreen on a separate host, you can apply the
|
||||
`zulip::profile::smokescreen` Puppet class on that host, and follow
|
||||
the above steps, setting the `[http_proxy]` block to point to that
|
||||
host.
|
||||
|
||||
If you wish to disable the outgoing proxy entirely, follow the above
|
||||
steps, configuring an empty `host` value.
|
||||
|
||||
Optionally, you can also configure the [Smokescreen ACL
|
||||
list][smokescreen-acls]. By default, Smokescreen denies access to all
|
||||
[non-public IP
|
||||
addresses](https://en.wikipedia.org/wiki/Private_network), including
|
||||
127.0.0.1, but allows traffic to all public Internet hosts.
|
||||
|
||||
In Zulip 4.7 and older, to enable SSRF protection via Smokescreen, you
|
||||
will need to explicitly add the `zulip::profile::smokescreen` Puppet
|
||||
class, and configure the `[http_proxy]` block as above.
|
||||
|
||||
[proxy.enable_for_camo]: #enable-for-camo
|
||||
[smokescreen]: https://github.com/stripe/smokescreen
|
||||
[smokescreen-acls]: https://github.com/stripe/smokescreen#acls
|
||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||
@@ -294,6 +295,33 @@ HTTP as follows:
|
||||
1. Finally, restart the Zulip server, using
|
||||
`/home/zulip/deployments/current/scripts/restart-server`.
|
||||
|
||||
#### Configuring Zulip to trust proxies
|
||||
|
||||
Before placing Zulip behind a reverse proxy, it needs to be configured to trust
|
||||
the client IP addresses that the proxy reports. This is important to have
|
||||
accurate IP addresses in server logs, as well as in notification emails which
|
||||
are sent to end users.
|
||||
|
||||
1. Determine the IP addresses of all reverse proxies you are setting up, as seen
|
||||
from the Zulip host. Depending on your network setup, these may not be the
|
||||
same as the public IP addresses of the reverse proxies.
|
||||
|
||||
1. Add the following block to `/etc/zulip/zulip.conf`.
|
||||
|
||||
```ini
|
||||
[loadbalancer]
|
||||
# Use the IP addresses you determined above, separated by commas.
|
||||
ips = 192.168.0.100
|
||||
```
|
||||
|
||||
1. Reconfigure Zulip with these settings. As root, run
|
||||
`/home/zulip/deployments/current/scripts/zulip-puppet-apply`. This will
|
||||
adjust Zulip's `nginx` configuration file to accept the `X-Forwarded-For`
|
||||
header when it is sent from one of the reverse proxy IPs.
|
||||
|
||||
1. Finally, restart the Zulip server, using
|
||||
`/home/zulip/deployments/current/scripts/restart-server`.
|
||||
|
||||
### nginx configuration
|
||||
|
||||
For `nginx` configuration, there's two things you need to set up:
|
||||
@@ -330,6 +358,10 @@ Don't forget to update `server_name`, `ssl_certificate`,
|
||||
`ssl_certificate_key` and `proxy_pass` with the appropriate values for
|
||||
your installation.
|
||||
|
||||
On the Zulip side, you will need to add the `nginx` server IP as a trusted
|
||||
reverse proxy. Follow the instructions to [configure Zulip to trust
|
||||
proxies](#configuring-zulip-to-trust-proxies).
|
||||
|
||||
[nginx-proxy-longpolling-config]: https://github.com/zulip/zulip/blob/main/puppet/zulip/files/nginx/zulip-include-common/proxy_longpolling
|
||||
[standalone.pp]: https://github.com/zulip/zulip/blob/main/puppet/zulip/manifests/profile/standalone.pp
|
||||
[zulipchat-puppet]: https://github.com/zulip/zulip/tree/main/puppet/zulip_ops/manifests
|
||||
@@ -352,7 +384,11 @@ make the following changes in two configuration files.
|
||||
|
||||
3. Restart your Zulip server with `/home/zulip/deployments/current/scripts/restart-server`.
|
||||
|
||||
4. Create an Apache2 virtual host configuration file, similar to the
|
||||
4. Follow the instructions to [configure Zulip to trust
|
||||
proxies](#configuring-zulip-to-trust-proxies). For this example, the reverse
|
||||
proxy IP would be `127.0.0.1`.
|
||||
|
||||
5. Create an Apache2 virtual host configuration file, similar to the
|
||||
following. Place it the appropriate path for your Apache2
|
||||
installation and enable it (E.g. if you use Debian or Ubuntu, then
|
||||
place it in `/etc/apache2/sites-available/zulip.example.com.conf`
|
||||
@@ -410,7 +446,9 @@ backend zulip
|
||||
|
||||
Since this configuration uses the `http` mode, you will also need to
|
||||
[configure Zulip to allow HTTP](#configuring-zulip-to-allow-http) as
|
||||
described above.
|
||||
described above. Additionally, you will need to [add the the HAProxy server IP
|
||||
address as a trusted load balancer](#configuring-zulip-to-trust-proxies)
|
||||
to have Zulip respect the addresses in `X-Forwarded-For` headers.
|
||||
|
||||
### Other proxies
|
||||
|
||||
@@ -419,7 +457,9 @@ things you need to be careful about when configuring it:
|
||||
|
||||
1. Configure your reverse proxy (or proxies) to correctly maintain the
|
||||
`X-Forwarded-For` HTTP header, which is supposed to contain the series
|
||||
of IP addresses the request was forwarded through. You can verify
|
||||
of IP addresses the request was forwarded through. Additionally,
|
||||
[configure Zulip to respect the addresses sent by your reverse
|
||||
proxies](#configuring-zulip-to-trust-proxies). You can verify
|
||||
your work by looking at `/var/log/zulip/server.log` and checking it
|
||||
has the actual IP addresses of clients, not the IP address of the
|
||||
proxy server.
|
||||
@@ -551,14 +591,6 @@ Override the default uwsgi backlog of 128 connections.
|
||||
Override the default `uwsgi` (Django) process count of 6 on hosts with
|
||||
more than 3.5GiB of RAM, 4 on hosts with less.
|
||||
|
||||
### `[certbot]`
|
||||
|
||||
#### `auto_renew`
|
||||
|
||||
If set to the string `yes`, [Certbot will attempt to automatically
|
||||
renew its certificate](../production/ssl-certificates.html#certbot-recommended). Do
|
||||
no set by hand; use `scripts/setup/setup-certbot` to configure this.
|
||||
|
||||
### `[postfix]`
|
||||
|
||||
#### `mailname`
|
||||
@@ -609,12 +641,6 @@ connections.
|
||||
The version of PostgreSQL that is in use. Do not set by hand; use the
|
||||
[PostgreSQL upgrade tool](../production/upgrade-or-modify.html#upgrading-postgresql).
|
||||
|
||||
### `[rabbitmq]`
|
||||
|
||||
#### `nodename`
|
||||
|
||||
The name used to identify the local RabbitMQ server; do not modify.
|
||||
|
||||
### `[memcached]`
|
||||
|
||||
#### `memory`
|
||||
@@ -634,13 +660,22 @@ load balancers whose `X-Forwarded-For` should be respected.
|
||||
#### `host`
|
||||
|
||||
The hostname or IP address of an [outgoing HTTP `CONNECT`
|
||||
proxy](#using-an-outgoing-http-proxy).
|
||||
proxy](#customizing-the-outgoing-http-proxy). Defaults to `localhost`
|
||||
if unspecified.
|
||||
|
||||
#### `port`
|
||||
|
||||
The TCP port of the HTTP `CONNECT` proxy on the host specified above.
|
||||
Defaults to `4750` if unspecified.
|
||||
|
||||
#### `listen_address`
|
||||
|
||||
The IP address that Smokescreen should bind to and listen on.
|
||||
Defaults to `127.0.0.1`.
|
||||
|
||||
#### `enable_for_camo`
|
||||
|
||||
Because Camo includes logic to deny access to private subnets, routing
|
||||
its requests through Smokescreen is generally not necessary. Set to
|
||||
'true' or 'false' to override the default, which uses the proxy only if
|
||||
it is not the default of Smokescreen on a local host.
|
||||
|
||||
@@ -63,9 +63,11 @@ If the script gives an error, consult [Troubleshooting](#troubleshooting) below.
|
||||
suitable for production use, but may be convenient for testing.
|
||||
|
||||
- `--certbot`: With this option, the Zulip installer automatically
|
||||
obtains an SSL certificate for the server [using Certbot][doc-certbot].
|
||||
If you'd prefer to acquire an SSL certificate yourself in any other
|
||||
way, it's easy to [provide it to Zulip][doc-ssl-manual].
|
||||
obtains an SSL certificate for the server [using
|
||||
Certbot][doc-certbot], and configures a cron job to renew the
|
||||
certificate automatically. If you'd prefer to acquire an SSL
|
||||
certificate yourself in any other way, it's easy to [provide it to
|
||||
Zulip][doc-ssl-manual].
|
||||
|
||||
You can see the more advanced installer options in our [deployment options][doc-deployment-options]
|
||||
documentation.
|
||||
|
||||
@@ -18,7 +18,7 @@ support forwarding push notifications to a central push notification
|
||||
forwarding service. Accessing this service requires outgoing HTTPS
|
||||
access to the public Internet; if that is restricted by a proxy, you
|
||||
will need to [configure Zulip to use your outgoing HTTP
|
||||
proxy](../production/deployment.html#using-an-outgoing-http-proxy)
|
||||
proxy](../production/deployment.html#customizing-the-outgoing-http-proxy)
|
||||
first.
|
||||
|
||||
You can enable this for your Zulip server as follows:
|
||||
@@ -106,9 +106,11 @@ forwarding service).
|
||||
|
||||
## Security and privacy
|
||||
|
||||
Use of the push notification bouncer is subject to the
|
||||
[Zulipchat Terms of Service](https://zulip.com/terms/). By using
|
||||
push notifications, you agree to those terms.
|
||||
Use of the push notification bouncer is subject to the Zulip Cloud [Terms of
|
||||
Service](https://zulip.com/policies/terms), [Privacy
|
||||
Policy](https://zulip.com/policies/privacy) and [Rules of
|
||||
Use](https://zulip.com/policies/rules). By using push notifications, you agree
|
||||
to these terms.
|
||||
|
||||
We've designed this push notification bouncer service with security
|
||||
and privacy in mind:
|
||||
@@ -170,10 +172,11 @@ Zulip open source project understand how many people are using Zulip,
|
||||
and help us allocate resources towards supporting self-hosted
|
||||
installations.
|
||||
|
||||
Our use of these statistics is governed by the same Terms of Service
|
||||
and Privacy Policy that covers the Mobile Push Notifications Service
|
||||
itself. If your organization does not want to submit these statistics,
|
||||
you can disable this feature at any time by setting
|
||||
Our use of these statistics is governed by the same [Terms of
|
||||
Service](https://zulip.com/policies/terms) and [Privacy
|
||||
Policy](https://zulip.com/policies/privacy) that covers the Mobile Push
|
||||
Notifications Service itself. If your organization does not want to submit these
|
||||
statistics, you can disable this feature at any time by setting
|
||||
`SUBMIT_USAGE_STATISTICS=False` in `/etc/zulip/settings.py`.
|
||||
|
||||
## Sending push notifications directly from your server
|
||||
|
||||
@@ -10,11 +10,15 @@ To run a Zulip server, you will need:
|
||||
- Debian 10 Buster
|
||||
- At least 2GB RAM, and 10GB disk space
|
||||
- If you expect 100+ users: 4GB RAM, and 2 CPUs
|
||||
- If you intend to [upgrade from Git][upgrade-from-git]: 3GB RAM, or
|
||||
2G and at least 1G of swap configured.
|
||||
- A hostname in DNS
|
||||
- Credentials for sending email
|
||||
|
||||
For details on each of these requirements, see below.
|
||||
|
||||
[upgrade-from-git]: ../production/upgrade-or-modify.html#upgrading-from-a-git-repository
|
||||
|
||||
## Server
|
||||
|
||||
#### General
|
||||
@@ -77,6 +81,11 @@ on hardware requirements for larger organizations.
|
||||
HTTPS, and will redirect HTTP requests to HTTPS.
|
||||
- Incoming port 25 if you plan to enable Zulip's [incoming email
|
||||
integration](../production/email-gateway.md).
|
||||
- Incoming port 4369 should be protected by a firewall to prevent
|
||||
exposing `epmd`, an Erlang service which does not support binding
|
||||
only to localhost. Leaving this exposed will allow unauthenticated
|
||||
remote users to determine that the server is running RabbitMQ, and
|
||||
on which port, though no further information is leaked.
|
||||
- Outgoing HTTP(S) access (ports 80 and 443) to the public Internet so
|
||||
that Zulip can properly manage image and website previews and mobile
|
||||
push notifications. Outgoing Internet access is not required if you
|
||||
@@ -92,13 +101,14 @@ on hardware requirements for larger organizations.
|
||||
address as its external hostname (though we don't recommend that
|
||||
configuration).
|
||||
- Zulip supports [running behind a reverse proxy][reverse-proxy].
|
||||
- Zulip servers running inside a private network should configure the
|
||||
[Smokescreen integration][smokescreen-proxy] to protect against
|
||||
[SSRF attacks][ssrf], where users could make the Zulip server make
|
||||
requests to private resources.
|
||||
- Zulip configures [Smokescreen, and outgoing HTTP
|
||||
proxy][smokescreen-proxy], to protect against [SSRF attacks][ssrf],
|
||||
which prevents user from making the Zulip server make requests to
|
||||
private resources. If your network has its own outgoing HTTP proxy,
|
||||
Zulip supports using that instead.
|
||||
|
||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||
[smokescreen-proxy]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen-proxy]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
[reverse-proxy]: ../production/deployment.html#putting-the-zulip-application-behind-a-reverse-proxy
|
||||
[email-mirror-code]: https://github.com/zulip/zulip/blob/main/zerver/management/commands/email_mirror.py
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ strength allowed is controlled by two settings in
|
||||
browser is logged into a Zulip account that has received the
|
||||
uploaded file in question).
|
||||
|
||||
- Zulip supports using the Camo image proxy to proxy content like
|
||||
- Zulip supports using the [go-camo][go-camo] image proxy to proxy content like
|
||||
inline image previews, that can be inserted into the Zulip message feed by
|
||||
other users. This ensures that clients do not make requests to external
|
||||
servers to fetch images, improving privacy.
|
||||
@@ -256,15 +256,21 @@ strength allowed is controlled by two settings in
|
||||
- Mobile push notifications (must be configured to be enabled)
|
||||
|
||||
- Notably, these first 3 features give end users (limited) control to cause
|
||||
the Zulip server to make HTTP requests on their behalf. As a result,
|
||||
Zulip supports routing all outgoing outgoing HTTP requests [through
|
||||
the Zulip server to make HTTP requests on their behalf. Because of this,
|
||||
Zulip routes all outgoing outgoing HTTP requests [through
|
||||
Smokescreen][smokescreen-setup] to ensure that Zulip cannot be
|
||||
used to execute [SSRF attacks][ssrf] against other systems on an
|
||||
internal corporate network. The default Smokescreen configuration
|
||||
denies access to all non-public IP addresses, including 127.0.0.1.
|
||||
|
||||
The Camo image server does not, by default, route its traffic
|
||||
through Smokescreen, since Camo includes logic to deny access to
|
||||
private subnets; this can be [overridden][proxy.enable_for_camo].
|
||||
|
||||
[go-camo]: https://github.com/cactus/go-camo
|
||||
[ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
|
||||
[smokescreen-setup]: ../production/deployment.html#using-an-outgoing-http-proxy
|
||||
[smokescreen-setup]: ../production/deployment.html#customizing-the-outgoing-http-proxy
|
||||
[proxy.enable_for_camo]: ../production/deployment.html#enable-for-camo
|
||||
|
||||
## Final notes and security response
|
||||
|
||||
|
||||
@@ -107,11 +107,29 @@ the server controls the website at that hostname; and is then given a
|
||||
certificate. (For details, refer to
|
||||
[Let's Encrypt](https://letsencrypt.org/how-it-works/).)
|
||||
|
||||
Then it records a flag in `/etc/zulip/zulip.conf` saying Certbot is in
|
||||
use and should be auto-renewed. A cron job checks that flag, then
|
||||
checks if any certificates are due for renewal, and if they are (so
|
||||
approximately once every 60 days), repeats the process of request,
|
||||
prove, get a fresh certificate.
|
||||
### Renewal
|
||||
|
||||
Let's Encrypt certificates expire after 90 days. Short expiration
|
||||
periods are good for security, but they also mean that it's important
|
||||
to automatically renew them to avoid regular maintenance work.
|
||||
|
||||
Zulip configures automatic renewal for you. As a result, a Zulip
|
||||
server configured with Certbot does not require any ongoing work to
|
||||
maintain a current valid SSL certificate.
|
||||
|
||||
The `certbot` package configures a systemd timer (similar to a cron
|
||||
job) that will renew any Certbot certificates that are due for
|
||||
renewal. The renewal process repeats the Certbot proof-of-control
|
||||
process, receives the new certificate from Certbot, installs the new
|
||||
certificate, and then reloads `nginx`.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
If your Certbot certificate expires, it is usually because of firewall
|
||||
rules preventing the Certbot renewal process (which is essentially
|
||||
identical to the initial certificate request process) from
|
||||
working. You can debug interactively by running the command from the
|
||||
cron job, `/usr/bin/certbot renew`, as `root`.
|
||||
|
||||
## Self-signed certificate
|
||||
|
||||
|
||||
@@ -638,7 +638,7 @@
|
||||
"Send digest emails when I'm away": "E-Mail mit Zusammenfassung senden, wenn ich abwesend bin",
|
||||
"Send email notifications for new logins to my account": "E-Mail-Benachrichtigungen für neue Logins in meinen Account senden",
|
||||
"Send emails introducing Zulip to new users": "E-Mails mit Einführung zu Zulip an neue Nutzer versenden ",
|
||||
"Send me occasional marketing emails about Zulip (a few times a year)": "Senden Sie mir gelegentlich Marketing-E-Mails über Zulip (ein paar mal pro Jahr)",
|
||||
"Send me occasional marketing emails about Zulip (a few times a year)": "Schicke mir gelegentlich Marketing-E-Mails über Zulip (ein paar mal pro Jahr)",
|
||||
"Send mobile notifications even if I'm online (useful for testing)": "Mobile Benachrichtigungen senden, auch wenn ich online bin (nützlich zum Testen)",
|
||||
"Send notification to new topic": "Benachrichtigung an neues Thema senden",
|
||||
"Send notification to old topic": "Benachrichtigung an altes Thema senden",
|
||||
@@ -750,8 +750,8 @@
|
||||
"Unknown stream": "Unbekannter Stream",
|
||||
"Unmute": "Stummschaltung aufheben",
|
||||
"Unmute stream": "Stummschaltung des Streams aufheben",
|
||||
"Unmute the topic <b>{topic}</b>": "Stummschalten des Themas<b>{topic}</b>deaktivieren",
|
||||
"Unmute this user": "stummschalten für Nutzer aufheben",
|
||||
"Unmute the topic <b>{topic}</b>": "Stummschaltung des Themas<b>{topic}</b>aufheben",
|
||||
"Unmute this user": "Stummschaltung für Nutzer aufheben",
|
||||
"Unmute topic": "Stummschaltung des Themas aufheben",
|
||||
"Unpin stream from top": "Oben angepinnten Stream loslösen",
|
||||
"Unread": "Ungelesen",
|
||||
@@ -870,7 +870,7 @@
|
||||
"You're not subscribed to this stream. You will not be notified if other users reply to your message.": "Du hast diesen Stream nicht abonniert. Du wirst nicht benachrichtigt, wenn andere Nutzer auf Deine Nachricht antworten.",
|
||||
"Your API key:": "Dein API-Schlüssel:",
|
||||
"Your reminder note is empty!": "Deine Erinnerungsnotiz ist leer!",
|
||||
"Zulip's translations are contributed by our amazing community of volunteer translators. If you'd like to help, see the <z-link>Zulip translation guidelines</z-link>.": "Zulips Übersetzungen werden von unserer erstaunlichen Gemeinschaft freiwilliger Übersetzer beigesteuert. Wenn Sie helfen möchten, lesen Sie die <z-link>Zulip translation guidelines</z-link>.",
|
||||
"Zulip's translations are contributed by our amazing community of volunteer translators. If you'd like to help, see the <z-link>Zulip translation guidelines</z-link>.": "Die Übersetzungen von Zulip werden von unserer wunderbaren Gemeinschaft freiwilliger Übersetzer beigesteuert. Wenn du helfen möchtest, schau dir bitte die <z-link>Richtlinien für die Übersetzung von Zulip</z-link> an.",
|
||||
"[Condense message]": "[Nachricht minimieren]",
|
||||
"[Configure]": "[Konfigurieren]",
|
||||
"[Disable]": "[Deaktivieren]",
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
"(no topic)": "(sin tema)",
|
||||
"(unavailable)": "(no disponible)",
|
||||
"(you)": "(tu)",
|
||||
"({message_retention_days} days)": "",
|
||||
"({message_retention_days} days)": "({message_retention_days} días)",
|
||||
"/dark (Toggle night mode)": "",
|
||||
"/day (Toggle day mode)": "",
|
||||
"/fixed-width (Toggle fixed width mode)": "",
|
||||
"/fluid-width (Toggle fluid width mode)": "",
|
||||
"/fixed-width (Toggle fixed width mode)": "/fixed-width (Cambiar a modo de ancho fijo)",
|
||||
"/fluid-width (Toggle fluid width mode)": "/fluid-width (Cambiar a modo de ancho fluido)",
|
||||
"/light (Toggle day mode)": "",
|
||||
"/me is excited (Display action text)": "/me se emociona (Mostrar texto de acción)",
|
||||
"/night (Toggle night mode)": "",
|
||||
"/poll Where should we go to lunch today? (Create a poll)": "/poll ¿Donde deberíamos comer hoy? (Crear encuesta)",
|
||||
"/settings (Load settings menu)": "",
|
||||
"/todo (Create a todo list)": "",
|
||||
"/todo (Create a todo list)": "/todo (Crear una lista de tareas)",
|
||||
"1 day": "1 día",
|
||||
"1 hour": "1 hora",
|
||||
"1 week": "1 semana",
|
||||
@@ -24,15 +24,15 @@
|
||||
"2 minutes": "2 minutos",
|
||||
"24-hour clock (17:00)": "Formato 24 horas (17:00)",
|
||||
"3 days": "3 días",
|
||||
"<b>Total messages</b>: {total_messages}": "",
|
||||
"<p>Stream will be announced in <b>#{notifications_stream}</b>.</p>": "",
|
||||
"<p>The stream <b>{stream_name}</b> does not exist.</p><p>Manage your subscriptions <z-link>on your Streams page</z-link>.</p>": "",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified if you mention them.": "",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified unless you subscribe them.": "",
|
||||
"<z-link>Click here</z-link> to learn about exporting private streams and messages.": "",
|
||||
"<z-link>Upgrade</z-link> for more space.": "",
|
||||
"<b>Total messages</b>: {total_messages}": "<b>Mensajes totales</b>: {total_messages}",
|
||||
"<p>Stream will be announced in <b>#{notifications_stream}</b>.</p>": "<p>El canal será anunciado en <b>#{notifications_stream}</b>.</p>",
|
||||
"<p>The stream <b>{stream_name}</b> does not exist.</p><p>Manage your subscriptions <z-link>on your Streams page</z-link>.</p>": "<p>El canal <b>{stream_name}</b> no existe.</p><p>Gestiona tus subscripciones <z-link>en tu página de canales</z-link>.</p>",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified if you mention them.": "<strong>{name}</strong> no está subscrito a este canal. No será notificado si le mencionas.",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified unless you subscribe them.": "<strong>{name}</strong> no está subscrito a este canal. No será notificado si no le subscribes.",
|
||||
"<z-link>Click here</z-link> to learn about exporting private streams and messages.": "<z-link>Haz clic aquí</z-link> para aprender sobre cómo exportar canales privados y mensajes.",
|
||||
"<z-link>Upgrade</z-link> for more space.": "<z-link>Mejora</z-link> para más espacio.",
|
||||
"A Topic Move already in progress.": "Un cambio de tema ya en marcha. ",
|
||||
"A language is marked as 100% translated only if every string in the web, desktop, and mobile apps is translated, including administrative UI and error messages.": "",
|
||||
"A language is marked as 100% translated only if every string in the web, desktop, and mobile apps is translated, including administrative UI and error messages.": "Un idioma está marcado como traducido al 100% únicamente si todas las cadenas en las aplicaciones web, escritorio y móvil son traducidas. Incluyendo la interfaz administrativa y mensajes de error.",
|
||||
"A stream needs to have a name": "Un canal necesita tener un nombre",
|
||||
"A stream with this name already exists": "Ya existe un canal con este nombre",
|
||||
"A unicode emoji with name <b>{emoji_name}</b> already exists. Uploading a custom emoji with this name will override the unicode emoji with this name.": "",
|
||||
@@ -95,7 +95,7 @@
|
||||
"All streams": "Todos los canales",
|
||||
"All time": "Todos los tiempos",
|
||||
"All unreads": "Todos sin leer",
|
||||
"Allow message content in message notification emails": "",
|
||||
"Allow message content in message notification emails": "Permitir el contenido del mensaje en los correos electrónicos de notificación de mensajes",
|
||||
"Allow message deleting": "Permitir borrado de mensajes",
|
||||
"Allow message editing": "Permitir la edición de mensajes",
|
||||
"Allow subdomains": "Permitir subdominios",
|
||||
@@ -122,14 +122,14 @@
|
||||
"Are you sure you want to deactivate your account?": "",
|
||||
"Are you sure you want to delete <b>{group_name}</b>?": "",
|
||||
"Are you sure you want to delete your profile picture?": "",
|
||||
"Are you sure you want to mention all <strong>{count}</strong> people in this stream? <br /> This will send email and mobile push notifications to most of those <strong>{count}</strong> users. <br /> If you don't want to do that, please edit your message to remove the <strong>@{mention}</strong> mention.": "",
|
||||
"Are you sure you want to mute <b>{user_name}</b>? Messages sent by muted users will never trigger notifications, will be marked as read, and will be hidden.": "",
|
||||
"Are you sure you want to mention all <strong>{count}</strong> people in this stream? <br /> This will send email and mobile push notifications to most of those <strong>{count}</strong> users. <br /> If you don't want to do that, please edit your message to remove the <strong>@{mention}</strong> mention.": "¿Estás seguro de querer mencionar a toda la gente, <strong>{count}</strong>, en este canal? <br /> Esto enviara notificaciones de correo electrónico y móvil a la mayoria de los <strong>{count}</strong> usuarios. <br /> si no quieres hacer eso, por favor, edita tu mensaje para quitar la mención <strong>@{mention}</strong>.",
|
||||
"Are you sure you want to mute <b>{user_name}</b>? Messages sent by muted users will never trigger notifications, will be marked as read, and will be hidden.": "¿Estás seguro de querer silenciar a <b>{user_name}</b>? Los mensajes enviados por usuarios silenciados no emitirán notificaciones, serán marcados como leídos, y serán ocultados.",
|
||||
"Are you sure you want to permanently delete <b>{topic_name}</b>?": "",
|
||||
"Are you sure you want to resend the invitation to <z-email></z-email>?": "",
|
||||
"Are you sure you want to revoke the invitation to <strong>{email}</strong>?": "",
|
||||
"Are you sure you want to revoke this invitation link created by <strong>{referred_by}</strong>?": "",
|
||||
"Are you sure you want to unstar all messages in <stream-topic></stream-topic>? This action cannot be undone.": "",
|
||||
"Are you sure you want to unstar all starred messages? This action cannot be undone.": "",
|
||||
"Are you sure you want to unstar all messages in <stream-topic></stream-topic>? This action cannot be undone.": "¿Seguro que quieres quitar la estrella a todos los mensajes en <stream-topic></stream-topic>? Esta acción no se puede deshacer.",
|
||||
"Are you sure you want to unstar all starred messages? This action cannot be undone.": "¿Estas seguro de querer quitar la estrella a todos los mensajes con estrella? Esta acción no se puede deshacer.",
|
||||
"Attachment deleted": "Adjunto eliminado",
|
||||
"Audible desktop notifications": "Notificaciones de escritorio audibles",
|
||||
"Audio": "Audio",
|
||||
@@ -171,7 +171,7 @@
|
||||
"Collapse": "Contraer",
|
||||
"Color scheme": "Esquema de color",
|
||||
"Complete": "Completado",
|
||||
"Compose message": "",
|
||||
"Compose message": "Escribir mensaje",
|
||||
"Compose your message here": "Escribe tu mensaje aquí",
|
||||
"Compose your message here...": "Escribe tu mensaje aquí...",
|
||||
"Condense message (-)": "Acortar mensaje (-)",
|
||||
@@ -188,7 +188,7 @@
|
||||
"Copy code": "Copiar código",
|
||||
"Copy from stream": "Copiar desde canal",
|
||||
"Copy link": "Copiar enlace",
|
||||
"Copy link to message": "",
|
||||
"Copy link to message": "Copiar enlace al mensaje",
|
||||
"Copy mention syntax": "Copiar la sintaxis de la mención",
|
||||
"Copy zuliprc": "Copiar zuliprc",
|
||||
"Create": "Crear",
|
||||
@@ -244,7 +244,7 @@
|
||||
"Depending on the size of your organization, an export can take anywhere from seconds to an hour.": "Dependiendo del tamaño de tu organización, las exportaciones pueden tardar de segundos a horas.",
|
||||
"Description": "Descripción",
|
||||
"Desktop": "Escritorio",
|
||||
"Detailed message formatting documentation": "",
|
||||
"Detailed message formatting documentation": "Documentación detallada sobre el formato de los mensajes",
|
||||
"Disabled": "Desactivado",
|
||||
"Discard": "Descartar",
|
||||
"Display my availability to other users when online": "Mostrar disponibilidad a otros usuarios cuando estás conectado",
|
||||
@@ -363,9 +363,9 @@
|
||||
"Image": "Imagen",
|
||||
"Inactive bots": "Bots inactivos",
|
||||
"Include content of private messages in desktop notifications": "Incluir el contenido de los mensajes privados en las notificaciones de escritorio",
|
||||
"Include message content in message notification emails": "",
|
||||
"Include message content in message notification emails": "Incluir el contenido de los mensajes en las notificaciones por correo electrónico",
|
||||
"Include muted": "Incluye silenciado",
|
||||
"Include organization name in subject of message notification emails": "",
|
||||
"Include organization name in subject of message notification emails": "Incluir el nombre de la organización en el asunto de los correos electrónicos de notificación",
|
||||
"Incoming webhooks can only send messages.": "Los webhooks de entrada solo pueden enviar mensajes.",
|
||||
"Interface": "Interfaz",
|
||||
"Invalid URL": "URL inválida",
|
||||
@@ -415,8 +415,8 @@
|
||||
"Mention a timezone-aware time": "Mencionar una hora del huso horario",
|
||||
"Mentioned in": "Mencionado en",
|
||||
"Mentions": "Menciones",
|
||||
"Message #{stream_name}": "",
|
||||
"Message #{stream_name} > {topic_name}": "",
|
||||
"Message #{stream_name}": "Enviar mensaje #{stream_name}",
|
||||
"Message #{stream_name} > {topic_name}": "Enviar mensaje a #{stream_name} > {topic_name}",
|
||||
"Message actions": "Acciones del mensaje",
|
||||
"Message editing": "Edición de mensajes",
|
||||
"Message formatting": "Formato de mensajes",
|
||||
@@ -424,10 +424,10 @@
|
||||
"Message retention for stream": "Retención de mensajes para el canal",
|
||||
"Message retention period": "Período de retención de mensajes",
|
||||
"Message sent when you were not subscribed": "Mensaje enviado cuando no estabas suscrito",
|
||||
"Message {recipient_label}": "",
|
||||
"Message {recipient_names}": "",
|
||||
"Message {recipient_name} ({recipient_status})": "",
|
||||
"Messages in this stream will be automatically deleted after {retention_days} days.": "",
|
||||
"Message {recipient_label}": "Enviar mensaje a {recipient_label}",
|
||||
"Message {recipient_names}": "Enviar mensaje a {recipient_names}",
|
||||
"Message {recipient_name} ({recipient_status})": "Enviar mensaje a {recipient_name} ({recipient_status})",
|
||||
"Messages in this stream will be automatically deleted after {retention_days} days.": "Los mensajes en este canal serán borrados automáticamente después de {retention_days} días.",
|
||||
"Messages in this stream will be retained forever.": "Mensajes en este canal serán guardados este canal para siempre",
|
||||
"Method": "Método",
|
||||
"Mobile": "Móvil",
|
||||
@@ -453,8 +453,8 @@
|
||||
"Name changes are disabled in this organization. Contact an administrator to change your name.": "El cambio de nombre esta desactivado para esta organización. Contacta con un administrador para cambiar tu nombre.",
|
||||
"Narrow to stream "{display_recipient}"": "",
|
||||
"Narrow to stream "{display_recipient}", topic "{topic}"": "",
|
||||
"Narrow to your private messages with {display_reply_to}": "",
|
||||
"Narrow to {message_recipient}": "",
|
||||
"Narrow to your private messages with {display_reply_to}": "Limitar a tus mensajes privados con {display_reply_to}",
|
||||
"Narrow to {message_recipient}": "Limitar a {message_recipient}",
|
||||
"Never": "Nunca",
|
||||
"Never had one? Forgotten it?": "¿Nunca has tenido una? ¿La has olvidado?",
|
||||
"New": "Nuevo",
|
||||
@@ -716,11 +716,11 @@
|
||||
"This is a <z-icon></z-icon> <b>web public stream</b>. Any member of the organization can join without an invitation and anyone on the internet can read the content published.": "",
|
||||
"This is a private stream": "Este es un canal privado",
|
||||
"This is what a Zulip notification looks like.": "Así es como se verá una notificación de Zulip",
|
||||
"This message was hidden because you have muted the sender.": "",
|
||||
"This organization is configured to restrict editing of message content to {minutes_to_edit} minutes after it is sent.": "",
|
||||
"This message was hidden because you have muted the sender.": "Este mensaje ha sido ocultado porque has silenciado al remitente.",
|
||||
"This organization is configured to restrict editing of message content to {minutes_to_edit} minutes after it is sent.": "Esta organización está configurada para restringir la edición del contenido de los mensajes hasta {minutes_to_edit} minutos después de enviados.",
|
||||
"This stream does not exist or is private.": "Este canal no existe o es privado.",
|
||||
"This stream has been deactivated": "Este canal ha sido desactivado",
|
||||
"This stream is reserved for <strong>announcements</strong>. <br /> Are you sure you want to message all <strong>{count}</strong> people in this stream?": "",
|
||||
"This stream is reserved for <strong>announcements</strong>. <br /> Are you sure you want to message all <strong>{count}</strong> people in this stream?": "Este canal está reservado para <strong>anuncios</strong>. <br /> ¿Seguro que quieres enviar un mensaje a toda la gente, <strong>{count}</strong>, en este canal?",
|
||||
"Thursday": "Jueves",
|
||||
"Time": "Fecha y hora",
|
||||
"Time format": "Formato de fecha y hora",
|
||||
@@ -758,8 +758,8 @@
|
||||
"Unread count summary (appears in desktop sidebar and browser tab)": "Resumen de mensajes sin leer (aparece en el menú lateral en escritorio y en una pestaña en navegadores)",
|
||||
"Unstar": "Desmarcar",
|
||||
"Unstar all messages": "Desmarcar todos los mensajes destacados",
|
||||
"Unstar all messages in topic": "",
|
||||
"Unstar messages in topic": "",
|
||||
"Unstar all messages in topic": "Quitar estrella a todos los mensajes en el tema",
|
||||
"Unstar messages in topic": "Quitar estrella a mensajes en el tema",
|
||||
"Unsubscribe": "Desuscribirse",
|
||||
"Unsubscribe from {stream_name}": "",
|
||||
"Unsubscribed successfully!": "¡Desuscrito exitosamente!",
|
||||
@@ -822,7 +822,7 @@
|
||||
"Who can add users to streams": "Quiénes pueden añadir usuarios a canales",
|
||||
"Who can create and manage user groups": "¿Quién puede crear y gestionar grupos de usuarios?",
|
||||
"Who can create streams": "Quiénes pueden crear canales",
|
||||
"Who can move messages between streams": "",
|
||||
"Who can move messages between streams": "Quién puede mover mensajes entre canales",
|
||||
"Who can post to the stream?": "Quiénes pueden publicar al canal?",
|
||||
"Who can use @all/@everyone mentions in large streams": "Quienes pueden usar @all/@everyone menciones en canales largos",
|
||||
"Who can use private messages": "Quienes pueden usar mensajes privados",
|
||||
@@ -881,7 +881,7 @@
|
||||
"beta": "beta",
|
||||
"clear": "limpiar",
|
||||
"cookie": "cookie",
|
||||
"group private messages with {recipient}": "",
|
||||
"group private messages with {recipient}": "agrupar mensajes privados con {recipient}",
|
||||
"in 1 hour": "en 1 hora",
|
||||
"in 20 minutes": "en 20 minutos",
|
||||
"in 3 hours": "en 3 horas",
|
||||
@@ -889,7 +889,7 @@
|
||||
"marketing": "marketing",
|
||||
"more topics": "más temas",
|
||||
"private messages with yourself": "mensajes privados contigo mismo",
|
||||
"private messages with {recipient}": "",
|
||||
"private messages with {recipient}": "mensajes privados con {recipient}",
|
||||
"{comma_separated_usernames} and {last_username} reacted with {emoji_name}": "",
|
||||
"{count} users are subscribed to #{title}": "",
|
||||
"{days_old} days ago": "",
|
||||
@@ -897,11 +897,11 @@
|
||||
"{hours} hours ago": "",
|
||||
"{last_active_date}": "",
|
||||
"{minutes} min to edit": "",
|
||||
"{minutes} minutes ago": "",
|
||||
"{minutes} minutes ago": "Hace {minutes} minutos",
|
||||
"{seconds} sec to edit": "",
|
||||
"{starred_status} this message": "",
|
||||
"{starred_status} this message (Ctrl + s)": "",
|
||||
"{username} [said]({link_to_message}):": "",
|
||||
"{starred_status} this message": "{starred_status} este mensaje",
|
||||
"{starred_status} this message (Ctrl + s)": "{starred_status} este mensaje (Ctrl + s)",
|
||||
"{username} [said]({link_to_message}):": "{username} [ha dicho]({link_to_message}):",
|
||||
"{username} reacted with {emoji_name}": "",
|
||||
"{wildcard_mention_token} (Notify stream)": ""
|
||||
}
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-23 19:14+0000\n"
|
||||
"POT-Creation-Date: 2021-11-30 22:59+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -1404,7 +1404,7 @@ msgstr ""
|
||||
msgid "Organization permissions"
|
||||
msgstr ""
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2390
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2391
|
||||
msgid "Custom emoji"
|
||||
msgstr ""
|
||||
|
||||
@@ -3803,7 +3803,7 @@ msgstr ""
|
||||
msgid "Message must have recipients"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:193
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:215
|
||||
msgid "Invalid message type"
|
||||
msgstr ""
|
||||
|
||||
@@ -3917,7 +3917,7 @@ msgstr ""
|
||||
msgid "Must be an organization administrator or emoji author"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:840
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:841
|
||||
msgid "Invalid characters in emoji name"
|
||||
msgstr ""
|
||||
|
||||
@@ -4237,11 +4237,11 @@ msgid ""
|
||||
"a previous message."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:293
|
||||
#: zerver/lib/outgoing_webhook.py:315
|
||||
msgid "Invalid JSON in response"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:302
|
||||
#: zerver/lib/outgoing_webhook.py:324
|
||||
msgid "Invalid response format"
|
||||
msgstr ""
|
||||
|
||||
@@ -4436,7 +4436,7 @@ msgstr ""
|
||||
msgid "Invalid interface type"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3469
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3470
|
||||
msgid "Invalid user ID: {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -4612,87 +4612,91 @@ msgstr ""
|
||||
msgid "CSRF error: {reason}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:372
|
||||
#: zerver/models.py:373
|
||||
msgid "stream events"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:406
|
||||
#: zerver/models.py:407
|
||||
msgid "Available on Zulip Standard. Upgrade to access."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:910
|
||||
msgid "Invalid linkifier pattern. Valid characters are {}."
|
||||
#: zerver/models.py:919 zerver/models.py:921
|
||||
msgid "Bad regular expression: {}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:928
|
||||
#: zerver/models.py:922
|
||||
msgid "Unknown regular expression error"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:929
|
||||
msgid "Invalid URL format string."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1035 zerver/views/realm_playgrounds.py:24
|
||||
#: zerver/models.py:1036 zerver/views/realm_playgrounds.py:24
|
||||
msgid "Invalid characters in pygments language"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1415
|
||||
#: zerver/models.py:1416
|
||||
msgid "Organization owner"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1416
|
||||
#: zerver/models.py:1417
|
||||
msgid "Organization administrator"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1417
|
||||
#: zerver/models.py:1418
|
||||
msgid "Moderator"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1418
|
||||
#: zerver/models.py:1419
|
||||
msgid "Member"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1419
|
||||
#: zerver/models.py:1420
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2389
|
||||
#: zerver/models.py:2390
|
||||
msgid "Unicode emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2391
|
||||
#: zerver/models.py:2392
|
||||
msgid "Zulip extra emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3473
|
||||
#: zerver/models.py:3474
|
||||
msgid "User with ID {} is deactivated"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3476
|
||||
#: zerver/models.py:3477
|
||||
msgid "User with ID {} is a bot"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3509
|
||||
#: zerver/models.py:3510
|
||||
msgid "List of options"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3512
|
||||
#: zerver/models.py:3513
|
||||
msgid "Person picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3524
|
||||
#: zerver/models.py:3525
|
||||
msgid "Short text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3525
|
||||
#: zerver/models.py:3526
|
||||
msgid "Long text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3526
|
||||
#: zerver/models.py:3527
|
||||
msgid "Date picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3527
|
||||
#: zerver/models.py:3528
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3530
|
||||
#: zerver/models.py:3531
|
||||
msgid "External account"
|
||||
msgstr ""
|
||||
|
||||
@@ -4708,24 +4712,24 @@ msgstr ""
|
||||
msgid "An unknown browser"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:632
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
msgid "Missing 'queue_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:635
|
||||
#: zerver/tornado/event_queue.py:647
|
||||
msgid "Missing 'last_event_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:638
|
||||
#: zerver/tornado/event_queue.py:650
|
||||
msgid "You are not authorized to get events from this queue"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
#: zerver/tornado/event_queue.py:656
|
||||
#, python-brace-format
|
||||
msgid "An event newer than {event_id} has already been pruned!"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:654
|
||||
#: zerver/tornado/event_queue.py:666
|
||||
#, python-brace-format
|
||||
msgid "Event {event_id} was not in this queue"
|
||||
msgstr ""
|
||||
@@ -5423,14 +5427,14 @@ msgstr ""
|
||||
msgid "Invalid data."
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:1922
|
||||
#: zproject/backends.py:1927
|
||||
msgid "Missing id_token parameter"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2277
|
||||
#: zproject/backends.py:2282
|
||||
msgid "Invalid OTP"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2280
|
||||
#: zproject/backends.py:2285
|
||||
msgid "Can't use both mobile_flow_otp and desktop_flow_otp together."
|
||||
msgstr ""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,13 +41,13 @@
|
||||
"Action": "Tevékenység",
|
||||
"Actions": "Tevékenységek",
|
||||
"Active": "Aktív",
|
||||
"Active bots": "Aktív botok",
|
||||
"Active bots": "Aktív robotok",
|
||||
"Active now": "Most aktív",
|
||||
"Active users": "Aktív felhasználók",
|
||||
"Add": "Hozzáadás",
|
||||
"Add GIF": "GIF hozzáadása",
|
||||
"Add a new alert word": "Új figyelt szó hozzáadása",
|
||||
"Add a new bot": "Új bot hozzáadása",
|
||||
"Add a new bot": "Új robot hozzáadása",
|
||||
"Add a new code playground": "Kód játszótér hozzáadása",
|
||||
"Add a new emoji": "Új hangulatjel hozzáadása",
|
||||
"Add a new linkifier": "Új linkesítő létrehozása",
|
||||
@@ -76,7 +76,7 @@
|
||||
"Admins": "Adminok",
|
||||
"Admins and full members": "Adminok és teljes tagok",
|
||||
"Admins and members": "Adminok és tagok",
|
||||
"Admins and members, but only admins can add generic bots": "Adminok és tagok, de csak az adminok adhatnak hozzá általános botokat",
|
||||
"Admins and members, but only admins can add generic bots": "Adminok és tagok, de csak az adminok adhatnak hozzá általános robotokat",
|
||||
"Admins and moderators": "Adminok és moderátorok",
|
||||
"Admins only": "Csak adminisztrátorok",
|
||||
"Admins, members and guests": "Adminok, tagok és vendégek",
|
||||
@@ -104,7 +104,7 @@
|
||||
"Already subscribed to {stream}": "Már feliratkozott a/az {stream} csatornára",
|
||||
"Already subscribed users:": "Már feliratkozott felhasználók:",
|
||||
"Always": "Mindig",
|
||||
"An API key can be used to programmatically access a Zulip account. Anyone with access to your API key has the ability to read your messages, send messages on your behalf, and otherwise impersonate you on Zulip, so you should guard your API key as carefully as you guard your password. <br /> We recommend creating bots and using the bots' accounts and API keys to access the Zulip API, unless the task requires access to your account.": "Egy API kulcs a Zulip-fiók programozott elérésére használható. Az API kulcsod birtokában bárki képes olvasni az üzeneteidet, üzeneteket küldhet a nevedben, és más módokon is megszemélyesíthet téged a Zulip szolgáltatásban, ezért a kulcsot ugyanolyan gondosan kell őrizned, mint a jelszavad.<br /> Hacsak a feladathoz nincs szükség közvetlen hozzáférést adni a saját fiókodhoz, a Zulip API eléréséhez elsősorban botok létrehozását javasoljuk, amelyek a botok saját fiókjának API kulcsát használják.",
|
||||
"An API key can be used to programmatically access a Zulip account. Anyone with access to your API key has the ability to read your messages, send messages on your behalf, and otherwise impersonate you on Zulip, so you should guard your API key as carefully as you guard your password. <br /> We recommend creating bots and using the bots' accounts and API keys to access the Zulip API, unless the task requires access to your account.": "Egy API kulcs a Zulip-fiók programozott elérésére használható. Az API kulcsod birtokában bárki képes olvasni az üzeneteidet, üzeneteket küldhet a nevedben, és más módokon is megszemélyesíthet téged a Zulip szolgáltatásban, ezért a kulcsot ugyanolyan gondosan kell őrizned, mint a jelszavad.<br /> Hacsak a feladathoz nincs szükség közvetlen hozzáférést adni a saját fiókodhoz, a Zulip API eléréséhez elsősorban robotok létrehozását javasoljuk, amelyek a robotok saját fiókjának API kulcsát használják.",
|
||||
"An hour ago": "Egy órája",
|
||||
"An unknown error occurred.": "Ismeretlen hiba történt!",
|
||||
"Announce stream": "Kihirdető üzenetfolyam",
|
||||
@@ -112,7 +112,7 @@
|
||||
"Any organization administrator can conduct an export.": "A szervezet bármelyik adminisztrátora végezhet exportálást.",
|
||||
"Any time": "Bármikor",
|
||||
"Anyone can join; anyone can view complete message history without joining": "Bárki beléphet; bárki megtekintheti a múltbeli üzeneteket belépés nélkül is",
|
||||
"Anyone in this organization can add bots": "Ebből a szervezetből bárki hozzáadhat botokat",
|
||||
"Anyone in this organization can add bots": "Ebből a szervezetből bárki hozzáadhat robotokat",
|
||||
"April": "április",
|
||||
"Archive stream": "Archív üzenetfolyam",
|
||||
"Are invitations required for joining the organization?": "Szükség van meghívóra a szervezethez való csatlakozáshoz?",
|
||||
@@ -138,17 +138,17 @@
|
||||
"Author": "Szerző",
|
||||
"Automatic": "Automatikus",
|
||||
"Avatar from Gravatar": "Avatar a Gravatar-ról",
|
||||
"Bot": "Bot",
|
||||
"Bot email": "Bot e-mail",
|
||||
"Bot email (a-z, 0-9, and dashes only)": "Bot e-mail (csak a-z, 0-9 és kötőjelek)",
|
||||
"Bot type": "Bot típusa",
|
||||
"Bots": "Botok",
|
||||
"Bot": "Robot",
|
||||
"Bot email": "Robot e-mail",
|
||||
"Bot email (a-z, 0-9, and dashes only)": "Robot e-mail (csak a-z, 0-9 és kötőjelek)",
|
||||
"Bot type": "Robot típusa",
|
||||
"Bots": "Robotok",
|
||||
"By deactivating <z-user></z-user>, they will be logged out immediately.": "A/az <z-user></z-user> deaktiválásával azonnal ki is lesznek jelentkeztetve.",
|
||||
"By deactivating your account, you will be logged out immediately.": "A fiókod deaktiválásával azonnal ki is fogunk jelentkeztetni.",
|
||||
"Cancel": "Mégse",
|
||||
"Cancel compose": "Írás megszakítása",
|
||||
"Change": "Változtatás",
|
||||
"Change bot info and owner": "Bot info és tulajdonos módosítása",
|
||||
"Change bot info and owner": "Robot info és tulajdonos módosítása",
|
||||
"Change color": "Szín módosítása",
|
||||
"Change email": "E-mail változtatása",
|
||||
"Change full name": "Teljes név változtatása",
|
||||
@@ -182,7 +182,7 @@
|
||||
"Configure the default streams new users are subscribed to when joining your organization.": "Az alapértelmezett üzenetfolyamok beállítása, amelyekre az új felhasználók fel legyenek iratkozva, amikor csatlakoznak a szervezetedhez.",
|
||||
"Confirm": "Megerősít",
|
||||
"Convert emoticons before sending (<code>:)</code> becomes \ud83d\ude03)": "Hangulatjelek konvertálása elküldés előtt ( <code>:)</code> -ből 😃 lesz)",
|
||||
"Cookie Bot": "Süti bot",
|
||||
"Cookie Bot": "Süti robot",
|
||||
"Copied!": "Lemásolva!",
|
||||
"Copy and close": "Másolás és bezárás",
|
||||
"Copy code": "Kód másolása",
|
||||
@@ -192,10 +192,10 @@
|
||||
"Copy mention syntax": "Említés formájának másolása",
|
||||
"Copy zuliprc": "zuliprc másolása",
|
||||
"Create": "Létrehozás",
|
||||
"Create bot": "Bot létrehozása",
|
||||
"Create bot": "Robot létrehozása",
|
||||
"Create new stream": "Új üzenetfolyam létrehozása",
|
||||
"Create stream": "Folyam létrehozása",
|
||||
"Creating bot": "Bot létrehozása...",
|
||||
"Creating bot": "Robot létrehozása...",
|
||||
"Creating stream...": "Üzenetfolyam létrehozása...",
|
||||
"Current password": "Jelenlegi jelszó",
|
||||
"Custom": "Egyedi",
|
||||
@@ -227,7 +227,7 @@
|
||||
"Default view": "Alapértelmezett nézet",
|
||||
"Delete": "Törlés",
|
||||
"Delete alert word": "Figyelt szó törlése",
|
||||
"Delete bot": "Bot törlése",
|
||||
"Delete bot": "Robot törlése",
|
||||
"Delete draft": "Piszkozat törlése",
|
||||
"Delete file": "Fájl törlése",
|
||||
"Delete icon": "Ikon törlése",
|
||||
@@ -254,7 +254,7 @@
|
||||
"Don\u2019t allow disposable email addresses": "Nem engedje meg az eldobható email címek használatát",
|
||||
"Download .zuliprc": ".zuliprc letöltése",
|
||||
"Download botserverrc": "A botserverrc letöltése",
|
||||
"Download config of all active outgoing webhook bots in Zulip Botserver format.": "Minden kimenő aktív webhook bot konfigurációjának letöltése Zulip Botserver formátumban",
|
||||
"Download config of all active outgoing webhook bots in Zulip Botserver format.": "Minden kimenő aktív webhook robot konfigurációjának letöltése Zulip Botserver formátumban",
|
||||
"Download file": "Fájl letöltése",
|
||||
"Download zuliprc": "zuliprc letöltése",
|
||||
"Drafts": "Piszkozatok",
|
||||
@@ -262,7 +262,7 @@
|
||||
"Drafts older than <strong>{draft_lifetime}</strong> days are automatically removed.": "A/az <strong>{draft_lifetime}</strong> napnál régebbi piszkozatokat automatikusan eltávolítjuk.",
|
||||
"EDITED": "SZERKESZTVE",
|
||||
"Edit": "Szerkesztés",
|
||||
"Edit bot": "Bot szerkesztése",
|
||||
"Edit bot": "Robot szerkesztése",
|
||||
"Edit linkifiers": "Linkesítők szerkesztése",
|
||||
"Edit status message": "Állapotüzeneted szerkesztése",
|
||||
"Edit topic": "Téma szerkesztése",
|
||||
@@ -316,7 +316,7 @@
|
||||
"File size must be at most {max_file_size} MiB.": "Az állomány mérete maximum {max_file_size} MiB lehet.",
|
||||
"File type is not supported.": "A fájltípus nem támogatott.",
|
||||
"Filter": "Szűrő",
|
||||
"Filter bots": "Szűrőbotok",
|
||||
"Filter bots": "Robotok szűrése",
|
||||
"Filter by category": "Szűrés kategória szerint",
|
||||
"Filter code playgrounds": "Kód játszóterek szűrése",
|
||||
"Filter deactivated users": "Letiltott felhasználók szűrése",
|
||||
@@ -361,7 +361,7 @@
|
||||
"Humans": "Emberek",
|
||||
"Idle": "Tétlen",
|
||||
"Image": "Kép",
|
||||
"Inactive bots": "Inaktív botok",
|
||||
"Inactive bots": "Inaktív robotok",
|
||||
"Include content of private messages in desktop notifications": "A privát üzenetek szövege megjelenhet az asztali értesítésekben",
|
||||
"Include message content in message notification emails": "Az üzenet szövege megjelenhet az üzenetről értesítő mailekben",
|
||||
"Include muted": "Némítottakkal együtt",
|
||||
@@ -479,7 +479,7 @@
|
||||
"Night": "Éjszaka",
|
||||
"Night logo": "Éjszakai logó",
|
||||
"Night mode": "Éjszakai mód",
|
||||
"No bots match your current filter.": "Nincs a szűrésnek megfelelő bot.",
|
||||
"No bots match your current filter.": "Nincs a szűrésnek megfelelő robot.",
|
||||
"No custom emoji.": "Nincs egyedi hangulatjel.",
|
||||
"No default streams match you current filter.": "Nincs a szűrésnek megfelelő alapértelmezett üzenetfolyam.",
|
||||
"No description.": "Nincs leírás.",
|
||||
@@ -501,7 +501,7 @@
|
||||
"No. Only moderators and admins can send invitations.": "Nem. Csak moderátorok és adminok küldhetnek meghívókat.",
|
||||
"Nobody": "Senki",
|
||||
"None": "Nincs",
|
||||
"Note that any bots that you maintain will be disabled.": "Vedd figyelembe, hogy minden botod letiltásra fog kerülni.",
|
||||
"Note that any bots that you maintain will be disabled.": "Vedd figyelembe, hogy minden robotod letiltásra fog kerülni.",
|
||||
"Note that organizations are limited to five exports per week.": "Megjegyzés: a szervezetek hetente öt alkalommal végezhetnek exportálást.",
|
||||
"Nothing to preview": "Nincs mit megmutatni előnézetként",
|
||||
"Notification sound": "Értesítési hang",
|
||||
@@ -516,9 +516,9 @@
|
||||
"Only group members and organization administrators can modify a group.": "Csak csoporttagok és szervezeti adminisztrátorok módosíthatják a csoportokat.",
|
||||
"Only organization administrators and moderators can post": "Csak szervezeti adminisztrátorok és moderátorok üzenhetnek",
|
||||
"Only organization administrators and moderators can post.": "Csak szervezeti adminisztrátorok és moderátorok üzenhetnek.",
|
||||
"Only organization administrators can add bots to this organization": "Csak szervezeti adminisztrátorok adhatnak hozzá botokat ehhez a szervezethez",
|
||||
"Only organization administrators can add bots to this organization": "Csak szervezeti adminisztrátorok adhatnak hozzá robotokat ehhez a szervezethez",
|
||||
"Only organization administrators can add custom emoji in this organization.": "Csak szervezeti adminisztrátorok adhatnak egyedi hangulatjelet ehhez a szervezethez.",
|
||||
"Only organization administrators can add generic bots": "Csak szervezeti adminisztrátorok hozhatnak létre általános botokat",
|
||||
"Only organization administrators can add generic bots": "Csak szervezeti adminisztrátorok hozhatnak létre általános robotokat",
|
||||
"Only organization administrators can edit these settings.": "Ezeket a beállításokat csak a szervezet adminisztrátorai módosíthatják.",
|
||||
"Only organization administrators can modify user groups in this organization.": "Csak szervezeti adminisztrátorok módosíthatnak felhasználói csoportokat ebben a szervezetben.",
|
||||
"Only organization administrators can post": "Csak a szervezeti adminisztrátorok üzenhetnek",
|
||||
@@ -591,7 +591,7 @@
|
||||
"Public stream messages in organization": "Nyilvános üzenetfolyam üzenetek a szervezetben",
|
||||
"Quote and reply or forward": "Válasz vagy továbbítás idézéssel",
|
||||
"Reactivate": "Újraaktiválás",
|
||||
"Reactivate bot": "Bot újraaktíválása",
|
||||
"Reactivate bot": "Robot újraaktíválása",
|
||||
"Receives new stream notifications": "Új üzenetfolyam értesítéseket kap",
|
||||
"Recent topics": "Legfrissebb témák",
|
||||
"Remind me about this": "Emlékeztess erről",
|
||||
@@ -699,14 +699,14 @@
|
||||
"Subscribers": "Feliratkozók",
|
||||
"Successfully subscribed users:": "Sikeresen feliratkozott felhasználók:",
|
||||
"Sunday": "vasárnap",
|
||||
"System bot": "Rendszet bot",
|
||||
"System bot": "Rendszer robot",
|
||||
"Task already exists": "A feladat már létezik",
|
||||
"The recipient {recipient} is not valid": "A/az {recipient} címzett érvénytelen",
|
||||
"The recipients {recipients} are not valid": "A/az {recipients} címzettek érvénytelenek",
|
||||
"The stream description cannot contain newline characters.": "Az üzenetfolyam leírása nem tartalmazhat soremelést.",
|
||||
"The stream description has been updated!": "Az üzenetfolyam leírását frissítettük!",
|
||||
"The stream has been renamed!": "Az üzenetfolyamot átnevezésre került!",
|
||||
"Their password will be cleared from our systems, and any bots they maintain will be disabled.": "Jelszavuk törlődik a rendszereinkből, és minden általuk fenntartott botot letiltunk.",
|
||||
"Their password will be cleared from our systems, and any bots they maintain will be disabled.": "Jelszavuk törlődik a rendszereinkből, és minden általuk fenntartott robotot letiltunk.",
|
||||
"There are no current alert words.": "Jelenleg nincsenek figyelt szavak.",
|
||||
"These settings are explained in detail in the <z-link>help center</z-link>.": "Ezeket a beállításokat a<z-link> Súgó Központban</z-link> részletesen is bemutatjuk.",
|
||||
"This action is permanent and cannot be undone. All users will permanently lose access to their Zulip accounts.": "Ez a művelet végleges és nem lehet visszavonni. Minden felhasználó végleg el fogja veszíteni hozzáférését a Zulip fiókjaikhoz.",
|
||||
@@ -817,7 +817,7 @@
|
||||
"Whether wildcard mentions like @all are treated as mentions for the purpose of notifications.": "A csoportos említések - mint pl. az @all - értesítési szempontból is említésként legyenek-e kezelve vagy sem.",
|
||||
"Who can access the stream?": "Ki érheti el az üzenetfolyamot?",
|
||||
"Who can access user email addresses": "Ki érheti el a felhasználó e-mail címeit",
|
||||
"Who can add bots": "Ki hozhat létre botokat",
|
||||
"Who can add bots": "Ki hozhat létre robotokat",
|
||||
"Who can add custom emoji": "Ki adhat hozzá egyedi hangulatjeleket",
|
||||
"Who can add users to streams": "Ki adhat hozzá felhasználókat az üzenetfolyamhoz",
|
||||
"Who can create and manage user groups": "Ki hozhat létre és kezelhet felhasználói csoportokat",
|
||||
@@ -855,8 +855,8 @@
|
||||
"You do not have permission to use wildcard mentions in this stream.": "Nincs engedélyed csoportos említések használatára ebben az üzenetfolyamban.",
|
||||
"You get": "Azt kapod",
|
||||
"You have muted <z-stream-topic></z-stream-topic>.": "<z-stream-topic></z-stream-topic> elnémítva.",
|
||||
"You have no active bots.": "Nincsenek aktív botjaid.",
|
||||
"You have no inactive bots.": "Nincsenek inaktív botjaid.",
|
||||
"You have no active bots.": "Nincsenek aktív robotjaid.",
|
||||
"You have no inactive bots.": "Nincsenek inaktív robotjaid.",
|
||||
"You have not muted any topics yet.": "Nem némítottál el egyetlen témát sem.",
|
||||
"You have not muted any users yet.": "Nem némítottál el egyetlen felhasználót sem.",
|
||||
"You have not uploaded any files.": "Még nincsenek feltöltött állományaid.",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# Alessio Schreiber <alessio.schreiber@gmail.com>, 2021
|
||||
# Paolo Midali <pmidali@latek.it>, 2021
|
||||
# Andrea, 2021
|
||||
# Alya Abbott <alya@zulip.com>, 2021
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
@@ -19,7 +20,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-05-26 18:04+0000\n"
|
||||
"PO-Revision-Date: 2021-04-02 21:39+0000\n"
|
||||
"Last-Translator: Andrea, 2021\n"
|
||||
"Last-Translator: Alya Abbott <alya@zulip.com>, 2021\n"
|
||||
"Language-Team: Italian (https://www.transifex.com/zulip/teams/53893/it/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -3821,7 +3822,7 @@ msgstr "Non siamo riusciti a trovare questa l'organizzazione Zulip."
|
||||
#: zerver/lib/actions.py:357 zerver/lib/actions.py:369
|
||||
#, python-brace-format
|
||||
msgid "{user} just signed up for Zulip. (total: {user_count})"
|
||||
msgstr "{user}appena registrato su Zulip. (total: {user_count})"
|
||||
msgstr "{user} appena registrato su Zulip. (total: {user_count})"
|
||||
|
||||
#: zerver/lib/actions.py:360
|
||||
msgid "signups"
|
||||
@@ -4869,7 +4870,7 @@ msgstr "{var_name} è troppo lungo (limit: {max_length} characters)"
|
||||
#, python-brace-format
|
||||
msgid "{var_name} has incorrect length {length}; should be {target_length}"
|
||||
msgstr ""
|
||||
"{var_name} ha lunghezza errata{length}; dovrebbe essere {target_length}"
|
||||
"{var_name} ha lunghezza errata {length}; dovrebbe essere {target_length}"
|
||||
|
||||
#: zerver/lib/validator.py:122 zerver/lib/validator.py:124
|
||||
#, python-brace-format
|
||||
@@ -5111,7 +5112,7 @@ msgstr "Un evento più recente di {event_id} è già stato eliminato!"
|
||||
#: zerver/tornado/event_queue.py:654
|
||||
#, python-brace-format
|
||||
msgid "Event {event_id} was not in this queue"
|
||||
msgstr "Evento{event_id} non è in questa coda"
|
||||
msgstr "Evento {event_id} non è in questa coda"
|
||||
|
||||
#: zerver/tornado/exceptions.py:15
|
||||
#, python-brace-format
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
# 최진호 <jinho.choi.999@gmail.com>, 2021
|
||||
# Yeonjeong Noh <nyj2800@hanmail.net>, 2021
|
||||
# sung yong kim <hikimsy@gmail.com>, 2021
|
||||
# F4D3C0D3 0x, 2021
|
||||
# KIM JINWOO, 2021
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
@@ -25,7 +27,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-05-26 18:04+0000\n"
|
||||
"PO-Revision-Date: 2021-04-02 21:39+0000\n"
|
||||
"Last-Translator: sung yong kim <hikimsy@gmail.com>, 2021\n"
|
||||
"Last-Translator: KIM JINWOO, 2021\n"
|
||||
"Language-Team: Korean (https://www.transifex.com/zulip/teams/53893/ko/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -226,6 +228,7 @@ msgid ""
|
||||
"A full update of all the graphs happens once a day. The “messages sent over "
|
||||
"time” graph is updated once an hour."
|
||||
msgstr ""
|
||||
"모든 그래프의 전체 업데이트는 하루에 한 번 합니다. \"메세지가 보내진지 시간 경과된\" 그래프는 한 시간에 한 번 업데이트 됩니다."
|
||||
|
||||
#: templates/analytics/stats.html:129
|
||||
msgid "Analytics documentation"
|
||||
@@ -243,10 +246,13 @@ msgid ""
|
||||
" from %(old_email_html_tag)s to %(new_email_html_tag)s\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"이것은 너의 Zulip 계정에 있는 이메일 주소가 변경되었는지 확인한다.\n"
|
||||
"from 전 이메일%(old_email_html_tag)s to 현재 새로운 이메일%(new_email_html_tag)s "
|
||||
|
||||
#: templates/confirmation/link_does_not_exist.html:9
|
||||
msgid "Whoops. We couldn't find your confirmation link in the system."
|
||||
msgstr ""
|
||||
msgstr "오류. 우리는 이 시스템에서 너를 확인할 만한 것을 찾지 못했습니다."
|
||||
|
||||
#: templates/confirmation/link_does_not_exist.html:11
|
||||
#: templates/confirmation/link_malformed.html:12
|
||||
@@ -256,24 +262,27 @@ msgid ""
|
||||
" Anyway, shoot us a line at %(support_email_html_tag)s and we'll get this resolved shortly.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"어떠한 방식으로든, 너는 우리에게 어떠한 얘기라도 보내라 %(support_email_html_tag)s으로 그러면 우리는 이것을 즉시 해결 할 것이다."
|
||||
|
||||
#: templates/confirmation/link_expired.html:10
|
||||
msgid "Whoops. The confirmation link has expired or been deactivated."
|
||||
msgstr ""
|
||||
msgstr "오류. 확인 링크가 만료되었거나 비활성화 되었습니다."
|
||||
|
||||
#: templates/confirmation/link_expired.html:11
|
||||
msgid "Please contact your organization administrator for a new link."
|
||||
msgstr ""
|
||||
msgstr "조직 관리자에게 새로운 링크로 연락해라"
|
||||
|
||||
#: templates/confirmation/link_malformed.html:9
|
||||
msgid "Whoops. The confirmation link is malformed."
|
||||
msgstr ""
|
||||
msgstr "오류. 이 확인 링크는 형식화되지 않았습니다."
|
||||
|
||||
#: templates/confirmation/link_malformed.html:10
|
||||
msgid ""
|
||||
"Make sure you copied the link correctly in to your browser. If you're still "
|
||||
"encountering this page, it's probably our fault. We're sorry."
|
||||
msgstr ""
|
||||
"너의 브라우저에 올바른 링크를 복사하는 것을 확실히 해주십시오. 이 페이지가 계속 생성될 경우, 아마도 오류가 생겼습니다. 죄송합니다."
|
||||
|
||||
#: templates/corporate/billing.html:21 templates/zerver/app/navbar.html:140
|
||||
msgid "Billing"
|
||||
@@ -298,11 +307,11 @@ msgstr "해마다 지불"
|
||||
|
||||
#: templates/corporate/upgrade.html:85
|
||||
msgid "License management"
|
||||
msgstr ""
|
||||
msgstr "라이센스 관리"
|
||||
|
||||
#: templates/corporate/upgrade.html:89
|
||||
msgid "Automatic"
|
||||
msgstr ""
|
||||
msgstr "자동"
|
||||
|
||||
#: templates/corporate/upgrade.html:90
|
||||
msgid "Most convenient"
|
||||
@@ -447,11 +456,11 @@ msgstr "메시지 삭제"
|
||||
|
||||
#: templates/zerver/app/delete_message.html:13
|
||||
msgid "Are you sure you want to permanently delete this message?"
|
||||
msgstr ""
|
||||
msgstr "당신은 이 메세지를 영구적으로 삭제하시겠습니까?"
|
||||
|
||||
#: templates/zerver/app/delete_message.html:14
|
||||
msgid "Deleting a message removes it for everyone."
|
||||
msgstr ""
|
||||
msgstr "모두를 위해 삭제된 메세지를 지움"
|
||||
|
||||
#: templates/zerver/app/delete_message.html:19
|
||||
#: templates/zerver/app/index.html:167
|
||||
@@ -461,7 +470,7 @@ msgstr "취소"
|
||||
|
||||
#: templates/zerver/app/delete_message.html:20
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
msgstr "확인"
|
||||
|
||||
#: templates/zerver/app/deprecation_notice.html:6
|
||||
msgid "Deprecation notice"
|
||||
@@ -644,19 +653,19 @@ msgstr ""
|
||||
|
||||
#: templates/zerver/app/index.html:160
|
||||
msgid "In a meeting"
|
||||
msgstr ""
|
||||
msgstr "회의 안 에서"
|
||||
|
||||
#: templates/zerver/app/index.html:161
|
||||
msgid "Commuting"
|
||||
msgstr ""
|
||||
msgstr "출근중"
|
||||
|
||||
#: templates/zerver/app/index.html:162
|
||||
msgid "Out sick"
|
||||
msgstr ""
|
||||
msgstr "병가"
|
||||
|
||||
#: templates/zerver/app/index.html:163
|
||||
msgid "Vacationing"
|
||||
msgstr ""
|
||||
msgstr "휴가 중"
|
||||
|
||||
#: templates/zerver/app/index.html:164
|
||||
msgid "Working remotely"
|
||||
@@ -702,7 +711,7 @@ msgstr "회원"
|
||||
#: templates/zerver/app/invite_user.html:43
|
||||
#: templates/zerver/development/dev_login.html:40
|
||||
msgid "Moderators"
|
||||
msgstr ""
|
||||
msgstr "중재자들"
|
||||
|
||||
#: templates/zerver/app/invite_user.html:44
|
||||
msgid "Organization administrators"
|
||||
@@ -789,7 +798,7 @@ msgstr "키보드 단축키 보기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:56
|
||||
msgid "Go to default view"
|
||||
msgstr ""
|
||||
msgstr "기본 보기로 돌아가기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:65
|
||||
msgid "Navigation"
|
||||
@@ -853,11 +862,11 @@ msgstr "선택해서 보기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:159
|
||||
msgid "Narrow to stream"
|
||||
msgstr ""
|
||||
msgstr "스트림을 묶기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:163
|
||||
msgid "Narrow to topic or PM conversation"
|
||||
msgstr ""
|
||||
msgstr "주제 또는 PM 대화와 묶기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:167
|
||||
msgid "Narrow to all private messages"
|
||||
@@ -931,7 +940,7 @@ msgstr "최근 주제들 보기"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:251
|
||||
msgid "Filter topics"
|
||||
msgstr ""
|
||||
msgstr "주제를 필터링"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:260
|
||||
msgid "Drafts"
|
||||
@@ -1012,11 +1021,11 @@ msgstr "구독, 추가 혹은 스트림 구성"
|
||||
|
||||
#: templates/zerver/app/left_sidebar.html:73
|
||||
msgid "Back to streams"
|
||||
msgstr ""
|
||||
msgstr "스트림으로 돌아가기"
|
||||
|
||||
#: templates/zerver/app/left_sidebar.html:80
|
||||
msgid "Subscribe to more streams"
|
||||
msgstr ""
|
||||
msgstr "더 많은 스트림들을 구독"
|
||||
|
||||
#: templates/zerver/app/lightbox_overlay.html:10
|
||||
msgid "Pan & Zoom"
|
||||
@@ -1079,7 +1088,7 @@ msgstr "조직 관리"
|
||||
|
||||
#: templates/zerver/app/navbar.html:83
|
||||
msgid "Usage statistics"
|
||||
msgstr ""
|
||||
msgstr "사용 통계"
|
||||
|
||||
#: templates/zerver/app/navbar.html:90 templates/zerver/footer.html:16
|
||||
msgid "Help center"
|
||||
@@ -1100,7 +1109,7 @@ msgstr "Zulip에 대해"
|
||||
|
||||
#: templates/zerver/app/navbar.html:117
|
||||
msgid "Contact support"
|
||||
msgstr ""
|
||||
msgstr "고객지원 연결"
|
||||
|
||||
#: templates/zerver/app/navbar.html:124
|
||||
msgid "Desktop & mobile apps"
|
||||
@@ -1116,7 +1125,7 @@ msgstr "API 문서"
|
||||
|
||||
#: templates/zerver/app/navbar.html:147
|
||||
msgid "Support Zulip"
|
||||
msgstr ""
|
||||
msgstr "Zulip에 도움"
|
||||
|
||||
#: templates/zerver/app/navbar.html:154
|
||||
msgid "Plans and pricing"
|
||||
@@ -1193,19 +1202,19 @@ msgstr ""
|
||||
|
||||
#: templates/zerver/app/navbar_alerts.html:43
|
||||
msgid "Download the latest version."
|
||||
msgstr ""
|
||||
msgstr "가장 최근 버전 다운로드"
|
||||
|
||||
#: templates/zerver/app/navbar_alerts.html:50
|
||||
msgid "This Zulip server is running an old version and should be upgraded."
|
||||
msgstr ""
|
||||
msgstr "Zulip 서버가 오래된 버전으로 사용 중 입니다. 업그레이드를 진행 하십시오"
|
||||
|
||||
#: templates/zerver/app/navbar_alerts.html:53
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
msgstr "좀 더 알아보기"
|
||||
|
||||
#: templates/zerver/app/navbar_alerts.html:56
|
||||
msgid "Dismiss for a week"
|
||||
msgstr ""
|
||||
msgstr "한 주 동안 무시"
|
||||
|
||||
#: templates/zerver/app/navbar_alerts.html:64
|
||||
#, python-format
|
||||
@@ -1285,7 +1294,7 @@ msgstr "해당 메시지 ID만 보기"
|
||||
|
||||
#: templates/zerver/app/search_operators.html:45
|
||||
msgid "Search all public streams in the organization."
|
||||
msgstr ""
|
||||
msgstr "이 조직에 있는 모든 공개 스트림들을 찾기 "
|
||||
|
||||
#: templates/zerver/app/search_operators.html:49
|
||||
msgid "Narrow to messages with alert words."
|
||||
@@ -1395,7 +1404,7 @@ msgstr "알림끈 주제"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:48
|
||||
msgid "Muted users"
|
||||
msgstr ""
|
||||
msgstr "음소거된 유저들"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:55
|
||||
msgid "Organization profile"
|
||||
@@ -1440,7 +1449,7 @@ msgstr "인증 방법"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:95
|
||||
msgid "Only organization owners can edit these settings."
|
||||
msgstr ""
|
||||
msgstr "오직 조직 주인만 이 설정을 변경할 수 있습니다."
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:110
|
||||
msgid "Deactivated users"
|
||||
@@ -1456,7 +1465,7 @@ msgstr "링크 변환기"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:143
|
||||
msgid "Code playgrounds"
|
||||
msgstr ""
|
||||
msgstr "코드방"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:151
|
||||
msgid "Custom profile fields"
|
||||
@@ -1468,11 +1477,11 @@ msgstr "초대장"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:163
|
||||
msgid "Data exports"
|
||||
msgstr ""
|
||||
msgstr "데이터 내보내기"
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:169
|
||||
msgid "Show more"
|
||||
msgstr ""
|
||||
msgstr "더 보여주기"
|
||||
|
||||
#: templates/zerver/config_error.html:14
|
||||
msgid ""
|
||||
@@ -3571,7 +3580,7 @@ msgstr ""
|
||||
|
||||
#: zerver/lib/actions.py:2991
|
||||
msgid "Private messages are disabled in this organization."
|
||||
msgstr ""
|
||||
msgstr "이 조직에서 개인 메시지는 비활성화 되었습니다."
|
||||
|
||||
#: zerver/lib/actions.py:3116
|
||||
msgid "Widgets: API programmer sent invalid JSON content"
|
||||
@@ -4562,7 +4571,7 @@ msgstr ""
|
||||
|
||||
#: zerver/models.py:1417
|
||||
msgid "Moderator"
|
||||
msgstr ""
|
||||
msgstr "중재자"
|
||||
|
||||
#: zerver/models.py:1418
|
||||
msgid "Member"
|
||||
@@ -5122,7 +5131,7 @@ msgstr ""
|
||||
|
||||
#: zerver/views/user_settings.py:49
|
||||
msgid "Avatar changes are disabled in this organization."
|
||||
msgstr ""
|
||||
msgstr "아바타 변경은 이 조직에서 불가능합니다."
|
||||
|
||||
#: zerver/views/user_settings.py:63 zerver/views/user_settings.py:149
|
||||
msgid "Email address changes are disabled in this organization."
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +1,138 @@
|
||||
{
|
||||
"ar": {
|
||||
"not_translated": 218,
|
||||
"total": 256
|
||||
"not_translated": 239,
|
||||
"total": 277
|
||||
},
|
||||
"bg": {
|
||||
"not_translated": 126,
|
||||
"total": 256
|
||||
"not_translated": 147,
|
||||
"total": 277
|
||||
},
|
||||
"ca": {
|
||||
"not_translated": 31,
|
||||
"total": 256
|
||||
"not_translated": 52,
|
||||
"total": 277
|
||||
},
|
||||
"cs": {
|
||||
"not_translated": 21,
|
||||
"total": 256
|
||||
"not_translated": 41,
|
||||
"total": 277
|
||||
},
|
||||
"de": {
|
||||
"not_translated": 0,
|
||||
"total": 256
|
||||
"total": 277
|
||||
},
|
||||
"en_GB": {
|
||||
"not_translated": 0,
|
||||
"total": 256
|
||||
"total": 277
|
||||
},
|
||||
"es": {
|
||||
"not_translated": 31,
|
||||
"total": 256
|
||||
"not_translated": 51,
|
||||
"total": 277
|
||||
},
|
||||
"fa": {
|
||||
"not_translated": 77,
|
||||
"total": 256
|
||||
"not_translated": 97,
|
||||
"total": 277
|
||||
},
|
||||
"fi": {
|
||||
"not_translated": 27,
|
||||
"total": 256
|
||||
"not_translated": 47,
|
||||
"total": 277
|
||||
},
|
||||
"fr": {
|
||||
"not_translated": 0,
|
||||
"total": 256
|
||||
"total": 277
|
||||
},
|
||||
"gl": {
|
||||
"not_translated": 123,
|
||||
"total": 256
|
||||
"not_translated": 144,
|
||||
"total": 277
|
||||
},
|
||||
"hi": {
|
||||
"not_translated": 93,
|
||||
"total": 256
|
||||
"not_translated": 114,
|
||||
"total": 277
|
||||
},
|
||||
"hu": {
|
||||
"not_translated": 29,
|
||||
"total": 256
|
||||
"not_translated": 49,
|
||||
"total": 277
|
||||
},
|
||||
"id": {
|
||||
"not_translated": 131,
|
||||
"total": 256
|
||||
"not_translated": 152,
|
||||
"total": 277
|
||||
},
|
||||
"it": {
|
||||
"not_translated": 7,
|
||||
"total": 256
|
||||
"not_translated": 20,
|
||||
"total": 277
|
||||
},
|
||||
"ja": {
|
||||
"not_translated": 88,
|
||||
"total": 256
|
||||
"not_translated": 108,
|
||||
"total": 277
|
||||
},
|
||||
"ko": {
|
||||
"not_translated": 31,
|
||||
"total": 256
|
||||
"not_translated": 51,
|
||||
"total": 277
|
||||
},
|
||||
"lt": {
|
||||
"not_translated": 225,
|
||||
"total": 256
|
||||
"not_translated": 246,
|
||||
"total": 277
|
||||
},
|
||||
"ml": {
|
||||
"not_translated": 222,
|
||||
"total": 256
|
||||
"not_translated": 243,
|
||||
"total": 277
|
||||
},
|
||||
"nl": {
|
||||
"not_translated": 22,
|
||||
"total": 256
|
||||
"not_translated": 42,
|
||||
"total": 277
|
||||
},
|
||||
"pl": {
|
||||
"not_translated": 39,
|
||||
"total": 256
|
||||
"not_translated": 59,
|
||||
"total": 277
|
||||
},
|
||||
"pt": {
|
||||
"not_translated": 31,
|
||||
"total": 256
|
||||
"not_translated": 51,
|
||||
"total": 277
|
||||
},
|
||||
"pt_PT": {
|
||||
"not_translated": 75,
|
||||
"total": 256
|
||||
"not_translated": 95,
|
||||
"total": 277
|
||||
},
|
||||
"ro": {
|
||||
"not_translated": 30,
|
||||
"total": 256
|
||||
"not_translated": 50,
|
||||
"total": 277
|
||||
},
|
||||
"ru": {
|
||||
"not_translated": 0,
|
||||
"total": 256
|
||||
"total": 277
|
||||
},
|
||||
"sr": {
|
||||
"not_translated": 235,
|
||||
"total": 256
|
||||
"not_translated": 256,
|
||||
"total": 277
|
||||
},
|
||||
"sv": {
|
||||
"not_translated": 197,
|
||||
"total": 256
|
||||
"not_translated": 217,
|
||||
"total": 277
|
||||
},
|
||||
"ta": {
|
||||
"not_translated": 192,
|
||||
"total": 256
|
||||
"not_translated": 213,
|
||||
"total": 277
|
||||
},
|
||||
"tr": {
|
||||
"not_translated": 0,
|
||||
"total": 256
|
||||
"not_translated": 20,
|
||||
"total": 277
|
||||
},
|
||||
"uk": {
|
||||
"not_translated": 21,
|
||||
"total": 256
|
||||
"not_translated": 41,
|
||||
"total": 277
|
||||
},
|
||||
"vi": {
|
||||
"not_translated": 232,
|
||||
"total": 256
|
||||
"not_translated": 253,
|
||||
"total": 277
|
||||
},
|
||||
"zh_Hans": {
|
||||
"not_translated": 96,
|
||||
"total": 256
|
||||
"not_translated": 116,
|
||||
"total": 277
|
||||
},
|
||||
"zh_Hant": {
|
||||
"not_translated": 107,
|
||||
"total": 256
|
||||
"not_translated": 128,
|
||||
"total": 277
|
||||
},
|
||||
"zh_TW": {
|
||||
"not_translated": 29,
|
||||
"total": 256
|
||||
"not_translated": 49,
|
||||
"total": 277
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-23 19:14+0000\n"
|
||||
"POT-Creation-Date: 2021-11-30 22:59+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -1403,7 +1403,7 @@ msgstr ""
|
||||
msgid "Organization permissions"
|
||||
msgstr ""
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2390
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2391
|
||||
msgid "Custom emoji"
|
||||
msgstr ""
|
||||
|
||||
@@ -3802,7 +3802,7 @@ msgstr ""
|
||||
msgid "Message must have recipients"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:193
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:215
|
||||
msgid "Invalid message type"
|
||||
msgstr ""
|
||||
|
||||
@@ -3916,7 +3916,7 @@ msgstr ""
|
||||
msgid "Must be an organization administrator or emoji author"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:840
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:841
|
||||
msgid "Invalid characters in emoji name"
|
||||
msgstr ""
|
||||
|
||||
@@ -4236,11 +4236,11 @@ msgid ""
|
||||
"a previous message."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:293
|
||||
#: zerver/lib/outgoing_webhook.py:315
|
||||
msgid "Invalid JSON in response"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:302
|
||||
#: zerver/lib/outgoing_webhook.py:324
|
||||
msgid "Invalid response format"
|
||||
msgstr ""
|
||||
|
||||
@@ -4435,7 +4435,7 @@ msgstr ""
|
||||
msgid "Invalid interface type"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3469
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3470
|
||||
msgid "Invalid user ID: {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -4611,87 +4611,91 @@ msgstr ""
|
||||
msgid "CSRF error: {reason}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:372
|
||||
#: zerver/models.py:373
|
||||
msgid "stream events"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:406
|
||||
#: zerver/models.py:407
|
||||
msgid "Available on Zulip Standard. Upgrade to access."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:910
|
||||
msgid "Invalid linkifier pattern. Valid characters are {}."
|
||||
#: zerver/models.py:919 zerver/models.py:921
|
||||
msgid "Bad regular expression: {}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:928
|
||||
#: zerver/models.py:922
|
||||
msgid "Unknown regular expression error"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:929
|
||||
msgid "Invalid URL format string."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1035 zerver/views/realm_playgrounds.py:24
|
||||
#: zerver/models.py:1036 zerver/views/realm_playgrounds.py:24
|
||||
msgid "Invalid characters in pygments language"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1415
|
||||
#: zerver/models.py:1416
|
||||
msgid "Organization owner"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1416
|
||||
#: zerver/models.py:1417
|
||||
msgid "Organization administrator"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1417
|
||||
#: zerver/models.py:1418
|
||||
msgid "Moderator"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1418
|
||||
#: zerver/models.py:1419
|
||||
msgid "Member"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1419
|
||||
#: zerver/models.py:1420
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2389
|
||||
#: zerver/models.py:2390
|
||||
msgid "Unicode emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2391
|
||||
#: zerver/models.py:2392
|
||||
msgid "Zulip extra emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3473
|
||||
#: zerver/models.py:3474
|
||||
msgid "User with ID {} is deactivated"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3476
|
||||
#: zerver/models.py:3477
|
||||
msgid "User with ID {} is a bot"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3509
|
||||
#: zerver/models.py:3510
|
||||
msgid "List of options"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3512
|
||||
#: zerver/models.py:3513
|
||||
msgid "Person picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3524
|
||||
#: zerver/models.py:3525
|
||||
msgid "Short text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3525
|
||||
#: zerver/models.py:3526
|
||||
msgid "Long text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3526
|
||||
#: zerver/models.py:3527
|
||||
msgid "Date picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3527
|
||||
#: zerver/models.py:3528
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3530
|
||||
#: zerver/models.py:3531
|
||||
msgid "External account"
|
||||
msgstr ""
|
||||
|
||||
@@ -4707,24 +4711,24 @@ msgstr ""
|
||||
msgid "An unknown browser"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:632
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
msgid "Missing 'queue_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:635
|
||||
#: zerver/tornado/event_queue.py:647
|
||||
msgid "Missing 'last_event_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:638
|
||||
#: zerver/tornado/event_queue.py:650
|
||||
msgid "You are not authorized to get events from this queue"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
#: zerver/tornado/event_queue.py:656
|
||||
#, python-brace-format
|
||||
msgid "An event newer than {event_id} has already been pruned!"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:654
|
||||
#: zerver/tornado/event_queue.py:666
|
||||
#, python-brace-format
|
||||
msgid "Event {event_id} was not in this queue"
|
||||
msgstr ""
|
||||
@@ -5422,14 +5426,14 @@ msgstr ""
|
||||
msgid "Invalid data."
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:1922
|
||||
#: zproject/backends.py:1927
|
||||
msgid "Missing id_token parameter"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2277
|
||||
#: zproject/backends.py:2282
|
||||
msgid "Invalid OTP"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2280
|
||||
#: zproject/backends.py:2285
|
||||
msgid "Can't use both mobile_flow_otp and desktop_flow_otp together."
|
||||
msgstr ""
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"(unavailable)": "(недоступно)",
|
||||
"(you)": "(вы)",
|
||||
"({message_retention_days} days)": "({message_retention_days} дней)",
|
||||
"/dark (Toggle night mode)": "/dark (Включить ночной режим)",
|
||||
"/dark (Toggle night mode)": "/dark (Включить темный режим)",
|
||||
"/day (Toggle day mode)": "/day (Включить дневной режим)",
|
||||
"/fixed-width (Toggle fixed width mode)": "/fixed-width (Включить фиксированный формат отображения рабочей области)",
|
||||
"/fluid-width (Toggle fluid width mode)": "/fluid-width (Включить широкий формат отображения рабочей области)",
|
||||
@@ -32,10 +32,10 @@
|
||||
"<z-link>Click here</z-link> to learn about exporting private streams and messages.": "<z-link>Нажмите здесь</z-link>, чтобы узнать больше об экспорте закрытых каналов и сообщений.",
|
||||
"<z-link>Upgrade</z-link> for more space.": "<z-link>Обновите</z-link>, чтобы получить больше места.",
|
||||
"A Topic Move already in progress.": "Перемещение темы уже в процессе.",
|
||||
"A language is marked as 100% translated only if every string in the web, desktop, and mobile apps is translated, including administrative UI and error messages.": "Язык отмечается переведенным на 100% только если все строки в web, настольном и мобильном приложениях переведены, включая интерфейс администратора и сообщения об ошибках.",
|
||||
"A language is marked as 100% translated only if every string in the web, desktop, and mobile apps is translated, including administrative UI and error messages.": "Язык отмечается переведенным на 100% только, если переведены все строки веб-интерфейса, настольного и мобильного приложений, включая интерфейс администратора и сообщения об ошибках.",
|
||||
"A stream needs to have a name": "Канал должен иметь название",
|
||||
"A stream with this name already exists": "Канал с таким именем уже существует",
|
||||
"A unicode emoji with name <b>{emoji_name}</b> already exists. Uploading a custom emoji with this name will override the unicode emoji with this name.": "Эмодзи с именем <b>{emoji_name}</b> уже существует. Загрузка дополнительного эмодзи с этим именем перезапишет существующий эмодзи.",
|
||||
"A stream with this name already exists": "Канал с таким названием уже существует",
|
||||
"A unicode emoji with name <b>{emoji_name}</b> already exists. Uploading a custom emoji with this name will override the unicode emoji with this name.": "Эмодзи с названием <b>{emoji_name}</b> уже существует. Загрузка дополнительного эмодзи с этим названием перезапишет существующий эмодзи.",
|
||||
"A wide image for the upper left corner of the app.": "Широкое изображение для верхнего левого угла приложения.",
|
||||
"API key": "API-ключ",
|
||||
"Action": "Действие",
|
||||
@@ -86,7 +86,7 @@
|
||||
"Alert word already exists!": "Сигнальное слово уже существует!",
|
||||
"Alert word can't be empty!": "Сигнальное слово не может быть пустым!",
|
||||
"Alert word removed successfully!": "Сигнальное слово успешно удалено!",
|
||||
"Alert words allow you to be notified as if you were @-mentioned when certain words or phrases are used in Zulip. Alert words are not case sensitive.": "Слова предупреждения позволяют получать уведомления, как если бы вы упоминали @ при использовании определенных слов или фраз в Zulip. Оповещения не чувствительны к регистру.",
|
||||
"Alert words allow you to be notified as if you were @-mentioned when certain words or phrases are used in Zulip. Alert words are not case sensitive.": "Сигнальные слова позволяют получать уведомления, как если бы вас упомянули с помощью @, в случае, если в Zulip используются определенные слова или фразы. Сигнальные слова не чувствительны к регистру.",
|
||||
"All": "Все",
|
||||
"All messages": "Все сообщения",
|
||||
"All messages including muted streams": "Все сообщения, включая заглушенные каналы",
|
||||
@@ -123,7 +123,7 @@
|
||||
"Are you sure you want to delete <b>{group_name}</b>?": "Вы уверены, что хотите удалить <b>{group_name}</b>?",
|
||||
"Are you sure you want to delete your profile picture?": "Вы действительно хотите удалить изображение профиля?",
|
||||
"Are you sure you want to mention all <strong>{count}</strong> people in this stream? <br /> This will send email and mobile push notifications to most of those <strong>{count}</strong> users. <br /> If you don't want to do that, please edit your message to remove the <strong>@{mention}</strong> mention.": "Вы уверены, что хотите упомянуть всех <strong>{count}</strong> человек в этом канале? <br /> Это приведет к отправке почтовых и мобильных уведомлений для большинства из этих <strong>{count}</strong> пользователей. <br /> Если вы не хотите этого, пожалуйста, отредактируйте сообщение и удалите упоминание <strong>@{mention}</strong>.",
|
||||
"Are you sure you want to mute <b>{user_name}</b>? Messages sent by muted users will never trigger notifications, will be marked as read, and will be hidden.": "Вы уверенны, что хотите заглушить<b>{user_name}</b>? Сообщения отправленные заглушенным пользователем никогда не будут вызывать оповещения, будут помечены как прочитанные и будут скрыты.",
|
||||
"Are you sure you want to mute <b>{user_name}</b>? Messages sent by muted users will never trigger notifications, will be marked as read, and will be hidden.": "Вы уверенны, что хотите заглушить<b>{user_name}</b>? Сообщения, отправленные заглушенным пользователем, никогда не будут вызывать оповещения, будут помечены как прочитанные и будут скрыты.",
|
||||
"Are you sure you want to permanently delete <b>{topic_name}</b>?": "Вы уверены, что хотите безвозвратно удалить тему <b>{topic_name}</b>?",
|
||||
"Are you sure you want to resend the invitation to <z-email></z-email>?": "Вы уверены, что хотите повторно отправить приглашение для <z-email></z-email>?",
|
||||
"Are you sure you want to revoke the invitation to <strong>{email}</strong>?": "Вы уверены, что хотите отозвать приглашение для <strong>{email}</strong>?",
|
||||
@@ -164,7 +164,7 @@
|
||||
"Clear emoji image": "Очистить изображение эмодзи",
|
||||
"Clear profile picture": "Очистить картинку профиля",
|
||||
"Click anywhere on a message to reply.": "Кликните в любое место сообщения чтобы ответить.",
|
||||
"Click here to reveal.": "Нажмите здесь чтобы открыть.",
|
||||
"Click here to reveal.": "Нажмите здесь, чтобы открыть.",
|
||||
"Click outside the input box to save. We'll automatically notify anyone that was added or removed.": "Для сохранения нажмите вне поля ввода. Мы автоматически уведомим каждого, кто был добавлен или удален.",
|
||||
"Click to join video call": "Нажмите здесь, чтобы присоединиться к видеозвонку",
|
||||
"Close": "Закрыть",
|
||||
@@ -186,11 +186,11 @@
|
||||
"Copied!": "Скопировано!",
|
||||
"Copy and close": "Скопировать и закрыть",
|
||||
"Copy code": "Скопировать код",
|
||||
"Copy from stream": "Копировать из канала",
|
||||
"Copy from stream": "Скопировать из канала",
|
||||
"Copy link": "Скопировать ссылку",
|
||||
"Copy link to message": "Скопировать ссылку в сообщение",
|
||||
"Copy mention syntax": "Скопировать синтаксис упоминания",
|
||||
"Copy zuliprc": "Копировать zuliprc",
|
||||
"Copy zuliprc": "Скопировать zuliprc",
|
||||
"Create": "Создать",
|
||||
"Create bot": "Создать бот",
|
||||
"Create new stream": "Создать новый канал",
|
||||
@@ -331,7 +331,7 @@
|
||||
"Filter topics (t)": "Фильтровать темы (t)",
|
||||
"Filter uploads": "Фильтр загрузок",
|
||||
"Filter users": "Фильтр пользователей",
|
||||
"First time? Read our <z-link>guidelines</z-link> for creating and naming streams.": "В первый раз? Прочтите наши <z-link>рекомендации</z-link>по созданию и именованию каналов.",
|
||||
"First time? Read our <z-link>guidelines</z-link> for creating and naming streams.": "В первый раз? Прочтите наши <z-link>рекомендации</z-link> по созданию и именованию каналов.",
|
||||
"Fixed width": "Фиксированная ширина",
|
||||
"Fixed width mode": "Модус с фиксированной шириной",
|
||||
"Fluid width": "Изменяющаяся ширина",
|
||||
@@ -500,7 +500,7 @@
|
||||
"No. Only full members and admins can send invitations.": "Нет. Только участники и администраторы могут высылать приглашения.",
|
||||
"No. Only moderators and admins can send invitations.": "Нет. Только модераторы и администраторы могут отправлять приглашения.",
|
||||
"Nobody": "Никто",
|
||||
"None": "Пусто",
|
||||
"None": "Нет",
|
||||
"Note that any bots that you maintain will be disabled.": "Обратите внимание, что все ваши боты будут отключены.",
|
||||
"Note that organizations are limited to five exports per week.": "Пожалуйста, учтите, что организации ограничены пятью выгрузками данных за неделю.",
|
||||
"Nothing to preview": "Ничего нет для предпросмотра",
|
||||
@@ -809,7 +809,7 @@
|
||||
"Visual desktop notifications": "Визуальные оповещения на рабочем столе",
|
||||
"Waiting period (days)": "Период ожидания (дни)",
|
||||
"Waiting period before new members turn into full members": "Период ожидания, пока из новых членов становятся полноценные члены",
|
||||
"Warning: <strong>{stream_name}</strong> is a private stream.": "Предупреждение: канал<strong>{stream_name}</strong>является закрытым.",
|
||||
"Warning: <strong>{stream_name}</strong> is a private stream.": "Предупреждение: канал <strong>{stream_name}</strong> является закрытым.",
|
||||
"We are about to have a poll. Please wait for the question.": "У нас будет голосование. Пожалуйста, подождите, пока появится вопрос.",
|
||||
"We've replaced the \"{originalHotkey}\" hotkey with \"{replacementHotkey}\" to make this common shortcut easier to trigger.": "Мы заменили горячие клавиши \"{originalHotkey}\" на \"{replacementHotkey}\" чтобы упростить использование этого сокращения.",
|
||||
"Wednesday": "Среда",
|
||||
|
||||
5372
locale/si/LC_MESSAGES/django.po
Normal file
5372
locale/si/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
907
locale/si/translations.json
Normal file
907
locale/si/translations.json
Normal file
@@ -0,0 +1,907 @@
|
||||
{
|
||||
"(This user has been deactivated)": "",
|
||||
"(forever)": "(සදහටම)",
|
||||
"(no description)": "(සවිස්තරයක් නැත)",
|
||||
"(no topic)": "(මාතෘකාවක් නැත)",
|
||||
"(unavailable)": "",
|
||||
"(you)": "(ඔබ)",
|
||||
"({message_retention_days} days)": "(දවස් {message_retention_days})",
|
||||
"/dark (Toggle night mode)": "",
|
||||
"/day (Toggle day mode)": "",
|
||||
"/fixed-width (Toggle fixed width mode)": "",
|
||||
"/fluid-width (Toggle fluid width mode)": "",
|
||||
"/light (Toggle day mode)": "",
|
||||
"/me is excited (Display action text)": "",
|
||||
"/night (Toggle night mode)": "",
|
||||
"/poll Where should we go to lunch today? (Create a poll)": "",
|
||||
"/settings (Load settings menu)": "",
|
||||
"/todo (Create a todo list)": "",
|
||||
"1 day": "දවස් 1",
|
||||
"1 hour": "පැය 1",
|
||||
"1 week": "සති 1",
|
||||
"10 minutes": "විනාඩි 10",
|
||||
"12-hour clock (5:00 PM)": "පැය 12 ඔරලෝසුව (ප.ව. 5:00)",
|
||||
"2 minutes": "විනාඩි 2",
|
||||
"24-hour clock (17:00)": "පැය 24 ඔරලෝසුව (17:00)",
|
||||
"3 days": "දවස් 3",
|
||||
"<b>Total messages</b>: {total_messages}": "<b>මුළු පණිවිඩ</b>: {total_messages}",
|
||||
"<p>Stream will be announced in <b>#{notifications_stream}</b>.</p>": "",
|
||||
"<p>The stream <b>{stream_name}</b> does not exist.</p><p>Manage your subscriptions <z-link>on your Streams page</z-link>.</p>": "",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified if you mention them.": "",
|
||||
"<strong>{name}</strong> is not subscribed to this stream. They will not be notified unless you subscribe them.": "",
|
||||
"<z-link>Click here</z-link> to learn about exporting private streams and messages.": "",
|
||||
"<z-link>Upgrade</z-link> for more space.": "",
|
||||
"A Topic Move already in progress.": "මාතෘකාවක් ගෙන යාම දැනටමත් කෙරෙමින් පවතී.",
|
||||
"A language is marked as 100% translated only if every string in the web, desktop, and mobile apps is translated, including administrative UI and error messages.": "",
|
||||
"A stream needs to have a name": "",
|
||||
"A stream with this name already exists": "",
|
||||
"A unicode emoji with name <b>{emoji_name}</b> already exists. Uploading a custom emoji with this name will override the unicode emoji with this name.": "",
|
||||
"A wide image for the upper left corner of the app.": "",
|
||||
"API key": "යෙ.ක්ර.මු. යතුර",
|
||||
"Action": "ක්රියාමාර්ගය",
|
||||
"Actions": "ක්රියාමාර්ග",
|
||||
"Active": "ක්රියාත්මකයි",
|
||||
"Active bots": "ක්රියාත්මක ස්වයංක්රමලේඛ",
|
||||
"Active now": "දැන් ක්රියාත්මකයි",
|
||||
"Active users": "",
|
||||
"Add": "එකතු",
|
||||
"Add GIF": "චලනරූ එකතු කරන්න",
|
||||
"Add a new alert word": "නව අනතුරු ඇඟවීමේ වචනයක් එක්කරන්න",
|
||||
"Add a new bot": "නව ස්වයංක්රමලේඛයක් එක්කරන්න",
|
||||
"Add a new code playground": "නව කේත ක්රීඩාපිටියක් එක් කරන්න",
|
||||
"Add a new emoji": "නව ඉමොජි එකතු කරන්න",
|
||||
"Add a new linkifier": "",
|
||||
"Add a new profile field": "නව පැතිකඩ ක්ෂේත්රයක් එක්කරන්න",
|
||||
"Add a new user group": "නව පරිශීලක සමූහයක් එක්කරන්න",
|
||||
"Add alert word": "අනතුරු ඇඟවීමේ වචනය එක්කරන්න",
|
||||
"Add another user...": "වෙනත් පරිශීලකයෙකු එක්කරන්න...",
|
||||
"Add choice": "",
|
||||
"Add code playground": "කේත ක්රීඩා පිටිය එක්කරන්න",
|
||||
"Add emoji": "ඉමොජි එකතු කරන්න",
|
||||
"Add emoji reaction": "",
|
||||
"Add extra emoji for members of the {realm_name} organization.": "{realm_name} සංවිධානයේ සාමාජිකයින් සඳහා අතිරේක ඉමොජි එක්කරන්න.",
|
||||
"Add linkifier": "",
|
||||
"Add member\u2026": "සාමාජිකයා එක්කරන්න...",
|
||||
"Add new default stream": "",
|
||||
"Add one or more users": "පරිශීලකයෙකු හෝ වැඩි ගණනක් එක්කරන්න",
|
||||
"Add profile field": "පැතිකඩ ක්ෂේත්රය එක්කරන්න",
|
||||
"Add question": "ප්රශ්නය එකතු කරන්න",
|
||||
"Add stream": "",
|
||||
"Add subscribers. Use #streamname to add all subscribers from that stream.": "",
|
||||
"Add task": "කාර්යය එකතු කරන්න",
|
||||
"Add video call": "දෘශ්ය ඇමතුම එක්කරන්න",
|
||||
"Added successfully!": "සාර්ථකව එකතු කරන ලදි!",
|
||||
"Administrator": "පරිපාලකයින්",
|
||||
"Administrators can always delete any message.": "",
|
||||
"Admins": "පරිපාලකයින්",
|
||||
"Admins and full members": "පරිපාලකයින් සහ පූර්ණ සාමාජිකයින්",
|
||||
"Admins and members": "පරිපාලකයින් සහ සාමාජිකයින්",
|
||||
"Admins and members, but only admins can add generic bots": "",
|
||||
"Admins and moderators": "",
|
||||
"Admins only": "පරිපාලකයින් පමණි",
|
||||
"Admins, members and guests": "පරිපාලකයින්, සාමාජිකයින් සහ අමුත්තන්",
|
||||
"Admins, members, and guests": "පරිපාලකයින්, සාමාජිකයින් සහ අමුත්තන්",
|
||||
"Alert word": "අනතුරු ඇඟවීමේ වචනය",
|
||||
"Alert word \"{word}\" added successfully!": "අනතුරු ඇඟවීමේ වචනය \"{word}\" සාර්ථකව එකතු කෙරිණි!",
|
||||
"Alert word already exists!": "අනතුරු ඇඟවීමේ වචනය දැනටමත් පවතී!",
|
||||
"Alert word can't be empty!": "අනතුරු ඇඟවීමේ වචනය හිස් විය නොහැකිය!",
|
||||
"Alert word removed successfully!": "අනතුරු ඇඟවීමේ වචනය සාර්ථකව ඉවත් කෙරිණි!",
|
||||
"Alert words allow you to be notified as if you were @-mentioned when certain words or phrases are used in Zulip. Alert words are not case sensitive.": "",
|
||||
"All": "සියළුම",
|
||||
"All messages": "සියළුම පණිවිඩ",
|
||||
"All messages including muted streams": "",
|
||||
"All stream members can post": "",
|
||||
"All stream members can post.": "",
|
||||
"All streams": "",
|
||||
"All time": "සෑම වෙලාවෙම",
|
||||
"All unreads": "නොකියවූ සියල්ල",
|
||||
"Allow message content in message notification emails": "පණිවිඩ දැනුම්දීම් වි-තැපැල් හි පණිවිඩ අන්තර්ගතයට ඉඩදෙන්න",
|
||||
"Allow message deleting": "",
|
||||
"Allow message editing": "පණිවිඩ සංස්කරණයට ඉඩ දෙන්න",
|
||||
"Allow subdomains": "උප වසම් වලට ඉඩ දෙන්න",
|
||||
"Allowed domains": "ඉඩ දුන් වසම්",
|
||||
"Allowed domains: {domains}": "ඉඩ දුන් වසම්: {domains}",
|
||||
"Already subscribed to {stream}": "",
|
||||
"Already subscribed users:": "",
|
||||
"Always": "සැමවිටම",
|
||||
"An API key can be used to programmatically access a Zulip account. Anyone with access to your API key has the ability to read your messages, send messages on your behalf, and otherwise impersonate you on Zulip, so you should guard your API key as carefully as you guard your password. <br /> We recommend creating bots and using the bots' accounts and API keys to access the Zulip API, unless the task requires access to your account.": "සුලිප් ගිණුමකට ක්රමලේඛිතව ප්රවේශ වීම සඳහා යෙ.ක්ර.මු. යතුර භාවිතා කළ හැකිය. ඔබගේ යෙ.ක්ර.මු. යතුරට ප්රවේශ වන ඕනෑම අයෙකුට ඔබගේ පණිවිඩ කියවීමට, ඔබ වෙනුවට පණිවිඩ යැවීමට සහ වෙනත් අයුරකින් ඔබ ලෙස සුලිප් හි පෙනී සිටීමට හැකියාව ඇත, එබැවින් ඔබ යෙ.ක්ර.මු. යතුර මුරපදය ආරක්ෂා කරන තරමටම ප්රවේශම් කර ගත යුතුය. <br /> කාර්යයට ඔබගේ ගිණුමට ප්රවේශය අවශ්ය නොවන්නේ නම්, ස්වයංක්රමලේඛ සෑදීම සහ ස්වයංක්රමලේඛ ගිණුම් භාවිතය සහ සුලිප් යෙ.ක්ර.මු. වෙත ප්රවේශයට යෙ.ක්ර.මු. යතුරු ද අපි නිර්දේශ කරමු.",
|
||||
"An hour ago": "පැයකට කලින්",
|
||||
"An unknown error occurred.": "නොදන්නා දෝෂයක් සිදු විය.",
|
||||
"Announce stream": "",
|
||||
"Any member of this organization can add custom emoji.": "මෙම සංවිධානයේ ඕනෑම සාමාජිකයෙකුට අභිරුචි ඉමොජි එකතු කළ හැකිය.",
|
||||
"Any organization administrator can conduct an export.": "ඕනෑම සංවිධානයේ පරිපාලකයෙකුට නිර්යාතයක් කළ හැකිය.",
|
||||
"Any time": "ඕනෑම වෙලාවක",
|
||||
"Anyone can join; anyone can view complete message history without joining": "",
|
||||
"Anyone in this organization can add bots": "මෙම සංවිධානයේ ඕනෑම අයෙකුට ස්වයංක්රමලේඛ එකතු කළ හැකිය",
|
||||
"April": "බක්",
|
||||
"Archive stream": "",
|
||||
"Are invitations required for joining the organization?": "සංවිධානයට එක්වීමට ඇරයුම් කළ යුතුද?",
|
||||
"Are you sure you want to archive this stream?": "",
|
||||
"Are you sure you want to create stream ''''{stream_name}'''' and subscribe {count} users to it?": "",
|
||||
"Are you sure you want to deactivate this organization?": "",
|
||||
"Are you sure you want to deactivate your account?": "",
|
||||
"Are you sure you want to delete <b>{group_name}</b>?": "",
|
||||
"Are you sure you want to delete your profile picture?": "",
|
||||
"Are you sure you want to mention all <strong>{count}</strong> people in this stream? <br /> This will send email and mobile push notifications to most of those <strong>{count}</strong> users. <br /> If you don't want to do that, please edit your message to remove the <strong>@{mention}</strong> mention.": "",
|
||||
"Are you sure you want to mute <b>{user_name}</b>? Messages sent by muted users will never trigger notifications, will be marked as read, and will be hidden.": "ඔබට <b>{user_name}</b> නිහඬ කිරීමට අවශ්ය බව විශ්වාසයි ද? නිහඬ කළ පරිශීලකයින් විසින් යවන ලද පණිවිඩ වලට දැනුම්දීම් සිදු නොවේ, කියවූ ලෙස සලකුණු වී සැඟවෙනු ඇත.",
|
||||
"Are you sure you want to permanently delete <b>{topic_name}</b>?": "",
|
||||
"Are you sure you want to resend the invitation to <z-email></z-email>?": "ඇරයුම <z-email></z-email> වෙත නැවත යැවීමට අවශ්ය බව ඔබට විශ්වාසද?",
|
||||
"Are you sure you want to revoke the invitation to <strong>{email}</strong>?": "",
|
||||
"Are you sure you want to revoke this invitation link created by <strong>{referred_by}</strong>?": "",
|
||||
"Are you sure you want to unstar all messages in <stream-topic></stream-topic>? This action cannot be undone.": "",
|
||||
"Are you sure you want to unstar all starred messages? This action cannot be undone.": "",
|
||||
"Attachment deleted": "",
|
||||
"Audible desktop notifications": "",
|
||||
"Audio": "ශ්රව්ය",
|
||||
"August": "නිකිණි",
|
||||
"Authentication methods": "",
|
||||
"Author": "කර්තෘ",
|
||||
"Automatic": "ස්වයංක්රීය",
|
||||
"Avatar from Gravatar": "",
|
||||
"Bot": "ස්වයංක්රමලේඛ",
|
||||
"Bot email": "ස්වයංක්රමලේඛයේ වි-තැපෑල",
|
||||
"Bot email (a-z, 0-9, and dashes only)": "ස්වයංක්රමලේඛ වි-තැපෑල (අ-ෆ, 0-9, සහ ඉරි පමණි)",
|
||||
"Bot type": "ස්වයංක්රමලේඛ වර්ගය",
|
||||
"Bots": "ස්වයංක්රමලේඛ",
|
||||
"By deactivating <z-user></z-user>, they will be logged out immediately.": "",
|
||||
"By deactivating your account, you will be logged out immediately.": "",
|
||||
"Cancel": "අවලංගු",
|
||||
"Cancel compose": "",
|
||||
"Change": "වෙනස් කරන්න",
|
||||
"Change bot info and owner": "ස්වයංක්රමලේඛයේ තොරතුරු හා හිමිකරු වෙනස්කරන්න",
|
||||
"Change color": "වර්ණය වෙනස් කරන්න",
|
||||
"Change email": "වි-තැපෑල වෙනස් කරන්න",
|
||||
"Change full name": "සම්පූර්ණ නම වෙනස් කරන්න",
|
||||
"Change later messages to this topic": "මෙම මාතෘකාවට පසු පණිවිඩ වෙනස් කරන්න",
|
||||
"Change only this message topic": "මෙම පණිවිඩයේ මාතෘකාව පමණක් වෙනස් කරන්න",
|
||||
"Change password": "මුරපදය වෙනස් කරන්න",
|
||||
"Change previous and following messages to this topic": "මෙම මාතෘකාවට පෙර සහ පහත සඳහන් පණිවිඩ වෙනස් කරන්න",
|
||||
"Change stream permissions for #": "",
|
||||
"Change user info and roles": "පරිශීලක තොරතුරු සහ භූමිකාවන් වෙනස් කරන්න",
|
||||
"Check all": "සියල්ල පරීක්ෂා කරන්න",
|
||||
"Check your email ({email}) to confirm the new address.": "",
|
||||
"Choose avatar": "",
|
||||
"Clear emoji image": "",
|
||||
"Clear profile picture": "",
|
||||
"Click anywhere on a message to reply.": "පිළිතුරු දීමට පණිවිඩයක් මත ඕනෑම තැනක ඔබන්න.",
|
||||
"Click here to reveal.": "හෙළි කිරීමට මෙතැන ඔබන්න.",
|
||||
"Click outside the input box to save. We'll automatically notify anyone that was added or removed.": "",
|
||||
"Click to join video call": "දෘශ්ය ඇමතුමට එක්වීමට ඔබන්න",
|
||||
"Close": "වසන්න",
|
||||
"Collapse": "",
|
||||
"Color scheme": "",
|
||||
"Complete": "සම්පූර්ණයි",
|
||||
"Compose message": "",
|
||||
"Compose your message here": "",
|
||||
"Compose your message here...": "",
|
||||
"Condense message (-)": "",
|
||||
"Configure external code playgrounds for your Zulip organization. Code playgrounds are interactive in-browser development environments, such as <z-link-repl>replit</z-link-repl>, that are designed to make it convenient to edit and debug code. Zulip code blocks that are <z-link-markdown-help>tagged with a programming language</z-link-markdown-help> will have a button visible on hover that allows you to open the code block in the code playground site.": "",
|
||||
"Configure how Zulip notifies you about new messages.": "නව පණිවිඩ ගැන සුලිප් ඔබට දැනුම් දෙන අයුරු සකසන්න.",
|
||||
"Configure regular expression patterns that will be automatically linkified when used in Zulip message bodies or topics. For example to automatically linkify commit IDs and issue numbers (e.g. #123) to the corresponding items in a GitHub project, you could use the following:": "",
|
||||
"Configure the authentication methods for your organization.": "",
|
||||
"Configure the default streams new users are subscribed to when joining your organization.": "",
|
||||
"Confirm": "",
|
||||
"Convert emoticons before sending (<code>:)</code> becomes \ud83d\ude03)": "",
|
||||
"Cookie Bot": "",
|
||||
"Copied!": "පිටපත් විය!",
|
||||
"Copy and close": "පිටපත් කර වසන්න",
|
||||
"Copy code": "කේතය පිටපත් කරන්න",
|
||||
"Copy from stream": "",
|
||||
"Copy link": "සබැඳිය පිටපත් කරන්න",
|
||||
"Copy link to message": "පණිවිඩයට සබැඳිය පිටපත් කරන්න",
|
||||
"Copy mention syntax": "",
|
||||
"Copy zuliprc": "zuliprc පිටපත් කරන්න",
|
||||
"Create": "සාදන්න",
|
||||
"Create bot": "ස්වයංක්රමලේඛය සාදන්න",
|
||||
"Create new stream": "",
|
||||
"Create stream": "",
|
||||
"Creating bot": "ස්වයංක්රමලේඛ සෑදීම",
|
||||
"Creating stream...": "",
|
||||
"Current password": "වත්මන් මුරපදය",
|
||||
"Custom": "අභිරුචි",
|
||||
"Custom emoji added!": "අභිරුචි ඉමොජි එකතු කෙරිණි!",
|
||||
"Custom language: {query}": "අභිරුචි භාෂාව: {query}",
|
||||
"Custom linkifier added!": "",
|
||||
"Custom playground added!": "අභිරුචි ක්රීඩා පිටිය එකතු කෙරිණි!",
|
||||
"Custom profile fields": "අභිරුචි පැතිකඩ ක්ෂේත්ර",
|
||||
"Customize profile picture": "",
|
||||
"Data exports": "දත්ත නිර්යාත",
|
||||
"Date muted": "නිහඬ කළ දිනය ",
|
||||
"Date uploaded": "උඩුගත කළ දිනය",
|
||||
"Day": "දවස",
|
||||
"Day logo": "දවසේ ලාංඡනය",
|
||||
"Day mode": "",
|
||||
"Day of the week to send digests": "",
|
||||
"Deactivate": "",
|
||||
"Deactivate account": "",
|
||||
"Deactivate organization": "",
|
||||
"Deactivate your account": "",
|
||||
"Deactivated": "",
|
||||
"Deactivated users": "",
|
||||
"December": "උඳුවප්",
|
||||
"Default is {language}. Use 'text' to disable highlighting.": "",
|
||||
"Default language": "පෙරනිමි භාෂාව",
|
||||
"Default language for code blocks:": "",
|
||||
"Default settings for new users joining this organization.": "මෙම සංවිධානයට එක්වන නව පරිශීලකයින් සඳහා පෙරනිමි සැකසුම්.",
|
||||
"Default user settings": "පෙරනිමි පරිශීලක සැකසුම්",
|
||||
"Default view": "",
|
||||
"Delete": "",
|
||||
"Delete alert word": "",
|
||||
"Delete bot": "",
|
||||
"Delete draft": "",
|
||||
"Delete file": "",
|
||||
"Delete icon": "",
|
||||
"Delete logo": "",
|
||||
"Delete message": "",
|
||||
"Delete profile picture": "",
|
||||
"Delete topic": "",
|
||||
"Delete user group": "",
|
||||
"Deleted": "",
|
||||
"Deleted successfully!": "",
|
||||
"Deleting a topic will immediately remove it and its messages for everyone. Other users may find this confusing, especially if they had received an email or push notification related to the deleted messages.": "",
|
||||
"Demote inactive streams": "",
|
||||
"Dense mode": "",
|
||||
"Depending on the size of your organization, an export can take anywhere from seconds to an hour.": "ඔබේ සංවිධානයේ ප්රමාණය අනුව නිර්යාතයට තත්පරයක සිට පැයක් දක්වා කාලයක් ගත විය හැකිය.",
|
||||
"Description": "සවිස්තරය",
|
||||
"Desktop": "",
|
||||
"Detailed message formatting documentation": "",
|
||||
"Disabled": "අබල කර ඇත",
|
||||
"Discard": "",
|
||||
"Display my availability to other users when online": "",
|
||||
"Display settings": "",
|
||||
"Do you want to proceed?": "ඔබට ඉදිරියට යාමට අවශ්යද?",
|
||||
"Domain": "වසම",
|
||||
"Don\u2019t allow disposable email addresses": "",
|
||||
"Download .zuliprc": ".zuliprc බාගන්න",
|
||||
"Download botserverrc": "බොට්සර්වර්ක් බාගන්න",
|
||||
"Download config of all active outgoing webhook bots in Zulip Botserver format.": "",
|
||||
"Download file": "ගොනුව බාගන්න",
|
||||
"Download zuliprc": "zuliprc බාගන්න",
|
||||
"Drafts": "",
|
||||
"Drafts ({draft_count})": "",
|
||||
"Drafts older than <strong>{draft_lifetime}</strong> days are automatically removed.": "",
|
||||
"EDITED": "සංස්කරණය කර ඇත",
|
||||
"Edit": "සංස්කරණය",
|
||||
"Edit bot": "ස්වයංක්රමලේඛය සංස්කරණය",
|
||||
"Edit linkifiers": "",
|
||||
"Edit status message": "තත්ව පණිවිඩය සංස්කරණය",
|
||||
"Edit topic": "මාතෘකාව සංස්කරණය",
|
||||
"Edit user": "පරිශීලක සංස්කරණය",
|
||||
"Edit your profile": "ඔබගේ පැතිකඩ සංස්කරණය කරන්න",
|
||||
"Edited ({last_edit_timestr})": "({last_edit_timestr}) සංස්කරණය කෙරිණි",
|
||||
"Email": "වි-තැපෑල",
|
||||
"Email address": "වි-තැපැල් ලිපිනය",
|
||||
"Email address changes are disabled in this organization.": "මෙම සංවිධානය තුළ වි-තැපැල් ලිපිනය වෙනස් කිරීම් අබල කර ඇත.",
|
||||
"Email copied": "වි-තැපෑල පිටපත් විය",
|
||||
"Email notifications": "වි-තැපැල් දැනුම්දීම්",
|
||||
"Emoji name": "ඉමොජි නම",
|
||||
"Emoji settings": "ඉමොජි සැකසුම්",
|
||||
"Emojiset changed successfully!": "ඉමොජි කට්ටලය සාර්ථකව වෙනස් කෙරිණි!",
|
||||
"Enable message edit history": "පණිවිඩ සංස්කරණ ඉතිහාසය සබල කරන්න",
|
||||
"Enabled": "සබල කර ඇත",
|
||||
"Endpoint URL": "",
|
||||
"Error": "දෝෂයකි",
|
||||
"Error adding alert word!": "අනතුරු ඇඟවීමේ වචනය එකතු කිරීමේ දෝෂයකි!",
|
||||
"Error adding subscription": "",
|
||||
"Error checking subscription": "",
|
||||
"Error creating stream": "",
|
||||
"Error deleting message": "",
|
||||
"Error fetching message edit history": "පණිවිඩ සංස්කරණ ඉතිහාසය ගැනීමේ දෝෂයකි",
|
||||
"Error listing invites": "",
|
||||
"Error moving the topic": "මාතෘකාව ගෙන යාමේ දෝෂයකි",
|
||||
"Error removing alert word!": "අනතුරු ඇඟවීමේ වචනය ඉවත් කිරීමේ දෝෂයකි!",
|
||||
"Error removing subscription": "",
|
||||
"Error removing user from this stream.": "",
|
||||
"Error saving edit": "සංස්කරණය සුරැකීමේ දෝෂයකි",
|
||||
"Error: Cannot deactivate the only organization owner.": "",
|
||||
"Error: Cannot deactivate the only user. You can deactivate the whole organization though in your <z-link>organization profile settings</z-link>.": "",
|
||||
"Estimated messages per week": "සතියකට තක්සේරුගත පණිවිඩ",
|
||||
"Everyone": "සෑම දෙනාම",
|
||||
"Expand message (-)": "පණිවිඩය පුළුල් කරන්න (-)",
|
||||
"Export failed": "නිර්යාතයට අසමත් විය",
|
||||
"Export started. Check back in a few minutes.": "නිර්යාතය ඇරඹිණි. විනාඩි කිහිපයකින් ආපසු පරීක්ෂා කරන්න.",
|
||||
"Exports all users, settings, and all data visible in public streams.": "",
|
||||
"External account type": "බාහිර ගිණුම් වර්ගය",
|
||||
"External link": "බාහිර සබැඳිය",
|
||||
"Failed": "අසමත් විය",
|
||||
"Failed to create video call.": "දෘශ්ය ඇමතුමක් සෑදීමට අසමත් විය.",
|
||||
"Failed to generate preview": "පෙරදසුන ජනනය කිරීමට අසමත් විය",
|
||||
"Failed to upload %'{file}'": "%'{file}' උඩුගත කිරීමට අසමත් විය",
|
||||
"Failed!": "අසමත්!",
|
||||
"Failed: Emoji name is required.": "අසමත් විය: ඉමොජි නම අවශ්යයි.",
|
||||
"February": "නවම්",
|
||||
"Field choices": "",
|
||||
"File": "ගොනුව",
|
||||
"File and image uploads have been disabled for this organization.": "මෙම සංවිධානය සඳහා ගොනු සහ රූප උඩුගත කිරීම් අබල කර ඇත.",
|
||||
"File size must be at most {max_file_size} MiB.": "ගොනුවේ ප්රමාණය බොහෝ විට මෙ.බ. {max_file_size} විය යුතුය.",
|
||||
"File type is not supported.": "ගොනු වර්ගයට සහාය නොදක්වයි.",
|
||||
"Filter": "පෙරහන",
|
||||
"Filter bots": "ස්වයංක්රමලේඛ පෙරන්න",
|
||||
"Filter by category": "ප්රවර්ගය අනුව පෙරන්න",
|
||||
"Filter code playgrounds": "කේත ක්රීඩා පිටි පෙරන්න",
|
||||
"Filter deactivated users": "",
|
||||
"Filter emojis": "ඉමොජි පෙරන්න",
|
||||
"Filter exports": "නිර්යාත පෙරන්න",
|
||||
"Filter invites": "ඇරයුම් පෙරන්න",
|
||||
"Filter languages": "භාෂා පෙරන්න",
|
||||
"Filter linkifiers": "",
|
||||
"Filter muted topics": "නිහඬ කළ මාතෘකා පෙරන්න",
|
||||
"Filter muted users": "නිහඬ කළ පරිශීලකයින් පෙරන්න",
|
||||
"Filter streams": "",
|
||||
"Filter topics (t)": "",
|
||||
"Filter uploads": "උඩුගත කිරීම් පෙරන්න",
|
||||
"Filter users": "පරිශීලකයින් පෙරන්න",
|
||||
"First time? Read our <z-link>guidelines</z-link> for creating and naming streams.": "",
|
||||
"Fixed width": "",
|
||||
"Fixed width mode": "",
|
||||
"Fluid width": "",
|
||||
"Fluid width mode": "",
|
||||
"For example, to configure code playgrounds for languages like Python or JavaScript, you could specify the <i>Language</i> and <i>URL prefix</i> fields as:": "උදාහරණයක් ලෙස, පයිතන් හෝ ජාවාස්ක්රිප්ට් වැනි භාෂා සඳහා කේත ක්රීඩාපිටි වින්යාසගත කිරීමට <i>භාෂාව</i> සහ <i>ඒ.ස.නි. උපසර්ගය</i> යන ක්ෂේත්රයන් මෙසේ දැක්විය හැකිය:",
|
||||
"Forgotten it?": "එය අමතක වෙලාද?",
|
||||
"Friday": "සිකුරාදා",
|
||||
"Full name": "සම්පූර්ණ නම",
|
||||
"GIPHY attribution": "",
|
||||
"GIPHY integration": "",
|
||||
"Generate invite link": "ඇරයුම් සබැඳියක් ජනනය කරන්න",
|
||||
"Generate new API key": "නව යෙ.ක්ර.මු. යතුරක් ජනනය කරන්න",
|
||||
"Generating link...": "සබැඳිය ජනනය වෙමින්...",
|
||||
"Generic": "",
|
||||
"Get API key": "යෙ.ක්ර.මු. යතුර ගන්න",
|
||||
"Go back": "ආපසු යන්න",
|
||||
"Got it!": "",
|
||||
"Guest": "අමුත්තා",
|
||||
"Guests are not allowed to post to this stream.": "",
|
||||
"Guests cannot edit custom emoji.": "අමුත්තන්ට අභිරුචි ඉමොජි සංස්කරණය කළ නොහැකිය.",
|
||||
"Help": "උදව්",
|
||||
"Hide password": "මුරපදය සඟවන්න",
|
||||
"Hide starred message count": "",
|
||||
"High contrast mode": "",
|
||||
"Hint": "ඉඟිය",
|
||||
"Hint (up to 80 characters)": "ඉඟිය (අකුරු 80 දක්වා)",
|
||||
"Humans": "මනුෂ්යයින්",
|
||||
"Idle": "",
|
||||
"Image": "",
|
||||
"Inactive bots": "",
|
||||
"Include content of private messages in desktop notifications": "",
|
||||
"Include message content in message notification emails": "පණිවිඩ දැනුම්දීම් වි-තැපැල් හි පණිවිඩ අන්තර්ගතය ඇතුළත් කරන්න",
|
||||
"Include muted": "නිහඬ කිරීම් ඇතුළත්ව",
|
||||
"Include organization name in subject of message notification emails": "පණිවිඩ දැනුම් දීමේ වි-තැපැල් වලට සංවිධානයේ නම ඇතුළත් කරන්න",
|
||||
"Incoming webhooks can only send messages.": "",
|
||||
"Interface": "අතුරුමුහුණත",
|
||||
"Invalid URL": "වලංගු නොවන ඒ.ස.නි.",
|
||||
"Invalid slash command. Check if you are missing a space after the command.": "",
|
||||
"Invalid stream id": "",
|
||||
"Invalid time format: {timestamp}": "",
|
||||
"Invite": "ආරාධනා කරන්න",
|
||||
"Invite link": "ඇරයුම් සබැඳිය",
|
||||
"Invite more users": "තවත් පරිශීලකයින්ට ආරාධනා කරන්න",
|
||||
"Invited as": "ලෙස ආරාධනා කර ඇත",
|
||||
"Invited at": "ට ආරාධනා කරන ලදි",
|
||||
"Invited by": "විසින් ආරාධනා කරන ලදි",
|
||||
"Invitee": "ආරාධිතයා",
|
||||
"Invites": "ඇරයුම්",
|
||||
"Inviting...": "ආරාධනා කරමින්...",
|
||||
"January": "දුරුතු",
|
||||
"Joined": "එක් විණි",
|
||||
"Joining the organization": "සංවිධානයට එක් වෙමින්",
|
||||
"July": "ඇසළ",
|
||||
"June": "පොසොන්",
|
||||
"Just now": "මේ දැන්",
|
||||
"Keyboard shortcuts": "යතුරුපුවරුවේ කෙටිමං",
|
||||
"Label": "",
|
||||
"Language": "භාෂාව",
|
||||
"Language settings": "භාෂා සැකසුම්",
|
||||
"Large number of subscribers": "",
|
||||
"Last 10 days": "පසුගිය දවස් 10",
|
||||
"Last 2 months": "පසුගිය මාස 2",
|
||||
"Last 30 days": "පසුගිය දවස් 30",
|
||||
"Last 6 months": "පසුගිය මාස 6",
|
||||
"Last active": "",
|
||||
"Last active: {last_seen}": "",
|
||||
"Last modified": "",
|
||||
"Link:": "සබැඳිය:",
|
||||
"Local time": "දේශීය වේලාව",
|
||||
"Looking for our <z-integrations>integrations</z-integrations> or <z-api>API</z-api> documentation?": "<z-integrations>අනුකලන</z-integrations> හෝ<z-api>යෙ.ක්ර.මු.</z-api> ප්රලේඛන බලන්නේද?",
|
||||
"Manage organization": "සංවිධානය කළමනාකරණය",
|
||||
"Manage user groups": "පරිශීලක සමූහ කළමනාකරණය",
|
||||
"March": "මැදින්",
|
||||
"Mark all messages as read": "සියළු පණිවිඩ කියවූ ලෙස සලකුණු කරන්න",
|
||||
"Mark as read": "කියවූ ලෙස සලකුණු කරන්න",
|
||||
"Marketing team": "අලෙවිකරණ කණ්ඩායම",
|
||||
"May": "වෙසක්",
|
||||
"Me": "මා",
|
||||
"Member": "සාමාජිකයා",
|
||||
"Members can only view or manage invitations that you yourself sent.": "",
|
||||
"Mention a timezone-aware time": "",
|
||||
"Mentioned in": "හි සඳහන් කර ඇත",
|
||||
"Mentions": "සැඳහුම්",
|
||||
"Message #{stream_name}": "",
|
||||
"Message #{stream_name} > {topic_name}": "",
|
||||
"Message actions": "පණිවිඩ ක්රියාමාර්ග",
|
||||
"Message editing": "පණිවිඩය සංස්කරණය",
|
||||
"Message formatting": "",
|
||||
"Message retention": "පණිවිඩ රඳවා ගැනීම",
|
||||
"Message retention for stream": "",
|
||||
"Message retention period": "පණිවිඩ රඳවා ගැනීමේ කාලය",
|
||||
"Message sent when you were not subscribed": "",
|
||||
"Message {recipient_label}": "{recipient_label} පණිවිඩය ",
|
||||
"Message {recipient_names}": "{recipient_names} පණිවිඩය",
|
||||
"Message {recipient_name} ({recipient_status})": "පණිවිඩය {recipient_name} ({recipient_status})",
|
||||
"Messages in this stream will be automatically deleted after {retention_days} days.": "",
|
||||
"Messages in this stream will be retained forever.": "",
|
||||
"Method": "ක්රමය",
|
||||
"Mobile": "ජංගම",
|
||||
"Mobile notifications": "ජංගම දැනුම්දීම්",
|
||||
"Mobile push notifications are not configured on this server.": "",
|
||||
"Moderator": "",
|
||||
"Monday": "සඳුදා",
|
||||
"More details are available <z-link>in the Help Center article</z-link>.": "වැඩි විස්තර <z-link>උපකාරක මධ්යස්ථානයේ ලිපියේ</z-link> තිබේ",
|
||||
"More than 2 weeks ago": "සති 2 කටත් පෙර",
|
||||
"Move all messages in <strong>{topic_name}</strong>": "සියළුම පණිවිඩ <strong>{topic_name}</strong> තුළට ගෙන යන්න",
|
||||
"Move topic": "මාතෘකාව ගෙන යන්න",
|
||||
"Must be invited by a member; new members can only see messages sent after they join; hidden from non-administrator users": "",
|
||||
"Must be invited by a member; new members can view complete message history; hidden from non-administrator users": "",
|
||||
"Mute stream": "",
|
||||
"Mute the topic <b>{topic}</b>": "<b>{topic}</b> මාතෘකාව නිහඬකරන්න",
|
||||
"Mute this user": "මෙම පරිශීලකයා නිහඬකරන්න",
|
||||
"Mute topic": "මාතෘකාව නිහඬකරන්න",
|
||||
"Mute user": "පරිශීලකයා නිහඬකරන්න",
|
||||
"Muted streams don't show up in \"All messages\" or generate notifications unless you are mentioned.": "",
|
||||
"Muted user": "නිහඬ කළ පරිශීලකයෙකි",
|
||||
"N": "",
|
||||
"Name": "නම",
|
||||
"Name changes are disabled in this organization. Contact an administrator to change your name.": "",
|
||||
"Narrow to stream "{display_recipient}"": "",
|
||||
"Narrow to stream "{display_recipient}", topic "{topic}"": "",
|
||||
"Narrow to your private messages with {display_reply_to}": "",
|
||||
"Narrow to {message_recipient}": "",
|
||||
"Never": "",
|
||||
"Never had one? Forgotten it?": "",
|
||||
"New": "නව",
|
||||
"New alert word": "නව අනතුරු ඇඟවීමේ වචනය",
|
||||
"New choice": "",
|
||||
"New email": "නව වි-තැපෑල",
|
||||
"New full name": "නව සම්පූර්ණ නම",
|
||||
"New members are not allowed to post to this stream.<br />Permission will be granted in {days} days.": "",
|
||||
"New members can only see messages sent after they join.": "නව සාමාජිකයින්ට ඔවුන් සම්බන්ධ වූ පසු පමණක් යැවූ පණිවිඩ දැකිය හැකිය.",
|
||||
"New members can view complete message history.": "නව සාමාජිකයින්ට සම්පූර්ණ පණිවිඩ ඉතිහාසය බැලිය හැකිය.",
|
||||
"New message": "නව පණිවිඩය",
|
||||
"New option": "නව විකල්පය",
|
||||
"New password": "නව මුරපදය",
|
||||
"New password is too weak": "නව මුරපදය ඉතා දුර්වල ය",
|
||||
"New private message": "නව පෞද්ගලික පණිවිඩය",
|
||||
"New stream message": "",
|
||||
"New stream notifications:": "",
|
||||
"New task": "නව කාර්යය",
|
||||
"New topic": "නව මාතෘකාව",
|
||||
"New user notifications:": "නව පරිශීලක දැනුම්දීම්:",
|
||||
"Next week": "ලබන සතිය",
|
||||
"Night": "රාත්රිය",
|
||||
"Night logo": "රාත්රී ලාංඡනය",
|
||||
"Night mode": "",
|
||||
"No bots match your current filter.": "ඔබගේ වත්මන් පෙරහනට ස්වයංක්රමලේඛ නොගැලපේ.",
|
||||
"No custom emoji.": "අභිරුචි ඉමොජි නැත.",
|
||||
"No default streams match you current filter.": "",
|
||||
"No description.": "සවිස්තරයක් නැත.",
|
||||
"No drafts.": "",
|
||||
"No exports.": "නිර්යාත නැත.",
|
||||
"No invites match your current filter.": "ඔබගේ වත්මන් පෙරහනට කිසිදු ඇරයුමක් නොගැලපේ.",
|
||||
"No language set": "භාෂා කට්ටලයක් නැත",
|
||||
"No linkifiers set.": "",
|
||||
"No owner": "හිමිකරු නැත",
|
||||
"No playgrounds configured.": "ක්රීඩාපිටි වින්යාසගත කර නැත.",
|
||||
"No restrictions": "",
|
||||
"No streams": "",
|
||||
"No topics match your current filter.": "ඔබගේ වත්මන් පෙරහනට මාතෘකා කිසිවක් නොගැලපේ.",
|
||||
"No user to subscribe.": "",
|
||||
"No users match your current filter.": "ඔබගේ වර්තමාන පෙරහනට කිසිදු පරිශීලයෙකු නොගැලපේ.",
|
||||
"No. Members and admins can send invitations.": "නැහැ. සාමාජිකයින්ට හා පරිපාලකයින්ට ආරාධනා යැවිය හැකිය.",
|
||||
"No. Only admins can send invitations.": "නැහැ. ආරාධනා යැවිය හැකි වන්නේ පරිපාලකයින්ට පමණි.",
|
||||
"No. Only full members and admins can send invitations.": "නැහැ. ආරාධනා යැවිය හැකි වන්නේ පූර්ණ සාමාජිකයින්ට සහ පරිපාලකයින්ට පමණි.",
|
||||
"No. Only moderators and admins can send invitations.": "",
|
||||
"Nobody": "කිසිවෙක් නැත",
|
||||
"None": "",
|
||||
"Note that any bots that you maintain will be disabled.": "ඔබ නඩත්තු කරන ඕනෑම ස්වයංක්රමලේඛයක් අබල වන බව සලකන්න.",
|
||||
"Note that organizations are limited to five exports per week.": "සංවිධාන සතියකට නිර්යාත පහකට සීමා වී ඇති බව සලකන්න.",
|
||||
"Nothing to preview": "පෙරදසුන් සඳහා කිසි දෙයක් නැත",
|
||||
"Notification sound": "දැනුම් දීමේ ශබ්දය",
|
||||
"Notification triggers": "",
|
||||
"Notifications": "දැනුම්දීම්",
|
||||
"Notifications for @all/@everyone mentions": "@සියළු/@සෑමදෙනා සැඳහුම් සඳහා දැනුම්දීම්",
|
||||
"November": "ඉල්",
|
||||
"October": "වප්",
|
||||
"Offline": "",
|
||||
"Old password": "පරණ මුරපදය",
|
||||
"Once you leave a private stream, you will not be able to rejoin.": "",
|
||||
"Only group members and organization administrators can modify a group.": "",
|
||||
"Only organization administrators and moderators can post": "",
|
||||
"Only organization administrators and moderators can post.": "",
|
||||
"Only organization administrators can add bots to this organization": "මෙම සංවිධානයට ස්වයංක්රමලේඛ එකතු කළ හැකි වන්නේ පරිපාලකයින්ට පමණි",
|
||||
"Only organization administrators can add custom emoji in this organization.": "මෙම සංවිධානය තුළ අභිරුචි ඉමොජි එකතු කළ හැකි වන්නේ පරිපාලකයින්ට පමණි.",
|
||||
"Only organization administrators can add generic bots": "",
|
||||
"Only organization administrators can edit these settings.": "මෙම සැකසුම් සංස්කරණය කළ හැකි වන්නේ පරිපාලකයින්ට පමණි",
|
||||
"Only organization administrators can modify user groups in this organization.": "",
|
||||
"Only organization administrators can post": "පළ කළ හැකි වන්නේ පරිපාලකයින්ට පමණි",
|
||||
"Only organization administrators can post.": "පළ කළ හැකි වන්නේ පරිපාලකයින්ට පමණි.",
|
||||
"Only organization admins and moderators are allowed to post to this stream.": "",
|
||||
"Only organization admins are allowed to post to this stream.": "",
|
||||
"Only organization full members can post": "පළ කළ හැකි වන්නේ පූර්ණ සාමාජිකයින්ට පමණි",
|
||||
"Only organization full members can post.": "පළ කළ හැකි වන්නේ පූර්ණ සාමාජිකයින්ට පමණි.",
|
||||
"Only organization owners can edit these settings.": "මෙම සැකසුම් සංස්කරණය කළ හැකි වන්නේ හිමිකරුවන්ට පමණි.",
|
||||
"Only owners can change message retention policy.": "පණිවිඩ රඳවා ගැනීමේ ප්රතිපත්තිය වෙනස් කළ හැකි වන්නේ හිමිකරුවන්ට පමණි.",
|
||||
"Only owners can change stream message retention policy.": "",
|
||||
"Only owners can deactivate the organization.": "",
|
||||
"Only stream members can add users to a private stream": "",
|
||||
"Optional": "",
|
||||
"Or, to automatically linkify GitHub's <code>org/repo#1234</code> syntax:": "",
|
||||
"Organization": "සංවිධානය",
|
||||
"Organization administrators can change this in the organization settings.": "සංවිධානයේ සැකසුම් තුළ සංවිධාන පරිපාලකයින්ට මෙය වෙනස් කළ හැකිය.",
|
||||
"Organization administrators can reactivate deactivated users.": "",
|
||||
"Organization description": "සංවිධානයේ සවිස්තරය",
|
||||
"Organization logo": "සංවිධානයේ ලාංඡනය",
|
||||
"Organization name": "සංවිධානයේ නම",
|
||||
"Organization profile": "සංවිධානයේ පැතිකඩ",
|
||||
"Organization profile picture": "",
|
||||
"Organization settings": "සංවිධානයේ සැකසුම්",
|
||||
"Organization using {percent_used}% of {upload_quota}.": "සංවිධානය {upload_quota} න් {percent_used}% ක් භාවිතා කරයි.",
|
||||
"Other notification settings": "වෙනත් දැනුම්දීම් සැකසුම්",
|
||||
"Other permissions": "වෙනත් අවසර",
|
||||
"Other settings": "වෙනත් සැකසුම්",
|
||||
"Outgoing webhook message format": "",
|
||||
"Override unicode emoji?": "",
|
||||
"Owner": "හිමිකරු",
|
||||
"Owner: {name}": "හිමිකරු: {name}",
|
||||
"PMs, mentions, and alerts": "පෞ.ප., සැඳහුම් හා අනතුරු ඇඟවීම්",
|
||||
"Participants": "සහභාගිවන්නන්",
|
||||
"Participated": "සහභාගී වූහ",
|
||||
"Password": "මුරපදය",
|
||||
"Password is too weak": "මුරපදය ඉතා දුර්වල ය",
|
||||
"Password should be at least {length} characters long": "මුරපදය අවම වශයෙන් අකුරු {length} ක් දිග විය යුතුය",
|
||||
"Pattern": "රටාව",
|
||||
"People to add": "එකතු කිරීමට මිනිසුන්",
|
||||
"Personal settings": "පෞද්ගලික සැකසුම්",
|
||||
"Pin stream to top": "",
|
||||
"Pin stream to top of left sidebar": "",
|
||||
"Play sound": "ශබ්දය වාදනය",
|
||||
"Please just upload one file.": "කරුණාකර එක් ගොනුවක් උඩුගත කරන්න.",
|
||||
"Please re-enter your password to confirm your identity.": "",
|
||||
"Please specify a date or time": "",
|
||||
"Please specify a stream": "",
|
||||
"Please specify a topic": "",
|
||||
"Please specify at least one valid recipient": "",
|
||||
"Presence": "",
|
||||
"Press > for list of topics": "",
|
||||
"Press Enter to send": "යැවීමට ඇතුල්කරන්න ඔබන්න",
|
||||
"Prevent users from changing their avatar": "",
|
||||
"Prevent users from changing their email address": "පරිශීලකයින් ඔවුන්ගේ වි-තැපැල් ලිපිනය වෙනස් කිරීම වලක්වන්න",
|
||||
"Prevent users from changing their name": "පරිශීලකයින් තම නම වෙනස් කිරීම වලක්වන්න",
|
||||
"Preview": "පෙරදසුන",
|
||||
"Preview organization profile": "සංවිධානයේ පැතිකඩ පෙරදසුන",
|
||||
"Preview profile": "පැතිකඩ පෙරදසුන",
|
||||
"Private messages": "පෞද්ගලික පණිවිඩ",
|
||||
"Private messages and mentions": "පෞද්ගලික පණිවිඩ සහ සැඳහුම්",
|
||||
"Private messages are disabled in this organization.": "මෙම සංවිධානය තුළ පෞද්ගලික පණිවිඩ අබල කර ඇත.",
|
||||
"Private messages disabled": "පෞද්ගලික පණිවිඩ අබල කර ඇත",
|
||||
"Private, protected history": "පෞද්ගලික, ආරක්ෂිත ඉතිහාසය",
|
||||
"Private, shared history": "පෞද්ගලික, හවුල් ඉතිහාසය",
|
||||
"Pro tip: You can use 'd' to open your drafts.": "",
|
||||
"Profile": "පැතිකඩ",
|
||||
"Profile picture": "පැතිකඩ පින්තූරය",
|
||||
"Public": "ප්රසිද්ධ",
|
||||
"Public stream messages in organization": "",
|
||||
"Quote and reply or forward": "",
|
||||
"Reactivate": "",
|
||||
"Reactivate bot": "",
|
||||
"Receives new stream notifications": "",
|
||||
"Recent topics": "මෑත මාතෘකා",
|
||||
"Remind me about this": "මේ ගැන මට මතක් කරන්න",
|
||||
"Reminder not set!": "සිහිකැඳවීම සකසා නැත!",
|
||||
"Reminder set!": "සිහිකැඳවීම සකස් කෙරිණි!",
|
||||
"Remove": "ඉවත් කරන්න",
|
||||
"Remove from default": "පෙරනිමියෙන් ඉවත් කරන්න",
|
||||
"Reply": "පිළිතුරු",
|
||||
"Reply mentioning user": "පරිශීලකයා සඳහන් කරමින් පිළිතුරු දෙන්න",
|
||||
"Requesting user": "පරිශීලකයාගෙන් ඉල්ලීම",
|
||||
"Require topics in stream messages": "",
|
||||
"Resend": "නැවත යවන්න",
|
||||
"Resend invitation to <z-email></z-email>": "<z-email></z-email> වෙත යළි ආරාධනාවක් යවන්න",
|
||||
"Resending encountered an error. Please reload and try again.": "",
|
||||
"Restore draft": "",
|
||||
"Restrict email domains of new users?": "",
|
||||
"Restrict to a list of domains": "",
|
||||
"Retain for N days after posting": "",
|
||||
"Retain forever": "සදහටම රඳවා ගන්න",
|
||||
"Retry": "නැවත උත්සාහ කරන්න",
|
||||
"Revoke": "",
|
||||
"Revoke invitation link": "",
|
||||
"Revoke invitation to {email}": "",
|
||||
"Role": "",
|
||||
"SAVING": "සුරැකෙමින්",
|
||||
"Saturday": "සෙනසුරාදා",
|
||||
"Save": "සුරකින්න",
|
||||
"Save changes": "වෙනස්කම් සුරකින්න",
|
||||
"Save failed": "සුරැකීමට අසමත් විය",
|
||||
"Saved": "සුරැකිණි",
|
||||
"Saved as draft": "",
|
||||
"Saved. Please <z-link>reload</z-link> for the change to take effect.": "",
|
||||
"Saving": "සුරැකෙමින්",
|
||||
"Scheduling...": "",
|
||||
"Search": "සොයන්න",
|
||||
"Search GIFs": "චලනරූ සොයන්න",
|
||||
"Search operators": "ක්රියාකරුවන් සොයන්න",
|
||||
"Search results": "සෙවුම් ප්රතිඵල",
|
||||
"Search subscribers": "",
|
||||
"Select a stream below or change topic name.": "",
|
||||
"Select date and time": "",
|
||||
"Select default language": "",
|
||||
"Send": "යවන්න",
|
||||
"Send digest emails when I'm away": "",
|
||||
"Send email notifications for new logins to my account": "මාගේ ගිණුමට නව ඇතුල් වීම් ගැන වි-තැපැල් දැනුම්දීම් යවන්න",
|
||||
"Send emails introducing Zulip to new users": "නව පරිශීලකයින්ට සුලිප් හඳුන්වා දෙන වි-තැපැල් යවන්න",
|
||||
"Send me occasional marketing emails about Zulip (a few times a year)": "සුලිප් ගැන මට ඉඳහිට අලෙවිකරණ වි-තැපැල් එවන්න. (වසරකට කිහිප වතාවක්)",
|
||||
"Send mobile notifications even if I'm online (useful for testing)": "",
|
||||
"Send notification to new topic": "නව මාතෘකාවට දැනුම් දීමක් යවන්න",
|
||||
"Send notification to old topic": "පරණ මාතෘකාවට දැනුම් දීමක් යවන්න",
|
||||
"Send private message": "පෞද්ගලික පණිවිඩය යවන්න",
|
||||
"Send test notification": "අත්හදාබැලීමේ නිවේදනය යවන්න",
|
||||
"Send weekly digest emails to inactive users": "",
|
||||
"Sending...": "යැවෙමින්...",
|
||||
"Sent!": "යැවිණි!",
|
||||
"Sent! Scroll down to view your message.": "",
|
||||
"Sent! Your message is outside your current narrow.": "",
|
||||
"Sent! Your message was sent to a stream you have muted.": "",
|
||||
"Sent! Your message was sent to a topic you have muted.": "යැවිණි! ඔබ නිහඬ කළ මාතෘකාවකට ඔබගේ පණිවිඩය යවන ලදි.",
|
||||
"Sent! Your recent message is outside the current search.": "යැවිණි! ඔබගේ මෑත පණිවිඩය වත්මන් සෙවුමෙන් පිටත ය.",
|
||||
"September": "බිනර",
|
||||
"Set a status message": "තත්ව පණිවිඩයක් සකසන්න",
|
||||
"Set up two factor authentication": "",
|
||||
"Set yourself as active": "",
|
||||
"Set yourself as unavailable": "",
|
||||
"Settings": "සැකසුම්",
|
||||
"Setup": "පිහිටුවීම",
|
||||
"Several people are typing\u2026": "",
|
||||
"Show API key": "යෙ.ක්ර.මු. යතුර පෙන්වන්න",
|
||||
"Show counts for starred messages": "",
|
||||
"Show fewer": "වඩා අඩුවෙන් පෙන්වන්න",
|
||||
"Show more": "තව පෙන්වන්න",
|
||||
"Show password": "මුරපදය පෙන්වන්න",
|
||||
"Show previews of linked websites": "",
|
||||
"Show previews of uploaded and linked images": "",
|
||||
"Show starred message count": "තරු ලකුණු කළ පණිවිඩ ගණන පෙන්වන්න",
|
||||
"Show user list on left sidebar in narrow windows": "",
|
||||
"Show/change your API key": "ඔබගේ යෙ.ක්ර.මු. යතුර පෙන්වන්න/වෙනස් කරන්න",
|
||||
"Size": "ප්රමාණය",
|
||||
"Slack compatible": "",
|
||||
"Slack's outgoing webhooks": "",
|
||||
"Some common words were excluded from your search.": "ඔබගේ සෙවුමෙන් සමහර සුලබ වචන බැහැර කර ඇත.",
|
||||
"Sort by estimated weekly traffic": "",
|
||||
"Sort by name": "",
|
||||
"Sort by number of subscribers": "",
|
||||
"Spoiler": "",
|
||||
"Star": "තරුව",
|
||||
"Starred messages": "තරු ලකුණු කළ පණිවිඩ",
|
||||
"Start public export": "ප්රසිද්ධ නිර්යාතය අරඹන්න",
|
||||
"Status": "තත්ත්වය",
|
||||
"Stream": "",
|
||||
"Stream color": "",
|
||||
"Stream created recently": "",
|
||||
"Stream creation": "",
|
||||
"Stream description": "",
|
||||
"Stream membership": "",
|
||||
"Stream name": "",
|
||||
"Stream permissions": "",
|
||||
"Stream settings": "",
|
||||
"Stream successfully created!": "",
|
||||
"Streams": "",
|
||||
"Subscribe": "",
|
||||
"Subscribed": "",
|
||||
"Subscriber count": "",
|
||||
"Subscribers": "",
|
||||
"Successfully subscribed users:": "",
|
||||
"Sunday": "ඉරිදා",
|
||||
"System bot": "පද්ධතියේ ස්වයංක්රමලේඛය",
|
||||
"Task already exists": "කාර්යය දැනටමත් පවතී",
|
||||
"The recipient {recipient} is not valid": "{recipient} ලබන්නා වලංගු නොවේ",
|
||||
"The recipients {recipients} are not valid": "{recipients} ලබන්නන් වලංගු නොවේ",
|
||||
"The stream description cannot contain newline characters.": "",
|
||||
"The stream description has been updated!": "",
|
||||
"The stream has been renamed!": "",
|
||||
"Their password will be cleared from our systems, and any bots they maintain will be disabled.": "ඔවුන්ගේ මුරපදය අපගේ පද්ධතියෙන් හිස් කෙරෙන අතර, ඔවුන් නඩත්තු කරන ඕනෑම ස්වයංක්රමලේඛයක් අබල වෙනු ඇත.",
|
||||
"There are no current alert words.": "දැනට අනතුරු ඇඟවීමේ වචන නැත.",
|
||||
"These settings are explained in detail in the <z-link>help center</z-link>.": "<z-link>උපකාරක මධ්යස්ථානය</z-link> හි මෙම සැකසුම් විස්තරාත්මකව දක්වා ඇත.",
|
||||
"This action is permanent and cannot be undone. All users will permanently lose access to their Zulip accounts.": "මෙම ක්රියාමාර්ගය නිත්ය වන අතර එය ආපසු හැරවිය නොහැකිය. සියළුම පරිශීලකයින්ට ඔවුන්ගේ සුලිප් ගිණුම් වෙත ප්රවේශය සදහටම අහිමි වේ.",
|
||||
"This file exceeds maximum allowed size of": "මෙම ගොනුව ඉඩ දී ඇති උපරිම ප්රමාණය ඉක්මවයි",
|
||||
"This is a <z-icon></z-icon> <b>private stream</b>. Only people who have been invited can access its content, but any member of the stream can invite others.": "",
|
||||
"This is a <z-icon></z-icon> <b>public stream</b>. Any member of the organization can join without an invitation.": "",
|
||||
"This is a <z-icon></z-icon> <b>web public stream</b>. Any member of the organization can join without an invitation and anyone on the internet can read the content published.": "",
|
||||
"This is a private stream": "",
|
||||
"This is what a Zulip notification looks like.": "සුලිප් නිවේදනයක පෙනුම මෙවැනි ය.",
|
||||
"This message was hidden because you have muted the sender.": "ඔබ එවන්නා නිහඬ කර ඇති නිසා මෙම පණිවිඩය සඟවා ඇත.",
|
||||
"This organization is configured to restrict editing of message content to {minutes_to_edit} minutes after it is sent.": "මෙම සංවිධානය වින්යාසගත කර ඇත්තේ පණිවිඩය යැවීමෙන් පසු අන්තර්ගතය සංස්කරණය විනාඩි {minutes_to_edit} කට සීමා කිරීමට ය.",
|
||||
"This stream does not exist or is private.": "",
|
||||
"This stream has been deactivated": "",
|
||||
"This stream is reserved for <strong>announcements</strong>. <br /> Are you sure you want to message all <strong>{count}</strong> people in this stream?": "",
|
||||
"Thursday": "බ්රහස්පතින්දා",
|
||||
"Time": "කාලය",
|
||||
"Time format": "",
|
||||
"Time settings": "කාල සැකසුම්",
|
||||
"Time zone": "වේලා කලාපය",
|
||||
"Time's up!": "කාලය ඉවරයි!",
|
||||
"Tip: You can also send \"/poll Some question\"": "",
|
||||
"To": "වෙත",
|
||||
"To add syntax highlighting to a multi-line code block, add the language's <b>first</b> <z-link>Pygments short name</z-link> after the first set of back-ticks. You can also make a code block by indenting each line with 4 spaces.": "",
|
||||
"Today": "අද",
|
||||
"Toggle subscription": "",
|
||||
"Tomorrow": "හෙට",
|
||||
"Topic": "මාතෘකාව",
|
||||
"Topic editing only": "මාතෘකා සංස්කරණය කිරීම පමණි",
|
||||
"Topic muted": "මාතෘකාව නිහඬ කෙරිණි",
|
||||
"Try again": "නැවත උත්සහා කරන්න",
|
||||
"Tuesday": "අඟහරුවාදා",
|
||||
"Two factor authentication": "",
|
||||
"Type": "වර්ගය",
|
||||
"URL format string": "",
|
||||
"URL pattern": "ඒ.ස.නි. රටාව",
|
||||
"URL prefix": "ඒ.ස.නි. උපසර්ගය",
|
||||
"Un-collapse": "",
|
||||
"Unavailable": "",
|
||||
"Uncheck all": "",
|
||||
"Unknown": "නොදන්නා",
|
||||
"Unknown stream": "",
|
||||
"Unmute": "",
|
||||
"Unmute stream": "",
|
||||
"Unmute the topic <b>{topic}</b>": "",
|
||||
"Unmute this user": "",
|
||||
"Unmute topic": "",
|
||||
"Unpin stream from top": "",
|
||||
"Unread": "නොකියවූ",
|
||||
"Unread count summary (appears in desktop sidebar and browser tab)": "",
|
||||
"Unstar": "",
|
||||
"Unstar all messages": "",
|
||||
"Unstar all messages in topic": "",
|
||||
"Unstar messages in topic": "",
|
||||
"Unsubscribe": "",
|
||||
"Unsubscribe from {stream_name}": "",
|
||||
"Unsubscribed successfully!": "",
|
||||
"Up to N minutes after posting": "",
|
||||
"Up to {time_limit} after posting": "පළ කිරීමෙන් පසු {time_limit} දක්වා",
|
||||
"Update successful: Subdomains allowed for {domain}": "යාවත්කාල කිරීම සාර්ථකයි: {domain} සඳහා උප වසම් වලට ඉඩ දුණි",
|
||||
"Update successful: Subdomains no longer allowed for {domain}": "යාවත්කාල කිරීම සාර්ථකයි: තවදුරටත් {domain} සඳහා උපවසම් වලට ඉඩ නොදේ",
|
||||
"Upload files": "ගොනු උඩුගත කරන්න",
|
||||
"Upload icon": "උඩුගත නිරූපකය",
|
||||
"Upload image or GIF": "",
|
||||
"Upload logo": "ලාංඡනය උඩුගත කරන්න",
|
||||
"Upload new profile picture": "",
|
||||
"Upload profile picture": "පැතිකඩ පින්තූරය උඩුගත කරන්න",
|
||||
"Upload stalled for %'{seconds}' seconds, aborting.": "",
|
||||
"Uploading {filename}\u2026": "{filename} උඩුගත වෙමින්…",
|
||||
"Uploading\u2026": "උඩුගත වෙමින්…",
|
||||
"Use full width on wide screens": "පුළුල් තිර මත පූර්ණ පළල භාවිතා කරන්න",
|
||||
"Use organization level settings": "සංවිධාන මට්ටමේ සැකසුම් භාවිතා කරන්න",
|
||||
"User": "පරිශීලක",
|
||||
"User group added!": "පරිශීලක සමූහය එකතු කෙරිණි!",
|
||||
"User groups allow you to <z-link>mention</z-link> multiple users at once. When you mention a user group, everyone in the group is notified as if they were individually mentioned.": "පරිශීලක සමූහය ඔබට එකවර පරිශීලකයින් කිහිපයක් <z-link>සැඳහුම</z-link> ට ඉඩ දෙයි. ඔබ පරිශීලක සමූහයක් සඳහන් කළ විට සමූහයේ සෑම දෙනාම තනි තනිව සඳහන් කළා ක් මෙන් දැනුම් දෙනු ඇත.",
|
||||
"User identity": "පරිශීලක අනන්යතාව",
|
||||
"User is already not subscribed.": "",
|
||||
"User is deactivated": "",
|
||||
"User role": "පරිශීලක භූමිකාව",
|
||||
"User settings": "පරිශීලක සැකසුම්",
|
||||
"User will not be notified": "පරිශීලකයාට දැනුම් නොදෙනු ඇත",
|
||||
"User(s) invited successfully.": "",
|
||||
"Users": "පරිශීලකයින්",
|
||||
"Users can edit the topic of any message": "පරිශීලකයින්ට ඕනෑම පණිවිඩයක මාතෘකාව සංස්කරණය කළ හැකිය",
|
||||
"Video call provider": "",
|
||||
"View edit history": "",
|
||||
"View file": "",
|
||||
"View full profile": "",
|
||||
"View in playground": "",
|
||||
"View in {name}": "",
|
||||
"View in {playground_name}": "",
|
||||
"View messages sent": "",
|
||||
"View private messages": "",
|
||||
"View private messages to myself": "",
|
||||
"View source": "",
|
||||
"View source / Edit topic": "",
|
||||
"View stream": "",
|
||||
"View user profile": "",
|
||||
"View your profile": "",
|
||||
"Visual": "",
|
||||
"Visual desktop notifications": "",
|
||||
"Waiting period (days)": "පොරොත්තු කාලය (දවස්)",
|
||||
"Waiting period before new members turn into full members": "නව සාමාජිකයින් පූර්ණ සාමාජිකයින් බවට පත්වීමට පෙර පොරොත්තු කාලය",
|
||||
"Warning: <strong>{stream_name}</strong> is a private stream.": "",
|
||||
"We are about to have a poll. Please wait for the question.": "අපි මත විමසුමක් පැවැත්වීමට ආසන්නයි. කරුණාකර ප්රශ්නය සඳහා රැඳී සිටින්න.",
|
||||
"We've replaced the \"{originalHotkey}\" hotkey with \"{replacementHotkey}\" to make this common shortcut easier to trigger.": "",
|
||||
"Wednesday": "බදාදා",
|
||||
"Week of {date}": "",
|
||||
"Whether wildcard mentions like @all are treated as mentions for the purpose of notifications.": "",
|
||||
"Who can access the stream?": "",
|
||||
"Who can access user email addresses": "පරිශීලක වි-තැපැල් ලිපින වලට ප්රවේශ විය හැකි වන්නේ කාටද?",
|
||||
"Who can add bots": "කාටද ස්වයංක්රමලේඛ එකතු කළ හැකි වන්නේ",
|
||||
"Who can add custom emoji": "අභිරුචි ඉමොජි එකතු කළ හැකි වන්නේ කාටද",
|
||||
"Who can add users to streams": "",
|
||||
"Who can create and manage user groups": "පරිශීලක සමූහ සෑදීමට සහ කළමනාකරණය කිරීමට හැකි වන්නේ කාටද",
|
||||
"Who can create streams": "",
|
||||
"Who can move messages between streams": "",
|
||||
"Who can post to the stream?": "",
|
||||
"Who can use @all/@everyone mentions in large streams": "",
|
||||
"Who can use private messages": "පෞද්ගලික පණිවිඩ භාවිතා කළ හැකි වන්නේ කාටද",
|
||||
"Widgets cannot be edited.": "",
|
||||
"Word": "වචනය",
|
||||
"Working\u2026": "වැඩ කරමින්…",
|
||||
"Write": "ලියන්න",
|
||||
"Yes": "ඔව්",
|
||||
"Yes, send": "ඔව්, යවන්න",
|
||||
"Yes, subscribe {count} users!": "",
|
||||
"Yes. Members and admins can send invitations.": "ඔව්. සාමාජිකයින්ට සහ පරිපාලකයින්ට ආරාධනා යැවිය හැකිය.",
|
||||
"Yes. Only admins can send invitations.": "ඔව්. ආරාධනා යැවිය හැකි වන්නේ පරිපාලකයින්ට පමණි.",
|
||||
"Yes. Only full members and admins can send invitations.": "ඔව්. ආරාධනා යැවිය හැකි වන්නේ පූර්ණ සාමාජිකයින්ට සහ පරිපාලකයින්ට පමණි.",
|
||||
"Yes. Only moderators and admins can send invitations.": "",
|
||||
"Yesterday": "ඊයේ",
|
||||
"You (click to remove) and {other_username} reacted with {emoji_name}": "",
|
||||
"You (click to remove) reacted with {emoji_name}": "",
|
||||
"You (click to remove), {comma_separated_usernames} and {last_username} reacted with {emoji_name}": "",
|
||||
"You and": "ඔබ සහ",
|
||||
"You and {display_reply_to}": "ඔබ සහ {display_reply_to}",
|
||||
"You and {recipients}": "ඔබ සහ {recipients}",
|
||||
"You are not currently subscribed to this stream.": "",
|
||||
"You are not subscribed to stream {stream}": "",
|
||||
"You are searching for messages that are sent by more than one person, which is not possible.": "ඔබ සොයන්නේ නොහැකි දෙයක් වන එක් පුද්ගලයෙකුට වඩා වැඩි දෙනෙක් යැවූ පණිවිඩයි",
|
||||
"You are searching for messages that belong to more than one stream, which is not possible.": "",
|
||||
"You are searching for messages that belong to more than one topic, which is not possible.": "ඔබ සොයන්නේ නොහැකි දෙයක් වන මාතෘකා එකකට වඩා වැඩි ගණනකට අයත් පණිවිඩ ය.",
|
||||
"You can also make <z-link>tables</z-link> with this <z-link>Markdown-ish table syntax</z-link>.": "",
|
||||
"You can reactivate deactivated users from <z-link>organization settings</z-link>.": "",
|
||||
"You cannot create a stream with no subscribers!": "",
|
||||
"You do not have permission to use wildcard mentions in this stream.": "",
|
||||
"You get": "ඔබට ලැබේ",
|
||||
"You have muted <z-stream-topic></z-stream-topic>.": "ඔබ <z-stream-topic></z-stream-topic> නිහඬ කර ඇත.",
|
||||
"You have no active bots.": "",
|
||||
"You have no inactive bots.": "",
|
||||
"You have not muted any topics yet.": "ඔබ තවමත් මාතෘකා කිසිවක් නිහඬ කර නැත.",
|
||||
"You have not muted any users yet.": "ඔබ තවමත් කිසිදු පරිශීලකයෙකු නිහඬ කර නැත.",
|
||||
"You have not uploaded any files.": "ඔබ කිසිදු ගොනුවක් උඩුගත කර නැත.",
|
||||
"You have nothing to send!": "ඔබට යැවීමට කිසිවක් නැත!",
|
||||
"You must be an organization administrator to create a stream without subscribing.": "",
|
||||
"You need to be running Zephyr mirroring in order to send messages!": "",
|
||||
"You searched for:": "ඔබ සෙව්වේ:",
|
||||
"You subscribed to stream {stream}": "",
|
||||
"You type": "",
|
||||
"You unsubscribed from stream {stream}": "",
|
||||
"You're not subscribed to this stream. You will not be notified if other users reply to your message.": "",
|
||||
"Your API key:": "ඔබගේ යෙ.ක්ර.මු. යතුර:",
|
||||
"Your reminder note is empty!": "ඔබගේ සිහිකැඳවීමේ සටහන හිස් ය!",
|
||||
"Zulip's translations are contributed by our amazing community of volunteer translators. If you'd like to help, see the <z-link>Zulip translation guidelines</z-link>.": "සුලිප් පරිවර්තන සඳහා දායක වී ඇත්තේ අපගේ විශ්මය ජනක ස්වේච්ඡා පරිවර්තක ප්රජාව විසිනි. ඔබට උදව් කිරීමට අවශ්ය නම්, <z-link>සුලිප් පරිවර්තන මාර්ගෝපදේශය</z-link> බලන්න.",
|
||||
"[Condense message]": "[සංෂිප්ත පණිවිඩය]",
|
||||
"[Configure]": "[වින්යාසගත කරන්න]",
|
||||
"[Disable]": "[අබල කරන්න]",
|
||||
"[More\u2026]": "[තව…]",
|
||||
"[Remove owner]": "[හිමිකරු ඉවත් කරන්න]",
|
||||
"[Unset]": "[සකසා නැත]",
|
||||
"and": "හා",
|
||||
"beta": "බීටා",
|
||||
"clear": "",
|
||||
"cookie": "",
|
||||
"group private messages with {recipient}": "{recipient} සමඟ පෞද්ගලික පණිවිඩ සමූහගත කරන්න",
|
||||
"in 1 hour": "පැය 1 කින්",
|
||||
"in 20 minutes": "විනාඩි 20 කින්",
|
||||
"in 3 hours": "පැය 3 කින්",
|
||||
"leafy green vegetable": "කොළ පැහැති එලවළු",
|
||||
"marketing": "අලෙවිකරණය",
|
||||
"more topics": "තවත් මාතෘකා",
|
||||
"private messages with yourself": "ඔබ සමඟ පෞද්ගලික පණිවිඩ",
|
||||
"private messages with {recipient}": "{recipient} සමඟ පෞද්ගලික පණිවිඩ",
|
||||
"{comma_separated_usernames} and {last_username} reacted with {emoji_name}": "",
|
||||
"{count} users are subscribed to #{title}": "",
|
||||
"{days_old} days ago": "දවස් {days_old} කට පෙර",
|
||||
"{full_name} is typing\u2026": "",
|
||||
"{hours} hours ago": "පැය {hours} කට පෙර",
|
||||
"{last_active_date}": "{last_active_date}",
|
||||
"{minutes} min to edit": "සංස්කරණයට විනාඩි {minutes}",
|
||||
"{minutes} minutes ago": "විනාඩි {minutes} කට පෙර",
|
||||
"{seconds} sec to edit": "සංස්කරණයට තත්පර {seconds}",
|
||||
"{starred_status} this message": "මෙම පණිවිඩය {starred_status}",
|
||||
"{starred_status} this message (Ctrl + s)": "",
|
||||
"{username} [said]({link_to_message}):": "",
|
||||
"{username} reacted with {emoji_name}": "",
|
||||
"{wildcard_mention_token} (Notify stream)": ""
|
||||
}
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Zulip\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-09-23 19:14+0000\n"
|
||||
"POT-Creation-Date: 2021-11-30 22:59+0000\n"
|
||||
"PO-Revision-Date: 2018-04-11 21:06+0000\n"
|
||||
"Last-Translator: Tim Abbott <tabbott@kandralabs.com>\n"
|
||||
"Language-Team: Tamil (http://www.transifex.com/zulip/zulip/language/ta/)\n"
|
||||
@@ -1428,7 +1428,7 @@ msgstr ""
|
||||
msgid "Organization permissions"
|
||||
msgstr ""
|
||||
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2390
|
||||
#: templates/zerver/app/settings_overlay.html:76 zerver/models.py:2391
|
||||
msgid "Custom emoji"
|
||||
msgstr ""
|
||||
|
||||
@@ -3863,7 +3863,7 @@ msgstr ""
|
||||
msgid "Message must have recipients"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:193
|
||||
#: zerver/lib/addressee.py:154 zerver/lib/outgoing_webhook.py:215
|
||||
msgid "Invalid message type"
|
||||
msgstr ""
|
||||
|
||||
@@ -3979,7 +3979,7 @@ msgstr ""
|
||||
msgid "Must be an organization administrator or emoji author"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:840
|
||||
#: zerver/lib/emoji.py:117 zerver/models.py:841
|
||||
msgid "Invalid characters in emoji name"
|
||||
msgstr ""
|
||||
|
||||
@@ -4307,11 +4307,11 @@ msgid ""
|
||||
"a previous message."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:293
|
||||
#: zerver/lib/outgoing_webhook.py:315
|
||||
msgid "Invalid JSON in response"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/outgoing_webhook.py:302
|
||||
#: zerver/lib/outgoing_webhook.py:324
|
||||
#, fuzzy
|
||||
#| msgid "Enable notifications"
|
||||
msgid "Invalid response format"
|
||||
@@ -4518,7 +4518,7 @@ msgstr ""
|
||||
msgid "Invalid interface type"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3469
|
||||
#: zerver/lib/users.py:223 zerver/lib/users.py:228 zerver/models.py:3470
|
||||
#, fuzzy
|
||||
#| msgid "Enable notifications"
|
||||
msgid "Invalid user ID: {}"
|
||||
@@ -4697,93 +4697,97 @@ msgstr ""
|
||||
msgid "CSRF error: {reason}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:372
|
||||
#: zerver/models.py:373
|
||||
#, fuzzy
|
||||
#| msgid "Username"
|
||||
msgid "stream events"
|
||||
msgstr "பயனர்பெயர்"
|
||||
|
||||
#: zerver/models.py:406
|
||||
#: zerver/models.py:407
|
||||
msgid "Available on Zulip Standard. Upgrade to access."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:910
|
||||
msgid "Invalid linkifier pattern. Valid characters are {}."
|
||||
#: zerver/models.py:919 zerver/models.py:921
|
||||
msgid "Bad regular expression: {}"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:928
|
||||
#: zerver/models.py:922
|
||||
msgid "Unknown regular expression error"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:929
|
||||
msgid "Invalid URL format string."
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1035 zerver/views/realm_playgrounds.py:24
|
||||
#: zerver/models.py:1036 zerver/views/realm_playgrounds.py:24
|
||||
msgid "Invalid characters in pygments language"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1415
|
||||
#: zerver/models.py:1416
|
||||
#, fuzzy
|
||||
#| msgid "Administrators"
|
||||
msgid "Organization owner"
|
||||
msgstr "நிர்வாகிகள்"
|
||||
|
||||
#: zerver/models.py:1416
|
||||
#: zerver/models.py:1417
|
||||
#, fuzzy
|
||||
#| msgid "Administrators"
|
||||
msgid "Organization administrator"
|
||||
msgstr "நிர்வாகிகள்"
|
||||
|
||||
#: zerver/models.py:1417
|
||||
#: zerver/models.py:1418
|
||||
msgid "Moderator"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1418
|
||||
#: zerver/models.py:1419
|
||||
msgid "Member"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:1419
|
||||
#: zerver/models.py:1420
|
||||
msgid "Guest"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2389
|
||||
#: zerver/models.py:2390
|
||||
msgid "Unicode emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:2391
|
||||
#: zerver/models.py:2392
|
||||
msgid "Zulip extra emoji"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3473
|
||||
#: zerver/models.py:3474
|
||||
msgid "User with ID {} is deactivated"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3476
|
||||
#: zerver/models.py:3477
|
||||
msgid "User with ID {} is a bot"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3509
|
||||
#: zerver/models.py:3510
|
||||
msgid "List of options"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3512
|
||||
#: zerver/models.py:3513
|
||||
msgid "Person picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3524
|
||||
#: zerver/models.py:3525
|
||||
msgid "Short text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3525
|
||||
#: zerver/models.py:3526
|
||||
msgid "Long text"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3526
|
||||
#: zerver/models.py:3527
|
||||
msgid "Date picker"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3527
|
||||
#: zerver/models.py:3528
|
||||
msgid "Link"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/models.py:3530
|
||||
#: zerver/models.py:3531
|
||||
msgid "External account"
|
||||
msgstr ""
|
||||
|
||||
@@ -4799,24 +4803,24 @@ msgstr ""
|
||||
msgid "An unknown browser"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:632
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
msgid "Missing 'queue_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:635
|
||||
#: zerver/tornado/event_queue.py:647
|
||||
msgid "Missing 'last_event_id' argument"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:638
|
||||
#: zerver/tornado/event_queue.py:650
|
||||
msgid "You are not authorized to get events from this queue"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:644
|
||||
#: zerver/tornado/event_queue.py:656
|
||||
#, python-brace-format
|
||||
msgid "An event newer than {event_id} has already been pruned!"
|
||||
msgstr ""
|
||||
|
||||
#: zerver/tornado/event_queue.py:654
|
||||
#: zerver/tornado/event_queue.py:666
|
||||
#, python-brace-format
|
||||
msgid "Event {event_id} was not in this queue"
|
||||
msgstr ""
|
||||
@@ -5530,15 +5534,15 @@ msgstr ""
|
||||
msgid "Invalid data."
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:1922
|
||||
#: zproject/backends.py:1927
|
||||
msgid "Missing id_token parameter"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2277
|
||||
#: zproject/backends.py:2282
|
||||
msgid "Invalid OTP"
|
||||
msgstr ""
|
||||
|
||||
#: zproject/backends.py:2280
|
||||
#: zproject/backends.py:2285
|
||||
msgid "Can't use both mobile_flow_otp and desktop_flow_otp together."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
# Cihan Alkan <cihanalk@gmail.com>, 2021
|
||||
# Gokdeniz.Kucukali, 2021
|
||||
# Hüseyin Fahri Uzun <mail@fahriuzun.com>, 2021
|
||||
# Oktay Altunergil, 2021
|
||||
# Tim Abbott <tabbott@kandralabs.com>, 2021
|
||||
# Oktay Altunergil, 2021
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
@@ -19,7 +19,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-05-26 18:04+0000\n"
|
||||
"PO-Revision-Date: 2021-04-02 21:39+0000\n"
|
||||
"Last-Translator: Tim Abbott <tabbott@kandralabs.com>, 2021\n"
|
||||
"Last-Translator: Oktay Altunergil, 2021\n"
|
||||
"Language-Team: Turkish (https://www.transifex.com/zulip/teams/53893/tr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -664,7 +664,7 @@ msgstr ""
|
||||
|
||||
#: templates/zerver/app/index.html:68
|
||||
msgid "Retrying soon..."
|
||||
msgstr "Yakıda yeniden deniyor..."
|
||||
msgstr "Az sonra yeniden denenecek..."
|
||||
|
||||
#: templates/zerver/app/index.html:68
|
||||
msgid "Try now."
|
||||
@@ -836,7 +836,7 @@ msgstr "Navigasyon"
|
||||
#: templates/zerver/app/left_sidebar.html:64
|
||||
#: templates/zerver/app/left_sidebar.html:66
|
||||
msgid "Filter streams"
|
||||
msgstr "Kanalları filtrele"
|
||||
msgstr "Kanalları süz"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:77
|
||||
#: templates/zerver/app/right_sidebar.html:9
|
||||
@@ -967,7 +967,7 @@ msgstr "Son konuları görüntüle"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:251
|
||||
msgid "Filter topics"
|
||||
msgstr "Konuları filtrele"
|
||||
msgstr "Konuları süz"
|
||||
|
||||
#: templates/zerver/app/keyboard_shortcuts.html:260
|
||||
msgid "Drafts"
|
||||
@@ -1287,7 +1287,7 @@ msgstr ""
|
||||
#: templates/zerver/app/right_sidebar.html:5
|
||||
#: templates/zerver/app/right_sidebar.html:6
|
||||
msgid "Filter users"
|
||||
msgstr "Kullanıcıları filtrele"
|
||||
msgstr "Kullanıcıları süz"
|
||||
|
||||
#: templates/zerver/app/right_sidebar.html:5
|
||||
msgid "USERS"
|
||||
@@ -3175,7 +3175,7 @@ msgstr "Arama entegrasyonları"
|
||||
|
||||
#: templates/zerver/integrations/index.html:48
|
||||
msgid "Filter by category"
|
||||
msgstr "Kategorilere göre filtrele"
|
||||
msgstr "Kategorilere göre süz"
|
||||
|
||||
#: templates/zerver/integrations/index.html:62
|
||||
#: templates/zerver/integrations/index.html:89
|
||||
|
||||
@@ -315,22 +315,22 @@
|
||||
"File and image uploads have been disabled for this organization.": "Dosya ve resim yüklemeleri bu organizasyon için iptal edilmiştir.",
|
||||
"File size must be at most {max_file_size} MiB.": "Dosya boyutu en fazla {max_file_size} MiB olmalıdır.",
|
||||
"File type is not supported.": "Dosya türü desteklenmiyor.",
|
||||
"Filter": "Filtre",
|
||||
"Filter bots": "Filtreleme botları",
|
||||
"Filter by category": "Kategorilere göre filtrele",
|
||||
"Filter code playgrounds": "Kod oyun alanlarını filtrele",
|
||||
"Filter": "Süz",
|
||||
"Filter bots": "Süzme botları",
|
||||
"Filter by category": "Kategorilere göre süz",
|
||||
"Filter code playgrounds": "Kod oyun alanlarını süz",
|
||||
"Filter deactivated users": "Devre dışı bırakılmış kullanıcıları ayır",
|
||||
"Filter emojis": "Emojlleri filtrele",
|
||||
"Filter exports": "Dışa aktarımları filtrele",
|
||||
"Filter invites": "Davetiyeleri filtrele",
|
||||
"Filter languages": "Dilleri filtrele",
|
||||
"Filter linkifiers": "Linkifierları filtrele",
|
||||
"Filter muted topics": "Sessiz konuları filtrele",
|
||||
"Filter muted users": "Sesi kapatılmış kullanıcıları filtrele",
|
||||
"Filter streams": "Kanalları filtrele",
|
||||
"Filter topics (t)": "Konuları filtrele (t)",
|
||||
"Filter uploads": "Yüklemeleri filtrele",
|
||||
"Filter users": "Kullanıcıları filtrele",
|
||||
"Filter emojis": "Emojlleri süz",
|
||||
"Filter exports": "Dışa aktarımları süz",
|
||||
"Filter invites": "Davetiyeleri süz",
|
||||
"Filter languages": "Dilleri süz",
|
||||
"Filter linkifiers": "Linkifierları süz",
|
||||
"Filter muted topics": "Sessiz konuları süz",
|
||||
"Filter muted users": "Sesi kapatılmış kullanıcıları süz",
|
||||
"Filter streams": "Kanalları süz",
|
||||
"Filter topics (t)": "Konuları süz (t)",
|
||||
"Filter uploads": "Yüklemeleri süz",
|
||||
"Filter users": "Kullanıcıları süz",
|
||||
"First time? Read our <z-link>guidelines</z-link> for creating and naming streams.": "İlk kullanışınız mı? Kanal oluşturmak ve adlandırmak için<z-link> yönergeleri</z-link>.",
|
||||
"Fixed width": "Sabitlenmiş genişlik",
|
||||
"Fixed width mode": "Sabit genişlik modu",
|
||||
@@ -479,22 +479,22 @@
|
||||
"Night": "Gece",
|
||||
"Night logo": "Gece logosu",
|
||||
"Night mode": "Gece modu",
|
||||
"No bots match your current filter.": "Şu anki filtrenizle eşleşen bot bulunmuyor.",
|
||||
"No bots match your current filter.": "Şu anki süzmeyle eşleşen bot bulunmuyor.",
|
||||
"No custom emoji.": "Özel emoji yok",
|
||||
"No default streams match you current filter.": "Şu anki filtrenizle eşleşen varsayılan kanal bulunmuyor.",
|
||||
"No default streams match you current filter.": "Şu anki süzmeyle eşleşen varsayılan kanal bulunmuyor.",
|
||||
"No description.": "Tanım yok.",
|
||||
"No drafts.": "Taslak yok.",
|
||||
"No exports.": "Dışa aktarım yok",
|
||||
"No invites match your current filter.": "Şu anki filtrenizle eşleşen davetiye bulunmuyor.",
|
||||
"No invites match your current filter.": "Şu anki süzmeyle eşleşen davetiye bulunmuyor.",
|
||||
"No language set": "Dil ayarlanmadı",
|
||||
"No linkifiers set.": "Linkifier oluşturulmadı.",
|
||||
"No owner": "Sahipsiz",
|
||||
"No playgrounds configured.": "Yapılandırılmış oyun alanı yok.",
|
||||
"No restrictions": "Kısıtlama yok",
|
||||
"No streams": "Kanal yok",
|
||||
"No topics match your current filter.": "Şuanki filtre ile eşleşen konu yok.",
|
||||
"No topics match your current filter.": "Şuanki süzme ile eşleşen konu yok.",
|
||||
"No user to subscribe.": "Abone olacak kullanıcı yok",
|
||||
"No users match your current filter.": "Şu anki filtrenizle eşleşen kullanıcı bulunmuyor.",
|
||||
"No users match your current filter.": "Şu anki süzmeyle eşleşen kullanıcı bulunmuyor.",
|
||||
"No. Members and admins can send invitations.": "Hayır. Üyeler ve yöneticiler davetiye gönderebilir.",
|
||||
"No. Only admins can send invitations.": "Hayır. Yalnızca yöneticiler davetiye gönderebilir.",
|
||||
"No. Only full members and admins can send invitations.": "Hayır. Yalnızca tam üyeler ve yöneticiler davetiye gönderebilir.",
|
||||
|
||||
@@ -38,6 +38,7 @@ Listen 127.0.0.1:8888
|
||||
WSGIScriptAlias / /home/zulip/deployments/current/zproject/wsgi.py
|
||||
WSGIDaemonProcess zulip threads=5 user=zulip python-path=/home/zulip/deployments/current/
|
||||
WSGIProcessGroup zulip
|
||||
WSGIApplicationGroup %{GLOBAL}
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/zulip_auth_error.log
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
SHELL=/bin/bash
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
USER=root
|
||||
|
||||
# Cron job to renew certbot twice a day.
|
||||
52 0,12 * * * root /home/zulip/deployments/current/scripts/lib/certbot-maybe-renew
|
||||
3
puppet/zulip/files/letsencrypt/nginx-deploy-hook.sh
Executable file
3
puppet/zulip/files/letsencrypt/nginx-deploy-hook.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
service nginx reload
|
||||
@@ -3,12 +3,8 @@
|
||||
# combination. See the clustering on a single machine guide for details:
|
||||
# http://www.rabbitmq.com/clustering.html#single-machine
|
||||
#
|
||||
# By default, we set nodename to rabbit@localhost so it will always resolve
|
||||
<% if @rabbitmq_nodename != '' -%>
|
||||
NODENAME=<%= @rabbitmq_nodename %>
|
||||
<% else -%>
|
||||
NODENAME=rabbit
|
||||
<% end -%>
|
||||
# By default, we set nodename to zulip@localhost so it will always resolve
|
||||
NODENAME=zulip@localhost
|
||||
|
||||
# By default RabbitMQ will bind to all interfaces, on IPv4 and IPv6 if
|
||||
# available. Set this if you only want to bind to one network interface or#
|
||||
@@ -1,11 +0,0 @@
|
||||
# This file is sourced by /etc/init.d/rabbitmq-server. Its primary
|
||||
# reason for existing is to allow adjustment of system limits for the
|
||||
# rabbitmq-server process.
|
||||
#
|
||||
# Maximum number of open file handles. This will need to be increased
|
||||
# to handle many simultaneous connections. Refer to the system
|
||||
# documentation for ulimit (in man bash) for more information.
|
||||
#
|
||||
#ulimit -n 1024
|
||||
|
||||
export ERL_EPMD_ADDRESS=127.0.0.1
|
||||
@@ -1,4 +1,2 @@
|
||||
[{kernel, [{inet_dist_use_interface, {127,0,0,1}}]},
|
||||
{rabbit, [{tcp_listeners, [{"127.0.0.1", 5672}]}]},
|
||||
{rabbitmq_mochiweb, [{listeners, [{mgmt, [{ip, "127.0.0.1"},
|
||||
{port, 55672}]}]}]}].
|
||||
{rabbit, [{tcp_listeners, [{"127.0.0.1", 5672}]}]}].
|
||||
|
||||
25
puppet/zulip/files/secret-env-wrapper
Executable file
25
puppet/zulip/files/secret-env-wrapper
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" == "--" ]; then
|
||||
shift
|
||||
exec "$@"
|
||||
elif [[ "$arg" == *"="* ]]; then
|
||||
shift
|
||||
varname="${arg%%=*}"
|
||||
secretname="${arg#*=}"
|
||||
secret=$(crudini --get /etc/zulip/zulip-secrets.conf secrets "$secretname")
|
||||
export "$varname"="$secret"
|
||||
else
|
||||
exec "$@"
|
||||
fi
|
||||
done
|
||||
|
||||
{
|
||||
echo "Usage:"
|
||||
echo " secret-env-wrapper ENVNAME=secretname binary [argument [argument [...]]]"
|
||||
} >&2
|
||||
|
||||
exit 1
|
||||
@@ -5,7 +5,12 @@ module Puppet::Parser::Functions
|
||||
zulip_conf_path = lookupvar("zulip_conf_path")
|
||||
output = `/usr/bin/crudini --get #{zulip_conf_path} #{joined} 2>&1`; result = $?.success?
|
||||
if result
|
||||
output.strip()
|
||||
if [true, false].include? default
|
||||
# If the default is a bool, coerce into a bool
|
||||
['1','y','t','true','yes','enable','enabled'].include? output.strip.downcase
|
||||
else
|
||||
output.strip
|
||||
end
|
||||
else
|
||||
default
|
||||
end
|
||||
|
||||
@@ -73,7 +73,7 @@ class zulip::app_frontend_base {
|
||||
# multiprocess. Multiprocess scales much better, but requires more
|
||||
# RAM; we just auto-detect based on available system RAM.
|
||||
$queues_multiprocess_default = $zulip::common::total_memory_mb > 3500
|
||||
$queues_multiprocess = Boolean(zulipconf('application_server', 'queue_workers_multiprocess', $queues_multiprocess_default))
|
||||
$queues_multiprocess = zulipconf('application_server', 'queue_workers_multiprocess', $queues_multiprocess_default)
|
||||
$queues = [
|
||||
'deferred_work',
|
||||
'digest_emails',
|
||||
@@ -96,8 +96,14 @@ class zulip::app_frontend_base {
|
||||
$uwsgi_default_processes = 4
|
||||
}
|
||||
$tornado_ports = $zulip::tornado_sharding::tornado_ports
|
||||
$proxy_host = zulipconf('http_proxy', 'host', '')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '')
|
||||
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
|
||||
if ($proxy_host in ['localhost', '127.0.0.1', '::1']) and ($proxy_port == '4750') {
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
|
||||
@@ -1,22 +1,57 @@
|
||||
class zulip::camo {
|
||||
$camo_packages = [# Needed for camo
|
||||
'nodejs',
|
||||
'camo',
|
||||
]
|
||||
package { $camo_packages: ensure => 'installed' }
|
||||
class zulip::camo (String $listen_address = '0.0.0.0') {
|
||||
# TODO/compatibility: Removed 2021-11 in version 5.0; these lines
|
||||
# can be removed once one must have upgraded through Zulip 5.0 or
|
||||
# higher to get to the next release.
|
||||
package { 'camo':
|
||||
ensure => 'purged',
|
||||
}
|
||||
|
||||
$camo_key = zulipsecret('secrets', 'camo_key', '')
|
||||
$version = $zulip::common::versions['go-camo']['version']
|
||||
$goversion = $zulip::common::versions['go-camo']['goversion']
|
||||
$dir = "/srv/zulip-go-camo-${version}"
|
||||
$bin = "${dir}/bin/go-camo"
|
||||
|
||||
file { '/etc/default/camo':
|
||||
zulip::external_dep { 'go-camo':
|
||||
version => $version,
|
||||
url => "https://github.com/cactus/go-camo/releases/download/v${version}/go-camo-${version}.go${goversion}.linux-${zulip::common::goarch}.tar.gz",
|
||||
tarball_prefix => "go-camo-${version}",
|
||||
}
|
||||
|
||||
# We would like to not waste resources by going through Smokescreen,
|
||||
# as go-camo already prohibits private-IP access; but a
|
||||
# non-Smokescreen exit proxy may be required to access the public
|
||||
# Internet. The `enable_for_camo` flag, if it exists, can override
|
||||
# our guess, in either direction.
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
$proxy_is_smokescreen = ($proxy_host in ['localhost', '127.0.0.1', '::1']) and ($proxy_port == '4750')
|
||||
$camo_use_proxy = zulipconf('http_proxy', 'enable_for_camo', !$proxy_is_smokescreen)
|
||||
if $camo_use_proxy {
|
||||
if $proxy_is_smokescreen {
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
|
||||
file { "${zulip::common::supervisor_conf_dir}/go-camo.conf":
|
||||
ensure => file,
|
||||
require => Package[camo],
|
||||
require => [
|
||||
Package['camo'],
|
||||
Package[supervisor],
|
||||
Zulip::External_Dep['go-camo'],
|
||||
File['/usr/local/bin/secret-env-wrapper'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/camo_defaults.template.erb'),
|
||||
notify => Service[camo],
|
||||
}
|
||||
service { 'camo':
|
||||
ensure => running,
|
||||
content => template('zulip/supervisor/go-camo.conf.erb'),
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class zulip::common {
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877086
|
||||
# "restart" is actually "stop" under sysvinit
|
||||
$supervisor_reload = '/etc/init.d/supervisor restart && (/etc/init.d/supervisor start || /bin/true) && /etc/init.d/supervisor status'
|
||||
$supervisor_status = '/etc/init.d/supervisor status'
|
||||
}
|
||||
'redhat': {
|
||||
$nagios_plugins = 'nagios-plugins'
|
||||
@@ -22,6 +23,7 @@ class zulip::common {
|
||||
$supervisor_service = 'supervisord'
|
||||
$supervisor_start = 'systemctl start supervisord'
|
||||
$supervisor_reload = 'systemctl reload supervisord'
|
||||
$supervisor_status = 'systemctl status supervisord'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
@@ -30,4 +32,46 @@ class zulip::common {
|
||||
$supervisor_conf_dir = "${supervisor_system_conf_dir}/zulip"
|
||||
|
||||
$total_memory_mb = Integer($::memorysize_mb)
|
||||
|
||||
$goarch = $::architecture ? {
|
||||
'amd64' => 'amd64',
|
||||
'aarch64' => 'arm64',
|
||||
}
|
||||
|
||||
$versions = {
|
||||
# https://github.com/cactus/go-camo/releases
|
||||
'go-camo' => {
|
||||
'version' => '2.3.0',
|
||||
'goversion' => '1171',
|
||||
'sha256' => {
|
||||
'amd64' => '965506e6edb9d974c810519d71e847afb7ca69d1d01ae7d8be6d7a91de669c0c',
|
||||
'aarch64' => '40463f6790eb0d2da69ad6a902fcc4c6b0c0ac24106a6c28fbfce9dfa4cb15cd',
|
||||
},
|
||||
},
|
||||
|
||||
# https://go.dev/dl/
|
||||
'golang' => {
|
||||
'version' => '1.17.3',
|
||||
'sha256' => {
|
||||
'amd64' => '550f9845451c0c94be679faf116291e7807a8d78b43149f9506c1b15eb89008c',
|
||||
'aarch64' => '06f505c8d27203f78706ad04e47050b49092f1b06dc9ac4fbee4f0e4d015c8d4',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/stripe/smokescreen/tags
|
||||
'smokescreen-src' => {
|
||||
'version' => 'dc403015f563eadc556a61870c6ad327688abe88',
|
||||
# Source code, so arch-invariant sha256
|
||||
'sha256' => 'ad4b181d14adcd9425045152b903a343dbbcfcad3c1e7625d2c65d1d50e1959d',
|
||||
},
|
||||
|
||||
# https://github.com/wal-g/wal-g/releases
|
||||
'wal-g' => {
|
||||
'version' => '1.1.1-rc',
|
||||
'sha256' => {
|
||||
'amd64' => 'eed4de63c2657add6e0fe70f8c0fbe62a4a54405b9bfc801b1912b6c4f2c7107',
|
||||
# No aarch64 builds
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
45
puppet/zulip/manifests/external_dep.pp
Normal file
45
puppet/zulip/manifests/external_dep.pp
Normal file
@@ -0,0 +1,45 @@
|
||||
define zulip::external_dep(
|
||||
String $version,
|
||||
String $url,
|
||||
String $tarball_prefix,
|
||||
String $sha256 = '',
|
||||
) {
|
||||
if $sha256 == '' {
|
||||
if $zulip::common::versions[$title]['sha256'] =~ Hash {
|
||||
$sha256_filled = $zulip::common::versions[$title]['sha256'][$::architecture]
|
||||
if $sha256_filled == undef {
|
||||
err("No sha256 found for ${title} for architecture ${::architecture}")
|
||||
fail()
|
||||
}
|
||||
} else {
|
||||
# For things like source code which are arch-invariant
|
||||
$sha256_filled = $zulip::common::versions[$title]['sha256']
|
||||
}
|
||||
} else {
|
||||
$sha256_filled = $sha256
|
||||
}
|
||||
|
||||
$dir = "/srv/zulip-${title}-${version}"
|
||||
|
||||
zulip::sha256_tarball_to { $title:
|
||||
url => $url,
|
||||
sha256 => $sha256_filled,
|
||||
install => {
|
||||
$tarball_prefix => $dir,
|
||||
},
|
||||
}
|
||||
|
||||
unless $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '18.04' {
|
||||
# Puppet 5.5.0 and below make this always-noisy, as they spout out
|
||||
# a notify line about tidying the managed directory above. Skip
|
||||
# on Bionic, which has that old version; they'll get tidied upon
|
||||
# upgrade to 20.04.
|
||||
tidy { "/srv/zulip-${title}-*":
|
||||
path => '/srv/',
|
||||
recurse => 1,
|
||||
rmdirs => true,
|
||||
matches => "zulip-${title}-*",
|
||||
require => Zulip::Sha256_Tarball_To[$title],
|
||||
}
|
||||
}
|
||||
}
|
||||
13
puppet/zulip/manifests/golang.pp
Normal file
13
puppet/zulip/manifests/golang.pp
Normal file
@@ -0,0 +1,13 @@
|
||||
# @summary go compiler and tools
|
||||
#
|
||||
class zulip::golang {
|
||||
$version = $zulip::common::versions['golang']['version']
|
||||
$dir = "/srv/zulip-golang-${version}"
|
||||
$bin = "${dir}/bin/go"
|
||||
|
||||
zulip::external_dep { 'golang':
|
||||
version => $version,
|
||||
url => "https://golang.org/dl/go${version}.linux-${zulip::common::goarch}.tar.gz",
|
||||
tarball_prefix => 'go',
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
class zulip::localhost_camo {
|
||||
include zulip::camo
|
||||
class { 'zulip::camo':
|
||||
listen_address => '127.0.0.1',
|
||||
}
|
||||
|
||||
# Install nginx configuration to run camo locally
|
||||
file { '/etc/nginx/zulip-include/app.d/camo.conf':
|
||||
|
||||
@@ -124,14 +124,9 @@ class zulip::nginx {
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/logrotate/nginx',
|
||||
}
|
||||
|
||||
$certbot_auto_renew = zulipconf('certbot', 'auto_renew', '')
|
||||
if $certbot_auto_renew == 'yes' {
|
||||
package { 'certbot':
|
||||
ensure => 'installed',
|
||||
}
|
||||
package { 'certbot':
|
||||
ensure => 'installed',
|
||||
}
|
||||
|
||||
file { ['/var/lib/zulip', '/var/lib/zulip/certbot-webroot']:
|
||||
ensure => 'directory',
|
||||
owner => 'zulip',
|
||||
|
||||
@@ -3,17 +3,28 @@
|
||||
class zulip::postgresql_backups {
|
||||
include zulip::postgresql_common
|
||||
|
||||
$wal_g_version = '0.2.15'
|
||||
zulip::sha256_tarball_to { 'wal-g':
|
||||
url => "https://github.com/wal-g/wal-g/releases/download/v${wal_g_version}/wal-g.linux-amd64.tar.gz",
|
||||
sha256 => 'ea33c2341d7bfb203c6948590c29834c013ab06a28c7a2b236a73d906f785c84',
|
||||
install => {
|
||||
'wal-g' => "/usr/local/bin/wal-g-${wal_g_version}",
|
||||
},
|
||||
$wal_g_version = $zulip::common::versions['wal-g']['version']
|
||||
$bin = "/srv/zulip-wal-g-${wal_g_version}"
|
||||
$package = "wal-g-pg-ubuntu-20.04-${zulip::common::goarch}"
|
||||
|
||||
# This tarball contains only a single file
|
||||
zulip::external_dep { 'wal-g':
|
||||
version => $wal_g_version,
|
||||
url => "https://github.com/wal-g/wal-g/releases/download/v${wal_g_version}/${package}.tar.gz",
|
||||
tarball_prefix => $package,
|
||||
}
|
||||
file { '/usr/local/bin/wal-g':
|
||||
ensure => 'link',
|
||||
target => "/usr/local/bin/wal-g-${wal_g_version}",
|
||||
ensure => 'link',
|
||||
target => $bin,
|
||||
require => Zulip::External_Dep['wal-g'],
|
||||
}
|
||||
# We used to install versions into /usr/local/bin/wal-g-VERSION,
|
||||
# until we moved to using Zulip::External_Dep which places them in
|
||||
# /srv/zulip-wal-g-VERSION. Tidy old versions.
|
||||
tidy { '/usr/local/bin/wal-g-*':
|
||||
recurse => 1,
|
||||
path => '/usr/local/bin/',
|
||||
matches => 'wal-g-*',
|
||||
}
|
||||
file { '/usr/local/bin/env-wal-g':
|
||||
ensure => file,
|
||||
|
||||
@@ -38,13 +38,32 @@ class zulip::profile::app_frontend {
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
# Trigger 2x a day certbot renew
|
||||
# We used to install a cron job, but certbot now has a systemd cron
|
||||
# that does better. This can be removed once upgrading from 5.0 is
|
||||
# no longer possible.
|
||||
file { '/etc/cron.d/certbot-renew':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/cron.d/certbot-renew',
|
||||
ensure => absent,
|
||||
}
|
||||
|
||||
# Reload nginx after deploying a new cert.
|
||||
file { ['/etc/letsencrypt/renewal-hooks', '/etc/letsencrypt/renewal-hooks/deploy']:
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
require => Package[certbot],
|
||||
}
|
||||
file { '/etc/letsencrypt/renewal-hooks/deploy/001-nginx.sh':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/letsencrypt/nginx-deploy-hook.sh',
|
||||
require => Package[certbot],
|
||||
}
|
||||
exec { 'fix-standalone-certbot':
|
||||
onlyif => 'test -d /etc/letsencrypt/renewal && grep -qx "authenticator = standalone" /etc/letsencrypt/renewal/*.conf',
|
||||
command => "${::zulip_scripts_path}/lib/fix-standalone-certbot",
|
||||
}
|
||||
|
||||
# Restart the server regularly to avoid potential memory leak problems.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
class zulip::profile::docker {
|
||||
include zulip::profile::base
|
||||
include zulip::profile::app_frontend
|
||||
include zulip::localhost_camo
|
||||
include zulip::supervisor
|
||||
include zulip::process_fts_updates
|
||||
|
||||
|
||||
@@ -8,50 +8,56 @@ class zulip::profile::rabbitmq {
|
||||
$erlang,
|
||||
'rabbitmq-server',
|
||||
]
|
||||
package { $rabbitmq_packages: ensure => 'installed' }
|
||||
|
||||
# Removed 2020-09 in version 4.0; these lines can be removed in
|
||||
# Zulip version 5.0 and later.
|
||||
file { ['/etc/cron.d/rabbitmq-queuesize', '/etc/cron.d/rabbitmq-numconsumers']:
|
||||
ensure => absent,
|
||||
}
|
||||
|
||||
file { '/etc/default/rabbitmq-server':
|
||||
ensure => file,
|
||||
require => Package[rabbitmq-server],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq-server',
|
||||
file { '/etc/rabbitmq':
|
||||
ensure => 'directory',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
before => Package['rabbitmq-server'],
|
||||
}
|
||||
|
||||
file { '/etc/rabbitmq/rabbitmq.config':
|
||||
ensure => file,
|
||||
require => Package[rabbitmq-server],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq.config',
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq.config',
|
||||
# This config file must be installed before the package, so that
|
||||
# port 25672 is not even briefly open to the Internet world, which
|
||||
# would be a security risk, due to insecure defaults in the
|
||||
# RabbitMQ package.
|
||||
before => Package['rabbitmq-server'],
|
||||
notify => Service['rabbitmq-server'],
|
||||
}
|
||||
|
||||
$rabbitmq_nodename = zulipconf('rabbitmq', 'nodename', '')
|
||||
if $rabbitmq_nodename != '' {
|
||||
file { '/etc/rabbitmq':
|
||||
ensure => 'directory',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
}
|
||||
|
||||
file { '/etc/rabbitmq/rabbitmq-env.conf':
|
||||
ensure => file,
|
||||
require => File['/etc/rabbitmq'],
|
||||
before => [Package[rabbitmq-server], Service[rabbitmq-server]],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/rabbitmq-env.conf.template.erb'),
|
||||
}
|
||||
exec { 'warn-rabbitmq-nodename-change':
|
||||
command => "${::zulip_scripts_path}/lib/warn-rabbitmq-nodename-change",
|
||||
onlyif => '[ -f /etc/rabbitmq/rabbitmq-env.conf ] && ! grep -xq NODENAME=zulip@localhost /etc/rabbitmq/rabbitmq-env.conf',
|
||||
before => [
|
||||
File['/etc/rabbitmq/rabbitmq-env.conf'],
|
||||
Service['rabbitmq-server'],
|
||||
],
|
||||
logoutput => true,
|
||||
loglevel => 'warning',
|
||||
}
|
||||
file { '/etc/rabbitmq/rabbitmq-env.conf':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq-env.conf',
|
||||
before => Package['rabbitmq-server'],
|
||||
notify => [
|
||||
Service['rabbitmq-server'],
|
||||
Exec['configure-rabbitmq'],
|
||||
],
|
||||
}
|
||||
package { $rabbitmq_packages:
|
||||
ensure => 'installed',
|
||||
}
|
||||
# epmd doesn't have an init script, so we just check if it is
|
||||
# running, and if it isn't, start it. Even in case of a race, this
|
||||
@@ -66,10 +72,15 @@ class zulip::profile::rabbitmq {
|
||||
|
||||
service { 'rabbitmq-server':
|
||||
ensure => running,
|
||||
require => [Exec['epmd'],
|
||||
File['/etc/rabbitmq/rabbitmq.config'],
|
||||
File['/etc/default/rabbitmq-server']],
|
||||
require => [
|
||||
Exec['epmd'],
|
||||
Package['rabbitmq-server'],
|
||||
],
|
||||
}
|
||||
|
||||
# TODO: Should also call exactly once "configure-rabbitmq"
|
||||
exec { 'configure-rabbitmq':
|
||||
command => "${::zulip_scripts_path}/setup/configure-rabbitmq",
|
||||
refreshonly => true,
|
||||
require => Service['rabbitmq-server'],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,62 +2,5 @@
|
||||
#
|
||||
class zulip::profile::smokescreen {
|
||||
include zulip::profile::base
|
||||
include zulip::supervisor
|
||||
|
||||
$golang_version = '1.16.4'
|
||||
zulip::sha256_tarball_to { 'golang':
|
||||
url => "https://golang.org/dl/go${golang_version}.linux-amd64.tar.gz",
|
||||
sha256 => '7154e88f5a8047aad4b80ebace58a059e36e7e2e4eb3b383127a28c711b4ff59',
|
||||
install => {
|
||||
'go/' => "/srv/golang-${golang_version}/",
|
||||
},
|
||||
}
|
||||
file { '/srv/golang':
|
||||
ensure => 'link',
|
||||
target => "/srv/golang-${golang_version}/",
|
||||
require => Zulip::Sha256_tarball_to['golang'],
|
||||
}
|
||||
|
||||
$version = 'bfca45c5e61f3587eaaf1dcc89a0c4116501cba3'
|
||||
zulip::sha256_tarball_to { 'smokescreen':
|
||||
url => "https://github.com/stripe/smokescreen/archive/${version}.tar.gz",
|
||||
sha256 => '7aa2719abd282930b01394e5e748885a8e8cb8121fe97a15446f93623ec13f59',
|
||||
install => {
|
||||
"smokescreen-${version}/" => "/srv/smokescreen-src-${version}/",
|
||||
},
|
||||
}
|
||||
exec { 'compile smokescreen':
|
||||
command => "/srv/golang/bin/go build -o /usr/local/bin/smokescreen-${version}",
|
||||
cwd => "/srv/smokescreen-src-${version}/",
|
||||
# GOCACHE is required; nothing is written to GOPATH, but it is required to be set
|
||||
environment => ['GOCACHE=/tmp/gocache', 'GOPATH=/root/go'],
|
||||
creates => "/usr/local/bin/smokescreen-${version}",
|
||||
require => [Zulip::Sha256_tarball_to['golang'], Zulip::Sha256_tarball_to['smokescreen']],
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/smokescreen':
|
||||
ensure => 'link',
|
||||
target => "/usr/local/bin/smokescreen-${version}",
|
||||
require => Exec['compile smokescreen'],
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
|
||||
$listen_address = zulipconf('http_proxy', 'listen_address', '127.0.0.1')
|
||||
file { '/etc/supervisor/conf.d/zulip/smokescreen.conf':
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[supervisor],
|
||||
File['/usr/local/bin/smokescreen'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/smokescreen.conf.erb'),
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
# Removed 2021-03 in version 4.0; these lines can be removed in
|
||||
# Zulip version 5.0 and later.
|
||||
file { '/etc/supervisor/conf.d/smokescreen.conf':
|
||||
ensure => absent,
|
||||
}
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
@@ -13,10 +13,6 @@ class zulip::profile::standalone {
|
||||
include zulip::profile::redis
|
||||
include zulip::profile::memcached
|
||||
include zulip::profile::rabbitmq
|
||||
if $::osfamily == debian {
|
||||
# camo is only required on Debian-based systems as part of
|
||||
# our migration towards not including camo at all.
|
||||
include zulip::localhost_camo
|
||||
}
|
||||
include zulip::localhost_camo
|
||||
include zulip::static_asset_compiler
|
||||
}
|
||||
|
||||
57
puppet/zulip/manifests/smokescreen.pp
Normal file
57
puppet/zulip/manifests/smokescreen.pp
Normal file
@@ -0,0 +1,57 @@
|
||||
class zulip::smokescreen {
|
||||
include zulip::supervisor
|
||||
include zulip::golang
|
||||
|
||||
$version = $zulip::common::versions['smokescreen-src']['version']
|
||||
$dir = "/srv/zulip-smokescreen-src-${version}"
|
||||
$bin = "/usr/local/bin/smokescreen-${version}-go-${zulip::golang::version}"
|
||||
|
||||
zulip::external_dep { 'smokescreen-src':
|
||||
version => $version,
|
||||
url => "https://github.com/stripe/smokescreen/archive/${version}.tar.gz",
|
||||
tarball_prefix => "smokescreen-${version}",
|
||||
}
|
||||
|
||||
exec { 'compile smokescreen':
|
||||
command => "${zulip::golang::bin} build -o ${bin}",
|
||||
cwd => $dir,
|
||||
# GOCACHE is required; nothing is written to GOPATH, but it is required to be set
|
||||
environment => ['GOCACHE=/tmp/gocache', 'GOPATH=/root/go'],
|
||||
creates => $bin,
|
||||
require => [
|
||||
Zulip::External_Dep['golang'],
|
||||
Zulip::External_Dep['smokescreen-src'],
|
||||
],
|
||||
}
|
||||
unless $::operatingsystem == 'Ubuntu' and $::operatingsystemrelease == '18.04' {
|
||||
# Puppet 5.5.0 and below make this always-noisy, as they spout out
|
||||
# a notify line about tidying the managed file above. Skip
|
||||
# on Bionic, which has that old version; they'll get tidied upon
|
||||
# upgrade to 20.04.
|
||||
tidy { '/usr/local/bin/smokescreen-*':
|
||||
path => '/usr/local/bin',
|
||||
recurse => 1,
|
||||
matches => 'smokescreen-*',
|
||||
require => Exec['compile smokescreen'],
|
||||
}
|
||||
}
|
||||
|
||||
$listen_address = zulipconf('http_proxy', 'listen_address', '127.0.0.1')
|
||||
file { '/etc/supervisor/conf.d/zulip/smokescreen.conf':
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[supervisor],
|
||||
Exec['compile smokescreen'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/smokescreen.conf.erb'),
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
# Removed 2021-03 in version 4.0; these lines can be removed in
|
||||
# Zulip version 5.0 and later.
|
||||
file { '/etc/supervisor/conf.d/smokescreen.conf':
|
||||
ensure => absent,
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class zulip::supervisor {
|
||||
Package['supervisor'],
|
||||
],
|
||||
hasstatus => true,
|
||||
status => 'supervisorctl status',
|
||||
status => $zulip::common::supervisor_status,
|
||||
# Restarting the whole supervisorctl on every update to its
|
||||
# configuration files has the unfortunate side-effect of
|
||||
# restarting all of the services it controls; this results in an
|
||||
@@ -107,4 +107,12 @@ class zulip::supervisor {
|
||||
content => template('zulip/supervisor/supervisord.conf.erb'),
|
||||
notify => Exec['supervisor-restart'],
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/secret-env-wrapper':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/secret-env-wrapper',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ENABLED=yes
|
||||
PORT=9292
|
||||
CAMO_KEY=<%= scope["zulip::camo::camo_key"] %>
|
||||
9
puppet/zulip/templates/supervisor/go-camo.conf.erb
Normal file
9
puppet/zulip/templates/supervisor/go-camo.conf.erb
Normal file
@@ -0,0 +1,9 @@
|
||||
[program:go-camo]
|
||||
command=/usr/local/bin/secret-env-wrapper GOCAMO_HMAC=camo_key <%= @bin %> --listen=<%= @listen_address %>:9292 -H "Strict-Transport-Security: max-age=15768000" -H "X-Frame-Options: DENY" --verbose
|
||||
environment=HTTP_PROXY="<%= @proxy %>",HTTPS_PROXY="<%= @proxy %>"
|
||||
priority=15
|
||||
autostart=true
|
||||
autorestart=true
|
||||
user=zulip
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/var/log/zulip/camo.log
|
||||
@@ -1,5 +1,5 @@
|
||||
[program:smokescreen]
|
||||
command=/usr/local/bin/smokescreen-<%= @version %> --listen-ip <%= @listen_address %>
|
||||
command=<%= @bin %> --listen-ip <%= @listen_address %>
|
||||
priority=15
|
||||
autostart=true
|
||||
autorestart=true
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
* * * * * root /bin/bash -c '(pgrep -u nobody -F /var/run/camo.pid || /etc/init.d/camo restart) 2>&1 >>/var/log/camo/restart-log'
|
||||
@@ -1,6 +1,7 @@
|
||||
class zulip_ops::apt_repository_debathena {
|
||||
$setup_file = "${::zulip_scripts_path}/lib/setup-apt-repo-debathena"
|
||||
$setup_apt_repo_file = "${::zulip_scripts_path}/lib/setup-apt-repo"
|
||||
exec { 'setup_apt_repo_debathena':
|
||||
command => "bash -c '${setup_file}'",
|
||||
command => "${setup_apt_repo_file} --list zulip_debathena",
|
||||
unless => "${setup_apt_repo_file} --list zulip_debathena --verify",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
class zulip_ops::camo {
|
||||
include zulip::camo
|
||||
|
||||
file { '/etc/cron.d/camo':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip_ops/cron.d/camo',
|
||||
class { 'zulip::camo':
|
||||
listen_address => '0.0.0.0',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ class zulip_ops::ksplice_uptrack {
|
||||
mode => '0640',
|
||||
content => template('zulip_ops/uptrack/uptrack.conf.erb'),
|
||||
}
|
||||
$setup_apt_repo_file = "${::zulip_scripts_path}/lib/setup-apt-repo-ksplice"
|
||||
$setup_apt_repo_file = "${::zulip_scripts_path}/lib/setup-apt-repo"
|
||||
exec{ 'setup-apt-repo-ksplice':
|
||||
command => $setup_apt_repo_file,
|
||||
unless => "${setup_apt_repo_file} --verify",
|
||||
command => "${setup_apt_repo_file} --list ksplice",
|
||||
unless => "${setup_apt_repo_file} --list ksplice --verify",
|
||||
}
|
||||
Package { 'uptrack':
|
||||
require => [
|
||||
|
||||
@@ -12,7 +12,7 @@ typing-extensions
|
||||
dataclasses;python_version<"3.7"
|
||||
|
||||
# Needed for rendering backend templates
|
||||
Jinja2
|
||||
Jinja2<3.0.0
|
||||
|
||||
# Needed for Markdown processing
|
||||
Markdown
|
||||
@@ -61,7 +61,7 @@ html2text
|
||||
https://github.com/zulip/talon/archive/1711705c952806d4a704c7dbf58f21db8e11756a.zip#egg=talon-core==1.4.8.zulip1&subdirectory=talon-core
|
||||
|
||||
# Needed for inlining the CSS in emails
|
||||
premailer
|
||||
premailer<3.9.0
|
||||
|
||||
# Needed for JWT-based auth
|
||||
PyJWT
|
||||
@@ -132,7 +132,7 @@ https://github.com/zulip/python-zulip-api/archive/4d482e0ef30297f716885fd8246f46
|
||||
py3dns
|
||||
|
||||
# Install Python Social Auth
|
||||
social-auth-app-django
|
||||
social-auth-app-django<5.0.0
|
||||
social-auth-core[azuread,saml]<4.0.3 # 4.0.3 needs PyJWT 2: https://github.com/Pr0Ger/PyAPNs2/pull/122, https://github.com/twilio/twilio-python/issues/556
|
||||
|
||||
# For encrypting a login token to the desktop app
|
||||
@@ -143,6 +143,7 @@ lxml
|
||||
|
||||
# Needed for 2-factor authentication
|
||||
django-two-factor-auth[call,phonenumberslite,sms]
|
||||
twilio<7.0.0
|
||||
|
||||
# Needed for processing payments (in corporate)
|
||||
stripe
|
||||
@@ -171,7 +172,7 @@ requests[security]
|
||||
requests-oauthlib
|
||||
|
||||
# For OpenAPI schema validation.
|
||||
openapi-core<0.14.0 # https://github.com/p1c2u/openapi-core/issues/322
|
||||
openapi-core
|
||||
|
||||
# For reporting errors to sentry.io
|
||||
sentry-sdk
|
||||
@@ -187,3 +188,6 @@ backoff
|
||||
|
||||
# Non-backtracking regular expressions
|
||||
google-re2
|
||||
|
||||
# CSS manipulation
|
||||
soupsieve
|
||||
|
||||
@@ -27,7 +27,7 @@ responses
|
||||
isort
|
||||
|
||||
# For doing highly usable Python profiling
|
||||
line-profiler<3.2 # https://github.com/pyutils/line_profiler/issues/77
|
||||
line-profiler
|
||||
|
||||
# for pep8 linter
|
||||
pycodestyle
|
||||
@@ -54,10 +54,10 @@ snakeviz
|
||||
python-digitalocean
|
||||
|
||||
# Needed for updating the locked pip dependencies
|
||||
pip-tools
|
||||
pip-tools<6.3.0 # https://github.com/jazzband/pip-tools/pull/1455 breaks our hack for installing specific commits from Git
|
||||
|
||||
# zulip's linting framework - zulint
|
||||
https://github.com/zulip/zulint/archive/6cc46d23906757895e917cc75e231f81f824a31d.zip#egg=zulint==0.0.1
|
||||
https://github.com/zulip/zulint/archive/9908540b7734b51f86ccabab706befc2ff33212a.zip#egg=zulint==0.0.1
|
||||
|
||||
-r mypy.in
|
||||
|
||||
@@ -70,10 +70,10 @@ importlib-metadata;python_version<"3.8" # for jsonpickle, jsonschema
|
||||
cairosvg
|
||||
|
||||
# Needed for tools/check-thirdparty
|
||||
python-debian
|
||||
python-debian<0.1.42 # https://bugs.debian.org/997857
|
||||
|
||||
# Pattern-based lint tool
|
||||
semgrep
|
||||
semgrep<0.53.0
|
||||
|
||||
# Contains Pysa, a security-focused static analyzer
|
||||
pyre-check
|
||||
|
||||
1611
requirements/dev.txt
1611
requirements/dev.txt
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
# See requirements/README.md for more detail.
|
||||
|
||||
# Needed to build RTD docs
|
||||
sphinx
|
||||
sphinx<4.0.0
|
||||
sphinx-rtd-theme
|
||||
|
||||
# Needed to build Markdown docs
|
||||
|
||||
@@ -19,13 +19,13 @@ babel==2.9.1 \
|
||||
--hash=sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9 \
|
||||
--hash=sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0
|
||||
# via sphinx
|
||||
certifi==2020.12.5 \
|
||||
--hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c \
|
||||
--hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830
|
||||
certifi==2021.10.8 \
|
||||
--hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
|
||||
--hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
|
||||
# via requests
|
||||
chardet==4.0.0 \
|
||||
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
|
||||
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
|
||||
charset-normalizer==2.0.7 \
|
||||
--hash=sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0 \
|
||||
--hash=sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b
|
||||
# via requests
|
||||
docutils==0.16 \
|
||||
--hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
|
||||
@@ -34,9 +34,9 @@ docutils==0.16 \
|
||||
# myst-parser
|
||||
# sphinx
|
||||
# sphinx-rtd-theme
|
||||
idna==2.10 \
|
||||
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
|
||||
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
|
||||
idna==3.3 \
|
||||
--hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
|
||||
--hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
|
||||
# via requests
|
||||
imagesize==1.2.0 \
|
||||
--hash=sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1 \
|
||||
@@ -54,127 +54,144 @@ markdown-it-py==1.1.0 \
|
||||
# via
|
||||
# mdit-py-plugins
|
||||
# myst-parser
|
||||
markupsafe==1.1.1 \
|
||||
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
||||
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
||||
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
||||
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
||||
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
||||
--hash=sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f \
|
||||
--hash=sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39 \
|
||||
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
||||
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b \
|
||||
--hash=sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014 \
|
||||
--hash=sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f \
|
||||
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
||||
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
||||
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
||||
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
||||
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
||||
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
||||
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
||||
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
||||
--hash=sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85 \
|
||||
--hash=sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1 \
|
||||
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
||||
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
||||
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
||||
--hash=sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850 \
|
||||
--hash=sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0 \
|
||||
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
||||
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
||||
--hash=sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb \
|
||||
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
||||
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
||||
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
||||
--hash=sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1 \
|
||||
--hash=sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2 \
|
||||
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
||||
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
||||
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
||||
--hash=sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7 \
|
||||
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
||||
--hash=sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8 \
|
||||
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
||||
--hash=sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193 \
|
||||
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
||||
--hash=sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b \
|
||||
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
||||
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
||||
--hash=sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5 \
|
||||
--hash=sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c \
|
||||
--hash=sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032 \
|
||||
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
||||
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \
|
||||
--hash=sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621
|
||||
markupsafe==2.0.1 \
|
||||
--hash=sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298 \
|
||||
--hash=sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64 \
|
||||
--hash=sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b \
|
||||
--hash=sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194 \
|
||||
--hash=sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567 \
|
||||
--hash=sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff \
|
||||
--hash=sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724 \
|
||||
--hash=sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74 \
|
||||
--hash=sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646 \
|
||||
--hash=sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35 \
|
||||
--hash=sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6 \
|
||||
--hash=sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a \
|
||||
--hash=sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6 \
|
||||
--hash=sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad \
|
||||
--hash=sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26 \
|
||||
--hash=sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38 \
|
||||
--hash=sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac \
|
||||
--hash=sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7 \
|
||||
--hash=sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6 \
|
||||
--hash=sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047 \
|
||||
--hash=sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75 \
|
||||
--hash=sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f \
|
||||
--hash=sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b \
|
||||
--hash=sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135 \
|
||||
--hash=sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8 \
|
||||
--hash=sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a \
|
||||
--hash=sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a \
|
||||
--hash=sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1 \
|
||||
--hash=sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9 \
|
||||
--hash=sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864 \
|
||||
--hash=sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914 \
|
||||
--hash=sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee \
|
||||
--hash=sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f \
|
||||
--hash=sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18 \
|
||||
--hash=sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8 \
|
||||
--hash=sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2 \
|
||||
--hash=sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d \
|
||||
--hash=sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b \
|
||||
--hash=sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b \
|
||||
--hash=sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86 \
|
||||
--hash=sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6 \
|
||||
--hash=sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f \
|
||||
--hash=sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb \
|
||||
--hash=sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833 \
|
||||
--hash=sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28 \
|
||||
--hash=sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e \
|
||||
--hash=sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415 \
|
||||
--hash=sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902 \
|
||||
--hash=sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f \
|
||||
--hash=sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d \
|
||||
--hash=sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9 \
|
||||
--hash=sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d \
|
||||
--hash=sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145 \
|
||||
--hash=sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066 \
|
||||
--hash=sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c \
|
||||
--hash=sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1 \
|
||||
--hash=sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a \
|
||||
--hash=sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207 \
|
||||
--hash=sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f \
|
||||
--hash=sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53 \
|
||||
--hash=sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd \
|
||||
--hash=sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134 \
|
||||
--hash=sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85 \
|
||||
--hash=sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9 \
|
||||
--hash=sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5 \
|
||||
--hash=sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94 \
|
||||
--hash=sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509 \
|
||||
--hash=sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51 \
|
||||
--hash=sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872
|
||||
# via jinja2
|
||||
mdit-py-plugins==0.2.8 \
|
||||
--hash=sha256:1833bf738e038e35d89cb3a07eb0d227ed647ce7dd357579b65343740c6d249c \
|
||||
--hash=sha256:5991cef645502e80a5388ec4fc20885d2313d4871e8b8e320ca2de14ac0c015f
|
||||
# via myst-parser
|
||||
myst-parser==0.15.1 \
|
||||
--hash=sha256:7c3c78a36c4bc30ce6a67933ebd800a880c8d81f1688fad5c2ebd82cddbc1603 \
|
||||
--hash=sha256:e8baa9959dac0bcf0f3ea5fc32a1a28792959471d8a8094e3ed5ee0de9733ade
|
||||
myst-parser==0.15.2 \
|
||||
--hash=sha256:40124b6f27a4c42ac7f06b385e23a9dcd03d84801e9c7130b59b3729a554b1f9 \
|
||||
--hash=sha256:f7f3b2d62db7655cde658eb5d62b2ec2a4631308137bd8d10f296a40d57bbbeb
|
||||
# via -r requirements/docs.in
|
||||
packaging==20.9 \
|
||||
--hash=sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5 \
|
||||
--hash=sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a
|
||||
packaging==21.2 \
|
||||
--hash=sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966 \
|
||||
--hash=sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0
|
||||
# via sphinx
|
||||
pygments==2.9.0 \
|
||||
--hash=sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f \
|
||||
--hash=sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e
|
||||
pygments==2.10.0 \
|
||||
--hash=sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380 \
|
||||
--hash=sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6
|
||||
# via sphinx
|
||||
pyparsing==2.4.7 \
|
||||
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \
|
||||
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b
|
||||
# via packaging
|
||||
pytz==2021.1 \
|
||||
--hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da \
|
||||
--hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798
|
||||
pytz==2021.3 \
|
||||
--hash=sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c \
|
||||
--hash=sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326
|
||||
# via babel
|
||||
pyyaml==5.4.1 \
|
||||
--hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
|
||||
--hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
|
||||
--hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
|
||||
--hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
|
||||
--hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
|
||||
--hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
|
||||
--hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
|
||||
--hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
|
||||
--hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
|
||||
--hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
|
||||
--hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e \
|
||||
--hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
|
||||
--hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
|
||||
--hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
|
||||
--hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
|
||||
--hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
|
||||
--hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
|
||||
--hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
|
||||
--hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
|
||||
--hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
|
||||
--hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
|
||||
--hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
|
||||
--hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
|
||||
--hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
|
||||
--hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
|
||||
--hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
|
||||
--hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
|
||||
--hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
|
||||
--hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0
|
||||
pyyaml==6.0 \
|
||||
--hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \
|
||||
--hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \
|
||||
--hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \
|
||||
--hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \
|
||||
--hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \
|
||||
--hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \
|
||||
--hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \
|
||||
--hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \
|
||||
--hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \
|
||||
--hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \
|
||||
--hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \
|
||||
--hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \
|
||||
--hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \
|
||||
--hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \
|
||||
--hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \
|
||||
--hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \
|
||||
--hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \
|
||||
--hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \
|
||||
--hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \
|
||||
--hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \
|
||||
--hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \
|
||||
--hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \
|
||||
--hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \
|
||||
--hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \
|
||||
--hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \
|
||||
--hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \
|
||||
--hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \
|
||||
--hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \
|
||||
--hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \
|
||||
--hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \
|
||||
--hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \
|
||||
--hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \
|
||||
--hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5
|
||||
# via myst-parser
|
||||
requests==2.25.1 \
|
||||
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
|
||||
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
|
||||
requests==2.26.0 \
|
||||
--hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
|
||||
--hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
|
||||
# via sphinx
|
||||
snowballstemmer==2.1.0 \
|
||||
--hash=sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2 \
|
||||
--hash=sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914
|
||||
# via sphinx
|
||||
sphinx-rtd-theme==0.5.2 \
|
||||
--hash=sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a \
|
||||
--hash=sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f
|
||||
# via -r requirements/docs.in
|
||||
sphinx==3.5.4 \
|
||||
--hash=sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1 \
|
||||
--hash=sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8
|
||||
@@ -182,6 +199,10 @@ sphinx==3.5.4 \
|
||||
# -r requirements/docs.in
|
||||
# myst-parser
|
||||
# sphinx-rtd-theme
|
||||
sphinx-rtd-theme==1.0.0 \
|
||||
--hash=sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8 \
|
||||
--hash=sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c
|
||||
# via -r requirements/docs.in
|
||||
sphinxcontrib-applehelp==1.0.2 \
|
||||
--hash=sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a \
|
||||
--hash=sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58
|
||||
@@ -190,9 +211,9 @@ sphinxcontrib-devhelp==1.0.2 \
|
||||
--hash=sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e \
|
||||
--hash=sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4
|
||||
# via sphinx
|
||||
sphinxcontrib-htmlhelp==1.0.3 \
|
||||
--hash=sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f \
|
||||
--hash=sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b
|
||||
sphinxcontrib-htmlhelp==2.0.0 \
|
||||
--hash=sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07 \
|
||||
--hash=sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2
|
||||
# via sphinx
|
||||
sphinxcontrib-jsmath==1.0.1 \
|
||||
--hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \
|
||||
@@ -202,22 +223,22 @@ sphinxcontrib-qthelp==1.0.3 \
|
||||
--hash=sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72 \
|
||||
--hash=sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6
|
||||
# via sphinx
|
||||
sphinxcontrib-serializinghtml==1.1.4 \
|
||||
--hash=sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc \
|
||||
--hash=sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a
|
||||
sphinxcontrib-serializinghtml==1.1.5 \
|
||||
--hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \
|
||||
--hash=sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952
|
||||
# via sphinx
|
||||
typing-extensions==3.10.0.0 \
|
||||
--hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
|
||||
--hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \
|
||||
--hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84
|
||||
typing-extensions==3.10.0.2 \
|
||||
--hash=sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e \
|
||||
--hash=sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7 \
|
||||
--hash=sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34
|
||||
# via markdown-it-py
|
||||
urllib3==1.26.4 \
|
||||
--hash=sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df \
|
||||
--hash=sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937
|
||||
urllib3==1.26.7 \
|
||||
--hash=sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece \
|
||||
--hash=sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844
|
||||
# via requests
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
setuptools==56.1.0 \
|
||||
--hash=sha256:7d9b5609ebda3db0f2e7c6d2fba807e9bd653e3a3a93ce3426b2b68260193a77 \
|
||||
--hash=sha256:9ceb15de17f8e99dd4903f88e05e04285fa60f364f67bdcc4334aa71604b7a39
|
||||
setuptools==58.4.0 \
|
||||
--hash=sha256:af632270cb4b5ca0ebd272ac1939a3e8f76aa975d2722e999cfdcea2b9e824cb \
|
||||
--hash=sha256:e8b1d3127a0441fb99a130bcc3c2bf256c2d3ead3aba8fd400e5cbbaf788e036
|
||||
# via sphinx
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# /tools/update-locked-requirements to update requirements/dev.txt
|
||||
# and requirements/mypy.txt.
|
||||
# See requirements/README.md for more detail.
|
||||
mypy
|
||||
mypy==0.812
|
||||
sqlalchemy-stubs
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#
|
||||
# For details, see requirements/README.md .
|
||||
#
|
||||
mypy-extensions==0.4.3 \
|
||||
--hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \
|
||||
--hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8
|
||||
# via mypy
|
||||
mypy==0.812 \
|
||||
--hash=sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e \
|
||||
--hash=sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064 \
|
||||
@@ -37,6 +33,10 @@ mypy==0.812 \
|
||||
# via
|
||||
# -r requirements/mypy.in
|
||||
# sqlalchemy-stubs
|
||||
mypy-extensions==0.4.3 \
|
||||
--hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \
|
||||
--hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8
|
||||
# via mypy
|
||||
sqlalchemy-stubs==0.4 \
|
||||
--hash=sha256:5eec7aa110adf9b957b631799a72fef396b23ff99fe296df726645d01e312aa5 \
|
||||
--hash=sha256:c665d6dd4482ef642f01027fa06c3d5e91befabb219dc71fc2a09e7d7695f7ae
|
||||
@@ -73,10 +73,10 @@ typed-ast==1.4.3 \
|
||||
--hash=sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f \
|
||||
--hash=sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65
|
||||
# via mypy
|
||||
typing-extensions==3.10.0.0 \
|
||||
--hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
|
||||
--hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \
|
||||
--hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84
|
||||
typing-extensions==3.10.0.2 \
|
||||
--hash=sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e \
|
||||
--hash=sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7 \
|
||||
--hash=sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34
|
||||
# via
|
||||
# mypy
|
||||
# sqlalchemy-stubs
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#
|
||||
# For details, see requirements/README.md .
|
||||
#
|
||||
wheel==0.36.2 \
|
||||
--hash=sha256:78b5b185f0e5763c26ca1e324373aadd49182ca90e825f7853f4b2509215dc0e \
|
||||
--hash=sha256:e11eefd162658ea59a60a0f6c7d493a7190ea4b9a85e335b33489d9f17e0245e
|
||||
wheel==0.37.0 \
|
||||
--hash=sha256:21014b2bd93c6d0034b6ba5d35e4eb284340e09d63c59aef6fc14b0f346146fd \
|
||||
--hash=sha256:e2ef7239991699e3355d54f8e968a21bb940a1dbf34a4d226741e64462516fad
|
||||
# via -r requirements/pip.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
@@ -17,7 +17,7 @@ pip==20.3.4 \
|
||||
--hash=sha256:217ae5161a0e08c0fb873858806e3478c9775caffce5168b50ec885e358c199d \
|
||||
--hash=sha256:6773934e5f5fc3eaa8c5a44949b5b924fc122daa0a8aa9f80c835b4ca2a543fc
|
||||
# via -r requirements/pip.in
|
||||
setuptools==56.1.0 \
|
||||
--hash=sha256:7d9b5609ebda3db0f2e7c6d2fba807e9bd653e3a3a93ce3426b2b68260193a77 \
|
||||
--hash=sha256:9ceb15de17f8e99dd4903f88e05e04285fa60f364f67bdcc4334aa71604b7a39
|
||||
setuptools==58.4.0 \
|
||||
--hash=sha256:af632270cb4b5ca0ebd272ac1939a3e8f76aa975d2722e999cfdcea2b9e824cb \
|
||||
--hash=sha256:e8b1d3127a0441fb99a130bcc3c2bf256c2d3ead3aba8fd400e5cbbaf788e036
|
||||
# via -r requirements/pip.in
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
zulip_conf_get_boolean() {
|
||||
# Get a boolean flag from zulip.conf, using the Python
|
||||
# `configparser` library's conventions for what counts as true.
|
||||
# Treat absent and invalid values as false.
|
||||
value=$(crudini --get /etc/zulip/zulip.conf "$1" "$2" 2>/dev/null)
|
||||
case "$(echo "$value" | tr '[:upper:]' '[:lower:]')" in
|
||||
1 | yes | true | on) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
if ! zulip_conf_get_boolean certbot auto_renew; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
deploy_hook="${ZULIP_CERTBOT_DEPLOY_HOOK:-service nginx reload}"
|
||||
|
||||
certbot renew --quiet \
|
||||
--webroot --webroot-path=/var/lib/zulip/certbot-webroot/ \
|
||||
--deploy-hook "$deploy_hook"
|
||||
14
scripts/lib/fix-standalone-certbot
Executable file
14
scripts/lib/fix-standalone-certbot
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
hostnames=$(grep -l 'authenticator = standalone' /etc/letsencrypt/renewal/*.conf | sed 's/.*\///; s/\.conf$//')
|
||||
|
||||
for hostname in $hostnames; do
|
||||
# Force a cert renewal to force the config file to update
|
||||
/usr/bin/certbot certonly --webroot --webroot-path=/var/lib/zulip/certbot-webroot/ --force-renewal -d "$hostname"
|
||||
done
|
||||
|
||||
# Pick up any updated certs
|
||||
service nginx reload
|
||||
@@ -318,7 +318,7 @@ fi
|
||||
# installation process more seamless.
|
||||
if [ -z "$NO_DIST_UPGRADE" ]; then
|
||||
if [ "$package_system" = apt ]; then
|
||||
apt-get -y dist-upgrade "${APT_OPTIONS[@]}"
|
||||
apt-get -y --allow-downgrades dist-upgrade "${APT_OPTIONS[@]}"
|
||||
elif [ "$package_system" = yum ]; then
|
||||
# On CentOS, there is no need to do `yum -y upgrade` because `yum -y
|
||||
# update` already does the same thing.
|
||||
@@ -353,11 +353,10 @@ elif [ "$package_system" = yum ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$USE_CERTBOT" ]; then
|
||||
"$ZULIP_PATH"/scripts/setup/setup-certbot \
|
||||
--no-zulip-conf --method=standalone \
|
||||
"$EXTERNAL_HOST" --email "$ZULIP_ADMINISTRATOR"
|
||||
elif [ -n "$SELF_SIGNED_CERT" ]; then
|
||||
# We generate a self-signed cert even with certbot, so we can use the
|
||||
# webroot authenticator, which requires nginx be set up with a
|
||||
# certificate.
|
||||
if [ -n "$SELF_SIGNED_CERT" ] || [ -n "$USE_CERTBOT" ]; then
|
||||
"$ZULIP_PATH"/scripts/setup/generate-self-signed-cert \
|
||||
--exists-ok "${EXTERNAL_HOST:-$(hostname)}"
|
||||
fi
|
||||
@@ -397,10 +396,6 @@ deploy_type = production
|
||||
version = $POSTGRESQL_VERSION
|
||||
EOF
|
||||
|
||||
if [ -n "$USE_CERTBOT" ]; then
|
||||
crudini --set /etc/zulip/zulip.conf certbot auto_renew yes
|
||||
fi
|
||||
|
||||
if [ -n "$POSTGRESQL_MISSING_DICTIONARIES" ]; then
|
||||
crudini --set /etc/zulip/zulip.conf postgresql missing_dictionaries true
|
||||
fi
|
||||
@@ -415,29 +410,6 @@ EOF
|
||||
if ! has_class "zulip::postgresql_common" || [ "$package_system" != apt ]; then
|
||||
crudini --del /etc/zulip/zulip.conf postgresql
|
||||
fi
|
||||
|
||||
# Note: there are four dpkg-query outputs to consider:
|
||||
#
|
||||
# root@host# dpkg-query --showformat '${Status}\n' -W rabbitmq-server 2>/dev/null
|
||||
# root@host# apt install rabbitmq-server
|
||||
# root@host# dpkg-query --showformat '${Status}\n' -W rabbitmq-server 2>/dev/null
|
||||
# install ok installed
|
||||
# root@host# apt remove rabbitmq-server
|
||||
# root@host# dpkg-query --showformat '${Status}\n' -W rabbitmq-server 2>/dev/null
|
||||
# deinstall ok config-files
|
||||
# root@host# apt purge rabbitmq-server
|
||||
# root@host# dpkg-query --showformat '${Status}\n' -W rabbitmq-server 2>/dev/null
|
||||
# unknown ok not-installed
|
||||
#
|
||||
# (There are more possibilities in the case of dpkg errors.) Here
|
||||
# we are checking for either empty or not-installed.
|
||||
if ! dpkg-query --showformat '${Status}\n' -W rabbitmq-server 2>/dev/null | grep -vq ' not-installed$'; then
|
||||
cat <<EOF >>/etc/zulip/zulip.conf
|
||||
|
||||
[rabbitmq]
|
||||
nodename = zulip@localhost
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
if has_class "zulip::app_frontend_base"; then
|
||||
@@ -457,12 +429,17 @@ fi
|
||||
"$ZULIP_PATH"/scripts/zulip-puppet-apply -f
|
||||
|
||||
if [ "$package_system" = apt ]; then
|
||||
apt-get -y upgrade
|
||||
apt-get -y --allow-downgrades upgrade
|
||||
elif [ "$package_system" = yum ]; then
|
||||
# No action is required because `yum update` already does upgrade.
|
||||
:
|
||||
fi
|
||||
|
||||
if [ -n "$USE_CERTBOT" ]; then
|
||||
"$ZULIP_PATH"/scripts/setup/setup-certbot \
|
||||
"$EXTERNAL_HOST" --email "$ZULIP_ADMINISTRATOR"
|
||||
fi
|
||||
|
||||
if has_class "zulip::nginx" && ! has_class "zulip::profile::docker"; then
|
||||
# Check nginx was configured properly now that we've installed it.
|
||||
# Most common failure mode is certs not having been installed.
|
||||
@@ -497,7 +474,6 @@ For more information, see:
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
"$ZULIP_PATH"/scripts/setup/configure-rabbitmq
|
||||
fi
|
||||
|
||||
if has_class "zulip::postgresql_common" && [ -z "$NO_INIT_DB" ]; then
|
||||
|
||||
@@ -1,18 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script handles adding custom apt repositories into
|
||||
# /etc/apt/sources.list.d/ files. It bundles the GPG keys which are
|
||||
# used to verify the repositories (via `apt-key`), to explicitly pin
|
||||
# the trusted signing keys, as opposed to blindly trusting HTTPS.
|
||||
#
|
||||
# Each /etc/apt/sources.list.d/foo.list file is created via `--list
|
||||
# foo`, where `foo` defaults to `zulip`. The default `zulip.list` is
|
||||
# installed in `scripts/lib/install` / `tools/lib/provision.py`, and
|
||||
# other `.list` files may be installed by Puppet.
|
||||
set -x
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
shopt -s extglob
|
||||
|
||||
verify=false
|
||||
args="$(getopt -o '' --long verify -- "$@")"
|
||||
args="$(getopt -o '' --long verify,list: -- "$@")"
|
||||
eval "set -- $args"
|
||||
LIST=zulip
|
||||
while true; do
|
||||
case "$1" in
|
||||
--verify)
|
||||
verify=true
|
||||
shift
|
||||
;;
|
||||
--list)
|
||||
LIST="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -23,12 +40,34 @@ done
|
||||
# Ensure the directory for LAST_DEPENDENCIES_HASH exists
|
||||
mkdir -p /var/lib/zulip
|
||||
|
||||
SOURCES_FILE=/etc/apt/sources.list.d/zulip.list
|
||||
STAMP_FILE=/etc/apt/sources.list.d/zulip.list.apt-update-in-progress
|
||||
SOURCES_FILE=/etc/apt/sources.list.d/$LIST.list
|
||||
PREF_FILE=/etc/apt/preferences.d/$LIST.pref
|
||||
STAMP_FILE=/etc/apt/sources.list.d/$LIST.list.apt-update-in-progress
|
||||
|
||||
ZULIP_SCRIPTS="$(dirname "$(dirname "$0")")"
|
||||
DEPENDENCIES_HASH=$(sha1sum "$ZULIP_SCRIPTS/setup/"*.asc "$0")
|
||||
DEPENDENCIES_HASH_FILE="/var/lib/zulip/setup-repositories-state"
|
||||
ZULIP_SCRIPTS="$(cd "$(dirname "$(dirname "$0")")" && pwd)"
|
||||
LIST_PATH="$ZULIP_SCRIPTS/setup/apt-repos/$LIST"
|
||||
if ! [ -d "$LIST_PATH" ]; then
|
||||
echo "Not a valid value for --list: '$LIST'"
|
||||
echo ""
|
||||
echo "Valid values are:"
|
||||
ls -1 "$ZULIP_SCRIPTS/setup/apt-repos/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release="$(. /etc/os-release && printf '%s' "$VERSION_CODENAME")"
|
||||
|
||||
if [ ! -f "$LIST_PATH/$release.list" ]; then
|
||||
cat <<EOF
|
||||
Unsupported release $release for sources.list file $LIST. To add a
|
||||
new release, make a $LIST_PATH/$release.list file based on existing
|
||||
.list files in that directory.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPENDENCIES_HASH="$(sha256sum "$LIST_PATH"/?(*.asc|"$release.list"|"$LIST.pref"|custom.sh) "$ZULIP_SCRIPTS/lib/setup-apt-repo")"
|
||||
DEPENDENCIES_HASH_FILE="/var/lib/zulip/setup-repositories-state-$LIST"
|
||||
# Ensure that DEPENDENCIES_HASH_FILE exists before hashing it.
|
||||
touch "$DEPENDENCIES_HASH_FILE"
|
||||
LAST_DEPENDENCIES_HASH="$(cat "$DEPENDENCIES_HASH_FILE")"
|
||||
@@ -41,11 +80,8 @@ elif [ "$verify" == true ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure that the sources file exists
|
||||
touch "$SOURCES_FILE"
|
||||
|
||||
# Hash it to check if the sources file is changed by the script later.
|
||||
zulip_source_hash=$(sha1sum "$SOURCES_FILE")
|
||||
# Hash to check if the configuration is changed by the script later.
|
||||
hashes=$(sha256sum "$SOURCES_FILE" "$PREF_FILE" 2>/dev/null || true)
|
||||
|
||||
pre_setup_deps=(lsb-release apt-transport-https ca-certificates gnupg wget)
|
||||
if ! apt-get -dy install "${pre_setup_deps[@]}"; then
|
||||
@@ -53,70 +89,23 @@ if ! apt-get -dy install "${pre_setup_deps[@]}"; then
|
||||
fi
|
||||
apt-get -y install "${pre_setup_deps[@]}"
|
||||
|
||||
SCRIPTS_PATH="$(cd "$(dirname "$(dirname "$0")")" && pwd)"
|
||||
apt-key add "$LIST_PATH/"*.asc
|
||||
cp "$LIST_PATH/$release.list" "$SOURCES_FILE"
|
||||
|
||||
release=$(lsb_release -sc)
|
||||
if [[ "$release" =~ ^(bionic|cosmic|disco|eoan|focal|groovy)$ ]]; then
|
||||
distribution=ubuntu
|
||||
apt-key add "$SCRIPTS_PATH"/setup/pgdg.asc
|
||||
apt-key add "$SCRIPTS_PATH"/setup/pgroonga-ppa.asc
|
||||
cat >$SOURCES_FILE <<EOF
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ $release-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ $release-pgdg main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu $release main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu $release main
|
||||
EOF
|
||||
elif [[ "$release" =~ ^(buster|bullseye)$ ]]; then
|
||||
distribution=debian
|
||||
apt-key add "$SCRIPTS_PATH"/setup/pgdg.asc
|
||||
cat >$SOURCES_FILE <<EOF
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ $release-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ $release-pgdg main
|
||||
EOF
|
||||
if [ -e "$LIST_PATH/$LIST.pref" ]; then
|
||||
cp "$LIST_PATH/$LIST.pref" "$PREF_FILE"
|
||||
else
|
||||
echo "Unsupported release $release."
|
||||
exit 1
|
||||
rm -f "$PREF_FILE"
|
||||
fi
|
||||
|
||||
if [[ ! -e /usr/share/doc/groonga-apt-source/copyright ]]; then
|
||||
remove_pgroonga_apt_tmp_dir() {
|
||||
rm -rf "$pgroonga_apt_tmp_dir"
|
||||
}
|
||||
pgroonga_apt_tmp_dir=$(mktemp --directory)
|
||||
trap remove_pgroonga_apt_tmp_dir EXIT
|
||||
pushd "$pgroonga_apt_tmp_dir"
|
||||
tmp_gpg_home=.gnupg
|
||||
pgroonga_apt_sign_key="$SCRIPTS_PATH"/setup/pgroonga-packages.groonga.org.asc
|
||||
gpg --homedir="$tmp_gpg_home" --import "$pgroonga_apt_sign_key"
|
||||
# Find fingerprint of the first key.
|
||||
pgroonga_apt_sign_key_fingerprint=$(
|
||||
gpg --homedir="$tmp_gpg_home" --with-colons --list-keys \
|
||||
| grep '^fpr:' \
|
||||
| cut --delimiter=: --fields=10 \
|
||||
| head --lines=1
|
||||
)
|
||||
groonga_apt_source_deb="groonga-apt-source-latest-$release.deb"
|
||||
groonga_apt_source_deb_sign="$groonga_apt_source_deb.asc.$pgroonga_apt_sign_key_fingerprint"
|
||||
wget "https://packages.groonga.org/$distribution/$groonga_apt_source_deb"
|
||||
wget "https://packages.groonga.org/$distribution/$groonga_apt_source_deb_sign"
|
||||
gpg \
|
||||
--homedir="$tmp_gpg_home" \
|
||||
--verify \
|
||||
"$groonga_apt_source_deb_sign" \
|
||||
"$groonga_apt_source_deb"
|
||||
# To suppress the following warning by "apt-get install":
|
||||
# N: Download is performed unsandboxed as root as file
|
||||
# '.../groonga-apt-source-latest-$release.deb' couldn't be
|
||||
# accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
|
||||
chown _apt .
|
||||
apt-get -y install "./$groonga_apt_source_deb"
|
||||
popd
|
||||
touch "$STAMP_FILE"
|
||||
if [ -e "$LIST_PATH/custom.sh" ]; then
|
||||
export LIST_PATH
|
||||
export STAMP_FILE
|
||||
bash "$LIST_PATH/custom.sh"
|
||||
fi
|
||||
|
||||
if [ "$zulip_source_hash" = "$(sha1sum "$SOURCES_FILE")" ] && ! [ -e "$STAMP_FILE" ]; then
|
||||
echo "zulip.list file did not change; skipping apt-get update"
|
||||
if [ "$hashes" = "$(sha256sum "$SOURCES_FILE" "$PREF_FILE" 2>/dev/null || true)" ] && ! [ -e "$STAMP_FILE" ]; then
|
||||
echo "APT configuration did not change; skipping apt-get update"
|
||||
else
|
||||
# We create this stamp file to ensure `apt-get update` will be run
|
||||
# the next time this script is invoked, and each time after, until
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
|
||||
# Ensure the directory for LAST_DEPENDENCIES_HASH exists
|
||||
mkdir -p /var/lib/zulip
|
||||
|
||||
SOURCES_FILE=/etc/apt/sources.list.d/zulip_debathena.list
|
||||
STAMP_FILE=/etc/apt/sources.list.d/zulip_debathena.list.apt-update-in-progress
|
||||
|
||||
ZULIP_SCRIPTS="$(dirname "$(dirname "$0")")"
|
||||
DEPENDENCIES_HASH=$(sha1sum "$ZULIP_SCRIPTS/setup/"*.asc "$0")
|
||||
DEPENDENCIES_HASH_FILE="/var/lib/zulip/setup-repositories-state-debathena"
|
||||
# Ensure that DEPENDENCIES_HASH_FILE exists before hashing it.
|
||||
touch "$DEPENDENCIES_HASH_FILE"
|
||||
LAST_DEPENDENCIES_HASH="$(cat "$DEPENDENCIES_HASH_FILE")"
|
||||
|
||||
# First, we only do anything in setup-apt-repo if any of its inputs
|
||||
# (apt keys, code, etc.) changed.
|
||||
if [ "$DEPENDENCIES_HASH" = "$LAST_DEPENDENCIES_HASH" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ensure that the sources file exists
|
||||
touch "$SOURCES_FILE"
|
||||
|
||||
# Hash it to check if the sources file is changed by the script later.
|
||||
zulip_source_hash=$(sha1sum "$SOURCES_FILE")
|
||||
|
||||
apt-get install -y lsb-release apt-transport-https gnupg
|
||||
|
||||
SCRIPTS_PATH="$(dirname "$(dirname "$0")")"
|
||||
|
||||
release=$(lsb_release -sc)
|
||||
if [ "$release" = "bionic" ]; then
|
||||
apt-key add "$SCRIPTS_PATH"/setup/debathena-archive.asc
|
||||
cat >$SOURCES_FILE <<EOF
|
||||
deb http://debathena.mit.edu/apt $release debathena debathena-config
|
||||
deb-src http://debathena.mit.edu/apt $release debathena debathena-config
|
||||
EOF
|
||||
else
|
||||
echo "Unsupported release $release."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Copied blindly from scripts/lib/setup-apt-repo
|
||||
if [ "$zulip_source_hash" = "$(sha1sum "$SOURCES_FILE")" ] && ! [ -e "$STAMP_FILE" ]; then
|
||||
echo "zulip.list file did not change; skipping apt-get update"
|
||||
else
|
||||
# We create this stamp file to ensure `apt-get update` will be run
|
||||
# the next time this script is invoked, and each time after, until
|
||||
# `apt-get update` finishes successfully.
|
||||
touch "$STAMP_FILE"
|
||||
apt-get update && rm -f "$STAMP_FILE"
|
||||
fi
|
||||
|
||||
echo "$DEPENDENCIES_HASH" >"$DEPENDENCIES_HASH_FILE"
|
||||
@@ -1,80 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
verify=false
|
||||
args="$(getopt -o '' --long verify -- "$@")"
|
||||
eval "set -- $args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
--verify)
|
||||
verify=true
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Ensure the directory for LAST_DEPENDENCIES_HASH exists
|
||||
mkdir -p /var/lib/zulip
|
||||
|
||||
SOURCES_FILE=/etc/apt/sources.list.d/ksplice.list
|
||||
STAMP_FILE=/etc/apt/sources.list.d/ksplice.list.apt-update-in-progress
|
||||
|
||||
ZULIP_SCRIPTS="$(dirname "$(dirname "$0")")"
|
||||
DEPENDENCIES_HASH=$(sha1sum "$ZULIP_SCRIPTS/setup/"*.asc "$0")
|
||||
DEPENDENCIES_HASH_FILE="/var/lib/zulip/setup-repositories-state-ksplice"
|
||||
# Ensure that DEPENDENCIES_HASH_FILE exists before hashing it.
|
||||
touch "$DEPENDENCIES_HASH_FILE"
|
||||
LAST_DEPENDENCIES_HASH="$(cat "$DEPENDENCIES_HASH_FILE")"
|
||||
|
||||
# First, we only do anything in setup-apt-repo if any of its inputs
|
||||
# (apt keys, code, etc.) changed.
|
||||
if [ "$DEPENDENCIES_HASH" = "$LAST_DEPENDENCIES_HASH" ]; then
|
||||
exit 0
|
||||
elif [ "$verify" == true ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure that the sources file exists
|
||||
touch "$SOURCES_FILE"
|
||||
|
||||
# Hash it to check if the sources file is changed by the script later.
|
||||
zulip_source_hash=$(sha1sum "$SOURCES_FILE")
|
||||
|
||||
pre_setup_deps=(lsb-release apt-transport-https ca-certificates gnupg wget)
|
||||
if ! apt-get -dy install "${pre_setup_deps[@]}"; then
|
||||
apt-get update
|
||||
fi
|
||||
apt-get -y install "${pre_setup_deps[@]}"
|
||||
|
||||
SCRIPTS_PATH="$(cd "$(dirname "$(dirname "$0")")" && pwd)"
|
||||
|
||||
release=$(lsb_release -sc)
|
||||
if [[ "$release" =~ ^(buster|bullseye|bionic|cosmic|disco|eoan|focal|groovy)$ ]]; then
|
||||
apt-key add "$SCRIPTS_PATH"/setup/ksplice.asc
|
||||
cat >$SOURCES_FILE <<EOF
|
||||
deb http://www.ksplice.com/apt $release ksplice
|
||||
deb-src http://www.ksplice.com/apt $release ksplice
|
||||
EOF
|
||||
else
|
||||
echo "Unsupported release $release."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$zulip_source_hash" = "$(sha1sum "$SOURCES_FILE")" ] && ! [ -e "$STAMP_FILE" ]; then
|
||||
echo "zulip.list file did not change; skipping apt-get update"
|
||||
else
|
||||
# We create this stamp file to ensure `apt-get update` will be run
|
||||
# the next time this script is invoked, and each time after, until
|
||||
# `apt-get update` finishes successfully.
|
||||
touch "$STAMP_FILE"
|
||||
apt-get update && rm -f "$STAMP_FILE"
|
||||
fi
|
||||
|
||||
echo "$DEPENDENCIES_HASH" >"$DEPENDENCIES_HASH_FILE"
|
||||
@@ -13,7 +13,7 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import NoReturn
|
||||
@@ -31,6 +31,7 @@ from scripts.lib.zulip_tools import (
|
||||
get_config,
|
||||
get_config_file,
|
||||
get_tornado_ports,
|
||||
listening_publicly,
|
||||
parse_os_release,
|
||||
su_to_zulip,
|
||||
)
|
||||
@@ -101,12 +102,43 @@ tornado_processes = len(get_tornado_ports(config_file))
|
||||
IS_SERVER_UP = True
|
||||
|
||||
|
||||
# Check if rabbitmq port 25672 is listening on anything except 127.0.0.1
|
||||
rabbitmq_dist_listen = listening_publicly(25672)
|
||||
# Check the erlang magic cookie size
|
||||
cookie_size: Optional[int] = None
|
||||
if os.path.exists("/var/lib/rabbitmq/.erlang.cookie"):
|
||||
with open("/var/lib/rabbitmq/.erlang.cookie", "r") as cookie_fh:
|
||||
cookie_size = len(cookie_fh.readline())
|
||||
else:
|
||||
logging.info("No RabbitMQ erlang cookie found, not auditing RabbitMQ security.")
|
||||
if args.skip_puppet and rabbitmq_dist_listen:
|
||||
logging.error(
|
||||
"RabbitMQ is publicly-accessible on %s; this is a security vulnerability!",
|
||||
", ".join(rabbitmq_dist_listen),
|
||||
)
|
||||
issue = "issue"
|
||||
if cookie_size is not None and cookie_size == 20:
|
||||
# See the below comment -- this is used as a lightweight
|
||||
# signal for a cookie made with Erlang's bad randomizer.
|
||||
logging.error(
|
||||
"RabbitMQ erlang cookie is insecure; this is a critical security vulnerability!"
|
||||
)
|
||||
issue = "issues"
|
||||
logging.error(
|
||||
f"To fix the above security {issue}, re-run the upgrade without --skip-puppet "
|
||||
"(which may be set in /etc/zulip/zulip.conf), in order to restart the "
|
||||
"necessary services. Running zulip-puppet-apply by itself is not sufficient."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def shutdown_server() -> None:
|
||||
global IS_SERVER_UP
|
||||
|
||||
logging.info("Stopping Zulip...")
|
||||
subprocess.check_call(["./scripts/stop-server"], preexec_fn=su_to_zulip)
|
||||
IS_SERVER_UP = False
|
||||
if IS_SERVER_UP:
|
||||
logging.info("Stopping Zulip...")
|
||||
subprocess.check_call(["./scripts/stop-server"], preexec_fn=su_to_zulip)
|
||||
IS_SERVER_UP = False
|
||||
|
||||
|
||||
# postgresql.version is required for database servers, but wasn't
|
||||
@@ -150,7 +182,7 @@ if glob.glob("/usr/share/postgresql/*/extension/tsearch_extras.control"):
|
||||
if not args.skip_puppet:
|
||||
logging.info("Upgrading system packages...")
|
||||
subprocess.check_call(["apt-get", "update"])
|
||||
subprocess.check_call(["apt-get", "-y", "upgrade"])
|
||||
subprocess.check_call(["apt-get", "-y", "--allow-downgrades", "upgrade"])
|
||||
|
||||
# To bootstrap zulip-puppet-apply, we need to install the system yaml
|
||||
# package; new installs get this, but old installs may not have it.
|
||||
@@ -210,8 +242,8 @@ elif args.from_git:
|
||||
# Ideally, we'd have 2 thresholds here, depending on whether the
|
||||
# system is running queue workers multithreaded or multiprocess.
|
||||
# See puppet/zulip/manifests/app_frontend_base.pp for background.
|
||||
if mem_gib < 3.8:
|
||||
logging.info("Shutting down server to build static assets on a low-RAM system.")
|
||||
if mem_gib < 4.2:
|
||||
logging.info("Shutting down server to ensure sufficient free RAM for webpack.")
|
||||
shutdown_server()
|
||||
|
||||
# Note: The fact that this is before we apply Puppet changes means
|
||||
@@ -219,7 +251,15 @@ elif args.from_git:
|
||||
# update-prod-static with the Git upgrade process. But it'll fail
|
||||
# safely; this seems like a worthwhile tradeoff to minimize downtime.
|
||||
logging.info("Building static assets...")
|
||||
subprocess.check_call(["./tools/update-prod-static"], preexec_fn=su_to_zulip)
|
||||
try:
|
||||
subprocess.check_call(["./tools/update-prod-static"], preexec_fn=su_to_zulip)
|
||||
except subprocess.CalledProcessError:
|
||||
logging.error("Failed to build static assets.")
|
||||
if IS_SERVER_UP:
|
||||
logging.error("Usually the cause is insufficient free RAM to run webpack.")
|
||||
logging.error("Try stopping the Zulip server (scripts/stop-server) and trying again.")
|
||||
sys.exit(1)
|
||||
|
||||
logging.info("Caching Zulip Git version...")
|
||||
subprocess.check_call(["./tools/cache-zulip-git-version"], preexec_fn=su_to_zulip)
|
||||
else:
|
||||
@@ -266,6 +306,21 @@ if (not args.skip_puppet or migrations_needed) and IS_SERVER_UP:
|
||||
# state.
|
||||
shutdown_server()
|
||||
|
||||
if rabbitmq_dist_listen:
|
||||
shutdown_server()
|
||||
logging.info("Shutting down rabbitmq to adjust its ports...")
|
||||
subprocess.check_call(["/usr/sbin/service", "rabbitmq-server", "stop"])
|
||||
|
||||
if cookie_size is not None and cookie_size == 20:
|
||||
# Checking for a 20-character cookie is used as a signal that it
|
||||
# was generated by Erlang's insecure randomizer, which only
|
||||
# provides between 20 and 36 bits of entropy; were it 20
|
||||
# characters long by a good randomizer, it would be 96 bits and
|
||||
# more than sufficient. We generate, using good randomness, a
|
||||
# 255-character cookie, the max allowed length.
|
||||
logging.info("Generating a secure erlang cookie...")
|
||||
subprocess.check_call(["./scripts/setup/generate-rabbitmq-cookie"])
|
||||
|
||||
# Adjust Puppet class names for the manifest renames in the 4.0 release
|
||||
class_renames = {
|
||||
"zulip::app_frontend": "zulip::profile::app_frontend",
|
||||
@@ -295,7 +350,7 @@ if classes != new_classes:
|
||||
if not args.skip_puppet:
|
||||
logging.info("Applying Puppet changes...")
|
||||
subprocess.check_call(["./scripts/zulip-puppet-apply", "--force"])
|
||||
subprocess.check_call(["apt-get", "-y", "upgrade"])
|
||||
subprocess.check_call(["apt-get", "-y", "--allow-downgrades", "upgrade"])
|
||||
|
||||
if migrations_needed:
|
||||
logging.info("Applying database migrations...")
|
||||
@@ -308,9 +363,9 @@ if IS_SERVER_UP or not args.skip_puppet:
|
||||
# Even if the server wasn't up previously, puppet might have
|
||||
# started it if there were supervisord configuration changes, so
|
||||
# we need to use restart-server if puppet ran.
|
||||
subprocess.check_output(["./scripts/restart-server", "--fill-cache"], preexec_fn=su_to_zulip)
|
||||
subprocess.check_call(["./scripts/restart-server", "--fill-cache"], preexec_fn=su_to_zulip)
|
||||
else:
|
||||
subprocess.check_output(["./scripts/start-server", "--fill-cache"], preexec_fn=su_to_zulip)
|
||||
subprocess.check_call(["./scripts/start-server", "--fill-cache"], preexec_fn=su_to_zulip)
|
||||
|
||||
logging.info("Upgrade complete!")
|
||||
|
||||
|
||||
29
scripts/lib/warn-rabbitmq-nodename-change
Executable file
29
scripts/lib/warn-rabbitmq-nodename-change
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# For security reasons, we need to configure RabbitMQ to listen only
|
||||
# on localhost, which we cannot do if the nodename contains the
|
||||
# hostname (e.g. rabbit@zulip-host). Containing the hostname also
|
||||
# makes it brittle to hostname changes, which are (for example) common
|
||||
# in containerized environments.
|
||||
|
||||
set -eu
|
||||
|
||||
# Try to find the current nodename
|
||||
CURRENT=$(sh -c 'cd /usr/lib/rabbitmq/bin/ && . ./rabbitmq-env && echo $NODENAME')
|
||||
if [ "$CURRENT" != "zulip@localhost" ]; then
|
||||
cat <<EOF
|
||||
|
||||
***** WARNING *****
|
||||
|
||||
We are renaming the rabbitmq server's nodename from '$CURRENT' to
|
||||
'zulip@localhost', as rabbitmq is being reconfigured to listen only on
|
||||
localhost. This will also make the server more resilient to hostname
|
||||
changes. This will only affect you if you were using the rabbitmq
|
||||
server for other, non-Zulip uses.
|
||||
|
||||
*******************
|
||||
|
||||
EOF
|
||||
|
||||
service rabbitmq-server stop || true
|
||||
fi
|
||||
@@ -625,6 +625,24 @@ def deport(netloc: str) -> str:
|
||||
return "[" + r.hostname + "]" if ":" in r.hostname else r.hostname
|
||||
|
||||
|
||||
def listening_publicly(port: int) -> List[str]:
|
||||
filter = f"sport = :{port} and not src 127.0.0.1:{port} and not src [::1]:{port}"
|
||||
# Parse lines that look like this:
|
||||
# tcp LISTEN 0 128 0.0.0.0:25672 0.0.0.0:*
|
||||
lines = (
|
||||
subprocess.check_output(
|
||||
["/bin/ss", "-Hnl", filter],
|
||||
universal_newlines=True,
|
||||
# Hosts with IPv6 disabled will get "RTNETLINK answers: Invalid
|
||||
# argument"; eat stderr to hide that
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
.strip()
|
||||
.splitlines()
|
||||
)
|
||||
return [line.split()[4] for line in lines]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cmd = sys.argv[1]
|
||||
if cmd == "make_deploy_path":
|
||||
|
||||
2
scripts/setup/apt-repos/ksplice/bionic.list
Normal file
2
scripts/setup/apt-repos/ksplice/bionic.list
Normal file
@@ -0,0 +1,2 @@
|
||||
deb http://www.ksplice.com/apt bionic ksplice
|
||||
deb-src http://www.ksplice.com/apt bionic ksplice
|
||||
2
scripts/setup/apt-repos/ksplice/focal.list
Normal file
2
scripts/setup/apt-repos/ksplice/focal.list
Normal file
@@ -0,0 +1,2 @@
|
||||
deb http://www.ksplice.com/apt focal ksplice
|
||||
deb-src http://www.ksplice.com/apt focal ksplice
|
||||
5
scripts/setup/apt-repos/zulip/bionic.list
Normal file
5
scripts/setup/apt-repos/zulip/bionic.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu bionic main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu bionic main
|
||||
5
scripts/setup/apt-repos/zulip/bullseye.list
Normal file
5
scripts/setup/apt-repos/zulip/bullseye.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main
|
||||
|
||||
deb http://apt-archive.postgresql.org/pub/repos/apt/ bullseye-pgdg-archive main
|
||||
deb-src http://apt-archive.postgresql.org/pub/repos/apt/ bullseye-pgdg-archive main
|
||||
5
scripts/setup/apt-repos/zulip/buster.list
Normal file
5
scripts/setup/apt-repos/zulip/buster.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main
|
||||
|
||||
deb http://apt-archive.postgresql.org/pub/repos/apt/ buster-pgdg-archive main
|
||||
deb-src http://apt-archive.postgresql.org/pub/repos/apt/ buster-pgdg-archive main
|
||||
5
scripts/setup/apt-repos/zulip/cosmic.list
Normal file
5
scripts/setup/apt-repos/zulip/cosmic.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ cosmic-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ cosmic-pgdg main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu cosmic main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu cosmic main
|
||||
44
scripts/setup/apt-repos/zulip/custom.sh
Executable file
44
scripts/setup/apt-repos/zulip/custom.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ ! -e /usr/share/doc/groonga-apt-source/copyright ]]; then
|
||||
remove_pgroonga_apt_tmp_dir() {
|
||||
rm -rf "$pgroonga_apt_tmp_dir"
|
||||
}
|
||||
pgroonga_apt_tmp_dir=$(mktemp --directory)
|
||||
trap remove_pgroonga_apt_tmp_dir EXIT
|
||||
|
||||
{
|
||||
cd "$pgroonga_apt_tmp_dir" || exit 1
|
||||
tmp_gpg_home=.gnupg
|
||||
pgroonga_apt_sign_key="$LIST_PATH/pgroonga-packages.groonga.org.asc"
|
||||
gpg --homedir="$tmp_gpg_home" --import "$pgroonga_apt_sign_key"
|
||||
# Find fingerprint of the first key.
|
||||
pgroonga_apt_sign_key_fingerprint=$(
|
||||
gpg --homedir="$tmp_gpg_home" --with-colons --list-keys \
|
||||
| grep '^fpr:' \
|
||||
| cut --delimiter=: --fields=10 \
|
||||
| head --lines=1
|
||||
)
|
||||
os_info="$(. /etc/os-release && printf '%s\n' "$ID" "$VERSION_CODENAME")"
|
||||
{
|
||||
read -r distribution
|
||||
read -r release
|
||||
} <<<"$os_info"
|
||||
groonga_apt_source_deb="groonga-apt-source-latest-$release.deb"
|
||||
groonga_apt_source_deb_sign="$groonga_apt_source_deb.asc.$pgroonga_apt_sign_key_fingerprint"
|
||||
wget "https://packages.groonga.org/$distribution/$groonga_apt_source_deb"
|
||||
wget "https://packages.groonga.org/$distribution/$groonga_apt_source_deb_sign"
|
||||
gpg \
|
||||
--homedir="$tmp_gpg_home" \
|
||||
--verify \
|
||||
"$groonga_apt_source_deb_sign" \
|
||||
"$groonga_apt_source_deb"
|
||||
# To suppress the following warning by "apt-get install":
|
||||
# N: Download is performed unsandboxed as root as file
|
||||
# '.../groonga-apt-source-latest-$release.deb' couldn't be
|
||||
# accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
|
||||
chown _apt .
|
||||
apt-get -y install "./$groonga_apt_source_deb"
|
||||
}
|
||||
touch "$STAMP_FILE"
|
||||
fi
|
||||
5
scripts/setup/apt-repos/zulip/disco.list
Normal file
5
scripts/setup/apt-repos/zulip/disco.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ disco-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ disco-pgdg main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu disco main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu disco main
|
||||
5
scripts/setup/apt-repos/zulip/eoan.list
Normal file
5
scripts/setup/apt-repos/zulip/eoan.list
Normal file
@@ -0,0 +1,5 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ eoan-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ eoan-pgdg main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu eoan main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu eoan main
|
||||
8
scripts/setup/apt-repos/zulip/focal.list
Normal file
8
scripts/setup/apt-repos/zulip/focal.list
Normal file
@@ -0,0 +1,8 @@
|
||||
deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main
|
||||
deb-src http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main
|
||||
|
||||
deb http://apt-archive.postgresql.org/pub/repos/apt/ focal-pgdg-archive main
|
||||
deb-src http://apt-archive.postgresql.org/pub/repos/apt/ focal-pgdg-archive main
|
||||
|
||||
deb http://ppa.launchpad.net/groonga/ppa/ubuntu focal main
|
||||
deb-src http://ppa.launchpad.net/groonga/ppa/ubuntu focal main
|
||||
19
scripts/setup/apt-repos/zulip/zulip.pref
Normal file
19
scripts/setup/apt-repos/zulip/zulip.pref
Normal file
@@ -0,0 +1,19 @@
|
||||
Package: postgresql-10 postgresql-client-10 postgresql-server-dev-10
|
||||
Pin: version 10.19-*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: postgresql-11 postgresql-client-11 postgresql-server-dev-11
|
||||
Pin: version 11.14-*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: postgresql-12 postgresql-client-12 postgresql-server-dev-12
|
||||
Pin: version 12.9-*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: postgresql-13 postgresql-client-13 postgresql-server-dev-13
|
||||
Pin: version 13.5-*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: postgresql-14 postgresql-client-14 postgresql-server-dev-14
|
||||
Pin: version 14.1-*
|
||||
Pin-Priority: 1000
|
||||
2
scripts/setup/apt-repos/zulip_debathena/bionic.list
Normal file
2
scripts/setup/apt-repos/zulip_debathena/bionic.list
Normal file
@@ -0,0 +1,2 @@
|
||||
deb http://debathena.mit.edu/apt bionic debathena debathena-config
|
||||
deb-src http://debathena.mit.edu/apt bionic debathena debathena-config
|
||||
@@ -5,7 +5,7 @@ import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
sys.path.append(BASE_DIR)
|
||||
from scripts.lib.setup_path import setup_path
|
||||
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
#
|
||||
# Delete the "guest" default user and replace it with a Zulip user
|
||||
# with a real password
|
||||
set -e
|
||||
set -x
|
||||
set -eu
|
||||
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
rabbitmqctl=(rabbitmqctl)
|
||||
sudo=()
|
||||
else
|
||||
rabbitmqctl=(sudo rabbitmqctl)
|
||||
sudo=(sudo)
|
||||
fi
|
||||
|
||||
if [ -n "$RABBITMQ_NODE" ]; then
|
||||
rabbitmqctl+=(-n "$RABBITMQ_NODE")
|
||||
fi
|
||||
# If the RabbitMQ distribution cookie is insecure, reset it and
|
||||
# restart RabbitMQ.
|
||||
"${sudo[@]}" "$(dirname "$0")/generate-rabbitmq-cookie"
|
||||
|
||||
RABBITMQ_USERNAME=$("$(dirname "$0")/../get-django-setting" RABBITMQ_USERNAME)
|
||||
RABBITMQ_PASSWORD=$("$(dirname "$0")/../get-django-setting" RABBITMQ_PASSWORD)
|
||||
|
||||
# Wait for RabbitMQ to start up
|
||||
try_ping() {
|
||||
# `rabbitmqctl ping` requires 3.7.6 or newer
|
||||
out="$("${rabbitmqctl[@]}" eval 'net_adm:ping(node()).')" && [ "$out" = 'pong' ]
|
||||
out="$("${sudo[@]}" rabbitmqctl eval 'net_adm:ping(node()).')" && [ "$out" = 'pong' ]
|
||||
}
|
||||
retries=9
|
||||
while ! try_ping 2>/dev/null; do
|
||||
@@ -31,9 +31,9 @@ while ! try_ping 2>/dev/null; do
|
||||
fi
|
||||
done
|
||||
|
||||
"${rabbitmqctl[@]}" delete_user "$RABBITMQ_USERNAME" || true
|
||||
"${rabbitmqctl[@]}" delete_user zulip || true
|
||||
"${rabbitmqctl[@]}" delete_user guest || true
|
||||
"${rabbitmqctl[@]}" add_user "$RABBITMQ_USERNAME" "$RABBITMQ_PASSWORD"
|
||||
"${rabbitmqctl[@]}" set_user_tags "$RABBITMQ_USERNAME" administrator
|
||||
"${rabbitmqctl[@]}" set_permissions -p / "$RABBITMQ_USERNAME" '.*' '.*' '.*'
|
||||
"${sudo[@]}" rabbitmqctl delete_user "$RABBITMQ_USERNAME" || true
|
||||
"${sudo[@]}" rabbitmqctl delete_user zulip || true
|
||||
"${sudo[@]}" rabbitmqctl delete_user guest || true
|
||||
"${sudo[@]}" rabbitmqctl add_user "$RABBITMQ_USERNAME" "$RABBITMQ_PASSWORD"
|
||||
"${sudo[@]}" rabbitmqctl set_user_tags "$RABBITMQ_USERNAME" administrator
|
||||
"${sudo[@]}" rabbitmqctl set_permissions -p / "$RABBITMQ_USERNAME" '.*' '.*' '.*'
|
||||
|
||||
27
scripts/setup/generate-rabbitmq-cookie
Executable file
27
scripts/setup/generate-rabbitmq-cookie
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# rabbitmq sets an insecure "magic cookie" which is used for auth;
|
||||
# reset it to be longer.
|
||||
set -eu
|
||||
|
||||
cookiefile=/var/lib/rabbitmq/.erlang.cookie
|
||||
# If the RabbitMQ distribution cookie is insecure, reset it
|
||||
if [ ! -f "$cookiefile" ] || ! size="$(wc -c "$cookiefile")" || [ "${size%% *}" -le 20 ]; then
|
||||
running=0
|
||||
if service rabbitmq-server status >/dev/null; then
|
||||
running=1
|
||||
service rabbitmq-server stop
|
||||
fi
|
||||
|
||||
echo "Setting a more secure RabbitMQ distribution magic cookie"
|
||||
cookie="$(LC_ALL=C tr -dc '[:alnum:]' </dev/urandom | head -c255)"
|
||||
[ "${#cookie}" -eq 255 ] # make sure tr wasn’t OOM-killed
|
||||
tmpfile="$(mktemp "$cookiefile.XXXXXXXXXX")"
|
||||
chown rabbitmq: "$tmpfile"
|
||||
printf '%s' "$cookie" >"$tmpfile"
|
||||
mv "$tmpfile" "$cookiefile"
|
||||
|
||||
if [ "$running" == "1" ]; then
|
||||
service rabbitmq-server start
|
||||
fi
|
||||
fi
|
||||
@@ -6,15 +6,15 @@ import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.extensions
|
||||
from psycopg2.sql import SQL, Identifier
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "../.."))
|
||||
from scripts.lib.setup_path import setup_path
|
||||
|
||||
setup_path()
|
||||
|
||||
import psycopg2
|
||||
import psycopg2.extensions
|
||||
from psycopg2.sql import SQL, Identifier
|
||||
|
||||
from scripts.lib.zulip_tools import su_to_zulip
|
||||
|
||||
su_to_zulip()
|
||||
@@ -65,9 +65,7 @@ FROM
|
||||
JOIN pg_class AS trel ON trel.oid = i.indrelid
|
||||
JOIN pg_namespace AS tnsp ON trel.relnamespace = tnsp.oid
|
||||
JOIN pg_class AS irel ON irel.oid = i.indexrelid
|
||||
CROSS JOIN unnest(i.indkey) colnum
|
||||
JOIN pg_attribute AS a ON trel.oid = a.attrelid
|
||||
AND a.attnum = colnum
|
||||
JOIN pg_attribute AS a ON a.attrelid = i.indexrelid
|
||||
WHERE tnsp.nspname = 'zulip'
|
||||
AND a.attcollation != 0
|
||||
GROUP BY 1, 2, i.indrelid
|
||||
|
||||
@@ -5,7 +5,7 @@ set -e
|
||||
usage() {
|
||||
cat <<EOF >&2
|
||||
Usage: $0 --email=admin@example.com [--method={webroot|standalone}] \
|
||||
[--no-zulip-conf] hostname.example.com [another.example.com]
|
||||
hostname.example.com [another.example.com]
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
@@ -16,7 +16,7 @@ if [ "$EUID" -ne 0 ]; then
|
||||
fi
|
||||
|
||||
method=webroot
|
||||
args="$(getopt -o '' --long help,email:,method:,deploy-hook:,no-zulip-conf,agree-tos -n "$0" -- "$@")"
|
||||
args="$(getopt -o '' --long help,email:,method:,skip-symlink,agree-tos -n "$0" -- "$@")"
|
||||
eval "set -- $args"
|
||||
while true; do
|
||||
case "$1" in
|
||||
@@ -30,19 +30,14 @@ while true; do
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
--deploy-hook)
|
||||
deploy_hook=(--deploy-hook "$2")
|
||||
shift
|
||||
--skip-symlink)
|
||||
skip_symlink=1
|
||||
shift
|
||||
;;
|
||||
--agree-tos)
|
||||
agree_tos=--agree-tos
|
||||
shift
|
||||
;;
|
||||
--no-zulip-conf)
|
||||
no_zulip_conf=1
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_help=1
|
||||
shift
|
||||
@@ -71,7 +66,7 @@ fi
|
||||
|
||||
case "$method" in
|
||||
standalone)
|
||||
method_args=(--standalone)
|
||||
method_args=(--standalone --no-directory-hooks)
|
||||
;;
|
||||
webroot)
|
||||
method_args=(--webroot '--webroot-path=/var/lib/zulip/certbot-webroot/')
|
||||
@@ -112,7 +107,6 @@ esac
|
||||
certbot certonly "${method_args[@]}" \
|
||||
"${HOSTNAMES[@]}" -m "$EMAIL" \
|
||||
$agree_tos \
|
||||
"${deploy_hook[@]}" \
|
||||
--force-interactive --no-eff-email
|
||||
|
||||
symlink_with_backup() {
|
||||
@@ -125,22 +119,18 @@ symlink_with_backup() {
|
||||
ln -nsf "$1" "$2"
|
||||
}
|
||||
|
||||
if [ ${#deploy_hook} -eq 0 ]; then
|
||||
# If no deploy hook was specified, assume we're deploying to the default
|
||||
# location Zulip wants.
|
||||
if [ -z "$skip_symlink" ]; then
|
||||
CERT_DIR=/etc/letsencrypt/live/"$DOMAIN"
|
||||
symlink_with_backup "$CERT_DIR"/privkey.pem /etc/ssl/private/zulip.key
|
||||
symlink_with_backup "$CERT_DIR"/fullchain.pem /etc/ssl/certs/zulip.combined-chain.crt
|
||||
fi
|
||||
|
||||
# "certbot certonly" does not run deploy hooks, so reload nginx if
|
||||
# need be to pick up the new certificate.
|
||||
case "$method" in
|
||||
webroot)
|
||||
service nginx reload
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$no_zulip_conf" ]; then
|
||||
crudini --set /etc/zulip/zulip.conf certbot auto_renew yes
|
||||
fi
|
||||
|
||||
echo "Certbot SSL certificate configuration succeeded."
|
||||
|
||||
@@ -345,8 +345,15 @@ export function set_up() {
|
||||
}
|
||||
|
||||
$("#show_api_key").on("click", "button.regenerate_api_key", (e) => {
|
||||
const email = page_params.delivery_email;
|
||||
const api_key = $("#api_key_value").text();
|
||||
const authorization_header = "Basic " + btoa(`${email}:${api_key}`);
|
||||
|
||||
channel.post({
|
||||
url: "/json/users/me/api_key/regenerate",
|
||||
// This endpoint is only accessible with the previous API key,
|
||||
// via our usual HTTP Basic auth mechanism.
|
||||
url: "/api/v1/users/me/api_key/regenerate",
|
||||
headers: {Authorization: authorization_header},
|
||||
success(data) {
|
||||
$("#api_key_value").text(data.api_key);
|
||||
},
|
||||
|
||||
@@ -278,6 +278,7 @@ def install_apt_deps(deps_to_install: List[str]) -> None:
|
||||
"apt-get",
|
||||
"-y",
|
||||
"install",
|
||||
"--allow-downgrades",
|
||||
"--no-install-recommends",
|
||||
*deps_to_install,
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
|
||||
ZULIP_VERSION = "4.7"
|
||||
ZULIP_VERSION = "4.10"
|
||||
|
||||
# Add information on number of commits and commit hash to version, if available
|
||||
zulip_git_version_file = os.path.join(
|
||||
@@ -14,7 +14,7 @@ ZULIP_VERSION = lines.pop(0).strip()
|
||||
ZULIP_MERGE_BASE = lines.pop(0).strip()
|
||||
|
||||
LATEST_MAJOR_VERSION = "4.0"
|
||||
LATEST_RELEASE_VERSION = "4.7"
|
||||
LATEST_RELEASE_VERSION = "4.10"
|
||||
LATEST_RELEASE_ANNOUNCEMENT = "https://blog.zulip.com/2021/05/13/zulip-4-0-released/"
|
||||
|
||||
# Versions of the desktop app below DESKTOP_MINIMUM_VERSION will be
|
||||
@@ -47,4 +47,4 @@ API_FEATURE_LEVEL = 65
|
||||
# historical commits sharing the same major version, in which case a
|
||||
# minor version bump suffices.
|
||||
|
||||
PROVISION_VERSION = "146.1"
|
||||
PROVISION_VERSION = "146.2"
|
||||
|
||||
@@ -4,8 +4,9 @@ import random
|
||||
import secrets
|
||||
import shutil
|
||||
import subprocess
|
||||
import zipfile
|
||||
from collections import defaultdict
|
||||
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple
|
||||
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Type, TypeVar
|
||||
|
||||
import orjson
|
||||
import requests
|
||||
@@ -55,6 +56,41 @@ AddedChannelsT = Dict[str, Tuple[str, int]]
|
||||
AddedMPIMsT = Dict[str, Tuple[str, int]]
|
||||
DMMembersT = Dict[str, Tuple[str, str]]
|
||||
SlackToZulipRecipientT = Dict[str, int]
|
||||
# Generic type for SlackBotEmail class
|
||||
SlackBotEmailT = TypeVar("SlackBotEmailT", bound="SlackBotEmail")
|
||||
|
||||
|
||||
class SlackBotEmail:
|
||||
duplicate_email_count: Dict[str, int] = {}
|
||||
# Mapping of `bot_id` to final email assigned to the bot.
|
||||
assigned_email: Dict[str, str] = {}
|
||||
|
||||
@classmethod
|
||||
def get_email(cls: Type[SlackBotEmailT], user_profile: ZerverFieldsT, domain_name: str) -> str:
|
||||
slack_bot_id = user_profile["bot_id"]
|
||||
if slack_bot_id in cls.assigned_email:
|
||||
return cls.assigned_email[slack_bot_id]
|
||||
|
||||
if "real_name_normalized" in user_profile:
|
||||
slack_bot_name = user_profile["real_name_normalized"]
|
||||
elif "first_name" in user_profile:
|
||||
slack_bot_name = user_profile["first_name"]
|
||||
else:
|
||||
raise AssertionError("Could not identify bot type")
|
||||
|
||||
email = slack_bot_name.replace("Bot", "").replace(" ", "") + f"-bot@{domain_name}"
|
||||
|
||||
if email in cls.duplicate_email_count:
|
||||
email_prefix, email_suffix = email.split("@")
|
||||
email_prefix += cls.duplicate_email_count[email]
|
||||
email = "@".join([email_prefix, email_suffix])
|
||||
# Increment the duplicate email count
|
||||
cls.duplicate_email_count[email] += 1
|
||||
else:
|
||||
cls.duplicate_email_count[email] = 1
|
||||
|
||||
cls.assigned_email[slack_bot_id] = email
|
||||
return email
|
||||
|
||||
|
||||
def rm_tree(path: str) -> None:
|
||||
@@ -367,13 +403,7 @@ def get_user_email(user: ZerverFieldsT, domain_name: str) -> str:
|
||||
if user["is_mirror_dummy"]:
|
||||
return "{}@{}.slack.com".format(user["name"], user["team_domain"])
|
||||
if "bot_id" in user["profile"]:
|
||||
if "real_name_normalized" in user["profile"]:
|
||||
slack_bot_name = user["profile"]["real_name_normalized"]
|
||||
elif "first_name" in user["profile"]:
|
||||
slack_bot_name = user["profile"]["first_name"]
|
||||
else:
|
||||
raise AssertionError("Could not identify bot type")
|
||||
return slack_bot_name.replace("Bot", "").replace(" ", "") + f"-bot@{domain_name}"
|
||||
return SlackBotEmail.get_email(user["profile"], domain_name)
|
||||
if get_user_full_name(user).lower() == "slackbot":
|
||||
return f"imported-slackbot-bot@{domain_name}"
|
||||
raise AssertionError(f"Could not find email address for Slack user {user}")
|
||||
@@ -1065,8 +1095,6 @@ def get_attachment_path_and_content(fileinfo: ZerverFieldsT, realm_id: int) -> T
|
||||
s3_path = "/".join(
|
||||
[
|
||||
str(realm_id),
|
||||
"SlackImportAttachment", # This is a special placeholder which should be kept
|
||||
# in sync with 'exports.py' function 'import_message_data'
|
||||
format(random.randint(0, 255), "x"),
|
||||
secrets.token_urlsafe(18),
|
||||
sanitize_name(fileinfo["name"]),
|
||||
@@ -1246,7 +1274,7 @@ def fetch_team_icons(
|
||||
return records
|
||||
|
||||
|
||||
def do_convert_data(slack_zip_file: str, output_dir: str, token: str, threads: int = 6) -> None:
|
||||
def do_convert_data(original_path: str, output_dir: str, token: str, threads: int = 6) -> None:
|
||||
# Subdomain is set by the user while running the import command
|
||||
realm_subdomain = ""
|
||||
realm_id = 0
|
||||
@@ -1254,15 +1282,24 @@ def do_convert_data(slack_zip_file: str, output_dir: str, token: str, threads: i
|
||||
|
||||
check_token_access(token)
|
||||
|
||||
slack_data_dir = slack_zip_file.replace(".zip", "")
|
||||
if not os.path.exists(slack_data_dir):
|
||||
os.makedirs(slack_data_dir)
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
if os.listdir(output_dir):
|
||||
raise Exception("Output directory should be empty!")
|
||||
|
||||
subprocess.check_call(["unzip", "-q", slack_zip_file, "-d", slack_data_dir])
|
||||
if os.path.isfile(original_path) and original_path.endswith(".zip"):
|
||||
slack_data_dir = original_path.replace(".zip", "")
|
||||
if not os.path.exists(slack_data_dir):
|
||||
os.makedirs(slack_data_dir)
|
||||
|
||||
with zipfile.ZipFile(original_path) as zipObj:
|
||||
zipObj.extractall(slack_data_dir)
|
||||
elif os.path.isdir(original_path):
|
||||
slack_data_dir = original_path
|
||||
else:
|
||||
raise ValueError(f"Don't know how to import Slack data from {original_path}")
|
||||
|
||||
if not os.path.isfile(os.path.join(slack_data_dir, "channels.json")):
|
||||
raise ValueError(f"{original_path} does not have the layout we expect from a Slack export!")
|
||||
|
||||
# We get the user data from the legacy token method of Slack API, which is depreciated
|
||||
# but we use it as the user email data is provided only in this method
|
||||
@@ -1332,7 +1369,9 @@ def do_convert_data(slack_zip_file: str, output_dir: str, token: str, threads: i
|
||||
create_converted_data_files(attachment, output_dir, "/attachment.json")
|
||||
create_converted_data_files(realm_icon_records, output_dir, "/realm_icons/records.json")
|
||||
|
||||
rm_tree(slack_data_dir)
|
||||
# Clean up the directory if we unpacked it ourselves.
|
||||
if original_path != slack_data_dir:
|
||||
rm_tree(slack_data_dir)
|
||||
subprocess.check_call(["tar", "-czf", output_dir + ".tar.gz", output_dir, "-P"])
|
||||
|
||||
logging.info("######### DATA CONVERSION FINISHED #########\n")
|
||||
@@ -1352,6 +1391,8 @@ def check_token_access(token: str) -> None:
|
||||
data = requests.get(
|
||||
"https://slack.com/api/team.info", headers={"Authorization": "Bearer {}".format(token)}
|
||||
)
|
||||
if data.status_code != 200 or not data.json()["ok"]:
|
||||
raise ValueError("Invalid Slack token: {}".format(token))
|
||||
has_scopes = set(data.headers.get("x-oauth-scopes", "").split(","))
|
||||
required_scopes = set(["emoji:read", "users:read", "users:read.email", "team:read"])
|
||||
missing_scopes = required_scopes - has_scopes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user