Merge pull request #7 from KevinMidboe/status

Status
This commit is contained in:
2017-03-05 00:36:26 +01:00
committed by GitHub
9 changed files with 136 additions and 202 deletions

6
README.md Normal file
View File

@@ -0,0 +1,6 @@
# Node-Com-Handler
Internal API for getting status on all connected nodes on network
## Setup
## Other things to do when you fill in this document

59
app.py
View File

@@ -12,10 +12,11 @@ from werkzeug.security import generate_password_hash, \
from status.diskusage import diskUsage from status.diskusage import diskUsage
from status.uptime import timeSinceBoot from status.uptime import timeSinceBoot
from status.load import load
from status.cpuTemp import getCpuTemp from status.cpuTemp import getCpuTemp
from plex.tmdb import tmdbSearch
from plex.plexMovies import getSpecificMovieInfo from plex.tmdb import tmdbSearch
from plex.plexSearch import plexSearch
app = Flask(__name__, static_url_path = "") app = Flask(__name__, static_url_path = "")
auth = HTTPBasicAuth() auth = HTTPBasicAuth()
@@ -51,7 +52,7 @@ def get_pw(username):
# to not match. # to not match.
@auth.error_handler @auth.error_handler
def unauthorized(): def unauthorized():
return make_response(jsonify({'error': 'Unauthorized access'}), 401) return make_response(jsonify({'errors': 'Unauthorized access'}), 401)
# This would be replaced with a database, but single process and thread # This would be replaced with a database, but single process and thread
# can use local data like this for simplicity. # can use local data like this for simplicity.
@@ -60,39 +61,31 @@ def unauthorized():
# Want all return data to be JSON so create custom error response # Want all return data to be JSON so create custom error response
@app.errorhandler(404) @app.errorhandler(404)
def not_found(error): def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404) return make_response(jsonify({'errors': 'Not found'}), 404)
@app.errorhandler(400) @app.errorhandler(400)
def bad_request(error): def bad_request(error):
return make_response(jsonify({'error': 'Bad request'}), 400) return make_response(jsonify({'errors': 'Bad request'}), 400)
# --- Apollo Activity --- # # --- Apollo Activity --- #
@app.route('/api/v1/load', methods=['GET'])
def get_load():
return jsonify(load())
@app.route('/api/v1/disks', methods=['GET']) @app.route('/api/v1/disks', methods=['GET'])
@auth.login_required
def get_diskUsage(): def get_diskUsage():
returningDiskUsage = diskUsage(request.args.get('dir')) return jsonify(diskUsage(request.args.get('dir')))
if returningDiskUsage != None:
return jsonify(returningDiskUsage)
else:
abort(404)
@app.route('/api/v1/uptimes', methods=['GET']) @app.route('/api/v1/uptimes', methods=['GET'])
@auth.login_required
def get_uptimes(): def get_uptimes():
try: return jsonify({ 'uptime': timeSinceBoot() })
return jsonify({ 'uptime': timeSinceBoot() })
except:
abort(404)
@app.route('/api/v1/temps', methods=['GET']) @app.route('/api/v1/temps', methods=['GET'])
def get_temps(): def get_temps():
cpuTemp = getCpuTemp() return jsonify(getCpuTemp())
if cpuTemp != None:
return jsonify( {"Avg cpu temp": cpuTemp} )
else:
return jsonify( {"Error":"Temp reading not supported for host machine."} )
# TODO PLEX # TODO PLEX
# Search, watching, +photo # Search, watching, +photo
@@ -103,15 +96,15 @@ def get_movieRequest():
# TODO if list is empty # TODO if list is empty
return jsonify(tmdbSearch(query)) return jsonify(tmdbSearch(query))
else: return jsonify({ "Error": "Query not defined." }) else: return jsonify({ "errors": "Query not defined." })
@app.route('/api/v1/plex/movies', methods=['GET']) @app.route('/api/v1/plex/movies', methods=['GET'])
@auth.login_required
def getPlexMovies(): def getPlexMovies():
title = request.args.get('title') title = request.args.get('title')
movieInfo = getSpecificMovieInfo(title) movieInfo = plexSearch(title)
if movieInfo != None: if movieInfo != None:
print(movieInfo)
return jsonify(movieInfo) return jsonify(movieInfo)
abort(500) abort(500)
@@ -127,24 +120,6 @@ def getPlexWatchings():
return jsonify(movieInfo) return jsonify(movieInfo)
@app.route('/api/v1/uptimes/duration', methods=['GET'])
@auth.login_required
def get_uptimesDuration():
up = uptime.uptime()
return jsonify( {'Duration': up.duration} )
@app.route('/api/v1/uptimes/users', methods=['GET'])
@auth.login_required
def get_uptimesUsers():
up = uptime.uptime()
return jsonify( {'Users': up.users} )
@app.route('/api/v1/uptimes/load', methods=['GET'])
@auth.login_required
def get_uptimesLoad():
up = uptime.uptime()
return jsonify( {'Load': up.load} )
if __name__ == '__main__': if __name__ == '__main__':
app.run(host="0.0.0.0",port=63590, debug=True) app.run(host="0.0.0.0",port=63590, debug=True)

View File

@@ -3,9 +3,10 @@
# @Author: KevinMidboe # @Author: KevinMidboe
# @Date: 2017-02-08 14:00:04 # @Date: 2017-02-08 14:00:04
# @Last Modified by: KevinMidboe # @Last Modified by: KevinMidboe
# @Last Modified time: 2017-02-10 01:31:43 # @Last Modified time: 2017-02-18 11:37:08
from requests import get import requests
from pprint import pprint
plexBaseURL = "http://10.0.0.41:32400/" plexBaseURL = "http://10.0.0.41:32400/"
@@ -42,21 +43,36 @@ def getShowInfo(item):
return {"title":title, "year":year, "seasons":seasons, "episodes":episodes, "rating":rating, return {"title":title, "year":year, "seasons":seasons, "episodes":episodes, "rating":rating,
"art":art, "thumb":thumb} "art":art, "thumb":thumb}
def plexSearch(query):
payload = {"query":query, "type":"1,2"}
header = {'Accept': 'application/json'}
r = requests.get(plexBaseURL+"search",params=payload, headers=header)
rObject = r.json()["MediaContainer"]
if (r.status_code != requests.codes.ok or rObject["size"] == 0):
return {"errors": "Nothing found for query: " + query}
return rObject["Metadata"]
## MAJOR TODO ## MAJOR TODO
# Seems to be a change in the return obj. # Seems to be a change in the return obj.
# This looks way more like json. Need to re-write all this. # This looks way more like json. Need to re-write all this.
# IDEA: Send the size and resolution for comaprison # IDEA: Send the size and resolution for comaprison
# No this is for a admin page. OR maybe a github project for # No this is for a admin page. OR maybe a github project for
# people wanting to update movies. MAJOR IDEA HERE NOW! :D # people wanting to update movies. MAJOR IDEA HERE NOW! :D
def plexSearch(query): def plexXMLSearch(query):
print(query)
requestType = "search?" requestType = "search?"
requestQuery = "query=" + str(query) requestQuery = "query=" + str(query)
header = {'Accept': 'application/json'} header = {'Accept': 'application/json'}
url = plexBaseURL + requestType + requestQuery url = plexBaseURL + requestType + requestQuery
response = get(url, headers=header) response = requests.get(url, headers=header)
print(response.json())
pprint(response.json())
if response.status_code == 200: if response.status_code == 200:
resContent = response.json() resContent = response.json()
media = [] media = []
@@ -74,7 +90,4 @@ def plexSearch(query):
if __name__ == "__main__": if __name__ == "__main__":
# print(plexSearch("star+wars")) # print(plexSearch("star+wars"))
tiss = plexSearch("star+wars") pprint(plexSearch("star"))
for al in tiss:
if (al['year']==2015):
print('thishsihis')

View File

@@ -3,77 +3,48 @@
# @Author: KevinMidboe # @Author: KevinMidboe
# @Date: 2017-02-08 14:00:04 # @Date: 2017-02-08 14:00:04
# @Last Modified by: KevinMidboe # @Last Modified by: KevinMidboe
# @Last Modified time: 2017-02-08 23:19:53 # @Last Modified time: 2017-02-16 17:08:08
from requests import get import requests
from pprint import pprint
try: try:
from plexSearch import plexSearch from plexSearch import plexSearch
except ImportError: except ImportError:
from plex.plexSearch import plexSearch from plex.plexSearch import plexSearch
tmdbBaseURL = "https://api.themoviedb.org/3/" apiKey = "9fa154f5355c37a1b9b57ac06e7d6712"
def checkPlexExistance(tmdb, plex):
# THIS IS ONLY COMPARED ON YEAR
yearList = [movie["year"] for movie in plex]
print(yearList)
for movie in tmdb["movies"]:
print(movie["year"])
movie["exists"] = movie["year"] in str(yearList)
return tmdb
def createTMDBResultList(resContent):
movies = []
tvshows = []
for res in resContent["results"]:
if res["media_type"] == "movie":
id = res["id"]
title = res["original_title"]
year = res["release_date"][:4]
poster_path = res["poster_path"]
movies.append({"id": id, "title": title, "year": year, "poster_path": poster_path})
elif res["media_type"] == "tv":
id = res["id"]
name = res["original_name"]
year = res["first_air_date"][:4]
poster_path = res["poster_path"]
tvshows.append({"id": id, "title": name, "year": year, "poster_path": poster_path})
return { "movies": movies, "tvshows": tvshows }
def tmdbSearch(query, page=1): def tmdbSearch(query, page=1):
requestType = "search/multi?" payload = {"api_key":apiKey, "query":str(query), "language":"en.US", "page":str(page), }
requestAPI = "api_key=" + "9fa154f5355c37a1b9b57ac06e7d6712" header = {'Accept': 'application/json'}
requestQuery = "&query=" + str(query)
requestLanguage = "&language=en.US"
requestPage = "&page="+str(page)
url = tmdbBaseURL + requestType + requestAPI + requestQuery + requestLanguage + requestPage try:
print(url) r = requests.get("https://api.themoviedb.org/3/search/multi", params=payload, headers=header)
except requests.exceptions.ConnectionError:
return {"errors": "Could not connecting to: tmdb.com"}
except requests.exceptions.Timeout:
return {"errors": "Request timed out."}
except requests.exceptions.TooManyRedirects:
return {"errors": "Too many redirects, do you full network access?"}
response = get(url) if r.status_code == 401:
if response.status_code == 200: return {"errors": "api key is not valid."}
resContent = response.json() elif r.status_code == 404:
return {"errors": "Please check url. (404)"}
elif r.status_code == requests.codes.ok and r.json()['total_results'] == 0:
return {"errors": "No results found."}
plexSearchRes = plexSearch(query) return r.json()
tmdbSearchRes = createTMDBResultList(resContent)
return checkPlexExistance(tmdbSearchRes, plexSearchRes)
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
print(sys.argv) print(sys.argv)
if len(sys.argv) > 2: if len(sys.argv) > 2:
print(tmdbSearch(sys.argv[1], int(sys.argv[2]))) pprint(tmdbSearch(sys.argv[1], int(sys.argv[2])))
elif len(sys.argv) > 1: elif len(sys.argv) > 1:
print(tmdbSearch(sys.argv[1])) pprint(tmdbSearch(sys.argv[1]))
else: else:
print(tmdbSearch("star+wars",1)) pprint(tmdbSearch("star+wars",1))

View File

@@ -1,16 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# @Author: KevinMidboe
# @Date: 2017-02-15 23:37:36
# @Last Modified by: KevinMidboe
# @Last Modified time: 2017-02-15 23:49:18
import psutil import psutil
from platform import system
# TODO: Add cpu reading for macOS
def getCpuTemp(): def getCpuTemp():
# Check if sensors_temperatures exists sysName = system()
try: if sysName != 'Linux':
# Define cpu as function of sensors_temperatures return {"Error": "Running OS does not support cpu temp reads."}
cpu = psutil.sensors_temperatures()
except AttributeError: # Define cpu as function of sensors_temperatures
error = "'sensors_temperatures' is not supported in this verison of psutil or your OS." cpu = psutil.sensors_temperatures()
print(error)
return None
# Array for temps for each core. # Array for temps for each core.
curCpuTemps = [] curCpuTemps = []
@@ -19,17 +25,10 @@ def getCpuTemp():
curCpuTemps.append(temp[1]) # Append to list curCpuTemps.append(temp[1]) # Append to list
print(temp[0]+': '+str(temp[1])) # Print output print(temp[0]+': '+str(temp[1])) # Print output
# Check if len of curCpuTemps is something so not to avgCpuTemps = sum(curCpuTemps)/len(curCpuTemps)
# calculate on a empty list return {"Avg cpu temp": avgCpuTemps, "Max cpu temp": max(curCpuTemps),
if len(curCpuTemps) > 0: "Min cpu temp": min(curCpuTemps)}
# Compute avg of curCpuTemps
avgCpuTemps = sum(curCpuTemps)/len(curCpuTemps)
return avgCpuTemps
print("Avg: " + str(avgCpuTemps))
else:
print("Couldn't get cpu temp. (division by zero)")
return None
if __name__ == "__main__": if __name__ == "__main__":
print(getCpuTemp()) print(getCpuTemp())

View File

@@ -3,15 +3,17 @@
# @Author: KevinMidboe # @Author: KevinMidboe
# @Date: 2017-01-28 10:54:06 # @Date: 2017-01-28 10:54:06
# @Last Modified by: KevinMidboe # @Last Modified by: KevinMidboe
# @Last Modified time: 2017-01-31 22:29:43 # @Last Modified time: 2017-02-18 11:40:34
# f_avail = free blocks avail to non sudo # f_avail = free blocks avail to non sudo
# frsize = fundamental file sys byte size # frsize = fundamental file sys byte size
# f_blocks = total number of blocks in the filesystem # f_blocks = total number of blocks in the filesystem
from os import statvfs from os import statvfs, path
from re import sub from re import sub
# TODO: Add multiple dirs.
def sizeof(num, suffix='B'): def sizeof(num, suffix='B'):
for unit in ['','K','M','G','T','P','E','Z']: for unit in ['','K','M','G','T','P','E','Z']:
if abs(num) < 1024.0: if abs(num) < 1024.0:
@@ -20,24 +22,17 @@ def sizeof(num, suffix='B'):
return "%.1f%s%s" % (num, 'Y', suffix) return "%.1f%s%s" % (num, 'Y', suffix)
# diskUsage uses statvfs to calculate disk size and availability for given disk # diskUsage uses statvfs to calculate disk size and availability for given disk
def diskUsage(optionalPath=None): def diskUsage(rootPath=None):
path = '/' if rootPath == None: rootPath = '/'
if optionalPath != None:
path += sub('\+', '/', optionalPath) if not path.isdir(rootPath):
return {"errors": "Directory does not exist."}
try: s = statvfs(rootPath)
s = statvfs(path) byteLeft = s.f_bavail * s.f_frsize
byteLeft = s.f_bavail * s.f_frsize byteTotal = s.f_blocks * s.f_frsize
byteTotal = s.f_blocks * s.f_frsize byteUsed = byteTotal-byteLeft
byteUsed = byteTotal-byteLeft return { 'left': sizeof(byteLeft), 'used': sizeof(byteUsed), 'total': sizeof(byteTotal) }
return { 'left':sizeof(byteLeft), 'used':sizeof(byteUsed), 'total':sizeof(byteTotal) }
except FileNotFoundError:
return None
except TypeError:
return None
if __name__=="__main__": if __name__=="__main__":
n = diskUsage('/media/hdd1') print(diskUsage())
print(n)

View File

@@ -1,48 +0,0 @@
from functools import partial
from os import path
class LinuxCpuTemperatureReader():
files = [
'/sys/devices/LNXSYSTM:00/LNXTHERM:00/LNXTHERM:01/thermal_zone/temp',
'/sys/bus/acpi/devices/LNXTHERM:00/thermal_zone/temp',
'/proc/acpi/thermal_zone/THM0/temperature',
'/proc/acpi/thermal_zone/THRM/temperature',
'/proc/acpi/thermal_zone/THR1/temperature'
]
@classmethod
def get_reader(cls):
readers = {
cls.files[0]: cls.reader1,
cls.files[1]: cls.reader1,
cls.files[2]: cls.reader2,
cls.files[3]: cls.reader2,
cls.files[4]: cls.reader2
}
for file in cls.files:
if path.exists(file):
reader = readers.get(file)
if reader:
print(reader(file))
return reader(file)
@classmethod
def reader1(cls, file):
def reader(file):
temperature = open(file).read().strip()
temperature = int(temperature) // 1000
return temperature
return partial(reader, file)
@classmethod
def reader2(cls, file):
def reader(file):
temperature = open(file).read().strip()
temperature = temperature.lstrip('temperature :').rstrip(' C')
return int(temperature)
return partial(reader, file)
__all__ = ['LinuxCpuTemperatureReader']

25
status/load.py Executable file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: KevinMidboe
# @Date: 2017-02-15 23:45:16
# @Last Modified by: KevinMidboe
# @Last Modified time: 2017-02-18 11:42:42
from subprocess import check_output
from re import findall
from platform import system
def load():
sysName = system() # Get system name
if sysName == 'Linux':
arpOutput = check_output("cat /proc/loadavg", shell=True)
elif sysName == 'Darwin': # macOS
arpOutput = check_output("uptime", shell=True)
else:
return {"errors": "Running OS does not supported load."}
arpOutput = arpOutput.decode()
return {"loads": findall('[0-9]{1,2}[\.][0-9]{2}', arpOutput)}
if __name__ == '__main__':
print(load())

View File

@@ -3,7 +3,7 @@
# @Author: KevinMidboe # @Author: KevinMidboe
# @Date: 2017-01-27 19:48:42 # @Date: 2017-01-27 19:48:42
# @Last Modified by: KevinMidboe # @Last Modified by: KevinMidboe
# @Last Modified time: 2017-02-03 12:33:51 # @Last Modified time: 2017-02-18 11:49:30
# TODO add better error handling to return statements # TODO add better error handling to return statements
@@ -14,8 +14,7 @@ def secToDay(seconds):
days = int(seconds/86400) days = int(seconds/86400)
if days is 1: if days is 1:
return str(days)+' day' return str(days)+' day'
else: return str(days)+' days'
return str(days)+' days'
def secToHour(seconds): def secToHour(seconds):
hours = (seconds)//3600 hours = (seconds)//3600
@@ -28,16 +27,15 @@ def timeSinceBoot():
currTime = time() # Use 'time()' to get seconds currently currTime = time() # Use 'time()' to get seconds currently
deltaSeconds = int(currTime-bootTime) deltaSeconds = int(currTime-bootTime)
# Return in day format if deltaSeconds >= 86400: # Return in day format
if deltaSeconds >= 86400: uptime = secToDay(deltaSeconds)
return secToDay(deltaSeconds)
# Return in hour format
elif deltaSeconds < 86400 and deltaSeconds >= 0: elif deltaSeconds < 86400 and deltaSeconds >= 0:
return secToHour(deltaSeconds) uptime = secToHour(deltaSeconds)
else: else:
# TODO Throw error return {"errors": "Uptime not found"}
return None
return {"uptime": uptime}
if __name__=="__main__": if __name__=="__main__":
print(timeSinceBoot()) print(timeSinceBoot())