Skip to content

Commit

Permalink
Merge pull request #153 from mvanlaar/new-ui
Browse files Browse the repository at this point in the history
New ui and lot of new features brought in by @mvanlaar. Merging to non-master branch "v4.0.0". More time will be needed to work on resolving outstanding issues; then when we're ready we can make this the master branch.
  • Loading branch information
answerquest authored Oct 13, 2019
2 parents 98f5333 + 1163b0f commit 4a2b17c
Show file tree
Hide file tree
Showing 608 changed files with 336,042 additions and 4,784 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ db
export
logs
uploads
*.pyc

68 changes: 67 additions & 1 deletion GTFSManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import json
import os
import time, datetime
# import url handlers
from handlers.config import APIKeys
# import all utils from the /utils folder.
import utils

import xmltodict
import pandas as pd
Expand Down Expand Up @@ -1074,7 +1078,67 @@ def get(self):
# time check, from https://stackoverflow.com/a/24878413/4355695
end = time.time()
logmessage("shape GET call took {} seconds.".format(round(end-start,2)))



class gtfsshape(tornado.web.RequestHandler):
def post(self):
# ${APIpath}shape?pw=${pw}&route=${route_id}&id=${shape_id}&reverseFlag=${reverseFlag}
start = time.time()
logmessage('\nshape POST call')
pw = self.get_argument('pw', default='')
if not decrypt(pw):
self.set_status(400)
self.write("Error: invalid password.")
return
shapePrefix = self.get_argument('id', default='')
logmessage(shapePrefix)

if not (len(shapePrefix)):
self.set_status(400)
self.write("Error: Invalid route or shape id prefix.")
return

data = json.loads(self.request.body.decode('UTF-8'))

replaceTableDB('shapes', data, key='shape_id', value=shapePrefix)

self.write('Saved to shapes table in DB.')

end = time.time()
logmessage("shape POST call took {} seconds.".format(round(end-start, 2)))

def get(self):
# API/shape?shape=${shape_id}
start = time.time()
logmessage('\nshape GET call')
shape_id = self.get_argument('shape', default='')
print(shape_id)

if not len(shape_id):
self.set_status(400)
self.write("Error: invalid shape.")
return

shapeDf = readTableDB('shapes', key='shape_id', value=shape_id)

if not len(shapeDf):
self.set_status(400)
self.write("Error: Given shape_id is not present in shapes table in DB.")
return

# need to sort this array before returning it. See https://github.com/WRI-Cities/static-GTFS-manager/issues/22
shapeDf.shape_pt_sequence = shapeDf.shape_pt_sequence.astype(int)
# type-cast the column as int before sorting!

sortedShapeJson = shapeDf.sort_values(
'shape_pt_sequence').to_json(orient='records', force_ascii=False)
# sort ref: http://pandas.pydata.org/pandas-docs/version/0.19/generated/pandas.DataFrame.sort.html
self.write(sortedShapeJson)

# time check, from https://stackoverflow.com/a/24878413/4355695
end = time.time()
logmessage("shape GET call took {} seconds.".format(round(end-start, 2)))

class allShapesList(tornado.web.RequestHandler):
def get(self):
start = time.time()
Expand Down Expand Up @@ -1416,6 +1480,8 @@ def make_app():
(r"/API/frequencies", frequencies),
(r"/API/tableReadSave", tableReadSave),
(r"/API/tableColumn", tableColumn),
(r"/API/Config/ApiKeys", APIKeys),
(r"/API/gtfs/shapes", gtfsshape),
#(r"/API/idList", idList),
# (r"/(.*)", tornado.web.StaticFileHandler, {"path": root, "default_filename": "index.html"})
(r"/(.*)", MyStaticFileHandler, {"path": root, "default_filename": "index.html"})
Expand Down
240 changes: 176 additions & 64 deletions agency.html
Original file line number Diff line number Diff line change
@@ -1,71 +1,183 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Agency and Feed_info</title>
<link href="lib/jquery-ui.min.css" rel="stylesheet">
<link href="lib/tabulator.min.css" rel="stylesheet">
<link href="lib/bootstrap.v4.0.0.min.css" crossorigin="anonymous" alt="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" rel="stylesheet">
<link rel="stylesheet" href="lib/chosen/chosen.min.css">
<link href="js/commonstyle.css" rel="stylesheet">
<!-- Put the CSSs first and JSs next -->

<script src="lib/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="lib/jquery-ui.min.js" type="text/javascript"></script>
<script src="lib/tabulator.js" type="text/javascript"></script>
<script src="lib/popper.v1.12.9.min.js" crossorigin="anonymous" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" alt="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="lib/bootstrap.v4.0.0.min.js" crossorigin="anonymous" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" alt="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="lib/papaparse.min.js" type="text/javascript"></script>
<script src="lib/chosen/chosen.jquery.min.js" type="text/javascript"></script>
<style>
#agency-table {
height: 300px;
}
</style></head>
<body>
<div id="navBar"></div>

<div class="container">
<h2>Agency</h2>
<br>
<div class="row">
<div class="col-md-8">

<div id="agency-table"></div>
<br>
<p>Create a new agency:
<input placeholder="agency_id" id="agency2add" size="7"><button class="btn-primary btn-xs" id="addAgencyButton" type="button">Add</button> &nbsp; <small><span id="agencyAddStatus"></span></small></p>
<html lang="en">

<p><button id="saveAgencyButton" class="btn btn-outline-success btn-md">Save Agency Changes</button> &nbsp; <small id="agencySaveStatus"></small></p>

</div><div class="col-md-4">

<div class="alert alert-info"><small>
Used for the feed's metadata, and in Routes section if there are multiple agencies and the route has to be shown to operate under an agency. <a href="https://github.com/google/transit/blob/master/gtfs/spec/en/reference.md#agencytxt" target="_blank">See specs</a>.
<br><br>Note: To delete an agency, please go to <a href="deleteID.html">Tools > Delete ID</a>.
</small></div>
<head>
<!-- Required meta tags-->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>GTFS Manager : Agency info</title>
<!-- Fontfaces CSS-->
<link href="css/font-face.css" rel="stylesheet" media="all">
<link href="vendor/font-awesome-5/css/all.min.css" rel="stylesheet" media="all">
<!-- Bootstrap CSS-->
<link href="vendor/bootstrap-4.1/bootstrap.min.css" rel="stylesheet" media="all">
<!-- Vendor CSS-->
<link href="vendor/wow/animate.css" rel="stylesheet" media="all">
<link href="vendor/css-hamburgers/hamburgers.min.css" rel="stylesheet" media="all">
<link href="vendor/select2/css/select2.min.css" rel="stylesheet" media="all">
<link href="vendor/select2/css/select2-bootstrap4.min.css" rel="stylesheet" media="all">
<link href="vendor/toast-0.7.1/toast.min.css" rel="stylesheet" media="all">
<link href="vendor/tabulator-4.4.3/css/bootstrap/tabulator_bootstrap4.min.css" rel="stylesheet" media="all">
<script src="vendor/tabulator-4.4.3/js/tabulator.min.js"></script>
<!-- Main CSS-->
<link href="css/theme.css" rel="stylesheet" media="all">
<!-- Put the CSSs first and JSs next -->
<style>
/* Always set a height for the tabulator tables to imporve performance! */
#agency-table {
height: 250px;
}
</style>
<script src="config/settings.js" type="text/javascript"></script>
</head>

</div></div>
<body class="page-content--bgf7">
<div class="page-wrapper">
<!-- HEADER DESKTOP-->
<header class="header-desktop3 d-none d-lg-block">
<div class="section__content section__content--p35">
<div class="header3-wrap">
<div class="header__logo">
<a href="#">
<img src="extra_files/GTFS.png" width="52" height="170" alt="GTFS Manager" />
</a>
</div>
<div class="header__navbar" id="navmenuinsert">
<!-- menu will be inserted from menu.js.-->
</div>
<div class="form-inline my-2 my-md-0">
<input id="password" class="form-control mr-sm-2" type="text" placeholder="pw for edits" style="width:200px;" id="password">
</div>
</div>
</div>
</header>
<!-- END HEADER DESKTOP-->
<!-- MAIN CONTENT-->
<div class="page-content--bgf7">
<div class="section__content section__content--p30">
<div class="container-fluid p-t-20">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<strong class="card-title mb-3">Agency</strong>
</div>
<div class="card-body">
<div id="agency-table" class="table table-striped"></div>
</div>
</div>
</div>
</div>
</div>
<div class="container-fluid p-t-20">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<strong class="card-title mb-3">Create a new agency</strong>
</div>
<div class="card-body">
<div id="Form-AddAgency" data-parsley-validate>
<div class="form-group parsley-input">
<label for="agency_id" aria-required="true">agency_id</label>
<input placeholder="agency_id" id="agency_id" class="form-control" required autocomplete="off" data-parsley-required-message="You have to add a agency_id, without it it won't work!">
<small id="agency_idHelp" class="form-text text-muted">Identifies a transit brand, which is often the same as a transit agency.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_name" aria-required="true">agency_name</label>
<input placeholder="agency_name" id="agency_name" class="form-control" required autocomplete="off" data-parsley-required-message="You have to add a agency_name, without it it won't work!">
<small id="agency_nameHelp" class="form-text text-muted">Contains the full name of the transit agency.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_url" aria-required="true">agency_url</label>
<input placeholder="agency_url" id="agency_url" class="form-control" required autocomplete="off" data-parsley-required-message="You have to add a agency_url, without it it won't work!">
<small id="agency_urlHelp" class="form-text text-muted">Contains the URL of the transit agency.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_timezone" aria-required="true">agency_timezone</label>
<select id="agency_timezone" class="form-control" data-parsley-required-message="You have to add a agency_url, without it it won't work!"></select>
<small id="agency_timezoneHelp" class="form-text text-muted">Contains the timezone where the transit agency is located. If multiple agencies are specified in the feed, each must have the same agency_timezone.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_lang" aria-required="true">agency_lang</label>
<select id="agency_lang" class="form-control"></select>
<small id="agency_langHelp" class="form-text text-muted">Specifies the primary language used by this transit agency..</small>
</div>
<div class="form-group parsley-input">
<label for="agency_phone" aria-required="true">agency_phone</label>
<input placeholder="agency_phone" id="agency_phone" class="form-control" autocomplete="off">
<small id="agency_phoneHelp" class="form-text text-muted">Provides a voice telephone number for the specified agency.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_fare_url" aria-required="true">agency_fare_url</label>
<input placeholder="agency_fare_url" id="agency_url" class="form-control">
<small id="agency_fare_urlHelp" class="form-text text-muted">Specifies the URL of a web page where a rider can purchase tickets or other fare instruments for the agency online.</small>
</div>
<div class="form-group parsley-input">
<label for="agency_email" aria-required="true">agency_email</label>
<input placeholder="agency_email" id="agency_email" class="form-control">
<small id="agency_emailHelp" class="form-text text-muted">Contains a valid email address that's actively monitored by the agency's customer service department.</small>
</div>
</div>
<div class="alert alert-info" role="alert">
<small>
Used for the feed's metadata, and in Routes section if there are multiple agencies and the route has to be shown to operate under an agency. <a href="https://developers.google.com/transit/gtfs/reference/#agencytxt" target="_blank">See specs</a>.
<br>Note: To delete an agency, please go to <a href="deleteID.html">Tools > Delete ID</a>.
</small>
</div>
</div>
<div class="card-footer">
<button class="btn btn-primary float-right" id="addAgencyButton" type="button">Add Agency</button>
</div>

<hr>
<h2>Feed_info</h2>
<p>This is an optional table (only one row), for giving information about the feed. See <a href="https://github.com/google/transit/blob/master/gtfs/spec/en/reference.md#feed_infotxt" target="_blank">specs document</a> for details.</p>
<p>
feed_publisher_name* : <input id="feed_publisher_name"></p><p>
feed_publisher_url* : <input id="feed_publisher_url"></p><p>
feed_lang* : <input id="feed_lang"></p><p>
feed_start_date : <input id="feed_start_date"></p><p>
feed_end_date : <input id="feed_end_date"></p><p>
feed_version : <input id="feed_version"></p><p>
feed_contact_email : <input id="feed_contact_email"></p><p>
feed_contact_url : <input id="feed_contact_url"></p><p>
</p>
<p><button id="saveFeedInfoButton" class="btn btn-outline-success btn-md">Save Feed_info Changes</button> &nbsp; <small id="feedInfoSaveStatus"></small></p>
<p><small>Note: If you are having feed_info table at all, then the top 3 fields are compulsory. Otherwise, leave everything blank.</small></p>
</div>
<script src="config/settings.js" type="text/javascript"></script>
<script src="js/commonfuncs.js" type="text/javascript"></script>
<script src="js/agency.js"></script>
</div>
</div>
</div>
</div>
</div>
<!-- END MAIN CONTENT-->
<!-- END PAGE CONTAINER-->
</div>
</div>
<!-- Jquery JS-->
<script src="vendor/jquery-3.2.1.min.js"></script>
<!-- Bootstrap JS-->
<script src="vendor/bootstrap-4.1/popper.min.js"></script>
<script src="vendor/bootstrap-4.1/bootstrap.min.js"></script>
<!-- Vendor JS -->
<script src="vendor/select2/js/select2.min.js"></script>
<script src="js/Select2EditorTimezone.js"></script>
<script src="js/Select2EditorLanguage.js"></script>
<script src="vendor/toast-0.7.1/toast.min.js"></script>
<script src="js/tabulator-footer.js"></script>
<!-- Form validator-->
<script src="vendor/parsley-2.9.1/parsley.min.js"></script>
<!-- Main JS-->
<script src="js/main.js"></script>
<script src="js/menu.js"></script>
<script src="js/commonfuncs.js" type="text/javascript"></script>
<script src="js/agency.js"></script>

<!-- Modal -->
<div class="modal fade" id="DeleteColumnModal" tabindex="-1" role="dialog" aria-labelledby="DeleteColumnModalTitle" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="DeleteColumnModalTitle">Delete Non standard columns</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="DeleteColumnModalBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary nonstandardbutton" id="DeleteColumnButton">Remove columns</button>
</div>
</div>
</div>
</div>
</body>

</html>
Loading

0 comments on commit 4a2b17c

Please sign in to comment.