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.
- data/Gemfile +18 -0
- data/LICENSE.txt +20 -0
- data/README.md +54 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/bin/kermit +24 -0
- data/config/config.example.yml +24 -0
- data/doc/Adapter.html +533 -0
- data/doc/Converter.html +348 -0
- data/doc/DAO.html +1047 -0
- data/doc/KermitPFC.html +927 -0
- data/doc/Link.html +667 -0
- data/doc/Logging.html +401 -0
- data/doc/Logging/Settings.html +170 -0
- data/doc/RandomAdapter.html +501 -0
- data/doc/RandomConverter.html +359 -0
- data/doc/RandomPhraseGenerator.html +317 -0
- data/doc/ToUser.html +815 -0
- data/doc/TwitterAdapter.html +550 -0
- data/doc/TwitterConverter.html +598 -0
- data/doc/USMF.html +2188 -0
- data/doc/User.html +1407 -0
- data/doc/WebSocketClient.html +316 -0
- data/doc/WebSocketServer.html +427 -0
- data/doc/_index.html +270 -0
- data/doc/class_list.html +53 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +328 -0
- data/doc/file.LICENSE.html +73 -0
- data/doc/file.README.html +123 -0
- data/doc/file_list.html +58 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +123 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +173 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +764 -0
- data/doc/top-level-namespace.html +138 -0
- data/lib/business/adapter/adapter.rb +39 -0
- data/lib/business/adapter/random_adapter.rb +50 -0
- data/lib/business/adapter/twitter_adapter.rb +75 -0
- data/lib/business/converter/converter.rb +24 -0
- data/lib/business/converter/random_converter.rb +42 -0
- data/lib/business/converter/twitter_converter.rb +164 -0
- data/lib/business/random_phrase_generator.rb +39 -0
- data/lib/helper/DAO.rb +94 -0
- data/lib/helper/settings.rb +11 -0
- data/lib/helper/websocket_client.rb +37 -0
- data/lib/helper/websocket_server.rb +65 -0
- data/lib/kermitpfc.rb +164 -0
- data/lib/logging.rb +31 -0
- data/lib/model/USMF/USMF.rb +98 -0
- data/lib/model/USMF/link.rb +30 -0
- data/lib/model/USMF/to_user.rb +32 -0
- data/lib/model/USMF/user.rb +41 -0
- data/lib/model/templates/USMF +56 -0
- data/lib/model/templates/atom.xml +74 -0
- data/lib/model/templates/example +59 -0
- data/lib/model/templates/rss.xml +68 -0
- data/lib/model/templates/template +49 -0
- data/lib/model/templates/tweet +116 -0
- data/spec/DAO_spec.rb +64 -0
- data/spec/random_adapter_spec.rb +24 -0
- data/spec/random_converter_spec.rb +115 -0
- data/spec/random_phrase_generator_spec.rb +15 -0
- data/spec/twitter_adapter_spec.rb +24 -0
- data/spec/twitter_converter_spec.rb +132 -0
- data/websocket_client.html +20 -0
- 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
|
data/lib/helper/DAO.rb
ADDED
@@ -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
|
data/lib/kermitpfc.rb
ADDED
@@ -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
|
data/lib/logging.rb
ADDED
@@ -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
|