Skip to content

Commit

Permalink
#366 additional work for handling HERE map in the admin when editing/…
Browse files Browse the repository at this point in the history
…creating an event
  • Loading branch information
syjer committed Dec 1, 2017
1 parent 8cf93b0 commit da3abcd
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/main/java/alfio/config/MvcConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response,
+ " frame-src 'self' https://js.stripe.com https://www.google.com;"
+ " font-src 'self';"//
+ " media-src blob: 'self';"//for loading camera api
+ " connect-src 'self' https://api.stripe.com https://maps.googleapis.com/;" //<- currently stripe.js use jsonp but if they switch to xmlhttprequest+cors we will be ready
+ " connect-src 'self' https://api.stripe.com https://maps.googleapis.com/ https://geocoder.cit.api.here.com;" //<- currently stripe.js use jsonp but if they switch to xmlhttprequest+cors we will be ready
+ (environment.acceptsProfiles(Initializer.PROFILE_DEBUG_CSP) ? " report-uri /report-csp-violation" : ""));
}
};
Expand Down
67 changes: 51 additions & 16 deletions src/main/java/alfio/controller/api/admin/LocationApiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import alfio.model.system.Configuration;
import alfio.model.system.ConfigurationKeys;
import com.moodysalem.TimezoneMapper;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
Expand All @@ -46,40 +48,73 @@ public String unhandledException(Exception e) {
return e.getMessage();
}

@RequestMapping(value = "/location/maps-client-api-key")
public String mapsClientApiKey() {
return configurationManager.getStringConfigValue(Configuration.getSystemConfiguration(ConfigurationKeys.MAPS_CLIENT_API_KEY)).orElse(null);
}

@RequestMapping(value = "/location/timezones")
@RequestMapping("/location/timezones")
public List<String> getTimezones() {
List<String> s = new ArrayList<>(ZoneId.getAvailableZoneIds());
s.sort(String::compareTo);
return s;
}

@RequestMapping(value = "/location/timezone")
@RequestMapping("/location/timezone")
public String getTimezone(@RequestParam("lat") double lat, @RequestParam("lng") double lng) {
String tzId = TimezoneMapper.tzNameAt(lat, lng);
return getTimezones().contains(tzId) ? tzId : null;
}

@RequestMapping(value = "/location/static-map-image")


@RequestMapping("/location/static-map-image")
public String getMapImage(
@RequestParam("lat") String lat,
@RequestParam("lng") String lng,
@RequestParam("orgId") int orgId,
@RequestParam(value = "orgId", required = false) Integer orgId,
@RequestParam(value = "eventId", required = false) Integer eventId) {

Function<ConfigurationKeys, Configuration.ConfigurationPathKey> pathKeyBuilder = (key) ->
eventId == null ? Configuration.from(orgId, key) : Configuration.from(orgId, eventId, key);
Function<ConfigurationKeys, Configuration.ConfigurationPathKey> pathKeyBuilder = (key) -> {
if(orgId == null && eventId == null) {
return Configuration.getSystemConfiguration(key);
} else if (eventId == null) {
return Configuration.from(orgId, key);
} else {
return Configuration.from(orgId, eventId, key);
}
};

Map<ConfigurationKeys, Optional<String>> geoInfoConfiguration = configurationManager.getStringConfigValueFrom(
pathKeyBuilder.apply(ConfigurationKeys.MAPS_PROVIDER),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_CLIENT_API_KEY),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_ID),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_CODE));
Map<ConfigurationKeys, Optional<String>> geoInfoConfiguration = getGeoConf(pathKeyBuilder);

return LocationDescriptor.getMapUrl(lat, lng, geoInfoConfiguration);
}

private Map<ConfigurationKeys, Optional<String>> getGeoConf(Function<ConfigurationKeys, Configuration.ConfigurationPathKey> pathKeyBuilder) {
return configurationManager.getStringConfigValueFrom(
pathKeyBuilder.apply(ConfigurationKeys.MAPS_PROVIDER),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_CLIENT_API_KEY),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_ID),
pathKeyBuilder.apply(ConfigurationKeys.MAPS_HERE_APP_CODE));
}

@RequestMapping("/location/map-provider-client-api-key")
public ProviderAndKeys getGeoInfoProviderAndKeys() {

Function<ConfigurationKeys, Configuration.ConfigurationPathKey> pathKeyBuilder = (key) -> Configuration.getSystemConfiguration(key);

Map<ConfigurationKeys, Optional<String>> geoInfoConfiguration = getGeoConf(pathKeyBuilder);

ConfigurationKeys.GeoInfoProvider provider = LocationDescriptor.getProvider(geoInfoConfiguration);

Map<ConfigurationKeys, String> apiKeys = new HashMap<>();

geoInfoConfiguration.forEach((k,v) -> {
v.ifPresent(value -> apiKeys.put(k, value));
});

return new ProviderAndKeys(provider, apiKeys);
}

@AllArgsConstructor
@Getter
public static class ProviderAndKeys {
private final ConfigurationKeys.GeoInfoProvider provider;
private Map<ConfigurationKeys, String> keys;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static String getMapUrl(String lat, String lng, Map<ConfigurationKeys, Op
}

// for backward compatibility reason, the logic is not straightforward
private static ConfigurationKeys.GeoInfoProvider getProvider(Map<ConfigurationKeys, Optional<String>> geoConf) {
public static ConfigurationKeys.GeoInfoProvider getProvider(Map<ConfigurationKeys, Optional<String>> geoConf) {
if((!geoConf.containsKey(ConfigurationKeys.MAPS_PROVIDER) || !geoConf.get(ConfigurationKeys.MAPS_PROVIDER).isPresent()) &&
(geoConf.containsKey(ConfigurationKeys.MAPS_CLIENT_API_KEY) && geoConf.get(ConfigurationKeys.MAPS_CLIENT_API_KEY).isPresent())) {
return ConfigurationKeys.GeoInfoProvider.GOOGLE;
Expand Down
136 changes: 91 additions & 45 deletions src/main/webapp/resources/js/admin/service/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,61 +334,111 @@

baseServices.service("LocationService", function($http, $q, HttpErrorHandler) {

function mapUrl(lat, lng, key) {
var reqCounter = 0;

function getMapUrl(latitude, longitude, orgId, eventId) {
return $http.get('/admin/api/location/static-map-image', {params: {lat: latitude, lng: longitude, orgId : orgId, eventId: eventId}}).then(function(res) {
return res.data;
});
}


function handleGoogleGeolocate(location, locService, apiKeyAndProvider, resolve, reject) {
var key = apiKeyAndProvider.keys['MAPS_CLIENT_API_KEY'];

var keyParam = key ? ('&key='+encodeURIComponent(key)) : '';
return "https://maps.googleapis.com/maps/api/staticmap?center="+lat+","+lng+"&zoom=16&size=400x400&markers=color:blue%7Clabel:E%7C"+lat+","+lng+""+keyParam;

if(!window.google || !window.google.maps) {

reqCounter++;

var script = document.createElement('script');

var callBackName = 'clientGeolocate'+reqCounter;

script.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback='+callBackName+keyParam;
document.head.appendChild(script);
window[callBackName] = function() {
search();
}
} else {
search();
}

function search() {
var geocoder = new window.google.maps.Geocoder();
geocoder.geocode({'address': location}, function(results, status) {
if (status === 'OK') {
var ret = {};
ret.latitude = ""+results[0].geometry.location.lat()
ret.longitude = ""+results[0].geometry.location.lng()
$q.all([getMapUrl(ret.latitude, ret.longitude), locService.getTimezone(ret.latitude, ret.longitude)]).then(function(success) {
ret.mapUrl = success[0];
var tz = success[1];
if(tz.data) {
ret.timeZone = tz.data;
}
resolve(ret);
}, function () {
reject();
})

} else {
reject();
}
});
}
}

var reqCounter = 0;

function handleHEREGeolocate(location, locService, apiKeyAndProvider, resolve, reject) {
var appId = apiKeyAndProvider.keys['MAPS_HERE_APP_ID'];
var appCode = apiKeyAndProvider.keys['MAPS_HERE_APP_CODE'];
$http.get('https://geocoder.cit.api.here.com/6.2/geocode.json', {params: {app_id: appId, app_code: appCode, searchtext: location}}).then(function(res) {
var view = res.data.Response.View;
if(view.length > 0 && view[0].Result.length > 0 && view[0].Result[0].Location) {
var location = view[0].Result[0].Location;
var pos = location.DisplayPosition;
var ret = {latitude: pos.Latitude, longitude: pos.Longitude};
console.log(view);

$q.all([getMapUrl(ret.latitude, ret.longitude), locService.getTimezone(ret.latitude, ret.longitude)]).then(function(success) {
ret.mapUrl = success[0];
var tz = success[1];
if(tz.data) {
ret.timeZone = tz.data;
}
resolve(ret);
}, function () {
reject();
})
} else {
reject();
}

}, function () {
reject();
})
}

return {
mapApiKey: function() {
return $http.get('/admin/api/location/maps-client-api-key.json').then(function(res) {
return $http.get('/admin/api/location/map-provider-client-api-key').then(function(res) {
return res.data;
});
},
clientGeolocate: function(location) {
var locService = this;
return $q(function(resolve, reject) {

locService.mapApiKey().then(function(key) {
var keyParam = key ? ('&key='+encodeURIComponent(key)) : '';

if(!window.google || !window.google.maps) {

reqCounter++;

var script = document.createElement('script');
locService.mapApiKey().then(function(apiKeyAndProvider) {

var callBackName = 'clientGeolocate'+reqCounter;

script.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback='+callBackName+keyParam;
document.head.appendChild(script);
window[callBackName] = function() {
search();
}
if(apiKeyAndProvider.provider === 'GOOGLE') {
handleGoogleGeolocate(location, locService, apiKeyAndProvider, resolve, reject);
} else if (apiKeyAndProvider.provider === 'HERE') {
handleHEREGeolocate(location, locService, apiKeyAndProvider, resolve, reject);
} else {
search();
}

function search() {
var geocoder = new window.google.maps.Geocoder();
geocoder.geocode({'address': location}, function(results, status) {
if (status === 'OK') {
var ret = {};
ret.latitude = ""+results[0].geometry.location.lat()
ret.longitude = ""+results[0].geometry.location.lng()
ret.mapUrl = mapUrl(ret.latitude, ret.longitude, key);
locService.getTimezone(ret.latitude, ret.longitude).then(function(res) {
if(res.data) {
ret.timeZone = res.data;
}
resolve(ret);
});
} else {
reject();
}
});
alert('Must provide an API key (google or HERE maps)')
}
})

Expand All @@ -400,11 +450,7 @@
getTimezones: function() {
return $http.get('/admin/api/location/timezones');
},
getMapUrl : function(latitude, longitude, orgId, eventId) {
return $http.get('/admin/api/location/static-map-image', {params: {lat: latitude, lng: longitude, orgId : orgId, eventId: eventId}}).then(function(res) {
return res.data;
});
}
getMapUrl : getMapUrl
};
});

Expand Down

0 comments on commit da3abcd

Please sign in to comment.