diff --git a/daemon.py b/daemon.py index 4da348bde..77642227b 100644 --- a/daemon.py +++ b/daemon.py @@ -134,10 +134,10 @@ from webapp_timeline import htmlInboxBlogs from webapp_timeline import htmlInboxNews from webapp_timeline import htmlOutbox from webapp_timeline import htmlModeration +from webapp_create_post import htmlNewPost from webapp import htmlLogin from webapp import htmlSuspended from webapp import htmlGetLoginCredentials -from webapp import htmlNewPost from webapp import htmlFollowConfirm from webapp import htmlUnfollowConfirm from webapp import htmlEditNewsPost diff --git a/webapp.py b/webapp.py index 01122e489..f51ff06ff 100644 --- a/webapp.py +++ b/webapp.py @@ -14,14 +14,12 @@ from utils import getNicknameFromActor from utils import getDomainFromActor from utils import locatePost from utils import noOfAccounts -from utils import isPublicPostFromUrl from utils import loadJson from utils import getConfigParam from posts import isEditor from shares import getValidSharedItemID from webapp_utils import getAltPath from webapp_utils import getIconsDir -from webapp_utils import getBannerFile from webapp_utils import htmlHeader from webapp_utils import htmlFooter from webapp_post import individualPostAsHtml @@ -53,46 +51,6 @@ def htmlFollowingList(cssCache: {}, baseDir: str, return '' -def htmlFollowingDataList(baseDir: str, nickname: str, - domain: str, domainFull: str) -> str: - """Returns a datalist of handles being followed - """ - listStr = '\n' - followingFilename = \ - baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt' - if os.path.isfile(followingFilename): - with open(followingFilename, 'r') as followingFile: - msg = followingFile.read() - # add your own handle, so that you can send DMs - # to yourself as reminders - msg += nickname + '@' + domainFull + '\n' - # include petnames - petnamesFilename = \ - baseDir + '/accounts/' + \ - nickname + '@' + domain + '/petnames.txt' - if os.path.isfile(petnamesFilename): - followingList = [] - with open(petnamesFilename, 'r') as petnamesFile: - petStr = petnamesFile.read() - # extract each petname and append it - petnamesList = petStr.split('\n') - for pet in petnamesList: - followingList.append(pet.split(' ')[0]) - # add the following.txt entries - followingList += msg.split('\n') - else: - # no petnames list exists - just use following.txt - followingList = msg.split('\n') - followingList.sort() - if followingList: - for followingAddress in followingList: - if followingAddress: - listStr += \ - '\n' - listStr += '\n' - return listStr - - def htmlModerationInfo(cssCache: {}, translate: {}, baseDir: str, httpPrefix: str) -> str: msgStr1 = \ @@ -524,684 +482,6 @@ def htmlSuspended(cssCache: {}, baseDir: str) -> str: return suspendedForm -def htmlNewPostDropDown(scopeIcon: str, scopeDescription: str, - replyStr: str, - translate: {}, - iconsDir: str, - showPublicOnDropdown: bool, - defaultTimeline: str, - pathBase: str, - dropdownNewPostSuffix: str, - dropdownNewBlogSuffix: str, - dropdownUnlistedSuffix: str, - dropdownFollowersSuffix: str, - dropdownDMSuffix: str, - dropdownReminderSuffix: str, - dropdownEventSuffix: str, - dropdownReportSuffix: str) -> str: - """Returns the html for a drop down list of new post types - """ - dropDownContent = '
\n' - dropDownContent += ' \n' - dropDownContent += ' \n' - dropDownContent += ' \n' - dropDownContent += '
\n' - return dropDownContent - - -def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {}, - baseDir: str, httpPrefix: str, - path: str, inReplyTo: str, - mentions: [], - reportUrl: str, pageNumber: int, - nickname: str, domain: str, - domainFull: str, - defaultTimeline: str, newswire: {}) -> str: - """New post screen - """ - iconsDir = getIconsDir(baseDir) - replyStr = '' - - showPublicOnDropdown = True - messageBoxHeight = 400 - - # filename of the banner shown at the top - bannerFile, bannerFilename = getBannerFile(baseDir, nickname, domain) - - if not path.endswith('/newshare'): - if not path.endswith('/newreport'): - if not inReplyTo or path.endswith('/newreminder'): - newPostText = '

' + \ - translate['Write your post text below.'] + '

\n' - else: - newPostText = \ - '

' + \ - translate['Write your reply to'] + \ - ' ' + \ - translate['this post'] + '

\n' - replyStr = '\n' - - # if replying to a non-public post then also make - # this post non-public - if not isPublicPostFromUrl(baseDir, nickname, domain, - inReplyTo): - newPostPath = path - if '?' in newPostPath: - newPostPath = newPostPath.split('?')[0] - if newPostPath.endswith('/newpost'): - path = path.replace('/newpost', '/newfollowers') - elif newPostPath.endswith('/newunlisted'): - path = path.replace('/newunlisted', '/newfollowers') - showPublicOnDropdown = False - else: - newPostText = \ - '

' + \ - translate['Write your report below.'] + '

\n' - - # custom report header with any additional instructions - if os.path.isfile(baseDir + '/accounts/report.txt'): - with open(baseDir + '/accounts/report.txt', 'r') as file: - customReportText = file.read() - if '

' not in customReportText: - customReportText = \ - '

' + \ - customReportText + '

\n' - repStr = '

' - customReportText = \ - customReportText.replace('

', repStr) - newPostText += customReportText - - idx = 'This message only goes to moderators, even if it ' + \ - 'mentions other fediverse addresses.' - newPostText += \ - '

' + translate[idx] + '

\n' + \ - '

' + translate['Also see'] + \ - ' ' + \ - translate['Terms of Service'] + '

\n' - else: - newPostText = \ - '

' + \ - translate['Enter the details for your shared item below.'] + \ - '

\n' - - if path.endswith('/newquestion'): - newPostText = \ - '

' + \ - translate['Enter the choices for your question below.'] + \ - '

\n' - - if os.path.isfile(baseDir + '/accounts/newpost.txt'): - with open(baseDir + '/accounts/newpost.txt', 'r') as file: - newPostText = \ - '

' + file.read() + '

\n' - - cssFilename = baseDir + '/epicyon-profile.css' - if os.path.isfile(baseDir + '/epicyon.css'): - cssFilename = baseDir + '/epicyon.css' - - newPostCSS = getCSS(baseDir, cssFilename, cssCache) - if newPostCSS: - if httpPrefix != 'https': - newPostCSS = newPostCSS.replace('https://', - httpPrefix + '://') - - if '?' in path: - path = path.split('?')[0] - pathBase = path.replace('/newreport', '').replace('/newpost', '') - pathBase = pathBase.replace('/newblog', '').replace('/newshare', '') - pathBase = pathBase.replace('/newunlisted', '') - pathBase = pathBase.replace('/newevent', '') - pathBase = pathBase.replace('/newreminder', '') - pathBase = pathBase.replace('/newfollowers', '').replace('/newdm', '') - - newPostImageSection = '
' - if not path.endswith('/newevent'): - newPostImageSection += \ - ' \n' - else: - newPostImageSection += \ - ' \n' - newPostImageSection += \ - ' \n' - - if path.endswith('/newevent'): - newPostImageSection += \ - ' \n' - newPostImageSection += \ - ' \n' - else: - newPostImageSection += \ - ' \n' - newPostImageSection += '
\n' - - scopeIcon = 'scope_public.png' - scopeDescription = translate['Public'] - placeholderSubject = \ - translate['Subject or Content Warning (optional)'] + '...' - placeholderMentions = '' - if inReplyTo: - # mentionsAndContent = getMentionsString(content) - placeholderMentions = \ - translate['Replying to'] + '...' - placeholderMessage = translate['Write something'] + '...' - extraFields = '' - endpoint = 'newpost' - if path.endswith('/newblog'): - placeholderSubject = translate['Title'] - scopeIcon = 'scope_blog.png' - if defaultTimeline != 'tlnews': - scopeDescription = translate['Blog'] - else: - scopeDescription = translate['Article'] - endpoint = 'newblog' - elif path.endswith('/newunlisted'): - scopeIcon = 'scope_unlisted.png' - scopeDescription = translate['Unlisted'] - endpoint = 'newunlisted' - elif path.endswith('/newfollowers'): - scopeIcon = 'scope_followers.png' - scopeDescription = translate['Followers'] - endpoint = 'newfollowers' - elif path.endswith('/newdm'): - scopeIcon = 'scope_dm.png' - scopeDescription = translate['DM'] - endpoint = 'newdm' - elif path.endswith('/newreminder'): - scopeIcon = 'scope_reminder.png' - scopeDescription = translate['Reminder'] - endpoint = 'newreminder' - elif path.endswith('/newevent'): - scopeIcon = 'scope_event.png' - scopeDescription = translate['Event'] - endpoint = 'newevent' - placeholderSubject = translate['Event name'] - placeholderMessage = translate['Describe the event'] + '...' - elif path.endswith('/newreport'): - scopeIcon = 'scope_report.png' - scopeDescription = translate['Report'] - endpoint = 'newreport' - elif path.endswith('/newquestion'): - scopeIcon = 'scope_question.png' - scopeDescription = translate['Question'] - placeholderMessage = translate['Enter your question'] + '...' - endpoint = 'newquestion' - extraFields = '
\n' - extraFields += '
\n' - for questionCtr in range(8): - extraFields += \ - '
\n' - extraFields += \ - '
\n' - extraFields += '
' - elif path.endswith('/newshare'): - scopeIcon = 'scope_share.png' - scopeDescription = translate['Shared Item'] - placeholderSubject = translate['Name of the shared item'] + '...' - placeholderMessage = \ - translate['Description of the item being shared'] + '...' - endpoint = 'newshare' - extraFields = '
\n' - extraFields += \ - ' \n' - extraFields += \ - ' \n' - extraFields += \ - '
\n' - extraFields += \ - ' \n' - extraFields += \ - '
\n' - extraFields += ' \n' - extraFields += '
\n' - extraFields += '
\n' - extraFields += \ - '\n' - extraFields += '\n' - extraFields += '
\n' - - citationsStr = '' - if endpoint == 'newblog': - citationsFilename = \ - baseDir + '/accounts/' + \ - nickname + '@' + domain + '/.citations.txt' - if os.path.isfile(citationsFilename): - citationsStr = '
\n' - citationsStr += '

\n' - citationsStr += ' \n' - citationsStr += '
\n' - - dateAndLocation = '' - if endpoint != 'newshare' and \ - endpoint != 'newreport' and \ - endpoint != 'newquestion': - dateAndLocation = '
\n' - - if endpoint == 'newevent': - # event status - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - # maximum attendees - dateAndLocation += '\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - # event joining options - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - # Event posts don't allow replies - they're just an announcement. - # They also have a few more checkboxes - dateAndLocation += \ - '

\n' - dateAndLocation += \ - '

' + \ - '

\n' - else: - dateAndLocation += \ - '

\n' - - if not inReplyTo and endpoint != 'newevent': - dateAndLocation += \ - '

\n' - - if endpoint != 'newevent': - dateAndLocation += \ - '

\n' - # select a date and time for this post - dateAndLocation += '\n' - dateAndLocation += '\n' - dateAndLocation += '

\n' - else: - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += \ - '

\n' - # select start time for the event - dateAndLocation += '\n' - dateAndLocation += '\n' - dateAndLocation += '

\n' - # select end time for the event - dateAndLocation += \ - '
\n' - dateAndLocation += '\n' - dateAndLocation += '\n' - dateAndLocation += '\n' - - if endpoint == 'newevent': - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += \ - ' \n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - if endpoint == 'newevent': - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - dateAndLocation += '\n' - dateAndLocation += '
\n' - - newPostForm = htmlHeader(cssFilename, newPostCSS) - - newPostForm += \ - '\n' - newPostForm += '\n' - - mentionsStr = '' - for m in mentions: - mentionNickname = getNicknameFromActor(m) - if not mentionNickname: - continue - mentionDomain, mentionPort = getDomainFromActor(m) - if not mentionDomain: - continue - if mentionPort: - mentionsHandle = \ - '@' + mentionNickname + '@' + \ - mentionDomain + ':' + str(mentionPort) - else: - mentionsHandle = '@' + mentionNickname + '@' + mentionDomain - if mentionsHandle not in mentionsStr: - mentionsStr += mentionsHandle + ' ' - - # build suffixes so that any replies or mentions are - # preserved when switching between scopes - dropdownNewPostSuffix = '/newpost' - dropdownNewBlogSuffix = '/newblog' - dropdownUnlistedSuffix = '/newunlisted' - dropdownFollowersSuffix = '/newfollowers' - dropdownDMSuffix = '/newdm' - dropdownEventSuffix = '/newevent' - dropdownReminderSuffix = '/newreminder' - dropdownReportSuffix = '/newreport' - if inReplyTo or mentions: - dropdownNewPostSuffix = '' - dropdownNewBlogSuffix = '' - dropdownUnlistedSuffix = '' - dropdownFollowersSuffix = '' - dropdownDMSuffix = '' - dropdownEventSuffix = '' - dropdownReminderSuffix = '' - dropdownReportSuffix = '' - if inReplyTo: - dropdownNewPostSuffix += '?replyto=' + inReplyTo - dropdownNewBlogSuffix += '?replyto=' + inReplyTo - dropdownUnlistedSuffix += '?replyto=' + inReplyTo - dropdownFollowersSuffix += '?replyfollowers=' + inReplyTo - dropdownDMSuffix += '?replydm=' + inReplyTo - for mentionedActor in mentions: - dropdownNewPostSuffix += '?mention=' + mentionedActor - dropdownNewBlogSuffix += '?mention=' + mentionedActor - dropdownUnlistedSuffix += '?mention=' + mentionedActor - dropdownFollowersSuffix += '?mention=' + mentionedActor - dropdownDMSuffix += '?mention=' + mentionedActor - dropdownReportSuffix += '?mention=' + mentionedActor - - dropDownContent = '' - if not reportUrl: - dropDownContent = \ - htmlNewPostDropDown(scopeIcon, scopeDescription, - replyStr, - translate, - iconsDir, - showPublicOnDropdown, - defaultTimeline, - pathBase, - dropdownNewPostSuffix, - dropdownNewBlogSuffix, - dropdownUnlistedSuffix, - dropdownFollowersSuffix, - dropdownDMSuffix, - dropdownReminderSuffix, - dropdownEventSuffix, - dropdownReportSuffix) - else: - mentionsStr = 'Re: ' + reportUrl + '\n\n' + mentionsStr - - newPostForm += \ - '
\n' - newPostForm += '
\n' - newPostForm += \ - ' \n' - newPostForm += '
\n' - newPostForm += ' \n' - newPostForm += '\n' - - newPostForm += \ - ' \n' - newPostForm += ' \n' - newPostForm += '
' + dropDownContent + '' + \
-        translate['Search for emoji'] + '
\n' - newPostForm += '
\n' - - newPostForm += '
\n' - - # newPostForm += \ - # ' \n' - - # for a new blog if newswire items exist then add a citations button - if newswire and path.endswith('/newblog'): - newPostForm += \ - ' \n' - - newPostForm += \ - ' \n' - - newPostForm += '
\n' - - newPostForm += replyStr - if mediaInstance and not replyStr: - newPostForm += newPostImageSection - - newPostForm += \ - '
' - newPostForm += ' ' - newPostForm += '' - - selectedStr = ' selected' - if inReplyTo or endpoint == 'newdm': - if inReplyTo: - newPostForm += \ - '
\n' - else: - newPostForm += \ - ' ' \ - ' 📄
\n' - newPostForm += \ - ' \n' - newPostForm += \ - htmlFollowingDataList(baseDir, nickname, domain, domainFull) - newPostForm += '' - selectedStr = '' - - newPostForm += \ - '
' - if mediaInstance: - messageBoxHeight = 200 - - if endpoint == 'newquestion': - messageBoxHeight = 100 - elif endpoint == 'newblog': - messageBoxHeight = 800 - - newPostForm += \ - ' \n' - newPostForm += extraFields + citationsStr + dateAndLocation - if not mediaInstance or replyStr: - newPostForm += newPostImageSection - newPostForm += '
\n' - newPostForm += '
\n' - - if not reportUrl: - newPostForm = \ - newPostForm.replace('', '') - - newPostForm += htmlFooter() - return newPostForm - - def htmlRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str, actor: str, shareName: str, callingDomain: str) -> str: diff --git a/webapp_create_post.py b/webapp_create_post.py new file mode 100644 index 000000000..b69edc7ee --- /dev/null +++ b/webapp_create_post.py @@ -0,0 +1,735 @@ +__filename__ = "webapp_create_post.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.1.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@freedombone.net" +__status__ = "Production" + +import os +from utils import isPublicPostFromUrl +from utils import getCSS +from utils import getNicknameFromActor +from utils import getDomainFromActor +from webapp_utils import getIconsDir +from webapp_utils import getBannerFile +from webapp_utils import htmlHeader +from webapp_utils import htmlFooter + + +def htmlFollowingDataList(baseDir: str, nickname: str, + domain: str, domainFull: str) -> str: + """Returns a datalist of handles being followed + """ + listStr = '\n' + followingFilename = \ + baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt' + if os.path.isfile(followingFilename): + with open(followingFilename, 'r') as followingFile: + msg = followingFile.read() + # add your own handle, so that you can send DMs + # to yourself as reminders + msg += nickname + '@' + domainFull + '\n' + # include petnames + petnamesFilename = \ + baseDir + '/accounts/' + \ + nickname + '@' + domain + '/petnames.txt' + if os.path.isfile(petnamesFilename): + followingList = [] + with open(petnamesFilename, 'r') as petnamesFile: + petStr = petnamesFile.read() + # extract each petname and append it + petnamesList = petStr.split('\n') + for pet in petnamesList: + followingList.append(pet.split(' ')[0]) + # add the following.txt entries + followingList += msg.split('\n') + else: + # no petnames list exists - just use following.txt + followingList = msg.split('\n') + followingList.sort() + if followingList: + for followingAddress in followingList: + if followingAddress: + listStr += \ + '\n' + listStr += '\n' + return listStr + + +def htmlNewPostDropDown(scopeIcon: str, scopeDescription: str, + replyStr: str, + translate: {}, + iconsDir: str, + showPublicOnDropdown: bool, + defaultTimeline: str, + pathBase: str, + dropdownNewPostSuffix: str, + dropdownNewBlogSuffix: str, + dropdownUnlistedSuffix: str, + dropdownFollowersSuffix: str, + dropdownDMSuffix: str, + dropdownReminderSuffix: str, + dropdownEventSuffix: str, + dropdownReportSuffix: str) -> str: + """Returns the html for a drop down list of new post types + """ + dropDownContent = '
\n' + dropDownContent += ' \n' + dropDownContent += ' \n' + dropDownContent += ' \n' + dropDownContent += '
\n' + return dropDownContent + + +def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {}, + baseDir: str, httpPrefix: str, + path: str, inReplyTo: str, + mentions: [], + reportUrl: str, pageNumber: int, + nickname: str, domain: str, + domainFull: str, + defaultTimeline: str, newswire: {}) -> str: + """New post screen + """ + iconsDir = getIconsDir(baseDir) + replyStr = '' + + showPublicOnDropdown = True + messageBoxHeight = 400 + + # filename of the banner shown at the top + bannerFile, bannerFilename = getBannerFile(baseDir, nickname, domain) + + if not path.endswith('/newshare'): + if not path.endswith('/newreport'): + if not inReplyTo or path.endswith('/newreminder'): + newPostText = '

' + \ + translate['Write your post text below.'] + '

\n' + else: + newPostText = \ + '

' + \ + translate['Write your reply to'] + \ + ' ' + \ + translate['this post'] + '

\n' + replyStr = '\n' + + # if replying to a non-public post then also make + # this post non-public + if not isPublicPostFromUrl(baseDir, nickname, domain, + inReplyTo): + newPostPath = path + if '?' in newPostPath: + newPostPath = newPostPath.split('?')[0] + if newPostPath.endswith('/newpost'): + path = path.replace('/newpost', '/newfollowers') + elif newPostPath.endswith('/newunlisted'): + path = path.replace('/newunlisted', '/newfollowers') + showPublicOnDropdown = False + else: + newPostText = \ + '

' + \ + translate['Write your report below.'] + '

\n' + + # custom report header with any additional instructions + if os.path.isfile(baseDir + '/accounts/report.txt'): + with open(baseDir + '/accounts/report.txt', 'r') as file: + customReportText = file.read() + if '

' not in customReportText: + customReportText = \ + '

' + \ + customReportText + '

\n' + repStr = '

' + customReportText = \ + customReportText.replace('

', repStr) + newPostText += customReportText + + idx = 'This message only goes to moderators, even if it ' + \ + 'mentions other fediverse addresses.' + newPostText += \ + '

' + translate[idx] + '

\n' + \ + '

' + translate['Also see'] + \ + ' ' + \ + translate['Terms of Service'] + '

\n' + else: + newPostText = \ + '

' + \ + translate['Enter the details for your shared item below.'] + \ + '

\n' + + if path.endswith('/newquestion'): + newPostText = \ + '

' + \ + translate['Enter the choices for your question below.'] + \ + '

\n' + + if os.path.isfile(baseDir + '/accounts/newpost.txt'): + with open(baseDir + '/accounts/newpost.txt', 'r') as file: + newPostText = \ + '

' + file.read() + '

\n' + + cssFilename = baseDir + '/epicyon-profile.css' + if os.path.isfile(baseDir + '/epicyon.css'): + cssFilename = baseDir + '/epicyon.css' + + newPostCSS = getCSS(baseDir, cssFilename, cssCache) + if newPostCSS: + if httpPrefix != 'https': + newPostCSS = newPostCSS.replace('https://', + httpPrefix + '://') + + if '?' in path: + path = path.split('?')[0] + pathBase = path.replace('/newreport', '').replace('/newpost', '') + pathBase = pathBase.replace('/newblog', '').replace('/newshare', '') + pathBase = pathBase.replace('/newunlisted', '') + pathBase = pathBase.replace('/newevent', '') + pathBase = pathBase.replace('/newreminder', '') + pathBase = pathBase.replace('/newfollowers', '').replace('/newdm', '') + + newPostImageSection = '
' + if not path.endswith('/newevent'): + newPostImageSection += \ + ' \n' + else: + newPostImageSection += \ + ' \n' + newPostImageSection += \ + ' \n' + + if path.endswith('/newevent'): + newPostImageSection += \ + ' \n' + newPostImageSection += \ + ' \n' + else: + newPostImageSection += \ + ' \n' + newPostImageSection += '
\n' + + scopeIcon = 'scope_public.png' + scopeDescription = translate['Public'] + placeholderSubject = \ + translate['Subject or Content Warning (optional)'] + '...' + placeholderMentions = '' + if inReplyTo: + # mentionsAndContent = getMentionsString(content) + placeholderMentions = \ + translate['Replying to'] + '...' + placeholderMessage = translate['Write something'] + '...' + extraFields = '' + endpoint = 'newpost' + if path.endswith('/newblog'): + placeholderSubject = translate['Title'] + scopeIcon = 'scope_blog.png' + if defaultTimeline != 'tlnews': + scopeDescription = translate['Blog'] + else: + scopeDescription = translate['Article'] + endpoint = 'newblog' + elif path.endswith('/newunlisted'): + scopeIcon = 'scope_unlisted.png' + scopeDescription = translate['Unlisted'] + endpoint = 'newunlisted' + elif path.endswith('/newfollowers'): + scopeIcon = 'scope_followers.png' + scopeDescription = translate['Followers'] + endpoint = 'newfollowers' + elif path.endswith('/newdm'): + scopeIcon = 'scope_dm.png' + scopeDescription = translate['DM'] + endpoint = 'newdm' + elif path.endswith('/newreminder'): + scopeIcon = 'scope_reminder.png' + scopeDescription = translate['Reminder'] + endpoint = 'newreminder' + elif path.endswith('/newevent'): + scopeIcon = 'scope_event.png' + scopeDescription = translate['Event'] + endpoint = 'newevent' + placeholderSubject = translate['Event name'] + placeholderMessage = translate['Describe the event'] + '...' + elif path.endswith('/newreport'): + scopeIcon = 'scope_report.png' + scopeDescription = translate['Report'] + endpoint = 'newreport' + elif path.endswith('/newquestion'): + scopeIcon = 'scope_question.png' + scopeDescription = translate['Question'] + placeholderMessage = translate['Enter your question'] + '...' + endpoint = 'newquestion' + extraFields = '
\n' + extraFields += '
\n' + for questionCtr in range(8): + extraFields += \ + '
\n' + extraFields += \ + '
\n' + extraFields += '
' + elif path.endswith('/newshare'): + scopeIcon = 'scope_share.png' + scopeDescription = translate['Shared Item'] + placeholderSubject = translate['Name of the shared item'] + '...' + placeholderMessage = \ + translate['Description of the item being shared'] + '...' + endpoint = 'newshare' + extraFields = '
\n' + extraFields += \ + ' \n' + extraFields += \ + ' \n' + extraFields += \ + '
\n' + extraFields += \ + ' \n' + extraFields += \ + '
\n' + extraFields += ' \n' + extraFields += '
\n' + extraFields += '
\n' + extraFields += \ + '\n' + extraFields += '\n' + extraFields += '
\n' + + citationsStr = '' + if endpoint == 'newblog': + citationsFilename = \ + baseDir + '/accounts/' + \ + nickname + '@' + domain + '/.citations.txt' + if os.path.isfile(citationsFilename): + citationsStr = '
\n' + citationsStr += '

\n' + citationsStr += ' \n' + citationsStr += '
\n' + + dateAndLocation = '' + if endpoint != 'newshare' and \ + endpoint != 'newreport' and \ + endpoint != 'newquestion': + dateAndLocation = '
\n' + + if endpoint == 'newevent': + # event status + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + # maximum attendees + dateAndLocation += '\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + # event joining options + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + # Event posts don't allow replies - they're just an announcement. + # They also have a few more checkboxes + dateAndLocation += \ + '

\n' + dateAndLocation += \ + '

' + \ + '

\n' + else: + dateAndLocation += \ + '

\n' + + if not inReplyTo and endpoint != 'newevent': + dateAndLocation += \ + '

\n' + + if endpoint != 'newevent': + dateAndLocation += \ + '

\n' + # select a date and time for this post + dateAndLocation += '\n' + dateAndLocation += '\n' + dateAndLocation += '

\n' + else: + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += \ + '

\n' + # select start time for the event + dateAndLocation += '\n' + dateAndLocation += '\n' + dateAndLocation += '

\n' + # select end time for the event + dateAndLocation += \ + '
\n' + dateAndLocation += '\n' + dateAndLocation += '\n' + dateAndLocation += '\n' + + if endpoint == 'newevent': + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += \ + ' \n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + if endpoint == 'newevent': + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + dateAndLocation += '\n' + dateAndLocation += '
\n' + + newPostForm = htmlHeader(cssFilename, newPostCSS) + + newPostForm += \ + '\n' + newPostForm += '\n' + + mentionsStr = '' + for m in mentions: + mentionNickname = getNicknameFromActor(m) + if not mentionNickname: + continue + mentionDomain, mentionPort = getDomainFromActor(m) + if not mentionDomain: + continue + if mentionPort: + mentionsHandle = \ + '@' + mentionNickname + '@' + \ + mentionDomain + ':' + str(mentionPort) + else: + mentionsHandle = '@' + mentionNickname + '@' + mentionDomain + if mentionsHandle not in mentionsStr: + mentionsStr += mentionsHandle + ' ' + + # build suffixes so that any replies or mentions are + # preserved when switching between scopes + dropdownNewPostSuffix = '/newpost' + dropdownNewBlogSuffix = '/newblog' + dropdownUnlistedSuffix = '/newunlisted' + dropdownFollowersSuffix = '/newfollowers' + dropdownDMSuffix = '/newdm' + dropdownEventSuffix = '/newevent' + dropdownReminderSuffix = '/newreminder' + dropdownReportSuffix = '/newreport' + if inReplyTo or mentions: + dropdownNewPostSuffix = '' + dropdownNewBlogSuffix = '' + dropdownUnlistedSuffix = '' + dropdownFollowersSuffix = '' + dropdownDMSuffix = '' + dropdownEventSuffix = '' + dropdownReminderSuffix = '' + dropdownReportSuffix = '' + if inReplyTo: + dropdownNewPostSuffix += '?replyto=' + inReplyTo + dropdownNewBlogSuffix += '?replyto=' + inReplyTo + dropdownUnlistedSuffix += '?replyto=' + inReplyTo + dropdownFollowersSuffix += '?replyfollowers=' + inReplyTo + dropdownDMSuffix += '?replydm=' + inReplyTo + for mentionedActor in mentions: + dropdownNewPostSuffix += '?mention=' + mentionedActor + dropdownNewBlogSuffix += '?mention=' + mentionedActor + dropdownUnlistedSuffix += '?mention=' + mentionedActor + dropdownFollowersSuffix += '?mention=' + mentionedActor + dropdownDMSuffix += '?mention=' + mentionedActor + dropdownReportSuffix += '?mention=' + mentionedActor + + dropDownContent = '' + if not reportUrl: + dropDownContent = \ + htmlNewPostDropDown(scopeIcon, scopeDescription, + replyStr, + translate, + iconsDir, + showPublicOnDropdown, + defaultTimeline, + pathBase, + dropdownNewPostSuffix, + dropdownNewBlogSuffix, + dropdownUnlistedSuffix, + dropdownFollowersSuffix, + dropdownDMSuffix, + dropdownReminderSuffix, + dropdownEventSuffix, + dropdownReportSuffix) + else: + mentionsStr = 'Re: ' + reportUrl + '\n\n' + mentionsStr + + newPostForm += \ + '
\n' + newPostForm += '
\n' + newPostForm += \ + ' \n' + newPostForm += '
\n' + newPostForm += ' \n' + newPostForm += '\n' + + newPostForm += \ + ' \n' + newPostForm += ' \n' + newPostForm += '
' + dropDownContent + '' + \
+        translate['Search for emoji'] + '
\n' + newPostForm += '
\n' + + newPostForm += '
\n' + + # newPostForm += \ + # ' \n' + + # for a new blog if newswire items exist then add a citations button + if newswire and path.endswith('/newblog'): + newPostForm += \ + ' \n' + + newPostForm += \ + ' \n' + + newPostForm += '
\n' + + newPostForm += replyStr + if mediaInstance and not replyStr: + newPostForm += newPostImageSection + + newPostForm += \ + '
' + newPostForm += ' ' + newPostForm += '' + + selectedStr = ' selected' + if inReplyTo or endpoint == 'newdm': + if inReplyTo: + newPostForm += \ + '
\n' + else: + newPostForm += \ + ' ' \ + ' 📄
\n' + newPostForm += \ + ' \n' + newPostForm += \ + htmlFollowingDataList(baseDir, nickname, domain, domainFull) + newPostForm += '' + selectedStr = '' + + newPostForm += \ + '
' + if mediaInstance: + messageBoxHeight = 200 + + if endpoint == 'newquestion': + messageBoxHeight = 100 + elif endpoint == 'newblog': + messageBoxHeight = 800 + + newPostForm += \ + ' \n' + newPostForm += extraFields + citationsStr + dateAndLocation + if not mediaInstance or replyStr: + newPostForm += newPostImageSection + newPostForm += '
\n' + newPostForm += '
\n' + + if not reportUrl: + newPostForm = \ + newPostForm.replace('', '') + + newPostForm += htmlFooter() + return newPostForm