eeml-simple 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +19 -0
- data/README +39 -0
- data/examples/simple_server.rb +30 -0
- data/lib/eeml/data.rb +44 -0
- data/lib/eeml/environment.rb +174 -0
- data/lib/eeml/exceptions.rb +7 -0
- data/lib/eeml/location.rb +94 -0
- data/lib/eeml/unit.rb +41 -0
- data/lib/eeml.rb +5 -0
- metadata +72 -0
data/COPYING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 James Smith (james@floppy.org.uk)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
== EEML-Ruby
|
2
|
+
|
3
|
+
A Ruby wrapper around the Extended Environments Markup Language
|
4
|
+
(http://www.eeml.org)
|
5
|
+
|
6
|
+
Licensed under the MIT license (See COPYING file for details)
|
7
|
+
|
8
|
+
Author: James Smith (james@floppy.org.uk / http://www.floppy.org.uk)
|
9
|
+
|
10
|
+
Homepage: http://github.com/Floppy/eeml-ruby
|
11
|
+
|
12
|
+
Documentation: http://docs.github.com/Floppy/eeml-ruby
|
13
|
+
|
14
|
+
== INSTALLATION
|
15
|
+
|
16
|
+
1) Enable gems from gemcutter, if you haven't already done so:
|
17
|
+
> sudo gem install gemcutter
|
18
|
+
> sudo gem tumble
|
19
|
+
|
20
|
+
2) Install gem
|
21
|
+
> sudo gem install eeml-simple
|
22
|
+
|
23
|
+
== STATUS
|
24
|
+
|
25
|
+
The code can current create EEML at a level equivalent to the
|
26
|
+
"complete" EEML example at http://eeml.org/xml/005/complete.xml, and parse the
|
27
|
+
"minimal" level at http://eeml.org/xml/005/minimal.xml
|
28
|
+
|
29
|
+
To parse EEML: call EEML::Environment#from_eeml(your_eeml_string), and you will
|
30
|
+
get back an EEML::Environment object containing a number of EEML::Data objects.
|
31
|
+
|
32
|
+
To create EEML: create an EEML::Environment object, add one or more EEML::Data
|
33
|
+
objects to it, and call EEML::Environment#to_eeml.
|
34
|
+
|
35
|
+
== EXAMPLES
|
36
|
+
|
37
|
+
The file examples/simple_server.rb contains a simple WEBrick server which serves
|
38
|
+
an EEML document. This allows a site like Pachube (http://www.pachube.com) to
|
39
|
+
fetch EEML data from your system.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__) + '/../lib'
|
4
|
+
$LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
5
|
+
|
6
|
+
require 'webrick'
|
7
|
+
require 'eeml'
|
8
|
+
|
9
|
+
# Create an environment object
|
10
|
+
$environment = EEML::Environment.new
|
11
|
+
|
12
|
+
# Set dummy data in environment object
|
13
|
+
$environment << EEML::Data.new(42, :id => "ABC123")
|
14
|
+
|
15
|
+
# Create WEBrick server
|
16
|
+
s = WEBrick::HTTPServer.new( :Port => 50000 )
|
17
|
+
|
18
|
+
# Create a simple webrick servlet for index.eeml
|
19
|
+
class EEMLServlet < WEBrick::HTTPServlet::AbstractServlet
|
20
|
+
def do_GET(request, response)
|
21
|
+
response.status = 200
|
22
|
+
response['Content-Type'] = "text/xml"
|
23
|
+
response.body = $environment.to_eeml
|
24
|
+
end
|
25
|
+
end
|
26
|
+
s.mount("/index.eeml", EEMLServlet)
|
27
|
+
|
28
|
+
# Go
|
29
|
+
trap("INT"){ s.shutdown }
|
30
|
+
s.start
|
data/lib/eeml/data.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module EEML
|
2
|
+
|
3
|
+
# An EEML data item. A valid EEML::Environment must contain at least one of
|
4
|
+
# these.
|
5
|
+
class Data
|
6
|
+
|
7
|
+
# Create a new EEML::Data item.
|
8
|
+
def initialize(value, options = {})
|
9
|
+
@value = value
|
10
|
+
@id = options[:id]
|
11
|
+
@tags = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# Data value
|
15
|
+
attr_accessor :value
|
16
|
+
|
17
|
+
# Data value
|
18
|
+
attr_accessor :id
|
19
|
+
|
20
|
+
# Tag array
|
21
|
+
attr_accessor :tags
|
22
|
+
|
23
|
+
# Minimum value
|
24
|
+
attr_accessor :min_value
|
25
|
+
|
26
|
+
# Maximum value
|
27
|
+
attr_accessor :max_value
|
28
|
+
|
29
|
+
# Unit of measurement
|
30
|
+
def unit
|
31
|
+
@unit
|
32
|
+
end
|
33
|
+
|
34
|
+
# Unit of measurement - must be a EEML::Unit object
|
35
|
+
def unit=(unit_val)
|
36
|
+
unless unit_val.is_a?(EEML::Unit)
|
37
|
+
raise TypeError.new("unit must be an EEML::Unit")
|
38
|
+
end
|
39
|
+
@unit = unit_val
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'builder'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module EEML
|
7
|
+
|
8
|
+
# An EEML environment object. Can contain a number of EEML::Data objects, as
|
9
|
+
# well as having other attributes.
|
10
|
+
class Environment
|
11
|
+
|
12
|
+
# Create new Environment object
|
13
|
+
def initialize
|
14
|
+
@data_items = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create from an EEML document
|
18
|
+
def self.from_eeml(eeml)
|
19
|
+
# Parse EEML
|
20
|
+
doc = REXML::Document.new(eeml)
|
21
|
+
# Create environment object
|
22
|
+
env = Environment.new
|
23
|
+
# Read data items
|
24
|
+
REXML::XPath.each(doc, "/eeml/environment/data") do |node|
|
25
|
+
env << EEML::Data.new(node.elements['value'].text.to_f)
|
26
|
+
end
|
27
|
+
# Done
|
28
|
+
return env
|
29
|
+
end
|
30
|
+
|
31
|
+
# Convert to EEML. Optional parameter describes the version of EEML to generate.
|
32
|
+
# Default (and currently only version implemented) is version 5.
|
33
|
+
def to_eeml(version = nil)
|
34
|
+
if version.nil? || version == 5
|
35
|
+
# Check that we have some data items
|
36
|
+
if size < 1
|
37
|
+
raise EEML::NoData.new('EEML requires at least one data item')
|
38
|
+
end
|
39
|
+
# Create EEML
|
40
|
+
eeml = Builder::XmlMarkup.new
|
41
|
+
eeml.instruct!
|
42
|
+
eeml_options = {:xmlns => "http://www.eeml.org/xsd/005",
|
43
|
+
:'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
|
44
|
+
:'xsi:schemaLocation' => "http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"}
|
45
|
+
eeml_options[:version] = version if version
|
46
|
+
eeml.eeml(eeml_options) do
|
47
|
+
env_options = {}
|
48
|
+
env_options[:updated] = @updated_at.xmlschema if @updated_at
|
49
|
+
env_options[:creator] = @creator if @creator
|
50
|
+
env_options[:id] = @id if @id
|
51
|
+
eeml.environment(env_options) do |env|
|
52
|
+
env.title @title if @title
|
53
|
+
env.feed @feed if @feed
|
54
|
+
env.status @status.to_s if @status
|
55
|
+
env.description @description if @description
|
56
|
+
env.icon @icon if @icon
|
57
|
+
env.website @website if @website
|
58
|
+
env.email @email if @email
|
59
|
+
if @location
|
60
|
+
loc_options = {}
|
61
|
+
loc_options[:domain] = @location.domain
|
62
|
+
loc_options[:exposure] = @location.exposure if @location.exposure
|
63
|
+
loc_options[:disposition] = @location.disposition if @location.disposition
|
64
|
+
env.location(loc_options) do |loc|
|
65
|
+
loc.name @location.name if @location.name
|
66
|
+
loc.lat @location.lat if @location.lat
|
67
|
+
loc.lon @location.lon if @location.lon
|
68
|
+
loc.ele @location.ele if @location.ele
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@data_items.each_index do |i|
|
72
|
+
env.data(:id => @data_items[i].id || i) do |data|
|
73
|
+
@data_items[i].tags.each do |tag|
|
74
|
+
data.tag tag
|
75
|
+
end
|
76
|
+
value_options = {}
|
77
|
+
value_options[:maxValue] = @data_items[i].max_value if @data_items[i].max_value
|
78
|
+
value_options[:minValue] = @data_items[i].min_value if @data_items[i].min_value
|
79
|
+
data.value @data_items[i].value, value_options
|
80
|
+
if @data_items[i].unit
|
81
|
+
unit_options = {}
|
82
|
+
unit_options[:symbol] = @data_items[i].unit.symbol if @data_items[i].unit.symbol
|
83
|
+
unit_options[:type] = @data_items[i].unit.type if @data_items[i].unit.type
|
84
|
+
data.unit @data_items[i].unit.name, unit_options
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Add an EEML::Data object to the environment
|
94
|
+
def <<(value)
|
95
|
+
raise TypeError.new('Only EEML::Data objects can be added to EEML::Environment objects') unless value.is_a?(EEML::Data)
|
96
|
+
@data_items << value
|
97
|
+
end
|
98
|
+
|
99
|
+
# The number of EEML::Data objects in the environment
|
100
|
+
def size
|
101
|
+
@data_items.size
|
102
|
+
end
|
103
|
+
|
104
|
+
# Access contained EEML::Data objects
|
105
|
+
def [](index)
|
106
|
+
@data_items[index]
|
107
|
+
end
|
108
|
+
|
109
|
+
# The title for this EEML feed
|
110
|
+
attr_accessor :title
|
111
|
+
|
112
|
+
# The URL for this EEML feed
|
113
|
+
attr_accessor :feed
|
114
|
+
|
115
|
+
# The status of this EEML feed - can be :frozen or :live
|
116
|
+
def status
|
117
|
+
@status
|
118
|
+
end
|
119
|
+
# The status of this EEML feed - can be :frozen or :live
|
120
|
+
def status=(val)
|
121
|
+
unless [nil, :frozen, :live].include?(val)
|
122
|
+
raise ArgumentError.new("Status must be :frozen or :live")
|
123
|
+
end
|
124
|
+
@status = val
|
125
|
+
end
|
126
|
+
|
127
|
+
# A description of this EEML feed
|
128
|
+
attr_accessor :description
|
129
|
+
|
130
|
+
# The URL of an icon for this feed
|
131
|
+
attr_accessor :icon
|
132
|
+
|
133
|
+
# The URL of a website related to this feed
|
134
|
+
attr_accessor :website
|
135
|
+
|
136
|
+
# The email address of the feed creator
|
137
|
+
attr_accessor :email
|
138
|
+
|
139
|
+
# The location of the feed
|
140
|
+
attr_reader :location
|
141
|
+
|
142
|
+
# Set the location of the feed - loc must be an EEML::Location object
|
143
|
+
def location=(loc)
|
144
|
+
unless loc.is_a?(EEML::Location)
|
145
|
+
raise TypeError.new('loc must be an EEML::Location')
|
146
|
+
end
|
147
|
+
@location = loc
|
148
|
+
end
|
149
|
+
|
150
|
+
# Last updated time
|
151
|
+
attr_reader :updated_at
|
152
|
+
|
153
|
+
# Set last updated time
|
154
|
+
def updated_at=(time)
|
155
|
+
unless time.is_a?(Time)
|
156
|
+
raise TypeError.new('updated_at must be a Time object')
|
157
|
+
end
|
158
|
+
@updated_at = time
|
159
|
+
end
|
160
|
+
|
161
|
+
# Set last updated time
|
162
|
+
def set_updated!
|
163
|
+
@updated_at = Time.now
|
164
|
+
end
|
165
|
+
|
166
|
+
# A string showing the creator of this environment object
|
167
|
+
attr_accessor :creator
|
168
|
+
|
169
|
+
# The ID of the environment object
|
170
|
+
attr_accessor :id
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module EEML
|
2
|
+
|
3
|
+
# An class representing a location. Can be added to EEML::Data objects.
|
4
|
+
class Location
|
5
|
+
|
6
|
+
# Create a new EEML::Location item. Domain setting is required, and must be either :physical or :virtual.
|
7
|
+
def initialize(loc_domain, options = {})
|
8
|
+
set_domain(loc_domain)
|
9
|
+
set_exposure(options[:exposure])
|
10
|
+
set_disposition(options[:disposition])
|
11
|
+
@name = options[:name]
|
12
|
+
self.lat = options[:lat]
|
13
|
+
self.lon = options[:lon]
|
14
|
+
@ele = options[:ele]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Domain (:physical or :virtual)
|
18
|
+
attr_reader :domain
|
19
|
+
|
20
|
+
# Set the domain of the Location - must be either :physical or :virtual
|
21
|
+
def domain=(loc_domain)
|
22
|
+
set_domain(loc_domain)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Exposure (:indoor or :outdoor)
|
26
|
+
attr_reader :exposure
|
27
|
+
|
28
|
+
# Set the exposure of the Location - must be either :indoor or :outdoor
|
29
|
+
def exposure=(loc_exposure)
|
30
|
+
set_exposure(loc_exposure)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Disposition (:fixed or :mobile)
|
34
|
+
attr_reader :disposition
|
35
|
+
|
36
|
+
# Set the disposition of the Location - must be either :fixed or :mobile
|
37
|
+
def disposition=(loc_disposition)
|
38
|
+
set_disposition(loc_disposition)
|
39
|
+
end
|
40
|
+
|
41
|
+
# The name of the location
|
42
|
+
attr_accessor :name
|
43
|
+
|
44
|
+
# Latitude of location
|
45
|
+
attr_reader :lat
|
46
|
+
|
47
|
+
# Set the latitude of the location
|
48
|
+
def lat=(latitude)
|
49
|
+
if latitude && (latitude < -90 || latitude > 90)
|
50
|
+
raise ArgumentError.new("Latitude must be between -90 and +90")
|
51
|
+
end
|
52
|
+
@lat = latitude
|
53
|
+
end
|
54
|
+
|
55
|
+
# Longitude of location
|
56
|
+
attr_reader :lon
|
57
|
+
|
58
|
+
# Set the longitude of the location
|
59
|
+
def lon=(longitude)
|
60
|
+
if longitude && (longitude < -180 || longitude > 180)
|
61
|
+
raise ArgumentError.new("Longitude must be between -180 and +180")
|
62
|
+
end
|
63
|
+
@lon = longitude
|
64
|
+
end
|
65
|
+
|
66
|
+
# Elevation of location
|
67
|
+
attr_accessor :ele
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def set_domain(loc_domain)
|
72
|
+
unless [:physical, :virtual].include?(loc_domain)
|
73
|
+
raise ArgumentError.new("Domain must be :physical or :virtual")
|
74
|
+
end
|
75
|
+
@domain = loc_domain
|
76
|
+
end
|
77
|
+
|
78
|
+
def set_exposure(loc_exposure)
|
79
|
+
unless [nil, :indoor, :outdoor].include?(loc_exposure)
|
80
|
+
raise ArgumentError.new("Exposure must be :indoor or :outdoor")
|
81
|
+
end
|
82
|
+
@exposure = loc_exposure
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_disposition(loc_disposition)
|
86
|
+
unless [nil, :fixed, :mobile].include?(loc_disposition)
|
87
|
+
raise ArgumentError.new("Disposition must be :fixed or :mobile")
|
88
|
+
end
|
89
|
+
@disposition = loc_disposition
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/lib/eeml/unit.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module EEML
|
2
|
+
|
3
|
+
# An class representing a unit or measurement. Can be added to EEML::Data
|
4
|
+
# objects
|
5
|
+
class Unit
|
6
|
+
|
7
|
+
# Create a new EEML::Unit item.
|
8
|
+
def initialize(unit_name, options = {})
|
9
|
+
@name = unit_name
|
10
|
+
@symbol = options[:symbol]
|
11
|
+
set_type(options[:type])
|
12
|
+
end
|
13
|
+
|
14
|
+
# Name of the unit (e.g. "metre")
|
15
|
+
attr_accessor :name
|
16
|
+
|
17
|
+
# Symbol for the unit (e.g. "m")
|
18
|
+
attr_accessor :symbol
|
19
|
+
|
20
|
+
# Get the type of the unit
|
21
|
+
def type
|
22
|
+
@type
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set the type of the unit - must be one of :basicSI, :derivedSI, :conversionBasedUnits, :derivedUnits or :contextDependentUnits
|
26
|
+
def type=(unit_type)
|
27
|
+
set_type(unit_type)
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def set_type(unit_type)
|
33
|
+
unless [nil, :basicSI, :derivedSI, :conversionBasedUnits, :derivedUnits, :contextDependentUnits].include?(unit_type)
|
34
|
+
raise ArgumentError.new("Type must be one of :basicSI, :derivedSI, :conversionBasedUnits, :derivedUnits or :contextDependentUnits")
|
35
|
+
end
|
36
|
+
@type = unit_type
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/eeml.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eeml-simple
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Smith
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-15 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: builder
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.1.2
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: james@floppy.org.uk
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- COPYING
|
36
|
+
- lib/eeml.rb
|
37
|
+
- lib/eeml/environment.rb
|
38
|
+
- lib/eeml/data.rb
|
39
|
+
- lib/eeml/exceptions.rb
|
40
|
+
- lib/eeml/location.rb
|
41
|
+
- lib/eeml/unit.rb
|
42
|
+
- examples/simple_server.rb
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: http://github.com/Floppy/eeml-ruby
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: A Ruby wrapper around the Extended Environments Markup Language
|
71
|
+
test_files: []
|
72
|
+
|