Moved follows on profile screen

merge-requests/30/head
Bob Mottram 2022-11-27 22:59:24 +00:00
parent 1d15e7f94f
commit ea50006402
30 changed files with 359 additions and 29 deletions

160
daemon.py
View File

@ -415,6 +415,7 @@ from crawlers import load_known_web_bots
from qrcode import save_domain_qrcode
from importFollowing import run_import_following_watchdog
from maps import map_format_from_tagmaps_path
from relationships import get_moved_feed
import os
@ -14363,6 +14364,145 @@ class PubServer(BaseHTTPRequestHandler):
return True
return False
def _show_moved_feed(self, authorized: bool,
calling_domain: str, referer_domain: str,
path: str, base_dir: str, http_prefix: str,
domain: str, port: int, getreq_start_time,
proxy_type: str, cookie: str,
debug: str, curr_session) -> bool:
"""Shows the moved feed
"""
following = \
get_moved_feed(base_dir, domain, port, path,
http_prefix, authorized, FOLLOWS_PER_PAGE)
if following:
if self._request_http():
page_number = 1
if '?page=' not in path:
search_path = path
# get a page of following, not the summary
following = \
get_following_feed(base_dir,
domain,
port,
path + '?page=true',
http_prefix,
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:
page_number_str = "1"
if page_number_str.isdigit():
page_number = int(page_number_str)
search_path = path.split('?page=')[0]
get_person = \
person_lookup(domain,
search_path.replace('/moved', ''),
base_dir)
if get_person:
curr_session = \
self._establish_session("show_moved_feed",
curr_session, proxy_type)
if not curr_session:
self._404()
return True
access_keys = self.server.access_keys
city = None
timezone = None
if '/users/' in path:
nickname = path.split('/users/')[1]
if '/' in nickname:
nickname = nickname.split('/')[0]
if self.server.key_shortcuts.get(nickname):
access_keys = \
self.server.key_shortcuts[nickname]
city = get_spoofed_city(self.server.city,
base_dir, nickname, domain)
if self.server.account_timezone.get(nickname):
timezone = \
self.server.account_timezone.get(nickname)
content_license_url = \
self.server.content_license_url
shared_items_federated_domains = \
self.server.shared_items_federated_domains
bold_reading = False
if self.server.bold_reading.get(nickname):
bold_reading = True
msg = \
html_profile(self.server.signing_priv_key_pem,
self.server.rss_icon_at_top,
self.server.icons_as_buttons,
self.server.default_timeline,
self.server.recent_posts_cache,
self.server.max_recent_posts,
self.server.translate,
self.server.project_version,
base_dir, http_prefix,
authorized,
get_person, 'moved',
curr_session,
self.server.cached_webfingers,
self.server.person_cache,
self.server.yt_replace_domain,
self.server.twitter_replacement_domain,
self.server.show_published_date_only,
self.server.newswire,
self.server.theme_name,
self.server.dormant_months,
self.server.peertube_instances,
self.server.allow_local_network_access,
self.server.text_mode_banner,
self.server.debug,
access_keys, city,
self.server.system_language,
self.server.max_like_count,
shared_items_federated_domains,
following,
page_number,
FOLLOWS_PER_PAGE,
self.server.cw_lists,
self.server.lists_enabled,
content_license_url,
timezone, bold_reading).encode('utf-8')
msglen = len(msg)
self._set_headers('text/html',
msglen, cookie, calling_domain, False)
self._write(msg)
fitness_performance(getreq_start_time,
self.server.fitness,
'_GET', '_show_moved_feed',
debug)
return True
else:
if self._secure_mode(curr_session, proxy_type):
msg_str = json.dumps(following,
ensure_ascii=False)
msg_str = self._convert_domains(calling_domain,
referer_domain,
msg_str)
msg = msg_str.encode('utf-8')
msglen = len(msg)
accept_str = self.headers['Accept']
protocol_str = \
get_json_content_from_accept(accept_str)
self._set_headers(protocol_str, msglen,
None, calling_domain, False)
self._write(msg)
fitness_performance(getreq_start_time,
self.server.fitness,
'_GET', '_show_moved_feed json',
debug)
else:
self._404()
return True
return False
def _show_followers_feed(self, authorized: bool,
calling_domain: str, referer_domain: str,
path: str, base_dir: str, http_prefix: str,
@ -19147,6 +19287,24 @@ class PubServer(BaseHTTPRequestHandler):
'_GET', 'show profile 3 done',
self.server.debug)
if self._show_moved_feed(authorized,
calling_domain, referer_domain,
self.path,
self.server.base_dir,
self.server.http_prefix,
self.server.domain,
self.server.port,
getreq_start_time,
proxy_type,
cookie, self.server.debug,
curr_session):
self.server.getreq_busy = False
return
fitness_performance(getreq_start_time, self.server.fitness,
'_GET', 'show moved 4 done',
self.server.debug)
if self._show_followers_feed(authorized,
calling_domain, referer_domain,
self.path,
@ -19162,7 +19320,7 @@ class PubServer(BaseHTTPRequestHandler):
return
fitness_performance(getreq_start_time, self.server.fitness,
'_GET', 'show profile 4 done',
'_GET', 'show profile 5 done',
self.server.debug)
# look up a person

View File

@ -7,9 +7,13 @@ __email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
import os
from utils import acct_dir
from utils import valid_nickname
from utils import get_full_domain
from utils import local_actor_url
from utils import remove_domain_port
from utils import remove_eol
def get_moved_accounts(base_dir: str, nickname: str, domain: str,
@ -51,3 +55,122 @@ def get_moved_accounts(base_dir: str, nickname: str, domain: str,
if refollow_dict.get(handle):
result[handle] = refollow_dict[handle]
return result
def get_moved_feed(base_dir: str, domain: str, port: int, path: str,
http_prefix: str, authorized: bool,
follows_per_page=12) -> {}:
"""Returns the moved accounts feed from GET requests.
"""
# Show a small number of follows to non-authorized viewers
if not authorized:
follows_per_page = 6
if '/moved' not in path:
return None
# handle page numbers
header_only = True
page_number = None
if '?page=' in path:
page_number = path.split('?page=')[1]
if len(page_number) > 5:
page_number = "1"
if page_number == 'true' or not authorized:
page_number = 1
else:
try:
page_number = int(page_number)
except BaseException:
print('EX: get_moved_feed unable to convert to int ' +
str(page_number))
path = path.split('?page=')[0]
header_only = False
if not path.endswith('/moved'):
return None
nickname = None
if path.startswith('/users/'):
nickname = \
path.replace('/users/', '', 1).replace('/moved', '')
if path.startswith('/@'):
nickname = path.replace('/@', '', 1).replace('/moved', '')
if not nickname:
return None
if not valid_nickname(domain, nickname):
return None
domain = get_full_domain(domain, port)
lines = get_moved_accounts(base_dir, nickname, domain,
'following.txt')
if header_only:
first_str = \
local_actor_url(http_prefix, nickname, domain) + \
'/moved?page=1'
id_str = \
local_actor_url(http_prefix, nickname, domain) + '/moved'
total_str = str(len(lines.items()))
following = {
'@context': 'https://www.w3.org/ns/activitystreams',
'first': first_str,
'id': id_str,
'totalItems': total_str,
'type': 'OrderedCollection'
}
return following
if not page_number:
page_number = 1
next_page_number = int(page_number + 1)
id_str = \
local_actor_url(http_prefix, nickname, domain) + \
'/moved?page=' + str(page_number)
part_of_str = \
local_actor_url(http_prefix, nickname, domain) + '/moved'
following = {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': id_str,
'orderedItems': [],
'partOf': part_of_str,
'totalItems': 0,
'type': 'OrderedCollectionPage'
}
handle_domain = domain
handle_domain = remove_domain_port(handle_domain)
accounts_dir = acct_dir(base_dir, nickname, handle_domain)
filename = accounts_dir + '/moved.txt'
if not os.path.isfile(filename):
return following
curr_page = 1
page_ctr = 0
total_ctr = 0
for handle, new_handle in lines.items():
# nickname@domain
page_ctr += 1
total_ctr += 1
if curr_page == page_number:
line2_lower = handle.lower()
line2 = remove_eol(line2_lower)
nick = line2.split('@')[0]
dom = line2.split('@')[1]
if not nick.startswith('!'):
# person actor
url = local_actor_url(http_prefix, nick, dom)
else:
# group actor
url = http_prefix + '://' + dom + '/c/' + nick
following['orderedItems'].append(url)
if page_ctr >= follows_per_page:
page_ctr = 0
curr_page += 1
following['totalItems'] = total_ctr
last_page = int(total_ctr / follows_per_page)
last_page = max(last_page, 1)
if next_page_number > last_page:
following['next'] = \
local_actor_url(http_prefix, nickname, domain) + \
'/moved?page=' + str(last_page)
return following

View File

@ -602,5 +602,6 @@
"Minimize all images": "تصغير كل الصور",
"Edit post": "تعديل المنشور",
"Preview posts on profile screen": "معاينة المشاركات على شاشة الملف الشخصي",
"Reverse timelines": "عكس الجداول الزمنية"
"Reverse timelines": "عكس الجداول الزمنية",
"Moved": "انتقل"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "সমস্ত ছবি ছোট করুন",
"Edit post": "পোস্ট সম্পাদনা করুন",
"Preview posts on profile screen": "প্রোফাইল স্ক্রিনে পোস্টের পূর্বরূপ দেখুন",
"Reverse timelines": "বিপরীত সময়রেখা"
"Reverse timelines": "বিপরীত সময়রেখা",
"Moved": "সরানো হয়েছে"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Minimitzar totes les imatges",
"Edit post": "Edita la publicació",
"Preview posts on profile screen": "Previsualitza les publicacions a la pantalla del perfil",
"Reverse timelines": "Cronologia inversa"
"Reverse timelines": "Cronologia inversa",
"Moved": "Mogut"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Lleihau pob delwedd",
"Edit post": "Golygu post",
"Preview posts on profile screen": "Rhagolwg postiadau ar sgrin proffil",
"Reverse timelines": "Gwrthdroi llinellau amser"
"Reverse timelines": "Gwrthdroi llinellau amser",
"Moved": "Wedi symud"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Alle Bilder minimieren",
"Edit post": "Beitrag bearbeiten",
"Preview posts on profile screen": "Vorschau von Beiträgen auf dem Profilbildschirm",
"Reverse timelines": "Umgekehrte Zeitlinien"
"Reverse timelines": "Umgekehrte Zeitlinien",
"Moved": "Gerührt"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Ελαχιστοποίηση όλων των εικόνων",
"Edit post": "Επεξεργασία ανάρτησης",
"Preview posts on profile screen": "Προεπισκόπηση αναρτήσεων στην οθόνη προφίλ",
"Reverse timelines": "Αντίστροφα χρονοδιαγράμματα"
"Reverse timelines": "Αντίστροφα χρονοδιαγράμματα",
"Moved": "Μετακινήθηκε"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Minimize all images",
"Edit post": "Edit post",
"Preview posts on profile screen": "Preview posts on profile screen",
"Reverse timelines": "Reverse timelines"
"Reverse timelines": "Reverse timelines",
"Moved": "Moved"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Minimizar todas las imágenes",
"Edit post": "Editar post",
"Preview posts on profile screen": "Vista previa de publicaciones en la pantalla de perfil",
"Reverse timelines": "Líneas de tiempo inversas"
"Reverse timelines": "Líneas de tiempo inversas",
"Moved": "Movida"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "تمام تصاویر را به حداقل برسانید",
"Edit post": "ویرایش پست",
"Preview posts on profile screen": "پیش نمایش پست ها در صفحه نمایه",
"Reverse timelines": "جدول های زمانی معکوس"
"Reverse timelines": "جدول های زمانی معکوس",
"Moved": "منتقل شد"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Réduire toutes les images",
"Edit post": "Modifier le message",
"Preview posts on profile screen": "Prévisualiser les messages sur l'écran de profil",
"Reverse timelines": "Chronologies inversées"
"Reverse timelines": "Chronologies inversées",
"Moved": "Déplacée"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Íoslaghdaigh gach íomhá",
"Edit post": "Cuir postáil in eagar",
"Preview posts on profile screen": "Réamhamhairc postálacha ar an scáileán próifíle",
"Reverse timelines": "Amlínte droim ar ais"
"Reverse timelines": "Amlínte droim ar ais",
"Moved": "Ar athraíodh a ionad"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "सभी छवियों को छोटा करें",
"Edit post": "संपादित पोस्ट",
"Preview posts on profile screen": "प्रोफ़ाइल स्क्रीन पर पोस्ट का पूर्वावलोकन करें",
"Reverse timelines": "रिवर्स टाइमलाइन"
"Reverse timelines": "रिवर्स टाइमलाइन",
"Moved": "ले जाया गया"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Riduci a icona tutte le immagini",
"Edit post": "Modifica post",
"Preview posts on profile screen": "Visualizza l'anteprima dei post nella schermata del profilo",
"Reverse timelines": "Invertire le tempistiche"
"Reverse timelines": "Invertire le tempistiche",
"Moved": "Mosso"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "すべての画像を最小化",
"Edit post": "投稿を編集",
"Preview posts on profile screen": "プロフィール画面で投稿をプレビュー",
"Reverse timelines": "逆タイムライン"
"Reverse timelines": "逆タイムライン",
"Moved": "移動しました"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "모든 이미지 최소화",
"Edit post": "게시물 수정",
"Preview posts on profile screen": "프로필 화면에서 게시물 미리보기",
"Reverse timelines": "역방향 타임라인"
"Reverse timelines": "역방향 타임라인",
"Moved": "움직이는"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Hemî wêneyan kêm bikin",
"Edit post": "Biguherîne post",
"Preview posts on profile screen": "Mesajên li ser ekrana profîlê pêşdîtin",
"Reverse timelines": "Reverse timelines"
"Reverse timelines": "Reverse timelines",
"Moved": "Moved"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Alle afbeeldingen minimaliseren",
"Edit post": "Bericht bewerken",
"Preview posts on profile screen": "Bekijk berichten op het profielscherm",
"Reverse timelines": "Omgekeerde tijdlijnen"
"Reverse timelines": "Omgekeerde tijdlijnen",
"Moved": "Verhuisd"
}

View File

@ -598,5 +598,6 @@
"Minimize all images": "Minimize all images",
"Edit post": "Edit post",
"Preview posts on profile screen": "Preview posts on profile screen",
"Reverse timelines": "Reverse timelines"
"Reverse timelines": "Reverse timelines",
"Moved": "Moved"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Zminimalizuj wszystkie obrazy",
"Edit post": "Edytuj post",
"Preview posts on profile screen": "Podgląd postów na ekranie profilu",
"Reverse timelines": "Odwróć ramy czasowe"
"Reverse timelines": "Odwróć ramy czasowe",
"Moved": "Przeniósł"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Minimize todas as imagens",
"Edit post": "Editar post",
"Preview posts on profile screen": "Visualizar postagens na tela do perfil",
"Reverse timelines": "Cronogramas reversos"
"Reverse timelines": "Cronogramas reversos",
"Moved": "Mudou-se"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Свернуть все изображения",
"Edit post": "Редактировать сообщение",
"Preview posts on profile screen": "Предварительный просмотр сообщений на экране профиля",
"Reverse timelines": "Обратные сроки"
"Reverse timelines": "Обратные сроки",
"Moved": "Взолнованный"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Punguza picha zote",
"Edit post": "Badilisha chapisho",
"Preview posts on profile screen": "Hakiki machapisho kwenye skrini ya wasifu",
"Reverse timelines": "Обратные сроки"
"Reverse timelines": "Обратные сроки",
"Moved": "Imehamishwa"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Tüm görüntüleri simge durumuna küçült",
"Edit post": "Gönderiyi düzenle",
"Preview posts on profile screen": "Gönderileri profil ekranında önizleyin",
"Reverse timelines": "Обратные сроки"
"Reverse timelines": "Обратные сроки",
"Moved": "Etkilenmiş"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "Згорнути всі зображення",
"Edit post": "Редагувати пост",
"Preview posts on profile screen": "Попередній перегляд дописів на екрані профілю",
"Reverse timelines": "Обратные сроки"
"Reverse timelines": "Обратные сроки",
"Moved": "Переїхав"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "מינאַמייז אַלע בילדער",
"Edit post": "רעדאַגירן פּאָסטן",
"Preview posts on profile screen": "פאָרויסיקע ווייַזונג אַרטיקלען אויף פּראָפיל פאַרשטעלן",
"Reverse timelines": "פאַרקערט טיימליינז"
"Reverse timelines": "פאַרקערט טיימליינז",
"Moved": "אריבערגעפארן"
}

View File

@ -602,5 +602,6 @@
"Minimize all images": "最小化所有图像",
"Edit post": "编辑帖子",
"Preview posts on profile screen": "在个人资料屏幕上预览帖子",
"Reverse timelines": "倒转时间线"
"Reverse timelines": "倒转时间线",
"Moved": "אריבערגעפארן"
}

View File

@ -2240,7 +2240,7 @@ def _get_reserved_words() -> str:
'minimal', 'search', 'eventdelete',
'searchemoji', 'catalog', 'conversationId',
'mention', 'http', 'https', 'ipfs', 'ipns',
'ontologies', 'data', 'postedit')
'ontologies', 'data', 'postedit', 'moved')
def get_nickname_validation_pattern() -> str:

View File

@ -680,6 +680,8 @@ def html_profile(signing_priv_key_pem: str,
profile_description = standardize_text(profile_description)
posts_button = 'button'
following_button = 'button'
moved_button = 'button'
moved_button = 'button'
followers_button = 'button'
roles_button = 'button'
skills_button = 'button'
@ -689,6 +691,8 @@ def html_profile(signing_priv_key_pem: str,
posts_button = 'buttonselected'
elif selected == 'following':
following_button = 'buttonselected'
elif selected == 'moved':
moved_button = 'buttonselected'
elif selected == 'followers':
followers_button = 'buttonselected'
elif selected == 'roles':
@ -1032,6 +1036,12 @@ def html_profile(signing_priv_key_pem: str,
'<button class="' + followers_button + \
'"><span>' + followers_str + ' </span></button></a>'
if not is_group:
if authorized:
profile_str += \
' <a href="' + users_path + \
'/moved#buttonheader" tabindex="2">' + \
'<button class="' + moved_button + '"><span>' + \
translate['Moved'] + ' </span></button></a>'
profile_str += \
' <a href="' + users_path + \
'/roles#buttonheader" tabindex="2">' + \
@ -1109,6 +1119,19 @@ def html_profile(signing_priv_key_pem: str,
max_items_per_page,
dormant_months, debug,
signing_priv_key_pem)
if authorized and selected == 'moved':
profile_str += \
_html_profile_following(translate, base_dir, http_prefix,
authorized, nickname,
domain, session,
cached_webfingers,
person_cache, extra_json,
project_version, ["unfollow"],
selected,
users_path, page_number,
max_items_per_page,
dormant_months, debug,
signing_priv_key_pem)
if selected == 'followers':
profile_str += \
_html_profile_following(translate, base_dir, http_prefix,