epicyon/webapp_column_right.py

764 lines
29 KiB
Python
Raw Normal View History

2020-11-09 22:44:03 +00:00
__filename__ = "webapp_column_right.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
2024-01-21 19:01:20 +00:00
__version__ = "1.5.0"
2020-11-09 22:44:03 +00:00
__maintainer__ = "Bob Mottram"
2021-09-10 16:14:50 +00:00
__email__ = "bob@libreserver.org"
2020-11-09 22:44:03 +00:00
__status__ = "Production"
2021-06-26 11:27:14 +00:00
__module_group__ = "Web Interface Columns"
2020-11-09 22:44:03 +00:00
import os
2021-12-29 21:55:09 +00:00
from content import remove_long_words
from content import limit_repeated_words
2024-02-05 20:05:00 +00:00
from utils import get_image_extensions
2021-12-26 16:01:32 +00:00
from utils import get_fav_filename_from_url
2021-12-26 11:29:40 +00:00
from utils import get_base_content_from_post
2021-12-27 15:43:22 +00:00
from utils import remove_html
2021-12-26 20:36:08 +00:00
from utils import locate_post
2021-12-26 15:13:34 +00:00
from utils import load_json
2021-12-27 22:32:59 +00:00
from utils import votes_on_newswire_item
2021-12-27 22:19:18 +00:00
from utils import get_nickname_from_actor
2021-12-26 13:27:57 +00:00
from utils import is_editor
2021-12-26 14:08:58 +00:00
from utils import get_config_param
2021-12-26 18:17:37 +00:00
from utils import remove_domain_port
2021-12-26 12:02:29 +00:00
from utils import acct_dir
2023-11-20 22:27:58 +00:00
from utils import date_from_string_format
2021-12-28 19:33:29 +00:00
from posts import is_moderator
2021-12-29 21:55:09 +00:00
from newswire import get_newswire_favicon_url
from webapp_utils import get_right_image_file
from webapp_utils import html_header_with_external_style
from webapp_utils import html_footer
from webapp_utils import get_banner_file
from webapp_utils import html_post_separator
from webapp_utils import header_buttons_front_screen
from webapp_utils import edit_text_field
from webapp_utils import text_mode_browser
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
def _votes_indicator(total_votes: int, positive_voting: bool) -> str:
2020-11-09 22:44:03 +00:00
"""Returns an indicator of the number of votes on a newswire item
"""
2022-01-03 22:37:22 +00:00
if total_votes <= 0:
2020-11-09 22:44:03 +00:00
return ''
2022-01-03 22:37:22 +00:00
total_votes_str = ' '
for _ in range(total_votes):
2021-12-25 20:14:45 +00:00
if positive_voting:
2022-01-03 22:37:22 +00:00
total_votes_str += ''
2020-11-09 22:44:03 +00:00
else:
2022-01-03 22:37:22 +00:00
total_votes_str += ''
return total_votes_str
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
def get_right_column_content(base_dir: str, nickname: str, domain_full: str,
2024-02-09 13:52:25 +00:00
translate: {}, moderator: bool, editor: bool,
2021-12-29 21:55:09 +00:00
newswire: {}, positive_voting: bool,
2022-01-03 22:37:22 +00:00
show_back_button: bool, timeline_path: str,
show_publish_button: bool,
2021-12-29 21:55:09 +00:00
show_publish_as_icon: bool,
rss_icon_at_top: bool,
publish_button_at_top: bool,
authorized: bool,
2022-01-03 22:37:22 +00:00
show_header_image: bool,
2021-12-29 21:55:09 +00:00
theme: str,
2021-12-31 23:50:29 +00:00
default_timeline: str,
2021-12-31 21:18:12 +00:00
access_keys: {}) -> str:
2020-11-09 22:44:03 +00:00
"""Returns html content for the right column
"""
2022-01-03 22:37:22 +00:00
html_str = ''
2020-11-09 22:44:03 +00:00
2021-12-26 18:17:37 +00:00
domain = remove_domain_port(domain_full)
2020-11-09 22:44:03 +00:00
if authorized:
# only show the publish button if logged in, otherwise replace it with
# a login button
2022-01-03 22:37:22 +00:00
title_str = translate['Publish a blog article']
2021-12-31 23:50:29 +00:00
if default_timeline == 'tlfeatures':
2022-01-03 22:37:22 +00:00
title_str = translate['Publish a news article']
publish_button_str = \
2020-11-09 22:44:03 +00:00
' <a href="' + \
'/users/' + nickname + '/newblog?nodropdown" ' + \
2022-01-03 22:37:22 +00:00
'title="' + title_str + '" ' + \
2022-05-25 19:33:09 +00:00
'accesskey="' + access_keys['menuNewBlog'] + '">' + \
2022-05-25 11:13:03 +00:00
'<button class="publishbtn" tabindex="4">' + \
2020-11-09 22:44:03 +00:00
translate['Publish'] + '</button></a>\n'
else:
# if not logged in then replace the publish button with
# a login button
2022-01-03 22:37:22 +00:00
publish_button_str = \
2022-05-25 11:13:03 +00:00
' <a href="/login">' + \
'<button class="publishbtn" tabindex="4">' + \
2020-11-09 22:44:03 +00:00
translate['Login'] + '</button></a>\n'
# show publish button at the top if needed
2021-12-25 19:00:00 +00:00
if publish_button_at_top:
2022-01-03 22:37:22 +00:00
html_str += '<center>' + publish_button_str + '</center>'
2020-11-09 22:44:03 +00:00
# show a column header image, eg. title of the theme or newswire banner
2022-01-03 22:37:22 +00:00
edit_image_class = ''
if show_header_image:
right_image_file, right_column_image_filename = \
2021-12-29 21:55:09 +00:00
get_right_image_file(base_dir, nickname, domain, theme)
2020-11-09 22:44:03 +00:00
# show the image at the top of the column
2022-01-03 22:37:22 +00:00
edit_image_class = 'rightColEdit'
if os.path.isfile(right_column_image_filename):
edit_image_class = 'rightColEditImage'
html_str += \
2020-11-09 22:44:03 +00:00
'\n <center>\n' + \
' <img class="rightColImg" ' + \
2022-03-28 08:47:53 +00:00
'alt="" loading="lazy" decoding="async" src="/users/' + \
2022-01-03 22:37:22 +00:00
nickname + '/' + right_image_file + '" />\n' + \
2020-11-09 22:44:03 +00:00
' </center>\n'
2022-01-03 22:37:22 +00:00
if show_publish_button or editor or rss_icon_at_top:
if not show_header_image:
html_str += '<div class="columnIcons">'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
if edit_image_class == 'rightColEdit':
html_str += '\n <center>\n'
2020-11-09 22:44:03 +00:00
# whether to show a back icon
# This is probably going to be osolete soon
2022-01-03 22:37:22 +00:00
if show_back_button:
html_str += \
' <a href="' + timeline_path + '">' + \
2020-11-09 22:44:03 +00:00
'<button class="cancelbtn">' + \
translate['Go Back'] + '</button></a>\n'
2022-01-03 22:37:22 +00:00
if show_publish_button and not publish_button_at_top:
2021-12-25 19:34:20 +00:00
if not show_publish_as_icon:
2022-01-03 22:37:22 +00:00
html_str += publish_button_str
2020-11-09 22:44:03 +00:00
# show the edit icon
if editor:
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/accounts/newswiremoderation.txt'):
2020-11-09 22:44:03 +00:00
# show the edit icon highlighted
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
' <a href="' + \
2021-04-23 19:06:34 +00:00
'/users/' + nickname + '/editnewswire" ' + \
2022-05-25 12:12:45 +00:00
'accesskey="' + access_keys['menuEdit'] + \
'" tabindex="4" class="imageAnchor">' + \
2022-01-03 22:37:22 +00:00
'<img class="' + edit_image_class + \
2022-03-28 08:47:53 +00:00
'" loading="lazy" decoding="async" alt="' + \
2021-02-01 19:28:07 +00:00
translate['Edit newswire'] + ' | " title="' + \
2020-11-09 22:44:03 +00:00
translate['Edit newswire'] + '" src="/' + \
2020-12-09 13:08:26 +00:00
'icons/edit_notify.png" /></a>\n'
2020-11-09 22:44:03 +00:00
else:
# show the edit icon
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
' <a href="' + \
2021-04-23 19:06:34 +00:00
'/users/' + nickname + '/editnewswire" ' + \
2022-05-25 12:12:45 +00:00
'accesskey="' + access_keys['menuEdit'] + \
'" tabindex="4" class="imageAnchor">' + \
2022-01-03 22:37:22 +00:00
'<img class="' + edit_image_class + \
2022-03-28 08:47:53 +00:00
'" loading="lazy" decoding="async" alt="' + \
2021-02-01 19:32:33 +00:00
translate['Edit newswire'] + ' | " title="' + \
2020-11-09 22:44:03 +00:00
translate['Edit newswire'] + '" src="/' + \
2020-12-09 13:08:26 +00:00
'icons/edit.png" /></a>\n'
2020-11-09 22:44:03 +00:00
2020-12-02 18:40:51 +00:00
# show the RSS icons
2022-01-03 22:37:22 +00:00
rss_icon_str = \
2022-05-25 12:12:45 +00:00
' <a href="/categories.xml" tabindex="4" ' + \
'class="imageAnchor">' + \
2022-01-03 22:37:22 +00:00
'<img class="' + edit_image_class + \
2022-03-28 08:47:53 +00:00
'" loading="lazy" decoding="async" alt="' + \
2021-02-01 19:28:07 +00:00
translate['Hashtag Categories RSS Feed'] + ' | " title="' + \
2020-12-02 18:40:51 +00:00
translate['Hashtag Categories RSS Feed'] + '" src="/' + \
2020-12-09 13:08:26 +00:00
'icons/categoriesrss.png" /></a>\n'
2022-01-03 22:37:22 +00:00
rss_icon_str += \
2022-05-25 12:12:45 +00:00
' <a href="/newswire.xml" tabindex="4" class="imageAnchor">' + \
2022-01-03 22:37:22 +00:00
'<img class="' + edit_image_class + \
2022-03-28 08:47:53 +00:00
'" loading="lazy" decoding="async" alt="' + \
2021-02-01 19:28:07 +00:00
translate['Newswire RSS Feed'] + ' | " title="' + \
2020-11-09 22:44:03 +00:00
translate['Newswire RSS Feed'] + '" src="/' + \
2020-12-09 13:08:26 +00:00
'icons/logorss.png" /></a>\n'
2021-12-25 19:09:03 +00:00
if rss_icon_at_top:
2022-01-03 22:37:22 +00:00
html_str += rss_icon_str
2020-11-09 22:44:03 +00:00
# show publish icon at top
2022-01-03 22:37:22 +00:00
if show_publish_button:
2021-12-25 19:34:20 +00:00
if show_publish_as_icon:
2022-01-03 22:37:22 +00:00
title_str = translate['Publish a blog article']
2021-12-31 23:50:29 +00:00
if default_timeline == 'tlfeatures':
2022-01-03 22:37:22 +00:00
title_str = translate['Publish a news article']
html_str += \
2020-11-09 22:44:03 +00:00
' <a href="' + \
2021-04-23 19:13:10 +00:00
'/users/' + nickname + '/newblog?nodropdown" ' + \
2022-05-25 19:33:09 +00:00
'accesskey="' + access_keys['menuNewBlog'] + \
2022-05-25 12:26:06 +00:00
'" class="imageAnchor" tabindex="4">' + \
2022-01-03 22:37:22 +00:00
'<img class="' + edit_image_class + \
2022-03-28 08:47:53 +00:00
'" loading="lazy" decoding="async" alt="' + \
2022-01-03 22:37:22 +00:00
title_str + '" title="' + \
title_str + '" src="/' + \
2020-12-09 13:08:26 +00:00
'icons/publish.png" /></a>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
if edit_image_class == 'rightColEdit':
html_str += ' </center>\n'
2020-11-09 22:44:03 +00:00
else:
2022-01-03 22:37:22 +00:00
if show_header_image:
html_str += ' <br>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
if show_publish_button or editor or rss_icon_at_top:
if not show_header_image:
html_str += '</div><br>'
2020-11-09 22:44:03 +00:00
# show the newswire lines
2022-01-03 22:37:22 +00:00
newswire_content_str = \
2021-12-29 21:55:09 +00:00
_html_newswire(base_dir, newswire, nickname, moderator, translate,
positive_voting)
2022-01-03 22:37:22 +00:00
html_str += newswire_content_str
2020-11-09 22:44:03 +00:00
# show the rss icon at the bottom, typically on the right hand side
2022-01-03 22:37:22 +00:00
if newswire_content_str and not rss_icon_at_top:
html_str += '<br><div class="columnIcons">' + rss_icon_str + '</div>'
return html_str
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
def _get_broken_fav_substitute() -> str:
2020-12-26 11:06:57 +00:00
"""Substitute link used if a favicon is not available
"""
2021-01-07 12:12:09 +00:00
return " onerror=\"this.onerror=null; this.src='/newswire_favicon.ico'\""
2020-12-26 11:06:57 +00:00
2021-12-29 21:55:09 +00:00
def _html_newswire(base_dir: str, newswire: {}, nickname: str, moderator: bool,
translate: {}, positive_voting: bool) -> str:
2020-11-09 22:44:03 +00:00
"""Converts a newswire dict into html
"""
2022-01-03 22:37:22 +00:00
separator_str = html_post_separator(base_dir, 'right')
html_str = ''
for date_str, item in newswire.items():
2021-12-27 15:43:22 +00:00
item[0] = remove_html(item[0]).strip()
2020-11-18 22:31:38 +00:00
if not item[0]:
2020-11-18 22:15:32 +00:00
continue
2020-11-18 22:31:38 +00:00
# remove any CDATA
if 'CDATA[' in item[0]:
item[0] = item[0].split('CDATA[')[1]
if ']' in item[0]:
item[0] = item[0].split(']')[0]
2023-11-20 22:27:58 +00:00
published_date = \
date_from_string_format(date_str, ["%Y-%m-%d %H:%M:%S%z"])
if not published_date:
2022-01-03 22:37:22 +00:00
print('EX: _html_newswire bad date format ' + date_str)
2020-11-22 15:41:42 +00:00
continue
2022-01-03 22:37:22 +00:00
date_shown = published_date.strftime("%Y-%m-%d %H:%M")
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
date_str_link = date_str.replace('T', ' ')
date_str_link = date_str_link.replace('Z', '')
2020-12-26 11:06:57 +00:00
url = item[1]
2022-01-03 22:37:22 +00:00
favicon_url = get_newswire_favicon_url(url)
favicon_link = ''
if favicon_url:
cached_favicon_filename = \
get_fav_filename_from_url(base_dir, favicon_url)
if os.path.isfile(cached_favicon_filename):
favicon_url = \
cached_favicon_filename.replace(base_dir, '')
2021-12-17 10:36:22 +00:00
else:
2024-02-05 20:05:00 +00:00
extensions = get_image_extensions()
2021-12-17 12:01:54 +00:00
for ext in extensions:
2022-01-03 22:37:22 +00:00
cached_favicon_filename = \
get_fav_filename_from_url(base_dir, favicon_url)
cached_favicon_filename = \
cached_favicon_filename.replace('.ico', '.' + ext)
if os.path.isfile(cached_favicon_filename):
favicon_url = \
cached_favicon_filename.replace(base_dir, '')
favicon_link = \
2022-03-28 08:47:53 +00:00
'<img loading="lazy" decoding="async" ' + \
'src="' + favicon_url + '" ' + \
2021-12-29 21:55:09 +00:00
'alt="" ' + _get_broken_fav_substitute() + '/>'
2022-01-03 22:37:22 +00:00
moderated_item = item[5]
link_url = url
# is this a podcast episode?
if len(item) > 8:
# change the link url to a podcast episode screen
podcast_properties = item[8]
2022-01-11 18:41:16 +00:00
if podcast_properties:
2022-01-12 18:35:15 +00:00
if podcast_properties.get('image'):
2022-01-12 13:11:40 +00:00
episode_id = date_str.replace(' ', '__')
2022-01-12 17:44:49 +00:00
episode_id = episode_id.replace(':', 'aa')
2022-01-11 18:41:16 +00:00
link_url = \
2022-01-12 13:11:40 +00:00
'/users/' + nickname + '/?podepisode=' + episode_id
2022-01-03 22:37:22 +00:00
html_str += separator_str
if moderated_item and 'vote:' + nickname in item[2]:
total_votes_str = ''
total_votes = 0
2020-11-09 22:44:03 +00:00
if moderator:
2022-01-03 22:37:22 +00:00
total_votes = votes_on_newswire_item(item[2])
total_votes_str = \
_votes_indicator(total_votes, positive_voting)
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
title = remove_long_words(item[0], 16, []).replace('\n', '<br>')
title = limit_repeated_words(title, 6)
2022-01-03 22:37:22 +00:00
html_str += '<p class="newswireItemVotedOn">' + \
'<a href="' + link_url + '" target="_blank" ' + \
2020-12-11 10:14:58 +00:00
'rel="nofollow noopener noreferrer">' + \
2020-12-26 11:06:57 +00:00
'<span class="newswireItemVotedOn">' + \
2022-01-03 22:37:22 +00:00
favicon_link + title + '</span></a>' + total_votes_str
2020-11-09 22:44:03 +00:00
if moderator:
2022-01-03 22:37:22 +00:00
html_str += \
' ' + date_shown + '<a href="/users/' + nickname + \
'/newswireunvote=' + date_str_link + '" ' + \
2022-05-25 12:12:45 +00:00
'title="' + translate['Remove Vote'] + \
'" class="imageAnchor">'
2022-03-28 08:47:53 +00:00
html_str += '<img loading="lazy" decoding="async" ' + \
'class="voteicon" src="/' + \
2021-02-01 18:58:24 +00:00
'alt="' + translate['Remove Vote'] + '" ' + \
2020-12-09 13:08:26 +00:00
'icons/vote.png" /></a></p>\n'
2020-11-09 22:44:03 +00:00
else:
2022-01-03 22:37:22 +00:00
html_str += ' <span class="newswireDateVotedOn">'
html_str += date_shown + '</span></p>\n'
2020-11-09 22:44:03 +00:00
else:
2022-01-03 22:37:22 +00:00
total_votes_str = ''
total_votes = 0
2020-11-09 22:44:03 +00:00
if moderator:
2022-01-03 22:37:22 +00:00
if moderated_item:
total_votes = votes_on_newswire_item(item[2])
2020-11-09 22:44:03 +00:00
# show a number of ticks or crosses for how many
# votes for or against
2022-01-03 22:37:22 +00:00
total_votes_str = \
_votes_indicator(total_votes, positive_voting)
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
title = remove_long_words(item[0], 16, []).replace('\n', '<br>')
title = limit_repeated_words(title, 6)
2022-01-03 22:37:22 +00:00
if moderator and moderated_item:
html_str += '<p class="newswireItemModerated">' + \
'<a href="' + link_url + '" target="_blank" ' + \
2020-12-11 10:14:58 +00:00
'rel="nofollow noopener noreferrer">' + \
2022-01-03 22:37:22 +00:00
favicon_link + title + '</a>' + total_votes_str
html_str += ' ' + date_shown
html_str += '<a href="/users/' + nickname + \
'/newswirevote=' + date_str_link + '" ' + \
2022-05-25 12:12:45 +00:00
'title="' + translate['Vote'] + '" class="imageAnchor">'
2022-01-03 22:37:22 +00:00
html_str += '<img class="voteicon" ' + \
2021-02-01 18:58:24 +00:00
'alt="' + translate['Vote'] + '" ' + \
'src="/icons/vote.png" /></a>'
2022-01-03 22:37:22 +00:00
html_str += '</p>\n'
2020-11-09 22:44:03 +00:00
else:
2022-01-03 22:37:22 +00:00
html_str += '<p class="newswireItem">' + \
'<a href="' + link_url + '" target="_blank" ' + \
2020-12-11 10:14:58 +00:00
'rel="nofollow noopener noreferrer">' + \
2022-01-03 22:37:22 +00:00
favicon_link + title + '</a>' + total_votes_str
html_str += ' <span class="newswireDate">'
html_str += date_shown + '</span></p>\n'
2020-12-27 15:22:14 +00:00
2022-01-03 22:37:22 +00:00
if html_str:
html_str = \
'<nav itemscope itemtype="http://schema.org/webFeed">\n' + \
html_str + '</nav>\n'
2022-01-03 22:37:22 +00:00
return html_str
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
def html_citations(base_dir: str, nickname: str, domain: str,
2022-07-12 19:03:30 +00:00
translate: {}, newswire: {},
2022-01-03 22:37:22 +00:00
blog_title: str, blog_content: str,
2021-12-29 21:55:09 +00:00
theme: str) -> str:
2020-11-09 22:44:03 +00:00
"""Show the citations screen when creating a blog
"""
2022-01-03 22:37:22 +00:00
html_str = ''
2020-11-09 22:44:03 +00:00
# create a list of dates for citations
# these can then be used to re-select checkboxes later
2022-01-03 22:37:22 +00:00
citations_filename = \
2021-12-26 12:02:29 +00:00
acct_dir(base_dir, nickname, domain) + '/.citations.txt'
2022-01-03 22:37:22 +00:00
citations_selected = []
if os.path.isfile(citations_filename):
citations_separator = '#####'
2022-06-09 14:46:30 +00:00
with open(citations_filename, 'r', encoding='utf-8') as fp_cit:
2022-01-03 22:37:22 +00:00
citations = fp_cit.readlines()
2020-11-09 22:44:03 +00:00
for line in citations:
2022-01-03 22:37:22 +00:00
if citations_separator not in line:
2020-11-09 22:44:03 +00:00
continue
2022-01-03 22:37:22 +00:00
sections = line.strip().split(citations_separator)
2020-11-09 22:44:03 +00:00
if len(sections) != 3:
continue
2022-01-03 22:37:22 +00:00
date_str = sections[0]
citations_selected.append(date_str)
2020-11-09 22:44:03 +00:00
# the css filename
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon-profile.css'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/epicyon.css'):
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon.css'
2020-11-09 22:44:03 +00:00
2021-12-31 21:18:12 +00:00
instance_title = \
2021-12-26 14:08:58 +00:00
get_config_param(base_dir, 'instanceTitle')
2022-01-03 22:37:22 +00:00
html_str = \
2021-12-31 21:18:12 +00:00
html_header_with_external_style(css_filename, instance_title, None)
2020-11-09 22:44:03 +00:00
# top banner
2022-01-03 22:37:22 +00:00
banner_file, _ = \
2021-12-29 21:55:09 +00:00
get_banner_file(base_dir, nickname, domain, theme)
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
'<a href="/users/' + nickname + '/newblog" title="' + \
translate['Go Back'] + '" alt="' + \
2022-05-25 12:12:45 +00:00
translate['Go Back'] + '" class="imageAnchor">\n'
2022-03-28 08:47:53 +00:00
html_str += '<img loading="lazy" decoding="async" ' + \
'class="timeline-banner" alt="" src="' + \
2021-12-31 21:18:12 +00:00
'/users/' + nickname + '/' + banner_file + '" /></a>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
'<form enctype="multipart/form-data" method="POST" ' + \
'accept-charset="UTF-8" action="/users/' + nickname + \
'/citationsdata">\n'
2022-01-03 22:37:22 +00:00
html_str += ' <center>\n'
html_str += translate['Choose newswire items ' +
'referenced in your article'] + '<br>'
if blog_title is None:
blog_title = ''
html_str += \
2020-11-09 22:44:03 +00:00
' <input type="hidden" name="blogTitle" value="' + \
2022-01-03 22:37:22 +00:00
blog_title + '">\n'
if blog_content is None:
blog_content = ''
html_str += \
2020-11-09 22:44:03 +00:00
' <input type="hidden" name="blogContent" value="' + \
2022-01-03 22:37:22 +00:00
blog_content + '">\n'
2020-11-09 22:44:03 +00:00
# submit button
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
' <input type="submit" name="submitCitations" value="' + \
2022-05-23 18:48:45 +00:00
translate['Publish'] + '">\n'
2022-01-03 22:37:22 +00:00
html_str += ' </center>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
citations_separator = '#####'
2020-11-09 22:44:03 +00:00
# list of newswire items
if newswire:
ctr = 0
2022-01-03 22:37:22 +00:00
for date_str, item in newswire.items():
2021-12-27 15:43:22 +00:00
item[0] = remove_html(item[0]).strip()
2020-11-18 22:31:38 +00:00
if not item[0]:
2020-11-18 22:15:32 +00:00
continue
2020-11-18 22:31:38 +00:00
# remove any CDATA
if 'CDATA[' in item[0]:
item[0] = item[0].split('CDATA[')[1]
if ']' in item[0]:
item[0] = item[0].split(']')[0]
2020-11-09 22:44:03 +00:00
# should this checkbox be selected?
2022-01-03 22:37:22 +00:00
selected_str = ''
if date_str in citations_selected:
selected_str = ' checked'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
published_date = \
2023-11-20 22:27:58 +00:00
date_from_string_format(date_str, ["%Y-%m-%d %H:%M:%S%z"])
2022-01-03 22:37:22 +00:00
date_shown = published_date.strftime("%Y-%m-%d %H:%M")
2020-11-09 22:44:03 +00:00
2021-12-29 21:55:09 +00:00
title = remove_long_words(item[0], 16, []).replace('\n', '<br>')
title = limit_repeated_words(title, 6)
2020-11-09 22:44:03 +00:00
link = item[1]
2022-01-03 22:37:22 +00:00
citation_value = \
date_str + citations_separator + \
title + citations_separator + \
2020-11-09 22:44:03 +00:00
link
2022-01-03 22:37:22 +00:00
html_str += \
2020-11-09 22:44:03 +00:00
'<input type="checkbox" name="newswire' + str(ctr) + \
2022-01-03 22:37:22 +00:00
'" value="' + citation_value + '"' + selected_str + '/>' + \
2020-11-09 22:44:03 +00:00
'<a href="' + link + '"><cite>' + title + '</cite></a> '
2022-01-03 22:37:22 +00:00
html_str += '<span class="newswireDate">' + \
date_shown + '</span><br>\n'
2020-11-09 22:44:03 +00:00
ctr += 1
2022-01-03 22:37:22 +00:00
html_str += '</form>\n'
return html_str + html_footer()
2021-12-29 21:55:09 +00:00
2022-07-12 19:03:30 +00:00
def html_newswire_mobile(base_dir: str, nickname: str,
2021-12-29 21:55:09 +00:00
domain: str, domain_full: str,
2024-02-09 14:49:47 +00:00
translate: {}, newswire: {},
2021-12-29 21:55:09 +00:00
positive_voting: bool,
2022-01-03 22:37:22 +00:00
timeline_path: str,
2021-12-29 21:55:09 +00:00
show_publish_as_icon: bool,
authorized: bool,
rss_icon_at_top: bool,
icons_as_buttons: bool,
2021-12-31 23:50:29 +00:00
default_timeline: str,
2021-12-29 21:55:09 +00:00
theme: str,
access_keys: {},
ua_str: str) -> str:
2020-11-09 22:44:03 +00:00
"""Shows the mobile version of the newswire right column
"""
2022-01-03 22:37:22 +00:00
html_str = ''
2020-11-09 22:44:03 +00:00
# the css filename
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon-profile.css'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/epicyon.css'):
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon.css'
2020-11-09 22:44:03 +00:00
if nickname == 'news':
editor = False
moderator = False
else:
# is the user a moderator?
2021-12-28 19:33:29 +00:00
moderator = is_moderator(base_dir, nickname)
2020-11-09 22:44:03 +00:00
# is the user a site editor?
2021-12-26 13:27:57 +00:00
editor = is_editor(base_dir, nickname)
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
show_publish_button = editor
2020-11-09 22:44:03 +00:00
2021-12-31 21:18:12 +00:00
instance_title = \
2021-12-26 14:08:58 +00:00
get_config_param(base_dir, 'instanceTitle')
metadata = None
if text_mode_browser(ua_str):
metadata = '<meta http-equiv="refresh" content="1800" >\n'
2022-01-03 22:37:22 +00:00
html_str = \
html_header_with_external_style(css_filename, instance_title, metadata)
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
banner_file, _ = \
2021-12-29 21:55:09 +00:00
get_banner_file(base_dir, nickname, domain, theme)
2022-01-03 22:37:22 +00:00
html_str += \
2021-12-31 23:50:29 +00:00
'<a href="/users/' + nickname + '/' + default_timeline + '" ' + \
2022-05-25 12:12:45 +00:00
'accesskey="' + access_keys['menuTimeline'] + '" ' + \
'class="imageAnchor">' + \
2022-03-28 08:47:53 +00:00
'<img loading="lazy" decoding="async" class="timeline-banner" ' + \
2021-02-01 18:58:24 +00:00
'alt="' + translate['Timeline banner image'] + '" ' + \
2021-12-31 21:18:12 +00:00
'src="/users/' + nickname + '/' + banner_file + '" /></a>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
html_str += '<div class="col-right-mobile">\n'
2022-01-03 22:37:22 +00:00
html_str += '<center>' + \
2021-12-29 21:55:09 +00:00
header_buttons_front_screen(translate, nickname,
'newswire', authorized,
icons_as_buttons) + '</center>'
2022-01-03 22:37:22 +00:00
html_str += \
2021-12-29 21:55:09 +00:00
get_right_column_content(base_dir, nickname, domain_full,
2024-02-09 13:52:25 +00:00
translate,
2021-12-29 21:55:09 +00:00
moderator, editor,
newswire, positive_voting,
2022-01-03 22:37:22 +00:00
False, timeline_path, show_publish_button,
2021-12-29 21:55:09 +00:00
show_publish_as_icon, rss_icon_at_top, False,
authorized, False, theme,
2021-12-31 23:50:29 +00:00
default_timeline, access_keys)
if editor and not newswire:
2022-01-03 22:37:22 +00:00
html_str += '<br><br><br>\n'
html_str += '<center>\n '
html_str += translate['Select the edit icon to add RSS feeds']
html_str += '\n</center>\n'
# end of col-right-mobile
2022-01-03 22:37:22 +00:00
html_str += '</div\n>'
2022-01-03 22:37:22 +00:00
html_str += html_footer()
return html_str
2020-11-09 22:44:03 +00:00
2022-07-12 19:03:30 +00:00
def html_edit_newswire(translate: {}, base_dir: str, path: str,
2024-02-09 14:49:47 +00:00
domain: str, default_timeline: str, theme: str,
2022-07-05 17:52:19 +00:00
access_keys: {}, dogwhistles: {}) -> str:
2020-11-09 22:44:03 +00:00
"""Shows the edit newswire screen
"""
if '/users/' not in path:
return ''
path = path.replace('/inbox', '').replace('/outbox', '')
2021-08-09 19:37:18 +00:00
path = path.replace('/shares', '').replace('/wanted', '')
2020-11-09 22:44:03 +00:00
2021-12-27 22:19:18 +00:00
nickname = get_nickname_from_actor(path)
2020-11-09 22:44:03 +00:00
if not nickname:
return ''
# is the user a moderator?
2021-12-28 19:33:29 +00:00
if not is_moderator(base_dir, nickname):
2020-11-09 22:44:03 +00:00
return ''
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon-links.css'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/links.css'):
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/links.css'
2020-11-09 22:44:03 +00:00
# filename of the banner shown at the top
2022-01-03 22:37:22 +00:00
banner_file, _ = \
2021-12-29 21:55:09 +00:00
get_banner_file(base_dir, nickname, domain, theme)
2020-11-09 22:44:03 +00:00
2021-12-31 21:18:12 +00:00
instance_title = \
2021-12-26 14:08:58 +00:00
get_config_param(base_dir, 'instanceTitle')
2022-01-03 22:37:22 +00:00
edit_newswire_form = \
2021-12-31 21:18:12 +00:00
html_header_with_external_style(css_filename, instance_title, None)
2020-11-09 22:44:03 +00:00
# top banner
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-12-27 16:57:15 +00:00
'<header>' + \
2021-12-31 23:50:29 +00:00
'<a href="/users/' + nickname + '/' + default_timeline + \
'" title="' + \
2020-11-09 22:44:03 +00:00
translate['Switch to timeline view'] + '" alt="' + \
2021-04-23 19:23:29 +00:00
translate['Switch to timeline view'] + '" ' + \
2021-12-31 21:18:12 +00:00
'accesskey="' + access_keys['menuTimeline'] + '">\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2022-03-28 08:47:53 +00:00
'<img loading="lazy" decoding="async" ' + \
'class="timeline-banner" src="' + \
2021-12-31 21:18:12 +00:00
'/users/' + nickname + '/' + banner_file + '" ' + \
2021-02-01 18:58:24 +00:00
'alt="" /></a>\n</header>'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
'<form enctype="multipart/form-data" method="POST" ' + \
'accept-charset="UTF-8" action="' + path + '/newswiredata">\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <div class="vertical-center">\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-21 09:44:33 +00:00
' <h1>' + translate['Edit newswire'] + '</h1>'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-12-21 16:20:17 +00:00
' <div class="containerSubmitNewPost">\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <input type="submit" name="submitNewswire" value="' + \
2022-05-23 18:48:45 +00:00
translate['Publish'] + '" ' + \
2021-12-31 21:18:12 +00:00
'accesskey="' + access_keys['submitButton'] + '">\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' </div>\n'
2022-01-03 22:37:22 +00:00
newswire_filename = base_dir + '/accounts/newswire.txt'
newswire_str = ''
if os.path.isfile(newswire_filename):
2022-06-09 14:46:30 +00:00
with open(newswire_filename, 'r', encoding='utf-8') as fp_news:
2022-01-03 22:37:22 +00:00
newswire_str = fp_news.read()
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
'<div class="container">'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' ' + \
translate['Add RSS feed links below.'] + \
'<br>'
2022-01-03 22:37:22 +00:00
new_feed_str = translate['New feed URL']
edit_newswire_form += \
edit_text_field(None, 'newNewswireFeed', '', new_feed_str)
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <textarea id="message" name="editedNewswire" ' + \
2021-02-28 14:26:04 +00:00
'style="height:80vh" spellcheck="false">' + \
2022-01-03 22:37:22 +00:00
newswire_str + '</textarea>'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
filter_str = ''
filter_filename = \
2021-12-25 16:17:53 +00:00
base_dir + '/accounts/news@' + domain + '/filters.txt'
2022-01-03 22:37:22 +00:00
if os.path.isfile(filter_filename):
2022-06-09 14:46:30 +00:00
with open(filter_filename, 'r', encoding='utf-8') as filterfile:
2022-01-03 22:37:22 +00:00
filter_str = filterfile.read()
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <br><b><label class="labels">' + \
translate['Filtered words'] + '</label></b>\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += ' <br><label class="labels">' + \
2020-11-09 22:44:03 +00:00
translate['One per line'] + '</label>'
2022-01-03 22:37:22 +00:00
edit_newswire_form += ' <textarea id="message" ' + \
2021-02-28 14:26:04 +00:00
'name="filteredWordsNewswire" style="height:50vh" ' + \
2022-01-03 22:37:22 +00:00
'spellcheck="true">' + filter_str + '</textarea>\n'
2020-11-09 22:44:03 +00:00
2022-07-05 17:52:19 +00:00
dogwhistle_str = ''
for whistle, category in dogwhistles.items():
if not category:
continue
dogwhistle_str += whistle + ' -> ' + category + '\n'
edit_newswire_form += \
' <br><b><label class="labels">' + \
translate['Dogwhistle words'] + '</label></b>\n'
edit_newswire_form += ' <br><label class="labels">' + \
translate['Content warnings will be added for the following'] + \
':</label>'
edit_newswire_form += ' <textarea id="message" ' + \
'name="dogwhistleWords" style="height:50vh" ' + \
'spellcheck="true">' + dogwhistle_str + '</textarea>\n'
2022-01-03 22:37:22 +00:00
hashtag_rules_str = ''
hashtag_rules_filename = \
2021-12-25 16:17:53 +00:00
base_dir + '/accounts/hashtagrules.txt'
2022-01-03 22:37:22 +00:00
if os.path.isfile(hashtag_rules_filename):
2022-06-09 14:46:30 +00:00
with open(hashtag_rules_filename, 'r', encoding='utf-8') as rulesfile:
2022-01-03 22:37:22 +00:00
hashtag_rules_str = rulesfile.read()
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <br><b><label class="labels">' + \
translate['News tagging rules'] + '</label></b>\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += ' <br><label class="labels">' + \
2020-11-09 22:44:03 +00:00
translate['One per line'] + '.</label>\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
' <a href="' + \
'https://gitlab.com/bashrc2/epicyon/-/raw/main/hashtagrules.txt' + \
'">' + translate['See instructions'] + '</a>\n'
2022-01-03 22:37:22 +00:00
edit_newswire_form += ' <textarea id="message" ' + \
2021-02-28 14:26:04 +00:00
'name="hashtagRulesList" style="height:80vh" spellcheck="false">' + \
2022-01-03 22:37:22 +00:00
hashtag_rules_str + '</textarea>\n'
2020-11-09 22:44:03 +00:00
2022-01-03 22:37:22 +00:00
edit_newswire_form += \
2020-11-09 22:44:03 +00:00
'</div>'
2022-01-03 22:37:22 +00:00
edit_newswire_form += html_footer()
return edit_newswire_form
2022-07-12 19:03:30 +00:00
def html_edit_news_post(translate: {}, base_dir: str, path: str,
2024-02-09 14:49:47 +00:00
domain: str, post_url: str,
2021-12-29 21:55:09 +00:00
system_language: str) -> str:
"""Edits a news post on the news/features timeline
"""
if '/users/' not in path:
return ''
2022-01-03 22:37:22 +00:00
path_original = path
2021-12-27 22:19:18 +00:00
nickname = get_nickname_from_actor(path)
if not nickname:
return ''
# is the user an editor?
2021-12-26 13:27:57 +00:00
if not is_editor(base_dir, nickname):
return ''
2024-02-09 14:49:47 +00:00
post_url = post_url.replace('/', '#')
post_filename = locate_post(base_dir, nickname, domain, post_url)
2021-12-26 23:41:34 +00:00
if not post_filename:
return ''
2021-12-26 23:41:34 +00:00
post_json_object = load_json(post_filename)
2021-12-25 22:09:19 +00:00
if not post_json_object:
return ''
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/epicyon-links.css'
2021-12-25 16:17:53 +00:00
if os.path.isfile(base_dir + '/links.css'):
2021-12-31 21:18:12 +00:00
css_filename = base_dir + '/links.css'
2021-12-31 21:18:12 +00:00
instance_title = \
2021-12-26 14:08:58 +00:00
get_config_param(base_dir, 'instanceTitle')
2022-01-03 22:37:22 +00:00
edit_news_post_form = \
2021-12-31 21:18:12 +00:00
html_header_with_external_style(css_filename, instance_title, None)
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
'<form enctype="multipart/form-data" method="POST" ' + \
'accept-charset="UTF-8" action="' + path + '/newseditdata">\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' <div class="vertical-center">\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
2020-11-21 09:56:45 +00:00
' <h1>' + translate['Edit News Post'] + '</h1>'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' <div class="container">\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' <a href="' + path_original + '/tlnews">' + \
'<button class="cancelbtn">' + translate['Go Back'] + '</button></a>\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' <input type="submit" name="submitEditedNewsPost" value="' + \
2022-05-23 18:48:45 +00:00
translate['Publish'] + '">\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' </div>\n'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
'<div class="container">'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
' <input type="hidden" name="newsPostUrl" value="' + \
2024-02-09 14:49:47 +00:00
post_url + '">\n'
2022-01-03 22:37:22 +00:00
news_post_title = post_json_object['object']['summary']
edit_news_post_form += \
' <input type="text" name="newsPostTitle" value="' + \
2022-01-03 22:37:22 +00:00
news_post_title + '"><br>\n'
2022-01-03 22:37:22 +00:00
news_post_content = get_base_content_from_post(post_json_object,
system_language)
edit_news_post_form += \
' <textarea id="message" name="editedNewsPost" ' + \
2021-02-28 14:26:04 +00:00
'style="height:600px" spellcheck="true">' + \
2022-01-03 22:37:22 +00:00
news_post_content + '</textarea>'
2022-01-03 22:37:22 +00:00
edit_news_post_form += \
'</div>'
2022-01-03 22:37:22 +00:00
edit_news_post_form += html_footer()
return edit_news_post_form