/* Written by Martin Kleppe, modified by Ken Mayer 2010. Neither party is responsible for damage or loss due to use. http://www.flickr.com/groups/geotagging/discuss/72157594165549916/ */ (function(window, undefined){ var $, // BASE_URL = "http://192.168.1.208:8000/", BASE_URL = "https://cdn.rawgit.com/ubilabs/flickr_geocoding_bookmarklet/master/", JQUERY_SRC = "https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js", GMAPS_API = "https://maps.google.com/maps/api/js?sensor=false&libraries=places&callback=?", SAVE_URL = "https://www.flickr.com/services/rest/?jsoncallback=?", POST_URL = "https://www.flickr.com/services/rest/", BOOKMARK_URL = "https://www.flickr.com/groups/geotagging/discuss/72157594165549916/", STYLES = '#flickr_bookmarklet{font-size:12px;position:fixed;text-align:left;width:1000px;height:550px;z-index:20003;display:block;left:50%;margin-left:-505px;margin-top:-255px;top:50%;background-color:#FFF;padding:10px;-moz-box-shadow:0 0 8px rgba(0,0,0,0.5);-moz-border-radius:4px 4px 4px 4px;}#flickr_bookmarklet .foot,#flickr_bookmarklet .mode-title{display:none;}#flickr_bookmarklet .map{width:1000px;height:400px;}#flickr_bookmarklet .location-overlay-wrapper{margin:0 0 1em 0;}#flickr_bookmarklet .close{background-image:url("https://s.yimg.com/g/images/close_x_sprite.png");border:0 none;cursor:pointer;height:16px;margin:0;padding:0;position:absolute;right:10px;top:10px;width:16px;}#flickr_bookmarklet .maximize{color:#666;cursor:pointer;position:absolute;right:36px;text-align:right;text-decoration:underline;top:10px;width:100px;}#flickr_bookmarklet.maximized{width:auto;height:auto;top:10px;left:10px;right:10px;bottom:10px;margin:0;}#flickr_bookmarklet.maximized .map{width:auto;margin:0 -10px;}#flickr_bookmarklet_background{background-color:#000;height:100%;left:0;opacity:.35;position:fixed;top:0;width:100%;z-index:20002;cursor:pointer;filter:alpha(opacity=35);}#flickr_bookmarklet form input{margin:0 .5em 1em .5em;width:20em;}#flickr_bookmarklet .DisabledButt,#flickr_bookmarklet .Butt{margin-right:5px;}#flickr_bookmarklet div.spinner{background:url("https://s.yimg.com/g/images/progress/balls-24x12-white.gif") no-repeat scroll 0 5px #FFF;display:inline-block;height:25px;margin:0 0 -9px 1em;width:24px;}#flickr_bookmarklet #submit_form button{display:none;}#flickr_bookmarklet #submit_form{margin-left:1em;}#flickr_bookmarklet #submit_form,#flickr_bookmarklet #submit_form fieldset,#flickr_bookmarklet #submit_form fieldset div div{display:inline-block;}#flickr_bookmarklet.no_location{width:300px;height:70px;margin-left:-205px;margin-top:-35px;text-align:center;}#flickr_bookmarklet.no_location div{margin:.5em 0 1em 0;}#flickr_bookmarklet .link{float:right;}#flickr_bookmarklet .edit_instruction,#flickr_bookmarklet #submit_form button{display:none;}.pac-container{z-index:20004 !important;}.pac-container:after{display:none;}', API_KEY, IS_OWNER, USER_NSID, OWNER_NSID, PHOTO_ID, CSRF, MARKER_SRC = BASE_URL + "/arrow.png", PANEL_SRC = "/photo_geopanel_fragment.gne", map, autocomplete, lat, lng, zoom, map_type, initial_position, address, marker, geocoder, $map, $input, $spinner, $container, $background, $save, $cancel, $submit_form, THE_TAGS, THE_DESCRIPTION, THE_TITLE, LAST_TAG_REMOVED=false; function log(){ if (!window.location.href.match("log=true")){ return false; } if (window.console && typeof window.console.log == "function"){ console.log.apply(console, arguments); } } function initialize(){ log("Initialize"); if (!document.location.href.match("flickr.com")){ if (document.location.href.match("github") || document.location.href.match("sumaato")) { // if he click the bookmarklet link at typolis, show him some infos who to use bookmarklets alert( "Localize Bookmarklet HowTo: \n " + "- Drag this link to your bookmarks. \n " + "- Rename it if you want. \n " + "- Visit your Flickr photo page. \n " + "- Click the bookmarklet to inject the fancy code." ); } else { // ask user if he wants to move to Flickr var goto_flickr = confirm( "This bookmarklet does not work at this page.\n" + "Do you want to move over to Flickr?" ); if (goto_flickr){ document.location.href = "https://flickr.com/"; } } return; } load_jquery(); window.geocoding_bookmarklet = { initialize: initialize, reload: reload }; } function reload(){ log("Reload"); show(); $input.select(); if (map){ google.maps.event.trigger(map, "resize"); } } function load_jquery(){ log("Load jQuery"); var script = document.createElement("script"); script.src = JQUERY_SRC; script.onload = script.onreadystatechange = jquery_loaded; document.body.appendChild(script); } function load_styles(){ var style = $("<style type='text/css'>" + STYLES + "</style>"); $("head").append(style); log("Load Styles", style); } function get_secrets(){ log("Get Secrets"); try { API_KEY = window.YUI_config.flickr.api.site_key; CSRF = window.auth.csrf; var url_parts = $("meta[name='og:url']").attr("content").split('/', 6); PHOTO_ID = url_parts[5]; USER_NSID = window.auth.user.nsid; OWNER_NSID = $('.attribution-icon').attr('data-person-nsid'); IS_OWNER = (USER_NSID == OWNER_NSID); return true; } catch (ex) { return false; } } function jquery_loaded(){ log("jQuery loaded."); $ = jQuery; $.noConflict(); load_styles(); var loaded_secrets = get_secrets(); if (!loaded_secrets) { alert('Sorry, could not correctly fetch your user info'); return; } $.get(PANEL_SRC, function(html){ log("Get panel"); get_initial_position(); draw_panel(html); update_clicks(); init_form(); $spinner.hide(); $.getJSON(GMAPS_API, function(){ init_map(); init_marker(); log("Ready") }); }); } function update_clicks(){ log("Update Clicks"); $("#photo-story-copyright").click(function(){ reload(); return false; }); } function draw_empty_panel(){ log("Draw empty panel"); $container.addClass("no_location"); $container.html( "<div>Uuuh no, this photo has no location :(</div>" ); $cancel = $("<button class='Butt'>CLOSE THIS MESSAGE</button>"); $container.append($cancel); $cancel.click(hide); } function draw_panel(html){ var $close; $background = $("<div>", { id: 'flickr_bookmarklet_background', title: "Close" }); $background.click(hide); $container = $("<div>", {id: 'flickr_bookmarklet'}); $container.html(html); $close = $container.find(".close"); $close.click(hide); $container.find(".breadcrumb h3").html( 'Location for "'+ $("meta[name='og:title']").attr("content") + '":' ); $("body").append($container).append($background); log("Container:", $container, "and background:", $background, " drawn."); } function init_form(){ var $form, $button, $link; $form = $container.find("form[name=location_search]"); $input = $form.find("input"); $button = $form.find("button"); $form.prepend($("<label>", { "for": $input.attr("id") }).html("Search:")); $form.submit(function(){ address = $input.val(); find(address); set_cookie("address", address); return false; }); $spinner = $("<div class='spinner'/>"); $save = $("<button class='Butt'>SAVE LOCATION</button>"); $cancel = $("<button class='CancelButt'>CANCEL</button>"); $container.append($save); $save.click(save_position); $link = $("<a href='https://www.flickr.com/groups/geotagging/discuss/72157594165549916/' target='_blank' class='link'>Feedback</a>"); $submit_form = $("<div>", {id: "submit_form"}); $container.append($cancel).append($spinner).append($submit_form).append($link); $cancel.click(cancel); log("Form", $form, "added."); } function getQueryVariable(variable, string) { var vars = string.split("&"); if (vars[0] != undefined) { var first_var_parts = vars[0].split('?'); var first_var_parts_count = first_var_parts.length; if (first_var_parts_count > 1) { vars[0] = first_var_parts[first_var_parts_count - 1]; } } for (var i=0; i<vars.length; i++) { var pair = vars[i].split("="); if (pair[0] == variable) { return pair[1]; } } return ""; } function get_initial_position(){ log("Get Initial Position"); var map_url, match, last_location, parts = []; map_url = $(".static-maps").attr("href"); if (map_url && getQueryVariable("fLat", map_url)){ initial_position = { lat : parseFloat(getQueryVariable("fLat", map_url), 10), lng : parseFloat(getQueryVariable("fLon", map_url), 10), zoom : 20 }; } last_location = get_cookie("location"); if (last_location) { parts = last_location.split(","); } if (initial_position) { lat = initial_position.lat; lng = initial_position.lng; zoom = initial_position.zoom; } else { lat = parseFloat(parts[0], 10) || 30; lng = parseFloat(parts[1], 10) || 0; zoom = parseFloat(parts[2], 10) || 2; } map_type = parts[3]; address = get_cookie("address") || "Enter place name or address."; address = address.replace(/ /g," ").replace(/^\s+/, ""); } function init_map(){ log("Init Map"); $map = $container.find(".map"); map = new google.maps.Map($map[0], { zoom: zoom, center: new google.maps.LatLng(lat, lng), mapTypeId: map_type || google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU } }); autocomplete = new google.maps.places.Autocomplete($input[0]); autocomplete.bindTo('bounds', map); google.maps.event.addListener(autocomplete, 'place_changed', function() { var place = autocomplete.getPlace(); if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); position(place.geometry.location); } else { map.setCenter(place.geometry.location); map.setZoom(17); } position(place.geometry.location); marker.setPosition(place.geometry.location); }); geocoder = new google.maps.Geocoder(); $input.val(address).select(); } function init_marker(){ log("Init Marker"); var icon, shadow, infowindow, message, show_info, hide_info, info_hidden; icon = new google.maps.MarkerImage(MARKER_SRC, new google.maps.Size(21, 29), new google.maps.Point(0,0), new google.maps.Point(9, 28) ); shadow = new google.maps.MarkerImage(MARKER_SRC, new google.maps.Size(21, 18), new google.maps.Point(0,29), new google.maps.Point(2, 17) ); marker = new google.maps.Marker({ map: map, title: "Drag me!" , draggable: true, visible: true, icon: icon, position: map.getCenter(), shadow: shadow }); message = "<h3>Drag me</h3>"; infowindow = new google.maps.InfoWindow(); info_hidden = true; show_info = function() { infowindow.setContent(message); infowindow.open(map, marker); info_hidden = false; }; hide_info = function(){ infowindow.close(); info_hidden = true; }; google.maps.event.addListener(marker, 'click', function(){ if (info_hidden){ show_info(); } else { hide_info(); } }); google.maps.event.addListener(marker, 'dragend', function(){ position(marker.getPosition()); }); google.maps.event.addListener(map, 'click', function(event) { if (event.latLng){ hide_info(); position(event.latLng); } }); } function position(latLng){ log("Update position"); marker.setPosition(latLng); lat = latLng.lat(); lng = latLng.lng(); if (!marker.getVisible()){ marker.setVisible(true); } var info = [ latLng.toUrlValue(), map.getZoom(), map.getMapTypeId() ]; set_cookie("location", info.join(",")); } function save_position(){ log("Save position"); var theDescription =""; var theTitle=""; if ($save.hasClass("DisabledButt")){ return; } $save.removeClass("Butt").addClass("DisabledButt"); var data = {}; $spinner.show(); data = { format: "json", api_key: API_KEY, photo_id: PHOTO_ID, csrf: CSRF, lat: lat, lon: lng, accuracy: Math.min(16, map.getZoom()), method: "flickr.photos.geo.setLocation", cachebust: Number(new Date()) }; if (IS_OWNER) { $.getJSON(SAVE_URL, data, function(saveResponse){ if (saveResponse.stat == "ok"){ $submit_form.html("Location Saved"); getInfo(); } else { $submit_form.html("Error: " + saveResponse.message); } }); } else { getInfo(); } } // gets the photo title, description, and tags function getInfo() { log("Get Photo Info"); var data = { format: "json", api_key: API_KEY, csrf: CSRF, photo_id: PHOTO_ID, method: "flickr.photos.getInfo", cachebust: Number(new Date()) }; $.getJSON(SAVE_URL, data, function(infoResponse){ if (infoResponse.stat == "ok"){ THE_TAGS = infoResponse.photo.tags.tag; THE_DESCRIPTION = infoResponse.photo.description._content; THE_TITLE = infoResponse.photo.title._content; removeTags(THE_TAGS); } else { $submit_form.html("Error getting data: " + infoResponse.message); } }); } function removeTags(tagArray) { log("Remove Tags"); var removeArray = []; if (IS_OWNER) { $.each(tagArray, function() { if (this.raw.indexOf("geo:")>-1) { removeArray.push(this.id); } }); } else { $.each(tagArray, function() { if (this.raw.indexOf("geo:")>-1 && this.author==USER_NSID){ removeArray.push(this.id); } }); } while (removeArray.length > 0) { var removeMe=removeArray.shift(); if (removeArray.length == 0) { LAST_TAG_REMOVED = true; } data = { format: "json", api_key: API_KEY, csrf: CSRF, photo_id: PHOTO_ID, tag_id: removeMe, method: "flickr.photos.removeTag", cachebust: Number(new Date()) }; $.getJSON(SAVE_URL, data, function(removeResponse){ if (removeResponse.stat == "ok" && LAST_TAG_REMOVED) { saveGeotags(); } }); } if (!LAST_TAG_REMOVED) { saveGeotags(); // if there were no tags to remove } } // saves the geotags function saveGeotags() { log("Save Geo Tags"); var data, theTag = "geo:lat=" + lat + " geo:lon=" + lng + " geotagged"; data = { format: "json", api_key: API_KEY, csrf: CSRF, photo_id: PHOTO_ID, tags: theTag, method: "flickr.photos.addTags", cachebust: Number(new Date()) }; $.getJSON(SAVE_URL, data, function(tagResponse){ if (tagResponse.stat == "ok"){ $submit_form.html("Geotags saved"); if (IS_OWNER){ setDescription(); } else { addComment(theTag); } } else { $submit_form.html("Geotag error: " + tagResponse.message); if (!IS_OWNER) { theTag = "http://maps.google.com/maps?q=loc:" + theTag; addComment(theTag); } } }); } // puts the loc.alize.us link in a comment function addComment(theTag) { log("Add Comment"); var theComment = "See where this picture was taken."; if (theTag.indexOf("google.com")>0){ theTag = theTag.replace("geo:lat=",""); theTag = theTag.replace("geo:lon=",","); theTag = theTag.replace(" geotagged","&z=18"); theTag = theTag.replace(/ /g,""); theComment = theComment + ": " + theTag + " <a href='" + BOOKMARK_URL + "'>[?]</a>"; } else { theComment = "<a href='http://loc.alize.us/#/flickr:" + PHOTO_ID + "'>" + theComment + ".</a> <a href='" + BOOKMARK_URL + "'>[?]</a>"; } var data = { format: "json", api_key: API_KEY, csrf: CSRF, photo_id: PHOTO_ID, comment_text: theComment, method: "flickr.photos.comments.addComment", cachebust: Number(new Date()) }; $.getJSON(SAVE_URL, data, function(comResponse){ if (comResponse.stat == "ok"){ $submit_form.html("Comment saved"); window.location.reload(); // closes the map window after saving all locations and tags } else { $submit_form.html("Comment error: " + comResponse.message); } }); } // appends the loc.alize.us link to the description function setDescription() { log("Set Description"); var theDescription = expungeLocalize(THE_DESCRIPTION); theDescription = theDescription + "\r\r<a href='http://loc.alize.us/#/flickr:" + PHOTO_ID + "'>See where this picture was taken.</a> <a href='" + BOOKMARK_URL + "'>[?]</a>"; var data = { format: "json", api_key: API_KEY, csrf: CSRF, photo_id: PHOTO_ID, description: theDescription, title:THE_TITLE, method: "flickr.photos.setMeta", cachebust: Number(new Date()) }; $.getJSON(SAVE_URL, data, function(localResponse){ if (localResponse.stat == "ok"){ $submit_form.html("Saved"); window.location.reload(); // closes the map window after saving all locations and tags } else { $submit_form.html("Loc.alize.us error: " + localResponse.message); } }); } function expungeLocalize(theString) { log("Expunge Localize"); var regEx = new RegExp("<a.*/a>", "gi"); var theLinks = theString.match(regEx); if (theLinks) { for (var i=0;i<theLinks.length;i++){ if (theLinks[i].indexOf("geolicker")>0) { theString = theString.replace(theLinks[i],""); } } } return theString; } function find(address){ log("Find Address", address); var options = { address: address, bounds: map.getBounds() }; geocoder.geocode(options, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { var geometry = results[0].geometry; map.fitBounds(geometry.viewport); position(geometry.location); } else { alert("Could not find location."); $input.select(); } }); } function set_cookie(name, value){ log("Set Cookie", name, "to", value); var one_year = 365*60*60*24*200, expire = new Date((new Date().getTime()) + one_year); document.cookie = "ubilabs_" + name + "=" + escape(value) + "; expires=" + expire.toGMTString() + "; path=/"; } function get_cookie(name){ log("Get Cookie", name); var regex, match; regex = new RegExp("ubilabs_" + name + "[^\=]*=([^\;]*)"); match = document.cookie.match(regex); return match && unescape(match[1]); } function cancel(){ log("Cancel"); var latLng; if (initial_position){ latLng = new google.maps.LatLng( initial_position.lat, initial_position.lng ); position(latLng); map.setCenter(latLng); map.setZoom(initial_position.zoom); } else { marker.setVisible(false); } $save.removeClass("Butt").addClass("DisabledButt"); $submit_form.html(""); hide(); } function show(){ log("Show"); $background && $background.show(); $container && $container.show(); } function hide(){ log("Hide"); window.location.reload(); } initialize(); })(window);