kermit 1.0.0

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.
Files changed (70) hide show
  1. data/Gemfile +18 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +54 -0
  4. data/Rakefile +31 -0
  5. data/VERSION +1 -0
  6. data/bin/kermit +24 -0
  7. data/config/config.example.yml +24 -0
  8. data/doc/Adapter.html +533 -0
  9. data/doc/Converter.html +348 -0
  10. data/doc/DAO.html +1047 -0
  11. data/doc/KermitPFC.html +927 -0
  12. data/doc/Link.html +667 -0
  13. data/doc/Logging.html +401 -0
  14. data/doc/Logging/Settings.html +170 -0
  15. data/doc/RandomAdapter.html +501 -0
  16. data/doc/RandomConverter.html +359 -0
  17. data/doc/RandomPhraseGenerator.html +317 -0
  18. data/doc/ToUser.html +815 -0
  19. data/doc/TwitterAdapter.html +550 -0
  20. data/doc/TwitterConverter.html +598 -0
  21. data/doc/USMF.html +2188 -0
  22. data/doc/User.html +1407 -0
  23. data/doc/WebSocketClient.html +316 -0
  24. data/doc/WebSocketServer.html +427 -0
  25. data/doc/_index.html +270 -0
  26. data/doc/class_list.html +53 -0
  27. data/doc/css/common.css +1 -0
  28. data/doc/css/full_list.css +57 -0
  29. data/doc/css/style.css +328 -0
  30. data/doc/file.LICENSE.html +73 -0
  31. data/doc/file.README.html +123 -0
  32. data/doc/file_list.html +58 -0
  33. data/doc/frames.html +28 -0
  34. data/doc/index.html +123 -0
  35. data/doc/js/app.js +214 -0
  36. data/doc/js/full_list.js +173 -0
  37. data/doc/js/jquery.js +4 -0
  38. data/doc/method_list.html +764 -0
  39. data/doc/top-level-namespace.html +138 -0
  40. data/lib/business/adapter/adapter.rb +39 -0
  41. data/lib/business/adapter/random_adapter.rb +50 -0
  42. data/lib/business/adapter/twitter_adapter.rb +75 -0
  43. data/lib/business/converter/converter.rb +24 -0
  44. data/lib/business/converter/random_converter.rb +42 -0
  45. data/lib/business/converter/twitter_converter.rb +164 -0
  46. data/lib/business/random_phrase_generator.rb +39 -0
  47. data/lib/helper/DAO.rb +94 -0
  48. data/lib/helper/settings.rb +11 -0
  49. data/lib/helper/websocket_client.rb +37 -0
  50. data/lib/helper/websocket_server.rb +65 -0
  51. data/lib/kermitpfc.rb +164 -0
  52. data/lib/logging.rb +31 -0
  53. data/lib/model/USMF/USMF.rb +98 -0
  54. data/lib/model/USMF/link.rb +30 -0
  55. data/lib/model/USMF/to_user.rb +32 -0
  56. data/lib/model/USMF/user.rb +41 -0
  57. data/lib/model/templates/USMF +56 -0
  58. data/lib/model/templates/atom.xml +74 -0
  59. data/lib/model/templates/example +59 -0
  60. data/lib/model/templates/rss.xml +68 -0
  61. data/lib/model/templates/template +49 -0
  62. data/lib/model/templates/tweet +116 -0
  63. data/spec/DAO_spec.rb +64 -0
  64. data/spec/random_adapter_spec.rb +24 -0
  65. data/spec/random_converter_spec.rb +115 -0
  66. data/spec/random_phrase_generator_spec.rb +15 -0
  67. data/spec/twitter_adapter_spec.rb +24 -0
  68. data/spec/twitter_converter_spec.rb +132 -0
  69. data/websocket_client.html +20 -0
  70. metadata +253 -0
@@ -0,0 +1,39 @@
1
+ # @author Daniel Machado Fernandez
2
+ # @version 1.0
3
+ #
4
+ # Self implementation from a Data Stream
5
+ class RandomPhraseGenerator
6
+
7
+ # Generates a random phrase
8
+ #
9
+ # @return [String] a random phrase
10
+ def generate
11
+
12
+ @phrase = ["12453243@juanito@Poesia es la union de dos palabras que uno nunca supuso que pudieran juntarse, y que forman algo asi como un misterio.",
13
+ "1243654@francisco@La poesia huye, a veces, de los libros para anidar extramuros, en la calle, en el silencio, en los suenos, en la piel, en los escombros, incluso en la basura. Donde no suele cobijarse nunca es en el verbo de los subsecretarios, de los comerciantes o de los lechuginos de television.",
14
+ "1288803@david@Al contacto del amor todo el mundo se vuelve poeta.",
15
+ "12388943@lucas@La poesia es el sentimiento que le sobra al corazon y te sale por la mano.",
16
+ "1987343@maria@Los poetas inmaduros imitan; los poetas maduros roban; los malos estropean lo que roban, y los buenos lo convierten en algo mejor.",
17
+ "12243@ana@Digamos que existen dos tipos de mentes poeticas: una apta para inventar fabulas y otra dispuesta a creerlas.",
18
+ "1232453243@lucia@No digais que, agotado su tesoro, de asuntos falta, enmudecio la lira: podra no haber poetas pero siempre habra poesia.",
19
+ "16853243@luisa@Cada poema es unico. En cada obra late, con mayor o menor grado, toda la poesia. Cada lector busca algo en el poema. Y no es insolito que lo encuentre: Ya lo llevaba dentro.",
20
+ "1288653243@mariana@La poesia es el eco de la melodia del universo en el corazon de los humanos.",
21
+ "12445543@kermit@Hacer versos malos depara mas felicidad que leer los versos mas bellos.",
22
+ "12488843@juanjose@En el fondo, un poema no es algo que se ve, sino la luz que nos permite ver. Y lo que vemos es la vida.",
23
+ "1245676543@aaron@El mes que es abundante de poesia, suele serlo de hambre.",
24
+ "12453675673@leticia@La poesia se escribe cuando ella quiere.",
25
+ "124532457673@beatriz@Los poetas son hombres que han conservado sus ojos de nino.",
26
+ "124532435@angel@La poesia no tiene tiempo, el que la lee la rescata, la hace presente y luego la regresa a su eternidad.",
27
+ "124537333@laura@Hay que saber que no existe pais sobre la tierra donde el amor no haya convertido a los amantes en poetas.",
28
+ "1245456093@rita@El vino siembra poesia en los corazones.",
29
+ "1245377993@juanluis@El poeta es un mentiroso que siempre dice la verdad.",
30
+ "1245567533@lorena@Ante la poesia, tanto da temblar como comprender.",
31
+ "124532969@jesus@Cuando un poeta canta estamos en sus manos: el es el que sabe despertar en nosotros aquellas fuerzas secretas; sus palabras nos descubren un mundo maravilloso que antes no conociamos.",
32
+ "124575673223@agustin@En mi propia casa como en la ajena, he creido sentir que la poesia, al penetrar en la palabra, la descompone, la abre como un capullo a todos los matices de significacion."]
33
+
34
+ return @phrase.shuffle.first
35
+
36
+ end
37
+
38
+
39
+ end
@@ -0,0 +1,94 @@
1
+ require 'redis'
2
+ require_relative '../logging'
3
+
4
+ # @author Daniel Machado Fernandez
5
+ # @version 1.0
6
+ #
7
+ # Data Access Object to manage the persistence layer of the app
8
+ class DAO
9
+
10
+ include Logging
11
+
12
+ # @!attribute type
13
+ # @return [String] Type of the stream to identify the database
14
+ attr_accessor :type
15
+
16
+ # @!attribute db
17
+ # @return [Redis] An instance from a Redis DB with the redis gem
18
+ # @see http://rubydoc.info/gems/redis/3.0.1/frames
19
+ attr_accessor :db
20
+
21
+ # Config the DAO defining the Data Stream
22
+ #
23
+ # @param type [String] type of the Data Stream to choose the correct database
24
+ def initialize (type = 'twitter')
25
+
26
+ @type = type
27
+
28
+ logger.debug('Starting DAO...')
29
+
30
+ logger.info(type + " DAO in " + type.to_s + " type")
31
+
32
+ logger.info("config loaded OK")
33
+ connect_database
34
+
35
+ end
36
+
37
+ # Connects to a redis database
38
+ def connect_database
39
+ @db = Redis.new
40
+
41
+ logger.debug("New instance for Redis")
42
+
43
+ @db = Redis.connect(
44
+ :db => "#{Settings.redis.db}",
45
+ :host => "#{Settings.redis.host}",
46
+ :port => Settings.redis.port,
47
+ :password => Settings.redis.password
48
+ )
49
+
50
+ logger.info("Redis connect OK")
51
+ end
52
+
53
+ # Retrieves the next status that were saved in the database
54
+ #
55
+ # @return [String] the status from the Adapter
56
+ def get_status
57
+ logger.debug("getting status")
58
+ status = @db.rpop @type
59
+ status
60
+ end
61
+
62
+ # Deletes the keys in the database to starts the FW empty
63
+ # @note if the user develops more Streams, add the new keys like the existing ones
64
+ def clean
65
+ logger.debug("cleaning the db")
66
+ @db.del 'twitter'
67
+ @db.del 'rpg'
68
+ end
69
+
70
+ # Persists the status into the database
71
+ #
72
+ # @param status [String] the status to persist it
73
+ def save_status status
74
+ @db.rpush @type, status
75
+ logger.info("Status saved")
76
+ end
77
+
78
+ # Returns the size of the database
79
+ #
80
+ # @return [Integer] the size (items) of the database
81
+ def size
82
+ logger.debug("getting size")
83
+ @db.llen @type
84
+ end
85
+
86
+ # Publish a message in the websocket server
87
+ #
88
+ # @param usmf [USMF] a message to publish
89
+ def publish usmf
90
+ logger.info("Publishing")
91
+ @db.publish 'ws', usmf
92
+ end
93
+
94
+ end
@@ -0,0 +1,11 @@
1
+ #settings.rb
2
+ require 'settingslogic'
3
+
4
+ # @author Daniel Machado Fernandez
5
+ # @version 1.0
6
+ # Implements the SettingsLogic gem Class to load the properties defined in the config.yml file
7
+ class Logging::Settings < Settingslogic
8
+
9
+ source "config/config.yml"
10
+
11
+ end
@@ -0,0 +1,37 @@
1
+ require 'em-http'
2
+ require_relative '../logging'
3
+
4
+ # @author Daniel Machado Fernandez
5
+ # @version 1.0
6
+ #
7
+ # A WebSocket client to help testing the WebSocket Server
8
+ class WebSocketClient
9
+
10
+ include Logging
11
+
12
+ # Starts the WebSocket client to consume the published info in the WebSocket Server
13
+ def start
14
+
15
+ EventMachine.run do
16
+
17
+ puts '='*80, "Connecting to websockets server at ws://#{Settings.websocket.host}:#{Settings.websocket.port}", '='*80
18
+
19
+ http = EventMachine::HttpRequest.new("ws://#{Settings.websocket.host}:#{Settings.websocket.port}/websocket").get :timeout => 0
20
+
21
+ http.errback do
22
+ logger.error "something was wrong in the websocket_client"
23
+ end
24
+
25
+ http.callback do
26
+ puts "#{Time.now.strftime('%H:%M:%S')} : Connected to server"
27
+ end
28
+
29
+ http.stream do |msg|
30
+ puts msg
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,65 @@
1
+ require 'redis'
2
+ require 'em-websocket'
3
+
4
+ require_relative '../logging'
5
+
6
+ # WebSocket clients array
7
+ SOCKETS = []
8
+
9
+ # @author Daniel Machado Fernandez
10
+ # @version 1.0
11
+ #
12
+ # WebSocket Server where the USMF messages will be published
13
+ class WebSocketServer
14
+
15
+ include Logging
16
+
17
+ # Configures the WebSocket to works in test mode (path controversia)
18
+ def initialize
19
+
20
+ logger.info("Starting WebSocketServer...")
21
+
22
+ end
23
+
24
+ # Starts the Websocket server and listen the new clients to broadcast the messages
25
+ def start
26
+ @redis = Redis.new(:host => "#{Settings.redis.host}", :port => Settings.redis.port)
27
+
28
+
29
+ Thread.new do
30
+ EventMachine.run do
31
+ puts '='*80, "Starting websockets server at ws://#{Settings.websocket.host}:#{Settings.websocket.port}", '='*80
32
+
33
+ EventMachine::WebSocket.start(:host => "#{Settings.websocket.host}", :port => Settings.websocket.port) do |ws|
34
+ ws.onopen do
35
+
36
+ puts "#{Time.now.strftime('%H:%M:%S')} : Client connected", '-'*80
37
+ SOCKETS << ws
38
+ end
39
+
40
+ ws.onclose do
41
+
42
+ puts "#{Time.now.strftime('%H:%M:%S')} : Client disconnected", '-'*80
43
+ SOCKETS.delete ws
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ Thread.new do
51
+ @redis.subscribe('ws') do |on|
52
+
53
+ on.message do |chan, msg|
54
+
55
+ puts "#{msg}"
56
+ SOCKETS.each {|s| s.send msg}
57
+
58
+ end
59
+ end
60
+ end
61
+
62
+ sleep
63
+
64
+ end
65
+ end
@@ -0,0 +1,164 @@
1
+ require_relative 'business/adapter/twitter_adapter'
2
+ require_relative 'business/converter/twitter_converter'
3
+ require_relative 'business/converter/random_converter'
4
+ require_relative 'business/adapter/random_adapter'
5
+ require_relative 'helper/DAO'
6
+ require_relative 'helper/websocket_server'
7
+ require_relative './logging'
8
+ require 'json'
9
+
10
+ # @author Daniel Machado Fernandez
11
+ # @version 1.0
12
+ #
13
+ # Masterclass that adapts the rakefile into a class to use the commander gem
14
+ # @see http://rubydoc.info/gems/commander/4.1.2/frames
15
+ class KermitPFC
16
+
17
+ # Load the config file
18
+ def initialize
19
+
20
+ begin
21
+
22
+ cleaning_the_house
23
+
24
+ puts 'pooling'
25
+
26
+ pool = []
27
+ pool << Thread.new { initialize_websocket_server }
28
+
29
+ puts 'websocket started'
30
+
31
+ for i in 1..Logging::Settings.twitter.streams
32
+
33
+ puts "adding twitter adapter ##{i}"
34
+ pool << Thread.new { twitter_adapter i }
35
+ sleep 1
36
+
37
+ end
38
+
39
+ puts 'twitter adapters added'
40
+
41
+ if Logging::Settings.rpg
42
+
43
+ pool << Thread.new { random_adapter }
44
+ puts 'random adapter added'
45
+
46
+ pool << Thread.new { random_converter }
47
+ puts 'random converter added'
48
+
49
+ end
50
+
51
+ pool << Thread.new { twitter_converter }
52
+ puts 'twitter converter added'
53
+
54
+ pool.each do |thread|
55
+ thread.join
56
+ end
57
+
58
+ rescue Exception => e
59
+
60
+ Logging::logger.error(e)
61
+
62
+ pool.each do |thread|
63
+ Thread.kill(thread)
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+
71
+ # Deletes the db keys previously used
72
+ def cleaning_the_house
73
+
74
+ dao = DAO.new
75
+ dao.clean
76
+
77
+ end
78
+
79
+ # Starts the WebSocket Server
80
+ def initialize_websocket_server
81
+
82
+ ws = WebSocketServer.new
83
+ ws.start
84
+
85
+ end
86
+
87
+ # Starts the Twitter Adapter
88
+ #
89
+ # @param stream [Integer] the number of the stream
90
+ def twitter_adapter stream
91
+
92
+ ta = TwitterAdapter.new
93
+ ta.connect_stream stream
94
+
95
+ end
96
+
97
+ # Starts the Random Adapter
98
+ #
99
+ # @param stream [Integer] the number of the stream
100
+ def random_adapter stream=1
101
+
102
+ ra = RandomAdapter.new
103
+ ra.connect_stream stream
104
+
105
+ end
106
+
107
+ # Starts the Twitter Converter
108
+ def twitter_converter
109
+
110
+ dao = DAO.new 'twitter'
111
+
112
+ while true
113
+
114
+ status = dao.get_status
115
+ puts 'Status retrieved'
116
+
117
+ while status != nil
118
+
119
+ tc = TwitterConverter.new
120
+ usmf = tc.to_usmf status
121
+
122
+ dao.publish usmf.to_hash.to_json
123
+ puts 'Published'
124
+
125
+ status = dao.get_status
126
+
127
+ end
128
+
129
+ puts 'All the statuses were been sent'
130
+ sleep 2
131
+
132
+ end
133
+
134
+ end
135
+
136
+ # Starts the Random Converter
137
+ def random_converter
138
+
139
+ dao = DAO.new 'rpg'
140
+
141
+ while true
142
+
143
+ status = dao.get_status
144
+ puts 'Status retrieved'
145
+
146
+ while status != nil
147
+
148
+ rc = RandomConverter.new
149
+ usmf = rc.to_usmf status
150
+
151
+ dao.publish usmf.to_hash.to_json
152
+ puts 'Published'
153
+
154
+ status = dao.get_status
155
+
156
+ end
157
+
158
+ puts 'All the statuses were been sent'
159
+ sleep 2
160
+
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,31 @@
1
+ # @author Daniel Machado Fernandez
2
+ # @version 1.0
3
+ #
4
+ # Loads the config file, the logger and the KermitPFC masterclass
5
+ module Logging
6
+
7
+ require 'yaml'
8
+ require 'logger'
9
+ require_relative './kermitpfc'
10
+ require_relative './helper/settings'
11
+
12
+ # its neccessary to build the gem and make it run
13
+ KermitPFC = ::KermitPFC
14
+
15
+ # offers the logger to the app
16
+ # @return [Logger] the logger
17
+ def logger
18
+ Logging.logger
19
+ end
20
+
21
+ # solve the problem with path controversia in the log file
22
+ # @return [Logger] the logger with the correct path of log.txt
23
+ def self.logger
24
+ begin
25
+ @logger ||= Logger.new('../log/log.txt','monthly')
26
+ rescue
27
+ @logger ||= Logger.new('./log/log.txt','monthly')
28
+ end
29
+ end
30
+
31
+ end