Revert "Reading functions"

This reverts commit ee0ffade9d.
merge-requests/30/head
Bob Mottram 2021-06-21 23:52:04 +01:00
parent ee0ffade9d
commit cd008c3013
26 changed files with 217 additions and 199 deletions

View File

@ -28,7 +28,6 @@ from utils import firstParagraphFromString
from posts import createBlogsTimeline from posts import createBlogsTimeline
from newswire import rss2Header from newswire import rss2Header
from newswire import rss2Footer from newswire import rss2Footer
from storage import readWholeFile
def _noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {}, def _noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {},
@ -745,9 +744,8 @@ def htmlEditBlog(mediaInstance: bool, translate: {},
editBlogText = '<h1">' + translate['Write your post text below.'] + '</h1>' editBlogText = '<h1">' + translate['Write your post text below.'] + '</h1>'
if os.path.isfile(baseDir + '/accounts/newpost.txt'): if os.path.isfile(baseDir + '/accounts/newpost.txt'):
newPostStr = readWholeFile(baseDir + '/accounts/newpost.txt') with open(baseDir + '/accounts/newpost.txt', 'r') as file:
if newPostStr: editBlogText = '<p>' + file.read() + '</p>'
editBlogText = '<p>' + newPostStr + '</p>'
cssFilename = baseDir + '/epicyon-profile.css' cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'): if os.path.isfile(baseDir + '/epicyon.css'):

View File

@ -25,7 +25,6 @@ from utils import saveJson
from posts import getPersonBox from posts import getPersonBox
from session import postJson from session import postJson
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def undoBookmarksCollectionEntry(recentPostsCache: {}, def undoBookmarksCollectionEntry(recentPostsCache: {},
@ -60,9 +59,10 @@ def undoBookmarksCollectionEntry(recentPostsCache: {},
bookmarkIndex = bookmarkIndex.replace('\n', '').replace('\r', '') bookmarkIndex = bookmarkIndex.replace('\n', '').replace('\r', '')
if bookmarkIndex not in open(bookmarksIndexFilename).read(): if bookmarkIndex not in open(bookmarksIndexFilename).read():
return return
indexStr = readWholeFile(bookmarksIndexFilename) indexStr = ''
indexStr = indexStr.replace(bookmarkIndex + '\n', '') with open(bookmarksIndexFilename, 'r') as indexFile:
storeValue(bookmarksIndexFilename, indexStr, 'writeonly') indexStr = indexFile.read().replace(bookmarkIndex + '\n', '')
storeValue(bookmarksIndexFilename, indexStr, 'writeonly')
if not postJsonObject.get('type'): if not postJsonObject.get('type'):
return return

View File

@ -10,7 +10,6 @@ __module_group__ = "RSS Feeds"
import os import os
import datetime import datetime
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def getHashtagCategory(baseDir: str, hashtag: str) -> str: def getHashtagCategory(baseDir: str, hashtag: str) -> str:
@ -25,9 +24,10 @@ def getHashtagCategory(baseDir: str, hashtag: str) -> str:
if not os.path.isfile(categoryFilename): if not os.path.isfile(categoryFilename):
return '' return ''
categoryStr = readWholeFile(categoryFilename) with open(categoryFilename, 'r') as fp:
if categoryStr: categoryStr = fp.read()
return categoryStr if categoryStr:
return categoryStr
return '' return ''
@ -53,10 +53,12 @@ def getHashtagCategories(baseDir: str,
hashtag = f.split('.')[0] hashtag = f.split('.')[0]
if len(hashtag) > maxTagLength: if len(hashtag) > maxTagLength:
continue continue
categoryStr = readWholeFile(categoryFilename) with open(categoryFilename, 'r') as fp:
if not categoryStr: categoryStr = fp.read()
continue
if categoryStr: if not categoryStr:
continue
if category: if category:
# only return a dictionary for a specific category # only return a dictionary for a specific category
if categoryStr != category: if categoryStr != category:

View File

@ -12,7 +12,6 @@ import datetime
import random import random
import math import math
from random import randint from random import randint
from storage import readWholeFile
# states which the simulated city dweller can be in # states which the simulated city dweller can be in
PERSON_SLEEP = 0 PERSON_SLEEP = 0
@ -295,7 +294,8 @@ def getSpoofedCity(city: str, baseDir: str, nickname: str, domain: str) -> str:
cityFilename = baseDir + '/accounts/' + \ cityFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/city.txt' nickname + '@' + domain + '/city.txt'
if os.path.isfile(cityFilename): if os.path.isfile(cityFilename):
city = readWholeFile(cityFilename).replace('\n', '') with open(cityFilename, 'r') as fp:
city = fp.read().replace('\n', '')
return city return city

View File

@ -19,7 +19,6 @@ from utils import dangerousMarkup
from utils import isPGPEncrypted from utils import isPGPEncrypted
from utils import containsPGPPublicKey from utils import containsPGPPublicKey
from petnames import getPetName from petnames import getPetName
from storage import readWholeFile
def removeHtmlTag(htmlStr: str, tag: str) -> str: def removeHtmlTag(htmlStr: str, tag: str) -> str:
@ -170,9 +169,8 @@ def dangerousCSS(filename: str, allowLocalNetworkAccess: bool) -> bool:
if not os.path.isfile(filename): if not os.path.isfile(filename):
return False return False
content = readWholeFile(filename) with open(filename, 'r') as fp:
if content: content = fp.read().lower()
content = content.lower()
cssMatches = ('behavior:', ':expression', '?php', '.php', cssMatches = ('behavior:', ':expression', '?php', '.php',
'google', 'regexp', 'localhost', 'google', 'regexp', 'localhost',

View File

@ -301,7 +301,6 @@ from speaker import getSSMLbox
from city import getSpoofedCity from city import getSpoofedCity
import os import os
from storage import storeValue from storage import storeValue
from storage import readWholeFile
# maximum number of posts to list in outbox feed # maximum number of posts to list in outbox feed
@ -666,7 +665,11 @@ class PubServer(BaseHTTPRequestHandler):
# self.send_header('Cache-Control', 'public, max-age=86400') # self.send_header('Cache-Control', 'public, max-age=86400')
etag = None etag = None
if os.path.isfile(mediaFilename + '.etag'): if os.path.isfile(mediaFilename + '.etag'):
etag = readWholeFile(mediaFilename + '.etag') try:
with open(mediaFilename + '.etag', 'r') as etagFile:
etag = etagFile.read()
except BaseException:
pass
if not etag: if not etag:
etag = sha1(data).hexdigest() # nosec etag = sha1(data).hexdigest() # nosec
storeValue(mediaFilename + '.etag', etag, 'writeonly') storeValue(mediaFilename + '.etag', etag, 'writeonly')
@ -687,7 +690,12 @@ class PubServer(BaseHTTPRequestHandler):
oldEtag = self.headers['If-None-Match'] oldEtag = self.headers['If-None-Match']
if os.path.isfile(mediaFilename + '.etag'): if os.path.isfile(mediaFilename + '.etag'):
# load the etag from file # load the etag from file
currEtag = readWholeFile(mediaFilename) currEtag = ''
try:
with open(mediaFilename, 'r') as etagFile:
currEtag = etagFile.read()
except BaseException:
pass
if oldEtag == currEtag: if oldEtag == currEtag:
# The file has not changed # The file has not changed
return True return True
@ -1524,7 +1532,12 @@ class PubServer(BaseHTTPRequestHandler):
loginNickname + '@' + domain + '/.salt' loginNickname + '@' + domain + '/.salt'
salt = createPassword(32) salt = createPassword(32)
if os.path.isfile(saltFilename): if os.path.isfile(saltFilename):
salt = readWholeFile(saltFilename) try:
with open(saltFilename, 'r') as fp:
salt = fp.read()
except Exception as e:
print('WARN: Unable to read salt for ' +
loginNickname + ' ' + str(e))
else: else:
storeValue(saltFilename, salt, 'writeonly') storeValue(saltFilename, salt, 'writeonly')
@ -13095,7 +13108,11 @@ class PubServer(BaseHTTPRequestHandler):
fileLength = os.path.getsize(mediaFilename) fileLength = os.path.getsize(mediaFilename)
mediaTagFilename = mediaFilename + '.etag' mediaTagFilename = mediaFilename + '.etag'
if os.path.isfile(mediaTagFilename): if os.path.isfile(mediaTagFilename):
etag = readWholeFile(mediaTagFilename) try:
with open(mediaTagFilename, 'r') as etagFile:
etag = etagFile.read()
except BaseException:
pass
else: else:
with open(mediaFilename, 'rb') as avFile: with open(mediaFilename, 'rb') as avFile:
mediaBinary = avFile.read() mediaBinary = avFile.read()
@ -14839,7 +14856,13 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
if not os.path.isfile(tokenFilename): if not os.path.isfile(tokenFilename):
continue continue
nickname = handle.split('@')[0] nickname = handle.split('@')[0]
token = readWholeFile(tokenFilename) token = None
try:
with open(tokenFilename, 'r') as fp:
token = fp.read()
except Exception as e:
print('WARN: Unable to read token for ' +
nickname + ' ' + str(e))
if not token: if not token:
continue continue
tokensDict[nickname] = token tokensDict[nickname] = token

View File

@ -57,7 +57,6 @@ from bookmarks import sendUndoBookmarkViaServer
from delete import sendDeleteViaServer from delete import sendDeleteViaServer
from person import getActorJson from person import getActorJson
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def _desktopHelp() -> None: def _desktopHelp() -> None:
@ -285,9 +284,10 @@ def _desktopShowBanner() -> None:
bannerFilename = 'theme/' + bannerTheme + '/banner.txt' bannerFilename = 'theme/' + bannerTheme + '/banner.txt'
if not os.path.isfile(bannerFilename): if not os.path.isfile(bannerFilename):
return return
banner = readWholeFile(bannerFilename) with open(bannerFilename, 'r') as bannerFile:
if banner: banner = bannerFile.read()
print(banner + '\n') if banner:
print(banner + '\n')
def _desktopWaitForCmd(timeout: int, debug: bool) -> str: def _desktopWaitForCmd(timeout: int, debug: bool) -> str:

View File

@ -31,8 +31,6 @@ from auth import createBasicAuthHeader
from session import getJson from session import getJson
from session import postJson from session import postJson
from storage import storeValue from storage import storeValue
from storage import readWholeFile
from storage import readFileLines
def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None: def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None:
@ -51,8 +49,8 @@ def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None:
lastSeenDir = accountDir + '/lastseen' lastSeenDir = accountDir + '/lastseen'
if not os.path.isdir(lastSeenDir): if not os.path.isdir(lastSeenDir):
os.mkdir(lastSeenDir) os.mkdir(lastSeenDir)
followingHandles = readFileLines(followingFilename) with open(followingFilename, 'r') as fp:
if followingHandles: followingHandles = fp.readlines()
for handle in followingHandles: for handle in followingHandles:
if '#' in handle: if '#' in handle:
continue continue
@ -216,7 +214,9 @@ def isFollowerOfPerson(baseDir: str, nickname: str, domain: str,
alreadyFollowing = False alreadyFollowing = False
followersStr = readWholeFile(followersFile) followersStr = ''
with open(followersFile, 'r') as fpFollowers:
followersStr = fpFollowers.read()
if handle in followersStr: if handle in followersStr:
alreadyFollowing = True alreadyFollowing = True
@ -556,7 +556,9 @@ def _storeFollowRequest(baseDir: str,
if os.path.isfile(followersFilename): if os.path.isfile(followersFilename):
alreadyFollowing = False alreadyFollowing = False
followersStr = readWholeFile(followersFilename) followersStr = ''
with open(followersFilename, 'r') as fpFollowers:
followersStr = fpFollowers.read()
if approveHandle in followersStr: if approveHandle in followersStr:
alreadyFollowing = True alreadyFollowing = True

View File

@ -8,7 +8,6 @@ __status__ = "Production"
__module_group__ = "Calendar" __module_group__ = "Calendar"
import os import os
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -30,8 +29,9 @@ def receivingCalendarEvents(baseDir: str, nickname: str, domain: str,
if not os.path.isfile(followingFilename): if not os.path.isfile(followingFilename):
return False return False
# create a new calendar file from the following file # create a new calendar file from the following file
followingHandles = readWholeFile(followingFilename) with open(followingFilename, 'r') as followingFile:
storeValue(calendarFilename, followingHandles, 'writeonly') followingHandles = followingFile.read()
storeValue(calendarFilename, followingHandles, 'writeonly')
return handle + '\n' in open(calendarFilename).read() return handle + '\n' in open(calendarFilename).read()
@ -66,11 +66,14 @@ def _receiveCalendarEvents(baseDir: str, nickname: str, domain: str,
followingHandles = '' followingHandles = ''
if os.path.isfile(calendarFilename): if os.path.isfile(calendarFilename):
print('Calendar file exists') print('Calendar file exists')
followingHandles = readWholeFile(calendarFilename) with open(calendarFilename, 'r') as calendarFile:
followingHandles = calendarFile.read()
else: else:
# create a new calendar file from the following file # create a new calendar file from the following file
print('Creating calendar file ' + calendarFilename) print('Creating calendar file ' + calendarFilename)
followingHandles = readWholeFile(followingFilename) followingHandles = ''
with open(followingFilename, 'r') as followingFile:
followingHandles = followingFile.read()
if add: if add:
storeValue(calendarFilename, followingHandles + handle, 'write') storeValue(calendarFilename, followingHandles + handle, 'write')

View File

@ -17,7 +17,6 @@ from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import locatePost from utils import locatePost
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def _validUuid(testUuid: str, version=4): def _validUuid(testUuid: str, version=4):
@ -36,9 +35,9 @@ def _removeEventFromTimeline(eventId: str, tlEventsFilename: str) -> None:
""" """
if eventId + '\n' not in open(tlEventsFilename).read(): if eventId + '\n' not in open(tlEventsFilename).read():
return return
eventsTimeline = readWholeFile(tlEventsFilename) with open(tlEventsFilename, 'r') as fp:
eventsTimeline = eventsTimeline.replace(eventId + '\n', '') eventsTimeline = fp.read().replace(eventId + '\n', '')
storeValue(tlEventsFilename, eventsTimeline, 'writeonly') storeValue(tlEventsFilename, eventsTimeline, 'writeonly')
def saveEventPost(baseDir: str, handle: str, postId: str, def saveEventPost(baseDir: str, handle: str, postId: str,

View File

@ -84,7 +84,6 @@ from context import hasValidContext
from speaker import updateSpeaker from speaker import updateSpeaker
from announce import isSelfAnnounce from announce import isSelfAnnounce
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None: def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
@ -1880,9 +1879,10 @@ def _likeNotify(baseDir: str, domain: str, onionDomain: str,
# was there a previous like notification? # was there a previous like notification?
if os.path.isfile(prevLikeFile): if os.path.isfile(prevLikeFile):
# is it the same as the current notification ? # is it the same as the current notification ?
prevLikeStr = readWholeFile(prevLikeFile) with open(prevLikeFile, 'r') as fp:
if prevLikeStr == likeStr: prevLikeStr = fp.read()
return if prevLikeStr == likeStr:
return
storeValue(prevLikeFile, likeStr, 'writeonly') storeValue(prevLikeFile, likeStr, 'writeonly')
storeValue(likeFile, likeStr, 'writeonly') storeValue(likeFile, likeStr, 'writeonly')
@ -2108,8 +2108,8 @@ def _updateLastSeen(baseDir: str, handle: str, actor: str) -> None:
daysSinceEpoch = (currTime - datetime.datetime(1970, 1, 1)).days daysSinceEpoch = (currTime - datetime.datetime(1970, 1, 1)).days
# has the value changed? # has the value changed?
if os.path.isfile(lastSeenFilename): if os.path.isfile(lastSeenFilename):
daysSinceEpochFile = readWholeFile(lastSeenFilename) with open(lastSeenFilename, 'r') as lastSeenFile:
if daysSinceEpochFile: daysSinceEpochFile = lastSeenFile.read()
if int(daysSinceEpochFile) == daysSinceEpoch: if int(daysSinceEpochFile) == daysSinceEpoch:
# value hasn't changed, so we can save writing anything to file # value hasn't changed, so we can save writing anything to file
return return

View File

@ -12,7 +12,6 @@ from follow import followedAccountAccepts
from follow import followedAccountRejects from follow import followedAccountRejects
from follow import removeFromFollowRequests from follow import removeFromFollowRequests
from utils import loadJson from utils import loadJson
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -97,7 +96,9 @@ def manualApproveFollowRequest(session, baseDir: str,
return return
# is the handle in the requests file? # is the handle in the requests file?
approveFollowsStr = readWholeFile(approveFollowsFilename) approveFollowsStr = ''
with open(approveFollowsFilename, 'r') as fpFollowers:
approveFollowsStr = fpFollowers.read()
exists = False exists = False
approveHandleFull = approveHandle approveHandleFull = approveHandle
if approveHandle in approveFollowsStr: if approveHandle in approveFollowsStr:

View File

@ -21,7 +21,6 @@ from shutil import copyfile
from shutil import rmtree from shutil import rmtree
from shutil import move from shutil import move
from city import spoofGeolocation from city import spoofGeolocation
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -71,10 +70,8 @@ def _spoofMetaData(baseDir: str, nickname: str, domain: str,
baseDir + '/accounts/' + nickname + '@' + domain + '/decoyseed' baseDir + '/accounts/' + nickname + '@' + domain + '/decoyseed'
decoySeed = 63725 decoySeed = 63725
if os.path.isfile(decoySeedFilename): if os.path.isfile(decoySeedFilename):
decoySeedStr = readWholeFile(decoySeedFilename) with open(decoySeedFilename, 'r') as fp:
if decoySeedStr: decoySeed = int(fp.read())
if decoySeedStr.isdigit():
decoySeed = int(decoySeedStr)
else: else:
decoySeed = randint(10000, 10000000000000000) decoySeed = randint(10000, 10000000000000000)
decoySeedStr = str(decoySeed) decoySeedStr = str(decoySeed)

View File

@ -34,7 +34,6 @@ from utils import clearFromPostCaches
from utils import dangerousMarkup from utils import dangerousMarkup
from inbox import storeHashTags from inbox import storeHashTags
from session import createSession from session import createSession
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -399,8 +398,9 @@ def _createNewsMirror(baseDir: str, domain: str,
# remove the corresponding index entries # remove the corresponding index entries
if removals: if removals:
indexContent = readWholeFile(mirrorIndexFilename) indexContent = ''
if indexContent: with open(mirrorIndexFilename, 'r') as indexFile:
indexContent = indexFile.read()
for removePostId in removals: for removePostId in removals:
indexContent = \ indexContent = \
indexContent.replace(removePostId + '\n', '') indexContent.replace(removePostId + '\n', '')

View File

@ -29,8 +29,6 @@ from utils import removeHtml
from blocking import isBlockedDomain from blocking import isBlockedDomain
from blocking import isBlockedHashtag from blocking import isBlockedHashtag
from filters import isFiltered from filters import isFiltered
from storage import readWholeFile
from storage import readFileLines
def _removeCDATA(text: str) -> str: def _removeCDATA(text: str) -> str:
@ -221,8 +219,8 @@ def loadHashtagCategories(baseDir: str, language: str) -> None:
if not os.path.isfile(hashtagCategoriesFilename): if not os.path.isfile(hashtagCategoriesFilename):
return return
xmlStr = readWholeFile(hashtagCategoriesFilename) with open(hashtagCategoriesFilename, 'r') as fp:
if xmlStr: xmlStr = fp.read()
_xml2StrToHashtagCategories(baseDir, xmlStr, 1024, True) _xml2StrToHashtagCategories(baseDir, xmlStr, 1024, True)
@ -1016,7 +1014,9 @@ def getDictFromNewswire(session, baseDir: str, domain: str,
maxPostsPerSource = 5 maxPostsPerSource = 5
# add rss feeds # add rss feeds
rssFeed = readFileLines(subscriptionsFilename) rssFeed = []
with open(subscriptionsFilename, 'r') as fp:
rssFeed = fp.readlines()
result = {} result = {}
for url in rssFeed: for url in rssFeed:
url = url.strip() url = url.strip()

View File

@ -52,7 +52,6 @@ from session import createSession
from session import getJson from session import getJson
from webfinger import webfingerHandle from webfinger import webfingerHandle
from pprint import pprint from pprint import pprint
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -1122,7 +1121,9 @@ def isPersonSnoozed(baseDir: str, nickname: str, domain: str,
replaceStr = line replaceStr = line
break break
if replaceStr: if replaceStr:
content = readWholeFile(snoozedFilename).replace(replaceStr, '') content = None
with open(snoozedFilename, 'r') as snoozedFile:
content = snoozedFile.read().replace(replaceStr, '')
if content: if content:
storeValue(snoozedFilename, content, 'writeonly') storeValue(snoozedFilename, content, 'writeonly')
@ -1167,7 +1168,9 @@ def personUnsnooze(baseDir: str, nickname: str, domain: str,
replaceStr = line replaceStr = line
break break
if replaceStr: if replaceStr:
content = readWholeFile(snoozedFilename).replace(replaceStr, '') content = None
with open(snoozedFilename, 'r') as snoozedFile:
content = snoozedFile.read().replace(replaceStr, '')
if content: if content:
storeValue(snoozedFilename, content, 'writeonly') storeValue(snoozedFilename, content, 'writeonly')

View File

@ -7,7 +7,6 @@ __email__ = "bob@freedombone.net"
__status__ = "Production" __status__ = "Production"
import os import os
from storage import readWholeFile
from storage import storeValue from storage import storeValue
@ -29,8 +28,8 @@ def setPetName(baseDir: str, nickname: str, domain: str,
# does this entry already exist? # does this entry already exist?
if os.path.isfile(petnamesFilename): if os.path.isfile(petnamesFilename):
petnamesStr = readWholeFile(petnamesFilename) with open(petnamesFilename, 'r') as petnamesFile:
if petnamesStr: petnamesStr = petnamesFile.read()
if entry in petnamesStr: if entry in petnamesStr:
return True return True
if ' ' + handle + '\n' in petnamesStr: if ' ' + handle + '\n' in petnamesStr:
@ -66,8 +65,8 @@ def getPetName(baseDir: str, nickname: str, domain: str,
if not os.path.isfile(petnamesFilename): if not os.path.isfile(petnamesFilename):
return '' return ''
petnamesStr = readWholeFile(petnamesFilename) with open(petnamesFilename, 'r') as petnamesFile:
if petnamesStr: petnamesStr = petnamesFile.read()
if ' ' + handle + '\n' in petnamesStr: if ' ' + handle + '\n' in petnamesStr:
petnamesList = petnamesStr.split('\n') petnamesList = petnamesStr.split('\n')
for pet in petnamesList: for pet in petnamesList:
@ -87,8 +86,8 @@ def _getPetNameHandle(baseDir: str, nickname: str, domain: str,
if not os.path.isfile(petnamesFilename): if not os.path.isfile(petnamesFilename):
return '' return ''
petnamesStr = readWholeFile(petnamesFilename) with open(petnamesFilename, 'r') as petnamesFile:
if petnamesStr: petnamesStr = petnamesFile.read()
if petname + ' ' in petnamesStr: if petname + ' ' in petnamesStr:
petnamesList = petnamesStr.split('\n') petnamesList = petnamesStr.split('\n')
for pet in petnamesList: for pet in petnamesList:

View File

@ -72,7 +72,6 @@ from git import convertPostToPatch
from linked_data_sig import generateJsonSignature from linked_data_sig import generateJsonSignature
from petnames import resolvePetnames from petnames import resolvePetnames
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def isModerator(baseDir: str, nickname: str) -> bool: def isModerator(baseDir: str, nickname: str) -> bool:
@ -3023,8 +3022,9 @@ def _addPostToTimeline(filePath: str, boxname: str,
postsInBox: [], boxActor: str) -> bool: postsInBox: [], boxActor: str) -> bool:
""" Reads a post from file and decides whether it is valid """ Reads a post from file and decides whether it is valid
""" """
postStr = readWholeFile(filePath) with open(filePath, 'r') as postFile:
if postStr: postStr = postFile.read()
if filePath.endswith('.json'): if filePath.endswith('.json'):
repliesFilename = filePath.replace('.json', '.replies') repliesFilename = filePath.replace('.json', '.replies')
if os.path.isfile(repliesFilename): if os.path.isfile(repliesFilename):
@ -3715,7 +3715,9 @@ def getPublicPostDomainsBlocked(session, baseDir: str,
return [] return []
# read the blocked domains as a single string # read the blocked domains as a single string
blockedStr = readWholeFile(blockingFilename) blockedStr = ''
with open(blockingFilename, 'r') as fp:
blockedStr = fp.read()
blockedDomains = [] blockedDomains = []
for domainName in postDomains: for domainName in postDomains:
@ -3764,7 +3766,8 @@ def checkDomains(session, baseDir: str,
updateFollowerWarnings = False updateFollowerWarnings = False
followerWarningStr = '' followerWarningStr = ''
if os.path.isfile(followerWarningFilename): if os.path.isfile(followerWarningFilename):
followerWarningStr = readWholeFile(followerWarningFilename) with open(followerWarningFilename, 'r') as fp:
followerWarningStr = fp.read()
if singleCheck: if singleCheck:
# checks a single random non-mutual # checks a single random non-mutual

View File

@ -22,8 +22,6 @@ from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import isPGPEncrypted from utils import isPGPEncrypted
from content import htmlReplaceQuoteMarks from content import htmlReplaceQuoteMarks
from storage import readFileLines
from storage import readWholeFile
speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!') speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!')
@ -137,8 +135,8 @@ def _speakerPronounce(baseDir: str, sayText: str, translate: {}) -> str:
")": "," ")": ","
} }
if os.path.isfile(pronounceFilename): if os.path.isfile(pronounceFilename):
pronounceList = readFileLines(pronounceFilename) with open(pronounceFilename, 'r') as fp:
if pronounceList: pronounceList = fp.readlines()
for conversion in pronounceList: for conversion in pronounceList:
separator = None separator = None
if '->' in conversion: if '->' in conversion:
@ -496,8 +494,8 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str,
accountsDir = baseDir + '/accounts/' + nickname + '@' + domainFull accountsDir = baseDir + '/accounts/' + nickname + '@' + domainFull
approveFollowsFilename = accountsDir + '/followrequests.txt' approveFollowsFilename = accountsDir + '/followrequests.txt'
if os.path.isfile(approveFollowsFilename): if os.path.isfile(approveFollowsFilename):
follows = readFileLines(approveFollowsFilename) with open(approveFollowsFilename, 'r') as fp:
if follows: follows = fp.readlines()
if len(follows) > 0: if len(follows) > 0:
followRequestsExist = True followRequestsExist = True
for i in range(len(follows)): for i in range(len(follows)):
@ -514,7 +512,8 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str,
likedBy = '' likedBy = ''
likeFilename = accountsDir + '/.newLike' likeFilename = accountsDir + '/.newLike'
if os.path.isfile(likeFilename): if os.path.isfile(likeFilename):
likedBy = readWholeFile(likeFilename) with open(likeFilename, 'r') as fp:
likedBy = fp.read()
calendarFilename = accountsDir + '/.newCalendar' calendarFilename = accountsDir + '/.newCalendar'
postCal = os.path.isfile(calendarFilename) postCal = os.path.isfile(calendarFilename)
shareFilename = accountsDir + '/.newShare' shareFilename = accountsDir + '/.newShare'

View File

@ -54,19 +54,3 @@ def storeValue(filename: str, lineStr: str, storeType: str) -> bool:
print('WARN: Unable to prepend to ' + print('WARN: Unable to prepend to ' +
filename + ' ' + str(e)) filename + ' ' + str(e))
return False return False
def readWholeFile(filename: str) -> str:
"""Returns the entire contents of a file
"""
with open(filename, 'r') as fp:
return fp.read()
return ''
def readFileLines(filename: str) -> []:
"""Returns a list of lines from a file
"""
with open(filename, 'r') as fp:
return fp.readlines()
return []

View File

@ -17,7 +17,6 @@ from shutil import unpack_archive
from shutil import rmtree from shutil import rmtree
from content import dangerousCSS from content import dangerousCSS
from storage import storeValue from storage import storeValue
from storage import readWholeFile
def importTheme(baseDir: str, filename: str) -> bool: def importTheme(baseDir: str, filename: str) -> bool:
@ -36,9 +35,9 @@ def importTheme(baseDir: str, filename: str) -> bool:
print('WARN: ' + themeFile + print('WARN: ' + themeFile +
' missing from imported theme') ' missing from imported theme')
return False return False
newThemeName = readWholeFile(tempThemeDir + '/name.txt') newThemeName = None
if newThemeName: with open(tempThemeDir + '/name.txt', 'r') as fp:
newThemeName = newThemeName.replace('\n', '').replace('\r', '') newThemeName = fp.read().replace('\n', '').replace('\r', '')
if len(newThemeName) > 20: if len(newThemeName) > 20:
print('WARN: Imported theme name is too long') print('WARN: Imported theme name is too long')
return False return False
@ -328,8 +327,8 @@ def _setThemeFromDict(baseDir: str, name: str,
if not os.path.isfile(templateFilename): if not os.path.isfile(templateFilename):
continue continue
css = readWholeFile(templateFilename) with open(templateFilename, 'r') as cssfile:
if css: css = cssfile.read()
for paramName, paramValue in themeParams.items(): for paramName, paramValue in themeParams.items():
if paramName == 'newswire-publish-icon': if paramName == 'newswire-publish-icon':
if paramValue.lower() == 'true': if paramValue.lower() == 'true':
@ -386,8 +385,8 @@ def _setBackgroundFormat(baseDir: str, name: str,
cssFilename = baseDir + '/' + backgroundType + '.css' cssFilename = baseDir + '/' + backgroundType + '.css'
if not os.path.isfile(cssFilename): if not os.path.isfile(cssFilename):
return return
css = readWholeFile(cssFilename) with open(cssFilename, 'r') as cssfile:
if css: css = cssfile.read()
css = css.replace('background.jpg', 'background.' + extension) css = css.replace('background.jpg', 'background.' + extension)
storeValue(cssFilename, css, 'writeonly') storeValue(cssFilename, css, 'writeonly')
@ -400,8 +399,8 @@ def enableGrayscale(baseDir: str) -> None:
templateFilename = baseDir + '/' + filename templateFilename = baseDir + '/' + filename
if not os.path.isfile(templateFilename): if not os.path.isfile(templateFilename):
continue continue
css = readWholeFile(templateFilename) with open(templateFilename, 'r') as cssfile:
if css: css = cssfile.read()
if 'grayscale' not in css: if 'grayscale' not in css:
css = \ css = \
css.replace('body, html {', css.replace('body, html {',
@ -421,8 +420,8 @@ def disableGrayscale(baseDir: str) -> None:
templateFilename = baseDir + '/' + filename templateFilename = baseDir + '/' + filename
if not os.path.isfile(templateFilename): if not os.path.isfile(templateFilename):
continue continue
css = readWholeFile(templateFilename) with open(templateFilename, 'r') as cssfile:
if css: css = cssfile.read()
if 'grayscale' in css: if 'grayscale' in css:
css = \ css = \
css.replace('\n filter: grayscale(100%);', '') css.replace('\n filter: grayscale(100%);', '')
@ -457,8 +456,8 @@ def _setCustomFont(baseDir: str):
templateFilename = baseDir + '/' + filename templateFilename = baseDir + '/' + filename
if not os.path.isfile(templateFilename): if not os.path.isfile(templateFilename):
continue continue
css = readWholeFile(templateFilename) with open(templateFilename, 'r') as cssfile:
if css: css = cssfile.read()
css = \ css = \
setCSSparam(css, "*src", setCSSparam(css, "*src",
"url('./fonts/custom." + "url('./fonts/custom." +
@ -541,9 +540,10 @@ def getTextModeBanner(baseDir: str) -> str:
""" """
textModeBannerFilename = baseDir + '/accounts/banner.txt' textModeBannerFilename = baseDir + '/accounts/banner.txt'
if os.path.isfile(textModeBannerFilename): if os.path.isfile(textModeBannerFilename):
bannerStr = readWholeFile(textModeBannerFilename) with open(textModeBannerFilename, 'r') as fp:
if bannerStr: bannerStr = fp.read()
return bannerStr.replace('\n', '<br>') if bannerStr:
return bannerStr.replace('\n', '<br>')
return None return None
@ -554,9 +554,10 @@ def getTextModeLogo(baseDir: str) -> str:
if not os.path.isfile(textModeLogoFilename): if not os.path.isfile(textModeLogoFilename):
textModeLogoFilename = baseDir + '/img/logo.txt' textModeLogoFilename = baseDir + '/img/logo.txt'
logoStr = readWholeFile(textModeLogoFilename) with open(textModeLogoFilename, 'r') as fp:
if logoStr: logoStr = fp.read()
return logoStr.replace('\n', '<br>') if logoStr:
return logoStr.replace('\n', '<br>')
return None return None

View File

@ -19,7 +19,6 @@ from followingCalendar import addPersonToCalendar
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes
from storage import storeValue from storage import storeValue
from storage import readWholeFile
# posts containing these strings will always get screened out, # posts containing these strings will always get screened out,
# both incoming and outgoing. # both incoming and outgoing.
@ -164,8 +163,8 @@ def isDormant(baseDir: str, nickname: str, domain: str, actor: str,
if not os.path.isfile(lastSeenFilename): if not os.path.isfile(lastSeenFilename):
return False return False
daysSinceEpochStr = readWholeFile(lastSeenFilename) with open(lastSeenFilename, 'r') as lastSeenFile:
if daysSinceEpochStr: daysSinceEpochStr = lastSeenFile.read()
daysSinceEpoch = int(daysSinceEpochStr) daysSinceEpoch = int(daysSinceEpochStr)
currTime = datetime.datetime.utcnow() currTime = datetime.datetime.utcnow()
currDaysSinceEpoch = (currTime - datetime.datetime(1970, 1, 1)).days currDaysSinceEpoch = (currTime - datetime.datetime(1970, 1, 1)).days
@ -507,8 +506,8 @@ def loadJson(filename: str, delaySec=2, maxTries=5) -> {}:
tries = 0 tries = 0
while tries < maxTries: while tries < maxTries:
try: try:
data = readWholeFile(filename) with open(filename, 'r') as fp:
if data: data = fp.read()
jsonObject = json.loads(data) jsonObject = json.loads(data)
break break
except BaseException: except BaseException:
@ -528,13 +527,14 @@ def loadJsonOnionify(filename: str, domain: str, onionDomain: str,
tries = 0 tries = 0
while tries < 5: while tries < 5:
try: try:
data = readWholeFile(filename) with open(filename, 'r') as fp:
if data: data = fp.read()
data = data.replace(domain, onionDomain) if data:
data = data.replace('https:', 'http:') data = data.replace(domain, onionDomain)
print('*****data: ' + data) data = data.replace('https:', 'http:')
jsonObject = json.loads(data) print('*****data: ' + data)
break jsonObject = json.loads(data)
break
except BaseException: except BaseException:
print('WARN: loadJson exception') print('WARN: loadJson exception')
if delaySec > 0: if delaySec > 0:
@ -942,13 +942,14 @@ def _setDefaultPetName(baseDir: str, nickname: str, domain: str,
storeValue(petnamesFilename, petnameLookupEntry, 'writeonly') storeValue(petnamesFilename, petnameLookupEntry, 'writeonly')
return return
petnamesStr = readWholeFile(petnamesFilename) with open(petnamesFilename, 'r') as petnamesFile:
if petnamesStr: petnamesStr = petnamesFile.read()
petnamesList = petnamesStr.split('\n') if petnamesStr:
for pet in petnamesList: petnamesList = petnamesStr.split('\n')
if pet.startswith(followNickname + ' '): for pet in petnamesList:
# petname already exists if pet.startswith(followNickname + ' '):
return # petname already exists
return
# petname doesn't already exist # petname doesn't already exist
storeValue(petnamesFilename, petnameLookupEntry, 'append') storeValue(petnamesFilename, petnameLookupEntry, 'append')
@ -1093,12 +1094,13 @@ def locateNewsArrival(baseDir: str, domain: str,
accountDir = baseDir + '/accounts/news@' + domain + '/' accountDir = baseDir + '/accounts/news@' + domain + '/'
postFilename = accountDir + 'outbox/' + postUrl postFilename = accountDir + 'outbox/' + postUrl
if os.path.isfile(postFilename): if os.path.isfile(postFilename):
arrival = readWholeFile(postFilename) with open(postFilename, 'r') as arrivalFile:
if arrival: arrival = arrivalFile.read()
arrivalDate = \ if arrival:
datetime.datetime.strptime(arrival, arrivalDate = \
"%Y-%m-%dT%H:%M:%SZ") datetime.datetime.strptime(arrival,
return arrivalDate "%Y-%m-%dT%H:%M:%SZ")
return arrivalDate
return None return None
@ -1486,8 +1488,8 @@ def noOfActiveAccountsMonthly(baseDir: str, months: int) -> bool:
lastUsedFilename = \ lastUsedFilename = \
baseDir + '/accounts/' + account + '/.lastUsed' baseDir + '/accounts/' + account + '/.lastUsed'
if os.path.isfile(lastUsedFilename): if os.path.isfile(lastUsedFilename):
lastUsed = readWholeFile(lastUsedFilename) with open(lastUsedFilename, 'r') as lastUsedFile:
if lastUsed: lastUsed = lastUsedFile.read()
if lastUsed.isdigit(): if lastUsed.isdigit():
timeDiff = (currTime - int(lastUsed)) timeDiff = (currTime - int(lastUsed))
if timeDiff < monthSeconds: if timeDiff < monthSeconds:
@ -1643,8 +1645,8 @@ def getCSS(baseDir: str, cssFilename: str, cssCache: {}) -> str:
# file hasn't changed, so return the version in the cache # file hasn't changed, so return the version in the cache
return cssCache[cssFilename][1] return cssCache[cssFilename][1]
css = readWholeFile(cssFilename) with open(cssFilename, 'r') as fpCSS:
if css: css = fpCSS.read()
if cssCache.get(cssFilename): if cssCache.get(cssFilename):
# alter the cache contents # alter the cache contents
cssCache[cssFilename][0] = lastModified cssCache[cssFilename][0] = lastModified
@ -1754,8 +1756,9 @@ def _searchVirtualBoxPosts(baseDir: str, nickname: str, domain: str,
postFilename = path + '/' + postFilename.strip() postFilename = path + '/' + postFilename.strip()
if not os.path.isfile(postFilename): if not os.path.isfile(postFilename):
continue continue
data = readWholeFile(postFilename).lower() with open(postFilename, 'r') as postFile:
if data: data = postFile.read().lower()
notFound = False notFound = False
for keyword in searchWords: for keyword in searchWords:
if keyword not in data: if keyword not in data:
@ -1796,8 +1799,9 @@ def searchBoxPosts(baseDir: str, nickname: str, domain: str,
for root, dirs, fnames in os.walk(path): for root, dirs, fnames in os.walk(path):
for fname in fnames: for fname in fnames:
filePath = os.path.join(root, fname) filePath = os.path.join(root, fname)
data = readWholeFile(filePath).lower() with open(filePath, 'r') as postFile:
if data: data = postFile.read().lower()
notFound = False notFound = False
for keyword in searchWords: for keyword in searchWords:
if keyword not in data: if keyword not in data:

View File

@ -13,7 +13,6 @@ from utils import getConfigParam
from webapp_utils import htmlHeaderWithWebsiteMarkup from webapp_utils import htmlHeaderWithWebsiteMarkup
from webapp_utils import htmlFooter from webapp_utils import htmlFooter
from webapp_utils import markdownToHtml from webapp_utils import markdownToHtml
from storage import readWholeFile
def htmlAbout(cssCache: {}, baseDir: str, httpPrefix: str, def htmlAbout(cssCache: {}, baseDir: str, httpPrefix: str,
@ -33,9 +32,8 @@ def htmlAbout(cssCache: {}, baseDir: str, httpPrefix: str,
aboutText = 'Information about this instance goes here.' aboutText = 'Information about this instance goes here.'
if os.path.isfile(baseDir + '/accounts/about.md'): if os.path.isfile(baseDir + '/accounts/about.md'):
aboutText = readWholeFile(baseDir + '/accounts/about.md') with open(baseDir + '/accounts/about.md', 'r') as aboutFile:
if aboutText: aboutText = markdownToHtml(aboutFile.read())
aboutText = markdownToHtml(aboutText)
aboutForm = '' aboutForm = ''
cssFilename = baseDir + '/epicyon-profile.css' cssFilename = baseDir + '/epicyon-profile.css'

View File

@ -18,7 +18,6 @@ from webapp_utils import headerButtonsFrontScreen
from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlHeaderWithExternalStyle
from webapp_utils import htmlFooter from webapp_utils import htmlFooter
from webapp_utils import getBannerFile from webapp_utils import getBannerFile
from storage import readWholeFile
def _linksExist(baseDir: str) -> bool: def _linksExist(baseDir: str) -> bool:
@ -404,7 +403,8 @@ def htmlEditLinks(cssCache: {}, translate: {}, baseDir: str, path: str,
linksFilename = baseDir + '/accounts/links.txt' linksFilename = baseDir + '/accounts/links.txt'
linksStr = '' linksStr = ''
if os.path.isfile(linksFilename): if os.path.isfile(linksFilename):
linksStr = readWholeFile(linksFilename) with open(linksFilename, 'r') as fp:
linksStr = fp.read()
editLinksForm += \ editLinksForm += \
'<div class="container">' '<div class="container">'
@ -426,7 +426,8 @@ def htmlEditLinks(cssCache: {}, translate: {}, baseDir: str, path: str,
aboutFilename = baseDir + '/accounts/about.md' aboutFilename = baseDir + '/accounts/about.md'
aboutStr = '' aboutStr = ''
if os.path.isfile(aboutFilename): if os.path.isfile(aboutFilename):
aboutStr = readWholeFile(aboutFilename) with open(aboutFilename, 'r') as fp:
aboutStr = fp.read()
editLinksForm += \ editLinksForm += \
'<div class="container">' '<div class="container">'
@ -444,7 +445,8 @@ def htmlEditLinks(cssCache: {}, translate: {}, baseDir: str, path: str,
TOSFilename = baseDir + '/accounts/tos.md' TOSFilename = baseDir + '/accounts/tos.md'
TOSStr = '' TOSStr = ''
if os.path.isfile(TOSFilename): if os.path.isfile(TOSFilename):
TOSStr = readWholeFile(TOSFilename) with open(TOSFilename, 'r') as fp:
TOSStr = fp.read()
editLinksForm += \ editLinksForm += \
'<div class="container">' '<div class="container">'

View File

@ -24,7 +24,6 @@ from webapp_utils import htmlFooter
from webapp_utils import getBannerFile from webapp_utils import getBannerFile
from webapp_utils import htmlPostSeparator from webapp_utils import htmlPostSeparator
from webapp_utils import headerButtonsFrontScreen from webapp_utils import headerButtonsFrontScreen
from storage import readWholeFile
def _votesIndicator(totalVotes: int, positiveVoting: bool) -> str: def _votesIndicator(totalVotes: int, positiveVoting: bool) -> str:
@ -577,7 +576,8 @@ def htmlEditNewswire(cssCache: {}, translate: {}, baseDir: str, path: str,
newswireFilename = baseDir + '/accounts/newswire.txt' newswireFilename = baseDir + '/accounts/newswire.txt'
newswireStr = '' newswireStr = ''
if os.path.isfile(newswireFilename): if os.path.isfile(newswireFilename):
newswireStr = readWholeFile(newswireFilename) with open(newswireFilename, 'r') as fp:
newswireStr = fp.read()
editNewswireForm += \ editNewswireForm += \
'<div class="container">' '<div class="container">'
@ -595,7 +595,8 @@ def htmlEditNewswire(cssCache: {}, translate: {}, baseDir: str, path: str,
filterFilename = \ filterFilename = \
baseDir + '/accounts/news@' + domain + '/filters.txt' baseDir + '/accounts/news@' + domain + '/filters.txt'
if os.path.isfile(filterFilename): if os.path.isfile(filterFilename):
filterStr = readWholeFile(filterFilename) with open(filterFilename, 'r') as filterfile:
filterStr = filterfile.read()
editNewswireForm += \ editNewswireForm += \
' <br><b><label class="labels">' + \ ' <br><b><label class="labels">' + \
@ -610,7 +611,8 @@ def htmlEditNewswire(cssCache: {}, translate: {}, baseDir: str, path: str,
hashtagRulesFilename = \ hashtagRulesFilename = \
baseDir + '/accounts/hashtagrules.txt' baseDir + '/accounts/hashtagrules.txt'
if os.path.isfile(hashtagRulesFilename): if os.path.isfile(hashtagRulesFilename):
hashtagRulesStr = readWholeFile(hashtagRulesFilename) with open(hashtagRulesFilename, 'r') as rulesfile:
hashtagRulesStr = rulesfile.read()
editNewswireForm += \ editNewswireForm += \
' <br><b><label class="labels">' + \ ' <br><b><label class="labels">' + \

View File

@ -17,7 +17,6 @@ from utils import getConfigParam
from webapp_utils import getBannerFile from webapp_utils import getBannerFile
from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlHeaderWithExternalStyle
from webapp_utils import htmlFooter from webapp_utils import htmlFooter
from storage import readWholeFile
def _htmlFollowingDataList(baseDir: str, nickname: str, def _htmlFollowingDataList(baseDir: str, nickname: str,
@ -28,33 +27,34 @@ def _htmlFollowingDataList(baseDir: str, nickname: str,
followingFilename = \ followingFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt' baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt'
if os.path.isfile(followingFilename): if os.path.isfile(followingFilename):
msg = readWholeFile(followingFilename) with open(followingFilename, 'r') as followingFile:
# add your own handle, so that you can send DMs msg = followingFile.read()
# to yourself as reminders # add your own handle, so that you can send DMs
msg += nickname + '@' + domainFull + '\n' # to yourself as reminders
# include petnames msg += nickname + '@' + domainFull + '\n'
petnamesFilename = \ # include petnames
baseDir + '/accounts/' + \ petnamesFilename = \
nickname + '@' + domain + '/petnames.txt' baseDir + '/accounts/' + \
if os.path.isfile(petnamesFilename): nickname + '@' + domain + '/petnames.txt'
followingList = [] if os.path.isfile(petnamesFilename):
petStr = readWholeFile(petnamesFilename) followingList = []
if petStr: with open(petnamesFilename, 'r') as petnamesFile:
# extract each petname and append it petStr = petnamesFile.read()
petnamesList = petStr.split('\n') # extract each petname and append it
for pet in petnamesList: petnamesList = petStr.split('\n')
followingList.append(pet.split(' ')[0]) for pet in petnamesList:
# add the following.txt entries followingList.append(pet.split(' ')[0])
followingList += msg.split('\n') # add the following.txt entries
else: followingList += msg.split('\n')
# no petnames list exists - just use following.txt else:
followingList = msg.split('\n') # no petnames list exists - just use following.txt
followingList.sort() followingList = msg.split('\n')
if followingList: followingList.sort()
for followingAddress in followingList: if followingList:
if followingAddress: for followingAddress in followingList:
listStr += \ if followingAddress:
'<option>@' + followingAddress + '</option>\n' listStr += \
'<option>@' + followingAddress + '</option>\n'
listStr += '</datalist>\n' listStr += '</datalist>\n'
return listStr return listStr