snac2

Fork of https://codeberg.org/grunfink/snac2
git clone https://git.inz.fi/snac2
Log | Files | Refs | README | LICENSE

commit 979718e3cc5489efdce2acc6f8c86f6d00bb91c7
parent 1b0804bb0da0ef89aef98d9a771d2aa5bfeb34d7
Author: Oliver <zen@noreply.codeberg.org>
Date:   Wed, 21 May 2025 21:11:47 +0200

Merge pull request 'master refresh' (#8) from grunfink/snac2:master into master

Reviewed-on: https://codeberg.org/zen/snac2/pulls/8

Diffstat:
M.gitignore | 3++-
MMakefile | 14++++++++++----
MMakefile.NetBSD | 5+++--
MRELEASE_NOTES.md | 44++++++++++++++++++++++++++++++++++++++++++--
MTODO.md | 24+++++++++++++++++-------
Mactivitypub.c | 115++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mdata.c | 137++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mdoc/snac.1 | 15+++++++++++++++
Mdoc/snac.8 | 10++++++++++
Aexamples/snac-admin | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mformat.c | 12++++++++----
Mhtml.c | 360+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mhttpd.c | 5++++-
Mmain.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmastoapi.c | 220++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mpo/cs.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/el_GR.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/en.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/es.po | 370++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/es_AR.po | 370++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/es_UY.po | 370++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/fi.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/fr.po | 456++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/it.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/pt_BR.po | 379++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/ru.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mpo/zh.po | 372++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msandbox.c | 30++++++++++++++----------------
Msnac.c | 1+
Msnac.h | 15++++++++++++++-
Atests/smtp.c | 25+++++++++++++++++++++++++
Mutils.c | 60+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mxs_curl.h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mxs_mime.h | 1+
Mxs_time.h | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mxs_version.h | 2+-
Axs_webmention.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 files changed, 3780 insertions(+), 2324 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ -*.o +**/*.o +tests/smtp snac diff --git a/Makefile b/Makefile @@ -8,11 +8,16 @@ snac: snac.o main.o sandbox.o data.o http.o httpd.o webfinger.o \ activitypub.o html.o utils.o format.o upgrade.o mastoapi.o $(CC) $(CFLAGS) -L$(PREFIX)/lib *.o -lcurl -lcrypto $(LDFLAGS) -pthread -o $@ +test: tests/smtp + +tests/smtp: tests/smtp.o + $(CC) $(CFLAGS) -L$(PREFIX)/lib $< -lcurl $(LDFLAGS) -o $@ + .c.o: - $(CC) $(CFLAGS) $(CPPFLAGS) -I$(PREFIX)/include -c $< + $(CC) $(CFLAGS) $(CPPFLAGS) -I$(PREFIX)/include -c $< -o $@ clean: - rm -rf *.o *.core snac makefile.depend + rm -rf *.o tests/*.o tests/smtp *.core snac makefile.depend dep: $(CC) -I$(PREFIX)/include -MM *.c > makefile.depend @@ -51,7 +56,7 @@ format.o: format.c xs.h xs_regex.h xs_mime.h xs_html.h xs_json.h \ xs_time.h xs_match.h snac.h http_codes.h html.o: html.c xs.h xs_io.h xs_json.h xs_regex.h xs_set.h xs_openssl.h \ xs_time.h xs_mime.h xs_match.h xs_html.h xs_curl.h xs_unicode.h xs_url.h \ - snac.h http_codes.h + xs_random.h snac.h http_codes.h http.o: http.c xs.h xs_io.h xs_openssl.h xs_curl.h xs_time.h xs_json.h \ snac.h http_codes.h httpd.o: httpd.c xs.h xs_io.h xs_json.h xs_socket.h xs_unix_socket.h \ @@ -66,7 +71,8 @@ sandbox.o: sandbox.c xs.h snac.h http_codes.h snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \ xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \ xs_httpd.h xs_mime.h xs_regex.h xs_set.h xs_time.h xs_glob.h xs_random.h \ - xs_match.h xs_fcgi.h xs_html.h xs_po.h snac.h http_codes.h + xs_match.h xs_fcgi.h xs_html.h xs_po.h xs_webmention.h snac.h \ + http_codes.h upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h http_codes.h utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ xs_random.h xs_glob.h xs_curl.h xs_regex.h snac.h http_codes.h diff --git a/Makefile.NetBSD b/Makefile.NetBSD @@ -45,7 +45,7 @@ format.o: format.c xs.h xs_regex.h xs_mime.h xs_html.h xs_json.h \ xs_time.h xs_match.h snac.h http_codes.h html.o: html.c xs.h xs_io.h xs_json.h xs_regex.h xs_set.h xs_openssl.h \ xs_time.h xs_mime.h xs_match.h xs_html.h xs_curl.h xs_unicode.h xs_url.h \ - snac.h http_codes.h + xs_random.h snac.h http_codes.h http.o: http.c xs.h xs_io.h xs_openssl.h xs_curl.h xs_time.h xs_json.h \ snac.h http_codes.h httpd.o: httpd.c xs.h xs_io.h xs_json.h xs_socket.h xs_unix_socket.h \ @@ -60,7 +60,8 @@ sandbox.o: sandbox.c xs.h snac.h http_codes.h snac.o: snac.c xs.h xs_hex.h xs_io.h xs_unicode_tbl.h xs_unicode.h \ xs_json.h xs_curl.h xs_openssl.h xs_socket.h xs_unix_socket.h xs_url.h \ xs_httpd.h xs_mime.h xs_regex.h xs_set.h xs_time.h xs_glob.h xs_random.h \ - xs_match.h xs_fcgi.h xs_html.h xs_po.h snac.h http_codes.h + xs_match.h xs_fcgi.h xs_html.h xs_po.h xs_webmention.h snac.h \ + http_codes.h upgrade.o: upgrade.c xs.h xs_io.h xs_json.h xs_glob.h snac.h http_codes.h utils.o: utils.c xs.h xs_io.h xs_json.h xs_time.h xs_openssl.h \ xs_random.h xs_glob.h xs_curl.h xs_regex.h snac.h http_codes.h diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md @@ -1,6 +1,46 @@ # Release Notes -## 2.74 +## UNRELEASED + +The number of pending follow confirmations is shown next to the "people" link. + +Faster performance metrics (contributed by dandelions). + +Mastodon API: added follow confirmation endpoints. + +## 2.77 "Ugly Links Everywhere" + +As they look confusing in some platforms, links in content posts are no longer included as `Link` attachments. + +## 2.76 + +Added Webmention support for links (Markdown-style or direct) written in a post. + +Added new command-line options for list maintenance. + +Display custom emoji in more places (contributed by dandelions). + +Mastodon API: fixed infinite scroll in many clients (thanks to cheeaun for giving me the clue), added `/api/v1/accounts/.../lists` endpoint (contributed by dandelions). + +Email notifications can now be sent via `libcurl` SMTP instead of spawning the `/usr/sbin/sendmail` program. To use this new feature, some additional server configuration is needed, see `snac(8)` (contributed by shtrophic). + +## 2.75 "Time Is On My Side" + +Added support for scheduled posts (for this to work correctly, users will have to set their time zone, see below). + +The user can now select a working time zone. This will be used to correctly parse the local date and time of a scheduled post. + +Fixed incorrect poll vote format, which was causing problems in platforms like GotoSocial. + +Mastodon API: added support for `/api/v1/instance/peers`. + +Added a new `snac-admin` helper script (contributed by shtrophic). + +In the web UI, posts are separated by the `<hr hidden>` tag; it's invisible in graphical browsers, but it separates post clearly in text-based browsers. + +Some Finnish, Spanish, Czech and Russian translation updates and fixes. + +## 2.74 "The Days of Nicole, the Fediverse Chick" Added Spanish (default, Argentina and Uruguay) translation (contributed by gnemmi). @@ -22,7 +62,7 @@ Added Greek translation (contributed by uhuru). Added Italian translation (contributed by anzu). -Mastodon API: added support for /api/v1/custom_emojis (contributed by violette). +Mastodon API: added support for `/api/v1/custom_emojis` (contributed by violette). Improved Undo+Follow logic (contributed by rozenglass). diff --git a/TODO.md b/TODO.md @@ -2,19 +2,21 @@ ## Open +It seems that Microsoft is planning to laminate Basic HTTP Auth, so make a plan, see https://codeberg.org/grunfink/snac2/issues/350 + Investigate the problem with boosts inside the same instance (see https://codeberg.org/grunfink/snac2/issues/214). Editing / Updating a post does not index newly added hashtags. -Wrong level of message visibility when using the Mastodon API: https://codeberg.org/grunfink/snac2/issues/200#issuecomment-2351042 - Unfollowing guppe groups seems to work (http status of 200), but messages continue to arrive as if it didn't. Important: deleting a follower should do more that just delete the object, see https://codeberg.org/grunfink/snac2/issues/43#issuecomment-956721 ## Wishlist -Each notification should show a link to the full thread, to see it in context. +Add account reporting. + +Add a list option to hide member posts from the main timeline, see https://codeberg.org/grunfink/snac2/issues/383 The instance timeline should also show boosts from users. @@ -30,14 +32,10 @@ Integrate "Added handling for International Domain Names" PR https://codeberg.or Do something about Akkoma and Misskey's quoted replies (they use the `quoteUrl` field instead of `inReplyTo`). -Add a list of hashtags to drop. - Take a look at crashes in the brittle Mastodon official app (crashes when hitting the reply button, crashes or 'ownVotes is null' errors when trying to show polls). The 'history' pages are just monthly HTML snapshots of the local timeline. This is ok and cheap and easy, but is problematic if you e.g. intentionally delete a post because it will remain there in the history forever. If you activate local timeline purging, purged entries will remain in the history as 'ghosts', which may or may not be what the user wants. -The actual storage system wastes too much disk space (lots of small files that really consume 4k of storage). Consider alternatives. - ## Closed Start a TODO file (2022-08-25T10:07:44+0200). @@ -367,3 +365,15 @@ Add support for /authorize_interaction (whatever it is) (2025-01-16T14:45:28+010 Implement following of hashtags (this is not trivial) (2025-01-30T16:12:16+0100). Add support for subscribing and posting to relays (see https://codeberg.org/grunfink/snac2/issues/216 for more information) (2025-01-30T16:12:34+0100). + +Wrong level of message visibility when using the Mastodon API: https://codeberg.org/grunfink/snac2/issues/200#issuecomment-2351042 (2025-03-23T15:44:35+0100). + +Each notification should show a link to the full thread, to see it in context (2025-03-23T15:44:50+0100). + +Add a list of hashtags to drop (2025-03-23T15:45:30+0100). + +The actual storage system wastes too much disk space (lots of small files that really consume 4k of storage). Consider alternatives (2025-03-23T15:46:02+0100). + +Add command-line tools for creating and manipulating lists (2025-04-18T10:04:41+0200). + +Do a [Webmention](https://www.w3.org/TR/webmention/) to every link written in a post (2025-05-04T11:16:21+0200). diff --git a/activitypub.c b/activitypub.c @@ -11,6 +11,7 @@ #include "xs_set.h" #include "xs_match.h" #include "xs_unicode.h" +#include "xs_webmention.h" #include "snac.h" @@ -34,7 +35,7 @@ const char *susie_cool = "+ZcgN7wF7ZVihXkfSlWIVzIA6dbQzaygllpNuTX" "ZmmFNlvxADX1+o0cUPMbAAAAAElFTkSuQmCC"; -const char *susie_muertos = +const char *susie_muertos = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQAAAAC" "CEkxzAAAAV0lEQVQoz4XQsQ0AMQxCUW/A/lv+DT" "ic6zGRolekIMyMELNp8PiCEw6Q4w4NoAt53IH5m" @@ -1044,17 +1045,21 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, xs *subject = xs_fmt("snac notify for @%s@%s", xs_dict_get(snac->config, "uid"), xs_dict_get(srv_config, "host")); - xs *from = xs_fmt("snac-daemon <snac-daemon@%s>", xs_dict_get(srv_config, "host")); + xs *from = xs_fmt("<snac-daemon@%s>", xs_dict_get(srv_config, "host")); xs *header = xs_fmt( - "From: %s\n" + "From: snac-daemon %s\n" "To: %s\n" "Subject: %s\n" "\n", from, email, subject); - xs *email_body = xs_fmt("%s%s", header, body); + xs *mailinfo = xs_dict_new(); + xs *bd = xs_fmt("%s%s", header, body); + mailinfo = xs_dict_append(mailinfo, "from", from); + mailinfo = xs_dict_append(mailinfo, "to", email); + mailinfo = xs_dict_append(mailinfo, "body", bd); - enqueue_email(email_body, 0); + enqueue_email(mailinfo, 0); } /* telegram */ @@ -1327,6 +1332,10 @@ xs_dict *msg_actor(snac *snac) msg = xs_dict_set(msg, "preferredUsername", snac->uid); msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published")); + // this exists so we get the emoji tags from our name too. + // and then we just throw away the result, because it's kinda useless to have markdown in the display name. + xs *name_dummy = not_really_markdown(xs_dict_get(snac->config, "name"), NULL, &tags); + xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL, &tags); f_bio = process_tags(snac, f_bio_2, &tags); msg = xs_dict_set(msg, "summary", f_bio); @@ -2563,32 +2572,53 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) } -int send_email(const char *msg) -/* invoke sendmail with email headers and body in msg */ +int send_email(const xs_dict *mailinfo) +/* invoke curl */ { - FILE *f; - int status; - int fds[2]; - pid_t pid; - if (pipe(fds) == -1) return -1; - pid = vfork(); - if (pid == -1) return -1; - else if (pid == 0) { - dup2(fds[0], 0); + const char *url = xs_dict_get(srv_config, "smtp_url"); + + if (!xs_is_string(url) || *url == '\0') { + /* revert back to old sendmail pipe behaviour */ + const char *msg = xs_dict_get(mailinfo, "body"); + FILE *f; + int status; + int fds[2]; + pid_t pid; + + if (pipe(fds) == -1) return -1; + pid = vfork(); + if (pid == -1) return -1; + else if (pid == 0) { + dup2(fds[0], 0); + close(fds[0]); + close(fds[1]); + execl("/usr/sbin/sendmail", "sendmail", "-t", (char *) NULL); + _exit(1); + } close(fds[0]); - close(fds[1]); - execl("/usr/sbin/sendmail", "sendmail", "-t", (char *) NULL); - _exit(1); - } - close(fds[0]); - if ((f = fdopen(fds[1], "w")) == NULL) { - close(fds[1]); - return -1; + if ((f = fdopen(fds[1], "w")) == NULL) { + close(fds[1]); + return -1; + } + fprintf(f, "%s\n", msg); + fclose(f); + if (waitpid(pid, &status, 0) == -1) return -1; + return status; } - fprintf(f, "%s\n", msg); - fclose(f); - if (waitpid(pid, &status, 0) == -1) return -1; - return status; + + const char + *user = xs_dict_get(srv_config, "smtp_username"), + *pass = xs_dict_get(srv_config, "smtp_password"), + *from = xs_dict_get(mailinfo, "from"), + *to = xs_dict_get(mailinfo, "to"), + *body = xs_dict_get(mailinfo, "body"); + + if (url == NULL || *url == '\0') + url = "smtp://localhost"; + + int smtp_port = parse_port(url, NULL); + + return xs_smtp_request(url, user, pass, from, to, body, smtp_port == 465 || smtp_port == 587); } @@ -2759,6 +2789,8 @@ int process_user_queue(snac *snac) cnt++; } + scheduled_process(snac); + return cnt; } @@ -2859,7 +2891,7 @@ void process_queue_item(xs_dict *q_item) else if (strcmp(type, "email") == 0) { /* send this email */ - const xs_str *msg = xs_dict_get(q_item, "message"); + const xs_dict *msg = xs_dict_get(q_item, "message"); int retries = xs_number_get(xs_dict_get(q_item, "retries")); if (!send_email(msg)) @@ -2999,6 +3031,25 @@ void process_queue_item(xs_dict *q_item) } } else + if (strcmp(type, "webmention") == 0) { + const xs_dict *msg = xs_dict_get(q_item, "message"); + const char *source = xs_dict_get(msg, "id"); + const char *content = xs_dict_get(msg, "content"); + + if (xs_is_string(source) && xs_is_string(content)) { + xs *links = xs_regex_select(content, "\"https?:/" "/[^\"]+"); + const char *link; + + xs_list_foreach(links, link) { + xs *target = xs_strip_chars_i(xs_dup(link), "\""); + + int r = xs_webmention_send(source, target, USER_AGENT); + + srv_debug(1, xs_fmt("webmention source=%s target=%s %d", source, target, r)); + } + } + } + else srv_log(xs_fmt("unexpected q_item type '%s'", type)); } @@ -3153,8 +3204,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, int total = 0; if (show_contact_metrics) { - xs *l = follower_list(&snac); - total = xs_list_len(l); + total = follower_list_len(&snac); } xs *id = xs_fmt("%s/%s", snac.actor, p_path); @@ -3165,8 +3215,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, int total = 0; if (show_contact_metrics) { - xs *l = following_list(&snac); - total = xs_list_len(l); + total = following_list_len(&snac); } xs *id = xs_fmt("%s/%s", snac.actor, p_path); diff --git a/data.c b/data.c @@ -282,6 +282,8 @@ int user_open(snac *user, const char *uid) } else srv_log(xs_fmt("error parsing '%s'", cfg_file)); + + user->tz = xs_dict_get_def(user->config, "tz", "UTC"); } else srv_debug(2, xs_fmt("error opening '%s' %d", cfg_file, errno)); @@ -1213,6 +1215,14 @@ int follower_check(snac *snac, const char *actor) } +int follower_list_len(snac *snac) +/* returns the number of followers */ +{ + xs *list = object_user_cache_list(snac, "followers", XS_ALL, 0); + return xs_list_len(list); +} + + xs_list *follower_list(snac *snac) /* returns the list of followers */ { @@ -1333,6 +1343,16 @@ xs_list *pending_list(snac *user) } +int pending_count(snac *user) +/* returns the number of pending follow confirmations */ +{ + xs *spec = xs_fmt("%s/pending/""*.json", user->basedir); + xs *l = xs_glob(spec, 0, 0); + + return xs_list_len(l); +} + + /** timeline **/ double timeline_mtime(snac *snac) @@ -1697,6 +1717,15 @@ int following_get(snac *snac, const char *actor, xs_dict **data) } +int following_list_len(snac *snac) +/* returns number of people being followed */ +{ + xs *spec = xs_fmt("%s/following/" "*_a.json", snac->basedir); + xs *glist = xs_glob(spec, 0, 0); + return xs_list_len(glist); +} + + xs_list *following_list(snac *snac) /* returns the list of people being followed */ { @@ -1929,6 +1958,70 @@ xs_list *draft_list(snac *user) } +/** scheduled posts **/ + +int is_scheduled(snac *user, const char *id) +/* returns true if this note is scheduled for future sending */ +{ + return object_user_cache_in(user, id, "sched"); +} + + +void schedule_del(snac *user, const char *id) +/* deletes an scheduled post */ +{ + object_user_cache_del(user, id, "sched"); +} + + +void schedule_add(snac *user, const char *id, const xs_dict *msg) +/* schedules this post for later */ +{ + /* delete from the index, in case it was already there */ + schedule_del(user, id); + + /* overwrite object */ + object_add_ow(id, msg); + + /* [re]add to the index */ + object_user_cache_add(user, id, "sched"); +} + + +xs_list *scheduled_list(snac *user) +/* return the list of scheduled posts */ +{ + return object_user_cache_list(user, "sched", XS_ALL, 1); +} + + +void scheduled_process(snac *user) +/* processes the scheduled list, sending those ready to be sent */ +{ + xs *posts = scheduled_list(user); + const char *md5; + xs *right_now = xs_str_utctime(0, ISO_DATE_SPEC); + + xs_list_foreach(posts, md5) { + xs *msg = NULL; + + if (valid_status(object_get_by_md5(md5, &msg))) { + if (strcmp(xs_dict_get(msg, "published"), right_now) < 0) { + /* due date! */ + const char *id = xs_dict_get(msg, "id"); + + timeline_add(user, id, msg); + + xs *c_msg = msg_create(user, msg); + enqueue_message(user, c_msg); + + schedule_del(user, id); + } + } + } +} + + /** hiding **/ xs_str *_hidden_fn(snac *snac, const char *id) @@ -2199,7 +2292,8 @@ xs_val *list_maint(snac *user, const char *list, int op) xs *l2 = xs_split(v2, "/"); /* return [ list_id, list_title ] */ - l = xs_list_append(l, xs_list_append(xs_list_new(), xs_list_get(l2, -1), title)); + xs *tmp_list = xs_list_append(xs_list_new(), xs_list_get(l2, -1), title); + l = xs_list_append(l, tmp_list); } } } @@ -2274,6 +2368,19 @@ xs_val *list_maint(snac *user, const char *list, int op) } break; + + case 4: /** find list id by name **/ + if (xs_is_string(list)) { + xs *lol = list_maint(user, NULL, 0); + const xs_list *li; + + xs_list_foreach(lol, li) { + if (strcmp(list, xs_list_get(li, 1)) == 0) { + l = xs_dup(xs_list_get(li, 0)); + break; + } + } + } } return l; @@ -2325,7 +2432,7 @@ xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op break; case 1: /** append actor to list **/ - if (actor_md5 != NULL) { + if (xs_is_string(actor_md5) && xs_is_hex(actor_md5)) { if (!index_in_md5(fn, actor_md5)) index_add_md5(fn, actor_md5); } @@ -2333,7 +2440,7 @@ xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op break; case 2: /** delete actor from list **/ - if (actor_md5 != NULL) + if (xs_is_string(actor_md5) && xs_is_hex(actor_md5)) index_del_md5(fn, actor_md5); break; @@ -2619,10 +2726,9 @@ xs_list *inbox_list(void) xs_list *ibl = xs_list_new(); xs *spec = xs_fmt("%s/inbox/" "*", srv_basedir); xs *files = xs_glob(spec, 0, 0); - xs_list *p = files; const xs_val *v; - while (xs_list_iter(&p, &v)) { + xs_list_foreach(files, v) { FILE *f; if ((f = fopen(v, "r")) != NULL) { @@ -2630,7 +2736,9 @@ xs_list *inbox_list(void) if (line && *line) { line = xs_strip_i(line); - ibl = xs_list_append(ibl, line); + + if (!is_instance_blocked(line)) + ibl = xs_list_append(ibl, line); } fclose(f); @@ -3276,7 +3384,7 @@ void enqueue_output_by_actor(snac *snac, const xs_dict *msg, } -void enqueue_email(const xs_str *msg, int retries) +void enqueue_email(const xs_dict *msg, int retries) /* enqueues an email message to be sent */ { xs *qmsg = _new_qmsg("email", msg, retries); @@ -3392,6 +3500,19 @@ void enqueue_actor_refresh(snac *user, const char *actor, int forward_secs) } +void enqueue_webmention(const xs_dict *msg) +/* enqueues a webmention for the post */ +{ + xs *qmsg = _new_qmsg("webmention", msg, 0); + const char *ntid = xs_dict_get(qmsg, "ntid"); + xs *fn = xs_fmt("%s/queue/%s.json", srv_basedir, ntid); + + qmsg = _enqueue_put(fn, qmsg); + + srv_debug(1, xs_fmt("enqueue_webmention")); +} + + int was_question_voted(snac *user, const char *id) /* returns true if the user voted in this poll */ { @@ -3696,7 +3817,7 @@ void purge_user(snac *snac) _purge_user_subdir(snac, "public", pub_days); const char *idxs[] = { "followers.idx", "private.idx", "public.idx", - "pinned.idx", "bookmark.idx", "draft.idx", NULL }; + "pinned.idx", "bookmark.idx", "draft.idx", "sched.idx", NULL }; for (n = 0; idxs[n]; n++) { xs *idx = xs_fmt("%s/%s", snac->basedir, idxs[n]); diff --git a/doc/snac.1 b/doc/snac.1 @@ -163,6 +163,9 @@ lists of accounts are never published). .It Web interface language If the administrator has installed any language file, it can be selected here. +.It Time zone +The time zone the user is on (default: UTC). Only +used for scheduled posts. .It Password Write the same string in these two fields to change your password. Don't write anything if you don't want to do this. @@ -347,6 +350,18 @@ Imports a Mastodon list of accounts to be blocked in CSV format. The file must be stored inside the .Pa import/ subdirectory of a user's directory inside the server base directory. +.It Cm lists Ar basedir Ar uid +Prints the name of the user created lists. +.It Cm list_members Ar basedir Ar uid Ar name +Prints the list of actors in the named list. +.It Cm create_list Ar basedir Ar uid Ar name +Creates a new list. +.It Cm delete_list Ar basedir Ar uid Ar name +Deletes an existing list. +.It Cm list_add Ar basedir Ar uid Ar name Ar account +Adds an account (by its @name@host handle or actor URL) to a list. +.It Cm list_del Ar basedir Ar uid Ar name Ar actor_url +Deletes an actor (by its actor URL) from a list. .El .Ss Migrating an account to/from Mastodon See diff --git a/doc/snac.8 b/doc/snac.8 @@ -267,6 +267,16 @@ The maximum number of attachments per post (default: 4). .It Ic enable_svg Since version 2.73, SVG image attachments are hidden by default; you can enable them by setting this value to true. +.It Ic smtp_url +Since version 2.76, email notifications can be sent via direct connection to an +SMTP server instead of the traditional behaviour of piping the message to +.Pa /usr/sbin/sendmail . +Set this value to the SMTP url to be used for sending email notifications +(for example, smtp://localhost). It may include a port number if it's not running on +the usual one, like in smtp://mail.example.com:587. +.It Ic smtp_user +.It Ic smtp_password +To be filled if the SMTP server defined by the previous directive needs credentials. .El .Pp You must restart the server to make effective these changes. diff --git a/examples/snac-admin b/examples/snac-admin @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +## +## SNAC-ADMIN +## a simple script that is supposed to improve +## a snac admin's life, especially when snac +## is being run as a systemd.unit with +## DynamicUser=yes enabled. +## Please make sure to adjust SNAC_DIR +## down below according to your setup. +## +## USAGE +## snac-admin state +## snac-admin adduser rikkert +## snac-admin block example.org +## snac-admin verify_links lisa +## ... +## +## Author: @chris@social.shtrophic.net +## +## Released into the public domain +## + +set -e + +SNAC_PID=$(pidof snac) +SNAC_DIR=/var/lib/snac + +SNAC_VERB=$1 +shift + +if [ -z $SNAC_PID ]; then + echo "no such process" >&2 + exit 1 +fi + +if [ $(id -u) -ne 0 ]; then + echo "not root" >&2 + exit 1 +fi + +if [ ! -d $SNAC_DIR ]; then + echo "$SNAC_DIR is not a directory" >&2 + exit 1 +fi + +if [ -z $SNAC_VERB ]; then + echo "no arguments" >&2 + exit 1 +fi + +nsenter -ae -S follow -G follow -t $SNAC_PID -- snac $SNAC_VERB $SNAC_DIR $@ diff --git a/format.c b/format.c @@ -154,8 +154,10 @@ static xs_str *format_line(const char *line, xs_list **attach) xs *l = xs_split_n(w, "](", 1); if (xs_list_len(l) == 2) { - xs *link = xs_fmt("<a href=\"%s\">%s</a>", - xs_list_get(l, 1), xs_list_get(l, 0)); + const char *name = xs_list_get(l, 0); + const char *url = xs_list_get(l, 1); + + xs *link = xs_fmt("<a href=\"%s\">%s</a>", url, name); s = xs_str_cat(s, link); } @@ -208,6 +210,7 @@ static xs_str *format_line(const char *line, xs_list **attach) } else if (xs_str_in(v, ":/" "/") != -1) { + /* direct URLs in the post body */ xs *u = xs_replace_i(xs_replace(v, "#", "&#35;"), "@", "&#64;"); xs *v2 = xs_strip_chars_i(xs_dup(u), ".,)"); @@ -382,10 +385,11 @@ xs_str *not_really_markdown(const char *content, xs_list **attach, xs_list **tag const char *k, *v; while (xs_dict_next(d, &k, &v, &c)) { - const char *t = NULL; + const char *t = xs_mime_by_ext(v); /* is it an URL to an image? */ - if (xs_startswith(v, "https:/" "/") && xs_startswith((t = xs_mime_by_ext(v)), "image/")) { + if (xs_startswith(v, "https:/" "/") && + (xs_startswith(t, "image/") || strcmp(t, "application/octet-stream") == 0)) { if (tag && xs_str_in(s, k) != -1) { /* add the emoji to the tag list */ xs *e = xs_dict_new(); diff --git a/html.c b/html.c @@ -14,6 +14,7 @@ #include "xs_curl.h" #include "xs_unicode.h" #include "xs_url.h" +#include "xs_random.h" #include "snac.h" @@ -68,10 +69,14 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p } xs *style = xs_fmt("height: %dem; width: %dem; vertical-align: middle;", ems, ems); + xs *class = xs_fmt("snac-emoji snac-emoji-%d-em", ems); const xs_dict *v; int c = 0; + xs_set rep_emoji; + xs_set_init(&rep_emoji); + while (xs_list_next(tag_list, &v, &c)) { const char *t = xs_dict_get(v, "type"); @@ -79,11 +84,21 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p const char *n = xs_dict_get(v, "name"); const xs_dict *i = xs_dict_get(v, "icon"); + /* avoid repeated emojis (Misskey seems to return this) */ + if (xs_set_add(&rep_emoji, n) == 0) + continue; + if (xs_is_string(n) && xs_is_dict(i)) { const char *u = xs_dict_get(i, "url"); const char *mt = xs_dict_get(i, "mediaType"); - if (xs_is_string(u) && xs_is_string(mt)) { + if (xs_is_string(u)) { + // on akkoma instances mediaType is not present. + // but we need to to know if the image is an svg or not. + // for now, i just use the file extention, which may not be the most reliable... + if (!xs_is_string(mt)) + mt = xs_mime_by_ext(u); + if (strcmp(mt, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) s = xs_replace_i(s, n, ""); else { @@ -93,6 +108,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p xs_html_attr("loading", "lazy"), xs_html_attr("src", url), xs_html_attr("alt", n), + xs_html_attr("title", n), + xs_html_attr("class", class), xs_html_attr("style", style)); xs *s1 = xs_html_render(img); @@ -104,6 +121,8 @@ xs_str *replace_shortnames(xs_str *s, const xs_list *tag, int ems, const char *p } } } + + xs_set_free(&rep_emoji); } return s; @@ -125,6 +144,26 @@ xs_str *actor_name(xs_dict *actor, const char *proxy) } +xs_str *format_text_with_emoji(snac *user, const char *text, int ems, const char *proxy) +/* needed when we have local text with no tags attached */ +{ + xs *tags = xs_list_new(); + xs *name1 = not_really_markdown(text, NULL, &tags); + + xs_str *name3; + if (user) { + xs *name2 = process_tags(user, name1, &tags); + name3 = sanitize(name2); + } + else { + name3 = sanitize(name1); + name3 = xs_replace_i(name3, "<br>", ""); + } + + return replace_shortnames(name3, tags, ems, proxy); +} + + xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, const char *udate, const char *url, int priv, int in_people, const char *proxy, const char *lang, @@ -177,7 +216,7 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, xs_html_attr("loading", "lazy"), xs_html_attr("class", "snac-avatar"), xs_html_attr("src", avatar), - xs_html_attr("alt", "")), + xs_html_attr("alt", "[?]")), xs_html_tag("a", xs_html_attr("href", href), xs_html_attr("class", "p-author h-card snac-author"), @@ -293,7 +332,8 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, } -xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, const char *proxy, const char *md5) +xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, + const char *proxy, const char *md5, const char *lang) { xs *actor = NULL; xs_html *actor_icon = NULL; @@ -302,7 +342,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con const char *date = NULL; const char *udate = NULL; const char *url = NULL; - const char *lang = NULL; int priv = 0; const char *type = xs_dict_get(msg, "type"); @@ -314,16 +353,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con date = xs_dict_get(msg, "published"); udate = xs_dict_get(msg, "updated"); - lang = xs_dict_get(msg, "contentMap"); - if (xs_is_dict(lang)) { - const char *v; - int c = 0; - - xs_dict_next(lang, &lang, &v, &c); - } - else - lang = NULL; - actor_icon = html_actor_icon(user, actor, date, udate, url, priv, 0, proxy, lang, md5); } @@ -339,7 +368,7 @@ xs_html *html_note(snac *user, const char *summary, const xs_val *mnt_only, const char *redir, const char *in_reply_to, int poll, const xs_list *att_files, const xs_list *att_alt_texts, - int is_draft) + int is_draft, const char *published) /* Yes, this is a FUCKTON of arguments and I'm a bit embarrased */ { xs *action = xs_fmt("%s/admin/note", user->actor); @@ -429,6 +458,42 @@ xs_html *html_note(snac *user, const char *summary, xs_html_attr("name", "is_draft"), xs_html_attr(is_draft ? "checked" : "", NULL)))); + /* post date and time */ + xs *post_date = NULL; + xs *post_time = NULL; + + if (xs_is_string(published)) { + time_t t = xs_parse_iso_date(published, 0); + + if (t > 0) { + post_date = xs_str_time(t, "%Y-%m-%d", 1); + post_time = xs_str_time(t, "%H:%M:%S", 1); + } + } + + if (edit_id == NULL || is_draft || is_scheduled(user, edit_id)) { + xs *pdat = xs_fmt(L("Post date and time (timezone: %s):"), user->tz); + + xs_html_add(form, + xs_html_tag("p", + xs_html_tag("details", + xs_html_tag("summary", + xs_html_text(L("Scheduled post..."))), + xs_html_tag("p", + xs_html_text(pdat), + xs_html_sctag("br", NULL), + xs_html_sctag("input", + xs_html_attr("type", "date"), + xs_html_attr("value", post_date ? post_date : ""), + xs_html_attr("name", "post_date")), + xs_html_text(" "), + xs_html_sctag("input", + xs_html_attr("type", "time"), + xs_html_attr("value", post_time ? post_time : ""), + xs_html_attr("step", "1"), + xs_html_attr("name", "post_time")))))); + } + if (edit_id) xs_html_add(form, xs_html_sctag("input", @@ -746,11 +811,7 @@ xs_html *html_user_head(snac *user, const char *desc, const char *url) /* show metrics in og:description? */ if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { - xs *fwers = follower_list(user); - xs *fwing = following_list(user); - - xs *s1 = xs_fmt(L("%d following, %d followers"), - xs_list_len(fwing), xs_list_len(fwers)); + xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); s1 = xs_str_cat(s1, " · "); @@ -848,7 +909,9 @@ static xs_html *html_user_body(snac *user, int read_only) } else { int n_len = notify_new_num(user); + int p_len = pending_count(user); xs_html *notify_count = NULL; + xs_html *pending_follow_count = NULL; /* show the number of new notifications, if there are any */ if (n_len) { @@ -860,6 +923,15 @@ static xs_html *html_user_body(snac *user, int read_only) else notify_count = xs_html_text(""); + if (p_len) { + xs *s = xs_fmt(" %d ", p_len); + pending_follow_count = xs_html_tag("sup", + xs_html_attr("style", "background-color: red; color: white;"), + xs_html_text(s)); + } + else + pending_follow_count = xs_html_text(""); + xs *admin_url = xs_fmt("%s/admin", user->actor); xs *notify_url = xs_fmt("%s/notifications", user->actor); xs *people_url = xs_fmt("%s/people", user->actor); @@ -882,6 +954,7 @@ static xs_html *html_user_body(snac *user, int read_only) xs_html_tag("a", xs_html_attr("href", people_url), xs_html_text(L("people"))), + pending_follow_count, xs_html_text(" - "), xs_html_tag("a", xs_html_attr("href", instance_url), @@ -922,10 +995,12 @@ static xs_html *html_user_body(snac *user, int read_only) xs_dict_get(user->config, "uid"), xs_dict_get(srv_config, "host")); + xs *display_name = format_text_with_emoji(NULL, xs_dict_get(user->config, "name"), 1, proxy); + xs_html_add(top_user, xs_html_tag("p", xs_html_attr("class", "p-name snac-top-user-name"), - xs_html_text(xs_dict_get(user->config, "name"))), + xs_html_raw(display_name)), xs_html_tag("p", xs_html_attr("class", "snac-top-user-id"), xs_html_text(handle))); @@ -953,16 +1028,11 @@ static xs_html *html_user_body(snac *user, int read_only) } if (read_only) { - xs *tags = xs_list_new(); - xs *bio1 = not_really_markdown(xs_dict_get(user->config, "bio"), NULL, &tags); - xs *bio2 = process_tags(user, bio1, &tags); - xs *bio3 = sanitize(bio2); - - bio3 = replace_shortnames(bio3, tags, 2, proxy); + xs *bio = format_text_with_emoji(user, xs_dict_get(user->config, "bio"), 2, proxy); xs_html *top_user_bio = xs_html_tag("div", xs_html_attr("class", "p-note snac-top-user-bio"), - xs_html_raw(bio3)); /* already sanitized */ + xs_html_raw(bio)); /* already sanitized */ xs_html_add(top_user, top_user_bio); @@ -1082,11 +1152,7 @@ static xs_html *html_user_body(snac *user, int read_only) } if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { - xs *fwers = follower_list(user); - xs *fwing = following_list(user); - - xs *s1 = xs_fmt(L("%d following, %d followers"), - xs_list_len(fwing), xs_list_len(fwers)); + xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); xs_html_add(top_user, xs_html_tag("p", @@ -1116,7 +1182,7 @@ xs_html *html_top_controls(snac *user) NULL, NULL, xs_stock(XSTYPE_FALSE), "", xs_stock(XSTYPE_FALSE), NULL, - NULL, 1, NULL, NULL, 0), + NULL, 1, NULL, NULL, 0, NULL), /** operations **/ xs_html_tag("details", @@ -1270,6 +1336,27 @@ xs_html *html_top_controls(snac *user) xs_html_attr("value", lang))); } + /* timezone */ + xs_html *tz_select = xs_html_tag("select", + xs_html_attr("name", "tz")); + + xs *tzs = xs_tz_list(); + const char *tz; + + xs_list_foreach(tzs, tz) { + if (strcmp(tz, user->tz) == 0) + xs_html_add(tz_select, + xs_html_tag("option", + xs_html_text(tz), + xs_html_attr("value", tz), + xs_html_attr("selected", "selected"))); + else + xs_html_add(tz_select, + xs_html_tag("option", + xs_html_text(tz), + xs_html_attr("value", tz))); + } + xs *user_setup_action = xs_fmt("%s/admin/user-setup", user->actor); xs_html_add(top_controls, @@ -1466,6 +1553,11 @@ xs_html *html_top_controls(snac *user) lang_select), xs_html_tag("p", + xs_html_text(L("Time zone:")), + xs_html_sctag("br", NULL), + tz_select), + + xs_html_tag("p", xs_html_text(L("New password:")), xs_html_sctag("br", NULL), xs_html_sctag("input", @@ -1774,7 +1866,8 @@ xs_html *html_entry_controls(snac *user, const char *actor, id, NULL, xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"), xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir, - NULL, 0, att_files, att_alt_texts, is_draft(user, id))), + NULL, 0, att_files, att_alt_texts, is_draft(user, id), + xs_dict_get(msg, "published"))), xs_html_tag("p", NULL)); } @@ -1793,7 +1886,7 @@ xs_html *html_entry_controls(snac *user, const char *actor, NULL, NULL, xs_dict_get(msg, "sensitive"), xs_dict_get(msg, "summary"), xs_stock(is_msg_public(msg) ? XSTYPE_FALSE : XSTYPE_TRUE), redir, - id, 0, NULL, NULL, 0)), + id, 0, NULL, NULL, 0, NULL)), xs_html_tag("p", NULL)); } @@ -1840,6 +1933,15 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, return xs_html_tag("mark", xs_html_text(L("Truncated (too deep)"))); + const char *lang = NULL; + const xs_dict *cmap = xs_dict_get(msg, "contentMap"); + if (xs_is_dict(cmap)) { + const char *dummy; + int c = 0; + + xs_dict_next(cmap, &lang, &dummy, &c); + } + if (strcmp(type, "Follow") == 0) { return xs_html_tag("div", xs_html_attr("class", "snac-post"), @@ -1848,7 +1950,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, xs_html_tag("div", xs_html_attr("class", "snac-origin"), xs_html_text(L("follows you"))), - html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL))); + html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL, lang))); } else if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { @@ -2029,13 +2131,17 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } xs_html_add(post_header, - html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5)); + html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5, lang)); /** post content **/ xs_html *snac_content_wrap = xs_html_tag("div", xs_html_attr("class", "e-content snac-content")); + if (xs_is_string(lang)) + xs_html_add(snac_content_wrap, + xs_html_attr("lang", lang)); + xs_html_add(entry, snac_content_wrap); @@ -2313,14 +2419,10 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, const char *o_href = xs_dict_get(a, "href"); const char *name = xs_dict_get(a, "name"); - /* if this image is already in the post content, skip */ + /* if this URL is already in the post content, skip */ if (content && xs_str_in(content, o_href) != -1) continue; - /* drop silently any attachment that may include JavaScript */ - if (strcmp(type, "text/html") == 0) - continue; - if (strcmp(type, "image/svg+xml") == 0 && !xs_is_true(xs_dict_get(srv_config, "enable_svg"))) continue; @@ -2396,13 +2498,19 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, name = NULL; } else { + xs *d_href = xs_dup(o_href); + if (strlen(d_href) > 64) { + d_href[64] = '\0'; + d_href = xs_str_cat(d_href, "..."); + } + xs_html_add(content_attachments, xs_html_tag("p", xs_html_tag("a", xs_html_attr("href", o_href), xs_html_text(L("Attachment")), xs_html_text(": "), - xs_html_text(o_href)))); + xs_html_text(d_href)))); /* do not generate an Alt... */ name = NULL; @@ -2689,6 +2797,11 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, } } + /* add an invisible hr, to help differentiate between posts in text browsers */ + xs_html_add(entry_top, + xs_html_sctag("hr", + xs_html_attr("hidden", NULL))); + return entry_top; } @@ -2830,6 +2943,18 @@ xs_str *html_timeline(snac *user, const xs_list *list, int read_only, xs_html_text(L("drafts"))))); } + { + /* show the list of scheduled posts */ + xs *url = xs_fmt("%s/sched", user->actor); + xs_html_add(lol, + xs_html_tag("li", + xs_html_tag("a", + xs_html_attr("href", url), + xs_html_attr("class", "snac-list-link"), + xs_html_attr("title", L("Scheduled posts")), + xs_html_text(L("scheduled posts"))))); + } + /* the list of followed hashtags */ const char *followed_hashtags = xs_dict_get(user->config, "followed_hashtags"); @@ -3019,6 +3144,8 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c xs_html_tag("summary", xs_html_text("...")))); + xs *redir = xs_fmt("%s/people", user->actor); + const char *actor_id; xs_list_foreach(list, actor_id) { @@ -3040,6 +3167,7 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c if (!xs_is_null(c)) { xs *sc = sanitize(c); + sc = replace_shortnames(sc, xs_dict_get(actor, "tag"), 2, proxy); xs_html *snac_content = xs_html_tag("div", xs_html_attr("class", "snac-content")); @@ -3071,6 +3199,10 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c xs_html_attr("value", actor_id)), xs_html_sctag("input", xs_html_attr("type", "hidden"), + xs_html_attr("name", "hard-redir"), + xs_html_attr("value", redir)), + xs_html_sctag("input", + xs_html_attr("type", "hidden"), xs_html_attr("name", "actor-form"), xs_html_attr("value", "yes"))); @@ -3130,7 +3262,7 @@ xs_html *html_people_list(snac *user, xs_list *list, const char *header, const c NULL, actor_id, xs_stock(XSTYPE_FALSE), "", xs_stock(XSTYPE_FALSE), NULL, - NULL, 0, NULL, NULL, 0), + NULL, 0, NULL, NULL, 0, NULL), xs_html_tag("p", NULL)); xs_html_add(snac_post, snac_controls); @@ -3257,7 +3389,8 @@ xs_str *html_notifications(snac *user, int skip, int show) continue; xs *a_name = actor_name(actor, proxy); - const char *label = type; + xs *label_sanatized = sanitize(type); + const char *label = label_sanatized; if (strcmp(type, "Create") == 0) label = L("Mention"); @@ -3268,11 +3401,12 @@ xs_str *html_notifications(snac *user, int skip, int show) if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") == 0) label = L("Unfollow"); else - if (strcmp(type, "EmojiReact") == 0) { + if (strcmp(type, "EmojiReact") == 0 || strcmp(type, "Like") == 0) { const char *content = xs_dict_get_path(noti, "msg.content"); if (xs_type(content) == XSTYPE_STRING) { - wrk = xs_fmt("%s (%s)", type, content); + xs *emoji = replace_shortnames(xs_dup(content), xs_dict_get_path(noti, "msg.tag"), 1, proxy); + wrk = xs_fmt("%s (%s&#xFE0F;)", type, emoji); label = wrk; } } @@ -3284,7 +3418,7 @@ xs_str *html_notifications(snac *user, int skip, int show) xs_html *this_html_label = xs_html_container( xs_html_tag("b", - xs_html_text(label), + xs_html_raw(label), xs_html_text(" by "), xs_html_tag("a", xs_html_attr("href", actor_id), @@ -3584,7 +3718,7 @@ int html_get_handler(const xs_dict *req, const char *q_path, if (xs_is_true(xs_dict_get(srv_config, "strict_public_timelines"))) list = timeline_simple_list(&snac, "public", skip, show, &more); - else + else list = timeline_list(&snac, "public", skip, show, &more); xs *pins = pinned_list(&snac); @@ -3879,6 +4013,21 @@ int html_get_handler(const xs_dict *req, const char *q_path, } } else + if (strcmp(p_path, "sched") == 0) { /** list of scheduled posts **/ + if (!login(&snac, req)) { + *body = xs_dup(uid); + status = HTTP_STATUS_UNAUTHORIZED; + } + else { + xs *list = scheduled_list(&snac); + + *body = html_timeline(&snac, list, 0, skip, show, + 0, L("Scheduled posts"), "", 0, error); + *b_size = strlen(*body); + status = HTTP_STATUS_OK; + } + } + else if (xs_startswith(p_path, "list/")) { /** list timelines **/ if (!login(&snac, req)) { *body = xs_dup(uid); @@ -4175,12 +4324,14 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac_debug(&snac, 1, xs_fmt("web action '%s' received", p_path)); /* post note */ - const xs_str *content = xs_dict_get(p_vars, "content"); - const xs_str *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); - const xs_str *to = xs_dict_get(p_vars, "to"); - const xs_str *sensitive = xs_dict_get(p_vars, "sensitive"); - const xs_str *summary = xs_dict_get(p_vars, "summary"); - const xs_str *edit_id = xs_dict_get(p_vars, "edit_id"); + const char *content = xs_dict_get(p_vars, "content"); + const char *in_reply_to = xs_dict_get(p_vars, "in_reply_to"); + const char *to = xs_dict_get(p_vars, "to"); + const char *sensitive = xs_dict_get(p_vars, "sensitive"); + const char *summary = xs_dict_get(p_vars, "summary"); + const char *edit_id = xs_dict_get(p_vars, "edit_id"); + const char *post_date = xs_dict_get_def(p_vars, "post_date", ""); + const char *post_time = xs_dict_get_def(p_vars, "post_time", ""); int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only")); int store_as_draft = !xs_is_null(xs_dict_get(p_vars, "is_draft")); xs *attach_list = xs_list_new(); @@ -4210,9 +4361,12 @@ int html_post_handler(const xs_dict *req, const char *q_path, const char *fn = xs_list_get(attach_file, 0); if (xs_is_string(fn) && *fn != '\0') { - char *ext = strrchr(fn, '.'); - xs *hash = xs_md5_hex(fn, strlen(fn)); - xs *id = xs_fmt("%s%s", hash, ext); + char rnd[32]; + xs_rnd_buf(rnd, sizeof(rnd)); + + const char *ext = strrchr(fn, '.'); + xs *hash = xs_md5_hex(rnd, strlen(rnd)); + xs *id = xs_fmt("post-%s%s", hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(attach_file, 1)); int fs = xs_number_get(xs_list_get(attach_file, 2)); @@ -4268,6 +4422,31 @@ int html_post_handler(const xs_dict *req, const char *q_path, msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary); } + if (xs_is_string(post_date) && *post_date) { + xs *post_pubdate = xs_fmt("%sT%s", post_date, + xs_is_string(post_time) && *post_time ? post_time : "00:00:00"); + + time_t t = xs_parse_iso_date(post_pubdate, 0); + + if (t != 0) { + t -= xs_tz_offset(snac.tz); + + xs *iso_date = xs_str_iso_date(t); + msg = xs_dict_set(msg, "published", iso_date); + + snac_debug(&snac, 1, xs_fmt("Published date: [%s]", iso_date)); + } + else + snac_log(&snac, xs_fmt("Invalid post date: [%s]", post_pubdate)); + } + + /* is the published date from the future? */ + int future_post = 0; + xs *right_now = xs_str_utctime(0, ISO_DATE_SPEC); + + if (strcmp(xs_dict_get(msg, "published"), right_now) > 0) + future_post = 1; + if (xs_is_null(edit_id)) { /* new message */ const char *id = xs_dict_get(msg, "id"); @@ -4275,6 +4454,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (store_as_draft) { draft_add(&snac, id, msg); } + else + if (future_post) { + schedule_add(&snac, id, msg); + } else { c_msg = msg_create(&snac, msg); timeline_add(&snac, id, msg); @@ -4286,7 +4469,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (valid_status(object_get(edit_id, &p_msg))) { /* copy relevant fields from previous version */ - char *fields[] = { "id", "context", "url", "published", + char *fields[] = { "id", "context", "url", "to", "inReplyTo", NULL }; int n; @@ -4302,18 +4485,34 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (is_draft(&snac, edit_id)) { /* message was previously a draft; it's a create activity */ - /* set the published field to now */ - xs *published = xs_str_utctime(0, ISO_DATE_SPEC); - msg = xs_dict_set(msg, "published", published); + /* if the date is from the past, overwrite it with right_now */ + if (strcmp(xs_dict_get(msg, "published"), right_now) < 0) { + snac_debug(&snac, 1, xs_fmt("setting draft ancient date to %s", right_now)); + msg = xs_dict_set(msg, "published", right_now); + } /* overwrite object */ object_add_ow(edit_id, msg); - c_msg = msg_create(&snac, msg); - timeline_add(&snac, edit_id, msg); + if (future_post) { + schedule_add(&snac, edit_id, msg); + } + else { + c_msg = msg_create(&snac, msg); + timeline_add(&snac, edit_id, msg); + } + draft_del(&snac, edit_id); } + else + if (is_scheduled(&snac, edit_id)) { + /* editing an scheduled post; just update it */ + schedule_add(&snac, edit_id, msg); + } else { + /* ignore the (possibly changed) published date */ + msg = xs_dict_set(msg, "published", xs_dict_get(p_msg, "published")); + /* set the updated field */ xs *updated = xs_str_utctime(0, ISO_DATE_SPEC); msg = xs_dict_set(msg, "updated", updated); @@ -4329,8 +4528,10 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac_log(&snac, xs_fmt("cannot get object '%s' for editing", edit_id)); } - if (c_msg != NULL) + if (c_msg != NULL) { enqueue_message(&snac, c_msg); + enqueue_webmention(msg); + } history_del(&snac, "timeline.html_"); } @@ -4398,6 +4599,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (is_draft(&snac, id)) draft_del(&snac, id); else + if (is_scheduled(&snac, id)) + schedule_del(&snac, id); + else hide(&snac, id); } else @@ -4493,6 +4697,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, draft_del(&snac, id); + schedule_del(&snac, id); + snac_log(&snac, xs_fmt("deleted entry %s", id)); } } @@ -4613,6 +4819,8 @@ int html_post_handler(const xs_dict *req, const char *q_path, snac.config = xs_dict_set(snac.config, "show_contact_metrics", xs_stock(XSTYPE_FALSE)); if ((v = xs_dict_get(p_vars, "web_ui_lang")) != NULL) snac.config = xs_dict_set(snac.config, "lang", v); + if ((v = xs_dict_get(p_vars, "tz")) != NULL) + snac.config = xs_dict_set(snac.config, "tz", v); snac.config = xs_dict_set(snac.config, "latitude", xs_dict_get_def(p_vars, "latitude", "")); snac.config = xs_dict_set(snac.config, "longitude", xs_dict_get_def(p_vars, "longitude", "")); @@ -4636,7 +4844,7 @@ int html_post_handler(const xs_dict *req, const char *q_path, if (xs_startswith(mimetype, "image/")) { const char *ext = strrchr(fn, '.'); xs *hash = xs_md5_hex(fn, strlen(fn)); - xs *id = xs_fmt("%s%s", hash, ext); + xs *id = xs_fmt("%s-%s%s", uploads[n], hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(uploaded_file, 1)); int fs = xs_number_get(xs_list_get(uploaded_file, 2)); @@ -4705,6 +4913,9 @@ int html_post_handler(const xs_dict *req, const char *q_path, /* set the option */ msg = xs_dict_append(msg, "name", v); + /* delete the content */ + msg = xs_dict_del(msg, "content"); + xs *c_msg = msg_create(&snac, msg); enqueue_message(&snac, c_msg); @@ -4793,12 +5004,19 @@ int html_post_handler(const xs_dict *req, const char *q_path, } if (status == HTTP_STATUS_SEE_OTHER) { - const char *redir = xs_dict_get(p_vars, "redir"); + const char *hard_redir = xs_dict_get(p_vars, "hard-redir"); - if (xs_is_null(redir)) - redir = "top"; + if (xs_is_string(hard_redir)) + *body = xs_dup(hard_redir); + else { + const char *redir = xs_dict_get(p_vars, "redir"); + + if (xs_is_null(redir)) + redir = "top"; + + *body = xs_fmt("%s/admin#%s", snac.actor, redir); + } - *body = xs_fmt("%s/admin#%s", snac.actor, redir); *b_size = strlen(*body); } diff --git a/httpd.c b/httpd.c @@ -139,6 +139,8 @@ static xs_str *greeting_html(void) snac user; if (strcmp(uid, "relay") && user_open(&user, uid)) { + xs *formatted_name = format_text_with_emoji(NULL, xs_dict_get(user.config, "name"), 1, NULL); + xs_html_add(ul, xs_html_tag("li", xs_html_tag("a", @@ -148,7 +150,7 @@ static xs_str *greeting_html(void) xs_html_text("@"), xs_html_text(host), xs_html_text(" ("), - xs_html_text(xs_dict_get(user.config, "name")), + xs_html_raw(formatted_name), xs_html_text(")")))); user_free(&user); @@ -554,6 +556,7 @@ void httpd_connection(FILE *f) headers = xs_dict_append(headers, "access-control-allow-origin", "*"); headers = xs_dict_append(headers, "access-control-allow-headers", "*"); + headers = xs_dict_append(headers, "access-control-expose-headers", "Link"); /* disable any form of fucking JavaScript */ headers = xs_dict_append(headers, "Content-Security-Policy", "script-src ;"); diff --git a/main.c b/main.c @@ -59,6 +59,12 @@ int usage(void) printf("import_csv {basedir} {uid} Imports data from CSV files\n"); printf("import_list {basedir} {uid} {file} Imports a Mastodon CSV list file\n"); printf("import_block_list {basedir} {uid} {file} Imports a Mastodon CSV block list file\n"); + printf("lists {basedir} {uid} Returns the names of the lists created by the user\n"); + printf("list_members {basedir} {uid} {name} Returns the list of accounts inside a list\n"); + printf("create_list {basedir} {uid} {name} Creates a new list\n"); + printf("delete_list {basedir} {uid} {name} Deletes an existing list\n"); + printf("list_add {basedir} {uid} {name} {acct} Adds an account (@user@host or actor url) to a list\n"); + printf("list_del {basedir} {uid} {name} {actor} Deletes an actor URL from a list\n"); return 1; } @@ -282,9 +288,114 @@ int main(int argc, char *argv[]) return migrate_account(&snac); } + if (strcmp(cmd, "lists") == 0) { /** **/ + xs *lol = list_maint(&snac, NULL, 0); + const xs_list *l; + + xs_list_foreach(lol, l) { + printf("%s (%s)\n", xs_list_get(l, 1), xs_list_get(l, 0)); + } + + return 0; + } + if ((url = GET_ARGV()) == NULL) return usage(); + if (strcmp(cmd, "list_members") == 0) { /** **/ + xs *lid = list_maint(&snac, url, 4); + + if (lid != NULL) { + xs *lcont = list_content(&snac, lid, NULL, 0); + const char *md5; + + xs_list_foreach(lcont, md5) { + xs *actor = NULL; + + if (valid_status(object_get_by_md5(md5, &actor))) { + printf("%s (%s)\n", xs_dict_get(actor, "id"), xs_dict_get_def(actor, "preferredUsername", "")); + } + } + } + else + fprintf(stderr, "Cannot find a list named '%s'\n", url); + + return 0; + } + + if (strcmp(cmd, "create_list") == 0) { /** **/ + xs *lid = list_maint(&snac, url, 4); + + if (lid == NULL) { + xs *n_lid = list_maint(&snac, url, 1); + printf("New list named '%s' created (%s)\n", url, n_lid); + } + else + fprintf(stderr, "A list named '%s' already exist\n", url); + + return 0; + } + + if (strcmp(cmd, "delete_list") == 0) { /** **/ + xs *lid = list_maint(&snac, url, 4); + + if (lid != NULL) { + list_maint(&snac, lid, 2); + printf("List '%s' (%s) deleted\n", url, lid); + } + else + fprintf(stderr, "Cannot find a list named '%s'\n", url); + + return 0; + } + + if (strcmp(cmd, "list_add") == 0) { /** **/ + const char *account = GET_ARGV(); + + if (account != NULL) { + xs *lid = list_maint(&snac, url, 4); + + if (lid != NULL) { + xs *actor = NULL; + xs *uid = NULL; + + if (valid_status(webfinger_request(account, &actor, &uid))) { + xs *md5 = xs_md5_hex(actor, strlen(actor)); + + list_content(&snac, lid, md5, 1); + printf("Actor %s (%s) added to list '%s' (%s)\n", actor, uid, url, lid); + } + else + fprintf(stderr, "Cannot resolve account '%s'\n", account); + } + else + fprintf(stderr, "Cannot find a list named '%s'\n", url); + + } + + return 0; + } + + if (strcmp(cmd, "list_del") == 0) { /** **/ + const char *account = GET_ARGV(); + + if (account != NULL) { + xs *lid = list_maint(&snac, url, 4); + + if (lid != NULL) { + xs *md5 = xs_md5_hex(account, strlen(account)); + + list_content(&snac, lid, md5, 2); + printf("Actor %s deleted from list '%s' (%s)\n", account, url, lid); + } + else + fprintf(stderr, "Cannot find a list named '%s'\n", url); + + } + + return 0; + } + if (strcmp(cmd, "alias") == 0) { /** **/ xs *actor = NULL; xs *uid = NULL; @@ -719,6 +830,7 @@ int main(int argc, char *argv[]) } enqueue_message(&snac, c_msg); + enqueue_webmention(msg); timeline_add(&snac, xs_dict_get(msg, "id"), msg); diff --git a/mastoapi.c b/mastoapi.c @@ -680,10 +680,10 @@ xs_dict *mastoapi_account(snac *logged, const xs_dict *actor) /* does this user want to publish their contact metrics? */ if (xs_is_true(xs_dict_get(user.config, "show_contact_metrics"))) { - xs *fwing = following_list(&user); - xs *fwers = follower_list(&user); - xs *ni = xs_number_new(xs_list_len(fwing)); - xs *ne = xs_number_new(xs_list_len(fwers)); + int fwing = following_list_len(&user); + int fwers = follower_list_len(&user); + xs *ni = xs_number_new(fwing); + xs *ne = xs_number_new(fwers); acct = xs_dict_append(acct, "followers_count", ne); acct = xs_dict_append(acct, "following_count", ni); @@ -1223,7 +1223,10 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) acct = xs_dict_append(acct, "last_status_at", xs_dict_get(snac.config, "published")); acct = xs_dict_append(acct, "note", xs_dict_get(snac.config, "bio")); acct = xs_dict_append(acct, "url", snac.actor); - acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE)); + + acct = xs_dict_append(acct, "locked", + xs_stock(xs_is_true(xs_dict_get(snac.config, "approve_followers")) ? XSTYPE_TRUE : XSTYPE_FALSE)); + acct = xs_dict_append(acct, "bot", xs_stock(xs_is_true(bot) ? XSTYPE_TRUE : XSTYPE_FALSE)); acct = xs_dict_append(acct, "emojis", xs_stock(XSTYPE_LIST)); @@ -1306,10 +1309,10 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) /* does this user want to publish their contact metrics? */ if (xs_is_true(xs_dict_get(snac.config, "show_contact_metrics"))) { - xs *fwing = following_list(&snac); - xs *fwers = follower_list(&snac); - xs *ni = xs_number_new(xs_list_len(fwing)); - xs *ne = xs_number_new(xs_list_len(fwers)); + int fwing = following_list_len(&snac); + int fwers = follower_list_len(&snac); + xs *ni = xs_number_new(fwing); + xs *ne = xs_number_new(fwers); acct = xs_dict_append(acct, "followers_count", ne); acct = xs_dict_append(acct, "following_count", ni); @@ -1500,6 +1503,44 @@ xs_str *timeline_link_header(const char *endpoint, xs_list *timeline) } +xs_list *mastoapi_account_lists(snac *user, const char *uid) +/* returns the list of list an user is in */ +{ + xs_list *out = xs_list_new(); + xs *actor_md5 = NULL; + xs *lol = list_maint(user, NULL, 0); + + if (uid) { + if (!xs_is_hex(uid)) + actor_md5 = xs_md5_hex(uid, strlen(uid)); + else + actor_md5 = xs_dup(uid); + } + + const xs_list *li; + xs_list_foreach(lol, li) { + const char *list_id = xs_list_get(li, 0); + const char *list_title = xs_list_get(li, 1); + if (uid) { + xs *users = list_content(user, list_id, NULL, 0); + if (xs_list_in(users, actor_md5) == -1) + continue; + } + + xs *d = xs_dict_new(); + + d = xs_dict_append(d, "id", list_id); + d = xs_dict_append(d, "title", list_title); + d = xs_dict_append(d, "replies_policy", "list"); + d = xs_dict_append(d, "exclusive", xs_stock(XSTYPE_FALSE)); + + out = xs_list_append(out, d); + } + + return out; +} + + int mastoapi_get_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype, xs_str **link) { @@ -1723,6 +1764,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (strcmp(opt, "followers") == 0) { out = xs_list_new(); } + else + if (strcmp(opt, "lists") == 0) { + out = mastoapi_account_lists(&snac1, uid); + } user_free(&snac2); } @@ -1744,6 +1789,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, /* implement empty response so apps like Tokodon don't show an error */ out = xs_list_new(); } + else + if (strcmp(opt, "lists") == 0) { + out = mastoapi_account_lists(&snac1, uid); + } } } @@ -1825,13 +1874,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (logged_in) { xs *l = notify_list(&snac1, 0, 64); xs *out = xs_list_new(); - const xs_dict *v; + const char *v; const xs_list *excl = xs_dict_get(args, "exclude_types[]"); + const xs_list *incl = xs_dict_get(args, "types[]"); const char *min_id = xs_dict_get(args, "min_id"); const char *max_id = xs_dict_get(args, "max_id"); const char *limit = xs_dict_get(args, "limit"); int limit_count = 0; - if (!xs_is_null(limit)) { + if (xs_is_string(limit)) { limit_count = atoi(limit); } @@ -1850,11 +1900,12 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, const char *utype = xs_dict_get(noti, "utype"); const char *objid = xs_dict_get(noti, "objid"); const char *id = xs_dict_get(noti, "id"); + const char *actid = xs_dict_get(noti, "actor"); xs *fid = xs_replace(id, ".", ""); xs *actor = NULL; xs *entry = NULL; - if (!valid_status(actor_get(xs_dict_get(noti, "actor"), &actor))) + if (!valid_status(actor_get(actid, &actor))) continue; if (objid != NULL && !valid_status(object_get(objid, &entry))) @@ -1895,7 +1946,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, continue; /* excluded type? */ - if (!xs_is_null(excl) && xs_list_in(excl, type) != -1) + if (xs_is_list(excl) && xs_list_in(excl, type) != -1) + continue; + + /* included type? */ + if (xs_is_list(incl) && xs_list_in(incl, type) == -1) continue; xs *mn = xs_dict_new(); @@ -1921,10 +1976,9 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } out = xs_list_append(out, mn); - if (!xs_is_null(limit)) { - if (--limit_count <= 0) - break; - } + + if (--limit_count <= 0) + break; } srv_debug(1, xs_fmt("mastoapi_notifications count %d", xs_list_len(out))); @@ -1975,21 +2029,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, else if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/ if (logged_in) { - xs *lol = list_maint(&snac1, NULL, 0); - xs *l = xs_list_new(); - int c = 0; - const xs_list *li; - - while (xs_list_next(lol, &li, &c)) { - xs *d = xs_dict_new(); - - d = xs_dict_append(d, "id", xs_list_get(li, 0)); - d = xs_dict_append(d, "title", xs_list_get(li, 1)); - d = xs_dict_append(d, "replies_policy", "list"); - d = xs_dict_append(d, "exclusive", xs_stock(XSTYPE_FALSE)); - - l = xs_list_append(l, d); - } + xs *l = mastoapi_account_lists(&snac1, NULL); *body = xs_json_dumps(l, 4); *ctype = "application/json"; @@ -2069,10 +2109,26 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(cmd, "/v1/follow_requests") == 0) { /** **/ - /* snac does not support optional follow confirmations */ - *body = xs_dup("[]"); - *ctype = "application/json"; - status = HTTP_STATUS_OK; + if (logged_in) { + xs *pend = pending_list(&snac1); + xs *resp = xs_list_new(); + const char *id; + + xs_list_foreach(pend, id) { + xs *actor = NULL; + + if (valid_status(object_get(id, &actor))) { + xs *acct = mastoapi_account(&snac1, actor); + + if (acct) + resp = xs_list_append(resp, acct); + } + } + + *body = xs_json_dumps(resp, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } } else if (strcmp(cmd, "/v1/announcements") == 0) { /** **/ @@ -2256,6 +2312,25 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, status = HTTP_STATUS_OK; } else + if (strcmp(cmd, "/v1/instance/peers") == 0) { /** **/ + /* get the collected inbox list as the instances "this domain is aware of" */ + xs *list = inbox_list(); + xs *peers = xs_list_new(); + const char *inbox; + + xs_list_foreach(list, inbox) { + xs *l = xs_split(inbox, "/"); + const char *domain = xs_list_get(l, 2); + + if (xs_is_string(domain)) + peers = xs_list_append(peers, domain); + } + + *body = xs_json_dumps(peers, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + else if (xs_startswith(cmd, "/v1/statuses/")) { /** **/ /* information about a status */ if (logged_in) { @@ -2707,14 +2782,24 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, msg = xs_dict_set(msg, "summary", summary); } - /* store */ - timeline_add(&snac, xs_dict_get(msg, "id"), msg); + /* scheduled? */ + const char *scheduled_at = xs_dict_get(args, "scheduled_at"); - /* 'Create' message */ - xs *c_msg = msg_create(&snac, msg); - enqueue_message(&snac, c_msg); + if (xs_is_string(scheduled_at) && *scheduled_at) { + msg = xs_dict_set(msg, "published", scheduled_at); - timeline_touch(&snac); + schedule_add(&snac, xs_dict_get(msg, "id"), msg); + } + else { + /* store */ + timeline_add(&snac, xs_dict_get(msg, "id"), msg); + + /* 'Create' message */ + xs *c_msg = msg_create(&snac, msg); + enqueue_message(&snac, c_msg); + + timeline_touch(&snac); + } /* convert to a mastodon status as a response code */ xs *st = mastoapi_status(&snac, msg); @@ -3160,6 +3245,57 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, status = HTTP_STATUS_OK; } else + if (xs_startswith(cmd, "/v1/follow_requests")) { /** **/ + if (logged_in) { + /* "authorize" or "reject" */ + xs *rel = NULL; + xs *l = xs_split(cmd, "/"); + const char *md5 = xs_list_get(l, -2); + const char *s_cmd = xs_list_get(l, -1); + + if (xs_is_string(md5) && xs_is_string(s_cmd)) { + xs *actor = NULL; + + if (valid_status(object_get_by_md5(md5, &actor))) { + const char *actor_id = xs_dict_get(actor, "id"); + + if (strcmp(s_cmd, "authorize") == 0) { + xs *fwreq = pending_get(&snac, actor_id); + + if (fwreq != NULL) { + xs *reply = msg_accept(&snac, fwreq, actor_id); + + enqueue_message(&snac, reply); + + if (xs_is_null(xs_dict_get(fwreq, "published"))) { + xs *date = xs_str_utctime(0, ISO_DATE_SPEC); + fwreq = xs_dict_set(fwreq, "published", date); + } + + timeline_add(&snac, xs_dict_get(fwreq, "id"), fwreq); + + follower_add(&snac, actor_id); + + pending_del(&snac, actor_id); + rel = mastoapi_relationship(&snac, md5); + } + } + else + if (strcmp(s_cmd, "reject") == 0) { + pending_del(&snac, actor_id); + rel = mastoapi_relationship(&snac, md5); + } + } + } + + if (rel != NULL) { + *body = xs_json_dumps(rel, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + } + } + else status = HTTP_STATUS_UNPROCESSABLE_CONTENT; /* user cleanup */ diff --git a/po/cs.po b/po/cs.po @@ -8,673 +8,673 @@ msgstr "" "Language: cs\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Citlivý obsah: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Varování k citlivému obsahu" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Pouze pro zmíněné osoby:" -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Odpovědět na (URL):" -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Nesdílet, pouze uložit do rozepsaných" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Rozepsané:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Přílohy..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Soubor:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Pro smazání přilohy vymažte toto pole" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Popisek přílohy" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Anketa..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Možnosti ankety (jedna na řádek, max 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Vyber jednu" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Vyber více možností" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Konec za 5 minut" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Konec za 1 hodinu" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Konec za 1 den" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Poslat" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Popisek stránky" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email administrátora" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Účet adminitrátora" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d sledovaných, %d sledujících" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "soukromé" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "veřejné" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "upozornění" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "lidé" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instance" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" msgstr "" "Vyhledejte příspěvek podle URL (regex), @uživatel@instance účtu, nebo #tagu" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Hledání obsahu" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "ověřený odkaz" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Místo: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nový příspěvek..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Co se vám honí hlavou?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operace..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Sledovat" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(podle URL nebo @uživatel@instance)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Boostit" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(podle URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Líbí" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Nastavení..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Jméno:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Vaše jméno" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Smazat současný avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Obrázek v záhlaví profilu: " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Smazat současný obrázek v záhlaví" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Bio:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Napište sem něco o sobě..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Vždy zobrazit příspěvky s varováním o citlivém obsahu" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Emailová adresa pro upozornění" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Upozornění na Telegram (bot klíč a chat id):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "ntfy notifikace (ntfy server a token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Životnost příspěvků ve dnech (0: nastavení serveru):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Zahodit soukromé zprávy od lidí, které nesledujete" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Tenhle účet je robot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Automaticky boostovat všechny zmíňky o tomto účtu" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "" "Tento účet je soukromý (příspěvky nejsou zobrazitelné napříč internetem)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Zobrazovat vlákna složená" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Žádosti o sledování je nutno manuálně potvrdit" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Zobraz údaje o počtu sledovaných a sledujících" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Geolokace:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Metadata profilu (klíč=hodnota na jeden řádek):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Jazyk rozhraní:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nové heslo:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Zopakujte nové heslo:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Uložit" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Sledované hashtagy..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Jeden hashtag na řádek" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Aktualizovat hashtagy" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Dejte najevo, že se vám příspěvek líbí" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Nelíbí" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Vlastně se mi to zas tak nelíbí" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Odepnout" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Odepnout tento příspěvek z vaší osy" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Připnout" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Připnout tento příspěvěk na začátek vaší osy" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Ukázat tenhle příspěvek vašim sledujícím" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Odboostit" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Boostit to byl blbej nápad" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Zahodit" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Odstraň tenhle příspěvěk ze svých záložek" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Uložit" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Uložit tenhle příspěvek mezi záložky" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Přestat sledovat" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Přestat sledovat tohoto uživatele" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Začít sledovat tohoto uživatele" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Přestat Sledovat Skupinu" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Přestat sledovat tuto skupinu nebo kanál" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Sledovat Skupinu" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Začít sledovat tuto skupinu nebo kanál" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "ZTIŠIT" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Jednou provždy zablokovat všechno od tohoto uživatele" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Smazat" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Smazat tento příspěvek" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Schovat" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Schovat tento příspěvek a příspěvky pod ním" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Editovat..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Odpovědět..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Ořezáno (moc hluboké)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "sleduje vás" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Připnuto" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Zazáložkováno" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Anketa" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Odhlasováno" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Událost" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "boostuje" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "odpověď pro" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr "[CITLIVÝ OBSAH]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Hlasuj" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Uzavřeno" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Končí za" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Příloha" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Popisek..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Čas:" -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Starší..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "o této stránce" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "pohání " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Zahodit" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Časová osa pro seznam '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Připnuté příspěvky" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Záložky" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Rozepsané příspěky" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Nic víc nového" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Zpátky nahoru" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historie" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Více..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Povolit boosty" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Zobrazovat boosty od tohoto uživatele" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Skrýt boosty" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Ztišit boosty od tohoto uživatele" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Smazat tohoto užiatele" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Schválit" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Schválit žádost o sledování" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Zahodit" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Zahodit žádost o sledování" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Zrušit ztišení" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Přestat blokovat tohoto uživatele" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Zablokovat všechno od tohoto uživatele" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Soukomá zpráva..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Dosud nepotvrzené žádosti o sledování" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Lidé, které sledujete" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Lidé, kteří vás sledují" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Smazat vše" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Zmínil vás" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Ukončená anketa" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Žádost o sledování" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Kontext" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nové" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Zobrazeno dříve" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Nic" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Výsledky vyhledávání účtu %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Účet %s nenalezen" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Výsledky k tagu %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Nic k tagu %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Výsledky vyhledávání pro '%s' (může toho být víc)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Výsledky vyhledávání pro '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Nic víc pro '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Žádný výsledek pro '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Časová osa místní instance" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Časová osa pro seznam '%s'" @@ -688,15 +688,15 @@ msgstr "Výsledky vyhledávání tagu #%s" msgid "Recent posts by users in this instance" msgstr "Nedávné příspěvky od uživatelů této instance" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Blokované hashtagy..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL adresa příspěvku, na který odpovědět" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,30 +708,54 @@ msgstr "" "Možnost 3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "API klíč Bota" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Chat id" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "ntfy server - celá URL adresa (např: https://ntfy.sh/VaseTema)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "ntfy token - pokud je zapotřebí" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "připnuté" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "záložky" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "rozepsané" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Naplánovat příspěvek..." + +msgid "Post date and time:" +msgstr "Den a čas:" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Naplánované příspěvky" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "naplánované příspěvky" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Den a čas (časové pásmo: %s)" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Časové pásmo:" diff --git a/po/el_GR.po b/po/el_GR.po @@ -14,120 +14,120 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.5\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Ευαίσθητο περιεχόμενο: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Περιγραφή ευαίσθητου περιεχομένου" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Μόνο για αναφερόμενα άτομα: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Απάντηση σε (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Μη δημοσιεύσεις, αλλά αποθήκευσε σαν προσχέδιο" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Προσχέδιο:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Επισυνάψεις..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Αρχείο:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Καθάρισε αυτό το πεδίο για να διαγράψεις την επισύναψη" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Περιγραφή επισύναψης" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Δημοσκόπηση..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Επιλογές δημοσκόπησης (μία ανά σειρά, μέχρι 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Μία επιλογή" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Πολλαπλές επιλογές" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Τελειώνει σε 5 λεπτά" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Τελειώνει σε 1 ώρα" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Τελειώνει σε 1 ημέρα" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Δημοσίευση" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Περιγραφή ιστότοπου" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email διαχειριστή" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Διαχειριστής" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d ακολουθείτε, %d ακόλουθοι" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "ιδιωτικό" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "δημόσιο" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "ειδοποιήσεις" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "άνθρωποι" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "διακομιστής" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -135,554 +135,554 @@ msgstr "" "Αναζήτηση δημοσιεύσεων με URL ή περιεχόμενο (κανονική έκφραση), " "@χρήστης@διακομιστής, ή #ετικέτα" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Αναζήτηση περιεχομένου" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "πιστοποιημένος σύνδεσμος" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Τοποθεσία: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Νέα Δημοσίευση..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Τι έχεις στο μυαλό σου;" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Λειτουργίες..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Ακολούθησε" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(με URL ή user@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Ενίσχυση" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(από URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Μου αρέσει" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Ρυθμίσεις Χρήστη..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Προβαλλόμενο όνομα:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Το όνομα σου" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Εικόνα προφίλ: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Διαγραφή τρέχουσας εικόνας προφίλ" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Εικόνα κεφαλίδας (banner): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Διαγραφή τρέχουσας εικόνας κεφαλίδας" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Βιογραφικό:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Γράψε για τον εαυτό σου εδώ..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Πάντα πρόβαλε ευαίσθητο περιεχόμενο" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Διεύθυνση email για ειδοποιήσεις:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Ειδοποιήσεις Telegram (κλειδί bot και chat id):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "ειδοποιήσεις ntfy (διακομιστής ntfy και token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Διατήρηση δημοσιεύσεων για ημέρες (0: ρυθμίσεις διακομιστή):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Απόρριψη άμεσων μηνυμάτων από άτομα που δεν ακολουθείτε" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Αυτός ο λογαριασμός είναι αυτοματοποιημένος (bot)" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Αυτόματη ενίσχυση όλων των αναφορών σε αυτό το λογαριασμό" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "" "Αυτός ο λογαριασμός είναι ιδιωτικός (οι δημοσιεύσεις δεν εμφανίζονται στο " "διαδίκτυο)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Αναδίπλωση κορυφαίων συζητήσεων εξ'ορισμού" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Τα αιτήματα ακόλουθων πρέπει να εγκρίνονται" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Δημοσίευση στατιστικών ακόλουθων και ακολουθούμενων" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Τρέχουσα τοποθεσία:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Μεταστοιχεία προφίλ (κλειδί=τιμή ζευγάρια σε κάθε γραμμή):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Γλώσσα περιβάλλοντος web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Νέος κωδικός:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Επανάληψη νέου κωδικού:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Ενημέρωση στοιχείων χρήστη" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Ετικέτες που ακολουθείτε..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Μία ετικέτα ανά γραμμή" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Ενημέρωση ετικετών" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Ανάφερε ότι σου αρέσει αυτή η δημοσίευση" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Αναίρεση μου αρέσει" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Μπα δεν μ' αρέσει τόσο" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Ξεκαρφίτσωμα" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Ξεκαρφίτσωμα αυτής της δημοσίευσης από τη ροή σας" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Καρφίτσωμα" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Καρφίτσωμα αυτής της δημοσίευσης στη κορυφή της ροής σας" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Ανακοίνωση αυτής της δημοσίευσης στους ακόλουθους σας" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Αφαίρεση ενίσχυσης" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Μετάνιωσα που το ενίσχυσα" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Αφαίρεση σελιδοδείκτη" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Διαγραφή αυτής της δημοσίευσης από τους σελιδοδείκτες σου" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Εισαγωγή σελιδοδείκτη" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Προσθήκη αυτής της δημοσίευσης στους σελιδοδείκτες σου" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Αναίρεση ακολουθίας" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Σταμάτα να ακολουθείς τη δραστηριότητα αυτού του χρήστη" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Ξεκίνα να ακολουθείς τη δραστηριότητα αυτού του χρήστη" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Αναίρεση ακολουθίας ομάδας" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Σταμάτα να ακολουθείς αυτή την ομάδα ή κανάλι" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Ακολούθησε την Ομάδα" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Ξεκίνα να ακολουθείς αυτή την ομάδα ή κανάλι" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "ΣΙΓΑΣΗ" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Αποκλεισμός οποιασδήποτε δραστηριότητας από αυτόν τον χρήστη για πάντα" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Διαγραφή" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Διαγραφή αυτής της δημοσίευσης" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Απόκρυψη" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Απόκρυψη αυτής της δημοσίευσης και των απαντήσεων της" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Επεξεργασία..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Απάντηση..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Έγινε περικοπή (πολύ βαθύ)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "σε ακολουθεί" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Καρφιτσωμένο" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Εισήχθηκε σελιδοδείκτης" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Δημοσκόπηση" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Ψήφισες" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Εκδήλωση" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "ενισχύθηκε" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "σε απάντηση του" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [ΕΥΑΙΣΘΗΤΟ ΠΕΡΙΕΧΟΜΕΝΟ]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Ψήφισε" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Έκλεισε" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Κλείνει σε" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Βίντεο" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Ήχος" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Επισύναψη" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Εναλλακτικό κείμενο..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Πηγή κανάλι ή κοινότητα" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Ώρα: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Παλαιότερα..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "σχετικά με αυτό τον ιστότοπο" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "λειτουργεί με " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Απόρριψη" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Ροή για λίστα '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Καρφιτσωμένες δημοσιεύσεις" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Σελιδοδείκτες" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Προσχέδια δημοσιεύσεων" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Δεν υπάρχουν άλλες αδιάβαστες δημοσιεύσεις" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Πίσω στη κορυφή" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Ιστορικό" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Περισσότερα..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Αφαίρεση περιορισμού" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Επέτρεψε ανακοινώσεις (ενισχύσεις) από αυτό το χρήστη" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Περιορισμός" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Απέκλεισε ανακοινώσεις (ενισχύσεις) από αυτό το χρήστη" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Διαγραφή αυτού του χρήστη" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Έγκριση" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Έγκριση αυτού του αιτήματος ακόλουθου" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Απόρριψη" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Απόρριψη αυτού του αιτήματος ακόλουθου" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Αφαίρεση σίγασης" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Διακοπή αποκλεισμού δραστηριοτήτων από αυτό το χρήστη" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Αποκλεισμός οποιασδήποτε δραστηριότητας από αυτό τον χρήστη" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Απευθείας Μήνυμα..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Εκκεμείς επιβεβαιώσεις ακολουθήσεων" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Άνθρωποι που ακολουθείτε" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Άνθρωποι που σας ακολουθούν" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Εκκαθάριση όλων" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Αναφορά" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Ολοκληρωμένη δημοσκόπηση" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Αίτημα Ακόλουθου" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Περιεχόμενο" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Νέο" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Έχει ήδη προβληθεί" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Κανένα" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Αποτελέσματα αναζήτηση για λογαριασμό %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Ο λογαριασμός %s δεν βρέθηκε" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Αποτελέσματα αναζήτησης για ετικέτα %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Δε βρέθηκε κάτι για ετικέτα %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Αποτελέσματα αναζήτησης για '%s' (μπορεί να υπάρχουν περισσότερα)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Αποτελέσματα αναζήτησης για '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Δεν υπάρχουν άλλα αποτελέσματα για '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Δε βρέθηκε κάτι για '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Προβάλλεται η ροή του διακομιστή" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Προβάλετε η ροή της λίστας '%s'" @@ -696,15 +696,15 @@ msgstr "Αποτελέσματα αναζήτησης για ετικέτα #%s" msgid "Recent posts by users in this instance" msgstr "Πρόσφατες αναρτήσεις από χρήστες σε αυτό τον ιστότοπο" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Αποκλεισμένες ετικέτες..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -712,30 +712,54 @@ msgid "" "..." msgstr "" -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "" + +msgid "Post date and time:" +msgstr "" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "" + +#: html.c:1538 +msgid "Time zone:" +msgstr "" diff --git a/po/en.po b/po/en.po @@ -8,671 +8,671 @@ msgstr "" "Language: en\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "" -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "" -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "" -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "" -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "" -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" msgstr "" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "" -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "" -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "" -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "" -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "" -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "" -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "" -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "" -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "" -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "" -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr "" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "" -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "" -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "" -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "" -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "" -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "" -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "" @@ -686,15 +686,15 @@ msgstr "" msgid "Recent posts by users in this instance" msgstr "" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "" -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -702,30 +702,54 @@ msgid "" "..." msgstr "" -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "" + +msgid "Post date and time:" +msgstr "" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "" + +#: html.c:1538 +msgid "Time zone:" +msgstr "" diff --git a/po/es.po b/po/es.po @@ -8,120 +8,120 @@ msgstr "" "Language: es\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Contenido sensible: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Descripción del contenido sensible" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Solo personas mencionadas: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Responder a (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "No enviar. Guardar como borrador" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Borrador:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Adjuntos..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Archivo:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Limpiar este campo para eliminar el adjunto" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Descripción del adjunto" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Encuesta..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Opciones de encuesta (una por línea, hasta 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Una opción" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Opciones múltiples" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Finalizar en 5 minutos" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Finalizar en 1 hora" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Finalizar en 1 día" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Publicar" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Descripción del sitio" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email del Administrador" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Cuenta del Administrador" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d siguiendo, %d seguidores" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privado" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "público" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notificaciones" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "personas" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instancia" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -129,554 +129,554 @@ msgstr "" "Buscar publicaciones por URL o contenido (expresiones regulares), cuenta " "@usuario@host , ó #etiqueta" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Buscar contenido" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "link verificado" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Ubicación: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nueva Publicación..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "¿En qué estás pensando?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operaciones..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Seguir" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(por URL o usuario@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Impulsar" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(por URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Me gusta" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Configuración de usuario..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nombre para mostrar:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Su nombre" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Eliminar avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Imagen de cabecera (banner): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Eliminar imagen de cabecera" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Bio:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Escriba algo sobre usted aquí..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Siempre mostrar contenido sensible" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Cuenta de email para las notificaciones:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notificaciones en Telegram (llave del bot e id del chat):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "Notificaciones en ntfy (servidor ntfy y token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "" "Plazo máximo de conservación de publicaciones en días (0: usar configuración " "del servidor):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Descartar mensajes directos de personas a las que no sigue" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Esta cuenta es un bot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Impulsar automáticamente todas las menciones a esta cuenta" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Esta cuenta es privada (las publicaciones no se muestran en la web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Contraer hilo de publicaciones por defecto" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Las solicitudes de seguimiento deben ser aprobadas" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Mostrar cantidad de seguidores y seguidos" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Ubicación actual:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Metadata del perfil (pares llave=valor en cada línea):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Idioma de la interfaz Web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nueva contraseña:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Repetir nueva contraseña:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Actualizar información de usuario" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Etiquetas en seguimiento..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Una etiqueta por línea" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Actualizar etiquetas" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Decir que te gusta esta publicación" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "No me gusta" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Nah, no me gusta tanto" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Desanclar" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Desanclar esta publicación de su línea de tiempo" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Anclar" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Anclar esta publicación al inicio de su línea de tiempo" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Anunciar esta publicación a sus seguidores" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Eliminar impulso" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Me arrepiento de haber impulsado esto" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Eliminar marcador" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Eliminar marcador de esta publicación" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Marcador" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Agregar esta publicación a mis marcadores" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Dejar de seguir" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Dejar de seguir la actividad de este usuario" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Seguir la actividad de este usuario" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Dejar de seguir este Grupo" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Dejar de seguir este grupo o canal" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Seguir Grupo" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Seguir grupo o canal" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "SILENCIAR" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Bloquear toda la actividad de este usuario para siempre" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Eliminar" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Eliminar esta publicación" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Ocultar" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Ocultar esta publicación y sus respuestas" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Editar..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Responder..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Truncado (demasiado profundo)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "te sigue" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Anclado" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Marcado" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Encuesta" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Votado" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Evento" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "impulsado" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "en respuesta a" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTENIDO SENSIBLE]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Votar" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Cerrado" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Cierra en" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Adjunto" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Alt..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Canal o comunidad de origen" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Hora: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Más antiguo..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "acerca de este sitio" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "provisto por " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Descartar" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Línea de tiempo de la lista '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Publicaciones ancladas" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Publicaciones marcadas" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Borradores de publicaciones" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "No quedan publicaciones sin ver" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Volver al inicio" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historia" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Más..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Sin límite" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Permitir anuncios (impulsos) de este usuario" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Límite" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Bloquear anuncios (impulsos) de este usuario" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Eliminar este usuario" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Aprobar" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Aprobar solicitud de seguimiento" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Descartar" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Descartar solicitud de seguimiento" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Dejar de SILENCIAR" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Dejar de bloquear actividad de este usuario" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Bloquear toda actividad de este usuario" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Mensaje Directo..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Confirmaciones de seguimiento pendientes" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Personas que sigues" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Personas que te siguen" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Limpiar todo" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Mención" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Encuesta finalizada" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Solicitud de Seguimiento" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contexto" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nuevo" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Ya visto" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Ninguno" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Buscar resultados para la cuenta %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "No se encontró la cuenta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Buscar resultados para la etiqueta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "No se encontró nada con la etiqueta %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Resultados de búsqueda para '%s' (puede haber más)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Resultados de búsqueda para '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "No hay más coincidencias para '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "No se encontró nada para '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Mostrando línea de tiempo de la instancia" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Mostrando línea de tiempo de la lista '%s'" @@ -690,15 +690,15 @@ msgstr "Resultado de búsqueda para la etiqueta #%s" msgid "Recent posts by users in this instance" msgstr "Publicaciones recientes de los usuarios de esta instancia" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Etiquetas bloqueadas..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL opcional a la que responder" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,31 +708,53 @@ msgstr "" "Opción 1...\n" "Opción 2...\n" "Opción 3...\n" +"..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Clave del API del Bot" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Identificador de chat" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "Servidor ntfy - URL completa (example: https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "Token ntft - si es necesario" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "Anclados" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "Marcados" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "Borradores" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Envío programado..." + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Envíos programados" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "envíos programados" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Fecha y hora de publicación (zona horaria: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Zona horaria:" diff --git a/po/es_AR.po b/po/es_AR.po @@ -8,120 +8,120 @@ msgstr "" "Language: es_AR\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Contenido sensible: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Descripción del contenido sensible" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Solo personas mencionadas: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Responder a (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "No enviar. Guardar como borrador" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Borrador:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Adjuntos..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Archivo:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Limpiar este campo para eliminar el adjunto" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Descripción del adjunto" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Encuesta..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Opciones de encuesta (una por línea, hasta 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Una opción" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Opciones múltiples" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Finalizar en 5 minutos" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Finalizar en 1 hora" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Finalizar en 1 día" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Publicar" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Descripción del sitio" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email del Administrador" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Cuenta del Administrador" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d siguiendo, %d seguidores" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privado" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "público" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notificaciones" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "personas" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instancia" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -129,554 +129,554 @@ msgstr "" "Buscar publicaciones por URL o contenido (expresiones regulares), cuenta " "@usuario@host , ó #etiqueta" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Buscar contenido" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "link verificado" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Ubicación: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nueva Publicación..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "¿En qué estás pensando?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operaciones..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Seguir" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(por URL o usuario@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Impulsar" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(por URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Me gusta" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Configuración de usuario..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nombre para mostrar:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Su nombre" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Eliminar avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Imagen de cabecera (banner): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Eliminar imagen de cabecera" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Bio:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Escriba algo sobre usted aquí..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Siempre mostrar contenido sensible" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Cuenta de email para las notificaciones:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notificaciones en Telegram (llave del bot e id del chat):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "Notificaciones en ntfy (servidor ntfy y token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "" "Plazo máximo de conservación de publicaciones en días (0: usar configuración " "del servidor):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Descartar mensajes directos de personas a las que no sigue" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Esta cuenta es un bot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Impulsar automáticamente todas las menciones a esta cuenta" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Esta cuenta es privada (las publicaciones no se muestran en la web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Contraer hilo de publicaciones por defecto" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Las solicitudes de seguimiento deben ser aprobadas" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Mostrar cantidad de seguidores y seguidos" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Ubicación actual:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Metadata del perfil (pares llave=valor en cada línea):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Idioma de la interfaz Web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nueva contraseña:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Repetir nueva contraseña:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Actualizar información de usuario" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Etiquetas en seguimiento..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Una etiqueta por línea" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Actualizar etiquetas" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Decir que te gusta esta publicación" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "No me gusta" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Nah, no me gusta tanto" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Desanclar" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Desanclar esta publicación de su línea de tiempo" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Anclar" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Anclar esta publicación al inicio de su línea de tiempo" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Anunciar esta publicación a sus seguidores" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Eliminar impulso" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Me arrepiento de haber impulsado esto" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Eliminar marcador" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Eliminar marcador de esta publicación" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Marcador" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Agregar esta publicación a mis marcadores" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Dejar de seguir" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Dejar de seguir la actividad de este usuario" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Seguir la actividad de este usuario" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Dejar de seguir este Grupo" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Dejar de seguir este grupo o canal" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Seguir Grupo" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Seguir grupo o canal" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "SILENCIAR" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Bloquear toda la actividad de este usuario para siempre" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Eliminar" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Eliminar esta publicación" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Ocultar" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Ocultar esta publicación y sus respuestas" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Editar..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Responder..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Truncado (demasiado profundo)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "te sigue" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Anclado" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Marcado" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Encuesta" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Votado" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Evento" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "impulsado" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "en respuesta a" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTENIDO SENSIBLE]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Votar" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Cerrado" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Cierra en" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Adjunto" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Alt..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Canal o comunidad de origen" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Hora: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Más antiguo..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "acerca de este sitio" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "provisto por " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Descartar" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Línea de tiempo de la lista '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Publicaciones ancladas" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Publicaciones marcadas" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Borradores de publicaciones" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "No quedan publicaciones sin ver" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Volver al inicio" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historia" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Más..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Sin límite" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Permitir anuncios (impulsos) de este usuario" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Límite" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Bloquear anuncios (impulsos) de este usuario" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Eliminar este usuario" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Aprobar" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Aprobar solicitud de seguimiento" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Descartar" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Descartar solicitud de seguimiento" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Dejar de SILENCIAR" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Dejar de bloquear actividad de este usuario" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Bloquear toda actividad de este usuario" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Mensaje Directo..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Confirmaciones de seguimiento pendientes" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Personas que sigues" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Personas que te siguen" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Limpiar todo" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Mención" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Encuesta finalizada" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Solicitud de Seguimiento" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contexto" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nuevo" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Ya visto" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Ninguno" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Buscar resultados para la cuenta %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "No se encontró la cuenta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Buscar resultados para la etiqueta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "No se encontró nada con la etiqueta %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Resultados de búsqueda para '%s' (puede haber más)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Resultados de búsqueda para '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "No hay más coincidencias para '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "No se encontró nada para '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Mostrando línea de tiempo de la instancia" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Mostrando línea de tiempo de la lista '%s'" @@ -690,15 +690,15 @@ msgstr "Resultado de búsqueda para la etiqueta #%s" msgid "Recent posts by users in this instance" msgstr "Publicaciones recientes de los usuarios de esta instancia" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Etiquetas bloqueadas..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL opcional a la que responder" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,31 +708,53 @@ msgstr "" "Opción 1...\n" "Opción 2...\n" "Opción 3...\n" +"..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Clave del API del Bot" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Identificador de chat" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "Servidor ntfy - URL completa (example: https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "Token ntft - si es necesario" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "Anclados" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "Marcados" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "Borradores" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Envío programado..." + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Envíos programados" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "envíos programados" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Fecha y hora de publicación (zona horaria: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Zona horaria:" diff --git a/po/es_UY.po b/po/es_UY.po @@ -8,120 +8,120 @@ msgstr "" "Language: es_UY\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Contenido sensible: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Descripción del contenido sensible" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Solo personas mencionadas: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Responder a (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "No enviar. Guardar como borrador" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Borrador:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Adjuntos..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Archivo:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Limpiar este campo para eliminar el adjunto" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Descripción del adjunto" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Encuesta..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Opciones de encuesta (una por línea, hasta 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Una opción" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Opciones múltiples" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Finalizar en 5 minutos" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Finalizar en 1 hora" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Finalizar en 1 día" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Publicar" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Descripción del sitio" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email del Administrador" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Cuenta del Administrador" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d siguiendo, %d seguidores" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privado" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "público" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notificaciones" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "personas" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instancia" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -129,554 +129,554 @@ msgstr "" "Buscar publicaciones por URL o contenido (expresiones regulares), cuenta " "@usuario@host , ó #etiqueta" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Buscar contenido" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "link verificado" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Ubicación: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nueva Publicación..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "¿En qué estás pensando?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operaciones..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Seguir" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(por URL o usuario@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Impulsar" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(por URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Me gusta" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Configuración de usuario..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nombre para mostrar:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Su nombre" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Eliminar avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Imagen de cabecera (banner): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Eliminar imagen de cabecera" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Bio:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Escriba algo sobre usted aquí..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Siempre mostrar contenido sensible" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Cuenta de email para las notificaciones:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notificaciones en Telegram (llave del bot e id del chat):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "Notificaciones en ntfy (servidor ntfy y token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "" "Plazo máximo de conservación de publicaciones en días (0: usar configuración " "del servidor):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Descartar mensajes directos de personas a las que no sigue" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Esta cuenta es un bot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Impulsar automáticamente todas las menciones a esta cuenta" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Esta cuenta es privada (las publicaciones no se muestran en la web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Contraer hilo de publicaciones por defecto" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Las solicitudes de seguimiento deben ser aprobadas" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Mostrar cantidad de seguidores y seguidos" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Ubicación actual:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Metadata del perfil (pares llave=valor en cada línea):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Idioma de la interfaz Web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nueva contraseña:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Repetir nueva contraseña:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Actualizar información de usuario" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Etiquetas en seguimiento..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Una etiqueta por línea" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Actualizar etiquetas" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Decir que te gusta esta publicación" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "No me gusta" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Nah, no me gusta tanto" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Desanclar" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Desanclar esta publicación de su línea de tiempo" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Anclar" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Anclar esta publicación al inicio de su línea de tiempo" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Anunciar esta publicación a sus seguidores" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Eliminar impulso" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Me arrepiento de haber impulsado esto" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Eliminar marcador" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Eliminar marcador de esta publicación" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Marcador" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Agregar esta publicación a mis marcadores" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Dejar de seguir" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Dejar de seguir la actividad de este usuario" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Seguir la actividad de este usuario" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Dejar de seguir este Grupo" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Dejar de seguir este grupo o canal" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Seguir Grupo" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Seguir grupo o canal" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "SILENCIAR" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Bloquear toda la actividad de este usuario para siempre" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Eliminar" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Eliminar esta publicación" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Ocultar" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Ocultar esta publicación y sus respuestas" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Editar..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Responder..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Truncado (demasiado profundo)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "te sigue" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Anclado" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Marcado" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Encuesta" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Votado" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Evento" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "impulsado" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "en respuesta a" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTENIDO SENSIBLE]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Votar" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Cerrado" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Cierra en" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Adjunto" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Alt..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Canal o comunidad de origen" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Hora: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Más antiguo..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "acerca de este sitio" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "provisto por " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Descartar" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Línea de tiempo de la lista '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Publicaciones ancladas" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Publicaciones marcadas" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Borradores de publicaciones" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "No quedan publicaciones sin ver" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Volver al inicio" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historia" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Más..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Sin límite" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Permitir anuncios (impulsos) de este usuario" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Límite" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Bloquear anuncios (impulsos) de este usuario" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Eliminar este usuario" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Aprobar" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Aprobar solicitud de seguimiento" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Descartar" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Descartar solicitud de seguimiento" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Dejar de SILENCIAR" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Dejar de bloquear actividad de este usuario" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Bloquear toda actividad de este usuario" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Mensaje Directo..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Confirmaciones de seguimiento pendientes" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Personas que sigues" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Personas que te siguen" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Limpiar todo" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Mención" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Encuesta finalizada" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Solicitud de Seguimiento" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contexto" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nuevo" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Ya visto" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Ninguno" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Buscar resultados para la cuenta %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "No se encontró la cuenta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Buscar resultados para la etiqueta %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "No se encontró nada con la etiqueta %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Resultados de búsqueda para '%s' (puede haber más)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Resultados de búsqueda para '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "No hay más coincidencias para '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "No se encontró nada para '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Mostrando línea de tiempo de la instancia" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Mostrando línea de tiempo de la lista '%s'" @@ -690,15 +690,15 @@ msgstr "Resultado de búsqueda para la etiqueta #%s" msgid "Recent posts by users in this instance" msgstr "Publicaciones recientes de los usuarios de esta instancia" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Etiquetas bloqueadas..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL opcional a la que responder" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,31 +708,53 @@ msgstr "" "Opción 1...\n" "Opción 2...\n" "Opción 3...\n" +"..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Clave del API del Bot" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Identificador de chat" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "Servidor ntfy - URL completa (example: https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "Token ntft - si es necesario" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "Anclados" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "Marcados" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "Borradores" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Envío programado..." + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Envíos programados" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "envíos programados" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Fecha y hora de publicación (zona horaria: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Zona horaria:" diff --git a/po/fi.po b/po/fi.po @@ -8,120 +8,120 @@ msgstr "" "Language: fi\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Arkaluontoista sisältöä: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Arkaluontoisen sisällön kuvaus" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Vain mainituille: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Vastaus (osoite): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Älä lähetä, tallenna luonnoksena" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Luonnos:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Liitteet..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Tiedosto:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Tyhjennä kenttä poistaaksesi liiteen" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Liitteen kuvaus" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Kysely..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Kyselyn vaihtoehdot (riveittäin, korkeintaan 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Yksi valinta" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Monta valintaa" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Päättyy viiden minuutin päästä" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Päättyy tunnin päästä" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Päättyy päivän päästä" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Julkaise" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Sivuston kuvaus" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Ylläpitäjän sähköposti" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Ylläpitäjän tili" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "Seuraa %d, %d seuraajaa" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "yksityinen" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "julkinen" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "ilmoitukset" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "ihmiset" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "palvelin" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -129,552 +129,552 @@ msgstr "" "Etsi julkaisuja osoitteella tai sisällön perusteella, @käyttäjä@palvelin " "tai #tagi" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Sisälöhaku" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "varmistettu linkki" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Sijainti: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Uusi julkaisu..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Mitä on mielessäsi?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Toiminnot..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Seuraa" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(osoite tai käyttäjä@palvelin)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Tehosta" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(osoite)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Tykkää" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Käyttäjäasetukset..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Näytetty nimi:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Nimesi" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Poista nykyinen avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Otsikkokuva: " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Poista nykyinen otsikkokuva" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Kuvaus:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Kirjoita itsestäsi tähän..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Näytä arkaluontoinen sisältö aina" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Sähköposti ilmoituksille:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Telegram-ilmoitukset (botin avain ja chat id):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "nfty-ilmoitukset (ntfy-palvelin ja token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Säilytä julkaisut korkeintaan (päivää, 0: palvelimen asetukset)" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Poista yksityisviestit ihmisiltä, joita et seuraa" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Tämä tili on botti" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Tehosta tilin maininnat automaattisesti" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Tili on yksityinen (julkaisuja ei näytetä sivustolla)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Avaa säikeet automaattisesti" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Vaadi hyväksyntä seurantapyynnöille" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Julkaise seuraamistilastot" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Nykyinen sijainti:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Profiilin metadata (avain=arvo, riveittäin):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Käyttöliitymän kieli:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Uusi salasana:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Toista salasana:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Päivitä käyttäjätiedot" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Seuratut aihetunnisteet..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Aihetunnisteet, riveittäin" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Päivitä aihetunnisteet" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Tykkää tästä julkaisusta" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Poista tykkäys" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Ei ole omaan makuuni" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Poista kiinnitys" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Poista julkaisun kiinnitys aikajanalle" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Kiinnitä" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Kiinnitä julkaisu aikajanasi alkuun" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Ilmoita julkaisusta seuraajillesi" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Poista tehostus" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Kadun tehostaneeni tätä" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Poista kirjanmerkki" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Poista julkaisu kirjanmerkeistäsi" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Lisää kirjanmerkki" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Lisää julkaisu kirjanmerkkeihisi" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Älä seuraa" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Lakkaa seuraamasta käyttäjän toimintaa" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Seuraa käyttäjän toimintaa" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Älä seuraa ryhmää" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Lopeta ryhnän tai kanavan seuraaminen" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Seuraa ryhmää" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Seuraa tätä ryhmää tai kanavaa" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "VAIMENNA" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Estä kaikki toiminta tältä käyttäjältä" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Poista" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Poista julkaisu" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Piilota" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Piilota julkaisu ja vastaukset" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Muokkaa..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Vastaa..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Katkaistu (liian syvä)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "seuraa sinua" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Kiinnitetty" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Kirjanmerkitty" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Kysely" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Äänestetty" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Tapahtuma" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "tehostettu" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "vastauksena" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [ARKALUONTOISTA SISÄLTÖÄ]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Äänestä" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Sulkeutunut" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Sulkeutuu" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Ääni" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Liite" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Kuvaus..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Lähdekanava tai -yhteisö" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Aika: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Vanhemmat..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "tietoa sivustosta" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "moottorina " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Kuittaa" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Listan ”%s” aikajana" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Kiinnitetyt julkaisut" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Kirjanmerkit" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Vedokset" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Ei lukemattonia julkaisuja" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Takaisin" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historia" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Enemmän..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Poista rajoitus" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Salli tehostukset käyttäjältä" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Rajoita" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Kiellö tehostukset käyttäjältä" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Poista käyttäjä" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Hyväksy" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Hyväksy seurantapyyntö" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Hylkää" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Hylkää seurantapyyntö" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Poista vaimennus" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Salli toiminta käyttäjältä" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Estä kaikki toiminnat käyttäjältä" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Yksityisviesti..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Hyväksymistä odottavat seurantapyynnöt" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Seuraamasi ihniset" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Sinua seuraavat" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Tyhjennä" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Mainitse" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Päättynyt kysely" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Seurantapyyntö" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Konteksti" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Uusi" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Nähty" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Ei ilmoituksia" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Hakutulokset tilille %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Tiliä %s ei löytynyt" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Hakutulokset aihetunnisteelle %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Aihetunnisteella %s ei löytynyt tuloksia" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Tulokset haulle ”%s” (mahdollisesti enemmän tuloksia)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Tulokset haulle ”%s”" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Ei enempää tuloksia haulle ”%s”" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Haulla ”%s” ei löytynyt tuloksia" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Palvelimen aikajana" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Listan ”%s” aikajana" @@ -688,15 +688,15 @@ msgstr "Hakutulokset aihetunnisteelle #%s" msgid "Recent posts by users in this instance" msgstr "Viimeaikaisia julkaisuja tällä palvelimella" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Estetyt aihetunnisteet..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "Vastaus julkaisuun (osoite, valinnainen)" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,30 +708,54 @@ msgstr "" "Vaihtoehto 3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "botin API-avain" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "chat id" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "ntfy-palvelin - täydellinen osoite (esim: https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "ntfy token - tarvittaessa" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "kiinnitetyt" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "kirjanmerkit" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "vedokset" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Ajastettu julkaisu..." + +msgid "Post date and time:" +msgstr "Julkaisuajankohta:" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Ajastetut julkaisut" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "ajastetut julkaisut" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Julkaisuajankohta (aikavyöhyke: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Aikavyöhyke: " diff --git a/po/fr.po b/po/fr.po @@ -8,674 +8,674 @@ msgstr "" "Language: fr\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Contenu sensible :" -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Description du contenu sensible :" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Seulement pour les personnes mentionnées :" -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Répondre à (URL) :" -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Ne pas envoyer, mais sauvegarder en tant que brouillon" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Brouillon :" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Pièces jointes…" -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Fichier :" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" -msgstr "Nettoyer ce champs pour supprimer l'attachement" +msgstr "Nettoyer ce champs pour supprimer la pièce jointe" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" -msgstr "Description de l'attachement" +msgstr "Description de la pièce jointe" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Sondage…" -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Options du sondage (une par ligne, jusqu'à 8) :" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Un seul choix" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Choix multiples" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Se termine dans 5 minutes" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Se termine dans 1 heure" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Se termine dans 1 jour" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Envoyer" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Description du site" -#: html.c:671 +#: html.c:719 msgid "Admin email" -msgstr "email de l'admin" +msgstr "Email de l'admin" -#: html.c:684 +#: html.c:732 msgid "Admin account" -msgstr "compte de l'admin" +msgstr "Compte de l'admin" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" -msgstr "Suit %d, %d suiveurs" +msgstr "%d abonnements, %d personnes abonnées" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privé" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "public" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notifications" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "personnes" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instance" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" msgstr "" "Chercher les messages par URL ou contenu (expression régulière), comptes " -"@utilisateur@hôte, ou #tag" +"@pseudo@hôte, ou #tag" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Recherche de contenu" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "Lien vérifié" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Emplacement : " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nouveau message…" -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Qu'avez-vous en tête ?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Opérations…" -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Suivre" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" -msgstr "(par URL ou utilisateur@hôte)" +msgstr "(par URL ou pseudo@hôte)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" -msgstr "repartager" +msgstr "Repartager" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(par URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Aime" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." -msgstr "Réglages utilisateur…" +msgstr "Paramètre du compte…" -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nom affiché :" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Votre nom" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar : " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Supprimer l'avatar actuel" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Image d'entête (bannière) : " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Supprimer l'image d'entête actuelle" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" -msgstr "CV :" +msgstr "Description :" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Décrivez-vous ici…" -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Toujours afficher le contenu sensible" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Adresse email pour les notifications :" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notifications Telegram (clé de bot et ID de discussion) :" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "notifications ntfy (serveur et jeton ntfy) :" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "" "Nombre de jours maximum de rétention des messages (0 : réglages du serveur) :" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Rejeter les messages directs des personnes que vous ne suivez pas" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Ce compte est un bot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Auto-repartage de toutes les mentions de ce compte" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Ce compte est privé (les messages ne sont pas affiché sur le web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "replier les fils de discussion principaux par défaut" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Les demande de suivi doivent être approuvées" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" -msgstr "Publier les suiveurs et les statistiques de suivis" +msgstr "Publier les statistiques d'abonnements" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Localisation actuelle :" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Métadonnées du profile (paires clé=valeur à chaque ligne) :" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Langue de l'interface web :" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nouveau mot de passe :" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Répétez le nouveau mot de passe :" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" -msgstr "Mettre à jour les infos utilisateur" +msgstr "Mettre à jour les infos du compte" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "hashtags suivis…" -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Un hashtag par ligne" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Mettre à jour les hashtags" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Dire que vous aimez ce message" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "N'aime plus" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Nan, j'aime pas tant que ça" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Dés-épingler" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Dés-épingler ce message de votre chronologie" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Épingler" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Épingler ce message en haut de votre chronologie" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" -msgstr "Annoncer ce message à vos suiveurs" +msgstr "Annoncer ce message aux personnes abonnées" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Dé-repartager" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Je regrette d'avoir repartagé ceci" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Retirer le signet" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Supprime ce message de vos signets" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Signet" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Ajouter ce message à vos signets" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Ne plus suivre" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" -msgstr "Arrêter de suivre les activités de cet utilisateur" +msgstr "Arrêter de suivre les activités de cette personne" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" -msgstr "Commencer à suivre les activité de cet utilisateur" +msgstr "Commencer à suivre les activité de cette personne" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Ne plus suivre le Groupe" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Arrêter de suivre ce groupe ou canal" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Suivre le Groupe" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Commencer à suivre ce groupe ou canal" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" -msgstr "TAIRE" +msgstr "SOURDINE" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" -msgstr "Bloquer toute activité de cet utilisateur à jamais" +msgstr "Bloquer toute activité de cette personne à jamais" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Supprimer" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Supprimer ce message" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Cacher" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Cacher ce message et ses réponses" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." -msgstr "Éditer…" +msgstr "Modifier…" -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Répondre…" -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Tronqué (trop profond)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "vous suit" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Épinglé" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" -msgstr "Ajouté au signets" +msgstr "Ajouté aux signets" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Sondage" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Voté" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Événement" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "Repartagé" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "En réponse à" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTENU SENSIBLE]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Vote" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Terminé" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Termine dans" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Vidéo" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" -msgstr "Attachement" +msgstr "Pièce jointe" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Alt…" -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Canal ou communauté source" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Date : " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Plus anciens…" -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "à propos de ce site" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "fonctionne grace à " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Rejeter" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Chronologie pour la liste '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Messages épinglés" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Messages en signets" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Brouillons de messages" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Pas d'avantage de message non vus" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Retourner en haut" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Historique" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Plus…" -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Illimité" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" -msgstr "Permettre les annonces (repartages) par cet utilisateur" +msgstr "Permettre les annonces (repartages) par cette personne" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Limite" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" -msgstr "Bloquer les annonces (repartages) par cet utilisateur" +msgstr "Bloquer les annonces (repartages) par cette personne" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" -msgstr "Supprimer cet utilisateur" +msgstr "Supprimer cette personne" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Approuver" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" -msgstr "Approuver cette demande de suivit" +msgstr "Approuver cette demande de suivi" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Rejeter" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Rejeter la demande suivante" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Ne plus taire" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" -msgstr "Arrêter de bloquer les activités de cet utilisateur" +msgstr "Arrêter de bloquer les activités de cette personne" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" -msgstr "Bloque toutes les activités de cet utilisateur" +msgstr "Bloque toutes les activités de cette personne" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Message direct…" -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" -msgstr "Confirmation de suivit en attente" +msgstr "Confirmation de suivi en attente" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Personnes que vous suivez" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Personnes qui vous suivent" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Tout nettoyer" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Mention" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Sondage terminé" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" -msgstr "Requête de suivit" +msgstr "Requête de suivi" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contexte" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nouveau" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Déjà vu" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Aucun" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" -msgstr "Résultats de recher pour le compte %s" +msgstr "Résultats de recherche pour le compte %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Compte %s non trouvé" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Résultats de recherche pour le tag %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Rien n'a été trouvé pour le tag %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" -msgstr "Résultats de recherche pour '%s' (il pourrait y en avoir d'avantage)" +msgstr "Résultats de recherche pour '%s' (il pourrait y en avoir davantage)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Résultats de recherche pour '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" -msgstr "Pas d'avantage de résultats pour '%s'" +msgstr "Pas davantage de résultats pour '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Rien n'a été trouvé pour '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Montrer la chronologie de l'instance" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Montrer le chronologie pour la liste '%s'" @@ -687,48 +687,76 @@ msgstr "Résultats de recherche pour le tag #%s" #: httpd.c:259 msgid "Recent posts by users in this instance" -msgstr "Messages récents des utilisateurs de cette instance" +msgstr "Messages récents des internautes de cette instance" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Hashtags bloqués…" -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" -msgstr "" +msgstr "URL optionnelle pour répondre à" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" "Option 3...\n" "..." msgstr "" +"Option 1…\n" +"Option 2…\n" +"Option 3…\n" +"…" -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" -msgstr "" +msgstr "Clé API de bot" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" -msgstr "" +msgstr "Identifiant du salon" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" -msgstr "" +msgstr "serveur ntfy – adresse complète (ex : https://ntfy.sh/VotreSujet)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" -msgstr "" +msgstr "jeton ntfy – si nécessaire" -#: html.c:2806 +#: html.c:2892 msgid "pinned" -msgstr "" +msgstr "épinglé" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" -msgstr "" +msgstr "signets" -#: html.c:2830 +#: html.c:2916 msgid "drafts" -msgstr "" +msgstr "brouillons" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Publication planifiée…" + +msgid "Post date and time:" +msgstr "Date et heure de publication :" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Publications planifiées" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "publications planifiées" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Date et heure de publication (fuseau horaire : %s) :" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Fuseau horaire :" diff --git a/po/it.po b/po/it.po @@ -8,120 +8,120 @@ msgstr "" "Language: it\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Contenuto sensibile" -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Descrizione del contenuto sensibile" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Riservato alle persone indicate: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Rispondi a (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Salva come bozza senza inviare" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Bozza" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Allegati..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "File:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Pulisci ed elimina l'allegato" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Descrizione dell'allegato" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Sondaggio..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Scelte per il sondaggio (una per linea, massimo 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Una scelta" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Scelte multiple" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Termina in 5 minuti" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Termina in 1 ora" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Termina in 1 giorno" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Post" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Descrizione del sito web" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Email dell'amministratore" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Account amministratore" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d seguiti, %d seguenti" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privato" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "pubblico" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notifiche" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "persone" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "istanza" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -129,552 +129,552 @@ msgstr "" "Ricerca post per URL o contenuto (espressione regolare), @user@host " "accounts, #tag" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Ricerca contenuto" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "link verificato" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Posizione: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nuovo post..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Cosa stai pensando?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operazioni..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Segui" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(per URL o user@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Annuncia" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(per URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Mi piace" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Impostazioni..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nome visualizzato:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Il tuo nome" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Elimina l'avatar" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Immagine intestazione (banner): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Elimina l'immagine d'intestazione" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Bio:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Descriviti qui..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Mostra sempre i contenuti sensibili" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Indirizzo email per le notifiche:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notifiche Telegram (bot key e chat id):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "Notifiche ntfy (server ntfy e token)" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Giorni di mantenimento dei post (0: impostazione server)" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Elimina i messaggi diretti delle persone non seguite" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Questo account è un bot" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Annuncio automatico delle citazioni a quest'account" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Quest'account è privato (post invisibili nel web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Tieni chiuse le discussioni" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Devi approvare le richieste dei seguenti" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Rendi pubblici seguenti e seguiti" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Posizione corrente:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Dati del profilo (coppie di chiave=valore per ogni linea):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Lingua dell'interfaccia web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nuova password:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Reinserisci la password:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Aggiorna dati utente" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Hashtag seguiti..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Un hashtag per linea" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Aggiorna hashtags" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Questo post ti piace" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Non mi piace" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "No, non mi piace molto" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Sgancia" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Sgancia questo post dalla timeline" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Aggancia" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Aggancia questo post in cima alla timeline" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Annuncia questo post ai tuoi seguenti" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Rimuovi annuncio" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Mi pento di aver annunciato questo" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Elimina segnalibro" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Elimina questo post dai segnalibri" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Segnalibro" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Aggiungi questo post ai segnalibri" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Smetti di seguire" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Smetti di seguire l'utente" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Sequi l'utente" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Smetti di seguire il gruppo" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Smetti di seguire il gruppo o canale" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Segui grupp" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Segui il gruppo o canale" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "Silenzia" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Blocca l'utente" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Elimina" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Elimina questo post" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Nascondi" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Nascondi questo post completamente" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Modifica..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Rispondi..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Troncato (troppo lungo)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "Ti segue" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Aggancia" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Segnalibro" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Sondaggio" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Votato" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Evento" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "Annunciato" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "in risposta a" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTENUTO SENSIBILE]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Vota" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Chiuso" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Chiude in" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Video" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Audio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Allegato" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Testo alternativo..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Provenienza del canale o comunità" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Orario:" -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Vecchi..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "descrizione" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "gestito da " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Congeda" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Timeline per la lista '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Post appuntati" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Post segnati" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Bozze" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Nessun ulteriore post" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Torna in cima" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Storico" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Ancora..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Senza limite" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Permetti annunci dall'utente" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Limite" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Blocca annunci dall'utente" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Elimina l'utente" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Approva" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Approva richiesta di seguirti" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Scarta" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Scarta richiesta di seguirti" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Rimuovi silenziamento" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Sblocca l'utente" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Blocca l'utente completamente" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Messaggio diretto..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Conferme di seguirti in attesa" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Persone che segui" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Persone che ti seguono" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Pulisci" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Citazione" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Sondaggio concluso" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Richiesta di seguire" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contesto" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Nuovo" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Già visto" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Niente" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Risultati per account %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Account %s non trovato" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Risultati per tag %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Nessun risultato per il tag %S" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Risultati per tag %s (ancora...)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Risultati per %s" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Nessuna corrispondenza per '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Non trovato per '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Mostra la timeline dell'istanza" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Mostra la timeline della lista '%s'" @@ -688,15 +688,15 @@ msgstr "Risultati per tag #%s" msgid "Recent posts by users in this instance" msgstr "Post recenti in questa istanza" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Hashtag bloccati..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL facoltativo di risposta" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -708,30 +708,54 @@ msgstr "" "Scelta 3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Chiave per le API del bot" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Id della chat" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "Server ntfy - URL completo (esempio: https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "Token ntfy - se richiesto" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "appuntati" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "segnalibri" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "bozze" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "" + +msgid "Post date and time:" +msgstr "" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "" + +#: html.c:1538 +msgid "Time zone:" +msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po @@ -4,125 +4,128 @@ msgid "" msgstr "" "Project-Id-Version: snac\n" -"Last-Translator: Daltux <https://daltux.net>\n" +"PO-Revision-Date: 2025-04-18\n" +"Last-Translator: Daltux <@daltux@snac.daltux.net>\n" "Language: pt_BR\n" +"MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"X-Generator: Poedit 3.5\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.6\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Conteúdo sensível: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Descrição do conteúdo sensível" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Apenas para pessoas mencionadas: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Resposta para (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Não enviar, mas armazenar como rascunho" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Rascunho:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Anexos..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Arquivo:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Limpe este campo para remover o anexo" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Descrição do anexo" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Enquete..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Alternativas da enquete (uma por linha, até 8):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Escolha única" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Escolhas múltiplas" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Encerrar em 5 minutos" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Encerrar em 1 hora" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Encerrar em 1 dia" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Publicar" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Descrição do sítio eletrônico" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "E-mail da administração" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Conta de quem administra" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d seguidos, %d seguidores" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "privado" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "público" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "notificações" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "pessoas" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "instância" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -130,552 +133,552 @@ msgstr "" "Procurar publicações por URL ou conteúdo (expressão regular), contas " "(@perfil@servidor) ou #tag" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Buscar conteúdo" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "ligação verificada" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Localização: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Nova publicação..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "O que tem em mente?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Operações..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Seguir" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(por URL ou conta@servidor)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Impulsionar" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(por URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Curtir" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Definições de uso..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Nome a ser exibido:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Seu nome" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Avatar: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Remover avatar atual" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Imagem de cabeçalho (capa): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Remover imagem de cabeçalho atual" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "Biografia:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Escreva aqui sobre você..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Sempre exibir conteúdo sensível" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Endereço de e-mail para notificações:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Notificações Telegram (chave do robô e ID da conversa):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "Notificações ntfy (servidor ntfy e token):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Máximo de dias a preservar publicações (0: definições do servidor):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Descartar mensagens diretas de pessoas que você não segue" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Esta conta é robô" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Impulsionar automaticamente todas as menções a esta conta" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Esta conta é privada (as publicações não são exibidas na Web)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Recolher por padrão as sequências de publicações" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Solicitações de seguimento precisam ser aprovadas" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Publicar métricas de seguidores e seguidos" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Localização atual:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Metadados do perfil (par de chave=valor em cada linha):" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Idioma da interface Web:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Nova senha:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Repita a nova senha:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Atualizar informações da conta" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Hashtags seguidas..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "Uma hashtag por linha" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Atualizar hashtags" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Declarar que gosta desta publicação" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Descurtir" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Não gosto tanto assim disso" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Desafixar" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Desafixar esta publicação da sua linha do tempo" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Afixar" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Afixar esta publicação no topo de sua linha do tempo" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Anunciar esta publicação para seus seguidores" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Desimpulsionar" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Arrependo-me de ter impulsionado isso" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Desmarcar" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Remover esta publicação dos seus marcadores" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Marcar" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Adicionar esta publicação aos seus marcadores" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Deixar de seguir" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Parar de acompanhar a atividade deste perfil" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Começar a acompanhar a atividade deste perfil" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Deixar de seguir grupo" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Parar de acompanhar este grupo ou canal" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Seguir grupo" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Começar a acompanhar este grupo ou canal" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "MUDO" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Bloquear toda atividade deste perfil para sempre" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Eliminar" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Apagar esta publicação" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Ocultar" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Ocultar esta publicação e suas respostas" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Editar..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Responder..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Truncada (muito extensa)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "segue você" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Afixada" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Marcada" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Enquete" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Votou" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Evento" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "impulsionou" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "em resposta a" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [CONTEÚDO SENSÍVEL]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Votar" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Encerrada" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Encerra em" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Vídeo" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Áudio" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Anexo" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Texto alternativo..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Canal ou comunidade de origem" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Horário: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Anteriores..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "sobre este sítio eletrônico" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "movido por " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Dispensar" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Linha do tempo da lista '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Publicações afixadas" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Publicações marcadas" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Publicações em rascunho" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Sem mais publicações não vistas" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Voltar ao topo" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "Histórico" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Mais..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Retirar restrição" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Permitir anúncios (impulsionamentos) deste perfil" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Restringir" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Bloquear anúncios (impulsionamentos) deste perfil" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Apagar este perfil" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Aprovar" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Aprovar esta solicitação de seguimento" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Descartar" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Descartar esta solicitação de seguimento" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Desbloquear" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Parar de bloquear as atividades deste perfil" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Bloquear toda atividade deste perfil" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Mensagem direta..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Confirmações de seguimento pendentes" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Pessoas que você segue" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Pessoas que seguem você" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Limpar tudo" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Menção" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Enquete encerrada" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Solicitação de seguimento" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Contexto" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Novas" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Já vistas" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Nenhuma" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Resultados da busca pela conta %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Conta %s não encontrada" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Resultados da busca pela hashtag %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Nada consta com hashtag %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Resultados da busca por '%s' (pode haver mais)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Resultados da busca por '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Sem mais combinações para '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Nada consta com '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Exibindo linha do tempo da instância" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Exibindo linha do tempo da lista '%s'" @@ -689,15 +692,15 @@ msgstr "Resultados da busca pela hashtag #%s" msgid "Recent posts by users in this instance" msgstr "Publicações recentes de perfis desta instância" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Hashtags bloqueadas..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "URL opcional para a qual responder" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -709,30 +712,54 @@ msgstr "" "Opção 3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Chave de API do robô" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "ID da conversa" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "Servidor ntfy - URL completa (exemplo: https://ntfy.sh/SeuTópico)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "Token ntfy - se necessário" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "afixadas" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "marcadores" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "rascunhos" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Publicação agendada..." + +msgid "Post date and time:" +msgstr "Data e horário da publicação:" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Publicações agendadas" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "publicações agendadas" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Data e hora da publicação (fuso horário: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Fuso horário:" diff --git a/po/ru.po b/po/ru.po @@ -15,120 +15,120 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.0\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "Чувствительное содержимое: " -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "Описание чувствительного содержимого" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "Только для упомянутых людей: " -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "Ответ на (URL): " -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "Не отправлять, сохранить черновик" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "Черновик:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "Вложения..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "Файл:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "Очистите это поле, чтоб удалить вложение" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "Описание вложения" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "Опрос..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "Варианты ответа (один на строку, до 8 шт):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "Один выбор" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "Множественный выбор" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "Заканчивается через 5 минут" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "Заканчивается через 1 час" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "Заканчивается через 1 день" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "Отправить" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "Описание сайта" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "Почта админа" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "Учётная запись админа" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d подписан, %d подписчиков" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "личное" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "публичное" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "уведомления" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "люди" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "экземпляр" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" @@ -136,552 +136,552 @@ msgstr "" "Поиск сообщений по URL или содержимому (регулярное выражение), учетной " "записи вида @user@host, или #тегу" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "Поиск содержимого" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "проверенная ссылка" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "Местоположение: " -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "Новое сообщение..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "Что у вас на уме?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "Действия..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "Подписаться" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(по URL или user@host)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "Продвинуть" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(по URL)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "Лайкнуть" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "Пользовательские настройки..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "Отображаемое имя:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "Ваше имя" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "Аватар: " -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "Удалить текущий аватар" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "Заглавное изображение (баннер): " -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "Удалить текущее заглавное изображение" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "О себе:" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "Напишите что-нибудь про себя..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "Всегда показывать чувствительное содержимое" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "Почтовый адрес для уведомлений:" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Уведомления в Telegram (ключ бота и id чата):" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "уведомления в ntfy (сервер и токен ntfy):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "Максимальное время хранения сообщений (0: настройки сервера):" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "Отклонять личные сообщения от незнакомцев" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "Это аккаунт бота" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "Автоматически продвигать все упоминания этого аккаунта" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "Это закрытый аккаунт (сообщения не показываются в сети)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "Сворачивать обсуждения по умолчанию" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "Запросы подписки требуют подтверждения" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "Публиковать статистику подписок и подписчиков" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "Текущее метоположение:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "Метаданные профиля (пары ключ=значение, по одной на строку)" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "Язык интерфейса:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "Новый пароль:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "Повторите новый пароль:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "Обновить данные пользователя" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "Отслеживаемые хештеги..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "По одному на строку" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "Обновить хештеги" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "Отметить сообщение понравившимся" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "Больше не нравится" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "Не так уж и понравилось" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "Открепить" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "Открепить это сообщение из своей ленты" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "Закрепить" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "Закрепить это сообщение в своей ленте" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "Поделиться этим сообщением со своими подписчиками" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "Отменить продвижение" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "Не буду продвигать, пожалуй" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "Удалить из закладок" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "Удалить это сообщение из закладок" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "Добавить в закладки" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "Добавить сообщение в закладки" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "Отписаться" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "Отменить подписку на этого пользователя" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "Начать следовать за этим пользователем" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "Отписаться от группы" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "Отписаться от группы или канала" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "Подписаться на группу" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "Подписаться на группу или канал" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "Заглушить" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "Заглушить всю активность от этого пользователя, навсегда" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "Удалить" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "Удалить это сообщение" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "Скрыть" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "Скрыть это сообщение вместе с обсуждением" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "Редактировать..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "Ответить..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "Обрезано (слишком много)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "подписан на вас" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "Закреплено" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "Добавлено в закладки" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "Опрос" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "Проголосовано" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "Событие" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "поделился" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "в ответ на" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr " [ЧУВСТВИТЕЛЬНО СОДЕРЖИМОЕ]" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "Голос" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "Закрыт" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "Закрывается через" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "Видео" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "Аудио" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "Вложение" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "Описание..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "Исходный канал или сообщество" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "Время: " -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "Ранее..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "про этот сайт" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "на основе " -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "Скрыть" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "Ленты для списка '%s'" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "Закреплённые сообщения" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "Сообщения в закладках" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "Черновики сообщений" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "Всё просмотрено" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "Вернуться наверх" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "История" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "Ещё..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "Без ограничения" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "Разрешить продвижения от этого пользователя" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "Лимит" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "Запретить продвижения от этого пользователя" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "Удалить пользователя" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "Подтвердить" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "Подтвердить запрос на подписку" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "Отклонить" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "Отклонить этот запрос на подписку" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "Отменить глушение" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "Прекратить глушение действий этого пользователя" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "Заглушить все действия этого пользователя" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "Личное сообщение..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "Ожидающие запросы на подписку" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "Ваши подписки" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "Ваши подписчики" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "Очистить всё" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "Упоминание" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "Завершённый опрос" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "Запрос на подписку" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "Контекст" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "Новое" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "Уже просмотрено" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "Нет" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "Результаты поиска для учётной записи %s" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "Учётная запись %s не найдена" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "Результаты поиска тега %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "Ничего не найдено по тегу %s" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "Результаты поиска для '%s' (возможно, есть ещё)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "Результаты поиска для '%s'" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "Больше нет совпадений для '%s'" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "Ничего не найдено для '%s'" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "Показываем ленту инстанции" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "Показываем ленты инстанции для списка '%s'" @@ -695,15 +695,15 @@ msgstr "Результаты поиска для тега #%s" msgid "Recent posts by users in this instance" msgstr "Последние сообщения на этой инстанции" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "Заблокированные теги..." -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "Необязательный URL для ответа" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -715,30 +715,54 @@ msgstr "" "Вариант 3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Ключ API для бота" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "Id чата" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "полный URL сервера ntfy (например https://ntfy.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "токен ntfy - если нужен" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "закреплено" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "закладки" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "черновики" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "Запланировать..." + +msgid "Post date and time:" +msgstr "Время поста:" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "Запланированные посты" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "запланированные посты" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "Время поста (Часовой пояс: %s):" + +#: html.c:1538 +msgid "Time zone:" +msgstr "Часовой пояс:" diff --git a/po/zh.po b/po/zh.po @@ -8,672 +8,672 @@ msgstr "" "Language: zh\n" "Content-Type: text/plain; charset=UTF-8\n" -#: html.c:372 +#: html.c:384 msgid "Sensitive content: " msgstr "敏感内容:" -#: html.c:380 +#: html.c:392 msgid "Sensitive content description" msgstr "敏感内容描述" -#: html.c:393 +#: html.c:405 msgid "Only for mentioned people: " msgstr "只有提及到的人:" -#: html.c:416 +#: html.c:428 msgid "Reply to (URL): " msgstr "回复给(网址):" -#: html.c:425 +#: html.c:437 msgid "Don't send, but store as a draft" msgstr "不要发送,但是保存为草稿" -#: html.c:426 +#: html.c:438 msgid "Draft:" msgstr "草稿:" -#: html.c:446 +#: html.c:494 msgid "Attachments..." msgstr "附件..." -#: html.c:469 +#: html.c:517 msgid "File:" msgstr "文件:" -#: html.c:473 +#: html.c:521 msgid "Clear this field to delete the attachment" msgstr "清除此项以删除附件" -#: html.c:482 html.c:507 +#: html.c:530 html.c:555 msgid "Attachment description" msgstr "附件描述" -#: html.c:518 +#: html.c:566 msgid "Poll..." msgstr "投票..." -#: html.c:520 +#: html.c:568 msgid "Poll options (one per line, up to 8):" msgstr "投票选项(每项一行,最多八项):" -#: html.c:532 +#: html.c:580 msgid "One choice" msgstr "单选" -#: html.c:535 +#: html.c:583 msgid "Multiple choices" msgstr "多选" -#: html.c:541 +#: html.c:589 msgid "End in 5 minutes" msgstr "五分钟后结束" -#: html.c:545 +#: html.c:593 msgid "End in 1 hour" msgstr "一小时后结束" -#: html.c:548 +#: html.c:596 msgid "End in 1 day" msgstr "一天后结束" -#: html.c:556 +#: html.c:604 msgid "Post" msgstr "" -#: html.c:653 html.c:660 +#: html.c:701 html.c:708 msgid "Site description" msgstr "站点描述" -#: html.c:671 +#: html.c:719 msgid "Admin email" msgstr "管理员电子邮箱" -#: html.c:684 +#: html.c:732 msgid "Admin account" msgstr "管理员帐号" -#: html.c:752 html.c:1088 +#: html.c:800 html.c:1136 #, c-format msgid "%d following, %d followers" msgstr "%d 个正在关注,%d 个关注者" -#: html.c:842 +#: html.c:890 msgid "RSS" msgstr "RSS" -#: html.c:847 html.c:875 +#: html.c:895 html.c:923 msgid "private" msgstr "私密" -#: html.c:871 +#: html.c:919 msgid "public" msgstr "公开" -#: html.c:879 +#: html.c:927 msgid "notifications" msgstr "通知" -#: html.c:884 +#: html.c:932 msgid "people" msgstr "成员" -#: html.c:888 +#: html.c:936 msgid "instance" msgstr "实例" -#: html.c:897 +#: html.c:945 msgid "" "Search posts by URL or content (regular expression), @user@host accounts, or " "#tag" msgstr "" "通过网址、内容(正则表达式)、@用户@服务器 帐号,或者 #话题标签搜索贴子" -#: html.c:898 +#: html.c:946 msgid "Content search" msgstr "内容搜索" -#: html.c:1020 +#: html.c:1068 msgid "verified link" msgstr "已验证的链接" -#: html.c:1077 html.c:2459 html.c:2472 html.c:2481 +#: html.c:1125 html.c:2540 html.c:2553 html.c:2562 msgid "Location: " msgstr "位置:" -#: html.c:1113 +#: html.c:1161 msgid "New Post..." msgstr "新贴子..." -#: html.c:1115 +#: html.c:1163 msgid "What's on your mind?" msgstr "你在想什么?" -#: html.c:1124 +#: html.c:1172 msgid "Operations..." msgstr "操作..." -#: html.c:1139 html.c:1714 html.c:3095 html.c:4412 +#: html.c:1187 html.c:1788 html.c:3193 html.c:4578 msgid "Follow" msgstr "关注" -#: html.c:1141 +#: html.c:1189 msgid "(by URL or user@host)" msgstr "(通过网址或者 用户名@服务器)" -#: html.c:1156 html.c:1690 html.c:4364 +#: html.c:1204 html.c:1764 html.c:4527 msgid "Boost" msgstr "转发" -#: html.c:1158 html.c:1175 +#: html.c:1206 html.c:1223 msgid "(by URL)" msgstr "(通过网址)" -#: html.c:1173 html.c:1669 html.c:4355 +#: html.c:1221 html.c:1743 html.c:4518 msgid "Like" msgstr "点赞" -#: html.c:1278 +#: html.c:1347 msgid "User Settings..." msgstr "用户设置..." -#: html.c:1287 +#: html.c:1356 msgid "Display name:" msgstr "显示名字:" -#: html.c:1293 +#: html.c:1362 msgid "Your name" msgstr "你的名字" -#: html.c:1295 +#: html.c:1364 msgid "Avatar: " msgstr "头像:" -#: html.c:1303 +#: html.c:1372 msgid "Delete current avatar" msgstr "删除当前头像" -#: html.c:1305 +#: html.c:1374 msgid "Header image (banner): " msgstr "页眉图像(横幅)" -#: html.c:1313 +#: html.c:1382 msgid "Delete current header image" msgstr "删除当前的页眉图像" -#: html.c:1315 +#: html.c:1384 msgid "Bio:" msgstr "简介" -#: html.c:1321 +#: html.c:1390 msgid "Write about yourself here..." msgstr "在这里介绍你自己..." -#: html.c:1330 +#: html.c:1399 msgid "Always show sensitive content" msgstr "总是显示敏感内容" -#: html.c:1332 +#: html.c:1401 msgid "Email address for notifications:" msgstr "用于通知的电子邮箱地址" -#: html.c:1340 +#: html.c:1409 msgid "Telegram notifications (bot key and chat id):" msgstr "Telegram通知(bot密钥和聊天ID)" -#: html.c:1354 +#: html.c:1423 msgid "ntfy notifications (ntfy server and token):" msgstr "ntfy通知(ntfy服务器和令牌):" -#: html.c:1368 +#: html.c:1437 msgid "Maximum days to keep posts (0: server settings):" msgstr "保存贴子的最大天数(0:服务器设置)" -#: html.c:1382 +#: html.c:1451 msgid "Drop direct messages from people you don't follow" msgstr "丢弃你没有关注的人的私信" -#: html.c:1391 +#: html.c:1460 msgid "This account is a bot" msgstr "此帐号是机器人" -#: html.c:1400 +#: html.c:1469 msgid "Auto-boost all mentions to this account" msgstr "自动转发所有对此帐号的提及" -#: html.c:1409 +#: html.c:1478 msgid "This account is private (posts are not shown through the web)" msgstr "这是一个私密帐号(贴子不会在网页中显示)" -#: html.c:1419 +#: html.c:1488 msgid "Collapse top threads by default" msgstr "默认收起主题帖" -#: html.c:1428 +#: html.c:1497 msgid "Follow requests must be approved" msgstr "关注请求必须经过审批" -#: html.c:1437 +#: html.c:1506 msgid "Publish follower and following metrics" msgstr "展示关注者和正在关注的数量" -#: html.c:1439 +#: html.c:1508 msgid "Current location:" msgstr "当前位置:" -#: html.c:1453 +#: html.c:1522 msgid "Profile metadata (key=value pairs in each line):" msgstr "个人资料元数据(每行一条 键=值)" -#: html.c:1464 +#: html.c:1533 msgid "Web interface language:" msgstr "网页界面语言:" -#: html.c:1469 +#: html.c:1543 msgid "New password:" msgstr "新密码:" -#: html.c:1476 +#: html.c:1550 msgid "Repeat new password:" msgstr "重复新密码:" -#: html.c:1486 +#: html.c:1560 msgid "Update user info" msgstr "更新用户信息:" -#: html.c:1497 +#: html.c:1571 msgid "Followed hashtags..." msgstr "已关注的话题标签..." -#: html.c:1499 html.c:1531 +#: html.c:1573 html.c:1605 msgid "One hashtag per line" msgstr "每行一个话题标签" -#: html.c:1520 html.c:1552 +#: html.c:1594 html.c:1626 msgid "Update hashtags" msgstr "更新话题标签" -#: html.c:1669 +#: html.c:1743 msgid "Say you like this post" msgstr "说你喜欢这个贴子" -#: html.c:1674 html.c:4373 +#: html.c:1748 html.c:4536 msgid "Unlike" msgstr "不喜欢" -#: html.c:1674 +#: html.c:1748 msgid "Nah don't like it that much" msgstr "啊,不怎么喜欢这个" -#: html.c:1680 html.c:4505 +#: html.c:1754 html.c:4673 msgid "Unpin" msgstr "取消置顶" -#: html.c:1680 +#: html.c:1754 msgid "Unpin this post from your timeline" msgstr "从你的时间线上取消置顶这个贴子" -#: html.c:1683 html.c:4500 +#: html.c:1757 html.c:4668 msgid "Pin" msgstr "置顶" -#: html.c:1683 +#: html.c:1757 msgid "Pin this post to the top of your timeline" msgstr "把这条贴子置顶在你的时间线上" -#: html.c:1690 +#: html.c:1764 msgid "Announce this post to your followers" msgstr "向你的关注者宣布这条贴子" -#: html.c:1695 html.c:4381 +#: html.c:1769 html.c:4544 msgid "Unboost" msgstr "取消转发" -#: html.c:1695 +#: html.c:1769 msgid "I regret I boosted this" msgstr "我后悔转发这个了" -#: html.c:1701 html.c:4515 +#: html.c:1775 html.c:4683 msgid "Unbookmark" msgstr "取消收藏" -#: html.c:1701 +#: html.c:1775 msgid "Delete this post from your bookmarks" msgstr "从收藏夹中删除这个贴子" -#: html.c:1704 html.c:4510 +#: html.c:1778 html.c:4678 msgid "Bookmark" msgstr "收藏" -#: html.c:1704 +#: html.c:1778 msgid "Add this post to your bookmarks" msgstr "把这个贴子加入收藏夹" -#: html.c:1710 html.c:3081 html.c:3269 html.c:4425 +#: html.c:1784 html.c:3179 html.c:3367 html.c:4591 msgid "Unfollow" msgstr "取消关注" -#: html.c:1710 html.c:3082 +#: html.c:1784 html.c:3180 msgid "Stop following this user's activity" msgstr "停止关注此用户的动态" -#: html.c:1714 html.c:3096 +#: html.c:1788 html.c:3194 msgid "Start following this user's activity" msgstr "开始关注此用户的动态" -#: html.c:1720 html.c:4455 +#: html.c:1794 html.c:4621 msgid "Unfollow Group" msgstr "取消关注群组" -#: html.c:1721 +#: html.c:1795 msgid "Stop following this group or channel" msgstr "取消关注这个群组或频道" -#: html.c:1725 html.c:4442 +#: html.c:1799 html.c:4608 msgid "Follow Group" msgstr "关注群组" -#: html.c:1726 +#: html.c:1800 msgid "Start following this group or channel" msgstr "开始关注这个群组或频道" -#: html.c:1731 html.c:3118 html.c:4389 +#: html.c:1805 html.c:3216 html.c:4552 msgid "MUTE" msgstr "静音" -#: html.c:1732 +#: html.c:1806 msgid "Block any activity from this user forever" msgstr "永久屏蔽来自这个用户的任何动态" -#: html.c:1737 html.c:3100 html.c:4472 +#: html.c:1811 html.c:3198 html.c:4638 msgid "Delete" msgstr "删除" -#: html.c:1737 +#: html.c:1811 msgid "Delete this post" msgstr "删除这条贴子" -#: html.c:1740 html.c:4397 +#: html.c:1814 html.c:4560 msgid "Hide" msgstr "隐藏" -#: html.c:1740 +#: html.c:1814 msgid "Hide this post and its children" msgstr "删除这条贴子及其回复" -#: html.c:1771 +#: html.c:1845 msgid "Edit..." msgstr "编辑..." -#: html.c:1790 +#: html.c:1865 msgid "Reply..." msgstr "回复..." -#: html.c:1841 +#: html.c:1916 msgid "Truncated (too deep)" msgstr "已被截断(太深了)" -#: html.c:1850 +#: html.c:1925 msgid "follows you" msgstr "关注了你" -#: html.c:1913 +#: html.c:1988 msgid "Pinned" msgstr "已置顶" -#: html.c:1921 +#: html.c:1996 msgid "Bookmarked" msgstr "已收藏" -#: html.c:1929 +#: html.c:2004 msgid "Poll" msgstr "投票" -#: html.c:1936 +#: html.c:2011 msgid "Voted" msgstr "已投票" -#: html.c:1945 +#: html.c:2020 msgid "Event" msgstr "事件" -#: html.c:1977 html.c:2006 +#: html.c:2052 html.c:2081 msgid "boosted" msgstr "已转发" -#: html.c:2022 +#: html.c:2097 msgid "in reply to" msgstr "回复给" -#: html.c:2073 +#: html.c:2148 msgid " [SENSITIVE CONTENT]" msgstr "【敏感内容】" -#: html.c:2250 +#: html.c:2325 msgid "Vote" msgstr "投票" -#: html.c:2260 +#: html.c:2335 msgid "Closed" msgstr "已关闭" -#: html.c:2285 +#: html.c:2360 msgid "Closes in" msgstr "距离关闭还有" -#: html.c:2366 +#: html.c:2441 msgid "Video" msgstr "视频" -#: html.c:2381 +#: html.c:2456 msgid "Audio" msgstr "音频" -#: html.c:2403 +#: html.c:2484 msgid "Attachment" msgstr "附件" -#: html.c:2417 +#: html.c:2498 msgid "Alt..." msgstr "描述..." -#: html.c:2430 +#: html.c:2511 msgid "Source channel or community" msgstr "来源频道或者社群" -#: html.c:2524 +#: html.c:2605 msgid "Time: " msgstr "时间:" -#: html.c:2605 +#: html.c:2686 msgid "Older..." msgstr "更早的..." -#: html.c:2702 +#: html.c:2788 msgid "about this site" msgstr "关于此站点" -#: html.c:2704 +#: html.c:2790 msgid "powered by " msgstr "驱动自" -#: html.c:2769 +#: html.c:2855 msgid "Dismiss" msgstr "忽略" -#: html.c:2786 +#: html.c:2872 #, c-format msgid "Timeline for list '%s'" msgstr "列表'%s'的时间线" -#: html.c:2805 html.c:3846 +#: html.c:2891 html.c:3944 msgid "Pinned posts" msgstr "置顶的贴子" -#: html.c:2817 html.c:3861 +#: html.c:2903 html.c:3959 msgid "Bookmarked posts" msgstr "收藏的贴子" -#: html.c:2829 html.c:3876 +#: html.c:2915 html.c:3974 msgid "Post drafts" msgstr "贴子草稿" -#: html.c:2888 +#: html.c:2986 msgid "No more unseen posts" msgstr "没有更多未读贴子了" -#: html.c:2892 html.c:2992 +#: html.c:2990 html.c:3090 msgid "Back to top" msgstr "返回顶部" -#: html.c:2945 +#: html.c:3043 msgid "History" msgstr "历史" -#: html.c:2997 html.c:3417 +#: html.c:3095 html.c:3515 msgid "More..." msgstr "更多..." -#: html.c:3086 html.c:4408 +#: html.c:3184 html.c:4574 msgid "Unlimit" msgstr "取消限制" -#: html.c:3087 +#: html.c:3185 msgid "Allow announces (boosts) from this user" msgstr "允许来自这个用户的通知(转发)" -#: html.c:3090 html.c:4404 +#: html.c:3188 html.c:4570 msgid "Limit" msgstr "限制" -#: html.c:3091 +#: html.c:3189 msgid "Block announces (boosts) from this user" msgstr "屏蔽来自这个用户的通知(转发)" -#: html.c:3100 +#: html.c:3198 msgid "Delete this user" msgstr "删除此用户" -#: html.c:3105 html.c:4520 +#: html.c:3203 html.c:4688 msgid "Approve" msgstr "允许" -#: html.c:3106 +#: html.c:3204 msgid "Approve this follow request" msgstr "允许这个关注请求" -#: html.c:3109 html.c:4544 +#: html.c:3207 html.c:4712 msgid "Discard" msgstr "丢弃" -#: html.c:3109 +#: html.c:3207 msgid "Discard this follow request" msgstr "丢弃这个关注请求" -#: html.c:3114 html.c:4393 +#: html.c:3212 html.c:4556 msgid "Unmute" msgstr "取消静音" -#: html.c:3115 +#: html.c:3213 msgid "Stop blocking activities from this user" msgstr "停止屏蔽来自此用户的动态" -#: html.c:3119 +#: html.c:3217 msgid "Block any activity from this user" msgstr "屏蔽来自此用户的任何动态" -#: html.c:3127 +#: html.c:3225 msgid "Direct Message..." msgstr "私信..." -#: html.c:3162 +#: html.c:3260 msgid "Pending follow confirmations" msgstr "待处理的关注确认" -#: html.c:3166 +#: html.c:3264 msgid "People you follow" msgstr "你关注的人" -#: html.c:3167 +#: html.c:3265 msgid "People that follow you" msgstr "关注你的人" -#: html.c:3206 +#: html.c:3304 msgid "Clear all" msgstr "清除全部" -#: html.c:3263 +#: html.c:3361 msgid "Mention" msgstr "提及" -#: html.c:3266 +#: html.c:3364 msgid "Finished poll" msgstr "结束投票" -#: html.c:3281 +#: html.c:3379 msgid "Follow Request" msgstr "关注请求" -#: html.c:3364 +#: html.c:3462 msgid "Context" msgstr "上下文" -#: html.c:3375 +#: html.c:3473 msgid "New" msgstr "新建" -#: html.c:3390 +#: html.c:3488 msgid "Already seen" msgstr "已经看过" -#: html.c:3405 +#: html.c:3503 msgid "None" msgstr "没有" -#: html.c:3671 +#: html.c:3769 #, c-format msgid "Search results for account %s" msgstr "账户 %s 的搜索结果" -#: html.c:3678 +#: html.c:3776 #, c-format msgid "Account %s not found" msgstr "没有找到账户 %s" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Search results for tag %s" msgstr "标签 %s 的搜索结果" -#: html.c:3709 +#: html.c:3807 #, c-format msgid "Nothing found for tag %s" msgstr "没有找到标签'%s'的结果" -#: html.c:3725 +#: html.c:3823 #, c-format msgid "Search results for '%s' (may be more)" msgstr "'%s'的搜索结果(可能还有更多)" -#: html.c:3728 +#: html.c:3826 #, c-format msgid "Search results for '%s'" msgstr "'%s'的搜索结果" -#: html.c:3731 +#: html.c:3829 #, c-format msgid "No more matches for '%s'" msgstr "没有更多匹配'%s'的结果了" -#: html.c:3733 +#: html.c:3831 #, c-format msgid "Nothing found for '%s'" msgstr "没有找到'%s'的结果" -#: html.c:3831 +#: html.c:3929 msgid "Showing instance timeline" msgstr "显示实例时间线" -#: html.c:3899 +#: html.c:4012 #, c-format msgid "Showing timeline for list '%s'" msgstr "显示列表'%s'的事件线" @@ -687,15 +687,15 @@ msgstr "标签 #%s 的搜索结果" msgid "Recent posts by users in this instance" msgstr "此实例上的用户最近的贴子" -#: html.c:1529 +#: html.c:1603 msgid "Blocked hashtags..." msgstr "已屏蔽的话题标签" -#: html.c:420 +#: html.c:432 msgid "Optional URL to reply to" msgstr "可选的回复的网址" -#: html.c:527 +#: html.c:575 msgid "" "Option 1...\n" "Option 2...\n" @@ -707,30 +707,54 @@ msgstr "" "选项3...\n" "..." -#: html.c:1346 +#: html.c:1415 msgid "Bot API key" msgstr "Bot API 密钥" -#: html.c:1352 +#: html.c:1421 msgid "Chat id" msgstr "聊天ID" -#: html.c:1360 +#: html.c:1429 msgid "ntfy server - full URL (example: https://ntfy.sh/YourTopic)" msgstr "ntfy服务器 - 完整网址(例如:https://ntft.sh/YourTopic)" -#: html.c:1366 +#: html.c:1435 msgid "ntfy token - if needed" msgstr "ntft令牌 - 如果需要的话" -#: html.c:2806 +#: html.c:2892 msgid "pinned" msgstr "置顶" -#: html.c:2818 +#: html.c:2904 msgid "bookmarks" msgstr "收藏夹" -#: html.c:2830 +#: html.c:2916 msgid "drafts" msgstr "草稿" + +#: html.c:464 +msgid "Scheduled post..." +msgstr "" + +msgid "Post date and time:" +msgstr "" + +#: html.c:2927 html.c:3989 +msgid "Scheduled posts" +msgstr "" + +#: html.c:2928 +msgid "scheduled posts" +msgstr "" + +#: html.c:458 +#, c-format +msgid "Post date and time (timezone: %s):" +msgstr "" + +#: html.c:1538 +msgid "Time zone:" +msgstr "" diff --git a/sandbox.c b/sandbox.c @@ -8,8 +8,6 @@ void sbox_enter(const char *basedir) { const char *address = xs_dict_get(srv_config, "address"); - int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications")); - if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) { srv_log(xs_dup("OpenBSD security disabled by admin")); return; @@ -24,9 +22,6 @@ void sbox_enter(const char *basedir) unveil("/etc/ssl/cert.pem", "r"); unveil("/usr/share/zoneinfo", "r"); - if (smail) - unveil("/usr/sbin/sendmail", "x"); - if (*address == '/') unveil(address, "rwc"); @@ -36,9 +31,6 @@ void sbox_enter(const char *basedir) xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr"); - if (smail) - p = xs_str_cat(p, " exec"); - if (*address == '/') p = xs_str_cat(p, " unix"); @@ -55,7 +47,7 @@ void sbox_enter(const char *basedir) #include "landloc.h" static -LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) { +LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smtp_port) { const unsigned long long rd = LANDLOCK_ACCESS_FS_READ_DIR, @@ -101,9 +93,6 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) LL_PATH(sdir, s); } - if (smail && mtime("/usr/sbin/sendmail") > 0) - LL_PATH("/usr/sbin/sendmail", x); - if (*address != '/') { unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port")); LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT); @@ -111,24 +100,33 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT); LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT); + if (smtp_port > 0) + LL_PORT((unsigned short)smtp_port, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT); } LL_END void sbox_enter(const char *basedir) { + const char *errstr; const char *address = xs_dict_get(srv_config, "address"); - - int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications")); + const char *smtp_url = xs_dict_get(srv_config, "smtp_url"); + int smtp_port = -1; if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) { srv_debug(1, xs_dup("Linux sandbox disabled by admin")); return; } - if (sbox_enter_linux_(basedir, address, smail) == 0) + if (xs_is_string(smtp_url) && *smtp_url != '\0') { + smtp_port = parse_port(smtp_url, &errstr); + if (errstr) + srv_debug(0, xs_fmt("Couldn't determine port from '%s': %s", smtp_url, errstr)); + } + + if (sbox_enter_linux_(basedir, address, smtp_port) == 0) srv_debug(1, xs_dup("Linux sandbox enabled")); else - srv_debug(1, xs_dup("Linux sandbox failed")); + srv_debug(0, xs_dup("Linux sandbox failed")); } #else /* defined(WITH_LINUX_SANDBOX) */ diff --git a/snac.c b/snac.c @@ -25,6 +25,7 @@ #include "xs_fcgi.h" #include "xs_html.h" #include "xs_po.h" +#include "xs_webmention.h" #include "snac.h" diff --git a/snac.h b/snac.h @@ -1,7 +1,7 @@ /* snac - A simple, minimalistic ActivityPub instance */ /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ -#define VERSION "2.74" +#define VERSION "2.77" #define USER_AGENT "snac/" VERSION @@ -61,6 +61,7 @@ typedef struct { xs_str *actor; /* actor url */ xs_str *md5; /* actor url md5 */ const xs_dict *lang;/* string translation dict */ + const char *tz; /* configured timezone */ } snac; typedef struct { @@ -152,12 +153,14 @@ int follower_add(snac *snac, const char *actor); int follower_del(snac *snac, const char *actor); int follower_check(snac *snac, const char *actor); xs_list *follower_list(snac *snac); +int follower_list_len(snac *snac); int pending_add(snac *user, const char *actor, const xs_dict *msg); int pending_check(snac *user, const char *actor); xs_dict *pending_get(snac *user, const char *actor); void pending_del(snac *user, const char *actor); xs_list *pending_list(snac *user); +int pending_count(snac *user); double timeline_mtime(snac *snac); int timeline_touch(snac *snac); @@ -182,6 +185,7 @@ int following_del(snac *snac, const char *actor); int following_check(snac *snac, const char *actor); int following_get(snac *snac, const char *actor, xs_dict **data); xs_list *following_list(snac *snac); +int following_list_len(snac *snac); void mute(snac *snac, const char *actor); void unmute(snac *snac, const char *actor); @@ -205,6 +209,12 @@ void draft_del(snac *user, const char *id); void draft_add(snac *user, const char *id, const xs_dict *msg); xs_list *draft_list(snac *user); +int is_scheduled(snac *user, const char *id); +void schedule_del(snac *user, const char *id); +void schedule_add(snac *user, const char *id, const xs_dict *msg); +xs_list *scheduled_list(snac *user); +void scheduled_process(snac *user); + int limited(snac *user, const char *id, int cmd); #define is_limited(user, id) limited((user), (id), 0) #define limit(user, id) limited((user), (id), 1) @@ -282,6 +292,7 @@ void enqueue_close_question(snac *user, const char *id, int end_secs); void enqueue_object_request(snac *user, const char *id, int forward_secs); void enqueue_verify_links(snac *user); void enqueue_actor_refresh(snac *user, const char *actor, int forward_secs); +void enqueue_webmention(const xs_dict *msg); int was_question_voted(snac *user, const char *id); xs_list *user_queue(snac *snac); @@ -367,6 +378,7 @@ int activitypub_post_handler(const xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype); xs_dict *emojis(void); +xs_str *format_text_with_emoji(snac *user, const char *text, int ems, const char *proxy); xs_str *not_really_markdown(const char *content, xs_list **attach, xs_list **tag); xs_str *sanitize(const char *content); xs_str *encode_html(const char *str); @@ -427,6 +439,7 @@ void import_blocked_accounts_csv(snac *user, const char *fn); void import_following_accounts_csv(snac *user, const char *fn); void import_list_csv(snac *user, const char *fn); void import_csv(snac *user); +int parse_port(const char *url, const char **errstr); typedef enum { #define HTTP_STATUS(code, name, text) HTTP_STATUS_ ## name = code, diff --git a/tests/smtp.c b/tests/smtp.c @@ -0,0 +1,24 @@ +/* snac - A simple, minimalistic ActivityPub instance */ +/* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ + +#define XS_IMPLEMENTATION +#include "../xs.h" +#include "../xs_curl.h" + +#define FROM "<snac-smtp-test@locahost>" + +int main(void) { + xs *to = xs_fmt("<%s@localhost>", getenv("USER")), + *body = xs_fmt("" + "To: %s \r\n" + "From: " FROM "\r\n" + "Subject: snac smtp test\r\n" + "\r\n" + "If you read this as an email, it probably worked!\r\n", + to); + + return xs_smtp_request("smtp://localhost", NULL, NULL, + FROM, + to, + body, 0); +} +\ No newline at end of file diff --git a/utils.c b/utils.c @@ -101,8 +101,9 @@ static const char *greeting_html = "<html><head>\n" "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n" "<link rel=\"icon\" type=\"image/x-icon\" href=\"https://%host%/favicon.ico\"/>\n" + "<style>*{color-scheme:light dark}body{margin:auto;max-width:50em}</style>\n" "<title>Welcome to %host%</title>\n</head>\n" - "<body style=\"margin: auto; max-width: 50em\">\n" + "<body>\n" "%blurb%" "<p>The following users are part of this community:</p>\n" "\n" @@ -912,3 +913,60 @@ void import_csv(snac *user) else snac_log(user, xs_fmt("Cannot open file %s", fn)); } + +static const struct { + const char *proto; + unsigned short default_port; +} FALLBACK_PORTS[] = { + /* caution: https > http, smpts > smtp */ + {"https", 443}, + {"http", 80}, + {"smtps", 465}, + {"smtp", 25} +}; + +int parse_port(const char *url, const char **errstr) +{ + const char *col, *rcol; + int tmp, ret = -1; + + if (errstr) + *errstr = NULL; + + if (!(col = strchr(url, ':'))) { + if (errstr) + *errstr = "bad url"; + + return -1; + } + + for (size_t i = 0; i < sizeof(FALLBACK_PORTS) / sizeof(*FALLBACK_PORTS); ++i) { + if (memcmp(url, FALLBACK_PORTS[i].proto, strlen(FALLBACK_PORTS[i].proto)) == 0) { + ret = FALLBACK_PORTS[i].default_port; + break; + } + } + + if (!(rcol = strchr(col + 1, ':'))) + rcol = col; + + if (rcol) { + tmp = atoi(rcol + 1); + if (tmp == 0) { + if (ret != -1) + return ret; + + if (errstr) + *errstr = strerror(errno); + + return -1; + } + + return tmp; + } + + if (errstr) + *errstr = "unknown protocol"; + + return -1; +} diff --git a/xs_curl.h b/xs_curl.h @@ -9,6 +9,10 @@ xs_dict *xs_http_request(const char *method, const char *url, const xs_str *body, int b_size, int *status, xs_str **payload, int *p_size, int timeout); +int xs_smtp_request(const char *url, const char *user, const char *pass, + const char *from, const char *to, const xs_str *body, + int use_ssl); + const char *xs_curl_strerr(int errnum); #ifdef XS_IMPLEMENTATION @@ -197,6 +201,49 @@ xs_dict *xs_http_request(const char *method, const char *url, } +int xs_smtp_request(const char *url, const char *user, const char *pass, + const char *from, const char *to, const xs_str *body, + int use_ssl) +{ + CURL *curl; + CURLcode res = CURLE_OK; + struct curl_slist *rcpt = NULL; + struct _payload_data pd = { + .data = (char *)body, + .size = strlen(body), + .offset = 0 + }; + + curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_URL, url); + if (user && pass) { + /* allow authless connections, to, e.g. localhost */ + curl_easy_setopt(curl, CURLOPT_USERNAME, user); + curl_easy_setopt(curl, CURLOPT_PASSWORD, pass); + } + + if (use_ssl) + curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); + + curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from); + + rcpt = curl_slist_append(rcpt, to); + curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt); + + curl_easy_setopt(curl, CURLOPT_READDATA, &pd); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, _post_callback); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + curl_slist_free_all(rcpt); + + return (int)res; +} + + const char *xs_curl_strerr(int errnum) { CURLcode cc = errnum < 0 ? -errnum : errnum; diff --git a/xs_mime.h b/xs_mime.h @@ -16,6 +16,7 @@ extern const char *xs_mime_types[]; const char *xs_mime_types[] = { "3gp", "video/3gpp", "aac", "audio/aac", + "apng", "image/apng", "avif", "image/avif", "css", "text/css", "flac", "audio/flac", diff --git a/xs_time.h b/xs_time.h @@ -15,6 +15,8 @@ time_t xs_parse_time(const char *str, const char *fmt, int local); #define xs_parse_localtime(str, fmt) xs_parse_time(str, fmt, 1) #define xs_parse_utctime(str, fmt) xs_parse_time(str, fmt, 0) xs_str *xs_str_time_diff(time_t time_diff); +xs_list *xs_tz_list(void); +int xs_tz_offset(const char *tz); #ifdef XS_IMPLEMENTATION @@ -106,6 +108,128 @@ time_t xs_parse_iso_date(const char *iso_date, int local) } +/** timezones **/ + +/* intentionally dead simple */ + +struct { + const char *tz; /* timezone name */ + float h_offset; /* hour offset */ +} xs_tz[] = { + { "UTC", 0 }, + { "WET (Western European Time)", 0 }, + { "WEST (Western European Summer Time)", 1 }, + { "CET (Central European Time)", 1 }, + { "CEST (Central European Summer Time)", 2 }, + { "EET (Eastern European Time)", 2 }, + { "EEST (Eastern European Summer Time)", 3 }, + { "MSK (Moskow Time Zone)", 3 }, + { "EST (Eastern Time Zone)", -5 }, + { "AST (Atlantic Time Zone)", -4 }, + { "ADT (Atlantic Daylight Time Zone)", -3 }, + { "CST (Central Time Zone)", -6 }, + { "CDT (Central Daylight Time Zone)", -5 }, + { "MST (Mountain Time Zone)", -7 }, + { "MDT (Mountain Daylight Time Zone)", -6 }, + { "PST (Pacific Time Zone)", -8 }, + { "PDT (Pacific Daylight Time Zone)", -7 }, + { "AKST (Alaska Time Zone)", -9 }, + { "AKDT (Alaska Daylight Time Zone)", -8 }, + { "China Time Zone", 8 }, + { "IST (Israel Standard Time)", 2 }, + { "IDT (Israel Daylight Standard Time)", 3 }, + { "WIB (Western Indonesia Time)", 7 }, + { "WITA (Central Indonesia Time)", 8 }, + { "WIT (Eastern Indonesia Time)", 9 }, + { "AWST (Australian Western Time)", 8 }, + { "ACST (Australian Eastern Time)", 9.5 }, + { "ACDT (Australian Daylight Eastern Time)", 10.5 }, + { "AEST (Australian Eastern Time)", 10 }, + { "AEDT (Australian Daylight Eastern Time)", 11 }, + { "NZST (New Zealand Time)", 12 }, + { "NZDT (New Zealand Daylight Time)", 13 }, + { "UTC", 0 }, + { "UTC+1", 1 }, + { "UTC+2", 2 }, + { "UTC+3", 3 }, + { "UTC+4", 4 }, + { "UTC+5", 5 }, + { "UTC+6", 6 }, + { "UTC+7", 7 }, + { "UTC+8", 8 }, + { "UTC+9", 9 }, + { "UTC+10", 10 }, + { "UTC+11", 11 }, + { "UTC+12", 12 }, + { "UTC-1", -1 }, + { "UTC-2", -2 }, + { "UTC-3", -3 }, + { "UTC-4", -4 }, + { "UTC-5", -5 }, + { "UTC-6", -6 }, + { "UTC-7", -7 }, + { "UTC-8", -8 }, + { "UTC-9", -9 }, + { "UTC-10", -10 }, + { "UTC-11", -11 }, + { "UTC-12", -12 }, + { "UTC-13", -13 }, + { "UTC-14", -14 }, + { "GMT", 0 }, + { "GMT+1", -1 }, + { "GMT+2", -2 }, + { "GMT+3", -3 }, + { "GMT+4", -4 }, + { "GMT+5", -5 }, + { "GMT+6", -6 }, + { "GMT+7", -7 }, + { "GMT+8", -8 }, + { "GMT+9", -9 }, + { "GMT+10", -10 }, + { "GMT+11", -11 }, + { "GMT+12", -12 }, + { "GMT-1", 1 }, + { "GMT-2", 2 }, + { "GMT-3", 3 }, + { "GMT-4", 4 }, + { "GMT-5", 5 }, + { "GMT-6", 6 }, + { "GMT-7", 7 }, + { "GMT-8", 8 }, + { "GMT-9", 9 }, + { "GMT-10", 10 }, + { "GMT-11", 11 }, + { "GMT-12", 12 }, + { "GMT-13", 13 }, + { "GMT-14", 14 }, + { NULL, 0 } +}; + + +xs_list *xs_tz_list(void) +/* returns the list of supported timezones */ +{ + xs_list *l = xs_list_new(); + + for (int n = 0; xs_tz[n].tz != NULL; n++) + l = xs_list_append(l, xs_tz[n].tz); + + return l; +} + + +int xs_tz_offset(const char *tz) +/* returns the offset in seconds from the specified Time Zone to UTC */ +{ + for (int n = 0; xs_tz[n].tz != NULL; n++) { + if (strcmp(xs_tz[n].tz, tz) == 0) + return xs_tz[n].h_offset * 3600; + } + + return 0; +} + + #endif /* XS_IMPLEMENTATION */ #endif /* _XS_TIME_H */ diff --git a/xs_version.h b/xs_version.h @@ -1 +1 @@ -/* d467dc71e518603250a55c8a67e26cf40e1710e9 2025-02-14T10:21:15+01:00 */ +/* 871d420cef893b6efe32869407294baf084ce3ab 2025-05-04T11:01:01+02:00 */ diff --git a/xs_webmention.h b/xs_webmention.h @@ -0,0 +1,123 @@ +/* copyright (c) 2025 grunfink et al. / MIT license */ + +#ifndef _XS_WEBMENTION_H + +#define _XS_WEBMENTION_H + +int xs_webmention_send(const char *source, const char *target, const char *user_agent); + + +#ifdef XS_IMPLEMENTATION + +int xs_webmention_send(const char *source, const char *target, const char *user_agent) +/* sends a Webmention to target. + Returns: < 0, error; 0, no Webmention endpoint; > 0, Webmention sent */ +{ + int status = 0; + xs *endpoint = NULL; + + xs *ua = xs_fmt("%s (Webmention)", user_agent ? user_agent : "xs_webmention"); + xs *headers = xs_dict_new(); + headers = xs_dict_set(headers, "accept", "text/html"); + headers = xs_dict_set(headers, "user-agent", ua); + + xs *h_req = NULL; + int p_size = 0; + + /* try first a HEAD, to see if there is a Webmention Link header */ + h_req = xs_http_request("HEAD", target, headers, NULL, 0, &status, NULL, &p_size, 0); + + /* return immediate failures */ + if (status < 200 || status > 299) + return -1; + + const char *link = xs_dict_get(h_req, "link"); + + if (xs_is_string(link) && xs_regex_match(link, "rel *= *(\"|')?webmention")) { + /* endpoint is between < and > */ + xs *r = xs_regex_select_n(link, "<[^>]+>", 1); + + if (xs_list_len(r) == 1) { + endpoint = xs_dup(xs_list_get(r, 0)); + endpoint = xs_strip_chars_i(endpoint, "<>"); + } + } + + if (endpoint == NULL) { + /* no Link header; get the content */ + xs *g_req = NULL; + xs *payload = NULL; + + g_req = xs_http_request("GET", target, headers, NULL, 0, &status, &payload, &p_size, 0); + + if (status < 200 || status > 299) + return -1; + + const char *ctype = xs_dict_get(g_req, "content-type"); + + /* not HTML? no point in looking inside */ + if (!xs_is_string(ctype) || xs_str_in(ctype, "text/html") == -1) + return -2; + + if (!xs_is_string(payload)) + return -3; + + xs *links = xs_regex_select(payload, "<(a +|link +)[^>]+>"); + const char *link; + + xs_list_foreach(links, link) { + if (xs_regex_match(link, "rel *= *(\"|')?webmention")) { + /* found; extract the href */ + xs *r = xs_regex_select_n(link, "href *= *(\"|')?[^\"]+(\"|')", 1); + + if (xs_list_len(r) == 1) { + xs *l = xs_split_n(xs_list_get(r, 0), "=", 1); + + if (xs_list_len(l) == 2) { + endpoint = xs_dup(xs_list_get(l, 1)); + endpoint = xs_strip_chars_i(endpoint, " \"'"); + + break; + } + } + } + } + } + + /* is it a relative endpoint? */ + if (xs_is_string(endpoint)) { + if (!xs_startswith(endpoint, "https://") && !xs_startswith(endpoint, "http://")) { + xs *l = xs_split(target, "/"); + + if (xs_list_len(l) < 3) + endpoint = xs_free(endpoint); + else { + xs *s = xs_fmt("%s/" "/%s", xs_list_get(l, 0), xs_list_get(l, 2)); + endpoint = xs_str_wrap_i(s, endpoint, NULL); + } + } + } + + if (xs_is_string(endpoint)) { + /* got it! */ + headers = xs_dict_set(headers, "content-type", "application/x-www-form-urlencoded"); + + xs *body = xs_fmt("source=%s&target=%s", source, target); + + xs *rsp = xs_http_request("POST", endpoint, headers, body, strlen(body), &status, NULL, 0, 0); + + if (status < 200 || status > 299) + status = -4; + else + status = 1; + } + else + status = 0; + + return status; +} + + +#endif /* XS_IMPLEMENTATION */ + +#endif /* _XS_WEBMENTION_H */