Created
June 8, 2015 11:46
-
-
Save openpaul/2104acb62916663848cd to your computer and use it in GitHub Desktop.
call RNV api via python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/bin/python | |
# RNV.py | |
# this script can call the server of RNV like the official | |
# desktop widget does. | |
# It then returns and saves the departures of a certain station | |
# and certain lines and directions. | |
# Tested on ubuntu 15.04 | |
# | |
# call via command line: | |
# rnv.py -i <hafasID> -n <Bus Number 1, Bus Number 2> -d <all|direction1, direction2> | |
# English: | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
# Deutsch: | |
# Dieses Programm ist Freie Software: Sie können es unter den Bedingungen | |
# der GNU General Public License, wie von der Free Software Foundation, | |
# Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren | |
# veröffentlichten Version, weiterverbreiten und/oder modifizieren. | |
# | |
# Dieses Programm wird in der Hoffnung, dass es nützlich sein wird, aber | |
# OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite | |
# Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK. | |
# Siehe die GNU General Public License für weitere Details. | |
# | |
# Sie sollten eine Kopie der GNU General Public License zusammen mit diesem | |
# Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>. | |
import urllib | |
import urllib2 | |
import json # for handleing the data | |
import pprint | |
import sys, getopt | |
import datetime | |
import os | |
import pickle # to save content | |
class rnv: | |
''' class to fetch and handle departures of lines in the | |
rnv area.''' | |
def __init__(self,argv): | |
# parse options: | |
self.options = self.parseOptions(argv) | |
self.content = {} | |
self.configPath = "%s/.config/rnv/storage.rnv" %(os.path.expanduser('~')) | |
# load old displays | |
self.content = self.loadDisplay() | |
if self.content == False: | |
self.fetchDepartures(self.options['id']) | |
else: | |
self.checkForUpdate() | |
self.ouput() | |
def parseOptions(self, argv): | |
# default options: | |
options = { | |
"id" : 1228, # number according to the url2 | |
"direction" : "all", # may be: all, | |
"number" : "all" # all or number of line | |
} | |
# fetch all options: | |
try: | |
opts, args = getopt.getopt(argv,"hi:n:d:",["help", "id=","number=","direction="]) | |
except getopt.GetoptError: | |
self.usage() | |
sys.exit(2) | |
for opt, arg in opts: | |
if opt in ("-h", "--help"): | |
# print usage tipps: | |
self.usage() | |
elif opt in ("-i", "--id"): | |
options['id'] = arg | |
elif opt in ("-n", "--number"): | |
options['number'] = arg.split(",") | |
elif opt in ("-d", "--direction"): | |
options['direction'] = arg.split(",") | |
print options['direction'] | |
return options | |
def usage(self): | |
print 'rnv.py -i <hafasID> -n <Bus Number 1, Bus Number 2> -d <all|direction1, direction2>' | |
def checkForUpdate(self): | |
needUpdate = False | |
n = self.content["n"] | |
display = self.content["display"] | |
calltime = self.content["calltime"] | |
ctime = datetime.datetime.now() | |
displayNew = [dep for dep in display if dep[2] > ctime] # new list with only the departures in the future | |
# update if we loste more then 30% of our departures compared to the last call | |
if n > 0 and float(len(displayNew)/n) < 0.7: | |
needUpdate = True | |
if n == 0 or n < 1: | |
needUpdate = True | |
# only update every 5 minutes, not more frequent! | |
difftime = ctime - calltime | |
elapsedMin = divmod(difftime.total_seconds(), 60)[0] | |
if elapsedMin < 5: | |
needUpdate = False | |
# update every 15 minutes anyway | |
if elapsedMin > 15: | |
needUpdate = True | |
# now update if you want | |
if needUpdate: | |
self.fetchDepartures(self.options['id']) | |
else: | |
# save the new display list | |
self.content = { "calltime": calltime, # time of the last call | |
"n":n, # number of results in the last call | |
"display":displayNew} # results of the last call | |
# save this to the cache | |
self.saveDisplay(self.content) | |
''' | |
def fetchStations(self): | |
# this function works, but is not used in this script | |
# it is usefulll to discover the ID of the station you want to display | |
# url for the RNV stations widgets | |
url = "http://rnv.the-agent-factory.de:8080/easygo2/rest/regions/rnv/modules/stations/packages/1" | |
# return the stations to a global variable | |
stations = self.fetchUrl(url) | |
return stations | |
''' | |
def fetchDepartures(self,hafasID): | |
print "fetch departures",hafasID | |
url = 'http://rnv.the-agent-factory.de:8080/easygo2/rest/regions/rnv/modules/stationmonitor/element?hafasID=%s&time=null' % (hafasID) | |
departureJSON = self.fetchUrl(url) | |
ctime = datetime.datetime.now() # current time | |
display = [] | |
# loop trough the results | |
for dep in departureJSON['listOfDepartures']: | |
# now we decide weather to show or to hide this ride | |
show = False | |
if "all" in self.options['number']: | |
show = True | |
elif dep['lineLabel'] in self.options['number']: | |
show = True | |
if show == True and "all" not in self.options["direction"] : | |
if dep['direction'] not in self.options["direction"]: | |
show = False | |
# now we know if we want to show this departure: | |
if show == True : | |
# this text could be displayed directly | |
text = "Line %s (%s) in %s Minuten" %(dep['lineLabel'],dep['direction'],dep['differenceTime']) | |
# transform minutes into absolute time for the cache | |
departureTime = ctime + datetime.timedelta(0,60*int(dep['differenceTime'])) | |
display.append([dep['lineLabel'],dep['direction'],departureTime]) | |
n = len(display) | |
# content object to store data | |
self.content = { "calltime": ctime, # time of the last call | |
"n":n, # number of results in the last call | |
"display":display} # results of the last call | |
# save this to the cache | |
self.saveDisplay(self.content) | |
def saveDisplay(self, content): | |
if(os.path.isfile(self.configPath) == False): | |
# create empty file | |
basedir = os.path.dirname(self.configPath) | |
if not os.path.exists(basedir): | |
os.makedirs(basedir) | |
open(self.configPath, 'a').close() | |
pickle.dump(content, open(self.configPath,"wb")) | |
return False | |
def loadDisplay(self): | |
# read previous saved display lines | |
if(os.path.isfile(self.configPath)): | |
self.content = pickle.load( open( self.configPath, "rb" ) ) | |
return self.content | |
else: | |
return False | |
def fetchUrl(self, url): | |
# fetch the content of the url givven | |
# passing the correct user agent | |
user_agent = 'RNV DesktopWidget v1.0.0' | |
headers = { 'User-Agent' : user_agent } | |
req = urllib2.Request(url, None, headers) | |
response = urllib2.urlopen(req) | |
content = json.loads(response.read()) | |
return content | |
def ouput(self): | |
# return everything to the console simple and plain: | |
n = self.content["n"] | |
display = self.content["display"] | |
calltime = self.content["calltime"] | |
ctime = datetime.datetime.now() | |
sysinfo = "Last call %s %s" % (calltime.date(), calltime.time()) | |
print(sysinfo) | |
for dep in display: | |
minutes = dep[2] - ctime | |
diffMin = int(divmod(minutes.total_seconds(), 60)[0])+1 | |
if diffMin == 1: | |
minuten = "Minute" | |
else: | |
minuten = "Minuten" | |
text = "%s %s Line %s (%s) um %s Uhr" %(diffMin, minuten,dep[0],dep[1],dep[2].strftime("%H:%M")) | |
print (text) | |
if __name__ == "__main__": | |
rnv(sys.argv[1:]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment