Merge pull request #3 from KevinMidboe/setup

Setup
This commit is contained in:
2017-08-01 18:40:18 +02:00
committed by GitHub
6 changed files with 7 additions and 322 deletions

3
.gitignore vendored
View File

@@ -97,3 +97,6 @@ ENV/
# mypy # mypy
.mypy_cache/ .mypy_cache/
.DS_Store

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 MiB

View File

@@ -1,154 +0,0 @@
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Author: KevinMidboe
# @Date: 2017-07-29 11:56:24
# @Last Modified by: KevinMidboe
# @Last Modified time: 2017-07-30 13:17:19
from fuzzywuzzy import process
# Find the first word, if it is a noun or a adjective. ✔️
# Remove the adjective and split if there is a AND ✔️
# Then match the first noun to list and add that emoji ✔️
# and then match the second to list and add that emoji ✔️
# REGEX this bitch up
symbol_table = {
'clear sky': '☀️',
'fair': '🌤',
'partly cloudy': '⛅️',
'cloudy': ' ☁️ ',
'thunder': '⚡️',
'rain showers': '🌦',
'rain': '🌧',
'sleet showers': '🌦 💦',
'sleet': '🌨 💦',
'snow showers': '⛅ ❄️',
'snow': '🌨',
'rain': '🌧',
'sleet': '🌧',
'snow': '🌨',
'showers': '🌤'
}
severity = {
'rain': ['', ' ☂️', ' ☔️'],
'sleet': [' 💦 ', ' 💧 ', ' 💧 💦 '],
'snow': [' ❄️ ', ' ❄️ ❄️ ', ' ❄️ ❄️ ❄️ ']
}
class EmojiParser(object):
def __init__(self, condition_text):
self.condition_expression = condition_text.lower()
self.severity = None
self.nouns = []
self.weather_nouns = ['cleary sky', 'fair', 'cloudy', 'rain', 'rain showers', 'sleet',
'sleet showers', 'snow showers', 'thunder', 'snow']
self.weather_adjectives = {'light': 0, 'normal': 1, 'heavy': 2}
def __str__(self):
return str([self.condition_expression, self.severity, self.nouns])
# Splits and lowers the condition text for easier parsing
def splitCondition(self, condition):
return condition.split()
# Takes a input or uses condition_expression to find adjective in sentence
def findAdjective(self, sentence=None):
if sentence is None:
sentence = self.condition_expression
# Splits and iterates over each word in sentence
expression = self.splitCondition(sentence)
for word in expression:
if word in self.weather_adjectives:
# Return the word if matched with weather_adjectives
return word
return None
# Removes the first adjective in the a given sentence
def removeAdjective(self):
adjective = self.findAdjective()
if adjective: # Adjective is not None
expression = self.splitCondition(self.condition_expression)
expression.remove(adjective)
return ' '.join(expression)
else:
return self.condition_expression
def severityValue(self):
adjective = self.findAdjective()
if adjective:
self.severity = self.weather_adjectives[adjective]
else:
self.severity = self.weather_adjectives['normal']
def findWeatherTokens(self):
# If present removes the leading adjective
sentence = self.removeAdjective()
# If multiple tokens/weather_nouns split all between the 'and'
if 'and' in sentence:
self.nouns = sentence.split(' and ')
else:
self.nouns = [sentence]
# Use the symbol_table to convert the forecast name to emoji
def emojify(self, noun):
return symbol_table[noun]
# Does as emojify above, but iterates over a list if multiple elements
def emojifyList(self, noun_list):
returnList = []
# TODO use more like a map function?
for noun in noun_list:
returnList.append(self.emojify(noun))
return ' '.join(returnList)
def findPrimaryForecast(self):
# Copies the contents not the refrence to the list
noun_list = list(self.nouns)
forecast = noun_list.pop(0)
# Translates to emoji once here instead of twice below
forecast_emoji = self.emojify(forecast)
if forecast in severity:
return ('%s %s' % (forecast_emoji, severity[forecast]))
else:
return forecast_emoji
# Trying to analyze the semantics of the condition text
def emojifyWeatherForecast(self):
# Finds the tokens/nouns of weather for the given input text and severity value
self.findWeatherTokens()
self.severityValue()
primary_forecast = self.findPrimaryForecast()
secondary_forecast = self.emojifyList(self.nouns[1:])
return ('%s %s' % (primary_forecast, secondary_forecast))
def convertSematicsToEmoji(self):
return self.emojifyWeatherForecast()
def main():
emojiParser = EmojiParser('Cloudy')
print(emojiParser.convertSematicsToEmoji())
if __name__ == '__main__':
main()

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Author: KevinMidboe
# @Date: 2017-07-30 13:53:38
# @Last Modified by: KevinMidboe
# @Last Modified time: 2017-07-30 13:53:46
import itertools
from threading import Thread
from time import sleep
from sys import stdout
class LoadingAnimation(object):
def __init__(self):
self.done = False
def start(self):
t = Thread(target=self.animate)
t.start()
def animate(self):
for c in itertools.cycle(['|', '/', '-', '\\']):
if self.done:
break
stdout.write('\rFetching ' + c)
stdout.flush()
sleep(0.1)
def stop(self):
self.done = True
def main():
loadingAnimation = LoadingAnimation()
loadingAnimation.start()
sleep(2)
loadingAnimation.stop()
stdout.write('\rTemp \n')
if __name__ == '__main__':
main()

View File

@@ -1,127 +0,0 @@
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
# @Author: KevinMidboe
# @Date: 2017-07-27 21:26:53
# @Last Modified by: KevinMidboe
# @Last Modified time: 2017-07-30 18:56:27
# TODO LIST
# Get coordinates from IP ✔
# Fetch coordinates from YR ✔
# Convert coordinates to place name w/ google GeoCode api ✔
# Parse return data
# Match weather description to icons ✔
# Check internet connection in a strict way
# Add table for time periode
# Add cache for quicker location for same ip
import fire, json, geoip2.database, ssl, os
from yr.libyr import Yr
from requests import get
from pprint import pprint
from sys import stdout
from emojiParser import EmojiParser
from loadingAnimation import LoadingAnimation
class Location(object):
def __init__(self):
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
self.reader = geoip2.database.Reader('conf/GeoLite2-City.mmdb')
self.getIP()
def getIP(self):
ip = get('https://api.ipify.org').text
self.ip = self.reader.city(ip)
def getCoordinates(self):
lat = self.ip.location.latitude
long = self.ip.location.longitude
return [lat, long]
def getAreaName(self):
lat, long = self.getCoordinates()
coordinates = ','.join([str(lat), str(long)])
areaURL = 'https://maps.googleapis.com/maps/api/geocode/json?&latlng='
areaAPIResponse = json.loads(get(areaURL + coordinates).text)
closestArea = areaAPIResponse['results'][0]['address_components']
area = {}
for item in closestArea:
if 'route' in item['types']:
area['street'] = item['long_name']
if 'locality' in item['types']:
area['town'] = item['long_name']
if 'administrative_area_level_1' in item['types']:
area['municipality'] = item['long_name']
if 'country' in item['types']:
area['country'] = item['long_name']
return area
class WeatherForecast(object):
def __init__(self, area=None):
# TODO search for area coordinates in a map
self.area = area
self.name = None
self.number = None
self.variable = None
def symbolVariables(self, symbol_obj):
self.name = symbol_obj['@name']
self.number = symbol_obj['@number']
self.variable = symbol_obj['@var']
def parseYrTemperature(self, temperature_obj):
return temperature_obj['@value'] + ' ' + temperature_obj['@unit']
def now(self):
location = Location()
self.area = location.getAreaName()
# Create seperate function for formatting
locationName = '/'.join([self.area['country'], self.area['municipality'], self.area['town'], self.area['street']])
# Use the defined location name with yr API for location based weather information
weather = Yr(location_name=locationName)
now = json.loads(weather.now(as_json=True))
temperature_output = self.parseYrTemperature(now['temperature'])
emojiParser = EmojiParser(now['symbol']['@name'])
weatherIcon_output = emojiParser.convertSematicsToEmoji()
return ('%s %s' % (temperature_output, weatherIcon_output))
class TermWeather(object):
# Add now, forecast as args
def auto(self):
loadingAnimation = LoadingAnimation()
loadingAnimation.start()
weatherForecast = WeatherForecast()
forecast = weatherForecast.now()
loadingAnimation.stop()
stdout.write('\r%s \n' % forecast)
def fetch(self, area=None):
weatherForecast = WeatherForcast(area)
weatherForecast.now()
if __name__ == '__main__':
ssl._create_default_https_context = ssl._create_unverified_context
fire.Fire(TermWeather())

5
term_weather.py → term_forecast/term_weather.py Executable file → Normal file
View File

@@ -3,7 +3,7 @@
# @Author: KevinMidboe # @Author: KevinMidboe
# @Date: 2017-07-27 21:26:53 # @Date: 2017-07-27 21:26:53
# @Last Modified by: KevinMidboe # @Last Modified by: KevinMidboe
# @Last Modified time: 2017-07-30 14:05:28 # @Last Modified time: 2017-07-30 19:56:18
# TODO LIST # TODO LIST
# Get coordinates from IP ✔ # Get coordinates from IP ✔
@@ -107,6 +107,9 @@ class WeatherForecast(object):
class TermWeather(object): class TermWeather(object):
def __init__(self):
print('here')
# Add now, forecast as args # Add now, forecast as args
def auto(self): def auto(self):
loadingAnimation = LoadingAnimation() loadingAnimation = LoadingAnimation()