diff --git a/blog.py b/blog.py index 9818aa8d2..acf875153 100644 --- a/blog.py +++ b/blog.py @@ -542,7 +542,7 @@ def html_blog_page(authorized: bool, session, timeline_json = \ create_blogs_timeline(base_dir, nickname, domain, port, http_prefix, - no_of_items, False, page_number) + no_of_items, False, page_number, '') if not timeline_json: return blog_str + html_footer() @@ -631,7 +631,7 @@ def html_blog_page_rss2(base_dir: str, http_prefix: str, translate: {}, nickname, domain, port, http_prefix, no_of_items, False, - page_number) + page_number, '') if not timeline_json: if include_header: @@ -670,7 +670,7 @@ def html_blog_page_rss3(base_dir: str, http_prefix: str, timeline_json = \ create_blogs_timeline(base_dir, nickname, domain, port, http_prefix, - no_of_items, False, page_number) + no_of_items, False, page_number, '') if not timeline_json: return blog_rss3 diff --git a/daemon.py b/daemon.py index 2708f8ff6..75aa0f517 100644 --- a/daemon.py +++ b/daemon.py @@ -12120,6 +12120,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -12294,6 +12296,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -12457,6 +12461,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -12619,6 +12625,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -12778,6 +12786,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -12938,6 +12948,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13103,6 +13115,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13260,6 +13274,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13356,6 +13372,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13465,6 +13483,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13623,6 +13643,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 0 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13768,6 +13790,8 @@ class PubServer(BaseHTTPRequestHandler): page_number = 1 if '?page=' in nickname: page_number = nickname.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] nickname = nickname.split('?page=')[0] if len(page_number) > 5: page_number = "1" @@ -13927,6 +13951,8 @@ class PubServer(BaseHTTPRequestHandler): SHARES_PER_PAGE) else: page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] if '#' in page_number_str: page_number_str = page_number_str.split('#')[0] if len(page_number_str) > 5: @@ -14062,6 +14088,8 @@ class PubServer(BaseHTTPRequestHandler): authorized, FOLLOWS_PER_PAGE) else: page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] if '#' in page_number_str: page_number_str = page_number_str.split('#')[0] if len(page_number_str) > 5: @@ -14200,6 +14228,8 @@ class PubServer(BaseHTTPRequestHandler): 'followers') else: page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] if '#' in page_number_str: page_number_str = page_number_str.split('#')[0] if len(page_number_str) > 5: @@ -14578,6 +14608,8 @@ class PubServer(BaseHTTPRequestHandler): nickname = nickname.split('?')[0] if '?page=' in path: page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] if '?' in page_number_str: page_number_str = page_number_str.split('?')[0] if '#' in page_number_str: diff --git a/gemini/EN/install.gmi b/gemini/EN/install.gmi index d7f9103b6..857656d82 100644 --- a/gemini/EN/install.gmi +++ b/gemini/EN/install.gmi @@ -41,7 +41,7 @@ Paste the following: User=epicyon Group=epicyon WorkingDirectory=/opt/epicyon - ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --debug + ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open Environment=USER=epicyon Environment=PYTHONUNBUFFERED=true Restart=always diff --git a/manual/manual.epub b/manual/manual.epub index 456c01cb6..db1e3a1c6 100644 Binary files a/manual/manual.epub and b/manual/manual.epub differ diff --git a/manual/manual.html b/manual/manual.html index 21ea2b56e..bcc5a4f4e 100644 --- a/manual/manual.html +++ b/manual/manual.html @@ -141,7 +141,7 @@ class="sourceCode bash">User=epicyon Group=epicyon WorkingDirectory=/opt/epicyon -ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --debug --log_login_failures +ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --log_login_failures Environment=USER=epicyon Environment=PYTHONUNBUFFERED=true Restart=always diff --git a/manual/manual.md b/manual/manual.md index 02cf62eeb..e74b4b906 100644 --- a/manual/manual.md +++ b/manual/manual.md @@ -89,7 +89,7 @@ Type=simple User=epicyon Group=epicyon WorkingDirectory=/opt/epicyon -ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --debug --log_login_failures +ExecStart=/usr/bin/python3 /opt/epicyon/epicyon.py --port 443 --proxy 7156 --domain YOUR_DOMAIN --registration open --log_login_failures Environment=USER=epicyon Environment=PYTHONUNBUFFERED=true Restart=always diff --git a/person.py b/person.py index b44509925..f821f009c 100644 --- a/person.py +++ b/person.py @@ -988,10 +988,20 @@ def person_box_json(recent_posts_cache: {}, # Only show the header by default header_only = True + # first post in the timeline + first_post_id = '' + if ';firstpost=' in path: + first_post_id = \ + path.split(';firstpost=')[1] + first_post_id = \ + first_post_id.replace('--', '/') + # handle page numbers page_number = None if '?page=' in path: page_number = path.split('?page=')[1] + if ';' in page_number: + page_number = page_number.split(';')[0] if len(page_number) > 5: page_number = 1 if page_number == 'true': @@ -1020,12 +1030,14 @@ def person_box_json(recent_posts_cache: {}, return create_inbox(recent_posts_cache, base_dir, nickname, domain, port, http_prefix, - no_of_items, header_only, page_number) + no_of_items, header_only, page_number, + first_post_id) if boxname == 'dm': return create_dm_timeline(recent_posts_cache, base_dir, nickname, domain, port, http_prefix, - no_of_items, header_only, page_number) + no_of_items, header_only, page_number, + first_post_id) if boxname in ('tlbookmarks', 'bookmarks'): return create_bookmarks_timeline(base_dir, nickname, domain, port, http_prefix, @@ -1036,7 +1048,8 @@ def person_box_json(recent_posts_cache: {}, base_dir, nickname, domain, port, http_prefix, no_of_items, header_only, - page_number) + page_number, + first_post_id) if boxname == 'tlmedia': return create_media_timeline(base_dir, nickname, domain, port, http_prefix, no_of_items, header_only, @@ -1053,7 +1066,7 @@ def person_box_json(recent_posts_cache: {}, if boxname == 'tlblogs': return create_blogs_timeline(base_dir, nickname, domain, port, http_prefix, no_of_items, header_only, - page_number) + page_number, first_post_id) if boxname == 'outbox': return create_outbox(base_dir, nickname, domain, port, http_prefix, diff --git a/posts.py b/posts.py index 726369b4d..29ecd3261 100644 --- a/posts.py +++ b/posts.py @@ -3591,12 +3591,12 @@ def send_to_followers_thread(server, session, session_onion, session_i2p, def create_inbox(recent_posts_cache: {}, base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, items_per_page: int, header_only: bool, - page_number: int) -> {}: + page_number: int, first_post_id: str) -> {}: return _create_box_indexed(recent_posts_cache, base_dir, 'inbox', nickname, domain, port, http_prefix, items_per_page, header_only, True, - 0, False, 0, page_number) + 0, False, 0, page_number, first_post_id) def create_bookmarks_timeline(base_dir: str, @@ -3612,31 +3612,35 @@ def create_bookmarks_timeline(base_dir: str, def create_dm_timeline(recent_posts_cache: {}, base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, items_per_page: int, - header_only: bool, page_number: int) -> {}: + header_only: bool, page_number: int, + first_post_id: str) -> {}: return _create_box_indexed(recent_posts_cache, base_dir, 'dm', nickname, domain, port, http_prefix, items_per_page, - header_only, True, 0, False, 0, page_number) + header_only, True, 0, False, 0, page_number, + first_post_id) def create_replies_timeline(recent_posts_cache: {}, base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, items_per_page: int, - header_only: bool, page_number: int) -> {}: + header_only: bool, page_number: int, + first_post_id: str) -> {}: return _create_box_indexed(recent_posts_cache, base_dir, 'tlreplies', nickname, domain, port, http_prefix, items_per_page, header_only, True, - 0, False, 0, page_number) + 0, False, 0, page_number, first_post_id) def create_blogs_timeline(base_dir: str, nickname: str, domain: str, port: int, http_prefix: str, items_per_page: int, - header_only: bool, page_number: int) -> {}: + header_only: bool, page_number: int, + first_post_id: str) -> {}: return _create_box_indexed({}, base_dir, 'tlblogs', nickname, domain, port, http_prefix, items_per_page, header_only, True, - 0, False, 0, page_number) + 0, False, 0, page_number, first_post_id) def create_features_timeline(base_dir: str, @@ -3960,7 +3964,8 @@ def _create_box_indexed(recent_posts_cache: {}, items_per_page: int, header_only: bool, authorized: bool, newswire_votes_threshold: int, positive_voting: bool, - voting_time_mins: int, page_number: int) -> {}: + voting_time_mins: int, page_number: int, + first_post_id: str = '') -> {}: """Constructs the box feed for a person with the given nickname """ if not authorized or not page_number: @@ -4024,6 +4029,9 @@ def _create_box_indexed(recent_posts_cache: {}, total_posts_count = 0 posts_added_to_timeline = 0 if os.path.isfile(index_filename): + if first_post_id: + first_post_id = first_post_id.replace('--', '#') + first_post_id = first_post_id.replace('/', '#') with open(index_filename, 'r', encoding='utf-8') as index_file: posts_added_to_timeline = 0 while posts_added_to_timeline < items_per_page: @@ -4032,6 +4040,12 @@ def _create_box_indexed(recent_posts_cache: {}, if not post_filename: break + if first_post_id and total_posts_count == 0: + if first_post_id not in post_filename: + continue + total_posts_count = \ + int((page_number - 1) * items_per_page) + # Has this post passed through the newswire voting stage? if not _passed_newswire_voting(newswire_votes_threshold, base_dir, domain, @@ -4041,9 +4055,11 @@ def _create_box_indexed(recent_posts_cache: {}, continue # Skip through any posts previous to the current page - if total_posts_count < int((page_number - 1) * items_per_page): - total_posts_count += 1 - continue + if not first_post_id: + if total_posts_count < \ + int((page_number - 1) * items_per_page): + total_posts_count += 1 + continue # if this is a full path then remove the directories if '/' in post_filename: diff --git a/translations/ko.json b/translations/ko.json index 65bfc8781..3713f90fe 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -4,8 +4,8 @@ "Your browser does not support the audio tag.": "이 브라우저는 오디오 태그를 지원하지 않습니다.", "Show profile": "프로필 표시", "Show options for this person": "이 사람에 대한 옵션 표시", - "Repeat this post": "이 포스트 반복", - "Undo the repeat": "반복 실행 취소", + "Repeat this post": "이 포스트 리포스트", + "Undo the repeat": "리포스트 실행 취소", "Like this post": "이 포스트 좋아요", "Undo the like": "좋아요 취소", "Delete this post": "이 포스트 삭제", @@ -514,8 +514,8 @@ "It is done": "완료했어요", "Time Zone": "시간대", "Show who liked this post": "이 포스트를 좋아한 사람 표시", - "Show who repeated this post": "이 포스트를 반복한 사람 표시", - "Repeated by": "반복한 사람", + "Show who repeated this post": "이 포스트를 리포스트한 사람 표시", + "Repeated by": "리포스트한 사람", "Register": "등록", "Web Bots Allowed": "웹 봇 허용", "Known Search Bots": "알려진 웹 검색 봇", @@ -596,8 +596,8 @@ "devops": "devops", "Reject spam accounts": "스팸 계정 거부", "User Manual": "사용자 매뉴얼", - "Allow announces": "공지 허용", - "Send": "보내다", + "Allow announces": "리포스트 허용", + "Send": "보내기", "Minimize all images": "모든 이미지 최소화", "Edit post": "게시물 수정" } diff --git a/webapp_post.py b/webapp_post.py index 7027f8905..f29f80ab1 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -109,12 +109,24 @@ def _html_post_metadata_open_graph(domain: str, post_json_object: {}, """Returns html OpenGraph metadata for a post """ metadata = \ + " \n" + metadata += \ + " \n" + metadata += \ " \n" metadata += \ " \n" obj_json = post_json_object if has_object_dict(post_json_object): obj_json = post_json_object['object'] + if obj_json.get('id'): + metadata += " \n" + if obj_json.get('summary'): + metadata += " \n" if obj_json.get('attributedTo'): if isinstance(obj_json['attributedTo'], str): attrib = obj_json['attributedTo'] @@ -122,6 +134,10 @@ def _html_post_metadata_open_graph(domain: str, post_json_object: {}, if actor_nick: actor_domain, _ = get_domain_from_actor(attrib) actor_handle = actor_nick + '@' + actor_domain + metadata += \ + " \n" metadata += \ " \n" @@ -130,6 +146,9 @@ def _html_post_metadata_open_graph(domain: str, post_json_object: {}, " \n" if obj_json.get('published'): + metadata += " \n" metadata += \ " \n" @@ -2634,6 +2653,7 @@ def html_individual_post(recent_posts_cache: {}, max_recent_posts: int, system_language) header_str = html_header_with_external_style(css_filename, instance_title, metadata_str) + return header_str + post_str + html_footer() diff --git a/webapp_timeline.py b/webapp_timeline.py index 645b2861c..73d213670 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -948,6 +948,8 @@ def html_timeline(default_timeline: str, if box_name == 'inbox': use_cache_only = True + last_post_id = '' + if timeline_json: # if this is the media timeline then add an extra gallery container if box_name == 'tlmedia': @@ -981,6 +983,7 @@ def html_timeline(default_timeline: str, curr_tl_str, box_name, page_number) + last_post_id = post_id _log_timeline_timing(enable_timing_log, timeline_start_time, box_name, '10') @@ -1027,6 +1030,8 @@ def html_timeline(default_timeline: str, if curr_tl_str: if curr_tl_str not in tl_str: + last_post_id = \ + remove_id_ending(item['id']).replace('/', '#') item_ctr += 1 tl_str += text_mode_separator + curr_tl_str if separator_str: @@ -1041,11 +1046,14 @@ def html_timeline(default_timeline: str, # page down arrow if item_ctr > 0: tl_str += text_mode_separator + first_post = '' + if last_post_id: + first_post = ';firstpost=' + last_post_id.replace('#', '--') tl_str += \ '
\n' + \ '
\n' + \ ' ' + \ '