Dropdown for spoofed city

main
Bob Mottram 2021-05-09 22:21:45 +01:00
parent 67ab24db90
commit f22e6ee20a
18 changed files with 308 additions and 195 deletions

419
daemon.py
View File

@ -312,6 +312,18 @@ def saveDomainQrcode(baseDir: str, httpPrefix: str,
class PubServer(BaseHTTPRequestHandler):
protocol_version = 'HTTP/1.1'
def _getSpoofedCity(self, baseDir: str, nickname: str, domain: str) -> str:
"""Returns the name of the city to use as a GPS spoofing location for
image metadata
"""
city = self.server.city
cityFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/city.txt'
if os.path.isfile(cityFilename):
with open(cityFilename, 'r') as fp:
city = fp.read().replace('\n', '')
return city
def _getInstalceUrl(self, callingDomain: str) -> str:
"""Returns the URL for this instance
"""
@ -420,6 +432,9 @@ class PubServer(BaseHTTPRequestHandler):
eventDate = None
eventTime = None
location = None
city = self._getSpoofedCity(self.server.baseDir,
nickname, self.server.domain)
messageJson = \
createPublicPost(self.server.baseDir,
nickname,
@ -428,7 +443,7 @@ class PubServer(BaseHTTPRequestHandler):
answer, False, False, False,
commentsEnabled,
attachImageFilename, mediaType,
imageDescription, self.server.city,
imageDescription, city,
inReplyTo,
inReplyToAtomUri,
subject,
@ -1144,9 +1159,13 @@ class PubServer(BaseHTTPRequestHandler):
Client to server message post
https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery
"""
city = self.server.city
if postToNickname:
print('Posting to nickname ' + postToNickname)
self.postToNickname = postToNickname
city = self._getSpoofedCity(self.server.baseDir,
postToNickname, self.server.domain)
return postMessageToOutbox(self.server.session,
self.server.translate,
@ -1171,7 +1190,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain,
self.server.showPublishedDateOnly,
self.server.allowLocalNetworkAccess,
self.server.city)
city)
def _postToOutboxThread(self, messageJson: {}) -> bool:
"""Creates a thread to send a post
@ -4076,8 +4095,11 @@ class PubServer(BaseHTTPRequestHandler):
os.remove(postImageFilename + '.etag')
except BaseException:
pass
city = self._getSpoofedCity(baseDir, nickname, domain)
processMetaData(baseDir, nickname,
filename, postImageFilename, self.server.city)
filename, postImageFilename, city)
if os.path.isfile(postImageFilename):
print('profile update POST ' + mType +
' image or font saved to ' + postImageFilename)
@ -4228,6 +4250,13 @@ class PubServer(BaseHTTPRequestHandler):
nickname,
pwd)
# change city
if fields.get('cityDropdown'):
cityFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/city.txt'
with open(cityFilename, 'w+') as fp:
fp.write(fields['cityDropdown'])
# change displayed name
if fields.get('displayNickname'):
if fields['displayNickname'] != actorJson['name']:
@ -4246,118 +4275,175 @@ class PubServer(BaseHTTPRequestHandler):
if checkNameAndBio:
redirectPath = 'previewAvatar'
# change media instance status
if fields.get('mediaInstance'):
self.server.mediaInstance = False
self.server.defaultTimeline = 'inbox'
if fields['mediaInstance'] == 'on':
self.server.mediaInstance = True
self.server.blogsInstance = False
self.server.newsInstance = False
self.server.defaultTimeline = 'tlmedia'
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.mediaInstance:
if nickname == adminNickname:
# change media instance status
if fields.get('mediaInstance'):
self.server.mediaInstance = False
self.server.defaultTimeline = 'inbox'
if fields['mediaInstance'] == 'on':
self.server.mediaInstance = True
self.server.blogsInstance = False
self.server.newsInstance = False
self.server.defaultTimeline = 'tlmedia'
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
# is this a news theme?
if isNewsThemeName(self.server.baseDir,
self.server.themeName):
fields['newsInstance'] = 'on'
# change news instance status
if fields.get('newsInstance'):
self.server.newsInstance = False
self.server.defaultTimeline = 'inbox'
if fields['newsInstance'] == 'on':
self.server.newsInstance = True
self.server.blogsInstance = False
self.server.mediaInstance = False
self.server.defaultTimeline = 'tlfeatures'
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.newsInstance:
self.server.newsInstance = False
self.server.defaultTimeline = 'inbox'
setConfigParam(baseDir,
"newsInstance",
self.server.mediaInstance)
# change blog instance status
if fields.get('blogsInstance'):
self.server.blogsInstance = False
self.server.defaultTimeline = 'inbox'
if fields['blogsInstance'] == 'on':
self.server.blogsInstance = True
self.server.mediaInstance = False
self.server.newsInstance = False
self.server.defaultTimeline = 'tlblogs'
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.blogsInstance:
self.server.blogsInstance = False
self.server.defaultTimeline = 'inbox'
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.mediaInstance:
self.server.mediaInstance = False
self.server.defaultTimeline = 'inbox'
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
# change theme
if fields.get('themeDropdown'):
self.server.themeName = fields['themeDropdown']
setTheme(baseDir, self.server.themeName, domain,
allowLocalNetworkAccess, systemLanguage)
self.server.textModeBanner = \
getTextModeBanner(self.server.baseDir)
self.server.iconsCache = {}
self.server.fontsCache = {}
self.server.showPublishAsIcon = \
getConfigParam(self.server.baseDir,
'showPublishAsIcon')
self.server.fullWidthTimelineButtonHeader = \
getConfigParam(self.server.baseDir,
'fullWidthTimelineButtonHeader')
self.server.iconsAsButtons = \
getConfigParam(self.server.baseDir,
'iconsAsButtons')
self.server.rssIconAtTop = \
getConfigParam(self.server.baseDir,
'rssIconAtTop')
self.server.publishButtonAtTop = \
getConfigParam(self.server.baseDir,
'publishButtonAtTop')
setNewsAvatar(baseDir,
fields['themeDropdown'],
httpPrefix,
domain,
domainFull)
# is this a news theme?
if isNewsThemeName(self.server.baseDir,
self.server.themeName):
fields['newsInstance'] = 'on'
# change news instance status
if fields.get('newsInstance'):
self.server.newsInstance = False
self.server.defaultTimeline = 'inbox'
if fields['newsInstance'] == 'on':
self.server.newsInstance = True
self.server.blogsInstance = False
self.server.mediaInstance = False
self.server.defaultTimeline = 'tlfeatures'
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.newsInstance:
self.server.newsInstance = False
self.server.defaultTimeline = 'inbox'
setConfigParam(baseDir,
"newsInstance",
self.server.mediaInstance)
# change blog instance status
if fields.get('blogsInstance'):
self.server.blogsInstance = False
self.server.defaultTimeline = 'inbox'
if fields['blogsInstance'] == 'on':
self.server.blogsInstance = True
self.server.mediaInstance = False
self.server.newsInstance = False
self.server.defaultTimeline = 'tlblogs'
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
setConfigParam(baseDir,
"mediaInstance",
self.server.mediaInstance)
setConfigParam(baseDir,
"newsInstance",
self.server.newsInstance)
else:
if self.server.blogsInstance:
self.server.blogsInstance = False
self.server.defaultTimeline = 'inbox'
setConfigParam(baseDir,
"blogsInstance",
self.server.blogsInstance)
# change theme
if fields.get('themeDropdown'):
self.server.themeName = fields['themeDropdown']
setTheme(baseDir, self.server.themeName, domain,
allowLocalNetworkAccess, systemLanguage)
self.server.textModeBanner = \
getTextModeBanner(self.server.baseDir)
self.server.iconsCache = {}
self.server.fontsCache = {}
self.server.showPublishAsIcon = \
getConfigParam(self.server.baseDir,
'showPublishAsIcon')
self.server.fullWidthTimelineButtonHeader = \
getConfigParam(self.server.baseDir,
'fullWidthTimelineButtonHeader')
self.server.iconsAsButtons = \
getConfigParam(self.server.baseDir,
'iconsAsButtons')
self.server.rssIconAtTop = \
getConfigParam(self.server.baseDir,
'rssIconAtTop')
self.server.publishButtonAtTop = \
getConfigParam(self.server.baseDir,
'publishButtonAtTop')
setNewsAvatar(baseDir,
fields['themeDropdown'],
httpPrefix,
domain,
domainFull)
# change instance title
if fields.get('instanceTitle'):
currInstanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
if fields['instanceTitle'] != currInstanceTitle:
setConfigParam(baseDir, 'instanceTitle',
fields['instanceTitle'])
# change YouTube alternate domain
if fields.get('ytdomain'):
currYTDomain = self.server.YTReplacementDomain
if fields['ytdomain'] != currYTDomain:
newYTDomain = fields['ytdomain']
if '://' in newYTDomain:
newYTDomain = newYTDomain.split('://')[1]
if '/' in newYTDomain:
newYTDomain = newYTDomain.split('/')[0]
if '.' in newYTDomain:
setConfigParam(baseDir,
'youtubedomain',
newYTDomain)
self.server.YTReplacementDomain = \
newYTDomain
else:
setConfigParam(baseDir,
'youtubedomain', '')
self.server.YTReplacementDomain = None
# change instance description
currInstanceDescriptionShort = \
getConfigParam(baseDir,
'instanceDescriptionShort')
if fields.get('instanceDescriptionShort'):
if fields['instanceDescriptionShort'] != \
currInstanceDescriptionShort:
iDesc = fields['instanceDescriptionShort']
setConfigParam(baseDir,
'instanceDescriptionShort',
iDesc)
else:
if currInstanceDescriptionShort:
setConfigParam(baseDir,
'instanceDescriptionShort', '')
currInstanceDescription = \
getConfigParam(baseDir, 'instanceDescription')
if fields.get('instanceDescription'):
if fields['instanceDescription'] != \
currInstanceDescription:
setConfigParam(baseDir,
'instanceDescription',
fields['instanceDescription'])
else:
if currInstanceDescription:
setConfigParam(baseDir,
'instanceDescription', '')
# change email address
currentEmailAddress = getEmailAddress(actorJson)
@ -4538,62 +4624,6 @@ class PubServer(BaseHTTPRequestHandler):
del actorJson['alsoKnownAs']
actorChanged = True
# change instance title
if fields.get('instanceTitle'):
currInstanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
if fields['instanceTitle'] != currInstanceTitle:
setConfigParam(baseDir, 'instanceTitle',
fields['instanceTitle'])
# change YouTube alternate domain
if fields.get('ytdomain'):
currYTDomain = self.server.YTReplacementDomain
if fields['ytdomain'] != currYTDomain:
newYTDomain = fields['ytdomain']
if '://' in newYTDomain:
newYTDomain = newYTDomain.split('://')[1]
if '/' in newYTDomain:
newYTDomain = newYTDomain.split('/')[0]
if '.' in newYTDomain:
setConfigParam(baseDir,
'youtubedomain',
newYTDomain)
self.server.YTReplacementDomain = \
newYTDomain
else:
setConfigParam(baseDir,
'youtubedomain', '')
self.server.YTReplacementDomain = None
# change instance description
currInstanceDescriptionShort = \
getConfigParam(baseDir,
'instanceDescriptionShort')
if fields.get('instanceDescriptionShort'):
if fields['instanceDescriptionShort'] != \
currInstanceDescriptionShort:
iDesc = fields['instanceDescriptionShort']
setConfigParam(baseDir,
'instanceDescriptionShort',
iDesc)
else:
if currInstanceDescriptionShort:
setConfigParam(baseDir,
'instanceDescriptionShort', '')
currInstanceDescription = \
getConfigParam(baseDir, 'instanceDescription')
if fields.get('instanceDescription'):
if fields['instanceDescription'] != \
currInstanceDescription:
setConfigParam(baseDir,
'instanceDescription',
fields['instanceDescription'])
else:
if currInstanceDescription:
setConfigParam(baseDir,
'instanceDescription', '')
# change user bio
if fields.get('bio'):
if fields['bio'] != actorJson['summary']:
@ -10295,6 +10325,11 @@ class PubServer(BaseHTTPRequestHandler):
"""
if '/users/' in path and path.endswith('/editprofile'):
peertubeInstances = self.server.peertubeInstances
nickname = getNicknameFromActor(path)
if nickname:
city = self._getSpoofedCity(baseDir, nickname, domain)
else:
city = self.server.city
msg = htmlEditProfile(self.server.cssCache,
translate,
baseDir,
@ -10304,7 +10339,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.defaultTimeline,
self.server.themeName,
peertubeInstances,
self.server.textModeBanner).encode('utf-8')
self.server.textModeBanner,
city).encode('utf-8')
if msg:
msglen = len(msg)
self._set_headers('text/html', msglen,
@ -13055,9 +13091,11 @@ class PubServer(BaseHTTPRequestHandler):
filename.endswith('.gif'):
postImageFilename = filename.replace('.temp', '')
print('Removing metadata from ' + postImageFilename)
city = self._getSpoofedCity(self.server.baseDir,
nickname, self.server.domain)
processMetaData(self.server.baseDir,
nickname, filename, postImageFilename,
self.server.city)
city)
if os.path.isfile(postImageFilename):
print('POST media saved to ' + postImageFilename)
else:
@ -13162,6 +13200,8 @@ class PubServer(BaseHTTPRequestHandler):
nickname, self.server.domain)
return 1
city = self._getSpoofedCity(self.server.baseDir,
nickname, self.server.domain)
messageJson = \
createPublicPost(self.server.baseDir,
nickname,
@ -13172,7 +13212,7 @@ class PubServer(BaseHTTPRequestHandler):
False, False, False, commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['replyTo'], fields['replyTo'],
fields['subject'], fields['schedulePost'],
fields['eventDate'], fields['eventTime'],
@ -13309,6 +13349,9 @@ class PubServer(BaseHTTPRequestHandler):
imgDescription = fields['imageDescription']
if filename:
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
postJsonObject['object'] = \
attachMedia(self.server.baseDir,
self.server.httpPrefix,
@ -13319,7 +13362,7 @@ class PubServer(BaseHTTPRequestHandler):
filename,
attachmentMediaType,
imgDescription,
self.server.city)
city)
replaceYouTube(postJsonObject,
self.server.YTReplacementDomain)
@ -13341,6 +13384,9 @@ class PubServer(BaseHTTPRequestHandler):
str(fields['postUrl']))
return -1
elif postType == 'newunlisted':
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createUnlistedPost(self.server.baseDir,
nickname,
@ -13350,7 +13396,7 @@ class PubServer(BaseHTTPRequestHandler):
False, False, False, commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['replyTo'],
fields['replyTo'],
fields['subject'],
@ -13372,6 +13418,9 @@ class PubServer(BaseHTTPRequestHandler):
else:
return -1
elif postType == 'newfollowers':
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createFollowersOnlyPost(self.server.baseDir,
nickname,
@ -13383,7 +13432,7 @@ class PubServer(BaseHTTPRequestHandler):
commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['replyTo'],
fields['replyTo'],
fields['subject'],
@ -13425,6 +13474,9 @@ class PubServer(BaseHTTPRequestHandler):
maximumAttendeeCapacity = \
int(fields['maximumAttendeeCapacity'])
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createEventPost(self.server.baseDir,
nickname,
@ -13436,7 +13488,7 @@ class PubServer(BaseHTTPRequestHandler):
False, False, commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['subject'],
fields['schedulePost'],
fields['eventDate'],
@ -13462,6 +13514,9 @@ class PubServer(BaseHTTPRequestHandler):
messageJson = None
print('A DM was posted')
if '@' in mentionsStr:
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createDirectMessagePost(self.server.baseDir,
nickname,
@ -13474,7 +13529,7 @@ class PubServer(BaseHTTPRequestHandler):
commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['replyTo'],
fields['replyTo'],
fields['subject'],
@ -13503,6 +13558,9 @@ class PubServer(BaseHTTPRequestHandler):
print('A reminder was posted for ' + handle)
if '@' + handle not in mentionsStr:
mentionsStr = '@' + handle + ' ' + mentionsStr
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createDirectMessagePost(self.server.baseDir,
nickname,
@ -13513,7 +13571,7 @@ class PubServer(BaseHTTPRequestHandler):
True, False, False, False,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
None, None,
fields['subject'],
True, fields['schedulePost'],
@ -13537,6 +13595,9 @@ class PubServer(BaseHTTPRequestHandler):
# and not accounts being reported we disable any
# included fediverse addresses by replacing '@' with '-at-'
fields['message'] = fields['message'].replace('@', '-at-')
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createReportPost(self.server.baseDir,
nickname,
@ -13546,7 +13607,7 @@ class PubServer(BaseHTTPRequestHandler):
True, False, False, True,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
self.server.debug, fields['subject'])
if messageJson:
if self._postToOutbox(messageJson, __version__, nickname):
@ -13566,6 +13627,9 @@ class PubServer(BaseHTTPRequestHandler):
str(questionCtr)])
if not qOptions:
return -1
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
messageJson = \
createQuestionPost(self.server.baseDir,
nickname,
@ -13577,7 +13641,7 @@ class PubServer(BaseHTTPRequestHandler):
commentsEnabled,
filename, attachmentMediaType,
fields['imageDescription'],
self.server.city,
city,
fields['subject'],
int(fields['duration']))
if messageJson:
@ -13602,6 +13666,9 @@ class PubServer(BaseHTTPRequestHandler):
if durationStr:
if ' ' not in durationStr:
durationStr = durationStr + ' days'
city = self._getSpoofedCity(self.server.baseDir,
nickname,
self.server.domain)
addShare(self.server.baseDir,
self.server.httpPrefix,
nickname,
@ -13614,7 +13681,7 @@ class PubServer(BaseHTTPRequestHandler):
fields['location'],
durationStr,
self.server.debug,
self.server.city)
city)
if filename:
if os.path.isfile(filename):
os.remove(filename)
@ -14837,10 +14904,6 @@ def runDaemon(city: str,
# spoofed city for gps location misdirection
httpd.city = city
cityFilename = baseDir + '/accounts/city.txt'
if os.path.isfile(cityFilename):
with open(cityFilename, 'r') as fp:
httpd.city = fp.read().replace('\n', '')
# For moderated newswire feeds this is the amount of time allowed
# for voting after the post arrives

View File

@ -440,5 +440,6 @@
"These access keys may be used": "قد يتم استخدام مفاتيح الوصول هذه، عادة مع مفتاح ALT + SHIFT + مفتاح ALT +",
"Show numbers of accounts within instance metadata": "إظهار عدد الحسابات داخل البيانات الوصفية للمثيلات",
"Show version number within instance metadata": "إظهار رقم الإصدار داخل البيانات الوصفية للمثيل",
"Joined": "تاريخ الانضمام"
"Joined": "تاريخ الانضمام",
"City for spoofed GPS image metadata": "مدينة للبيانات الوصفية لصور GPS المخادعة"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Es poden utilitzar aquestes tecles d'accés, típicament amb Alt + Maj + tecla o Alt + clau",
"Show numbers of accounts within instance metadata": "Mostra el nombre de comptes a les metadades de la instància",
"Show version number within instance metadata": "Mostra el número de versió a les metadades de la instància",
"Joined": "Data d'unió"
"Joined": "Data d'unió",
"City for spoofed GPS image metadata": "Ciutat per a metadades d'imatges GPS falsificades"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Gellir defnyddio'r allweddi mynediad hyn, fel arfer gyda ALT + Shift + Allwedd Allwedd neu ALT +",
"Show numbers of accounts within instance metadata": "Dangos nifer y cyfrifon o fewn metadata",
"Show version number within instance metadata": "Dangos rhif y fersiwn o fewn metadata",
"Joined": "Dyddiad ymuno"
"Joined": "Dyddiad ymuno",
"City for spoofed GPS image metadata": "Dinas ar gyfer metadata delwedd GPS spoofed"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Diese Zugriffstasten können verwendet werden, typischerweise mit ALT + SHIFT + -Taste oder ALT + -Taste",
"Show numbers of accounts within instance metadata": "Anzahl der Konten in Instanzmetadaten anzeigen",
"Show version number within instance metadata": "Versionsnummer in Instanzmetadaten anzeigen",
"Joined": "Verbundenes Datum"
"Joined": "Verbundenes Datum",
"City for spoofed GPS image metadata": "Stadt für gefälschte GPS-Bildmetadaten"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key",
"Show numbers of accounts within instance metadata": "Show numbers of accounts within instance metadata",
"Show version number within instance metadata": "Show version number within instance metadata",
"Joined": "Joined"
"Joined": "Joined",
"City for spoofed GPS image metadata": "City for spoofed GPS image metadata"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Se pueden usar estas teclas de acceso, típicamente con teclas ALT + MAYÚS + teclas o ALT +",
"Show numbers of accounts within instance metadata": "Muestra el número de cuentas dentro de los metadatos de la instancia.",
"Show version number within instance metadata": "Mostrar el número de versión dentro de los metadatos de la instancia",
"Joined": "Fecha unida"
"Joined": "Fecha unida",
"City for spoofed GPS image metadata": "Ciudad para metadatos de imagen GPS falsificados"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Ces touches d'accès peuvent être utilisées typiquement avec une touche Alt + Maj + ou Alt +",
"Show numbers of accounts within instance metadata": "Afficher le nombre de comptes dans les métadonnées de l'instance",
"Show version number within instance metadata": "Afficher le numéro de version dans les métadonnées de l'instance",
"Joined": "Joint"
"Joined": "Joint",
"City for spoofed GPS image metadata": "Ville pour les métadonnées d'image GPS falsifiées"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Is féidir na heochracha rochtana seo a úsáid, de ghnáth le Alt + Shift + Eochair nó Alt + Eochair",
"Show numbers of accounts within instance metadata": "Taispeáin líon na gcuntas laistigh de mheiteashonraí",
"Show version number within instance metadata": "Taispeáin uimhir an leagain laistigh de mheiteashonraí",
"Joined": "Dáta comhcheangailte"
"Joined": "Dáta comhcheangailte",
"City for spoofed GPS image metadata": "Cathair le haghaidh meiteashonraí íomhá GPS spoofed"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "इन एक्सेस कुंजियों का उपयोग किया जा सकता है, आमतौर पर Alt + Shift + कुंजी या Alt + कुंजी के साथ",
"Show numbers of accounts within instance metadata": "उदाहरण मेटाडेटा के भीतर खातों की संख्या दिखाएं",
"Show version number within instance metadata": "उदाहरण मेटाडेटा के भीतर संस्करण संख्या दिखाएं",
"Joined": "दिनांक"
"Joined": "दिनांक",
"City for spoofed GPS image metadata": "स्पूफ जीपीएस जीपीएस मेटाडेटा के लिए शहर"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Questi tasti di accesso possono essere utilizzati, in genere con tasto ALT + MAIUSC + o ALT + Key",
"Show numbers of accounts within instance metadata": "Mostra il numero di account all'interno dei metadati dell'istanza",
"Show version number within instance metadata": "Mostra il numero di versione nei metadati dell'istanza",
"Joined": "Unito"
"Joined": "Unito",
"City for spoofed GPS image metadata": "Città per metadati di immagini GPS falsificate"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "これらのアクセスキーは、通常はAlt + Shift +キーまたはAlt +キーを使用して使用できます。",
"Show numbers of accounts within instance metadata": "インスタンスメタデータ内のアカウント数を表示する",
"Show version number within instance metadata": "インスタンスメタデータ内にバージョン番号を表示する",
"Joined": "参加日"
"Joined": "参加日",
"City for spoofed GPS image metadata": "なりすましGPS画像メタデータの都市"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Dibe ku ev keysên gihîştinê bikar bînin, bi gelemperî bi alt + shift + key an alt + key",
"Show numbers of accounts within instance metadata": "Di nav metadata mînakê de hejmarên hesaban nîşan bidin",
"Show version number within instance metadata": "Di nav metadata mînakê de nimreya guhertoyê nîşan bide",
"Joined": "Beşdarbûna Dîrokê"
"Joined": "Beşdarbûna Dîrokê",
"City for spoofed GPS image metadata": "Bajar ji bo metadata wêneya GPS ya xapînok"
}

View File

@ -436,5 +436,6 @@
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key",
"Show numbers of accounts within instance metadata": "Show numbers of accounts within instance metadata",
"Show version number within instance metadata": "Show version number within instance metadata",
"Joined": "Joined"
"Joined": "Joined",
"City for spoofed GPS image metadata": "City for spoofed GPS image metadata"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Essas teclas de acesso podem ser usadas, normalmente com tecla Alt + Shift + Key ou Alt +",
"Show numbers of accounts within instance metadata": "Mostra o número de contas nos metadados da instância",
"Show version number within instance metadata": "Mostrar o número da versão nos metadados da instância",
"Joined": "Data juntada"
"Joined": "Data juntada",
"City for spoofed GPS image metadata": "Cidade para metadados de imagem GPS falsificados"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "Эти ключевые ключи доступа могут быть использованы, обычно с ALT + Shift + Key или Alt + Key",
"Show numbers of accounts within instance metadata": "Показать количество учетных записей в метаданных экземпляра",
"Show version number within instance metadata": "Показать номер версии в метаданных экземпляра",
"Joined": "Присоединенная дата"
"Joined": "Присоединенная дата",
"City for spoofed GPS image metadata": "Город для поддельных метаданных изображения GPS"
}

View File

@ -440,5 +440,6 @@
"These access keys may be used": "可以使用这些访问密钥通常使用Alt + Shift +键或ALT +键",
"Show numbers of accounts within instance metadata": "显示实例元数据中的帐户数",
"Show version number within instance metadata": "在实例元数据中显示版本号",
"Joined": "加入日期"
"Joined": "加入日期",
"City for spoofed GPS image metadata": "欺骗性GPS影像元数据的城市"
}

View File

@ -1068,7 +1068,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str,
defaultTimeline: str, theme: str,
peertubeInstances: [],
textModeBanner: str) -> str:
textModeBanner: str, city: str) -> str:
"""Shows the edit profile screen
"""
imageFormats = getImageFormats()
@ -1770,6 +1770,40 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
editProfileForm += '<details><summary class="cw">' + \
translate['Filtering and Blocking'] + '</summary>\n'
editProfileForm += ' <div class="container">\n'
editProfileForm += \
'<label class="labels">' + \
translate['City for spoofed GPS image metadata'] + \
'</label><br>\n'
cityFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/city.txt'
if os.path.isfile(cityFilename):
with open(cityFilename, 'r') as fp:
city = fp.read().replace('\n', '')
locationsFilename = baseDir + '/custom_locations.txt'
if not os.path.isfile(locationsFilename):
locationsFilename = baseDir + '/locations.txt'
cities = []
with open(locationsFilename, "r") as f:
cities = f.readlines()
editProfileForm += ' <select id="cityDropdown" ' + \
'name="cityDropdown" class="theme">\n'
city = city.lower()
for cityName in cities:
if ':' not in cityName:
continue
citySelected = ''
cityName = cityName.split(':')[0]
cityName = cityName.lower()
if city in cityName:
citySelected = ' selected'
editProfileForm += \
' <option value="' + cityName + \
'"' + citySelected.title() + '>' + \
cityName + '</option>\n'
editProfileForm += ' </select><br>\n'
editProfileForm += \
' <b><label class="labels">' + \
translate['Filtered words'] + '</label></b>\n'