Advertisement
cmiN

hello-cc.py

Feb 20th, 2017
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.20 KB | None | 0 0
  1. #! /usr/bin/env python
  2.  
  3.  
  4. import json
  5. import re
  6. import textwrap
  7. import sys
  8.  
  9. import requests
  10. from cryptography.fernet import Fernet
  11.  
  12.  
  13. EMAILS_PATH = "hello_emails.txt"
  14. API_KEYS_PATH = "api_keys.json"
  15.  
  16.  
  17. def is_ascii(string):
  18.     return all(ord(char) < 128 for char in string)
  19.  
  20.  
  21. class Hello(object):
  22.  
  23.     def __init__(self, from_email,
  24.                  to_emails_path=EMAILS_PATH, api_keys_path=API_KEYS_PATH):
  25.         """Instantiate with the from `email` address."""
  26.         self._from_email = from_email
  27.         self._to_emails = self.load_emails(to_emails_path)
  28.         self._api_keys = self.load_api_keys(api_keys_path)
  29.  
  30.     @staticmethod
  31.     def load_emails(path):
  32.         emails = []
  33.         with open(path) as stream:
  34.             for line in stream:
  35.                 idx = line.find("#")
  36.                 if idx:
  37.                     line = line[:idx]
  38.                 line = line.strip()
  39.                 if not line:
  40.                     continue
  41.                 emails.append(line)
  42.         return emails
  43.  
  44.     @staticmethod
  45.     def load_api_keys(path):
  46.         with open(path) as stream:
  47.             api_keys = json.load(stream)
  48.         key = api_keys.pop("key")
  49.         fernet = Fernet(key.encode())
  50.         for key, value in list(api_keys.items()):
  51.             api_keys[key] = fernet.decrypt(value.encode())
  52.         return api_keys
  53.  
  54.     def get_location(self):
  55.         # Get coordinates.
  56.         url = "https://www.googleapis.com/geolocation/v1/geolocate?key={}"
  57.         url = url.format(self._api_keys["location"])
  58.         response = requests.post(url)
  59.         response.raise_for_status()
  60.         result = response.json()["location"]
  61.         lat, lon = map(lambda key: result[key], ("lat", "lng"))
  62.  
  63.         # Now reverse geocoding to location/address.
  64.         url = ("http://maps.googleapis.com/maps/api/geocode/json?"
  65.                "latlng={},{}&sensor=false").format(lat, lon)
  66.         response = requests.get(url)
  67.         response.raise_for_status()
  68.         result = response.json()
  69.  
  70.         location = None
  71.         for address_chunks in result["results"]:
  72.             address = address_chunks["formatted_address"]
  73.             location = address.split(",")[1].strip()
  74.             if is_ascii(location):
  75.                 break
  76.         return location
  77.  
  78.     def get_weather(self, location):
  79.         url = ("http://api.openweathermap.org/data/2.5/"
  80.                "weather?q={input}&appid={key}")
  81.         url = url.format(
  82.             input=location,
  83.             key=self._api_keys["weather"]
  84.         )
  85.         response = requests.get(url)
  86.         response.raise_for_status()
  87.         result = response.json()["weather"][0]
  88.         weather = "{} - {}".format(result["main"], result["description"])
  89.         return weather
  90.  
  91.     def send_mail(self, subject, text):
  92.         url = "https://api.sendgrid.com/v3/mail/send"
  93.         headers = {
  94.             "Authorization": "Bearer {}".format(self._api_keys["sendgrid"]),
  95.             "Content-Type": "application/json",
  96.         }
  97.         data = {
  98.             "personalizations": [
  99.                 {
  100.                     "to": [
  101.                         {
  102.                             "email": None,
  103.                             "name": "Happy User"
  104.                         }
  105.                     ],
  106.                     "subject": None,
  107.                 }
  108.             ],
  109.             "from": {
  110.                 "email": None,
  111.                 "name": "FII Cloud"
  112.             },
  113.             "subject": None,
  114.             "content": [
  115.                 {
  116.                     "type": "text/html",
  117.                     "value": None
  118.                 }
  119.             ],
  120.             "tracking_settings": {
  121.                 "click_tracking": {
  122.                     "enable": True,
  123.                     "enable_text": True
  124.                 },
  125.                 "open_tracking": {
  126.                     "enable": True,
  127.                     "substitution_tag": "%opentrack"
  128.                 },
  129.             }
  130.         }
  131.  
  132.         data["from"]["email"] = self._from_email
  133.         data["subject"] = subject
  134.         data["content"][0]["value"] = text
  135.         data["personalizations"][0]["subject"] = subject
  136.         items = [{"email": email, "name": "Happy User"}
  137.                  for email in self._to_emails]
  138.         data["personalizations"][0]["to"] = items
  139.  
  140.         payload = json.dumps(data, separators=(",", ":"))
  141.         response = requests.post(url, headers=headers, data=payload)
  142.         response.raise_for_status()
  143.  
  144.     def start(self):
  145.         location = self.get_location()
  146.         weather = self.get_weather(location)
  147.  
  148.         subject = "Hi from {}".format(location)
  149.         text = textwrap.dedent("""
  150.        Hi there,
  151.  
  152.        I'm from {} and the weather outside is:
  153.        {}
  154.        """.format(location, weather))
  155.         self.send_mail(subject, text)
  156.  
  157.  
  158. def main():
  159.     if len(sys.argv) != 2:
  160.         print("Usage: {} EMAIL".format(sys.argv[0]))
  161.         return 1
  162.  
  163.     try:
  164.         hello = Hello(sys.argv[1])
  165.         hello.start()
  166.     except Exception as exc:
  167.         print("Error occurred: {}.".format(exc))
  168.         return 2
  169.  
  170.     print("Success run.")
  171.     return 0
  172.  
  173.  
  174. if __name__ == "__main__":
  175.     code = main()
  176.     sys.exit(code)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement