tg-can-controls-gateway 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +7 -0
  2. data/Capfile +8 -0
  3. data/README +243 -0
  4. data/Rakefile +54 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/application_controller.rb +10 -0
  7. data/app/helpers/application_helper.rb +3 -0
  8. data/bin/can_controls_gateway +36 -0
  9. data/doc/090630_Gestentracking_RFID.pdf +0 -0
  10. data/doc/README_FOR_APP +3 -0
  11. data/doc/home.png +0 -0
  12. data/doc/life.png +0 -0
  13. data/doc/preshow.png +0 -0
  14. data/doc/recognition-message-example.xml +69 -0
  15. data/etc/init-script_debian +56 -0
  16. data/lib/can-controls-gateway.rb +4 -0
  17. data/lib/ccg_logger.rb +6 -0
  18. data/lib/cursor_vector.rb +60 -0
  19. data/lib/dispatcher.rb +85 -0
  20. data/lib/osc_broadcast_receiver.rb +41 -0
  21. data/lib/osc_broadcast_sender.rb +44 -0
  22. data/lib/osc_package.rb +56 -0
  23. data/lib/osc_to_rca_dispatcher.rb +42 -0
  24. data/lib/ping.rb +84 -0
  25. data/lib/raw_event.rb +33 -0
  26. data/lib/rca_command.rb +42 -0
  27. data/lib/runner.rb +97 -0
  28. data/lib/server.rb +45 -0
  29. data/lib/settings.rb +17 -0
  30. data/log/development.log +0 -0
  31. data/log/production.log +0 -0
  32. data/log/server.log +0 -0
  33. data/log/test.log +0 -0
  34. data/public/404.html +30 -0
  35. data/public/422.html +30 -0
  36. data/public/500.html +30 -0
  37. data/public/favicon.ico +0 -0
  38. data/public/images/gesten/1.png +0 -0
  39. data/public/images/gesten/10.png +0 -0
  40. data/public/images/gesten/11.png +0 -0
  41. data/public/images/gesten/2.png +0 -0
  42. data/public/images/gesten/3.png +0 -0
  43. data/public/images/gesten/4.png +0 -0
  44. data/public/images/gesten/5.png +0 -0
  45. data/public/images/gesten/6.png +0 -0
  46. data/public/images/gesten/7.png +0 -0
  47. data/public/images/gesten/8.png +0 -0
  48. data/public/images/gesten/9.png +0 -0
  49. data/public/images/rails.png +0 -0
  50. data/public/index.html +275 -0
  51. data/public/javascripts/application.js +2 -0
  52. data/public/javascripts/controls.js +963 -0
  53. data/public/javascripts/dragdrop.js +973 -0
  54. data/public/javascripts/effects.js +1128 -0
  55. data/public/javascripts/prototype.js +4320 -0
  56. data/public/robots.txt +5 -0
  57. data/script/about +4 -0
  58. data/script/console +3 -0
  59. data/script/dbconsole +3 -0
  60. data/script/destroy +3 -0
  61. data/script/generate +3 -0
  62. data/script/performance/benchmarker +3 -0
  63. data/script/performance/profiler +3 -0
  64. data/script/plugin +3 -0
  65. data/script/runner +3 -0
  66. data/script/server +3 -0
  67. data/spec/can-controls-gateway/rca_command_spec.rb +31 -0
  68. data/spec/spec.opts +1 -0
  69. data/spec/spec_helper.rb +10 -0
  70. data/test/performance/browsing_test.rb +9 -0
  71. data/test/test_helper.rb +38 -0
  72. metadata +167 -0
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'socket'
3
+ require 'osc'
4
+ require 'time'
5
+
6
+ ADDR = ['0.0.0.0', 33333] # host, port
7
+ BasicSocket.do_not_reverse_lookup = true
8
+
9
+ UDPSock = UDPSocket.new
10
+ UDPSock.bind(ADDR[0], ADDR[1])
11
+
12
+ lastUpdate = 0
13
+ numPackages = 0
14
+ frequency = 0
15
+
16
+ while true do
17
+ currentUpdate = Time.now
18
+ my_data, my_addr = UDPSock.recvfrom(32768) # if this number is too low it will drop the larger packets and never give them to you
19
+
20
+ decoded = OSC::Packet.decode my_data rescue decoded = nil
21
+
22
+ if decoded.nil?
23
+ my_event = nil
24
+ else
25
+ my_msg = decoded[0][1]
26
+ if my_msg[0].kind_of?(OSC::OSCString) #s
27
+ my_event = my_msg[0]
28
+ elsif my_msg[2].kind_of?(OSC::OSCString) # ffs
29
+ my_event = my_msg[2]
30
+ else
31
+ my_event = nil # something else, e.g. ff
32
+ end
33
+ end
34
+ puts "#{Time.now.iso8601} | From addr: '%s', msg: '%s'" % [my_addr.inspect, my_event]
35
+ puts ""
36
+ frequency = 1 / (currentUpdate - lastUpdate) rescue nil
37
+ lastUpdate = currentUpdate
38
+ numPackages = 0
39
+ #puts "#{frequency} Hz"
40
+ end
41
+ UDPSock.close
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'socket'
3
+ require 'osc'
4
+ require 'time'
5
+
6
+ ADDR = ['<broadcast>', 6567] # broadcast address
7
+ STATION_ID = 1
8
+ DIMENSIONALITY = 2
9
+ EVENTS = [ "swipeDown", "swipeUp", "swipeLeft", "swipeRight", "zoomIn", "zoomOut",
10
+ "cancel", "mouseDown", 'bigSwipe', "mouseMove", 'mouseUp', 'otherunknown' ]
11
+
12
+ UDPSock = UDPSocket.new
13
+ UDPSock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
14
+
15
+ puts "sending osc packages"
16
+
17
+ while true do
18
+ #case ['cursor', 'event', 'event_and_cursor', 'invalid'].choice
19
+ case ['cursor', 'event', 'event_and_cursor', 'invalid'].choice
20
+ when 'cursor':
21
+ puts 'cursor'
22
+ my_message = OSC::Message.new("/cursor/#{STATION_ID}/1/#{DIMENSIONALITY}",
23
+ 'ff', 0.3, 0.3).encode
24
+ when 'event':
25
+ puts 'event'
26
+ my_message = OSC::Message.new("/cursor/#{STATION_ID}/1/#{DIMENSIONALITY}",'s', EVENTS.choice).encode
27
+ when 'event_and_cursor':
28
+ puts 'event_and_cursor'
29
+ my_message = OSC::Message.new("/cursor/#{STATION_ID}/1/#{DIMENSIONALITY}",
30
+ 'ffs', 0.3, 0.3, EVENTS.choice).encode
31
+ when 'invalid';
32
+ puts 'invalid'
33
+ my_message = 'hallo'
34
+ end
35
+
36
+ puts my_message.inspect
37
+
38
+ UDPSock.send(my_message, 0, ADDR[0], ADDR[1])
39
+ sleep 1.0/2.0 # Hz
40
+ end
41
+
42
+ UDPSock.close
43
+
44
+ puts "good bye"
@@ -0,0 +1,56 @@
1
+ require 'osc'
2
+ require 'socket'
3
+ #require 'ccg_logger'
4
+
5
+ module CanControlsGateway
6
+
7
+ class OscPackage
8
+
9
+ ADDR = ['<broadcast>', OSC_BROADCAST_PORT] # broadcast address
10
+
11
+ def initialize event, station_id
12
+ @event = event
13
+ @station_id = station_id
14
+ end
15
+
16
+ def broadcast
17
+ my_message = prepare_message
18
+ ##
19
+ #CcgLogger::LOGGER.info "#{Time.now.iso8601} | broadcasting osc_package with vector '#{@event.vector}' and event_type '#{@event.event_type}'"
20
+ ##
21
+ my_encoded_message = my_message.encode
22
+ BasicSocket.do_not_reverse_lookup = true
23
+ my_socket = UDPSocket.new
24
+
25
+ my_socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
26
+ my_socket.send(my_encoded_message, 0, ADDR[0], ADDR[1])
27
+ my_socket.close
28
+
29
+ my_encoded_message.to_s
30
+ end
31
+
32
+ private
33
+
34
+ def prepare_message
35
+ if @event.vector.nil?
36
+ dimensionality = 0
37
+ else
38
+ dimensionality = @event.vector.dimensions
39
+ end
40
+
41
+ if dimensionality == 0
42
+ my_message = OSC::Message.new "/cursor/#{@station_id}/1/#{dimensionality}",
43
+ 's', @event.event_type
44
+ elsif dimensionality == 2
45
+ my_message = OSC::Message.new "/cursor/#{@station_id}/1/#{dimensionality}",
46
+ 'sff', @event.event_type, @event.vector.x, @event.vector.y
47
+ else
48
+ my_message = OSC::Message.new "/cursor/#{@station_id}/1/#{dimensionality}",
49
+ 's', @event.event_type
50
+ end
51
+ my_message
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,42 @@
1
+ require 'osc'
2
+ require 'rca_command'
3
+
4
+ module CanControlsGateway
5
+
6
+ class OscToRcaDispatcher
7
+
8
+ attr_reader :event, :raw_data, :osc_packet, :osc_message
9
+
10
+ def initialize data
11
+ @raw_data = data
12
+ @osc_packet = OSC::Packet.decode @raw_data rescue @osc_packet = nil
13
+ @osc_message = @osc_packet[0][1] rescue @osc_message = nil
14
+ @event = extract_event
15
+ end
16
+
17
+ def dispatch_rca
18
+ return true if @event.nil?
19
+ my_args = { 'action' => @event }
20
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | >> OscToRcaDispatcher: sending command : rci_uri: #{STATION['rci_uri']}, target: #{STATION['target']}, args: #{my_args.inspect}"
21
+ my_command = CanControlsGateway::RcaCommand.new STATION['rci_uri'],
22
+ STATION['target'],
23
+ my_args
24
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} #{my_command.send_command}"
25
+ end
26
+
27
+ private
28
+
29
+ def extract_event
30
+ return nil if @osc_message.nil?
31
+ if @osc_message[0].kind_of?(OSC::OSCString) #s
32
+ return EVENTS[@osc_message[0].to_s]
33
+ elsif @osc_message[2].kind_of?(OSC::OSCString) # ffs
34
+ return EVENTS[@osc_message[2].to_s]
35
+ else
36
+ return nil # something else, e.g. ff
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
data/lib/ping.rb ADDED
@@ -0,0 +1,84 @@
1
+ require 'socket'
2
+ require 'time'
3
+
4
+ SERVER = "localhost"
5
+ PORT = 6567
6
+ STATIONS = 1
7
+ #EVENTS = [ 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove',
8
+ # 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove',
9
+ # 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove', 'mouseMove',
10
+ # 'mouseDown', 'mouseUp', 'mouseDown', 'mouseUp',
11
+ # "swipeDown", "swipeUp", "swipeLeft", "swipeRight", "zoomIn", "zoomOut",
12
+ # "cancel", "mouseDown", 'bigSwipe', "mouseMove", 'mouseUp', 'otherunknown'
13
+ # ]
14
+
15
+ EVENTS = ['mouseMove']
16
+
17
+ XML_EVENT_TEMPLATE = <<-XML
18
+ <?xml version="1.0" encoding="UTF-8"?>
19
+ <trackingdata ts="" station_id="%s">
20
+ <event type="%s">
21
+ <position type="vec3f" coordinate_system="plane">%s, %s, 0</position>
22
+ </event>
23
+ </trackingdata>
24
+ XML
25
+
26
+ XML_MOVE_EVENT_TEMPLATE = <<-XML
27
+ <?xml version="1.0" encoding="UTF-8"?>
28
+ <trackingdata ts="" station_id="%s">
29
+ <event type="mouseMove">
30
+ <position type="vec3f" coordinate_system="plane">%s, %s, 0</position>
31
+ </event>
32
+ <event type="%s"></event>
33
+ </trackingdata>
34
+ XML
35
+
36
+ XML_EVENT_TEMPLATE_NO_DATA = <<-XML
37
+ <?xml version="1.0" encoding="UTF-8"?>
38
+ <trackingdata ts="" station_id="%s">
39
+ <event type="%s">
40
+ </event>
41
+ </trackingdata>
42
+ XML
43
+
44
+ XML_NO_EVENT_TEMPLATE = <<-XML
45
+ <?xml version="1.0" encoding="UTF-8"?>
46
+ <trackingdata ts="" station_id="%s">
47
+ </trackingdata>
48
+ XML
49
+
50
+ def generate_payload
51
+ if [true].choice
52
+ my_event = EVENTS.choice
53
+ puts "event >>>>>> #{my_event}"
54
+ my_now = Time.now
55
+ if ['mouseMove', 'mouseDown', 'mouseUp'].include? my_event
56
+ sprintf(XML_EVENT_TEMPLATE, (rand*STATIONS).to_i, my_event, Math.sin(my_now), Math.cos(my_now))
57
+ else
58
+ sprintf(XML_MOVE_EVENT_TEMPLATE, (rand*STATIONS).to_i, Math.sin(my_now), Math.cos(my_now), my_event)
59
+ end
60
+ else
61
+ puts "no event"
62
+ sprintf(XML_NO_EVENT_TEMPLATE, (rand*STATIONS).to_i)
63
+ end
64
+ end
65
+
66
+ def send_gesture(server_addr, server_port, payload)
67
+ resp, sock = nil, nil
68
+ begin
69
+ sock = UDPSocket.open
70
+ puts payload
71
+ sock.send("#{payload}", 0, server_addr, server_port)
72
+ resp = ["sent"]
73
+ rescue IOError, SystemCallError
74
+ ensure
75
+ sock.close if sock
76
+ end
77
+ resp ? resp[0] : nil
78
+ end
79
+
80
+ (1..30000).each do |i|
81
+ sleep 1.0/40.0 # 40 Hertz
82
+ result = send_gesture(SERVER, PORT, generate_payload)
83
+ puts "#{result} - #{i}"
84
+ end
data/lib/raw_event.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'rexml/document'
2
+ require 'rexml/xpath'
3
+
4
+ require 'cursor_vector'
5
+
6
+ module CanControlsGateway
7
+
8
+ class RawEvent
9
+
10
+ attr_reader :vector, :event_type
11
+
12
+ def initialize xml_node
13
+ @xml_node = REXML::Document.new(xml_node.to_s)
14
+ @vector = nil
15
+ @event_type = nil
16
+ parse_xml
17
+ end
18
+
19
+ private
20
+
21
+ def parse_xml
22
+ @event_type = REXML::XPath.first(@xml_node, "/event/attribute::type")
23
+ @event_type = @event_type.value if @event_type
24
+
25
+ my_vector_match = REXML::XPath.first(@xml_node, "/event/position")
26
+ if my_vector_match
27
+ @vector = CanControlsGateway::CursorVector.new(my_vector_match)
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,42 @@
1
+ require 'net/https'
2
+ require 'cgi'
3
+
4
+ module CanControlsGateway
5
+
6
+ class RcaCommand
7
+
8
+ attr_reader :arguments, :target, :rci_uri
9
+
10
+ def initialize rci_uri, target, arguments={}
11
+ @rci_uri = rci_uri
12
+ @target = target
13
+ @arguments = prepare_command_arguments arguments
14
+ end
15
+
16
+ def send_command
17
+ post_data = "target=#{@target}&arguments=#{@arguments}"
18
+ url = URI.parse(@rci_uri)
19
+ request = Net::HTTP::Post.new(url.path)
20
+ begin
21
+ response = Net::HTTP::start(url.host, url.port) { |http|
22
+ http.request(request, post_data)
23
+ }
24
+ return response.code.to_i, response.body
25
+ rescue Exception => e
26
+ return 500, "#{e}"
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def prepare_command_arguments arguments
33
+ my_arguments_list = []
34
+ arguments.keys.sort.each do |key|
35
+ my_arguments_list << "#{key}=#{arguments[key]}"
36
+ end
37
+ CGI::escape(my_arguments_list.join("&"))
38
+ end
39
+
40
+ end
41
+
42
+ end
data/lib/runner.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+
4
+ require 'rest_fs/client'
5
+
6
+ require 'settings'
7
+ require 'server'
8
+
9
+ class CcgRunner < Gom::Remote::Entry
10
+
11
+ Defaults = {
12
+ :logfile => '-',
13
+ :port => nil,
14
+ :valve => :closed,
15
+ }
16
+
17
+ include OAttr
18
+ oattr :incoming_osc_port, :device
19
+
20
+ attr_reader :valve
21
+
22
+ def self.instance
23
+ @@instance
24
+ end
25
+
26
+ def initialize path, options = {}
27
+ @@instance = self
28
+ @path = path
29
+ @options = Defaults.merge(gnode @path).merge(options)
30
+ puts "options: #{@options.inspect}"
31
+
32
+ # FIXIT: legacy! pushing config values from GOM to global variable!!!
33
+ STATION['port'] = Integer(incoming_osc_port)
34
+ STATION['device'] = device
35
+ STATION['rci_uri'] = device_rci_uri
36
+ puts " -- STATION info: #{STATION.inspect}"
37
+
38
+ init_gnp
39
+ end
40
+
41
+ def device_rci_uri
42
+ @device_rci_uri ||= connection.read "#{device}:rci_uri.txt"
43
+ end
44
+
45
+ def run
46
+ #fill_settings
47
+ port = Integer(incoming_osc_port)
48
+ if port.nil?
49
+ raise "NOT Starting servers since port cannot be determined"
50
+ end
51
+
52
+ puts "#{Time.now.iso8601} | ++ Starting servers"
53
+ EventMachine::threadpool_size = 20
54
+ EventMachine::run do
55
+ puts "#{Time.now.iso8601} | ++ * UdpServer (port: #{port}) ..."
56
+ EventMachine::open_datagram_socket('0.0.0.0', port, UdpServer)
57
+ # TODO place http server component for GNP callbacks here...
58
+ end
59
+ end
60
+
61
+ private
62
+ def init_gnp
63
+ @sub = Subscription.new(
64
+ "#{@path}:valve", :name => "ccg", :operations => [:update, :create]
65
+ )
66
+ @sub.callback = lambda { |*args| valve_update(*args) }
67
+ connection.subscribe @sub
68
+ end
69
+
70
+ def valve_update op, attribute
71
+ @valve = attribute["value"].to_sym
72
+ puts " -- can-controls-valve now: #{@valve}"
73
+ end
74
+ end
75
+
76
+ __END__
77
+
78
+ def _fill_settings
79
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | ++ Initializing settings ..."
80
+ my_gom = RestFs::Client.new GOM_ROOT
81
+
82
+ my_res = my_gom.retrieve("#{STATION['device']}:rci_uri")
83
+ if my_res
84
+ STATION['rci_uri'] = my_res['attribute']['value']
85
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | ++ setting rci_uri for station #{STATION['device']} => #{STATION['rci_uri'].inspect}"
86
+
87
+ my_port_res = my_gom.retrieve("#{STATION['device']}/hid:port")
88
+ if my_port_res
89
+ STATION['port'] = my_port_res['attribute']['value']
90
+ else
91
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | ++ device's hid:port #{STATION['device']}/hid:port not found in gom"
92
+ end
93
+ else
94
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | ++ device's rci_uri #{STATION['device']}:rci_uri not found in gom"
95
+ end
96
+ end
97
+
data/lib/server.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+ require 'socket'
4
+
5
+ require 'osc_to_rca_dispatcher'
6
+
7
+ module UdpServer
8
+
9
+ def post_init
10
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | ++ ... server started"
11
+ end
12
+
13
+ def receive_data(data)
14
+ puts "1"
15
+ return unless(CcgRunner.instance.valve == :open)
16
+ puts "2"
17
+
18
+ ##
19
+ #CcgLogger::LOGGER.info "#{Time.now.iso8601} | >> raw incoming data: ----------------------"
20
+ #CcgLogger::LOGGER.info data.inspect
21
+ #CcgLogger::LOGGER.info " --------------------------------------------"
22
+ ##
23
+
24
+ #port, ip = Socket.unpack_sockaddr_in(get_peername)
25
+ #CcgLogger::LOGGER.info "#{Time.now.iso8601} | >> UdpServer: sender: #{ip}, #{port}"
26
+
27
+ # RCA
28
+ rca_dispatching = proc {
29
+ my_dispatcher = CanControlsGateway::OscToRcaDispatcher.new data
30
+ #CcgLogger::LOGGER.info my_dispatcher.event.inspect
31
+ my_dispatcher.dispatch_rca
32
+ }
33
+ rca_callback = proc { |result|
34
+ #if result
35
+ # CcgLogger::LOGGER.info "#{Time.now.iso8601} | >> UdpServer: result is: #{result.inspect}"
36
+ #end
37
+ }
38
+ EventMachine::defer rca_dispatching, rca_callback
39
+ end
40
+
41
+ def unbind
42
+ CcgLogger::LOGGER.info "#{Time.now.iso8601} | -- UdpServer stopped"
43
+ end
44
+
45
+ end
data/lib/settings.rb ADDED
@@ -0,0 +1,17 @@
1
+ STATION = {
2
+ 'device' => '/areas/home/tv',
3
+ 'target' => 'input_dispatcher',
4
+ }
5
+
6
+ #GOM_ROOT = "http://gom"
7
+ #GOM_ROOT = "http://localhost:3080"
8
+
9
+ EVENTS = { "swipeDown" => "down",
10
+ "swipeUp" => "up",
11
+ "swipeLeft" => "left",
12
+ "swipeRight" => "right",
13
+ "zoomIn" => "in",
14
+ "zoomOut" => "out",
15
+ "cancel" => "cancel",
16
+ "mouseDown" => "confirm",
17
+ "bigSwipe" => 'start'}
File without changes
File without changes
data/log/server.log ADDED
File without changes
data/log/test.log ADDED
File without changes
data/public/404.html ADDED
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+
6
+ <head>
7
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
8
+ <title>The page you were looking for doesn't exist (404)</title>
9
+ <style type="text/css">
10
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
11
+ div.dialog {
12
+ width: 25em;
13
+ padding: 0 4em;
14
+ margin: 4em auto 0 auto;
15
+ border: 1px solid #ccc;
16
+ border-right-color: #999;
17
+ border-bottom-color: #999;
18
+ }
19
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
20
+ </style>
21
+ </head>
22
+
23
+ <body>
24
+ <!-- This file lives in public/404.html -->
25
+ <div class="dialog">
26
+ <h1>The page you were looking for doesn't exist.</h1>
27
+ <p>You may have mistyped the address or the page may have moved.</p>
28
+ </div>
29
+ </body>
30
+ </html>
data/public/422.html ADDED
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+
6
+ <head>
7
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
8
+ <title>The change you wanted was rejected (422)</title>
9
+ <style type="text/css">
10
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
11
+ div.dialog {
12
+ width: 25em;
13
+ padding: 0 4em;
14
+ margin: 4em auto 0 auto;
15
+ border: 1px solid #ccc;
16
+ border-right-color: #999;
17
+ border-bottom-color: #999;
18
+ }
19
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
20
+ </style>
21
+ </head>
22
+
23
+ <body>
24
+ <!-- This file lives in public/422.html -->
25
+ <div class="dialog">
26
+ <h1>The change you wanted was rejected.</h1>
27
+ <p>Maybe you tried to change something you didn't have access to.</p>
28
+ </div>
29
+ </body>
30
+ </html>
data/public/500.html ADDED
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+
6
+ <head>
7
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
8
+ <title>We're sorry, but something went wrong (500)</title>
9
+ <style type="text/css">
10
+ body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
11
+ div.dialog {
12
+ width: 25em;
13
+ padding: 0 4em;
14
+ margin: 4em auto 0 auto;
15
+ border: 1px solid #ccc;
16
+ border-right-color: #999;
17
+ border-bottom-color: #999;
18
+ }
19
+ h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
20
+ </style>
21
+ </head>
22
+
23
+ <body>
24
+ <!-- This file lives in public/500.html -->
25
+ <div class="dialog">
26
+ <h1>We're sorry, but something went wrong.</h1>
27
+ <p>We've been notified about this issue and we'll take a look at it shortly.</p>
28
+ </div>
29
+ </body>
30
+ </html>
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file