Skip to content

Commit

Permalink
Merge pull request #18 from posm/feature/push-upstream
Browse files Browse the repository at this point in the history
Feature/push upstream
  • Loading branch information
thenav56 authored Jan 10, 2020
2 parents c44a453 + 4df4cea commit 84a6e02
Show file tree
Hide file tree
Showing 21 changed files with 1,456 additions and 307 deletions.
71 changes: 18 additions & 53 deletions API_Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ Response
27.682648488328013
],
"description": "Map of jawalakhel",
"dateCloned": "2019-12-19T09:39:50.023973",
"totalConflictingElements": 12,
"dateCloned": "2019-12-22T09:51:04.089626",
"totalConflictingElements": 1,
"totalResolvedElements": 0,
"localChangesetsCount": 6,
"localElementsCount": {
"waysCount": 6062,
Expand All @@ -31,7 +32,7 @@ Response
"relationsCount": 48
}
},
"state": "creating_geojsons",
"state": "conflicts",
"isCurrentStateComplete": true,
"hasErrored": false
}
Expand Down Expand Up @@ -99,14 +100,8 @@ When the step *creating_geojsons* is complete, one can now ask for conflicts and
},
"properties": {
"tags": [
{
"k": "name",
"v": "Bir Hospital"
},
{
"k": "name:en",
"v": "Bir Hospital बीर अस्पताल प्रवेश द्वार ७"
}
"name": "Bir Hospital",
"name:en": "Bir Hospital",
],
"deleted": false,
"visible": true
Expand All @@ -127,14 +122,8 @@ When the step *creating_geojsons* is complete, one can now ask for conflicts and
"id": 31232256,
"uid": 864593,
"tags": [
{
"k": "name",
"v": "Bir Hospital"
},
{
"k": "name:en",
"v": "Bir Hospital बीर अस्पताल प्रवेश द्वार ७"
}
"name": "Bir Hospital",
"name:en": "Bir Hospital",
],
"type": "node",
"user": "Sazal(Solaris)",
Expand All @@ -158,14 +147,8 @@ When the step *creating_geojsons* is complete, one can now ask for conflicts and
"id": 31232256,
"uid": 864593,
"tags": [
{
"k": "name",
"v": "Bir Hospital"
},
{
"k": "name:en",
"v": "Bir Hospital बीर अस्पताल प्रवेश द्वार ७"
}
"name": "Bir Hospital",
"name:en": "Bir Hospital",
],
"type": "node",
"user": "Sazal(Solaris)",
Expand All @@ -189,14 +172,8 @@ When the step *creating_geojsons* is complete, one can now ask for conflicts and
"id": 31232256,
"uid": 864593,
"tags": [
{
"k": "name",
"v": "Bir Hospital"
},
{
"k": "name:en",
"v": "Bir Hospital बीर अस्पताल प्रवेश द्वार ७"
}
"name": "Bir Hospital",
"name:en": "Bir Hospital",
],
"type": "node",
"user": "Sazal(Solaris)",
Expand Down Expand Up @@ -224,19 +201,13 @@ Note that all the data for the element resides in the *properties* key inside ge
### Update a conflict
Send the modified values for the attributes inside the *properties* key.

`PATCH /api/v1/conflicts/update/`
`PATCH /api/v1/conflicts/160/update/`
Sample Request body:
```
{
"tags": [
{
"k": "name",
"v": "Bir Aspatal"
},
{
"k": "name:en",
"v": "Bir Hospital"
}
"name": "Bir Aspatal",
"name:en": "Vir Aspatal"
],
// nodes in the case of way
"nodes": [
Expand All @@ -248,19 +219,13 @@ Sample Request body:
```
### Resolve a conflict
If you intend to set the update as resolved, use the following. The body is same as for updating.
`PATCH /api/v1/conflicts/resolve/`
`PATCH /api/v1/conflicts/160/resolve/`
Sample Request body:
```
{
"tags": [
{
"k": "name",
"v": "Bir Aspatal"
},
{
"k": "name:en",
"v": "Bir Hospital"
}
"name": "Bir Aspatal",
"name:en": "Vir Aspatal"
],
// nodes in the case of way
"nodes": [
Expand Down
47 changes: 40 additions & 7 deletions env_sample
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
SERVER_PORT=6007
# USE posm's ip and port 81 as OSM_BASE_URL
OSM_BASE_URL=http://192.168.31.127:81
# USE posm's ip
POSM_DB_HOST=192.168.31.127

OSM_BASE_URL=http://osm.posm.io
POSM_DB_HOST=posm.io
# LOCAL POSM DB config
POSM_DB_NAME=osm
POSM_DB_USER=osm
POSM_DB_PASSWORD=whynotposm
POSM_DB_PASSWORD=pass-word


# AOI Specific files and paths

# The root is generally /aoi and it is the path within docker container mapped with host's /opt/data/aoi
# No need to change this
AOI_ROOT=/aoi
# The directory name of the AOI, resides inside AOI_ROOT
AOI_NAME=Jawalakhel
ORIGINAL_AOI_NAME=jawalakhel.pbf
# Original aoi file name, which also resides inside AOI_ROOT
ORIGINAL_AOI_FILE_NAME=jawalakhel.osm

# For osmosis, because it is run outside docker
OSMOSIS_DB_HOST=posm.io
# Config for running osmosis from inside docker

# osmosis db host is the ip of posm itself
OSMOSIS_DB_HOST=192.168.31.127
# Since osmosis is run outside docker container, it needs host path instead of path inside docker
# And it can be seen in docker-compose file that /opt/data/aoi from host is mapped to /aoi inside docker container
OSMOSIS_AOI_ROOT=/opt/data/aoi

# DB setting for server app, No need to change this
DATABASE_NAME=postgres
DATABASE_USER=postgres
DATABASE_PASSWORD=password


# OAUTH config

# Consumer keys and secrets
OAUTH_CONSUMER_KEY=consumerkeyLSDFJKDSLFKJsldkfjsdl
OAUTH_CONSUMER_SECRET=consumersecretLSDFJKDSLFKJsldkfjsdl
# In production use production osm api endpoints
OAUTH_API_URL=https://master.apis.dev.openstreetmap.org

# In production use production osm api endpoints
REQUEST_TOKEN_URL=https://master.apis.dev.openstreetmap.org/oauth/request_token
ACCESS_TOKEN_URL=https://master.apis.dev.openstreetmap.org/oauth/access_token
AUTHORIZE_URL=https://master.apis.dev.openstreetmap.org/oauth/authorize
121 changes: 121 additions & 0 deletions posm_replay/backends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import os
import threading
from xml.dom import minidom

from social_core.backends.openstreetmap import OpenStreetMapOAuth

from replay_tool.models import UpstreamChangeSet, OSMElement
from replay_tool.utils.common import create_changeset_creation_xml
from replay_tool.utils.common import get_aoi_name
from replay_tool.tasks import create_and_push_changeset

import logging

logger = logging.getLogger('__name__')


class CustomOSMOAuth(OpenStreetMapOAuth):
AUTHORIZATION_URL = os.environ['AUTHORIZE_URL']
REQUEST_TOKEN_URL = os.environ['REQUEST_TOKEN_URL']
ACCESS_TOKEN_URL = os.environ['ACCESS_TOKEN_URL']
API_URL = os.environ.get('OAUTH_API_URL', 'https://master.apis.dev.openstreetmap.org')

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.osm_user = None
self._access_token = None # self.access_token is already a method

def oauth_request(self, token, url, params=None, method='GET', data=None, headers={}):
"""Generate OAuth request, setups callback url"""
return self.request(url, method=method, params=params,
auth=self.oauth_auth(token), headers=headers, data=data)

def user_data(self, access_token, *args, **kwargs):
"""Return user data provided"""
self._access_token = access_token
url = os.path.join(self.API_URL, 'api/0.6/user/details')
response = self.oauth_request(
access_token, url
)
try:
dom = minidom.parseString(response.content)
except ValueError:
return None
self.osm_user = dom.getElementsByTagName('user')[0]
username = self.osm_user.getAttribute('display_name')
try:
avatar = dom.getElementsByTagName('img')[0].getAttribute('href')
except IndexError:
avatar = None

thread = threading.Thread(
target=create_and_push_changeset,
args=(self,),
daemon=True,
)
thread.start()

return {
'id': self.osm_user and self.osm_user.getAttribute('id'),
'username': username,
'account_created': self.osm_user and self.osm_user.getAttribute('account_created'),
'avatar': avatar,
'access_token': access_token,
}

def get_or_create_changeset(self):
# NOTE: To avoid stale changesets upstream, create new every time
UpstreamChangeSet.objects.all().delete()

# Create a changeset
aoiname = get_aoi_name()
comment = f"Updates on POSM in area '{aoiname}'"
# TODO: get version
version = '1.1'
create_changeset_xml = create_changeset_creation_xml(comment, version)

url = os.path.join(self.API_URL, 'api/0.6/changeset/create')
logger.info(f'OSM API URL: {url}')
response = self.oauth_request(
self._access_token, url, method='PUT',
headers={'Content-Type': 'text/xml'},
data=create_changeset_xml,
)

logger.info(response.text)

if not response.status_code == 200:
raise Exception(f'Could not create changeset. Error: {response.text}')

changeset_id = int(response.text)
return UpstreamChangeSet.objects.create(changeset_id=changeset_id)

def upload_changeset(self, changeset_id):
changeset_xml = OSMElement.get_upstream_changeset(changeset_id)

url = os.path.join(self.API_URL, f'api/0.6/changeset/{changeset_id}/upload')
logger.info(f'OSM API URL: {url}')
response = self.oauth_request(
self._access_token, url, method='POST',
headers={'Content-Type': 'text/xml'},
data=changeset_xml,
)
logger.info(response.text)

if not response.status_code == 200:
raise Exception(f'Could not upload changeset {changeset_id}. Error: {response.text}')

return True

def close_changeset(self, changeset_id):
url = os.path.join(self.API_URL, f'api/0.6/changeset/{changeset_id}/close')
logger.info(f'OSM API URL: {url}')
response = self.oauth_request(
self._access_token, url, method='PUT',
headers={'Content-Type': 'text/xml'},
)
logger.info(response.text)
if not response.status_code == 200:
raise Exception(f'Could not close changeset {changeset_id}. Error: {response.text}')

return True
13 changes: 13 additions & 0 deletions posm_replay/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

# SOCIAL AUTH
SOCIAL_AUTH_OPENSTREETMAP_KEY = os.environ.get('OAUTH_CONSUMER_KEY')
SOCIAL_AUTH_OPENSTREETMAP_SECRET = os.environ.get('OAUTH_CONSUMER_SECRET')
SOCIAL_AUTH_POSTGRES_JSONFIELD = True
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'

# Application definition

INSTALLED_APPS = [
Expand All @@ -42,10 +48,16 @@
'rest_framework',
'corsheaders',
'djangorestframework_camel_case',
'social_django',

'replay_tool',
]

AUTHENTICATION_BACKENDS = (
'posm_replay.backends.CustomOSMOAuth',
'django.contrib.auth.backends.ModelBackend',
)

MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
Expand Down Expand Up @@ -95,6 +107,7 @@
}
}


CELERY_REDIS_URL = os.environ.get('CELERY_REDIS_URL', 'redis://redis:6379/0')
CELERY_BROKER_URL = CELERY_REDIS_URL
CELERY_RESULT_BACKEND = CELERY_REDIS_URL
Expand Down
3 changes: 3 additions & 0 deletions posm_replay/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
trigger,
retrigger,
reset,
LoginPageView,
)


Expand All @@ -39,4 +40,6 @@
path('api/v1/reset/', reset),
path('api/v1/re-trigger/', retrigger),
path('api/v1/', include(router.urls)),
path('login/', LoginPageView.as_view()),
path('', include('social_django.urls', namespace='social')),
]
Loading

0 comments on commit 84a6e02

Please sign in to comment.