summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift/Examples/ContactsMap.lua')
-rw-r--r--Sluift/Examples/ContactsMap.lua120
1 files changed, 120 insertions, 0 deletions
diff --git a/Sluift/Examples/ContactsMap.lua b/Sluift/Examples/ContactsMap.lua
new file mode 100644
index 0000000..d248dc7
--- /dev/null
+++ b/Sluift/Examples/ContactsMap.lua
@@ -0,0 +1,120 @@
+--[[
+ Copyright (c) 2013 Remko Tronçon
+ Licensed under the GNU General Public License v3.
+ See Documentation/Licenses/GPLv3.txt for more information.
+--]]
+
+--[[
+
+ Contacts map
+
+ Creates an HTML file of a map with all your contacts on it.
+
+ The following environment variables are used:
+ - SLUIFT_JID, SWIFT_PASS: JID and password to log in with
+
+--]]
+
+require "sluift"
+
+output_dir = arg[1]
+if not output_dir then
+ error("Please specify the directory to write the map to")
+end
+
+-- Collect all data
+geolocs = {}
+avatars = {}
+c = sluift.new_client(os.getenv("SLUIFT_JID"), os.getenv("SLUIFT_PASS"))
+c:connect(function ()
+ -- Indicate we're interested in getting user location information, and send initial presence
+ c:set_caps_node("http://swift.im/ContactsMap")
+ c:set_disco_info({identities = {{name = 'ContactsMap'}}, features = {
+ sluift.disco.features.DISCO_INFO,
+ sluift.disco.features.USER_LOCATION .. '+notify',
+ }})
+ c:send_presence()
+
+ -- Collect geoloc info
+ for event in c:pubsub_events {timeout = 10000} do
+ local from = sluift.jid.to_bare(event.from)
+ if event._type == 'pubsub_event_items' and event.item then
+ if event.node == sluift.disco.features.USER_LOCATION then
+ local lat, lon = event.item.latitude, event.item.longitude
+ if lat and lon then geolocs[from] = {lat = lat, lon = lon} end
+ end
+ end
+ end
+
+ -- Download the necessary avatars
+ for contact in pairs(geolocs) do
+ local vcard = c:get_vcard {to = contact}
+ if vcard and vcard.photo then
+ local avatar_hash = sluift.hexify(sluift.sha1(vcard.photo))
+ local file = io.open(output_dir.."/" .. avatar_hash .. ".png", "wb")
+ file:write(vcard.photo)
+ file:close()
+ avatars[contact] = avatar_hash
+ end
+ end
+end)
+
+-- Generate html
+min_lat, max_lat = 90, -90
+min_lon, max_lon = 180, -180
+contacts_html = {}
+for contact, geoloc in pairs(geolocs) do
+ if geoloc.lat < min_lat then min_lat = geoloc.lat end
+ if geoloc.lon < min_lon then min_lon = geoloc.lon end
+ if geoloc.lat > max_lat then max_lat = geoloc.lat end
+ if geoloc.lon > max_lon then max_lon = geoloc.lon end
+ local image = 'null'
+ if avatars[contact] then
+ image = "'" .. avatars[contact] .. ".png'"
+ end
+ contacts_html[#contacts_html+1] = "['" .. contact .. "'," .. geoloc.lat .. "," .. geoloc.lon .. "," .. image .. "]"
+end
+center_html = ((min_lat + max_lat) / 2) .. ',' .. ((min_lon + max_lon) / 2)
+
+map_html = [[
+<html>
+ <head>
+ <title>Contacts Map</title>
+ <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
+ </head>
+ <body>
+ <div id="map" style="height: 100%; width: 100%;"/>
+ <script>
+ var map = new google.maps.Map(document.getElementById('map'), {
+ zoom: 2,
+ center: new google.maps.LatLng(%(CENTER)),
+ mapTypeId: google.maps.MapTypeId.ROADMAP
+ });
+ var infowindow = new google.maps.InfoWindow();
+ var contacts = [%(CONTACTS)];
+ for (var i = 0; i < contacts.length; i++) {
+ var icon = null;
+ if (contacts[i][3]) {
+ icon = { url: contacts[i][3], scaledSize: { width: 30, height: 30} };
+ }
+ var marker = new google.maps.Marker({
+ position: new google.maps.LatLng(contacts[i][1], contacts[i][2]),
+ map: map,
+ icon: icon,
+ });
+ google.maps.event.addListener(marker, 'click', (function(marker, i) {
+ return function() {
+ infowindow.setContent(contacts[i][0]);
+ infowindow.open(map, marker);
+ }
+ })(marker, i));
+ }
+ </script>
+ </body>
+</html>
+]]
+local file = io.open(output_dir .. "/index.html", "w")
+file:write(map_html:
+ gsub('%%%(CONTACTS%)', table.concat(contacts_html, ",")):
+ gsub('%%%(CENTER%)', center_html))
+file:close()