mirror of https://gitlab.com/bashrc2/epicyon
Nogo areas for spoofed locations, to avoid rivers or sea
parent
4899fdea28
commit
69f9938846
132
city.py
132
city.py
|
@ -126,10 +126,45 @@ def _getCityPulse(currTimeOfDay, decoySeed: int) -> (float, float):
|
|||
return distanceFromCityCenter, angleRadians
|
||||
|
||||
|
||||
def parseNogoString(nogoLine: str) -> []:
|
||||
"""Parses a line from locations_nogo.txt and returns the polygon
|
||||
"""
|
||||
polygonStr = nogoLine.split(':', 1)[1]
|
||||
if ';' in polygonStr:
|
||||
pts = polygonStr.split(';')
|
||||
else:
|
||||
pts = polygonStr.split(',')
|
||||
if len(pts) <= 4:
|
||||
return []
|
||||
polygon = []
|
||||
for index in range(int(len(pts)/2)):
|
||||
if index*2 + 1 >= len(pts):
|
||||
break
|
||||
longitudeStr = pts[index*2].strip()
|
||||
latitudeStr = pts[index*2 + 1].strip()
|
||||
if 'E' in latitudeStr or 'W' in latitudeStr:
|
||||
longitudeStr = pts[index*2 + 1].strip()
|
||||
latitudeStr = pts[index*2].strip()
|
||||
if 'E' in longitudeStr:
|
||||
longitudeStr = \
|
||||
longitudeStr.replace('E', '')
|
||||
longitude = float(longitudeStr)
|
||||
elif 'W' in longitudeStr:
|
||||
longitudeStr = \
|
||||
longitudeStr.replace('W', '')
|
||||
longitude = -float(longitudeStr)
|
||||
else:
|
||||
longitude = float(longitudeStr)
|
||||
latitude = float(latitudeStr)
|
||||
polygon.append([latitude, longitude])
|
||||
return polygon
|
||||
|
||||
|
||||
def spoofGeolocation(baseDir: str,
|
||||
city: str, currTime, decoySeed: int,
|
||||
citiesList: []) -> (float, float, str, str,
|
||||
str, str, int):
|
||||
citiesList: [],
|
||||
nogoList: []) -> (float, float, str, str,
|
||||
str, str, int):
|
||||
"""Given a city and the current time spoofs the location
|
||||
for an image
|
||||
returns latitude, longitude, N/S, E/W,
|
||||
|
@ -138,6 +173,11 @@ def spoofGeolocation(baseDir: str,
|
|||
locationsFilename = baseDir + '/custom_locations.txt'
|
||||
if not os.path.isfile(locationsFilename):
|
||||
locationsFilename = baseDir + '/locations.txt'
|
||||
|
||||
nogoFilename = baseDir + '/custom_locations_nogo.txt'
|
||||
if not os.path.isfile(nogoFilename):
|
||||
nogoFilename = baseDir + '/locations_nogo.txt'
|
||||
|
||||
manCityRadius = 0.1
|
||||
varianceAtLocation = 0.0004
|
||||
default_latitude = 51.8744
|
||||
|
@ -156,6 +196,19 @@ def spoofGeolocation(baseDir: str,
|
|||
with open(locationsFilename, "r") as f:
|
||||
cities = f.readlines()
|
||||
|
||||
nogo = []
|
||||
if nogoList:
|
||||
nogo = nogoList
|
||||
else:
|
||||
if os.path.isfile(nogoFilename):
|
||||
with open(nogoFilename, "r") as f:
|
||||
nogoList = f.readlines()
|
||||
for line in nogoList:
|
||||
if line.startswith(city + ':'):
|
||||
polygon = parseNogoString(line)
|
||||
if polygon:
|
||||
nogo.append(polygon)
|
||||
|
||||
city = city.lower()
|
||||
for cityName in cities:
|
||||
if city in cityName.lower():
|
||||
|
@ -183,22 +236,35 @@ def spoofGeolocation(baseDir: str,
|
|||
datetime.timedelta(hours=approxTimeZone)
|
||||
camMake, camModel, camSerialNumber = \
|
||||
_getDecoyCamera(decoySeed)
|
||||
# patterns of activity change in the city over time
|
||||
(distanceFromCityCenter, angleRadians) = \
|
||||
_getCityPulse(currTimeAdjusted, decoySeed)
|
||||
# The city radius value is in longitude and the reference
|
||||
# is Manchester. Adjust for the radius of the chosen city.
|
||||
if areaKm2 > 1:
|
||||
manRadius = math.sqrt(630 / math.pi)
|
||||
radius = math.sqrt(areaKm2 / math.pi)
|
||||
cityRadius = manCityRadius * manRadius / radius
|
||||
else:
|
||||
cityRadius = manCityRadius
|
||||
# Get the position within the city, with some randomness added
|
||||
latitude += \
|
||||
distanceFromCityCenter * cityRadius * math.cos(angleRadians)
|
||||
longitude += \
|
||||
distanceFromCityCenter * cityRadius * math.sin(angleRadians)
|
||||
validCoord = False
|
||||
seedOffset = 0
|
||||
while not validCoord:
|
||||
# patterns of activity change in the city over time
|
||||
(distanceFromCityCenter, angleRadians) = \
|
||||
_getCityPulse(currTimeAdjusted, decoySeed + seedOffset)
|
||||
# The city radius value is in longitude and the reference
|
||||
# is Manchester. Adjust for the radius of the chosen city.
|
||||
if areaKm2 > 1:
|
||||
manRadius = math.sqrt(630 / math.pi)
|
||||
radius = math.sqrt(areaKm2 / math.pi)
|
||||
cityRadius = manCityRadius * manRadius / radius
|
||||
else:
|
||||
cityRadius = manCityRadius
|
||||
# Get the position within the city, with some randomness added
|
||||
latitude += \
|
||||
distanceFromCityCenter * cityRadius * \
|
||||
math.cos(angleRadians)
|
||||
longitude += \
|
||||
distanceFromCityCenter * cityRadius * \
|
||||
math.sin(angleRadians)
|
||||
longval = longitude
|
||||
if longdirection == 'W':
|
||||
longval = -longitude
|
||||
validCoord = not pointInNogo(nogo, latitude, longval)
|
||||
if not validCoord:
|
||||
seedOffset += 1
|
||||
if seedOffset > 100:
|
||||
break
|
||||
# add a small amount of variance around the location
|
||||
fraction = randint(0, 100000) / 100000
|
||||
distanceFromLocation = fraction * fraction * varianceAtLocation
|
||||
|
@ -229,3 +295,33 @@ def getSpoofedCity(city: str, baseDir: str, nickname: str, domain: str) -> str:
|
|||
with open(cityFilename, 'r') as fp:
|
||||
city = fp.read().replace('\n', '')
|
||||
return city
|
||||
|
||||
|
||||
def _pointInPolygon(poly: [], x: float, y: float) -> bool:
|
||||
"""Returns true if the given point is inside the given polygon
|
||||
"""
|
||||
n = len(poly)
|
||||
inside = False
|
||||
p2x = 0.0
|
||||
p2y = 0.0
|
||||
xints = 0.0
|
||||
p1x, p1y = poly[0]
|
||||
for i in range(n + 1):
|
||||
p2x, p2y = poly[i % n]
|
||||
if y > min(p1y, p2y):
|
||||
if y <= max(p1y, p2y):
|
||||
if x <= max(p1x, p2x):
|
||||
if p1y != p2y:
|
||||
xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
|
||||
if p1x == p2x or x <= xints:
|
||||
inside = not inside
|
||||
p1x, p1y = p2x, p2y
|
||||
|
||||
return inside
|
||||
|
||||
|
||||
def pointInNogo(nogo: [], latitude: float, longitude: float) -> bool:
|
||||
for polygon in nogo:
|
||||
if _pointInPolygon(polygon, latitude, longitude):
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
NEW YORK, USA: 73.951W,40.879, 73.974W,40.83, 74.029W,40.756, 74.038W,40.713, 74.056W,40.713, 74.127W,40.647, 74.038W,40.629, 73.995W,40.667, 74.014W,40.676, 73.994W,40.702, 73.967W,40.699, 73.958W,40.729, 73.956W,40.745, 73.918W,40.781, 73.937W,40.793, 73.946W,40.782, 73.977W,40.738, 73.98W,40.713, 74.012W,40.705, 74.006W,40.752, 73.955W,40.824
|
||||
NEW YORK, USA: 74.115W,40.663, 74.065W,40.602, 74.118W,40.555, 74.047W,40.516, 73.882W,40.547, 73.909W,40.618, 73.978W,40.579, 74.009W,40.602, 74.033W,40.61, 74.039W,40.623, 74.032W,40.641, 73.996W,40.665
|
2
media.py
2
media.py
|
@ -87,7 +87,7 @@ def _spoofMetaData(baseDir: str, nickname: str, domain: str,
|
|||
(latitude, longitude, latitudeRef, longitudeRef,
|
||||
camMake, camModel, camSerialNumber) = \
|
||||
spoofGeolocation(baseDir, spoofCity, currTimeAdjusted,
|
||||
decoySeed, None)
|
||||
decoySeed, None, None)
|
||||
os.system('exiftool -artist="' + nickname + '" ' +
|
||||
'-Make="' + camMake + '" ' +
|
||||
'-Model="' + camModel + '" ' +
|
||||
|
|
42
tests.py
42
tests.py
|
@ -81,7 +81,9 @@ from like import likePost
|
|||
from like import sendLikeViaServer
|
||||
from announce import announcePublic
|
||||
from announce import sendAnnounceViaServer
|
||||
from city import parseNogoString
|
||||
from city import spoofGeolocation
|
||||
from city import pointInNogo
|
||||
from media import getMediaPath
|
||||
from media import getAttachmentMediaType
|
||||
from delete import sendDeleteViaServer
|
||||
|
@ -3605,6 +3607,19 @@ def testRemovePostInteractions() -> None:
|
|||
|
||||
def testSpoofGeolocation() -> None:
|
||||
print('testSpoofGeolocation')
|
||||
nogoLine = \
|
||||
'NEW YORK, USA: 73.951W,40.879, 73.974W,40.83, ' + \
|
||||
'74.029W,40.756, 74.038W,40.713, 74.056W,40.713, ' + \
|
||||
'74.127W,40.647, 74.038W,40.629, 73.995W,40.667, ' + \
|
||||
'74.014W,40.676, 73.994W,40.702, 73.967W,40.699, ' + \
|
||||
'73.958W,40.729, 73.956W,40.745, 73.918W,40.781, ' + \
|
||||
'73.937W,40.793, 73.946W,40.782, 73.977W,40.738, ' + \
|
||||
'73.98W,40.713, 74.012W,40.705, 74.006W,40.752, ' + \
|
||||
'73.955W,40.824'
|
||||
polygon = parseNogoString(nogoLine)
|
||||
assert len(polygon) > 0
|
||||
assert polygon[0][1] == -73.951
|
||||
assert polygon[0][0] == 40.879
|
||||
citiesList = [
|
||||
'NEW YORK, USA:40.7127281:W74.0060152:784',
|
||||
'LOS ANGELES, USA:34.0536909:W118.242766:1214',
|
||||
|
@ -3613,11 +3628,23 @@ def testSpoofGeolocation() -> None:
|
|||
'BERLIN, GERMANY:52.5170365:13.3888599:891',
|
||||
'ANKARA, TURKEY:39.93:32.85:24521'
|
||||
]
|
||||
testSquare = [
|
||||
[[0.03, 0.01], [0.02, 10], [10.01, 10.02], [10.03, 0.02]]
|
||||
]
|
||||
assert pointInNogo(testSquare, 5, 5)
|
||||
assert pointInNogo(testSquare, 2, 3)
|
||||
assert not pointInNogo(testSquare, 20, 5)
|
||||
assert not pointInNogo(testSquare, 11, 6)
|
||||
assert not pointInNogo(testSquare, 5, -5)
|
||||
assert not pointInNogo(testSquare, 5, 11)
|
||||
assert not pointInNogo(testSquare, -5, -5)
|
||||
assert not pointInNogo(testSquare, -5, 5)
|
||||
nogoList = []
|
||||
currTime = datetime.datetime.utcnow()
|
||||
decoySeed = 7634681
|
||||
cityRadius = 0.1
|
||||
coords = spoofGeolocation('', 'los angeles', currTime,
|
||||
decoySeed, citiesList)
|
||||
decoySeed, citiesList, nogoList)
|
||||
assert coords[0] >= 34.0536909 - cityRadius
|
||||
assert coords[0] <= 34.0536909 + cityRadius
|
||||
assert coords[1] >= 118.242766 - cityRadius
|
||||
|
@ -3627,8 +3654,9 @@ def testSpoofGeolocation() -> None:
|
|||
assert len(coords[4]) > 4
|
||||
assert len(coords[5]) > 4
|
||||
assert coords[6] > 0
|
||||
nogoList = []
|
||||
coords = spoofGeolocation('', 'unknown', currTime,
|
||||
decoySeed, citiesList)
|
||||
decoySeed, citiesList, nogoList)
|
||||
assert coords[0] >= 51.8744 - cityRadius
|
||||
assert coords[0] <= 51.8744 + cityRadius
|
||||
assert coords[1] >= 0.368333 - cityRadius
|
||||
|
@ -3641,6 +3669,14 @@ def testSpoofGeolocation() -> None:
|
|||
kmlStr = '<?xml version="1.0" encoding="UTF-8"?>\n'
|
||||
kmlStr += '<kml xmlns="http://www.opengis.net/kml/2.2">\n'
|
||||
kmlStr += '<Document>\n'
|
||||
nogoLine2 = \
|
||||
'NEW YORK, USA: 74.115W,40.663, 74.065W,40.602, ' + \
|
||||
'74.118W,40.555, 74.047W,40.516, 73.882W,40.547, ' + \
|
||||
'73.909W,40.618, 73.978W,40.579, 74.009W,40.602, ' + \
|
||||
'74.033W,40.61, 74.039W,40.623, 74.032W,40.641, ' + \
|
||||
'73.996W,40.665'
|
||||
polygon2 = parseNogoString(nogoLine2)
|
||||
nogoList = [polygon, polygon2]
|
||||
for i in range(1000):
|
||||
dayNumber = randint(10, 30)
|
||||
hour = randint(1, 23)
|
||||
|
@ -3651,7 +3687,7 @@ def testSpoofGeolocation() -> None:
|
|||
" " + hourStr + ":14",
|
||||
"%Y-%m-%d %H:%M")
|
||||
coords = spoofGeolocation('', 'new york, usa', currTime,
|
||||
decoySeed, citiesList)
|
||||
decoySeed, citiesList, nogoList)
|
||||
longitude = coords[1]
|
||||
if coords[3] == 'W':
|
||||
longitude = -coords[1]
|
||||
|
|
Loading…
Reference in New Issue