Skip to content

Commit

Permalink
Merge pull request #6 from hiposfer/reader
Browse files Browse the repository at this point in the history
fix: read-edn macro doesnt exists in cljs
  • Loading branch information
carocad authored Dec 8, 2018
2 parents 7cb0e2e + 9f2abcb commit c7c3edb
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 35 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ dont want to manually recreate it.

# Usage

This project can be used in two ways, dependending on how you wish to use it.
This project can be used in two ways:

- as a Clojure(script) library

Expand All @@ -24,14 +24,19 @@ convenience functions exposed through the `hiposfer.gtfs.edn` namespace.
(ns my.namespace
(:require [hiposfer.gtfs.edn :as gtfs]))

;; fetch the reference gtfs spec first
;; ONLY for clojure -> in clojurescript you would need to use the git submodule
;; approach. See below
(def gtfs-spec (gtfs/spec))

;; fetch all gtfs fields that are required
(filter :required gtfs/fields)
(filter :required (gtfs/fields gtfs-spec))

;; fetch all gtfs fields that represent a dataset unique attribute
(filter :unique gtfs/fields)
(filter :unique (gtfs/fields gtfs-spec))

;; fetch all gtfs fields for the "agency.txt" feed
(filter #(= "agency.txt" (:filename %)) gtfs/fields)
(filter #(= "agency.txt" (:filename %)) (gtfs/fields gtfs-spec))
```

- as a git submodule
Expand Down
9 changes: 5 additions & 4 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
(defproject hiposfer/gtfs.edn "0.1.2"
(defproject hiposfer/gtfs.edn "0.2.0"
:description "A simple gtfs library that exposes the GTFS spec as edn data"
:url "https://github.com/hiposfer/kamal"
:url "https://github.com/hiposfer/gtfs.edn"
:license {:name "LGPLv3"
:url "https://github.com/hiposfer/kamal/blob/master/LICENSE"}
:url "https://github.com/hiposfer/gtfs.edn/blob/master/LICENSE"}
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.9.0" :scope "provided"]
[org.clojure/clojurescript "1.9.946" :scope "provided"]]
:profiles {:dev {:dependencies [[markdown2clj "0.1.3"]]
:plugins [[jonase/eastwood "0.2.6"]]}}
;; deploy to clojars as - lein deploy releases
:deploy-repositories [["releases" {:sign-releases false :url "https://clojars.org/repo"}]])
:deploy-repositories [["releases" {:sign-releases false :url "https://clojars.org/repo"}]
["snapshots" {:sign-releases false :url "https://clojars.org/repo"}]])
68 changes: 41 additions & 27 deletions src/hiposfer/gtfs/edn.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@
nil
coll))

#?(:clj (defmacro read-edn
[resource]
`(edn/read-string (slurp (io/resource ~resource)))))
#?(:clj (defn spec
[]
(edn/read-string (clojure.core/slurp (io/resource "reference.edn")))))

(def gtfs-spec (read-edn "reference.edn"))

(def identifiers (for [feed (:feeds gtfs-spec)
field (:fields feed)
:when (:unique field)]
field))
(defn identifiers
"returns a sequence of fields from the gtfs spec that are marked as DATASET UNIQUE"
[spec]
(for [feed (:feeds spec)
field (:fields feed)
:when (:unique field)]
field))

(defn- singularly
"removes the s at the end of a name"
Expand All @@ -33,15 +34,21 @@
(str/ends-with? text "s") (subs text 0 (dec (count text)))
:else text))

(defn- reference?
"checks if text references a field name based on its content. A reference
is a field name that ends with the same name as a unique field"
[text]
(some (fn [uf] (when (str/ends-with? text uf) uf)) (map :field-name identifiers)))
(defn reference?
"given the sequence of dataset unique identifiers, checks if a field
represents a reference to another field in the spec.
NOTE: this is not guaranteed to work as it is based on heuristics"
[identifiers field]
(some (fn [unique]
(when (and (str/ends-with? (:field-name field) (:field-name unique))
(not (:unique field)))
unique))
identifiers))

(defn- gtfs-mapping
"returns a namespaced keyword that will represent this field in datascript"
[ns-name field]
[dataset-unique ns-name field]
(let [field-name (:field-name field)]
(cond
;; "agency_id" -> :agency/id
Expand All @@ -53,7 +60,7 @@
(keyword ns-name (subs field-name (inc (count ns-name))))

;; "trip_route_id" -> :trip/route
(reference? field-name)
(reference? dataset-unique field)
(keyword ns-name (subs field-name 0 (- (count field-name) (count "_id"))))

;; "stop_time_pickup_type" -> :stop_time/pickup_type
Expand All @@ -66,34 +73,41 @@
(singularly (first (str/split (:filename feed) #"\.")))))
;;(feed-namespace (nth (:feeds gtfs-spec) 9))

(def fields
(defn fields
"a sequence of gtfs field data with a :keyword entry.
Useful to have a direct mapping between GTFS fields and Clojure fully
qualified keywords"
(for [feed (:feeds gtfs-spec)
:let [ns-name (feed-namespace feed)]
field (:fields feed)]
(let [k (gtfs-mapping ns-name field)]
(assoc field :keyword k :filename (:filename feed)))))
[spec]
(let [dataset-unique (identifiers spec)]
(for [feed (:feeds spec)
:let [ns-name (feed-namespace feed)]
field (:fields feed)]
(let [k (gtfs-mapping dataset-unique ns-name field)]
(assoc field :keyword k :filename (:filename feed))))))

(defn get-mapping
"given a gtfs feed and field name returns its field data from the gtfs/field
A single fully qualified keyword is also accepted as argument"
([filename field-name]
([spec filename field-name]
(reduce (fn [_ v] (when (and (= filename (:filename v))
(= field-name (:field-name v)))
(reduced v)))
nil
fields))
([k]
(fields spec)))
([spec k]
(reduce (fn [_ v] (when (= k (:keyword v)) (reduced v)))
nil
fields)))
;;(get-mapping "agency.txt" "agency_id")
(fields spec))))

;;(get-mapping (spec) "agency.txt" "agency_id")
;;(get-mapping "trips.txt" "route_id")
;;(get-mapping "calendar.txt" "service_id")
;;(get-mapping "calendar_dates.txt" "service_id")
;;(get-mapping :calendar/id)
;;(get-mapping :calendar_date/service)

;(def f1 (fields (reference)))

;(def f2 (fields (reference)))

0 comments on commit c7c3edb

Please sign in to comment.