mirror of https://gitlab.com/bashrc2/epicyon
Move time functions to a separate module
parent
6e324b2cc7
commit
5871155fe3
|
@ -14,7 +14,7 @@ import time
|
|||
from posts import send_signed_json
|
||||
from flags import has_group_type
|
||||
from flags import url_permitted
|
||||
from utils import get_status_number
|
||||
from status import get_status_number
|
||||
from utils import get_attributed_to
|
||||
from utils import get_user_paths
|
||||
from utils import text_in_file
|
||||
|
|
|
@ -12,6 +12,7 @@ __module_group__ = "ActivityPub"
|
|||
import os
|
||||
from flags import has_group_type
|
||||
from flags import url_permitted
|
||||
from status import get_status_number
|
||||
from utils import text_in_file
|
||||
from utils import get_user_paths
|
||||
from utils import has_object_string_object
|
||||
|
@ -20,7 +21,6 @@ from utils import remove_domain_port
|
|||
from utils import remove_id_ending
|
||||
from utils import has_users_path
|
||||
from utils import get_full_domain
|
||||
from utils import get_status_number
|
||||
from utils import create_outbox_dir
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import get_domain_from_actor
|
||||
|
|
2
auth.py
2
auth.py
|
@ -18,7 +18,7 @@ from utils import data_dir
|
|||
from utils import has_users_path
|
||||
from utils import text_in_file
|
||||
from utils import remove_eol
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_utcnow
|
||||
|
||||
|
||||
def _hash_password(password: str) -> str:
|
||||
|
|
|
@ -16,12 +16,12 @@ from session import create_session
|
|||
from flags import is_evil
|
||||
from flags import is_quote_toot
|
||||
from quote import get_quote_toot_url
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from utils import get_user_paths
|
||||
from utils import contains_statuses
|
||||
from utils import data_dir
|
||||
from utils import string_contains
|
||||
from utils import date_from_string_format
|
||||
from utils import date_utcnow
|
||||
from utils import remove_eol
|
||||
from utils import has_object_string
|
||||
from utils import has_object_string_object
|
||||
|
|
2
blog.py
2
blog.py
|
@ -16,11 +16,11 @@ from webapp_utils import html_footer
|
|||
from webapp_utils import get_post_attachments_as_html
|
||||
from webapp_utils import edit_text_area
|
||||
from webapp_media import add_embedded_elements
|
||||
from timeFunctions import date_from_string_format
|
||||
from utils import replace_strings
|
||||
from utils import data_dir
|
||||
from utils import remove_link_tracking
|
||||
from utils import get_url_from_post
|
||||
from utils import date_from_string_format
|
||||
from utils import get_attributed_to
|
||||
from utils import remove_eol
|
||||
from utils import text_in_file
|
||||
|
|
4
cache.py
4
cache.py
|
@ -26,9 +26,9 @@ from utils import load_json
|
|||
from utils import save_json
|
||||
from utils import get_file_case_insensitive
|
||||
from utils import get_user_paths
|
||||
from utils import date_utcnow
|
||||
from utils import date_from_string_format
|
||||
from utils import get_image_extensions
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from content import remove_script
|
||||
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ __module_group__ = "RSS Feeds"
|
|||
|
||||
import os
|
||||
import datetime
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_epoch
|
||||
from utils import data_dir
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import replace_strings
|
||||
|
||||
MAX_TAG_LENGTH = 42
|
||||
|
|
|
@ -15,6 +15,7 @@ import email.parser
|
|||
import urllib.parse
|
||||
from shutil import copyfile
|
||||
from dateutil.parser import parse
|
||||
from timeFunctions import convert_published_to_local_timezone
|
||||
from flags import is_pgp_encrypted
|
||||
from flags import contains_pgp_public_key
|
||||
from flags import is_float
|
||||
|
@ -31,7 +32,6 @@ from utils import binary_is_image
|
|||
from utils import get_content_from_post
|
||||
from utils import get_full_domain
|
||||
from utils import get_user_paths
|
||||
from utils import convert_published_to_local_timezone
|
||||
from utils import has_object_dict
|
||||
from utils import valid_hash_tag
|
||||
from utils import dangerous_svg
|
||||
|
|
|
@ -50,13 +50,13 @@ from categories import load_city_hashtags
|
|||
from categories import update_hashtag_categories
|
||||
from languages import load_default_post_languages
|
||||
from searchable import load_searchable_by_default
|
||||
from timeFunctions import load_account_timezones
|
||||
from utils import set_accounts_data_dir
|
||||
from utils import data_dir
|
||||
from utils import check_bad_path
|
||||
from utils import acct_handle_dir
|
||||
from utils import load_reverse_timeline
|
||||
from utils import load_min_images_for_accounts
|
||||
from utils import load_account_timezones
|
||||
from utils import load_translations_from_file
|
||||
from utils import load_bold_reading
|
||||
from utils import load_hide_follows
|
||||
|
|
|
@ -93,7 +93,7 @@ from flags import is_corporate
|
|||
from flags import is_image_file
|
||||
from flags import is_artist
|
||||
from flags import is_blog_post
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_utcnow
|
||||
from utils import replace_strings
|
||||
from utils import contains_invalid_chars
|
||||
from utils import save_json
|
||||
|
|
|
@ -13,11 +13,11 @@ from webapp_conversation import html_conversation_view
|
|||
from flags import is_public_post_from_url
|
||||
from flags import is_public_post
|
||||
from flags import is_premium_account
|
||||
from flags import can_reply_to
|
||||
from utils import get_instance_url
|
||||
from utils import local_actor_url
|
||||
from utils import locate_post
|
||||
from utils import get_config_param
|
||||
from utils import can_reply_to
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import get_new_post_endpoints
|
||||
from utils import acct_dir
|
||||
|
|
|
@ -15,7 +15,7 @@ from utils import get_nickname_from_actor
|
|||
from utils import get_domain_from_actor
|
||||
from utils import get_full_domain
|
||||
from utils import local_actor_url
|
||||
from utils import get_status_number
|
||||
from status import get_status_number
|
||||
from follow import unfollow_account
|
||||
from follow import send_follow_request
|
||||
from follow import remove_follower
|
||||
|
|
|
@ -16,12 +16,12 @@ from utils import data_dir
|
|||
from utils import remove_id_ending
|
||||
from utils import save_json
|
||||
from utils import first_paragraph_from_string
|
||||
from utils import date_from_string_format
|
||||
from utils import load_json
|
||||
from utils import locate_post
|
||||
from utils import acct_dir
|
||||
from utils import get_instance_url
|
||||
from utils import get_nickname_from_actor
|
||||
from timeFunctions import date_from_string_format
|
||||
from httpheaders import redirect_headers
|
||||
from posts import is_moderator
|
||||
from content import extract_text_fields_in_post
|
||||
|
|
|
@ -20,13 +20,13 @@ from httpheaders import clear_login_details
|
|||
from flags import is_artist
|
||||
from flags import is_memorial_account
|
||||
from flags import is_premium_account
|
||||
from timeFunctions import get_account_timezone
|
||||
from timeFunctions import set_account_timezone
|
||||
from utils import data_dir
|
||||
from utils import set_premium_account
|
||||
from utils import save_json
|
||||
from utils import save_reverse_timeline
|
||||
from utils import set_minimize_all_images
|
||||
from utils import set_account_timezone
|
||||
from utils import get_account_timezone
|
||||
from utils import set_memorials
|
||||
from utils import get_memorials
|
||||
from utils import license_link_from_name
|
||||
|
|
|
@ -31,8 +31,8 @@ from city import get_spoofed_city
|
|||
from flags import is_image_file
|
||||
from flags import is_float
|
||||
from searchable import set_searchable_by
|
||||
from utils import date_utcnow
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from utils import get_instance_url
|
||||
from utils import save_json
|
||||
from utils import remove_post_from_cache
|
||||
|
|
|
@ -9,7 +9,6 @@ __module_group__ = "ActivityPub"
|
|||
|
||||
import os
|
||||
from datetime import datetime, timezone
|
||||
from utils import date_from_numbers
|
||||
from utils import has_object_string
|
||||
from utils import remove_domain_port
|
||||
from utils import has_users_path
|
||||
|
@ -21,9 +20,10 @@ from utils import locate_post
|
|||
from utils import delete_post
|
||||
from utils import remove_moderation_post_from_index
|
||||
from utils import local_actor_url
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import get_actor_from_post
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import date_from_numbers
|
||||
from timeFunctions import date_utcnow
|
||||
from session import post_json
|
||||
from webfinger import webfinger_handle
|
||||
from auth import create_basic_auth_header
|
||||
|
|
50
flags.py
50
flags.py
|
@ -9,9 +9,11 @@ __module_group__ = "Core"
|
|||
|
||||
import os
|
||||
import re
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import get_published_date
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from utils import acct_dir
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import data_dir
|
||||
from utils import get_config_param
|
||||
from utils import get_image_extensions
|
||||
|
@ -23,7 +25,6 @@ from utils import has_object_dict
|
|||
from utils import locate_post
|
||||
from utils import load_json
|
||||
from utils import has_object_string_type
|
||||
from utils import date_from_string_format
|
||||
from utils import get_reply_to
|
||||
from utils import text_in_file
|
||||
from utils import get_group_paths
|
||||
|
@ -636,3 +637,46 @@ def is_corporate(server_name: str) -> bool:
|
|||
'github' in server_lower:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def can_reply_to(base_dir: str, nickname: str, domain: str,
|
||||
post_url: str, reply_interval_hours: int,
|
||||
curr_date_str: str = None,
|
||||
post_json_object: {} = None) -> bool:
|
||||
"""Is replying to the given local post permitted?
|
||||
This is a spam mitigation feature, so that spammers can't
|
||||
add a lot of replies to old post which you don't notice.
|
||||
"""
|
||||
if '/statuses/' not in post_url:
|
||||
return True
|
||||
if not post_json_object:
|
||||
post_filename = locate_post(base_dir, nickname, domain, post_url)
|
||||
if not post_filename:
|
||||
# the post is not stored locally
|
||||
return True
|
||||
post_json_object = load_json(post_filename)
|
||||
if not post_json_object:
|
||||
return False
|
||||
published = get_published_date(post_json_object)
|
||||
if not published:
|
||||
return False
|
||||
|
||||
pub_date = date_from_string_format(published, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not pub_date:
|
||||
print('EX: can_reply_to unrecognized published date ' + str(published))
|
||||
return False
|
||||
if not curr_date_str:
|
||||
curr_date = date_utcnow()
|
||||
else:
|
||||
curr_date = \
|
||||
date_from_string_format(curr_date_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not curr_date:
|
||||
print('EX: can_reply_to unrecognized current date ' +
|
||||
str(curr_date_str))
|
||||
return False
|
||||
hours_since_publication = \
|
||||
int((curr_date - pub_date).total_seconds() / 3600)
|
||||
if hours_since_publication < 0 or \
|
||||
hours_since_publication >= reply_interval_hours:
|
||||
return False
|
||||
return True
|
||||
|
|
|
@ -21,10 +21,7 @@ from utils import valid_nickname
|
|||
from utils import domain_permitted
|
||||
from utils import get_domain_from_actor
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import get_status_number
|
||||
from utils import follow_person
|
||||
from posts import send_signed_json
|
||||
from posts import get_person_box
|
||||
from utils import load_json
|
||||
from utils import save_json
|
||||
from utils import is_account_dir
|
||||
|
@ -34,6 +31,9 @@ from utils import text_in_file
|
|||
from utils import remove_eol
|
||||
from utils import get_actor_from_post
|
||||
from utils import data_dir
|
||||
from status import get_status_number
|
||||
from posts import send_signed_json
|
||||
from posts import get_person_box
|
||||
from acceptreject import create_accept
|
||||
from acceptreject import create_reject
|
||||
from webfinger import webfinger_handle
|
||||
|
|
|
@ -16,8 +16,6 @@ from flags import is_reminder
|
|||
from flags import is_public_post
|
||||
from utils import resembles_url
|
||||
from utils import replace_strings
|
||||
from utils import date_from_numbers
|
||||
from utils import date_from_string_format
|
||||
from utils import acct_handle_dir
|
||||
from utils import load_json
|
||||
from utils import save_json
|
||||
|
@ -27,10 +25,12 @@ from utils import acct_dir
|
|||
from utils import remove_html
|
||||
from utils import get_display_name
|
||||
from utils import delete_post
|
||||
from utils import get_status_number
|
||||
from utils import get_full_domain
|
||||
from utils import text_in_file
|
||||
from utils import remove_eol
|
||||
from status import get_status_number
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_from_numbers
|
||||
from filters import is_filtered
|
||||
from context import get_individual_post_context
|
||||
from session import get_method
|
||||
|
|
|
@ -25,9 +25,9 @@ from utils import get_full_domain
|
|||
from utils import get_sha_256
|
||||
from utils import get_sha_512
|
||||
from utils import local_actor_url
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
|
||||
|
||||
def message_content_digest(message_body_json_str: str,
|
||||
|
|
10
inbox.py
10
inbox.py
|
@ -14,6 +14,7 @@ import time
|
|||
import random
|
||||
from shutil import copyfile
|
||||
from linked_data_sig import verify_json_signature
|
||||
from flags import can_reply_to
|
||||
from flags import is_system_account
|
||||
from flags import is_blog_post
|
||||
from flags import is_recent_post
|
||||
|
@ -24,20 +25,19 @@ from flags import is_quote_toot
|
|||
from flags import url_permitted
|
||||
from quote import quote_toots_allowed
|
||||
from mitm import save_mitm_servers
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import get_account_timezone
|
||||
from utils import harmless_markup
|
||||
from utils import lines_in_file
|
||||
from utils import date_epoch
|
||||
from utils import date_utcnow
|
||||
from utils import contains_statuses
|
||||
from utils import get_actor_from_post_id
|
||||
from utils import acct_handle_dir
|
||||
from utils import text_in_file
|
||||
from utils import get_media_descriptions_from_post
|
||||
from utils import get_summary_from_post
|
||||
from utils import get_account_timezone
|
||||
from utils import domain_permitted
|
||||
from utils import get_reply_interval_hours
|
||||
from utils import can_reply_to
|
||||
from utils import get_base_content_from_post
|
||||
from utils import acct_dir
|
||||
from utils import remove_domain_port
|
||||
|
@ -49,7 +49,6 @@ from utils import has_users_path
|
|||
from utils import get_full_domain
|
||||
from utils import remove_id_ending
|
||||
from utils import create_inbox_queue_dir
|
||||
from utils import get_status_number
|
||||
from utils import get_domain_from_actor
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import locate_post
|
||||
|
@ -63,6 +62,7 @@ from utils import get_actor_from_post
|
|||
from utils import data_dir
|
||||
from utils import is_dm
|
||||
from utils import has_actor
|
||||
from status import get_status_number
|
||||
from httpsig import get_digest_algorithm_from_headers
|
||||
from httpsig import verify_post_headers
|
||||
from session import create_session
|
||||
|
|
|
@ -13,6 +13,7 @@ from flags import is_recent_post
|
|||
from flags import is_quote_toot
|
||||
from status import actor_status_expired
|
||||
from quote import get_quote_toot_url
|
||||
from timeFunctions import get_account_timezone
|
||||
from utils import get_actor_from_post_id
|
||||
from utils import contains_invalid_actor_url_chars
|
||||
from utils import get_attributed_to
|
||||
|
@ -30,7 +31,6 @@ from utils import has_users_path
|
|||
from utils import has_object_string_type
|
||||
from utils import get_config_param
|
||||
from utils import acct_dir
|
||||
from utils import get_account_timezone
|
||||
from utils import is_dm
|
||||
from utils import delete_cached_html
|
||||
from utils import harmless_markup
|
||||
|
|
|
@ -9,6 +9,7 @@ __module_group__ = "Timeline"
|
|||
|
||||
import os
|
||||
from flags import has_group_type
|
||||
from timeFunctions import get_account_timezone
|
||||
from utils import undo_announce_collection_entry
|
||||
from utils import has_object_dict
|
||||
from utils import remove_domain_port
|
||||
|
@ -16,7 +17,6 @@ from utils import remove_id_ending
|
|||
from utils import get_url_from_post
|
||||
from utils import undo_reaction_collection_entry
|
||||
from utils import remove_html
|
||||
from utils import get_account_timezone
|
||||
from utils import is_dm
|
||||
from utils import get_cached_post_filename
|
||||
from utils import load_json
|
||||
|
|
|
@ -21,7 +21,7 @@ from cryptography.hazmat.primitives.asymmetric import utils as hazutils
|
|||
from pyjsonld import normalize
|
||||
from context import has_valid_context
|
||||
from utils import get_sha_256
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_utcnow
|
||||
|
||||
|
||||
def _options_hash(doc: {}) -> str:
|
||||
|
|
6
maps.py
6
maps.py
|
@ -19,9 +19,9 @@ from utils import save_json
|
|||
from utils import locate_post
|
||||
from utils import remove_html
|
||||
from utils import has_object_dict
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from session import get_resolved_url
|
||||
|
||||
|
||||
|
|
4
media.py
4
media.py
|
@ -15,8 +15,8 @@ import random
|
|||
from random import randint
|
||||
from hashlib import sha1
|
||||
from auth import create_password
|
||||
from utils import date_epoch
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_epoch
|
||||
from utils import safe_system_string
|
||||
from utils import get_base_content_from_post
|
||||
from utils import get_full_domain
|
||||
|
|
|
@ -23,19 +23,19 @@ from newswire import get_dict_from_newswire
|
|||
# from posts import send_signed_json
|
||||
from posts import create_news_post
|
||||
from posts import archive_posts_for_person
|
||||
from utils import date_from_string_format
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from utils import valid_hash_tag
|
||||
from utils import get_base_content_from_post
|
||||
from utils import remove_html
|
||||
from utils import get_full_domain
|
||||
from utils import load_json
|
||||
from utils import save_json
|
||||
from utils import get_status_number
|
||||
from utils import dangerous_markup
|
||||
from utils import local_actor_url
|
||||
from utils import text_in_file
|
||||
from utils import data_dir
|
||||
from status import get_status_number
|
||||
from session import create_session
|
||||
from threads import begin_thread
|
||||
from webapp_hashtagswarm import store_hash_tags
|
||||
|
|
|
@ -17,7 +17,7 @@ import errno
|
|||
from datetime import timedelta
|
||||
from datetime import timezone
|
||||
from collections import OrderedDict
|
||||
from utils import valid_post_date
|
||||
from timeFunctions import valid_post_date
|
||||
from categories import set_hashtag_category
|
||||
from flags import is_suspended
|
||||
from flags import is_local_network_address
|
||||
|
@ -28,7 +28,6 @@ from utils import image_mime_types_dict
|
|||
from utils import resembles_url
|
||||
from utils import get_url_from_post
|
||||
from utils import remove_zero_length_strings
|
||||
from utils import date_from_string_format
|
||||
from utils import acct_handle_dir
|
||||
from utils import remove_eol
|
||||
from utils import get_domain_from_actor
|
||||
|
@ -48,6 +47,7 @@ from utils import acct_dir
|
|||
from utils import local_actor_url
|
||||
from utils import escape_text
|
||||
from utils import unescaped_text
|
||||
from timeFunctions import date_from_string_format
|
||||
from blocking import is_blocked_domain
|
||||
from blocking import is_blocked_hashtag
|
||||
from filters import is_filtered
|
||||
|
|
|
@ -18,12 +18,12 @@ from posts import send_to_named_addresses_thread
|
|||
from flags import is_featured_writer
|
||||
from flags import is_quote_toot
|
||||
from quote import quote_toots_allowed
|
||||
from timeFunctions import get_account_timezone
|
||||
from utils import data_dir
|
||||
from utils import get_post_attachments
|
||||
from utils import get_attributed_to
|
||||
from utils import contains_invalid_actor_url_chars
|
||||
from utils import get_attachment_property_value
|
||||
from utils import get_account_timezone
|
||||
from utils import has_object_string_type
|
||||
from utils import get_base_content_from_post
|
||||
from utils import has_object_dict
|
||||
|
|
|
@ -38,12 +38,12 @@ from roles import actor_roles_from_list
|
|||
from roles import get_actor_roles_list
|
||||
from media import process_meta_data
|
||||
from flags import is_image_file
|
||||
from timeFunctions import date_utcnow
|
||||
from utils import get_person_icon
|
||||
from utils import account_is_indexable
|
||||
from utils import get_image_mime_type
|
||||
from utils import get_instance_url
|
||||
from utils import get_url_from_post
|
||||
from utils import date_utcnow
|
||||
from utils import get_memorials
|
||||
from utils import is_account_dir
|
||||
from utils import valid_hash_tag
|
||||
|
@ -57,7 +57,6 @@ from utils import contains_invalid_actor_url_chars
|
|||
from utils import replace_users_with_at
|
||||
from utils import remove_eol
|
||||
from utils import remove_domain_port
|
||||
from utils import get_status_number
|
||||
from utils import get_full_domain
|
||||
from utils import valid_nickname
|
||||
from utils import load_json
|
||||
|
@ -77,6 +76,7 @@ from utils import text_in_file
|
|||
from utils import contains_statuses
|
||||
from utils import get_actor_from_post
|
||||
from utils import data_dir
|
||||
from status import get_status_number
|
||||
from session import get_json_valid
|
||||
from session import create_session
|
||||
from session import get_json
|
||||
|
|
2
pgp.py
2
pgp.py
|
@ -18,10 +18,10 @@ from utils import get_occupation_skills
|
|||
from utils import get_url_from_post
|
||||
from utils import safe_system_string
|
||||
from utils import get_full_domain
|
||||
from utils import get_status_number
|
||||
from utils import local_actor_url
|
||||
from utils import replace_users_with_at
|
||||
from utils import remove_html
|
||||
from status import get_status_number
|
||||
from webfinger import webfinger_handle
|
||||
from posts import get_person_box
|
||||
from auth import create_basic_auth_header
|
||||
|
|
46
posts.py
46
posts.py
|
@ -41,6 +41,10 @@ from flags import contains_private_key
|
|||
from flags import has_group_type
|
||||
from flags import is_premium_account
|
||||
from flags import url_permitted
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import valid_post_date
|
||||
from utils import resembles_url
|
||||
from utils import get_person_icon
|
||||
from utils import remove_post_from_index
|
||||
|
@ -50,9 +54,6 @@ from utils import get_actor_from_post_id
|
|||
from utils import string_contains
|
||||
from utils import get_post_attachments
|
||||
from utils import get_url_from_post
|
||||
from utils import date_from_string_format
|
||||
from utils import date_epoch
|
||||
from utils import date_utcnow
|
||||
from utils import get_attributed_to
|
||||
from utils import contains_statuses
|
||||
from utils import contains_invalid_actor_url_chars
|
||||
|
@ -76,10 +77,8 @@ from utils import reject_post_id
|
|||
from utils import remove_invalid_chars
|
||||
from utils import file_last_modified
|
||||
from utils import has_users_path
|
||||
from utils import valid_post_date
|
||||
from utils import get_full_domain
|
||||
from utils import get_followers_list
|
||||
from utils import get_status_number
|
||||
from utils import create_person_dir
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import get_domain_from_actor
|
||||
|
@ -90,7 +89,6 @@ from utils import load_json
|
|||
from utils import save_json
|
||||
from utils import get_config_param
|
||||
from utils import locate_news_votes
|
||||
from utils import locate_news_arrival
|
||||
from utils import votes_on_newswire_item
|
||||
from utils import remove_html
|
||||
from utils import dangerous_markup
|
||||
|
@ -99,6 +97,7 @@ from utils import local_actor_url
|
|||
from utils import get_reply_to
|
||||
from utils import get_actor_from_post
|
||||
from utils import data_dir
|
||||
from status import get_status_number
|
||||
from media import get_music_metadata
|
||||
from media import attach_media
|
||||
from media import replace_you_tube
|
||||
|
@ -4840,6 +4839,39 @@ def remove_post_interactions(post_json_object: {}, force: bool) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def _locate_news_arrival(base_dir: str, domain: str,
|
||||
post_url: str) -> str:
|
||||
"""Returns the arrival time for a news post
|
||||
within the news user account
|
||||
"""
|
||||
post_url1 = post_url.strip()
|
||||
post_url = remove_eol(post_url1)
|
||||
|
||||
# if this post in the shared inbox?
|
||||
post_url = remove_id_ending(post_url.strip()).replace('/', '#')
|
||||
|
||||
if post_url.endswith('.json'):
|
||||
post_url = post_url + '.arrived'
|
||||
else:
|
||||
post_url = post_url + '.json.arrived'
|
||||
|
||||
account_dir = data_dir(base_dir) + '/news@' + domain + '/'
|
||||
post_filename = account_dir + 'outbox/' + post_url
|
||||
if os.path.isfile(post_filename):
|
||||
try:
|
||||
with open(post_filename, 'r', encoding='utf-8') as fp_arrival:
|
||||
arrival = fp_arrival.read()
|
||||
if arrival:
|
||||
arrival_date = \
|
||||
date_from_string_format(arrival,
|
||||
["%Y-%m-%dT%H:%M:%S%z"])
|
||||
return arrival_date
|
||||
except OSError:
|
||||
print('EX: _locate_news_arrival unable to read ' + post_filename)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _passed_newswire_voting(newswire_votes_threshold: int,
|
||||
base_dir: str, domain: str,
|
||||
post_filename: str,
|
||||
|
@ -4853,7 +4885,7 @@ def _passed_newswire_voting(newswire_votes_threshold: int,
|
|||
# note that the presence of an arrival file also indicates
|
||||
# that this post is moderated
|
||||
arrival_date = \
|
||||
locate_news_arrival(base_dir, domain, post_filename)
|
||||
_locate_news_arrival(base_dir, domain, post_filename)
|
||||
if not arrival_date:
|
||||
return True
|
||||
# how long has elapsed since this post arrived?
|
||||
|
|
|
@ -20,8 +20,8 @@ from utils import load_json
|
|||
from utils import save_json
|
||||
from utils import remove_html
|
||||
from utils import get_image_extensions
|
||||
from utils import date_epoch
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from timeFunctions import date_from_string_format
|
||||
|
||||
|
||||
def get_book_link_from_content(content: str) -> str:
|
||||
|
|
2
roles.py
2
roles.py
|
@ -11,11 +11,11 @@ import os
|
|||
from utils import data_dir
|
||||
from utils import load_json
|
||||
from utils import save_json
|
||||
from utils import get_status_number
|
||||
from utils import remove_domain_port
|
||||
from utils import acct_dir
|
||||
from utils import text_in_file
|
||||
from utils import get_config_param
|
||||
from status import get_status_number
|
||||
|
||||
|
||||
def _clear_role_status(base_dir: str, role: str) -> None:
|
||||
|
|
|
@ -10,16 +10,16 @@ __module_group__ = "Calendar"
|
|||
import os
|
||||
import time
|
||||
from utils import data_dir
|
||||
from utils import date_from_string_format
|
||||
from utils import date_epoch
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from utils import acct_handle_dir
|
||||
from utils import has_object_dict
|
||||
from utils import get_status_number
|
||||
from utils import load_json
|
||||
from utils import is_account_dir
|
||||
from utils import acct_dir
|
||||
from utils import remove_eol
|
||||
from utils import date_utcnow
|
||||
from status import get_status_number
|
||||
from timeFunctions import date_utcnow
|
||||
from outbox import post_message_to_outbox
|
||||
from session import create_session
|
||||
from threads import begin_thread
|
||||
|
|
|
@ -24,18 +24,18 @@ from session import post_image
|
|||
from session import create_session
|
||||
from session import get_json_valid
|
||||
from flags import is_float
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_string_to_seconds
|
||||
from timeFunctions import date_seconds_to_string
|
||||
from utils import replace_strings
|
||||
from utils import data_dir
|
||||
from utils import resembles_url
|
||||
from utils import date_utcnow
|
||||
from utils import dangerous_markup
|
||||
from utils import remove_html
|
||||
from utils import get_media_extensions
|
||||
from utils import acct_handle_dir
|
||||
from utils import remove_eol
|
||||
from utils import has_object_string_type
|
||||
from utils import date_string_to_seconds
|
||||
from utils import date_seconds_to_string
|
||||
from utils import get_config_param
|
||||
from utils import get_full_domain
|
||||
from utils import valid_nickname
|
||||
|
|
31
status.py
31
status.py
|
@ -9,8 +9,9 @@ __module_group__ = "Core"
|
|||
__accounts_data_path__ = None
|
||||
__accounts_data_path_tests__ = False
|
||||
|
||||
from utils import date_utcnow
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from utils import remove_html
|
||||
from unicodetext import standardize_text
|
||||
|
||||
|
@ -66,3 +67,29 @@ def actor_status_expired(actor_status_json: {}) -> bool:
|
|||
if status_end_time < curr_time:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_status_number(published_str: str = None) -> (str, str):
|
||||
"""Returns the status number and published date
|
||||
"""
|
||||
if not published_str:
|
||||
curr_time = date_utcnow()
|
||||
else:
|
||||
curr_time = \
|
||||
date_from_string_format(published_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
days_since_epoch = (curr_time - date_epoch()).days
|
||||
# status is the number of seconds since epoch
|
||||
status_number = \
|
||||
str(((days_since_epoch * 24 * 60 * 60) +
|
||||
(curr_time.hour * 60 * 60) +
|
||||
(curr_time.minute * 60) +
|
||||
curr_time.second) * 1000 +
|
||||
int(curr_time.microsecond / 1000))
|
||||
# See https://github.com/tootsuite/mastodon/blob/
|
||||
# 995f8b389a66ab76ec92d9a240de376f1fc13a38/lib/mastodon/snowflake.rb
|
||||
# use the leftover microseconds as the sequence number
|
||||
sequence_id = curr_time.microsecond % 1000
|
||||
# shift by 16bits "sequence data"
|
||||
status_number = str((int(status_number) << 16) + sequence_id)
|
||||
published = curr_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
return status_number, published
|
||||
|
|
14
tests.py
14
tests.py
|
@ -59,6 +59,7 @@ from follow import send_follow_request_via_server
|
|||
from follow import send_unfollow_request_via_server
|
||||
from siteactive import site_is_active
|
||||
from siteactive import is_online
|
||||
from flags import can_reply_to
|
||||
from flags import contains_pgp_public_key
|
||||
from flags import is_group_actor
|
||||
from flags import is_group_account
|
||||
|
@ -72,27 +73,26 @@ from utils import data_dir
|
|||
from utils import data_dir_testing
|
||||
from utils import remove_link_tracking
|
||||
from utils import get_url_from_post
|
||||
from utils import date_from_string_format
|
||||
from utils import date_utcnow
|
||||
from utils import remove_markup_tag
|
||||
from utils import remove_style_within_html
|
||||
from utils import html_tag_has_closing
|
||||
from unicodetext import remove_inverted_text
|
||||
from unicodetext import remove_square_capitals
|
||||
from unicodetext import standardize_text
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import convert_published_to_local_timezone
|
||||
from timeFunctions import date_string_to_seconds
|
||||
from timeFunctions import date_seconds_to_string
|
||||
from utils import remove_eol
|
||||
from utils import text_in_file
|
||||
from utils import convert_published_to_local_timezone
|
||||
from utils import convert_to_snake_case
|
||||
from utils import get_sha_256
|
||||
from utils import dangerous_svg
|
||||
from utils import can_reply_to
|
||||
from utils import get_actor_languages_list
|
||||
from utils import get_category_types
|
||||
from utils import get_supported_languages
|
||||
from utils import set_config_param
|
||||
from utils import date_string_to_seconds
|
||||
from utils import date_seconds_to_string
|
||||
from utils import valid_password
|
||||
from utils import user_agent_domain
|
||||
from utils import camel_case_split
|
||||
|
@ -107,12 +107,12 @@ from utils import get_domain_from_actor
|
|||
from utils import copytree
|
||||
from utils import load_json
|
||||
from utils import save_json
|
||||
from utils import get_status_number
|
||||
from utils import valid_hash_tag
|
||||
from utils import get_followers_of_person
|
||||
from utils import remove_html
|
||||
from utils import dangerous_markup
|
||||
from utils import acct_dir
|
||||
from status import get_status_number
|
||||
from pgp import extract_pgp_public_key
|
||||
from pgp import pgp_public_key_upload
|
||||
from follow import add_follower_of_person
|
||||
|
|
|
@ -11,7 +11,7 @@ import threading
|
|||
import sys
|
||||
import time
|
||||
from socket import error as SocketError
|
||||
from utils import date_utcnow
|
||||
from timeFunctions import date_utcnow
|
||||
|
||||
|
||||
class thread_with_trace(threading.Thread):
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
__filename__ = "timeFunctions.py"
|
||||
__author__ = "Bob Mottram"
|
||||
__license__ = "AGPL3+"
|
||||
__version__ = "1.6.0"
|
||||
__maintainer__ = "Bob Mottram"
|
||||
__email__ = "bob@libreserver.org"
|
||||
__status__ = "Production"
|
||||
__module_group__ = "Core"
|
||||
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
from dateutil.tz import tz
|
||||
from utils import acct_dir
|
||||
from utils import data_dir
|
||||
from utils import has_object_dict
|
||||
|
||||
|
||||
def convert_published_to_local_timezone(published, timezone: str) -> str:
|
||||
"""Converts a post published time into local time
|
||||
"""
|
||||
to_zone = None
|
||||
from_zone = tz.gettz('UTC')
|
||||
if timezone:
|
||||
try:
|
||||
to_zone = tz.gettz(timezone)
|
||||
except BaseException:
|
||||
pass
|
||||
if not timezone or not to_zone:
|
||||
return published
|
||||
|
||||
utc = published.replace(tzinfo=from_zone)
|
||||
local_time = utc.astimezone(to_zone)
|
||||
return local_time
|
||||
|
||||
|
||||
def _utc_mktime(utc_tuple):
|
||||
"""Returns number of seconds elapsed since epoch
|
||||
Note that no timezone are taken into consideration.
|
||||
utc tuple must be: (year, month, day, hour, minute, second)
|
||||
"""
|
||||
|
||||
if len(utc_tuple) == 6:
|
||||
utc_tuple += (0, 0, 0)
|
||||
return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))
|
||||
|
||||
|
||||
def _datetime_to_timestamp(dtime):
|
||||
"""Converts a datetime object to UTC timestamp"""
|
||||
return int(_utc_mktime(dtime.timetuple()))
|
||||
|
||||
|
||||
def date_utcnow():
|
||||
"""returns the time now
|
||||
"""
|
||||
return datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
|
||||
def date_from_numbers(year: int, month: int, day: int,
|
||||
hour: int, mins: int):
|
||||
"""returns an offset-aware datetime
|
||||
"""
|
||||
return datetime.datetime(year, month, day, hour, mins, 0,
|
||||
tzinfo=datetime.timezone.utc)
|
||||
|
||||
|
||||
def date_from_string_format(date_str: str, formats: []):
|
||||
"""returns an offset-aware datetime from a string date
|
||||
"""
|
||||
if not formats:
|
||||
formats = ("%a, %d %b %Y %H:%M:%S %Z",
|
||||
"%a, %d %b %Y %H:%M:%S %z",
|
||||
"%Y-%m-%dT%H:%M:%S%z")
|
||||
dtime = None
|
||||
for date_format in formats:
|
||||
try:
|
||||
dtime = \
|
||||
datetime.datetime.strptime(date_str, date_format)
|
||||
except BaseException:
|
||||
continue
|
||||
break
|
||||
if not dtime:
|
||||
return None
|
||||
if not dtime.tzinfo:
|
||||
dtime = dtime.replace(tzinfo=datetime.timezone.utc)
|
||||
return dtime
|
||||
|
||||
|
||||
def date_epoch():
|
||||
"""returns an offset-aware version of epoch
|
||||
"""
|
||||
return date_from_numbers(1970, 1, 1, 0, 0)
|
||||
|
||||
|
||||
def date_string_to_seconds(date_str: str) -> int:
|
||||
"""Converts a date string (eg "published") into seconds since epoch
|
||||
"""
|
||||
expiry_time = \
|
||||
date_from_string_format(date_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not expiry_time:
|
||||
print('EX: date_string_to_seconds unable to parse date ' +
|
||||
str(date_str))
|
||||
return None
|
||||
return _datetime_to_timestamp(expiry_time)
|
||||
|
||||
|
||||
def date_seconds_to_string(date_sec: int) -> str:
|
||||
"""Converts a date in seconds since epoch to a string
|
||||
"""
|
||||
this_date = \
|
||||
datetime.datetime.fromtimestamp(date_sec, datetime.timezone.utc)
|
||||
if not this_date.tzinfo:
|
||||
this_date = this_date.replace(tzinfo=datetime.timezone.utc)
|
||||
this_date_tz = this_date.astimezone(datetime.timezone.utc)
|
||||
return this_date_tz.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
def get_account_timezone(base_dir: str, nickname: str, domain: str) -> str:
|
||||
"""Returns the timezone for the given account
|
||||
"""
|
||||
tz_filename = \
|
||||
acct_dir(base_dir, nickname, domain) + '/timezone.txt'
|
||||
if not os.path.isfile(tz_filename):
|
||||
return None
|
||||
timezone = None
|
||||
try:
|
||||
with open(tz_filename, 'r', encoding='utf-8') as fp_timezone:
|
||||
timezone = fp_timezone.read().strip()
|
||||
except OSError:
|
||||
print('EX: get_account_timezone unable to read ' + tz_filename)
|
||||
return timezone
|
||||
|
||||
|
||||
def set_account_timezone(base_dir: str, nickname: str, domain: str,
|
||||
timezone: str) -> None:
|
||||
"""Sets the timezone for the given account
|
||||
"""
|
||||
tz_filename = \
|
||||
acct_dir(base_dir, nickname, domain) + '/timezone.txt'
|
||||
timezone = timezone.strip()
|
||||
try:
|
||||
with open(tz_filename, 'w+', encoding='utf-8') as fp_timezone:
|
||||
fp_timezone.write(timezone)
|
||||
except OSError:
|
||||
print('EX: set_account_timezone unable to write ' +
|
||||
tz_filename)
|
||||
|
||||
|
||||
def load_account_timezones(base_dir: str) -> {}:
|
||||
"""Returns a dictionary containing the preferred timezone for each account
|
||||
"""
|
||||
account_timezone = {}
|
||||
dir_str = data_dir(base_dir)
|
||||
for _, dirs, _ in os.walk(dir_str):
|
||||
for acct in dirs:
|
||||
if '@' not in acct:
|
||||
continue
|
||||
if acct.startswith('inbox@') or acct.startswith('Actor@'):
|
||||
continue
|
||||
acct_directory = os.path.join(dir_str, acct)
|
||||
tz_filename = acct_directory + '/timezone.txt'
|
||||
if not os.path.isfile(tz_filename):
|
||||
continue
|
||||
timezone = None
|
||||
try:
|
||||
with open(tz_filename, 'r', encoding='utf-8') as fp_timezone:
|
||||
timezone = fp_timezone.read().strip()
|
||||
except OSError:
|
||||
print('EX: load_account_timezones unable to read ' +
|
||||
tz_filename)
|
||||
if timezone:
|
||||
nickname = acct.split('@')[0]
|
||||
account_timezone[nickname] = timezone
|
||||
break
|
||||
return account_timezone
|
||||
|
||||
|
||||
def week_day_of_month_start(month_number: int, year: int) -> int:
|
||||
"""Gets the day number of the first day of the month
|
||||
1=sun, 7=sat
|
||||
"""
|
||||
first_day_of_month = date_from_numbers(year, month_number, 1, 0, 0)
|
||||
return int(first_day_of_month.strftime("%w")) + 1
|
||||
|
||||
|
||||
def valid_post_date(published: str, max_age_days: int, debug: bool) -> bool:
|
||||
"""Returns true if the published date is recent and is not in the future
|
||||
"""
|
||||
baseline_time = date_epoch()
|
||||
|
||||
days_diff = date_utcnow() - baseline_time
|
||||
now_days_since_epoch = days_diff.days
|
||||
|
||||
post_time_object = \
|
||||
date_from_string_format(published, ["%Y-%m-%dT%H:%M:%S%z"])
|
||||
if not post_time_object:
|
||||
if debug:
|
||||
print('EX: valid_post_date invalid published date ' +
|
||||
str(published))
|
||||
return False
|
||||
|
||||
days_diff = post_time_object - baseline_time
|
||||
post_days_since_epoch = days_diff.days
|
||||
|
||||
if post_days_since_epoch > now_days_since_epoch:
|
||||
if debug:
|
||||
print("Inbox post has a published date in the future!")
|
||||
return False
|
||||
|
||||
if now_days_since_epoch - post_days_since_epoch >= max_age_days:
|
||||
if debug:
|
||||
print("Inbox post is not recent enough")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def time_days_ago(datestr: str) -> int:
|
||||
"""returns the number of days ago for the given date
|
||||
"""
|
||||
date1 = \
|
||||
date_from_string_format(datestr,
|
||||
["%Y-%m-%dT%H:%M:%S%z"])
|
||||
if not date1:
|
||||
return 0
|
||||
date_diff = date_utcnow() - date1
|
||||
return date_diff.days
|
||||
|
||||
|
||||
def get_published_date(post_json_object: {}) -> str:
|
||||
"""Returns the published date on the given post
|
||||
"""
|
||||
published = None
|
||||
if post_json_object.get('published'):
|
||||
published = post_json_object['published']
|
||||
elif has_object_dict(post_json_object):
|
||||
if post_json_object['object'].get('published'):
|
||||
published = post_json_object['object']['published']
|
||||
if not published:
|
||||
return None
|
||||
if not isinstance(published, str):
|
||||
return None
|
||||
return published
|
329
utils.py
329
utils.py
|
@ -18,7 +18,6 @@ import json
|
|||
import locale
|
||||
from pprint import pprint
|
||||
import idna
|
||||
from dateutil.tz import tz
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from followingCalendar import add_person_to_calendar
|
||||
|
@ -65,64 +64,6 @@ def remove_zero_length_strings(text: str) -> str:
|
|||
return text.replace('', '')
|
||||
|
||||
|
||||
def _utc_mktime(utc_tuple):
|
||||
"""Returns number of seconds elapsed since epoch
|
||||
Note that no timezone are taken into consideration.
|
||||
utc tuple must be: (year, month, day, hour, minute, second)
|
||||
"""
|
||||
|
||||
if len(utc_tuple) == 6:
|
||||
utc_tuple += (0, 0, 0)
|
||||
return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))
|
||||
|
||||
|
||||
def _datetime_to_timestamp(dtime):
|
||||
"""Converts a datetime object to UTC timestamp"""
|
||||
return int(_utc_mktime(dtime.timetuple()))
|
||||
|
||||
|
||||
def date_utcnow():
|
||||
"""returns the time now
|
||||
"""
|
||||
return datetime.datetime.now(datetime.timezone.utc)
|
||||
|
||||
|
||||
def date_from_numbers(year: int, month: int, day: int,
|
||||
hour: int, mins: int):
|
||||
"""returns an offset-aware datetime
|
||||
"""
|
||||
return datetime.datetime(year, month, day, hour, mins, 0,
|
||||
tzinfo=datetime.timezone.utc)
|
||||
|
||||
|
||||
def date_from_string_format(date_str: str, formats: []):
|
||||
"""returns an offset-aware datetime from a string date
|
||||
"""
|
||||
if not formats:
|
||||
formats = ("%a, %d %b %Y %H:%M:%S %Z",
|
||||
"%a, %d %b %Y %H:%M:%S %z",
|
||||
"%Y-%m-%dT%H:%M:%S%z")
|
||||
dtime = None
|
||||
for date_format in formats:
|
||||
try:
|
||||
dtime = \
|
||||
datetime.datetime.strptime(date_str, date_format)
|
||||
except BaseException:
|
||||
continue
|
||||
break
|
||||
if not dtime:
|
||||
return None
|
||||
if not dtime.tzinfo:
|
||||
dtime = dtime.replace(tzinfo=datetime.timezone.utc)
|
||||
return dtime
|
||||
|
||||
|
||||
def date_epoch():
|
||||
"""returns an offset-aware version of epoch
|
||||
"""
|
||||
return date_from_numbers(1970, 1, 1, 0, 0)
|
||||
|
||||
|
||||
def get_url_from_post(url_field) -> str:
|
||||
"""Returns a url from a post object
|
||||
"""
|
||||
|
@ -658,37 +599,6 @@ def has_users_path(path_str: str) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def valid_post_date(published: str, max_age_days: int, debug: bool) -> bool:
|
||||
"""Returns true if the published date is recent and is not in the future
|
||||
"""
|
||||
baseline_time = date_epoch()
|
||||
|
||||
days_diff = date_utcnow() - baseline_time
|
||||
now_days_since_epoch = days_diff.days
|
||||
|
||||
post_time_object = \
|
||||
date_from_string_format(published, ["%Y-%m-%dT%H:%M:%S%z"])
|
||||
if not post_time_object:
|
||||
if debug:
|
||||
print('EX: valid_post_date invalid published date ' +
|
||||
str(published))
|
||||
return False
|
||||
|
||||
days_diff = post_time_object - baseline_time
|
||||
post_days_since_epoch = days_diff.days
|
||||
|
||||
if post_days_since_epoch > now_days_since_epoch:
|
||||
if debug:
|
||||
print("Inbox post has a published date in the future!")
|
||||
return False
|
||||
|
||||
if now_days_since_epoch - post_days_since_epoch >= max_age_days:
|
||||
if debug:
|
||||
print("Inbox post is not recent enough")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_full_domain(domain: str, port: int) -> str:
|
||||
"""Returns the full domain name, including port number
|
||||
"""
|
||||
|
@ -1147,32 +1057,6 @@ def load_json_onionify(filename: str, domain: str, onion_domain: str,
|
|||
return json_object
|
||||
|
||||
|
||||
def get_status_number(published_str: str = None) -> (str, str):
|
||||
"""Returns the status number and published date
|
||||
"""
|
||||
if not published_str:
|
||||
curr_time = date_utcnow()
|
||||
else:
|
||||
curr_time = \
|
||||
date_from_string_format(published_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
days_since_epoch = (curr_time - date_epoch()).days
|
||||
# status is the number of seconds since epoch
|
||||
status_number = \
|
||||
str(((days_since_epoch * 24 * 60 * 60) +
|
||||
(curr_time.hour * 60 * 60) +
|
||||
(curr_time.minute * 60) +
|
||||
curr_time.second) * 1000 +
|
||||
int(curr_time.microsecond / 1000))
|
||||
# See https://github.com/tootsuite/mastodon/blob/
|
||||
# 995f8b389a66ab76ec92d9a240de376f1fc13a38/lib/mastodon/snowflake.rb
|
||||
# use the leftover microseconds as the sequence number
|
||||
sequence_id = curr_time.microsecond % 1000
|
||||
# shift by 16bits "sequence data"
|
||||
status_number = str((int(status_number) << 16) + sequence_id)
|
||||
published = curr_time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
return status_number, published
|
||||
|
||||
|
||||
def evil_incarnate() -> []:
|
||||
"""Hardcoded blocked domains
|
||||
"""
|
||||
|
@ -1866,39 +1750,6 @@ def locate_news_votes(base_dir: str, domain: str,
|
|||
return None
|
||||
|
||||
|
||||
def locate_news_arrival(base_dir: str, domain: str,
|
||||
post_url: str) -> str:
|
||||
"""Returns the arrival time for a news post
|
||||
within the news user account
|
||||
"""
|
||||
post_url1 = post_url.strip()
|
||||
post_url = remove_eol(post_url1)
|
||||
|
||||
# if this post in the shared inbox?
|
||||
post_url = remove_id_ending(post_url.strip()).replace('/', '#')
|
||||
|
||||
if post_url.endswith('.json'):
|
||||
post_url = post_url + '.arrived'
|
||||
else:
|
||||
post_url = post_url + '.json.arrived'
|
||||
|
||||
account_dir = data_dir(base_dir) + '/news@' + domain + '/'
|
||||
post_filename = account_dir + 'outbox/' + post_url
|
||||
if os.path.isfile(post_filename):
|
||||
try:
|
||||
with open(post_filename, 'r', encoding='utf-8') as fp_arrival:
|
||||
arrival = fp_arrival.read()
|
||||
if arrival:
|
||||
arrival_date = \
|
||||
date_from_string_format(arrival,
|
||||
["%Y-%m-%dT%H:%M:%S%z"])
|
||||
return arrival_date
|
||||
except OSError:
|
||||
print('EX: locate_news_arrival unable to read ' + post_filename)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def locate_post(base_dir: str, nickname: str, domain: str,
|
||||
post_url: str, replies: bool = False) -> str:
|
||||
"""Returns the filename for the given status post url
|
||||
|
@ -1937,22 +1788,6 @@ def locate_post(base_dir: str, nickname: str, domain: str,
|
|||
return None
|
||||
|
||||
|
||||
def _get_published_date(post_json_object: {}) -> str:
|
||||
"""Returns the published date on the given post
|
||||
"""
|
||||
published = None
|
||||
if post_json_object.get('published'):
|
||||
published = post_json_object['published']
|
||||
elif has_object_dict(post_json_object):
|
||||
if post_json_object['object'].get('published'):
|
||||
published = post_json_object['object']['published']
|
||||
if not published:
|
||||
return None
|
||||
if not isinstance(published, str):
|
||||
return None
|
||||
return published
|
||||
|
||||
|
||||
def get_reply_interval_hours(base_dir: str, nickname: str, domain: str,
|
||||
default_reply_interval_hrs: int) -> int:
|
||||
"""Returns the reply interval for the given account.
|
||||
|
@ -1994,49 +1829,6 @@ def set_reply_interval_hours(base_dir: str, nickname: str, domain: str,
|
|||
return False
|
||||
|
||||
|
||||
def can_reply_to(base_dir: str, nickname: str, domain: str,
|
||||
post_url: str, reply_interval_hours: int,
|
||||
curr_date_str: str = None,
|
||||
post_json_object: {} = None) -> bool:
|
||||
"""Is replying to the given local post permitted?
|
||||
This is a spam mitigation feature, so that spammers can't
|
||||
add a lot of replies to old post which you don't notice.
|
||||
"""
|
||||
if '/statuses/' not in post_url:
|
||||
return True
|
||||
if not post_json_object:
|
||||
post_filename = locate_post(base_dir, nickname, domain, post_url)
|
||||
if not post_filename:
|
||||
# the post is not stored locally
|
||||
return True
|
||||
post_json_object = load_json(post_filename)
|
||||
if not post_json_object:
|
||||
return False
|
||||
published = _get_published_date(post_json_object)
|
||||
if not published:
|
||||
return False
|
||||
|
||||
pub_date = date_from_string_format(published, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not pub_date:
|
||||
print('EX: can_reply_to unrecognized published date ' + str(published))
|
||||
return False
|
||||
if not curr_date_str:
|
||||
curr_date = date_utcnow()
|
||||
else:
|
||||
curr_date = \
|
||||
date_from_string_format(curr_date_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not curr_date:
|
||||
print('EX: can_reply_to unrecognized current date ' +
|
||||
str(curr_date_str))
|
||||
return False
|
||||
hours_since_publication = \
|
||||
int((curr_date - pub_date).total_seconds() / 3600)
|
||||
if hours_since_publication < 0 or \
|
||||
hours_since_publication >= reply_interval_hours:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _remove_attachment(base_dir: str, http_prefix: str,
|
||||
nickname: str, domain: str, post_json: {}) -> None:
|
||||
"""Removes media files for an attachment
|
||||
|
@ -3106,14 +2898,6 @@ def update_announce_collection(recent_posts_cache: {},
|
|||
save_json(post_json_object, post_filename)
|
||||
|
||||
|
||||
def week_day_of_month_start(month_number: int, year: int) -> int:
|
||||
"""Gets the day number of the first day of the month
|
||||
1=sun, 7=sat
|
||||
"""
|
||||
first_day_of_month = date_from_numbers(year, month_number, 1, 0, 0)
|
||||
return int(first_day_of_month.strftime("%w")) + 1
|
||||
|
||||
|
||||
def media_file_mime_type(filename: str) -> str:
|
||||
"""Given a media filename return its mime type
|
||||
"""
|
||||
|
@ -3149,18 +2933,6 @@ def media_file_mime_type(filename: str) -> str:
|
|||
return extensions[file_ext]
|
||||
|
||||
|
||||
def time_days_ago(datestr: str) -> int:
|
||||
"""returns the number of days ago for the given date
|
||||
"""
|
||||
date1 = \
|
||||
date_from_string_format(datestr,
|
||||
["%Y-%m-%dT%H:%M:%S%z"])
|
||||
if not date1:
|
||||
return 0
|
||||
date_diff = date_utcnow() - date1
|
||||
return date_diff.days
|
||||
|
||||
|
||||
def camel_case_split(text: str) -> str:
|
||||
""" Splits CamelCase into "Camel Case"
|
||||
"""
|
||||
|
@ -3526,29 +3298,6 @@ def valid_password(password: str, debug: bool) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
def date_string_to_seconds(date_str: str) -> int:
|
||||
"""Converts a date string (eg "published") into seconds since epoch
|
||||
"""
|
||||
expiry_time = \
|
||||
date_from_string_format(date_str, ['%Y-%m-%dT%H:%M:%S%z'])
|
||||
if not expiry_time:
|
||||
print('EX: date_string_to_seconds unable to parse date ' +
|
||||
str(date_str))
|
||||
return None
|
||||
return _datetime_to_timestamp(expiry_time)
|
||||
|
||||
|
||||
def date_seconds_to_string(date_sec: int) -> str:
|
||||
"""Converts a date in seconds since epoch to a string
|
||||
"""
|
||||
this_date = \
|
||||
datetime.datetime.fromtimestamp(date_sec, datetime.timezone.utc)
|
||||
if not this_date.tzinfo:
|
||||
this_date = this_date.replace(tzinfo=datetime.timezone.utc)
|
||||
this_date_tz = this_date.astimezone(datetime.timezone.utc)
|
||||
return this_date_tz.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
def get_currencies() -> {}:
|
||||
"""Returns a dictionary of currencies
|
||||
"""
|
||||
|
@ -3796,53 +3545,6 @@ def valid_hash_tag(hashtag: str) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def convert_published_to_local_timezone(published, timezone: str) -> str:
|
||||
"""Converts a post published time into local time
|
||||
"""
|
||||
to_zone = None
|
||||
from_zone = tz.gettz('UTC')
|
||||
if timezone:
|
||||
try:
|
||||
to_zone = tz.gettz(timezone)
|
||||
except BaseException:
|
||||
pass
|
||||
if not timezone or not to_zone:
|
||||
return published
|
||||
|
||||
utc = published.replace(tzinfo=from_zone)
|
||||
local_time = utc.astimezone(to_zone)
|
||||
return local_time
|
||||
|
||||
|
||||
def load_account_timezones(base_dir: str) -> {}:
|
||||
"""Returns a dictionary containing the preferred timezone for each account
|
||||
"""
|
||||
account_timezone = {}
|
||||
dir_str = data_dir(base_dir)
|
||||
for _, dirs, _ in os.walk(dir_str):
|
||||
for acct in dirs:
|
||||
if '@' not in acct:
|
||||
continue
|
||||
if acct.startswith('inbox@') or acct.startswith('Actor@'):
|
||||
continue
|
||||
acct_directory = os.path.join(dir_str, acct)
|
||||
tz_filename = acct_directory + '/timezone.txt'
|
||||
if not os.path.isfile(tz_filename):
|
||||
continue
|
||||
timezone = None
|
||||
try:
|
||||
with open(tz_filename, 'r', encoding='utf-8') as fp_timezone:
|
||||
timezone = fp_timezone.read().strip()
|
||||
except OSError:
|
||||
print('EX: load_account_timezones unable to read ' +
|
||||
tz_filename)
|
||||
if timezone:
|
||||
nickname = acct.split('@')[0]
|
||||
account_timezone[nickname] = timezone
|
||||
break
|
||||
return account_timezone
|
||||
|
||||
|
||||
def load_bold_reading(base_dir: str) -> {}:
|
||||
"""Returns a dictionary containing the bold reading status for each account
|
||||
"""
|
||||
|
@ -3902,37 +3604,6 @@ def load_hide_recent_posts(base_dir: str) -> {}:
|
|||
return hide_recent_posts
|
||||
|
||||
|
||||
def get_account_timezone(base_dir: str, nickname: str, domain: str) -> str:
|
||||
"""Returns the timezone for the given account
|
||||
"""
|
||||
tz_filename = \
|
||||
acct_dir(base_dir, nickname, domain) + '/timezone.txt'
|
||||
if not os.path.isfile(tz_filename):
|
||||
return None
|
||||
timezone = None
|
||||
try:
|
||||
with open(tz_filename, 'r', encoding='utf-8') as fp_timezone:
|
||||
timezone = fp_timezone.read().strip()
|
||||
except OSError:
|
||||
print('EX: get_account_timezone unable to read ' + tz_filename)
|
||||
return timezone
|
||||
|
||||
|
||||
def set_account_timezone(base_dir: str, nickname: str, domain: str,
|
||||
timezone: str) -> None:
|
||||
"""Sets the timezone for the given account
|
||||
"""
|
||||
tz_filename = \
|
||||
acct_dir(base_dir, nickname, domain) + '/timezone.txt'
|
||||
timezone = timezone.strip()
|
||||
try:
|
||||
with open(tz_filename, 'w+', encoding='utf-8') as fp_timezone:
|
||||
fp_timezone.write(timezone)
|
||||
except OSError:
|
||||
print('EX: set_account_timezone unable to write ' +
|
||||
tz_filename)
|
||||
|
||||
|
||||
def _is_onion_request(calling_domain: str, referer_domain: str,
|
||||
domain: str, onion_domain: str) -> bool:
|
||||
"""Do the given domains indicate that this is a request
|
||||
|
|
|
@ -18,14 +18,14 @@ from utils import get_nickname_from_actor
|
|||
from utils import get_domain_from_actor
|
||||
from utils import locate_post
|
||||
from utils import load_json
|
||||
from utils import week_day_of_month_start
|
||||
from utils import get_alt_path
|
||||
from utils import remove_domain_port
|
||||
from utils import acct_dir
|
||||
from utils import local_actor_url
|
||||
from utils import replace_users_with_at
|
||||
from utils import language_right_to_left
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import week_day_of_month_start
|
||||
from timeFunctions import date_from_string_format
|
||||
from happening import get_todays_events
|
||||
from happening import get_calendar_events
|
||||
from happening import get_todays_events_icalendar
|
||||
|
|
|
@ -24,7 +24,7 @@ from utils import get_nickname_from_actor
|
|||
from utils import get_config_param
|
||||
from utils import remove_domain_port
|
||||
from utils import acct_dir
|
||||
from utils import date_from_string_format
|
||||
from timeFunctions import date_from_string_format
|
||||
from posts import is_moderator
|
||||
from newswire import get_newswire_favicon_url
|
||||
from webapp_utils import get_right_image_file
|
||||
|
|
|
@ -18,7 +18,7 @@ from utils import load_json
|
|||
from utils import get_config_param
|
||||
from utils import get_alt_path
|
||||
from utils import acct_dir
|
||||
from utils import get_account_timezone
|
||||
from timeFunctions import get_account_timezone
|
||||
from blocking import sending_is_blocked2
|
||||
from webapp_utils import set_custom_background
|
||||
from webapp_utils import html_header_with_external_style
|
||||
|
|
|
@ -26,10 +26,10 @@ from utils import get_config_param
|
|||
from utils import acct_dir
|
||||
from utils import get_currencies
|
||||
from utils import get_category_types
|
||||
from utils import get_account_timezone
|
||||
from utils import get_supported_languages
|
||||
from utils import get_attributed_to
|
||||
from utils import get_full_domain
|
||||
from timeFunctions import get_account_timezone
|
||||
from blocking import sending_is_blocked2
|
||||
from webapp_utils import open_content_warning
|
||||
from webapp_utils import edit_check_box
|
||||
|
|
|
@ -11,7 +11,7 @@ import os
|
|||
from flags import is_system_account
|
||||
from utils import get_domain_from_actor
|
||||
from utils import get_config_param
|
||||
from utils import get_account_timezone
|
||||
from timeFunctions import get_account_timezone
|
||||
from person import person_box_json
|
||||
from webapp_utils import html_header_with_external_style
|
||||
from webapp_utils import html_footer
|
||||
|
|
|
@ -10,20 +10,20 @@ __module_group__ = "Web Interface"
|
|||
import os
|
||||
from datetime import datetime, timezone
|
||||
from flags import is_public_post
|
||||
from timeFunctions import date_utcnow
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import date_epoch
|
||||
from utils import valid_hash_tag
|
||||
from utils import remove_id_ending
|
||||
from utils import resembles_url
|
||||
from utils import has_object_dict
|
||||
from utils import local_actor_url
|
||||
from utils import date_from_string_format
|
||||
from utils import file_last_modified
|
||||
from utils import acct_dir
|
||||
from utils import data_dir
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import get_config_param
|
||||
from utils import escape_text
|
||||
from utils import date_utcnow
|
||||
from utils import date_epoch
|
||||
from utils import string_contains
|
||||
from delete import remove_old_hashtags
|
||||
from maps import get_category_from_post
|
||||
|
|
|
@ -10,12 +10,12 @@ __module_group__ = "ActivityPub"
|
|||
import os
|
||||
from utils import locate_post
|
||||
from utils import get_config_param
|
||||
from utils import get_account_timezone
|
||||
from utils import get_display_name
|
||||
from utils import get_nickname_from_actor
|
||||
from utils import has_object_dict
|
||||
from utils import load_json
|
||||
from utils import get_actor_from_post
|
||||
from timeFunctions import get_account_timezone
|
||||
from person import get_person_avatar_url
|
||||
from webapp_utils import html_header_with_external_style
|
||||
from webapp_utils import html_footer
|
||||
|
|
|
@ -45,7 +45,6 @@ from utils import contains_statuses
|
|||
from utils import data_dir
|
||||
from utils import get_post_attachments
|
||||
from utils import get_url_from_post
|
||||
from utils import date_from_string_format
|
||||
from utils import remove_markup_tag
|
||||
from utils import ap_proxy_type
|
||||
from utils import remove_style_within_html
|
||||
|
@ -54,7 +53,8 @@ from utils import dont_speak_hashtags
|
|||
from utils import remove_eol
|
||||
from utils import disallow_announce
|
||||
from utils import disallow_reply
|
||||
from utils import convert_published_to_local_timezone
|
||||
from timeFunctions import date_from_string_format
|
||||
from timeFunctions import convert_published_to_local_timezone
|
||||
from utils import remove_hash_from_post_id
|
||||
from utils import remove_html
|
||||
from utils import get_actor_languages_list
|
||||
|
|
|
@ -24,7 +24,6 @@ from unicodetext import standardize_text
|
|||
from utils import get_person_icon
|
||||
from utils import replace_strings
|
||||
from utils import data_dir
|
||||
from utils import time_days_ago
|
||||
from utils import get_attributed_to
|
||||
from utils import get_url_from_post
|
||||
from utils import get_memorials
|
||||
|
@ -47,10 +46,11 @@ from utils import acct_dir
|
|||
from utils import get_supported_languages
|
||||
from utils import local_actor_url
|
||||
from utils import get_reply_interval_hours
|
||||
from utils import get_account_timezone
|
||||
from utils import remove_eol
|
||||
from utils import get_actor_from_post
|
||||
from utils import resembles_url
|
||||
from timeFunctions import time_days_ago
|
||||
from timeFunctions import get_account_timezone
|
||||
from languages import get_actor_languages
|
||||
from skills import get_skills
|
||||
from theme import get_themes_list
|
||||
|
|
|
@ -13,11 +13,11 @@ import urllib.parse
|
|||
from flags import is_editor
|
||||
from flags import is_public_post
|
||||
from searchable import search_box_posts
|
||||
from timeFunctions import date_from_string_format
|
||||
from utils import get_person_icon
|
||||
from utils import data_dir
|
||||
from utils import get_post_attachments
|
||||
from utils import get_url_from_post
|
||||
from utils import date_from_string_format
|
||||
from utils import get_attributed_to
|
||||
from utils import get_actor_from_post_id
|
||||
from utils import remove_html
|
||||
|
|
Loading…
Reference in New Issue