From 09ddb21d425de9ae76cc08e74dfe0ba49d9962a1 Mon Sep 17 00:00:00 2001 From: nekobit Date: Mon, 22 Aug 2022 13:50:23 +0000 Subject: [PATCH] Finish cleaning up template stuff FossilOrigin-Name: 1fa9a720bfca80c96264c4f7263f6de710bee40da23d92f874070de5f32412a7 --- src/account.c | 31 --- src/account.h | 2 - src/emoji.c | 2 +- src/error.c | 36 +-- src/error.h | 8 - src/graphsnbars.c | 121 --------- src/graphsnbars.h | 32 --- src/hashtag.c | 37 --- src/hashtag.h | 3 +- src/lists.c | 4 - src/login.c | 6 +- src/navigation.c | 43 ---- src/navigation.h | 29 --- src/notifications.c | 160 ------------ src/notifications.h | 21 -- src/page_config.c | 5 - src/reply.c | 183 -------------- src/reply.h | 34 --- src/scrobble.c | 49 ++-- src/scrobble.h | 5 +- src/search.c | 36 --- src/search.h | 12 - src/status.c | 585 +------------------------------------------- src/status.h | 51 +--- src/timeline.c | 5 - src/type_string.c | 67 ----- src/type_string.h | 28 --- 27 files changed, 38 insertions(+), 1557 deletions(-) delete mode 100644 src/graphsnbars.c delete mode 100644 src/graphsnbars.h delete mode 100644 src/navigation.c delete mode 100644 src/navigation.h delete mode 100644 src/reply.c delete mode 100644 src/reply.h delete mode 100644 src/type_string.c delete mode 100644 src/type_string.h diff --git a/src/account.c b/src/account.c index 432b897..5c67bf7 100644 --- a/src/account.c +++ b/src/account.c @@ -31,7 +31,6 @@ #include "base_page.h" #include "scrobble.h" #include "string_helpers.h" -#include "navigation.h" #include "emoji.h" #include "timeline.h" @@ -504,36 +503,6 @@ AV* perlify_accounts(const struct mstdnt_account* accounts, size_t len) return av; } -HV* perlify_scrobble(const struct mstdnt_scrobble* scrobble) -{ - if (!scrobble) return NULL; - HV* scrobble_hv = newHV(); - - hvstores_ref(scrobble_hv, "account", perlify_account(&(scrobble->account))); - hvstores_str(scrobble_hv, "album", scrobble->album); - hvstores_str(scrobble_hv, "artist", scrobble->artist); - hvstores_int(scrobble_hv, "created_at", scrobble->created_at); - hvstores_str(scrobble_hv, "id", scrobble->id); - hvstores_int(scrobble_hv, "length", scrobble->length); - hvstores_str(scrobble_hv, "title", scrobble->title); - - return scrobble_hv; -} - -AV* perlify_scrobbles(const struct mstdnt_scrobble* scrobbles, size_t len) -{ - if (!(scrobbles && len)) return NULL; - AV* av = newAV(); - av_extend(av, len-1); - - for (int i = 0; i < len; ++i) - { - av_store(av, i, newRV_inc((SV*)perlify_scrobble(scrobbles + i))); - } - - return av; -} - HV* perlify_account(const struct mstdnt_account* acct) { if (!acct) return NULL; diff --git a/src/account.h b/src/account.h index 6ba8c47..97876b4 100644 --- a/src/account.h +++ b/src/account.h @@ -72,8 +72,6 @@ void content_account_bookmarks(PATH_ARGS); HV* perlify_account(const struct mstdnt_account* acct); AV* perlify_accounts(const struct mstdnt_account* accounts, size_t len); -HV* perlify_scrobble(const struct mstdnt_scrobble* scrobble); -AV* perlify_scrobbles(const struct mstdnt_scrobble* scrobbles, size_t len); HV* perlify_relationship(const struct mstdnt_relationship* rel); #endif // ACCOUNT_H diff --git a/src/emoji.c b/src/emoji.c index b92dcb2..e065296 100644 --- a/src/emoji.c +++ b/src/emoji.c @@ -109,7 +109,7 @@ char* construct_emoji_picker(char* status_id, size_t* size) AV* av = newAV(); for (int i = 0; i < EMO_CAT_LEN; ++i) { - av_store(av, i, newSVpv(emojis + i, len + i)); + av_store(av, i, newSVpv(emojis[i], len[i])); } XPUSHs(newRV_inc((SV*)av)); PERL_STACK_SCALAR_CALL("emojis::emoji_picker"); diff --git a/src/error.c b/src/error.c index f730d1a..679e14e 100644 --- a/src/error.c +++ b/src/error.c @@ -21,46 +21,12 @@ #include "easprintf.h" #include "l10n.h" -// Pages -#include "../static/error_404.ctmpl" -#include "../static/error.ctmpl" - -char* construct_error(const char* error, enum error_type type, unsigned pad, size_t* size) -{ - char* class; - - switch (type) - { - case E_ERROR: - class = "error"; break; - case E_WARNING: - class = "warning"; break; - case E_NOTICE: - class = "notice"; break; - } - - struct error_template data = { - .err_type = class, - .is_padded = pad ? "error-pad" : NULL, - .error = error ? error : "An error occured", - }; - - return tmpl_gen_error(&data, size); -} - void content_not_found(FCGX_Request* req, struct session* ssn, mastodont_t* api, char* path) { - char* page; - struct error_404_template data = { - .error = L10N[L10N_EN_US][L10N_PAGE_NOT_FOUND] - }; - page = tmpl_gen_error_404(&data, NULL); - struct base_page b = { - .content = page, + .content = "Content not found", .sidebar_left = NULL }; render_base_page(&b, req, ssn, api); - free(page); } diff --git a/src/error.h b/src/error.h index cb6fb72..cde3547 100644 --- a/src/error.h +++ b/src/error.h @@ -23,14 +23,6 @@ #include "session.h" #include "path.h" -enum error_type -{ - E_ERROR, - E_WARNING, - E_NOTICE -}; - -char* construct_error(const char* error, enum error_type type, unsigned pad, size_t* size); void content_not_found(FCGX_Request* req, struct session* ssn, mastodont_t* api, char* path); #endif // ERROR_H diff --git a/src/graphsnbars.c b/src/graphsnbars.c deleted file mode 100644 index ea717a1..0000000 --- a/src/graphsnbars.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include -#include "graphsnbars.h" -#include "easprintf.h" -#include "string_helpers.h" - -// Pages -#include "../static/bar.ctmpl" -#include "../static/bar_graph.ctmpl" - -struct hashtags_graph_args -{ - struct mstdnt_tag* tags; - size_t tags_len; - unsigned max; - time_t rel_day; - size_t days; -}; - -char* construct_bar_graph_container(char* bars, size_t* size) -{ - struct bar_graph_template data = { - .graph = bars, - }; - return tmpl_gen_bar_graph(&data, size); -} - -char* construct_bar(float value, size_t* size) -{ - struct bar_template data = { - .value = value * 100 - }; - return tmpl_gen_bar(&data, size); -} - -static char* construct_hashgraph_voidwrap(void* passed, size_t index, size_t* res) -{ - unsigned curr_sum = 0; - struct hashtags_graph_args* args = passed; - struct mstdnt_tag* tags = args->tags; - size_t tags_len = args->tags_len; - unsigned max = args->max; - time_t rel_day = args->rel_day; - size_t days = args->days; - - for (int i = 0; i < tags_len; ++i) - { - for (int j = 0; j < tags[i].history_len; ++j) - { - if (tags[i].history[j].day == rel_day-((days-index-1)*86400)) - curr_sum += tags[i].history[j].uses; - } - } - - return construct_bar((float)curr_sum / max, res); -} - -char* construct_hashtags_graph(struct mstdnt_tag* tags, - size_t tags_len, - size_t days, - size_t* ret_size) -{ - unsigned max_sum = 0; - unsigned curr_sum = 0; - size_t max_history_len = 0; - - // Get current time at midnight for basis, copy over - time_t t = time(NULL); - struct tm* mn_ptr = gmtime(&t); - struct tm mn; - memcpy(&mn, mn_ptr, sizeof(mn)); - mn.tm_hour = 0; - mn.tm_min = 0; - mn.tm_sec = 0; - time_t rel_day = timegm(&mn); - - // Run a loop through all the hashtags, sum each set up, - // then get the largest sum - for (size_t i = 0; i < days; ++i) - { - for (size_t j = 0; j < tags_len && i < tags[j].history_len; ++j) - { - if (tags[j].history_len > max_history_len) - max_history_len = tags[j].history_len; - if (tags[j].history[i].day >= rel_day-(i*86400)) - curr_sum += tags[j].history[i].uses; - } - - if (curr_sum > max_sum) - max_sum = curr_sum; - curr_sum = 0; - } - - struct hashtags_graph_args args = { - .tags = tags, - .tags_len = tags_len, - .max = max_sum, - .rel_day = rel_day, - .days = max_history_len, - }; - - return construct_func_strings(construct_hashgraph_voidwrap, &args, max_history_len, ret_size); -} diff --git a/src/graphsnbars.h b/src/graphsnbars.h deleted file mode 100644 index 344be91..0000000 --- a/src/graphsnbars.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef GRAPHS_N_BARS_H -#define GRAPHS_N_BARS_H -#include -#include -#include "session.h" - -char* construct_bar_graph_container(char* bars, size_t* size); -char* construct_bar(float value, size_t* size); -char* construct_hashtags_graph(struct mstdnt_tag* tags, - size_t tags_len, - size_t days, - size_t* ret_size); - -#endif /* GRAPHS_N_BARS_H */ diff --git a/src/hashtag.c b/src/hashtag.c index 2e44e33..8bdc886 100644 --- a/src/hashtag.c +++ b/src/hashtag.c @@ -22,44 +22,7 @@ #include "easprintf.h" #include "../config.h" -// Pages -#include "../static/hashtag.ctmpl" -#include "../static/hashtag_page.ctmpl" #define TAG_SIZE_INITIAL 12 -static unsigned hashtag_history_daily_uses(size_t max, struct mstdnt_history* history, size_t history_len) -{ - unsigned total = 0; - - for (int i = 0; i < history_len && i < max; ++i) - total += history[i].uses; - - return total; -} - -char* construct_hashtag(struct mstdnt_tag* hashtag, size_t* size) -{ - // Lol! - unsigned hash_size = TAG_SIZE_INITIAL + - CLAMP(hashtag_history_daily_uses(7, hashtag->history, hashtag->history_len)*2, 0, 42); - - struct hashtag_template data = { - .prefix = config_url_prefix, - .tag = hashtag->name, - .tag_size = hash_size, - }; - return tmpl_gen_hashtag(&data, size); -} - -static char* construct_hashtag_voidwrap(void* passed, size_t index, size_t* res) -{ - return construct_hashtag((struct mstdnt_tag*)passed + index, res); -} - -char* construct_hashtags(struct mstdnt_tag* hashtags, size_t size, size_t* ret_size) -{ - if (!(hashtags && size)) return NULL; - return construct_func_strings(construct_hashtag_voidwrap, hashtags, size, ret_size); -} diff --git a/src/hashtag.h b/src/hashtag.h index cbf2992..fb6f431 100644 --- a/src/hashtag.h +++ b/src/hashtag.h @@ -21,7 +21,6 @@ #include #include -char* construct_hashtag(struct mstdnt_tag* hashtag, size_t* size); -char* construct_hashtags(struct mstdnt_tag* hashtags, size_t size, size_t* ret_size); +// TODO? #endif /* HASHTAG_H */ diff --git a/src/lists.c b/src/lists.c index ce24f34..225133c 100644 --- a/src/lists.c +++ b/src/lists.c @@ -29,10 +29,6 @@ #include "lists.h" #include "string_helpers.h" #include "http.h" -// Files -#include "../static/account.ctmpl" -#include "../static/list.ctmpl" -#include "../static/lists.ctmpl" void content_lists(PATH_ARGS) { diff --git a/src/login.c b/src/login.c index 9a09c82..4c3f5fd 100644 --- a/src/login.c +++ b/src/login.c @@ -29,8 +29,6 @@ #include #include -// Files -#include "../static/login.ctmpl" #define LOGIN_SCOPE "read+write+follow+push" @@ -163,7 +161,7 @@ void content_login(PATH_ARGS) if (mastodont_register_app(api, &m_args, &args_app, &storage, &app) != 0) { - error = construct_error(oauth_store.error, E_ERROR, 1, NULL); +// error = construct_error(oauth_store.error, E_ERROR, 1, NULL); } else { struct mstdnt_application_args args_token = { @@ -183,7 +181,7 @@ void content_login(PATH_ARGS) &oauth_store, &token) != 0 && oauth_store.error) { - error = construct_error(oauth_store.error, E_ERROR, 1, NULL); + //error = construct_error(oauth_store.error, E_ERROR, 1, NULL); } else { if (url_link) diff --git a/src/navigation.c b/src/navigation.c deleted file mode 100644 index fe45f2b..0000000 --- a/src/navigation.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include "navigation.h" -#include "easprintf.h" - -// Pages -#include "../static/navigation.ctmpl" - -#define SUBMIT_HTML "" - -char* construct_navigation_box(char* start_id, - char* prev_id, - char* next_id, - size_t* size) -{ - int is_start = start_id && prev_id ? strcmp(start_id, prev_id) == 0 : 0; - - struct navigation_template tdata = { - .start_id = start_id, - .min_id = prev_id, - .prev_active = is_start ? "btn-disabled" : NULL, - .prev_submit = is_start ? "" : SUBMIT_HTML, - .max_id = next_id - }; - return tmpl_gen_navigation(&tdata, size); -} diff --git a/src/navigation.h b/src/navigation.h deleted file mode 100644 index e15901b..0000000 --- a/src/navigation.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef NAVIGATION_H -#define NAVIGATION_H -#include -#include - -char* construct_navigation_box(char* start_id, - char* prev_id, - char* next_id, - size_t* size); - -#endif // NAVIGATION_H diff --git a/src/notifications.c b/src/notifications.c index 3c4418c..e5bdf9d 100644 --- a/src/notifications.c +++ b/src/notifications.c @@ -25,7 +25,6 @@ #include "base_page.h" #include "string_helpers.h" #include "easprintf.h" -#include "navigation.h" #include "http.h" #include "status.h" #include "error.h" @@ -33,165 +32,6 @@ #include "account.h" #include "../config.h" -// Pages -#include "../static/notifications_page.ctmpl" -#include "../static/notifications.ctmpl" -#include "../static/notification_action.ctmpl" -#include "../static/notification.ctmpl" -#include "../static/notification_compact.ctmpl" -#include "../static/like_svg.ctmpl" -#include "../static/repeat_svg.ctmpl" -#include "../static/notifications_embed.ctmpl" - -struct notification_args -{ - struct session* ssn; - mastodont_t* api; - struct mstdnt_notification* notifs; -}; - -char* construct_notification(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notif, - size_t* size) -{ - char* notif_html; - - if (notif->status) - { - // Construct status with notification_info - notif_html = construct_status(ssn, api, notif->status, size, notif, NULL, 0); - } - else { - notif_html = construct_notification_action(notif, size); - } - - return notif_html; -} - -char* construct_notification_action(struct mstdnt_notification* notif, size_t* size) -{ - char* res; - char* serialized_display_name = sanitize_html(notif->account->display_name); - char* display_name = emojify(serialized_display_name, - notif->account->emojis, - notif->account->emojis_len); - struct notification_action_template tdata = { - .avatar = notif->account->avatar, - .acct = notif->account->acct, - .display_name = display_name, - .prefix = config_url_prefix, - .action = notification_type_compact_str(notif->type), - .notif_svg = notification_type_svg(notif->type) - }; - res = tmpl_gen_notification_action(&tdata, size); - /* // Cleanup */ - if (display_name != notif->account->display_name && - display_name != serialized_display_name) - free(display_name); - if (serialized_display_name != notif->account->display_name) - free(serialized_display_name); - return res; -} - -char* construct_notification_compact(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notif, - size_t* size) -{ - char* notif_html; - char* status_format = NULL; - char* notif_stats = NULL; - - const char* type_str = notification_type_compact_str(notif->type); - const char* type_svg = notification_type_svg(notif->type); - - if (notif->status) - { - if (notif->type == MSTDNT_NOTIFICATION_MENTION) - notif_stats = construct_interaction_buttons(ssn, notif->status, NULL, - STATUS_NO_LIKEBOOST | STATUS_NO_DOPAMEME); - status_format = reformat_status(ssn, - notif->status->content, - notif->status->emojis, - notif->status->emojis_len); - } - - char* serialized_display_name = sanitize_html(notif->account->display_name); - char* display_name = emojify(serialized_display_name, - notif->account->emojis, - notif->account->emojis_len); - struct notification_compact_template tdata = { - .avatar = notif->account->avatar, - .has_icon = strlen(type_svg) == 0 ? "" : "-with-icon", - .acct = notif->account->acct, - .display_name = display_name, - .action = type_str, - .notif_svg = type_svg, - .is_status = (notif->type == MSTDNT_NOTIFICATION_STATUS || - notif->type == MSTDNT_NOTIFICATION_MENTION ? "is-mention" : NULL), - /* Might show follower address */ - .content = (notif->type == MSTDNT_NOTIFICATION_FOLLOW ? - notif->account->acct : status_format), - .stats = notif_stats - }; - - notif_html = tmpl_gen_notification_compact(&tdata, size); - - if (status_format && - status_format != notif->status->content) free(status_format); - if (notif_stats) free(notif_stats); - if (serialized_display_name != notif->account->display_name) - free(serialized_display_name); - if (display_name != notif->account->display_name && - display_name != serialized_display_name) - free(display_name); - return notif_html; -} - -static char* construct_notification_voidwrap(void* passed, size_t index, size_t* res) -{ - struct notification_args* args = passed; - return construct_notification(args->ssn, args->api, args->notifs + index, res); -} - -static char* construct_notification_compact_voidwrap(void* passed, size_t index, size_t* res) -{ - struct notification_args* args = passed; - return construct_notification_compact(args->ssn, args->api, args->notifs + index, res); -} - -char* construct_notifications(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notifs, - size_t size, - size_t* ret_size) -{ - struct notification_args args = { - .ssn = ssn, - .api = api, - .notifs = notifs - }; - return construct_func_strings(construct_notification_voidwrap, &args, size, ret_size); -} - -char* construct_notifications_compact(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notifs, - size_t size, - size_t* ret_size) -{ - struct notification_args args = { - .ssn = ssn, - .api = api, - .notifs = notifs - }; - return construct_func_strings(construct_notification_compact_voidwrap, - &args, - size, - ret_size); -} - void content_notifications(PATH_ARGS) { struct mstdnt_args m_args; diff --git a/src/notifications.h b/src/notifications.h index 9ceed69..8df3ab5 100644 --- a/src/notifications.h +++ b/src/notifications.h @@ -23,29 +23,8 @@ #include #include "session.h" #include "path.h" -#include "type_string.h" #include "global_perl.h" -char* construct_notification(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notif, - size_t* size); -char* construct_notification_action(struct mstdnt_notification* notif, size_t* size); -char* construct_notification_compact(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notif, - size_t* size); -char* construct_notifications(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notifs, - size_t size, - size_t* ret_size); -char* construct_notifications_compact(struct session* ssn, - mastodont_t* api, - struct mstdnt_notification* notifs, - size_t size, - size_t* ret_size); - // Page contents void content_notifications(PATH_ARGS); void content_notifications_compact(PATH_ARGS); diff --git a/src/page_config.c b/src/page_config.c index f7022c0..6e35af7 100644 --- a/src/page_config.c +++ b/src/page_config.c @@ -31,11 +31,6 @@ #include "l10n.h" #include -// Pages -#include "../static/config_general.ctmpl" -#include "../static/config_appearance.ctmpl" -#include "../static/config_sidebar.ctmpl" - #define bool_checked(key) (ssn->config.key ? "checked" : "") enum config_category diff --git a/src/reply.c b/src/reply.c deleted file mode 100644 index 7203cde..0000000 --- a/src/reply.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#define PCRE2_CODE_UNIT_WIDTH 8 - -#include -#include -#include -#include "reply.h" -#include "easprintf.h" -#include "../config.h" - -// Pages -#include "../static/post.ctmpl" - -#define ID_REPLY_SIZE 256 -#define ID_RESPONSE "" - -char* construct_post_box(struct mstdnt_status* reply_status, - char* default_content, - size_t* size) -{ -#define C_S "checked" -#define D_S "disabled" - char* reply_html; - char id_reply[ID_REPLY_SIZE]; - enum mstdnt_visibility_type vis = MSTDNT_VISIBILITY_PUBLIC; - - // Put hidden post request and check visibility - if (reply_status) - { - snprintf(id_reply, ID_REPLY_SIZE, ID_RESPONSE, reply_status->id); - vis = reply_status->visibility; - } - - /* - * Mastodont-c orders the visibility type from smallest (PUBLIC) to - * largest (LOCAL), so we take advantage of the enum values - */ - struct post_template tdata = { - .prefix = config_url_prefix, - .reply_input = reply_status ? id_reply : NULL, - .content = default_content, - .public_checked = vis == MSTDNT_VISIBILITY_PUBLIC ? C_S : NULL, - // You can reply with public to unlisted posts - .public_disabled = vis > MSTDNT_VISIBILITY_UNLISTED ? D_S : NULL, - .unlisted_checked = vis == MSTDNT_VISIBILITY_UNLISTED ? C_S : NULL, - .unlisted_disabled = vis > MSTDNT_VISIBILITY_UNLISTED ? D_S : NULL, - .private_checked = vis == MSTDNT_VISIBILITY_PRIVATE ? C_S : NULL, - .private_disabled = vis > MSTDNT_VISIBILITY_PRIVATE ? D_S : NULL, - .direct_checked = vis == MSTDNT_VISIBILITY_DIRECT ? C_S : NULL, - .local_checked = vis == MSTDNT_VISIBILITY_LOCAL ? C_S : NULL, - }; - return tmpl_gen_post(&tdata, size); -} - -/* Some comments: - * - Misskey does not return , but we still regex to make sure it's a highlight - * - The order of parameters in a tag can be changed (mastodon does this), - * so we just grep for regex href - * - Misskey/Mastodon adds an @ symbol in the href param, while pleroma adds /users and honk adds /u - */ -#define REGEX_REPLY "@(?:)?.*?(?:<\\/span>)?" - -char* reply_status(struct session* ssn, char* id, struct mstdnt_status* status) -{ - char* content = status->content; - size_t content_len = strlen(status->content); - char* stat_reply; - // Regex - pcre2_code* re; - PCRE2_SIZE* re_results; - pcre2_match_data* re_data; - // Regex data - int rc; - int error; - PCRE2_SIZE erroffset; - int url_off, url_len, name_off, name_len; - // Replies - size_t replies_size = 0, replies_size_orig; - char* replies = NULL; - char* instance_domain = malloc(sizeof(config_instance_url)+sizeof("https:///")+1); - - // sscanf instead of regex works here and requires less work, we just need to trim off the slash at the end - if (sscanf(config_instance_url, "https://%s/", instance_domain) == 0) - if (sscanf(config_instance_url, "http://%s/", instance_domain) == 0) - { - free(instance_domain); - return NULL; - } - - instance_domain[strlen(instance_domain)] = '\0'; - // Remove ports, if any. Needed for development or if - // the server actually supports these - char* port_val = strchr(instance_domain, ':'); - if (port_val) *port_val = '\0'; - - // Load first reply - if (ssn->logged_in && strcmp(status->account.acct, ssn->acct.acct) != 0) - { - replies = malloc(replies_size = strlen(status->account.acct)+2); - replies[0] = '@'; - strcpy(replies+1, status->account.acct); - replies[replies_size-1] = ' '; - } - - // Compile regex - re = pcre2_compile((PCRE2_SPTR)REGEX_REPLY, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL); - if (re == NULL) - { - fprintf(stderr, "Couldn't parse regex at offset %ld: %d\n", erroffset, error); - free(replies); - pcre2_code_free(re); - } - - re_data = pcre2_match_data_create_from_pattern(re, NULL); - - for (int ind = 0;;) - { - rc = pcre2_match(re, (PCRE2_SPTR)content, content_len, ind, 0, re_data, NULL); - if (rc < 0) - break; - - re_results = pcre2_get_ovector_pointer(re_data); - - // Store to last result - ind = re_results[5]; - - // Read out - url_off = re_results[2]; - url_len = re_results[3] - url_off; - name_off = re_results[4]; - name_len = re_results[5] - name_off; - - int instance_cmp = strncmp(instance_domain, content+url_off, url_len); - // Is this the same as us? - // Cut off url_len by one to slice the '/' at the end - if (instance_cmp == 0 && - strncmp(ssn->acct.acct, content+name_off, name_len) == 0) - continue; - - replies_size_orig = replies_size; - replies_size += (instance_cmp!=0?url_len:0)+name_len+3-(instance_cmp==0); // Bool as int :^) - - // Realloc string - replies = realloc(replies, replies_size+1); - - replies[replies_size_orig] = '@'; - memcpy(replies + replies_size_orig + 1, content + name_off, name_len); - if (instance_cmp != 0) - { - replies[replies_size_orig+1+name_len] = '@'; - memcpy(replies + replies_size_orig + 1 + name_len + 1, content + url_off, url_len); - } - replies[replies_size-1] = ' '; - } - - if (replies) - replies[replies_size-1] = '\0'; - - pcre2_match_data_free(re_data); - - stat_reply = construct_post_box(status, replies, NULL); - pcre2_code_free(re); - free(replies); - free(instance_domain); - return stat_reply; -} diff --git a/src/reply.h b/src/reply.h deleted file mode 100644 index b01c6be..0000000 --- a/src/reply.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef REPLY_H -#define REPLY_H -#include "session.h" -#include -#include - -char* construct_post_box(struct mstdnt_status* reply_id, - char* default_content, - size_t* size); - -char* reply_status(struct session* ssn, - char* id, - struct mstdnt_status* status); - - -#endif // REPLY_H diff --git a/src/scrobble.c b/src/scrobble.c index eb0aab1..c6a2040 100644 --- a/src/scrobble.c +++ b/src/scrobble.c @@ -19,35 +19,36 @@ #include "scrobble.h" #include "easprintf.h" #include "string_helpers.h" +#include "account.h" -#include "../static/scrobble.ctmpl" - -char* construct_scrobble(struct mstdnt_scrobble* scrobble, size_t* size) +// Converts it into a perl struct +HV* perlify_scrobble(struct mstdnt_scrobble* scrobble) { - struct scrobble_template tdata = { - .scrobble_id = scrobble->id, - .avatar = scrobble->account.avatar, - .username = scrobble->account.display_name, - .activity = "is listening to...", - .title_key = "Title", - .title = scrobble->title, - .artist_key = "Artist", - .artist = scrobble->artist, - .album_key = "Album", - .album = scrobble->album, - .length_key = "Duration", - .length = scrobble->length - }; + if (!scrobble) return NULL; + HV* scrobble_hv = newHV(); - return tmpl_gen_scrobble(&tdata, size); + hvstores_str(scrobble_hv, "album", scrobble->album); + hvstores_str(scrobble_hv, "artist", scrobble->artist); + hvstores_str(scrobble_hv, "id", scrobble->id); + hvstores_str(scrobble_hv, "title", scrobble->title); + hvstores_int(scrobble_hv, "created_at", scrobble->created_at); + hvstores_int(scrobble_hv, "length", scrobble->created_at); + hvstores_ref(scrobble_hv, "account", perlify_account(&(scrobble->account))); + + return scrobble_hv; } -static char* construct_scrobble_voidwrap(void* passed, size_t index, size_t* res) +// The same as above, but for multiple +AV* perlify_scrobbles(struct mstdnt_scrobble* scrobble, size_t len) { - return construct_scrobble((struct mstdnt_scrobble*)passed + index, res); -} + if (!(scrobble && len)) return NULL; + AV* av = newAV(); + av_extend(av, len-1); -char* construct_scrobbles(struct mstdnt_scrobble* scrobbles, size_t scrobbles_len, size_t* ret_size) -{ - return construct_func_strings(construct_scrobble_voidwrap, scrobbles, scrobbles_len, ret_size); + for (int i = 0; i < len; ++i) + { + av_store(av, i, newRV_inc((SV*)perlify_scrobble(scrobble + i))); + } + + return av; } diff --git a/src/scrobble.h b/src/scrobble.h index 9e1f90d..ef20e9b 100644 --- a/src/scrobble.h +++ b/src/scrobble.h @@ -19,8 +19,9 @@ #ifndef SCROBBLE_H #define SCROBBLE_H #include +#include "global_perl.h" -char* construct_scrobble(struct mstdnt_scrobble* scrobble, size_t* size); -char* construct_scrobbles(struct mstdnt_scrobble* scrobbles, size_t scrobbles_len, size_t* ret_size); +HV* perlify_scrobble(struct mstdnt_scrobble* scrobble); +AV* perlify_scrobbles(struct mstdnt_scrobble* scrobble, size_t len); #endif /* SCROBBLE_H */ diff --git a/src/search.c b/src/search.c index 5377e63..cf407f0 100644 --- a/src/search.c +++ b/src/search.c @@ -28,42 +28,6 @@ #include "hashtag.h" #include "error.h" #include "account.h" -#include "graphsnbars.h" - -// Pages -#include "../static/search.ctmpl" -#include "../static/search_all.ctmpl" - -void search_page(FCGX_Request* req, - struct session* ssn, - mastodont_t* api, - enum search_tab tab, - char* content) -{ - char* out_data; - struct search_template tdata = { - .prefix = config_url_prefix, - .query = keystr(ssn->query.query), - .accounts_active = MAKE_FOCUSED_IF(tab, SEARCH_ACCOUNTS), - .accounts = "Accounts", - .hashtags_active = MAKE_FOCUSED_IF(tab, SEARCH_HASHTAGS), - .hashtags = "Hashtags", - .statuses_active = MAKE_FOCUSED_IF(tab, SEARCH_STATUSES), - .statuses = "Statuses", - .results = content - }; - out_data = tmpl_gen_search(&tdata, NULL); - - struct base_page b = { - .category = BASE_CAT_NONE, - .content = out_data, - .sidebar_left = NULL - }; - - // Output - render_base_page(&b, req, ssn, api); - free(out_data); -} void content_search_all(PATH_ARGS) { diff --git a/src/search.h b/src/search.h index 756de7c..7d30abf 100644 --- a/src/search.h +++ b/src/search.h @@ -23,18 +23,6 @@ #include "path.h" #include "global_perl.h" -enum search_tab -{ - SEARCH_STATUSES, - SEARCH_ACCOUNTS, - SEARCH_HASHTAGS, -}; - -void search_page(FCGX_Request* req, - struct session* ssn, - mastodont_t* api, - enum search_tab tab, - char* content); void content_search_all(PATH_ARGS); void content_search_statuses(PATH_ARGS); void content_search_accounts(PATH_ARGS); diff --git a/src/status.c b/src/status.c index a4890ec..39e8b71 100644 --- a/src/status.c +++ b/src/status.c @@ -30,50 +30,16 @@ #include "cookie.h" #include "string_helpers.h" #include "error.h" -#include "reply.h" #include "attachments.h" #include "emoji_reaction.h" #include "../config.h" -#include "type_string.h" #include "string.h" #include "emoji.h" #include "account.h" -// Pages -#include "../static/status.ctmpl" -#include "../static/notification.ctmpl" -#include "../static/in_reply_to.ctmpl" -#include "../static/status_interactions_label.ctmpl" -#include "../static/status_interactions.ctmpl" -#include "../static/status_interaction_profile.ctmpl" -#include "../static/interactions_page.ctmpl" -#include "../static/likeboost.ctmpl" -#include "../static/reactions_btn.ctmpl" -#include "../static/interaction_buttons.ctmpl" -#include "../static/reply_link.ctmpl" -#include "../static/reply_checkbox.ctmpl" -#include "../static/menu_item.ctmpl" -#include "../static/like_btn.ctmpl" -#include "../static/repeat_btn.ctmpl" -#include "../static/reply_btn.ctmpl" -#include "../static/expand_btn.ctmpl" -#include "../static/like_btn_img.ctmpl" -#include "../static/repeat_btn_img.ctmpl" -#include "../static/reply_btn_img.ctmpl" -#include "../static/expand_btn_img.ctmpl" -#include "../static/thread_page_btn.ctmpl" - #define ACCOUNT_INTERACTIONS_LIMIT 11 #define NUM_STR "%u" -struct status_args -{ - mastodont_t* api; - struct mstdnt_status* status; - struct construct_statuses_args* args; - struct session* ssn; -}; - int try_post_status(struct session* ssn, mastodont_t* api) { if (!(keystr(ssn->post.content))) return 1; @@ -185,27 +151,6 @@ void content_status_react(PATH_ARGS) redirect(req, REDIRECT_303, referer); } -const char* status_visibility_str(enum l10n_locale loc, - enum mstdnt_visibility_type vis) -{ - switch (vis) - { - case MSTDNT_VISIBILITY_UNLISTED: - return L10N[loc][L10N_VIS_UNLISTED]; - case MSTDNT_VISIBILITY_PRIVATE: - return L10N[loc][L10N_VIS_PRIVATE]; - case MSTDNT_VISIBILITY_DIRECT: - return L10N[loc][L10N_VIS_DIRECT]; - case MSTDNT_VISIBILITY_LOCAL: - return L10N[loc][L10N_VIS_LOCAL]; - case MSTDNT_VISIBILITY_LIST: - return L10N[loc][L10N_VIS_LIST]; - case MSTDNT_VISIBILITY_PUBLIC: - default: - return L10N[loc][L10N_VIS_PUBLIC]; - } -} - int try_interact_status(struct session* ssn, mastodont_t* api, char* id) { struct mstdnt_args m_args; @@ -245,127 +190,6 @@ int try_interact_status(struct session* ssn, mastodont_t* api, char* id) return res; } -char* construct_status_interactions_label(char* status_id, - int is_favourites, - char* header, - int val, - size_t* size) -{ - struct status_interactions_label_template tdata = { - .prefix = config_url_prefix, - .status_id = status_id, - .action = is_favourites ? "favourited_by" : "reblogged_by", - .header = header, - .value = val, - }; - return tmpl_gen_status_interactions_label(&tdata, size); -} - -char* construct_interaction_buttons(struct session* ssn, - struct mstdnt_status* status, - size_t* size, - uint8_t flags) -{ - return ""; -} - -char* construct_status_interactions(char* status_id, - int fav_count, - int reblog_count, - struct mstdnt_account* fav_accounts, - size_t fav_accounts_len, - struct mstdnt_account* reblog_accounts, - size_t reblog_accounts_len, - size_t* size) -{ - char* html; - char* reblogs_label = reblog_count ? - construct_status_interactions_label(status_id, 0, "Reblogs", reblog_count, NULL) : NULL; - char* favourites_label = fav_count ? - construct_status_interactions_label(status_id, 1, "Favorites", fav_count, NULL) : NULL; - char* profiles = construct_status_interaction_profiles(reblog_accounts, - fav_accounts, - reblog_accounts_len, - fav_accounts_len, - NULL); - struct status_interactions_template tdata = { - .favourites_count = favourites_label, - .reblogs_count = reblogs_label, - .users = profiles - }; - html = tmpl_gen_status_interactions(&tdata, size); - if (reblogs_label) free(reblogs_label); - if (favourites_label) free(favourites_label); - if (profiles) free(profiles); - return html; -} - -char* construct_status_interaction_profile(struct interact_profile_args* args, size_t index, size_t* size) -{ - size_t s = 0; - // Might change - struct mstdnt_account* check_type = args->reblogs; - char* profile_html = NULL; - - // Loop through reblogs first, then favourites - if (index >= args->reblogs_len) - { - index -= args->reblogs_len; - check_type = args->favourites; - } - - // If favourites, loops through reblogs to verify no duplicates - if (check_type == args->favourites) - { - for (size_t i = 0; i < args->reblogs_len; ++i) - if (strcmp(check_type[index].id, args->reblogs[i].id) == 0) - { - if (size) *size = 0; - return NULL; - } - } - - // Usually means no reblogs if check_type is NULL - if (check_type) - { - struct status_interaction_profile_template tdata = { - .acct = check_type[index].acct, - .avatar = check_type[index].avatar - }; - profile_html = tmpl_gen_status_interaction_profile(&tdata, &s); - } - - if (size) *size = s; - return profile_html; -} - -static char* construct_status_interaction_profiles_voidwrap(void* passed, size_t index, size_t* res) -{ - struct interact_profile_args* args = passed; - return construct_status_interaction_profile(args, index, res); -} - -char* construct_status_interaction_profiles(struct mstdnt_account* reblogs, - struct mstdnt_account* favourites, - size_t reblogs_len, - size_t favourites_len, - size_t* ret_size) -{ - size_t arr_size = reblogs_len + favourites_len; - // Set a limit to interactions - if (arr_size > ACCOUNT_INTERACTIONS_LIMIT) - arr_size = ACCOUNT_INTERACTIONS_LIMIT; - - struct interact_profile_args args = { - .reblogs = reblogs, - .reblogs_len = reblogs_len, - .favourites = favourites, - .favourites_len = favourites_len - }; - - return construct_func_strings(construct_status_interaction_profiles_voidwrap, &args, arr_size, ret_size); -} - char* get_in_reply_to(mastodont_t* api, struct session* ssn, struct mstdnt_status* status, @@ -383,418 +207,15 @@ char* get_in_reply_to(mastodont_t* api, &acct, &storage); - char* html = construct_in_reply_to(status, res == 0 ? &acct : NULL, size); + char* html = "TODO"; + +// char* html = construct_in_reply_to(status, res == 0 ? &acct : NULL, size); if (res == 0) mstdnt_cleanup_account(&acct); mastodont_storage_cleanup(&storage); return html; } -char* construct_in_reply_to(struct mstdnt_status* status, - struct mstdnt_account* account, - size_t* size) -{ - struct in_reply_to_template tdata = { - .prefix = config_url_prefix, - .in_reply_to_text = L10N[L10N_EN_US][L10N_IN_REPLY_TO], - .acct = account ? account->acct : status->in_reply_to_id, - .status_id = status->in_reply_to_id - }; - - return tmpl_gen_in_reply_to(&tdata, size); -} - -#define REGEX_GREENTEXT "((?:^|
|\\s)>.*?)(?:
|$)" - -char* reformat_status(struct session* ssn, - char* content, - struct mstdnt_emoji* emos, - size_t emos_len) -{ - if (!content) return NULL; - char* res = make_mentions_local(content); - char* gt_res, *emo_res; - - if (emos) - { - emo_res = emojify(res, emos, emos_len); - if (emo_res != res && res != content) - free(res); - res = emo_res; - } - - if (ssn->config.stat_greentexts) - { - gt_res = greentextify(res); - if (gt_res != res && res != content) - free(res); - res = gt_res; - } - - return res; -} - -#define REGEX_MENTION "(?=
.*?)\\/(?:@|users\\/)?(?<>.*?)?\".*?>" - -char* make_mentions_local(char* content) -{ - char* url_format; - int error; - PCRE2_SIZE erroffset; - int substitute_success = 0; - // Initial size, will be increased by 30% if pcre2_substitute cannot fit into the size - // ...why can't pcre2 just allocate a string with the size for us? Thanks... - size_t res_len = 1024; - char* res = malloc(res_len); - pcre2_code* re = pcre2_compile((PCRE2_SPTR)REGEX_MENTION, - PCRE2_ZERO_TERMINATED, PCRE2_MULTILINE, - &error, &erroffset, NULL); - if (re == NULL) - { - fprintf(stderr, "Couldn't parse regex at offset %d: %s\n", error, REGEX_MENTION + erroffset); - pcre2_code_free(re); - return NULL; - } - - int len = easprintf(&url_format, - "", - config_host_url_insecure ? "" : "s", - getenv("HTTP_HOST")); - - int rc = -1; - PCRE2_SIZE res_len_str; - while (rc < 0) - { - res_len_str = res_len; - rc = pcre2_substitute( - re, - (PCRE2_SPTR)content, - PCRE2_ZERO_TERMINATED, - 0, - PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL, - NULL, - NULL, - (PCRE2_SPTR)url_format, - len, - (PCRE2_UCHAR*)res, - &res_len_str - ); - if (rc < 0) - { - switch (rc) - { - case PCRE2_ERROR_NOMEMORY: - // Increase by 30% and try again - res_len = (float)res_len + ((float)res_len * .3); - res = realloc(res, res_len); - break; - default: - { - char buf[256]; - pcre2_get_error_message(rc, buf, 256); - goto out; - } - } - } - else - substitute_success = 1; - } - -out: - if (!substitute_success) - free(res); - free(url_format); - pcre2_code_free(re); - return substitute_success ? res : content; -} - -char* greentextify(char* content) -{ - if (!content) return NULL; - - int error; - PCRE2_SIZE erroffset; - int rc; - int gt_off; - int gt_len; - char* res = content; - - // Malloc'd strings - char* reg_string; - char* gt_string; - - char* oldres = NULL; - PCRE2_SIZE* re_results; - pcre2_code* re = pcre2_compile((PCRE2_SPTR)REGEX_GREENTEXT, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL); - pcre2_match_data* re_data; - if (re == NULL) - { - fprintf(stderr, "Couldn't parse regex at offset %ld: %d\n", erroffset, error); - pcre2_code_free(re); - return res; - } - - re_data = pcre2_match_data_create_from_pattern(re, NULL); - - for (int ind = 0;;) - { - rc = pcre2_match(re, (PCRE2_SPTR)res, strlen(res), ind, 0, re_data, NULL); - if (rc < 0) - break; - - re_results = pcre2_get_ovector_pointer(re_data); - - // Store to last result - gt_off = re_results[2]; - gt_len = re_results[3] - gt_off; - - oldres = res; - - // Malloc find/repl strings - reg_string = malloc(gt_len + 1); - strncpy(reg_string, res + gt_off, gt_len); - reg_string[gt_len] = '\0'; - easprintf(>_string, "%s", reg_string); - - res = strrepl(res, reg_string, gt_string, STRREPL_ALL ); - if (oldres != content) free(oldres); - ind = re_results[2] + strlen(gt_string); - free(reg_string); - free(gt_string); - } - - pcre2_match_data_free(re_data); - pcre2_code_free(re); - return res; -} - -char* construct_status(struct session* ssn, - mastodont_t* api, - struct mstdnt_status* local_status, - size_t* size, - struct mstdnt_notification* local_notif, - struct construct_statuses_args* args, - uint8_t flags) -{ - struct mstdnt_args m_args; - set_mstdnt_args(&m_args, ssn); - char* stat_html; - - // Counts - char* formatted_display_name = NULL; - char* attachments = NULL; - char* emoji_reactions = NULL; - char* serialized_display_name = NULL; - char* interaction_btns = NULL; - char* notif_info = NULL; - char* post_response = NULL; - char* in_reply_to_str = NULL; - char* delete_status = NULL; - char* pin_status = NULL; - char* interactions_html = NULL; - enum l10n_locale locale = l10n_normalize(ssn->config.lang); - struct mstdnt_status* status = local_status; - // Create a "fake" notification header which contains information for - // the reblogged status - struct mstdnt_notification notif_reblog; - struct mstdnt_notification* notif = local_notif; - struct mstdnt_account* favourites = NULL; - struct mstdnt_account* reblogs = NULL; - struct mstdnt_storage favourites_storage = { 0 }; - struct mstdnt_storage reblogs_storage = { 0 }; - size_t favourites_len = 0; - size_t reblogs_len = 0; - - if (!status) return NULL; - - // If focused, show status interactions - if ((flags & STATUS_FOCUSED) == STATUS_FOCUSED && - (status->reblogs_count || status->favourites_count)) - { - if (status->favourites_count) - mastodont_status_favourited_by(api, - &m_args, - status->id, - &favourites_storage, - &favourites, - &favourites_len); - if (status->reblogs_count) - mastodont_status_reblogged_by(api, - &m_args, - status->id, - &reblogs_storage, - &reblogs, - &reblogs_len); - interactions_html = construct_status_interactions(status->id, - status->favourites_count, - status->reblogs_count, - favourites, - favourites_len, - reblogs, - reblogs_len, - NULL); - mastodont_storage_cleanup(&reblogs_storage); - mastodont_storage_cleanup(&favourites_storage); - - mstdnt_cleanup_accounts(favourites, favourites_len); - mstdnt_cleanup_accounts(reblogs, reblogs_len); - } - - // Repoint value if it's a reblog - if (status->reblog) - { - status = status->reblog; - // Point to our account - notif_reblog.account = &(local_status->account); - notif_reblog.type = MSTDNT_NOTIFICATION_REBLOG; - notif = ¬if_reblog; - } - - // Format username with emojis - serialized_display_name = sanitize_html(status->account.display_name); - formatted_display_name = emojify(serialized_display_name, - status->account.emojis, - status->account.emojis_len); - // Format status - char* parse_content = reformat_status(ssn, status->content, status->emojis, status->emojis_len); - - interaction_btns = construct_interaction_buttons(ssn, status, NULL, flags); - - // Find and replace - if (args && args->highlight_word && parse_content != status->content) - { - char* parse_content_tmp; - char* repl_str = NULL; - easprintf(&repl_str, "%s", args->highlight_word); - parse_content_tmp = parse_content; - parse_content = strrepl(parse_content, args->highlight_word, repl_str, STRREPL_ALL); - // Check if the old parse_content needed to be free'd - if (parse_content_tmp != status->content && - parse_content != parse_content_tmp) - free(parse_content_tmp); - else // No results, move back - parse_content = parse_content_tmp; - - free(repl_str); - } - - if (ssn->logged_in) - post_response = reply_status(ssn, status->in_reply_to_account_id , status); - - // Delete status menu item and pinned, logged in only - if (ssn->logged_in && strcmp(status->account.acct, ssn->acct.acct) == 0) - { - struct menu_item_template mdata = { - .prefix = config_url_prefix, - .status_id = status->id, - .itype = "delete", - .text = "Delete status" - }; - delete_status = tmpl_gen_menu_item(&mdata, NULL); - - mdata.itype = status->pinned ? "unpin" : "pin"; - mdata.text = status->pinned ? "Unpin status" : "Pin status"; - pin_status = tmpl_gen_menu_item(&mdata, NULL); - } - - if (status->media_attachments_len) - attachments = construct_attachments(ssn, status->sensitive, status->media_attachments, status->media_attachments_len, NULL); - if (status->pleroma.emoji_reactions_len) - emoji_reactions = construct_emoji_reactions(status->id, status->pleroma.emoji_reactions, status->pleroma.emoji_reactions_len, NULL); - if (notif && notif->type != MSTDNT_NOTIFICATION_MENTION) - { - char* notif_serialized_name = sanitize_html(notif->account->display_name); - char* notif_display_name = emojify(notif_serialized_name, - notif->account->emojis, - notif->account->emojis_len); - struct notification_template tdata = { - .avatar = notif->account->avatar, - .username = notif_display_name, - .action = (local_status->reblog ? notification_type_compact_str(notif->type) : notification_type_str(notif->type)), - .action_item = notification_type_svg(notif->type), - }; - notif_info = tmpl_gen_notification(&tdata, NULL); - if (notif_display_name != notif->account->display_name) - free(notif_display_name); - if (notif_serialized_name != notif_display_name && - notif_serialized_name != notif->account->display_name) - free(notif_serialized_name); - } - - if (status->in_reply_to_id && status->in_reply_to_account_id) - in_reply_to_str = get_in_reply_to(api, ssn, status, NULL); - - struct status_template tmpl = { - .status_id = status->id, - .notif_info = notif_info, - .thread_hidden = status->muted ? "checked" : "", - // TODO doesn't even need to be a hashtag, this is a temporary hack - .is_cat = status->account.note && strstr(status->account.note, "isCat") ? "is-cat" : NULL, - .is_bun = status->account.note && strstr(status->account.note, "isBun") ? " is-bun" : NULL, - .avatar = status->account.avatar, - .username = formatted_display_name, - .prefix = config_url_prefix, - .acct = status->account.acct, - .visibility = status_visibility_str(locale, status->visibility), - .unmute = status->muted ? "un" : "", - .unmute_btn = status->muted ? "Unmute thread" : "Mute thread", - .unbookmark = status->bookmarked ? "un" : "", - .unbookmark_btn = status->bookmarked ? "Remove Bookmark" : "Bookmark", - .delete_status = delete_status, - .pin_status = pin_status, - .in_reply_to_str = in_reply_to_str, - .status_content = parse_content, - .attachments = attachments, - .interactions = interactions_html, - .emoji_reactions = emoji_reactions, - .interaction_btns = interaction_btns, - .reply = post_response, - }; - - stat_html = tmpl_gen_status(&tmpl, size); - - // Cleanup - if (formatted_display_name != status->account.display_name && - formatted_display_name != serialized_display_name) - free(formatted_display_name); - if (serialized_display_name != status->account.display_name) - free(serialized_display_name); - free(in_reply_to_str); - free(attachments); - free(post_response); - free(emoji_reactions); - if (notif) free(notif_info); - free(delete_status); - free(pin_status); - free(interactions_html); - if (parse_content != status->content) - free(parse_content); - return stat_html; -} - -static char* construct_status_voidwrap(void* passed, size_t index, size_t* res) -{ - struct status_args* args = passed; - return construct_status(args->ssn, args->api, args->status + index, res, NULL, args->args, 0); -} - -char* construct_statuses(struct session* ssn, - mastodont_t* api, - struct mstdnt_status* statuses, - size_t size, - struct construct_statuses_args* args, - size_t* ret_size) -{ - if (!(statuses && size)) return NULL; - struct status_args stat_args = { - .api = api, - .status = statuses, - .args = args, - .ssn = ssn, - }; - return construct_func_strings(construct_status_voidwrap, &stat_args, size, ret_size); -} - void status_interact(PATH_ARGS) { char* referer = GET_ENV("HTTP_REFERER", req); diff --git a/src/status.h b/src/status.h index 812af79..f90648c 100644 --- a/src/status.h +++ b/src/status.h @@ -53,64 +53,17 @@ void content_status_create(PATH_ARGS); void content_status_react(PATH_ARGS); // HTML Builders -char* construct_status(struct session* ssn, - mastodont_t* api, - struct mstdnt_status* status, - size_t* size, - struct mstdnt_notification* notif, - struct construct_statuses_args* args, - uint8_t flags); -char* construct_statuses(struct session* ssn, - mastodont_t* api, - struct mstdnt_status* statuses, - size_t size, - struct construct_statuses_args* args, - size_t* ret_size); -char* construct_interaction_buttons(struct session* ssn, - struct mstdnt_status* status, - size_t* size, - uint8_t flags); + // Reply to +/** Deprecated: May be used in the future for Mastodon only */ char* get_in_reply_to(mastodont_t* api, struct session* ssn, struct mstdnt_status* status, size_t* size); -char* construct_in_reply_to(struct mstdnt_status* status, - struct mstdnt_account* account, - size_t* size); - -char* construct_status_interactions(char* status_id, - int fav_count, - int reblog_count, - struct mstdnt_account* fav_accounts, - size_t fav_accounts_len, - struct mstdnt_account* reblog_accounts, - size_t reblog_accounts_len, - size_t* size); - -char* construct_status_interaction_profiles(struct mstdnt_account* reblogs, - struct mstdnt_account* favourites, - size_t reblogs_len, - size_t favourites_len, - size_t* ret_size); -char* construct_status_interaction_profile(struct interact_profile_args* args, size_t index, size_t* size); -char* construct_status_interactions_label(char* status_id, - int is_favourites, - char* header, - int val, - size_t* size); -char* reformat_status(struct session* ssn, - char* content, - struct mstdnt_emoji* emos, - size_t emos_len); -char* greentextify(char* content); -char* make_mentions_local(char* content); void status_view_reblogs(PATH_ARGS); void status_view_favourites(PATH_ARGS); -const char* status_visibility_str(enum l10n_locale locale, enum mstdnt_visibility_type visibility); - void content_status_interactions(FCGX_Request* req, struct session* ssn, mastodont_t* api, diff --git a/src/timeline.c b/src/timeline.c index 2f57909..d6151af 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -26,15 +26,10 @@ #include "index.h" #include "status.h" #include "easprintf.h" -#include "reply.h" -#include "navigation.h" #include "query.h" #include "error.h" #include "string_helpers.h" -#include "../static/timeline_options.ctmpl" -#include "../static/navigation.ctmpl" - void content_timeline(FCGX_Request* req, struct session* ssn, mastodont_t* api, diff --git a/src/type_string.c b/src/type_string.c deleted file mode 100644 index 24d20f7..0000000 --- a/src/type_string.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include "type_string.h" - -// Icons -#include "../static/like_svg.ctmpl" -#include "../static/repeat_svg.ctmpl" -#include "../static/follow_svg.ctmpl" - -const char* notification_type_str(mstdnt_notification_t type) -{ - switch (type) - { - case MSTDNT_NOTIFICATION_FOLLOW: return L10N[L10N_EN_US][L10N_NOTIF_FOLLOW]; - case MSTDNT_NOTIFICATION_FOLLOW_REQUEST: return L10N[L10N_EN_US][L10N_NOTIF_FOLLOW_REQUEST]; - case MSTDNT_NOTIFICATION_REBLOG: return L10N[L10N_EN_US][L10N_NOTIF_REPEATED]; - case MSTDNT_NOTIFICATION_FAVOURITE: return L10N[L10N_EN_US][L10N_NOTIF_LIKED]; - case MSTDNT_NOTIFICATION_POLL: return L10N[L10N_EN_US][L10N_NOTIF_POLL]; - case MSTDNT_NOTIFICATION_EMOJI_REACT: return L10N[L10N_EN_US][L10N_NOTIF_REACTED_WITH]; - default: return ""; - } -} - -const char* notification_type_compact_str(mstdnt_notification_t type) -{ - switch (type) - { - case MSTDNT_NOTIFICATION_FOLLOW: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_FOLLOW]; - case MSTDNT_NOTIFICATION_FOLLOW_REQUEST: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_FOLLOW_REQUEST]; - case MSTDNT_NOTIFICATION_REBLOG: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_REPEATED]; - case MSTDNT_NOTIFICATION_FAVOURITE: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_LIKED]; - case MSTDNT_NOTIFICATION_POLL: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_POLL]; - case MSTDNT_NOTIFICATION_EMOJI_REACT: return L10N[L10N_EN_US][L10N_NOTIF_COMPACT_REACTED_WITH]; - default: return ""; - } -} - - -const char* notification_type_svg(mstdnt_notification_t type) -{ - switch (type) - { - case MSTDNT_NOTIFICATION_FOLLOW: return data_follow_svg; - case MSTDNT_NOTIFICATION_FOLLOW_REQUEST: return ""; - case MSTDNT_NOTIFICATION_REBLOG: return data_repeat_svg; - case MSTDNT_NOTIFICATION_FAVOURITE: return data_like_svg; - case MSTDNT_NOTIFICATION_POLL: return ""; - case MSTDNT_NOTIFICATION_EMOJI_REACT: return ""; - default: return ""; - } -} diff --git a/src/type_string.h b/src/type_string.h deleted file mode 100644 index a24f403..0000000 --- a/src/type_string.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Treebird - Lightweight frontend for Pleroma - * Copyright (C) 2022 Nekobit - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef TYPE_STRING_H -#define TYPE_STRING_H -#include -#include "l10n.h" - -const char* notification_type_svg(mstdnt_notification_t type); -const char* notification_type_str(mstdnt_notification_t type); -const char* notification_type_compact_str(mstdnt_notification_t type); - -#endif // TYPE_STRING_H