<file_sep>import os
import pyowm
from dotenv import load_dotenv
from os.path import join, dirname
from generate_countries import read_file

dotenv_path = join(dirname(__file__),'.env')
load_dotenv(dotenv_path)

#Checks if the user gave a correct country
def getTag(country):
    countries = read_file()
    
    code = ""

    try:
        code = countries[country.strip()]
    except:
        pass
    
    return code


#Checks if the user gave a correct location
def valid_location(message):
    tuple = message.strip().split(",")
    if len(tuple) != 2:
        return False, "Not valid"

    code = getTag(tuple[1])
    if code == "":
        return False, "Not valid"

    APIKEY = os.environ.get("API_KEY")
    owm = pyowm.OWM(APIKEY)
    reg = owm.city_id_registry()

    list_of_locations = reg.locations_for(tuple[0], country=code)

    if len(list_of_locations) == 0:
        return False, "Not valid"

    return True, (tuple[0] + "," + code).strip()
<file_sep># Twitter Bot that tweets the Weather everyday!
Works by tweeting at the bot with the location you want to be notified  

## Usage
`@bot_tag Lisbon, Portugal`  
The bot will tweet at you everyday at 08:00 Lisbon Time the maximum and minimum expected temperature for Madrid, Spain

## Bot features
- Tweets everyday at 9am Lisbon Time
- Doesn't allow multiple locations for 1 user automatically (can be done manually by changing your users_accepted.txt)
- Auto follow back (if enabled)
- Information provided:
  - Forecast for maximum and minimum temperature
  - Actual temperature and sensation temperature
  - Bad conditions warning (Rain & Snow)
  - UV Index
  - Advice for sunscreen on high UV
  - Tell if the weather is good to go to the beach
  - Sunset time (Lisbon Time)

## Dependencies
`pip install tweepy`  
`pip install pycountry`  
`pip install pyowm`  
`pip install google-trans-new`  
`pip install python-dotenv`  

## API Keys
To use this repository create a file named `.env` on `weather_twitterbot` directory  
For this you need to create a Developer Twitter Account
```
CONSUMER_KEY=YOUR_CONSUMER_KEY_TWITTER_DEVELOPER_ACCOUNT
CONSUMER_SECRET=YOUR_CONSUMER_SECRET_KEY_TWITTER_DEVELOPER_ACCOUNT
ACCESS_TOKEN=YOUR_ACCESS_TOKEN_TWITTER_DEVELOPER_ACCOUNT
ACCESS_TOKEN_SECRET=YOUR_ACCESS_TOKEN_SECRET_TWITTER_DEVELOPER_ACCOUNT
API_KEY=YOUR_API_KEY_OWM
```

## Create a service
On `line 8` in `twitterbot.service`  
Change `~/github/weather_twitterbot/bot.py` to `your_path_to_file/bot.py`  
If you aren't sure what's the path to the file go inside the directory that contains the file and do `pwd` on the terminal  

Now open the terminal on `weather_twitterbot/` and run  
```
sudo cp twitterbot.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start twitterbot.service
sudo systemctl enable twitterbot.service
```
The last command is to make sure that the service is started on system startup
<file_sep>import os
import time
import pytz
import json
import pyowm  #import Python Open Weather Map
import tweepy
import datetime
import traceback
from dotenv import load_dotenv
from os.path import join, dirname
from generate_countries import read_file
from tweet_handler import valid_location
from google_trans_new import google_translator


#Get the last 20 mentions on the timeline and store it on a file
def getMention(api):
    tweets = api.mentions_timeline()

    with open(text_path, 'r') as f:
        users_accepted = json.load(f)
        print(users_accepted)

    with open(text_path, 'w') as f:
        user_exists = False
        location_exists = False
        data = []

        for tweet in tweets:
            tag = str(tweet.user.screen_name)

            #Sees if the user is already in the database
            for dic in users_accepted:
                if dic.get(tag) is not None:
                    user_exists = True
                    break                   #If its already in the database skip
                else:
                    user_exists = False

            #If the user isnt already in the databse then add him
            if not user_exists:
                message = str(tweet.text.replace('@WeatherDailyBot', '').strip())
                location_exists, place = valid_location(message)

                if location_exists:
                    d = {tag: place}
                    data.append(dict(d))

        for dat in data:
            users_accepted.append(dat)
        json.dump(users_accepted, f)


#Follows everyone back
def followBack(api):
    print("\nFollowers:")
    for follower in tweepy.Cursor(api.followers).items():
        follower.follow()
        print(follower.screen_name)
    print()


#Check if there will be rain or snow in the location
def checkBadConditions(onecall):
    status = onecall.forecast_daily[0].detailed_status
    
    info = ""

    if "snow" in status:
        info = "\nHoje vai nevar " + '\U0001F328'
    elif "rain" in status:
        translator = google_translator()  
        translate_text = translator.translate(status, lang_tgt='pt') 
        info = "\nHoje vai ter " + translate_text + " " + '\U0001F327'
    return info


#Tweets the weather
def tweetWeather(api):
    now = datetime.datetime.now()
    if now.hour == 8:
        with open(text_path, 'r') as f:
            users_accepted = json.load(f)  #Do a list of dictionaries that are inside the .txt

        for user in users_accepted:
            key, value = list(user.items())[0]  #Get the handler as a string

            city, country = value.split(",")
            
            place = reg.locations_for(city, country)[0]
            one_call = mgr.one_call(place.lat, place.lon)  #Creates a One Call object
            forecast = one_call.forecast_daily[0].temperature('celsius')  #Get information for the day

            tweet_content = "Dia " + str(now.day) + " de " + months[now.month-1] + " @" + key + " vai ter máximas de " + str(round(forecast['max'], 1)) + "ºC com mínimas de " + str(round(forecast['min'], 1)) + "ºC. Atualmente estão " + str(round(one_call.current.temperature('celsius')['temp'], 1)) + "ºC em " + city + ", " + country
            tweet_content += "\nA sensação de temperatura é de " + str(round(one_call.current.temperature('celsius')['feels_like'], 1)) + "ºC"

            #Bad conditions warning (rain, snow, thunder?)
            tweet_content += checkBadConditions(one_call)

            uvi = mgruv.uvindex_around_coords(place.lat, place.lon).to_dict()['value']
            tweet_content += "\nÍndice UV: " + str(round(uvi, 1))

            #Sunscreen warning
            if uvi >= 9.0:
                tweet_content += " mete protetor solar! " + '\U0001F9F4'

            #Beach time
            if forecast['max'] >= 29:
                tweet_content += "\nHoje vai estar bom para ir à praia! " + '\U0001F60E'

            #Sunset information
            observation = mgr.weather_at_place(city + ", " + country)
            sunset = observation.weather.sunset_time(timeformat='date')
            tweet_content += "\nO pôr-do-sol vai ser às " + sunset.astimezone(pytz.timezone("Europe/Lisbon")).strftime("%H:%M")

            api.update_status(tweet_content)
            print(tweet_content)  #Debug
            time.sleep(20)
        time.sleep(2 * 60* 60)  #Wait 2 hours


#Setting up enviorment variables
dotenv_path = join(dirname(__file__),'.env')
text_path = join(dirname(__file__),'users_accepted.txt')
load_dotenv(dotenv_path)
CONSUMER_KEY = os.environ.get("CONSUMER_KEY")
CONSUMER_SECRET = os.environ.get("CONSUMER_SECRET")
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN")
ACCESS_TOKEN_SECRET = os.environ.get("ACCESS_TOKEN_SECRET")

#Authenticate Twitter Credentials
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

#OpenWeatherMap API Setup
APIKEY = os.environ.get("API_KEY")
owm = pyowm.OWM(APIKEY)
mgr = owm.weather_manager()
mgruv = owm.uvindex_manager()
reg = owm.city_id_registry()

months = ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]

while True:
    #Create API object
    api = tweepy.API(auth, wait_on_rate_limit = True)

    #Terminal debug
    try:
        api.verify_credentials()
        print("Authentication OK")
        #followBack(api)
        getMention(api)
        tweetWeather(api)
    except:
        print("Error during authentication")
        traceback.print_exc()

    print("Waiting...")
    time.sleep(2 * 60)  #Request every 2 minutes
<file_sep>import pycountry
import json

#To read this dictionary to a file
def write_file():
    countries = {}
    for country in pycountry.countries:
        countries[country.name] = country.alpha_2

    with open('countries.txt', 'w') as f:
        f.write(json.dumps(countries))

#To read this dictionary and save it on your code use the following function
def read_file():
    with open('countries.txt', 'r') as f:
        data = f.read()

    dict = json.loads(data)

    """
    print(dict)
    print(dict["Portugal"]) """
    return dict
