home *** CD-ROM | disk | FTP | other *** search
-
- var gYaGeolocation;
-
- // (!fx3.0 && !macos)
- if (Ci.nsIWifiMonitor &&
- !/^darwin/i.test(Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime).OS)) {
-
- gYaGeolocation = {
- GEO_API_VERSION: "1.2",
- GEO_URL: "http://wi2geo.mobile.yandex.net/getlocation",
- GEO_KEY: "AQIAAHBWEoNf/VB4O81cL2HOFJvtdNtP",
-
- TRUSTED_DOMAINS: ["ya.ru", ".yandex.ru", ".yandex.kz", ".yandex.ua",
- ".yandex.by", ".yandex.com", ".moikrug.ru"],
-
- UPDATE_INTERVAL: 10 * 60 * 1000,
-
- PREFS_PREFIX: "yasearch.geolocation.",
-
- _inited: false,
- _updated: false,
-
- wifi: "",
- lastWifi: "",
- lastIP: "",
-
- position: null,//{"latitude":null, "longitude":null, "precision":null},
-
- _watchingTimer: null,
-
- get enabled() {
- return gYaSearchService.getBoolPref(this.PREFS_PREFIX + "enabled");
- },
-
- get WifiMonitorService() {
- return Cc["@mozilla.org/wifi/monitor;1"].getService(Ci.nsIWifiMonitor);
- },
-
- get prefBranch() {
- return Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
- },
-
- init: function YaGeoLoc_init() {
- Cu.import("resource://yasearch/JSON.jsm", this);
-
- if (this._inited)
- return;
-
- this._inited = true;
-
- OBSERVER_SERVICE.addObserver(this, "profile-before-change", false);
- this.prefBranch.addObserver(this.PREFS_PREFIX, this, false);
-
- let dataStr = gYaSearchService.getCharPref(this.PREFS_PREFIX + "position") || "";
- let savedPosition = null;
-
- try {
- savedPosition = this.JSON.parse(dataStr);
- } catch (e) {}
-
- if (savedPosition) {
- this.position = savedPosition;
- this.wifi = this.lastWifi = gYaSearchService.getCharPref(this.PREFS_PREFIX + "wifi.data") || "";
- }
-
- this.lastIP = gYaSearchService.getCharPref(this.PREFS_PREFIX + "ip") || "";
-
- if (this.enabled)
- this.startWatching();
-
- gYaSearchService.log("init\nsavedPosition: " + dataStr + "\nwifi: " + this.wifi);
- },
-
- uninit: function YaGeoLoc_uninit() {
- if (!this._inited)
- return;
-
- this._inited = false;
-
- this.stopWatching();
-
- OBSERVER_SERVICE.removeObserver(this, "profile-before-change");
- this.prefBranch.removeObserver(this.PREFS_PREFIX, this);
- gYaSearchService.log("uninit");
- },
-
- observe: function YaGeoLoc_observe(aSubject, aTopic, aData) {
- switch (aTopic) {
- case "profile-before-change":
- this.uninit();
- break;
-
- case "nsPref:changed":
- let prefName = aData.split(this.PREFS_PREFIX)[1];
- switch (prefName) {
- case "enabled":
- if (this.enabled) {
- this.startWatching();
- } else {
- this.stopWatching();
- this.removeGeoData();
- }
- break;
- }//switch
- break;//case "nsPref:changed"
-
- }//switch
- },
-
- getLocalIP: function YaGeoLoc_getLocalIP() {
- try {
- let DNSService = Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService);
- let DNSRecord = DNSService.resolve(DNSService.myHostName, DNSService.RESOLVE_BYPASS_CACHE);
- let ipAddress;
- while (DNSRecord.hasMore()) {
- ipAddress = DNSRecord.getNextAddrAsString();
-
- if (ipAddress.indexOf(":") >= 0)
- continue;
-
- return ipAddress;
- }
- } catch(e) {
- return "";
- }
- },
-
- removeGeoData: function YaGeoLogic_removeGeoData() {
- //this.wifi = "";
- this.lastWifi = "";
- this.lastIP = "";
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "wifi.data", "");
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "position", "");
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "ip", "");
- },
-
- startWatching: function YaGeoLoc_startWatching() {
- if (!this._watchingTimer) {
- this._watchingTimer = new G_Timer(this.updateOnTimer.bind(this), this.UPDATE_INTERVAL, true);
- this.WifiMonitorService.startWatching(this);
- this.updateOnTimer();
- gYaSearchService.log("geo.StartWatching");
- }
- },
-
- stopWatching: function YaGeoLoc_stopWatching() {
- if (this._watchingTimer) {
- this._watchingTimer.cancel();
- this._watchingTimer = null;
-
- this.WifiMonitorService.stopWatching(this);
-
- this.removeCookies();
- }
- },
-
- updateWiFi: function YaGeoLoc_updateWiFi(aWifiString) {
- this.wifi = aWifiString;
- gYaSearchService.log("updateWiFi: " + aWifiString);
- if (!this._updated)
- this.updateOnTimer();
- },
-
- updateOnTimer: function YaGeoLoc_updateOnTimer() {
- gYaSearchService.log("updateOnTimer");
- let ip = this.getLocalIP();
- let ipChanged = (ip != this.lastIP);
-
- if (ipChanged) {
- this.lastIP = ip;
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "ip", ip);
- }
-
- if (!this.wifi || !this.equalWiFi(this.wifi, this.lastWifi) || !this.position) {
- this.lastWifi = this.wifi;
-
- if (!this.wifi && !ipChanged && this.position) {
- this._updated = false;
- this.setCookies();
- return;
- }
-
- this._updated = true;
- this.getPositionByWiFi();
- } else {
- this._updated = false;
- this.setCookies();
- }
- },
-
- equalWiFi: function YaGeoLoc_equalWiFi(wifi1, wifi2) {
- let arr1 = wifi1.split(",");
- let arr2 = wifi2.split(",");
-
- if (arr1.length != arr2.length)
- return false;
-
- for (let i = 1, len = arr1.length; i < len; i += 3) {
- if (arr1[i] != arr2[i])
- return false;
- }
-
- return true;
- },
-
- getPositionByWiFi: function YaGeoLoc_getPositionByWiFi() {
- let params = [ "version=" + this.GEO_API_VERSION,
- "apikey=" + encodeURIComponent(this.GEO_KEY) ];
-
- if (this.wifi)
- params.push("wifinetworks=" + encodeURIComponent(this.wifi));
-
- params.push("nogeocode");
-
- gYaSearchService.xmlHttpRequest(this.GEO_URL, {
- callbackFunc: this.getPositionByWiFiCallback.bind(this),
- data: params.join("&"),
- background: true
- });
-
- gYaSearchService.log("=== GetPositionByWiFi ===\nPost data:\n" + params.join("\n"));
- },
-
- getPositionByWiFiCallback: function YaGeoLoc_getPositionByWiFiCallback(aRequest) {
- try {
- gYaSearchService.log("Wi2geo response: " + aRequest.target.responseText);
- } catch (ex) {
- gYaSearchService.log("Wi2geo response: [error]");
- }
-
- if (gYaSearchService.isReqError(aRequest))
- return;
-
- let responseXML = gYaSearchService.safeE4Xml(aRequest.target.responseXML, null, "wi2geo");
- if (!(responseXML && responseXML.iamhere.length()))
- return;
-
- responseXML = responseXML.iamhere[0];
-
- let position = { __proto__: null };
-
- for each (let aPositionProp in ["latitude", "longitude", "precision"]) {
- let element = responseXML[aPositionProp][0];
- let propValue = element ? element.toString() : null;
- if (!propValue)
- return;
-
- position[aPositionProp] = propValue;
- }
-
- position.timestamp = parseInt(Date.now() / 1000, 10);
-
- this.position = position;
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "position", this.JSON.stringify(position));
- gYaSearchService.log("getPositionByWiFiCallback: position: " + this.JSON.stringify(position));
- this.setCookies();
- },
-
- setCookies: function YaGeoLoc_setCookies(aSubCookieValue) {
- gYaSearchService.log("SetCookies");
- const cookieSvc = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
-
- this.TRUSTED_DOMAINS.forEach(function(aDomain) {
- let cookieURI = Cc["@mozilla.org/network/standard-url;1"].createInstance(Ci.nsIURI);
- cookieURI.spec = "http://" + aDomain.replace(/^\./, "");
-
- let allCookiesStr = cookieSvc.getCookieString(cookieURI, null) || "";
- let cookieMatch = allCookiesStr.match("(?:^|;)\\s*ys=([^;]*)");
- let newCookieValue = this.parseCookie(cookieMatch ? decodeURIComponent(cookieMatch[1]) : "", aSubCookieValue);
-
- let cookieStr = "ys=" + newCookieValue//encodeURIComponent(newCookieValue);
-
- if(newCookieValue.length == 0) {
- let zeroDate = new Date(0);
- cookieStr += ";expires=" + zeroDate;
- }
-
- if (aDomain.charAt(0) == ".")
- cookieStr += ";domain=" + aDomain;
-
- cookieSvc.setCookieString(cookieURI, null, cookieStr, null);
-
- gYaSearchService.log("setCookies: cookie for [" + cookieURI.spec + "]: " + cookieSvc.getCookieString(cookieURI, null));
- }, this);
- },
-
- removeCookies: function YaGeoLoc_removeCookies() {
- this.setCookies("");
- gYaSearchService.log("removeCookies");
- },
-
- parseCookie: function YaGeoLoc_parseCookie(aCookieContainerStr, aSubCookieValue) {
- let gpCookieText = typeof aSubCookieValue == "undefined" ? this.getCookieText() : aSubCookieValue;
-
- let ySubCookies = aCookieContainerStr.split("#");
- let found = false;
-
- if (gpCookieText !== null) {
- for (let i = ySubCookies.length; i--;) {
- if (ySubCookies[i].indexOf("gpauto.") == 0) {
- found = true;
- ySubCookies[i] = gpCookieText;
- break;
- }
- }
- }
-
- if (!found && gpCookieText)
- ySubCookies.push(gpCookieText);
-
- return ySubCookies.filter(function(v) !!v).join("#");
- },
-
- getCookieText: function YaGeoLoc_getCookieText() {
- let position = this.position;
-
- if (position) {
- try {
- return "gpauto." +
- [ position.latitude.replace(".", "_"),
- position.longitude.replace(".", "_"),
- position.precision,
- "1",
- parseInt(Date.now() / 1000, 10)
- ].join(":");
- } catch(e) {}
- }
-
- return null;
- },
-
- onChange: function YaGeoLoc_onChange(aAccessPoints) {
- let wifiData = aAccessPoints.map(function(aPoint, aIndex) {
- return [ aIndex, aPoint.mac.replace(/\-/g,":"), aPoint.signal ].join(",");
- }).join(",");
-
- let lastWifiData = gYaSearchService.getCharPref(this.PREFS_PREFIX + "wifi.data");
- if (wifiData == lastWifiData)
- return;
-
- gYaSearchService.setCharPref(this.PREFS_PREFIX + "wifi.data", wifiData);
-
- this.updateWiFi(wifiData);
- },
-
- onError: function YaGeoLoc_onError(aValue) {
- gYaSearchService.log("onError: Wifi scan error: " + aValue);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIWifiListener, Ci.nsIObserver])
- }
-
- }// (!fx3.0 && !macos)
-