Esempio n. 1
0
class GoogleMapsScanner:
    """Representation of an Google Maps location sharing account."""

    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(
                hass, self._update_info, MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error("You have specified invalid login credentials")
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            try:
                dev_id = 'google_maps_{0}'.format(slugify(person.id))
            except TypeError:
                _LOGGER.warning("No location(s) shared with this account")
                return

            if self.max_gps_accuracy is not None and \
                    person.accuracy > self.max_gps_accuracy:
                _LOGGER.info("Ignoring %s update because expected GPS "
                             "accuracy %s is not met: %s",
                             person.nickname, self.max_gps_accuracy,
                             person.accuracy)
                continue

            attrs = {
                ATTR_ADDRESS: person.address,
                ATTR_FULL_NAME: person.full_name,
                ATTR_ID: person.id,
                ATTR_LAST_SEEN: dt_util.as_utc(person.datetime),
                ATTR_NICKNAME: person.nickname,
                ATTR_BATTERY_CHARGING: person.charging,
                ATTR_BATTERY_LEVEL: person.battery_level
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                gps_accuracy=person.accuracy,
                attributes=attrs,
            )
Esempio n. 2
0
class GoogleMapsScanner:
    """Representation of an Google Maps location sharing account."""
    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(hass, self._update_info,
                                MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error("You have specified invalid login credentials")
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            try:
                dev_id = 'google_maps_{0}'.format(slugify(person.id))
            except TypeError:
                _LOGGER.warning("No location(s) shared with this account")
                return

            if self.max_gps_accuracy is not None and \
                    person.accuracy > self.max_gps_accuracy:
                _LOGGER.info(
                    "Ignoring %s update because expected GPS "
                    "accuracy %s is not met: %s", person.nickname,
                    self.max_gps_accuracy, person.accuracy)
                continue

            attrs = {
                ATTR_ADDRESS: person.address,
                ATTR_FULL_NAME: person.full_name,
                ATTR_ID: person.id,
                ATTR_LAST_SEEN: person.datetime,
                ATTR_NICKNAME: person.nickname,
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                gps_accuracy=person.accuracy,
                attributes=attrs,
            )
Esempio n. 3
0
def get_people_latlons():
    service = Service(cookies_file='cookies.txt',
                      authenticating_account=os.getenv('GOOGLE_ACCOUNT_EMAIL'))
    people = {}
    for person in service.get_all_people():
        people[person.nickname] = {
            'lat': person.latitude,
            'lon': person.longitude
        }
        print(person.nickname, person.latitude, person.longitude)
    return people
Esempio n. 4
0
def get_location():
  cookies_file = 'location_sharing.cookies'
  google_email = '*****@*****.**'


  service = Service(cookies_file=cookies_file, authenticating_account=google_email)

  person = list(service.get_all_people())[0]
  for location in settings.locations:
    dist = geodesic((person.latitude,person.longitude),location[1]).miles 
    if dist <= location[2]:
      return location[0]
Esempio n. 5
0
class GoogleMapsScanner(object):
    """Representation of an Google Maps location sharing account."""

    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(
                hass, self._update_info, MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error('You have specified invalid login credentials')
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            dev_id = 'google_maps_{0}'.format(slugify(person.id))

            attrs = {
                'id': person.id,
                'nickname': person.nickname,
                'full_name': person.full_name,
                'last_seen': person.datetime,
                'address': person.address
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                attributes=attrs
            )
Esempio n. 6
0
class GoogleMapsScanner(object):
    """Representation of an Google Maps location sharing account."""
    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        from locationsharinglib import Service
        from locationsharinglib.locationsharinglibexceptions import InvalidUser

        self.see = see
        self.username = config[CONF_USERNAME]
        self.password = config[CONF_PASSWORD]

        try:
            self.service = Service(self.username, self.password,
                                   hass.config.path(CREDENTIALS_FILE))
            self._update_info()

            track_time_interval(hass, self._update_info,
                                MIN_TIME_BETWEEN_SCANS)

            self.success_init = True

        except InvalidUser:
            _LOGGER.error('You have specified invalid login credentials')
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            dev_id = 'google_maps_{0}'.format(slugify(person.id))

            attrs = {
                'id': person.id,
                'nickname': person.nickname,
                'full_name': person.full_name,
                'last_seen': person.datetime,
                'address': person.address
            }
            self.see(dev_id=dev_id,
                     gps=(person.latitude, person.longitude),
                     picture=person.picture_url,
                     source_type=SOURCE_TYPE_GPS,
                     gps_accuracy=person.accuracy,
                     attributes=attrs)
Esempio n. 7
0
class GoogleMapsScanner:
    """Representation of an Google Maps location sharing account."""

    def __init__(self, opp, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        self.see = see
        self.username = config[CONF_USERNAME]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]
        self.scan_interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=60)
        self._prev_seen = {}

        credfile = "{}.{}".format(
            opp.config.path(CREDENTIALS_FILE), slugify(self.username)
        )
        try:
            self.service = Service(credfile, self.username)
            self._update_info()

            track_time_interval(opp, self._update_info, self.scan_interval)

            self.success_init = True

        except InvalidCookies:
            _LOGGER.error(
                "The cookie file provided does not provide a valid session. Please create another one and try again."
            )
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            try:
                dev_id = "google_maps_{0}".format(slugify(person.id))
            except TypeError:
                _LOGGER.warning("No location(s) shared with this account")
                return

            if (
                self.max_gps_accuracy is not None
                and person.accuracy > self.max_gps_accuracy
            ):
                _LOGGER.info(
                    "Ignoring %s update because expected GPS "
                    "accuracy %s is not met: %s",
                    person.nickname,
                    self.max_gps_accuracy,
                    person.accuracy,
                )
                continue

            last_seen = dt_util.as_utc(person.datetime)
            if last_seen < self._prev_seen.get(dev_id, last_seen):
                _LOGGER.warning(
                    "Ignoring %s update because timestamp "
                    "is older than last timestamp",
                    person.nickname,
                )
                _LOGGER.debug("%s < %s", last_seen, self._prev_seen[dev_id])
                continue
            self._prev_seen[dev_id] = last_seen

            attrs = {
                ATTR_ADDRESS: person.address,
                ATTR_FULL_NAME: person.full_name,
                ATTR_ID: person.id,
                ATTR_LAST_SEEN: last_seen,
                ATTR_NICKNAME: person.nickname,
                ATTR_BATTERY_CHARGING: person.charging,
                ATTR_BATTERY_LEVEL: person.battery_level,
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                gps_accuracy=person.accuracy,
                attributes=attrs,
            )
class GoogleMapsScanner:
    """Representation of an Google Maps location sharing account."""

    def __init__(self, hass, config: ConfigType, see) -> None:
        """Initialize the scanner."""
        self.see = see
        self.username = config[CONF_USERNAME]
        self.max_gps_accuracy = config[CONF_MAX_GPS_ACCURACY]
        self.scan_interval = config.get(CONF_SCAN_INTERVAL) or timedelta(seconds=60)

        credfile = "{}.{}".format(
            hass.config.path(CREDENTIALS_FILE), slugify(self.username)
        )
        try:
            self.service = Service(credfile, self.username)
            self._update_info()

            track_time_interval(hass, self._update_info, self.scan_interval)

            self.success_init = True

        except InvalidCookies:
            _LOGGER.error(
                "You have specified invalid login credentials. "
                "Please make sure you have saved your credentials"
                " in the following file: %s",
                credfile,
            )
            self.success_init = False

    def _update_info(self, now=None):
        for person in self.service.get_all_people():
            try:
                dev_id = "google_maps_{0}".format(slugify(person.id))
            except TypeError:
                _LOGGER.warning("No location(s) shared with this account")
                return

            if (
                self.max_gps_accuracy is not None
                and person.accuracy > self.max_gps_accuracy
            ):
                _LOGGER.info(
                    "Ignoring %s update because expected GPS "
                    "accuracy %s is not met: %s",
                    person.nickname,
                    self.max_gps_accuracy,
                    person.accuracy,
                )
                continue

            attrs = {
                ATTR_ADDRESS: person.address,
                ATTR_FULL_NAME: person.full_name,
                ATTR_ID: person.id,
                ATTR_LAST_SEEN: dt_util.as_utc(person.datetime),
                ATTR_NICKNAME: person.nickname,
                ATTR_BATTERY_CHARGING: person.charging,
                ATTR_BATTERY_LEVEL: person.battery_level,
            }
            self.see(
                dev_id=dev_id,
                gps=(person.latitude, person.longitude),
                picture=person.picture_url,
                source_type=SOURCE_TYPE_GPS,
                gps_accuracy=person.accuracy,
                attributes=attrs,
            )
Esempio n. 9
0
class FrontEnd:
    def __init__(self, username, cookie):
        try:
            self.service = Service(cookie, username)
        except InvalidCookies:
            print("Invalid cookie.")
            raise InvalidCookies
        print("Authenticated.\n")
        print(list(self.service.get_all_people()))
        self.now = None
        self.you = None
        self.people = []
        # dictionary of people by id
        self.person_d = {}
        self.person_n = {}
        self.load()
        self.auto_update()

    def load(self):
        if not os.path.isfile(FNAME):
            return
        for line in open(FNAME, 'r'):
            parts = line.split(",")
            if len(parts) != 3:
                continue
            pid, lat, lon = parts
            home = (float(lat), float(lon))
            self.person_d[pid] = home
        print("Loaded.")

    def auto_update(self):
        self.update()
        # update every N seconds (on a thread)
        self.t = Timer(POLLING_DURATION, self.auto_update)
        self.t.start()

    def update(self):
        self.now = datetime.datetime.now()
        if PRINT_UPDATES:
            print("Updating... (%s)\n> " % self.now.strftime("%H:%M:%S"))
        you = self.service.get_authenticated_person()

        if self.person_d.get(you.id) is None:
            self.you = You(you)
        else:
            # both 'homes' and people stored in the person dictionary
            if type(self.person_d[you.id]) == tuple:
                self.you = You(you, home=self.person_d[you.id])
            else:
                self.you = self.person_d[you.id]
                self.you.update(you)
        self.person_d[you.id] = self.you

        self.people = []
        for p in self.service.get_shared_people():
            new_p = None
            if p.id in self.person_d.keys():
                # both 'homes' and people stored in the person dictionary
                if type(self.person_d[p.id]) == tuple:
                    new_p = Person(p, you=self.you, home=self.person_d[p.id])
                else:
                    new_p = self.person_d[p.id]
                    new_p.update(p, self.you)
            else:
                new_p = Person(p, you=self.you)
            self.person_d[p.id] = new_p
            self.people.append(new_p)
            self.person_n[new_p.nickname.lower()] = new_p

        # sort by furthest distance
        self.people.sort(key=lambda p: p.distance)

    def print_all(self):
        self.you.print()
        print("")
        for i, p in enumerate(self.people):
            print("%2d. " % (i + 1), end="")
            p.print()
        print("(Refreshed at %s.)" % self.now.strftime('%Y-%m-%d %H:%M:%S'))

    def who_find(self):
        if len(self.people):
            return "I've got no-one to find."
        res = "I can find "
        lst = [str(p.nickname) for p in self.people]
        if len(lst) == 1:
            res += lst[0] + "."
        else:
            res += ", ".join(lst[:-1]) + " and " + lst[-1] + "."

    def who_home(self):
        people_at_home = []
        for i, p in enumerate(self.people):
            if p.at_home:
                people_at_home.append(p)

        if len(people_at_home) == 0:
            if self.you.at_home:
                return "You are at home by yourself."
            else:
                return "No-one is home."
        else:
            res = ""
            if self.you.at_home:
                res += "You are at home with "
            lst = [str(p.nickname) for p in people_at_home]
            if len(lst) == 1:
                res += lst[0] + "."
            else:
                res += ", ".join(lst[:-1]) + " and " + lst[-1] + "."
            return res

    def who_out(self):
        people_out = []
        for i, p in enumerate(self.people):
            if not p.at_home:
                people_out.append(p)

        if len(people_out) == 0:
            if self.you.at_home:
                return "Everyone is home."
            else:
                return "Everyone but you is home."
        else:
            res = ""
            if not self.you.at_home:
                res += "You, "
            lst = [str(p.nickname) for p in people_out]
            if len(lst) == 1:
                res += lst[0]
            else:
                res += ", ".join(lst[:-1]) + " and " + lst[-1]
            return res + " are out."

    def set_home(self, name):
        if name == 'me':
            self.you.set_home()
            self.save()
            return "Set your home to where you are."
        else:
            p = self.person_n.get(name.lower())
            if p is None:
                return "Could not find {}.".format(name)
            else:
                p.set_home()
                self.save()
                return "Set home of {}.".format(p.nickname)

    def save(self):
        f = open(FNAME, "w")
        for p in self.person_d.values():
            x = p.serialise()
            if x is not None:
                f.write(x)

    def whereis(self, name):
        if name == 'me':
            return self.you.get_info_str()
        else:
            p = self.person_n.get(name.lower())
            if p is None:
                return "Could not find where \"{}\" is.".format(name)
            else:
                return p.get_info_str()
Esempio n. 10
0
import re
from locationsharinglib import Service
service = Service("*****@*****.**",
                  "3BUnwejC4BwDkTjP",
                  cookies_file=".google_maps_location_sharing.cookies")
for person in service.get_all_people():
    print(person)
Esempio n. 11
0
home_longitude = os.environ['HOME_LONGITUDE']

print("Pulling locations for", email)

client = mqtt.Client()
client.connect(mqtt_server, 1883, 60)
client.loop_start()

print("Connected to", mqtt_server)

service = Service(email, password)

home = (float(home_latitude), float(home_longitude))

while True:
    people = service.get_all_people()
    print("Found " + str(len(people)) + " people.")
    for person in people:
        # ignore locations that are not at least accurate within 1000 meters
        if person._accuracy > 1000:
            continue
        mqtt_topic = 'google/location/' + person.full_name.lower().replace(
            " ", "_")
        mqtt_data = {
            "latitude": person.latitude,
            "longitude": person.longitude,
            "datetime": int(person.datetime.timestamp()),
            "gps_accuracy": person._accuracy
        }

        # if home is within the accuracy radius, assume home