diff --git a/blog.py b/blog.py index f2651b8db..0866842d7 100644 --- a/blog.py +++ b/blog.py @@ -11,9 +11,11 @@ from datetime import datetime from content import replaceEmojiFromTags from webapp_utils import htmlHeaderWithExternalStyle +from webapp_utils import htmlHeaderWithBlogMarkup from webapp_utils import htmlFooter from webapp_utils import getPostAttachmentsAsHtml from webapp_media import addEmbeddedElements +from utils import removeHtml from utils import getConfigParam from utils import getFullDomain from utils import getMediaFormats @@ -375,11 +377,28 @@ def _htmlBlogRemoveCwButton(blogStr: str, translate: {}) -> str: return blogStr +def _getSnippetFromBlogContent(postJsonObject: {}) -> str: + """Returns a snippet of text from the blog post as a preview + """ + content = postJsonObject['object']['content'] + if '

' in content: + content = content.split('

', 1)[1] + if '

' in content: + content = content.split('

', 1)[0] + content = removeHtml(content) + if '\n' in content: + content = content.split('\n')[0] + if len(content) >= 256: + content = content[:252] + '...' + return content + + def htmlBlogPost(authorized: bool, baseDir: str, httpPrefix: str, translate: {}, nickname: str, domain: str, domainFull: str, postJsonObject: {}, - peertubeInstances: []) -> str: + peertubeInstances: [], + systemLanguage: str) -> str: """Returns a html blog post """ blogStr = '' @@ -389,7 +408,13 @@ def htmlBlogPost(authorized: bool, cssFilename = baseDir + '/blog.css' instanceTitle = \ getConfigParam(baseDir, 'instanceTitle') - blogStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle) + published = postJsonObject['object']['published'] + title = postJsonObject['object']['summary'] + snippet = _getSnippetFromBlogContent(postJsonObject) + blogStr = htmlHeaderWithBlogMarkup(cssFilename, instanceTitle, + httpPrefix, domainFull, nickname, + systemLanguage, published, + title, snippet) _htmlBlogRemoveCwButton(blogStr, translate) blogStr += _htmlBlogPostContent(authorized, baseDir, diff --git a/daemon.py b/daemon.py index 68b8c8acf..b54fd2b07 100644 --- a/daemon.py +++ b/daemon.py @@ -7399,6 +7399,7 @@ class PubServer(BaseHTTPRequestHandler): if isinstance(actorJson['affiliation']['roleName'], list): rolesList = actorJson['affiliation']['roleName'] + city = self._getSpoofedCity(baseDir, nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -7422,7 +7423,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, rolesList, + accessKeys, city, rolesList, None, None) msg = msg.encode('utf-8') msglen = len(msg) @@ -7501,6 +7502,8 @@ class PubServer(BaseHTTPRequestHandler): actorSkillsList = \ actorJson['hasOccupation']['skills'] skills = getSkillsFromList(actorSkillsList) + city = self._getSpoofedCity(baseDir, + nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -7524,7 +7527,7 @@ class PubServer(BaseHTTPRequestHandler): allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, skills, + accessKeys, city, skills, None, None) msg = msg.encode('utf-8') msglen = len(msg) @@ -9398,6 +9401,7 @@ class PubServer(BaseHTTPRequestHandler): accessKeys = \ self.server.keyShortcuts[nickname] + city = self._getSpoofedCity(baseDir, nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -9422,7 +9426,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, + accessKeys, city, shares, pageNumber, sharesPerPage) msg = msg.encode('utf-8') @@ -9500,6 +9504,7 @@ class PubServer(BaseHTTPRequestHandler): return True accessKeys = self.server.accessKeys + city = None if '/users/' in path: nickname = path.split('/users/')[1] if '/' in nickname: @@ -9508,6 +9513,7 @@ class PubServer(BaseHTTPRequestHandler): accessKeys = \ self.server.keyShortcuts[nickname] + city = self._getSpoofedCity(baseDir, nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -9532,7 +9538,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, + accessKeys, city, following, pageNumber, followsPerPage).encode('utf-8') @@ -9609,6 +9615,7 @@ class PubServer(BaseHTTPRequestHandler): return True accessKeys = self.server.accessKeys + city = None if '/users/' in path: nickname = path.split('/users/')[1] if '/' in nickname: @@ -9617,6 +9624,7 @@ class PubServer(BaseHTTPRequestHandler): accessKeys = \ self.server.keyShortcuts[nickname] + city = self._getSpoofedCity(baseDir, nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -9642,7 +9650,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, + accessKeys, city, followers, pageNumber, followsPerPage).encode('utf-8') @@ -9742,6 +9750,7 @@ class PubServer(BaseHTTPRequestHandler): return True accessKeys = self.server.accessKeys + city = None if '/users/' in path: nickname = path.split('/users/')[1] if '/' in nickname: @@ -9750,6 +9759,7 @@ class PubServer(BaseHTTPRequestHandler): accessKeys = \ self.server.keyShortcuts[nickname] + city = self._getSpoofedCity(baseDir, nickname, domain) msg = \ htmlProfile(self.server.rssIconAtTop, self.server.cssCache, @@ -9775,7 +9785,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.allowLocalNetworkAccess, self.server.textModeBanner, self.server.debug, - accessKeys, + accessKeys, city, None, None).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -11094,7 +11104,8 @@ class PubServer(BaseHTTPRequestHandler): nickname, self.server.domain, self.server.domainFull, postJsonObject, - self.server.peertubeInstances) + self.server.peertubeInstances, + self.server.systemLanguage) if msg is not None: msg = msg.encode('utf-8') msglen = len(msg) diff --git a/webapp_profile.py b/webapp_profile.py index 8b91ba5d6..5a8baffa4 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -520,7 +520,7 @@ def htmlProfile(rssIconAtTop: bool, peertubeInstances: [], allowLocalNetworkAccess: bool, textModeBanner: str, - debug: bool, accessKeys: {}, + debug: bool, accessKeys: {}, city: str, extraJson=None, pageNumber=None, maxItemsPerPage=None) -> str: """Show the profile page as html @@ -901,7 +901,8 @@ def htmlProfile(rssIconAtTop: bool, instanceTitle = \ getConfigParam(baseDir, 'instanceTitle') profileStr = \ - htmlHeaderWithPersonMarkup(cssFilename, instanceTitle, profileJson) + \ + htmlHeaderWithPersonMarkup(cssFilename, instanceTitle, + profileJson, city) + \ profileStr + htmlFooter() return profileStr diff --git a/webapp_utils.py b/webapp_utils.py index 00fc3cace..2b9e43269 100644 --- a/webapp_utils.py +++ b/webapp_utils.py @@ -711,7 +711,8 @@ def htmlHeaderWithExternalStyle(cssFilename: str, instanceTitle: str, def htmlHeaderWithPersonMarkup(cssFilename: str, instanceTitle: str, - actorJson: {}, lang='en') -> str: + actorJson: {}, city: str, + lang='en') -> str: """html header which includes person markup https://schema.org/Person """ @@ -731,7 +732,23 @@ def htmlHeaderWithPersonMarkup(cssFilename: str, instanceTitle: str, occupationStr + \ ' "skills": ' + str(skillsList) + '\n' + \ ' "},\n' - + cityMarkup = '' + if city: + city = city.lower().title() + addComma = '' + countryMarkup = '' + if ',' in city: + country = city.split(',', 1)[1].strip().title() + city = city.split(',', 1)[0] + countryMarkup = \ + ' "addressCountry": "' + country + '"\n' + addComma = ',' + cityMarkup = \ + ' "address": {\n' + \ + ' "@type": "PostalAddress",\n' + \ + ' "addressLocality": "' + city + '"' + addComma + '\n' + \ + countryMarkup + \ + ' },\n' personMarkup = \ ' \n' @@ -757,7 +774,7 @@ def htmlHeaderWithWebsiteMarkup(cssFilename: str, instanceTitle: str, htmlStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle, systemLanguage) - licenseUrl = 'https://www.gnu.org/licenses/agpl-3.0.en.html' + licenseUrl = 'https://www.gnu.org/licenses/agpl-3.0.rdf' # social networking category genreUrl = 'http://vocab.getty.edu/aat/300312270' @@ -791,6 +808,42 @@ def htmlHeaderWithWebsiteMarkup(cssFilename: str, instanceTitle: str, return htmlStr +def htmlHeaderWithBlogMarkup(cssFilename: str, instanceTitle: str, + httpPrefix: str, domain: str, nickname: str, + systemLanguage: str, published: str, + title: str, snippet: str) -> str: + """html header which includes blog post markup + https://schema.org/BlogPosting + """ + htmlStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle, + systemLanguage) + + authorUrl = httpPrefix + '://' + domain + '/users/' + nickname + blogMarkup = \ + ' \n' + htmlStr = htmlStr.replace('\n', '\n' + blogMarkup) + return htmlStr + + def htmlFooter() -> str: htmlStr = ' \n' htmlStr += '\n'