infractores 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.
- checksums.yaml +7 -0
- data/.env.sample +8 -0
- data/.gitignore +22 -0
- data/.travis.yml +14 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +67 -0
- data/Gemfile.lock +417 -0
- data/Guardfile +8 -0
- data/LICENSE +21 -0
- data/Procfile +2 -0
- data/README.md +48 -0
- data/Rakefile +6 -0
- data/app/assets/images/.keep +0 -0
- data/app/assets/images/gallery-buttons.png +0 -0
- data/app/assets/images/logo-infractores.svg +10 -0
- data/app/assets/javascripts/application.js +18 -0
- data/app/assets/javascripts/bootstrap.js +4 -0
- data/app/assets/javascripts/index.js +82 -0
- data/app/assets/javascripts/twitter.js +18 -0
- data/app/assets/stylesheets/1-utilities/_variables.scss +12 -0
- data/app/assets/stylesheets/2-quarks/_typography.scss +32 -0
- data/app/assets/stylesheets/3-atoms/_buttons.scss +3 -0
- data/app/assets/stylesheets/4-molecules/_footer.scss +32 -0
- data/app/assets/stylesheets/4-molecules/_infraction-gallery.scss +101 -0
- data/app/assets/stylesheets/4-molecules/_navbar.scss +71 -0
- data/app/assets/stylesheets/5-pages/index.scss +165 -0
- data/app/assets/stylesheets/5-pages/show.scss +29 -0
- data/app/assets/stylesheets/application.css +18 -0
- data/app/assets/stylesheets/bootstrap_and_overrides.css +7 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/concerns/.keep +0 -0
- data/app/controllers/infractions_controller.rb +23 -0
- data/app/controllers/users_controller.rb +7 -0
- data/app/helpers/application_helper.rb +19 -0
- data/app/helpers/infractions_helper.rb +6 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/models/concerns/.keep +0 -0
- data/app/models/evidence.rb +23 -0
- data/app/models/infraction.rb +43 -0
- data/app/models/tweet.rb +54 -0
- data/app/models/user.rb +34 -0
- data/app/services/twitter_service.rb +51 -0
- data/app/uploaders/evidence_uploader.rb +62 -0
- data/app/views/infractions/_map.html.erb +17 -0
- data/app/views/infractions/_reported_by.html.erb +4 -0
- data/app/views/infractions/_summary.html.erb +23 -0
- data/app/views/infractions/index.html.erb +18 -0
- data/app/views/infractions/show.html.erb +24 -0
- data/app/views/layouts/application.html.erb +90 -0
- data/app/views/shared/_google_analytics.html.erb +12 -0
- data/app/views/users/index.html.erb +21 -0
- data/app/workers/tweet_inspector.rb +18 -0
- data/bin/bundle +3 -0
- data/bin/rails +8 -0
- data/bin/rake +8 -0
- data/bin/setup +29 -0
- data/bin/spring +15 -0
- data/config.ru +4 -0
- data/config/application.rb +27 -0
- data/config/boot.rb +3 -0
- data/config/database.yml.sample +85 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +50 -0
- data/config/environments/production.rb +79 -0
- data/config/environments/test.rb +42 -0
- data/config/initializers/assets.rb +15 -0
- data/config/initializers/backtrace_silencers.rb +7 -0
- data/config/initializers/carrierwave.rb +17 -0
- data/config/initializers/cookies_serializer.rb +3 -0
- data/config/initializers/filter_parameter_logging.rb +4 -0
- data/config/initializers/inflections.rb +16 -0
- data/config/initializers/mime_types.rb +4 -0
- data/config/initializers/session_store.rb +3 -0
- data/config/initializers/twitter.rb +1 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/locales/en.bootstrap.yml +23 -0
- data/config/locales/en.yml +23 -0
- data/config/locales/es.yml +263 -0
- data/config/routes.rb +6 -0
- data/config/secrets.yml +22 -0
- data/db/migrate/20150824210535_add_tweets_table.rb +8 -0
- data/db/migrate/20150829133406_create_infractions.rb +11 -0
- data/db/migrate/20150829134520_create_users.rb +12 -0
- data/db/migrate/20150829141909_add_user_id_to_tweets.rb +5 -0
- data/db/migrate/20150829154430_create_locations.rb +10 -0
- data/db/migrate/20150830224603_create_evidences_table.rb +8 -0
- data/db/migrate/20150911020838_add_valid_column_to_infractions.rb +6 -0
- data/db/migrate/20150911025204_add_index_to_users_username.rb +5 -0
- data/db/migrate/20151102220702_add_lat_lon_to_infractions.rb +6 -0
- data/db/migrate/20151102221811_remove_locations.rb +5 -0
- data/db/migrate/20151117194703_add_reported_at_to_infractions.rb +5 -0
- data/db/migrate/20160229023500_change_lat_lon_precision.rb +6 -0
- data/db/seeds.rb +7 -0
- data/infractores.gemspec +25 -0
- data/lib/assets/.keep +0 -0
- data/lib/infractores.rb +1 -0
- data/lib/infractores/version.rb +3 -0
- data/lib/tasks/.keep +0 -0
- data/lib/tasks/twitter.rake +16 -0
- data/lib/tasks/users.rake +9 -0
- data/log/.keep +0 -0
- data/public/404.html +67 -0
- data/public/422.html +67 -0
- data/public/500.html +66 -0
- data/public/favicon.ico +0 -0
- data/public/robots.txt +5 -0
- data/vendor/assets/images/blank.gif +0 -0
- data/vendor/assets/images/fancybox_loading.gif +0 -0
- data/vendor/assets/images/fancybox_loading@2x.gif +0 -0
- data/vendor/assets/images/fancybox_overlay.png +0 -0
- data/vendor/assets/images/fancybox_sprite.png +0 -0
- data/vendor/assets/images/fancybox_sprite@2x.png +0 -0
- data/vendor/assets/images/glyphicons-halflings-white.png +0 -0
- data/vendor/assets/images/glyphicons-halflings.png +0 -0
- data/vendor/assets/javascripts/.keep +0 -0
- data/vendor/assets/javascripts/jquery.fancybox-buttons.js +122 -0
- data/vendor/assets/javascripts/jquery.fancybox.pack.js +46 -0
- data/vendor/assets/javascripts/livereload.js +1183 -0
- data/vendor/assets/stylesheets/.keep +0 -0
- data/vendor/assets/stylesheets/jquery.fancybox-buttons.css +97 -0
- data/vendor/assets/stylesheets/jquery.fancybox.css +274 -0
- metadata +215 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
class TwitterService
|
|
2
|
+
|
|
3
|
+
@@instance = nil
|
|
4
|
+
|
|
5
|
+
def self.instance
|
|
6
|
+
@@instance ||= TwitterService.new
|
|
7
|
+
@@instance
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_accessor :client
|
|
11
|
+
|
|
12
|
+
# Downloads all the new mentions since the last mention and the hashtagged
|
|
13
|
+
# tweets. Creates all the necessary {Tweet} records.
|
|
14
|
+
def download_tweets
|
|
15
|
+
opts = {}
|
|
16
|
+
if tweet = Tweet.last
|
|
17
|
+
opts[:since_id] = tweet.id
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
tl = client.mentions_timeline(opts)
|
|
21
|
+
|
|
22
|
+
tl.each do |tuit|
|
|
23
|
+
Tweet.find_or_create!(tuit)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
tl = client.search "##{screen_name} -rt"
|
|
27
|
+
|
|
28
|
+
tl.each do |tuit|
|
|
29
|
+
tuit = client.status tuit.id
|
|
30
|
+
Tweet.find_or_create!(tuit)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def screen_name
|
|
35
|
+
@screen_name ||= client.user.screen_name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def initialize
|
|
41
|
+
client = Twitter::REST::Client.new do |config|
|
|
42
|
+
config.consumer_key = ENV["TWITTER_CONSUMER_KEY"]
|
|
43
|
+
config.consumer_secret = ENV["TWITTER_CONSUMER_SECRET"]
|
|
44
|
+
config.access_token = ENV["TWITTER_ACCESS_TOKEN"]
|
|
45
|
+
config.access_token_secret = ENV["TWITTER_ACCESS_SECRET"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
self.client = client
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
class EvidenceUploader < CarrierWave::Uploader::Base
|
|
4
|
+
# Include RMagick or MiniMagick support:
|
|
5
|
+
# include CarrierWave::RMagick
|
|
6
|
+
include CarrierWave::MiniMagick
|
|
7
|
+
|
|
8
|
+
if Rails.env.test?
|
|
9
|
+
storage :file
|
|
10
|
+
else
|
|
11
|
+
storage :fog
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Override the directory where uploaded files will be stored.
|
|
16
|
+
# This is a sensible default for uploaders that are meant to be mounted:
|
|
17
|
+
def store_dir
|
|
18
|
+
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Provide a default URL as a default if there hasn't been a file uploaded:
|
|
22
|
+
# def default_url
|
|
23
|
+
# # For Rails 3.1+ asset pipeline compatibility:
|
|
24
|
+
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
|
25
|
+
#
|
|
26
|
+
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
|
27
|
+
# end
|
|
28
|
+
|
|
29
|
+
# Process files as they are uploaded:
|
|
30
|
+
# process :scale => [200, 300]
|
|
31
|
+
#
|
|
32
|
+
# def scale(width, height)
|
|
33
|
+
# # do something
|
|
34
|
+
# end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Create different versions of your uploaded files:
|
|
38
|
+
version :square do
|
|
39
|
+
process resize_to_fit: [400, 400]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
version :horizontal do
|
|
43
|
+
process resize_to_fit: [300, 200]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
version :vertical do
|
|
47
|
+
process resize_to_fit: [200, 300]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Add a white list of extensions which are allowed to be uploaded.
|
|
51
|
+
# For images you might use something like this:
|
|
52
|
+
def extension_white_list
|
|
53
|
+
%w(jpg jpeg gif png)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Override the filename of the uploaded files:
|
|
57
|
+
# Avoid using model.id or version_name here, see uploader/store.rb for details.
|
|
58
|
+
# def filename
|
|
59
|
+
# "something.jpg" if original_filename
|
|
60
|
+
# end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<div class="map" id="map_canvas_<%= infraction.id %>"></div>
|
|
2
|
+
<script>
|
|
3
|
+
function initialize_<%= infraction.id %>() {
|
|
4
|
+
var myLatLng = {lat: <%= infraction.lat %>, lng: <%= infraction.lon %>};
|
|
5
|
+
var mapCanvas = document.getElementById('map_canvas_<%= infraction.id %>');
|
|
6
|
+
var mapOptions = {
|
|
7
|
+
center: myLatLng,
|
|
8
|
+
zoom: 16,
|
|
9
|
+
mapTypeId: google.maps.MapTypeId.ROADMAP
|
|
10
|
+
}
|
|
11
|
+
var map = new google.maps.Map(mapCanvas, mapOptions);
|
|
12
|
+
var marker = new google.maps.Marker({
|
|
13
|
+
map: map,
|
|
14
|
+
position: myLatLng
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<div class="content">
|
|
2
|
+
<div class="details span4">
|
|
3
|
+
<%= render 'infractions/reported_by', infraction: infraction %>
|
|
4
|
+
<div class="description">
|
|
5
|
+
<div class="tweet" tweetID="<%= infraction.tweet_id %>"></div>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="gallery-container">
|
|
9
|
+
<h4>Imágenes de la infracción:</h4>
|
|
10
|
+
<div class="main-gallery-test">
|
|
11
|
+
<% infraction.evidences.each do |ev| %>
|
|
12
|
+
<div class="gallery-img">
|
|
13
|
+
<a class="fancybox" rel="group-<%= infraction.id %>" href="<%= ev.media.url %>"><%= image_tag ev.media.horizontal.url %></a>
|
|
14
|
+
</div>
|
|
15
|
+
<% end %>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<a href="#infraccion-<%= infraction.id %>" class="show-infraction" id="ver-infraccion-<%= infraction.id %>" title="Ver infracción">Ver infracción</a>
|
|
19
|
+
<div class="infraction-map">
|
|
20
|
+
<h4><a href="#" data-infraction-id="<%= infraction.id %>" title="Ver mapa" class="see-map">Ver mapa</a></h4>
|
|
21
|
+
<%= render 'infractions/map', infraction: infraction %>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<div class="list-container">
|
|
2
|
+
<div class="span12">
|
|
3
|
+
<ul class="span8 infractions">
|
|
4
|
+
<% @infractions.each do |infraction| %>
|
|
5
|
+
<li id="infraccion-<%= infraction.id %>" class="infraction span12 <%= cycle('odd', 'even') %>">
|
|
6
|
+
<%= render 'infractions/summary', infraction: infraction %>
|
|
7
|
+
</li>
|
|
8
|
+
<% end %>
|
|
9
|
+
</ul>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="main-map">
|
|
13
|
+
<div class="map" id="map_canvas_main"></div>
|
|
14
|
+
<script>
|
|
15
|
+
var infractionMarkers = <%= raw @infraction_markers.to_json %>;
|
|
16
|
+
</script>
|
|
17
|
+
</div>
|
|
18
|
+
<!-- /.row -->
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<h2>Infracción #<%= @infraction.tweet_id %></h2>
|
|
2
|
+
|
|
3
|
+
<div class="row detail bordered">
|
|
4
|
+
<div class="span12">
|
|
5
|
+
<div class="row">
|
|
6
|
+
<%= render 'infractions/reported_by', infraction: @infraction %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="row description span7">
|
|
9
|
+
<div class="tweet" tweetID="<%= @infraction.tweet_id %>"></div>
|
|
10
|
+
<div class="row source">
|
|
11
|
+
[Fuente: <%= link_to 'Twitter', @infraction.source_url %>]
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render 'infractions/map', infraction: @infraction %>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="row bordered">
|
|
19
|
+
<span class="span12">
|
|
20
|
+
<% @infraction.evidences.each do |ev| %>
|
|
21
|
+
<%= image_tag ev.media.horizontal.url %>
|
|
22
|
+
<% end %>
|
|
23
|
+
</span>
|
|
24
|
+
</div>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Infractores Escrachados</title>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<meta name="description" content="">
|
|
8
|
+
<meta name="author" content="@InfractoresBA">
|
|
9
|
+
<link href='https://fonts.googleapis.com/css?family=Rubik:400,500,700,300' rel='stylesheet' type='text/css'>
|
|
10
|
+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
|
11
|
+
<%= stylesheet_link_tag 'application', media: 'all' %>
|
|
12
|
+
<%= javascript_include_tag 'application' %>
|
|
13
|
+
<%= csrf_meta_tags %>
|
|
14
|
+
|
|
15
|
+
<script src="https://maps.googleapis.com/maps/api/js"></script>
|
|
16
|
+
|
|
17
|
+
<script>window.twttr = (function(d, s, id) {
|
|
18
|
+
var js, fjs = d.getElementsByTagName(s)[0],
|
|
19
|
+
t = window.twttr || {};
|
|
20
|
+
if (d.getElementById(id)) return t;
|
|
21
|
+
js = d.createElement(s);
|
|
22
|
+
js.id = id;
|
|
23
|
+
js.src = "https://platform.twitter.com/widgets.js";
|
|
24
|
+
fjs.parentNode.insertBefore(js, fjs);
|
|
25
|
+
|
|
26
|
+
t._e = [];
|
|
27
|
+
t.ready = function(f) {
|
|
28
|
+
t._e.push(f);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return t;
|
|
32
|
+
}(document, "script", "twitter-wjs"));
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
</head>
|
|
36
|
+
|
|
37
|
+
<body>
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
<!-- NAVBAR
|
|
41
|
+
================================================== -->
|
|
42
|
+
<div class="navbar-wrapper">
|
|
43
|
+
<!-- Wrap the .navbar in .container to center it within the absolutely positioned parent. -->
|
|
44
|
+
<div>
|
|
45
|
+
|
|
46
|
+
<div class="navbar navbar-inverse">
|
|
47
|
+
<div class="navbar-inner">
|
|
48
|
+
<h1 class="brand"><a href="#">InfractoresBA</a></h1>
|
|
49
|
+
<!-- Responsive Navbar Part 2: Place all navbar contents you want collapsed withing .navbar-collapse.collapse. -->
|
|
50
|
+
<a href="#" id="info">¿Cómo funciona?</a>
|
|
51
|
+
|
|
52
|
+
<div class="nav-collapse collapse">
|
|
53
|
+
<ul class="nav">
|
|
54
|
+
<li class="<%= calculate_class('infractions', '') %>"><%= link_to 'Infracciones', infractions_path %></li>
|
|
55
|
+
<li class="<%= calculate_class('leaderboard') %>"><a href="/leaderboard">Tabla de puntajes</a></li>
|
|
56
|
+
</ul>
|
|
57
|
+
</div><!--/.nav-collapse -->
|
|
58
|
+
</div><!-- /.navbar-inner -->
|
|
59
|
+
</div><!-- /.navbar -->
|
|
60
|
+
<div id="description">
|
|
61
|
+
<p>Para reportar una infracción sólo es necesario mencionar a <strong><%= screen_name %></strong> o agregar el hashtag <strong><%= screen_name_hashtag %></strong> a tu tweet.</p>
|
|
62
|
+
<p>Una denuncia válida debe tener:</p>
|
|
63
|
+
<ul>
|
|
64
|
+
<li>Por lo menos una foto que muestre la infracción</li>
|
|
65
|
+
<li>Geolocalización activada al momento de enviar el tweet</li>
|
|
66
|
+
</ul>
|
|
67
|
+
<a href="#" id="close">Cerrar</a>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
</div> <!-- /.container -->
|
|
72
|
+
</div><!-- /.navbar-wrapper -->
|
|
73
|
+
|
|
74
|
+
<!-- Marketing messaging and featurettes
|
|
75
|
+
================================================== -->
|
|
76
|
+
<!-- Wrap the rest of the page in another container to center all the content. -->
|
|
77
|
+
|
|
78
|
+
<div class="<%= controller_name %> <%= controller_name %>-<%= action_name %>">
|
|
79
|
+
|
|
80
|
+
<%= yield %>
|
|
81
|
+
|
|
82
|
+
</div><!-- /.container -->
|
|
83
|
+
<!-- FOOTER -->
|
|
84
|
+
<footer>
|
|
85
|
+
<p class="pull-right"><a href="#">Back to top</a></p>
|
|
86
|
+
<p>Lovingly crafted by <a href="http://www.ombulabs.com" title="Ombu Labs">Ombu Labs</a> in Buenos Aires, Argentina!</p>
|
|
87
|
+
</footer>
|
|
88
|
+
<%= render 'shared/google_analytics' %>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<% if ENV['GOOGLE_ANALYTICS_ID'] %>
|
|
2
|
+
<script>
|
|
3
|
+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
4
|
+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
5
|
+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
6
|
+
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
7
|
+
|
|
8
|
+
ga('create', '<%= ENV['GOOGLE_ANALYTICS_ID'] %>', 'auto');
|
|
9
|
+
ga('send', 'pageview');
|
|
10
|
+
|
|
11
|
+
</script>
|
|
12
|
+
<% end %>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<h2>Tabla de Puntajes</h2>
|
|
2
|
+
|
|
3
|
+
<!-- Three columns of text below the carousel -->
|
|
4
|
+
<div class="row">
|
|
5
|
+
<div class="span12">
|
|
6
|
+
<table class="table table-condensed table-responsive table-hover">
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<th>Usuario</th>
|
|
10
|
+
<th>Denuncias</th>
|
|
11
|
+
</tr>
|
|
12
|
+
</thead>
|
|
13
|
+
<% @users.each do |user| %>
|
|
14
|
+
<tr>
|
|
15
|
+
<td><%= raw decorated_username(user) %></td>
|
|
16
|
+
<td><%= link_to user.infractions_count, "/#{user.username}" %></td>
|
|
17
|
+
</tr>
|
|
18
|
+
<% end %>
|
|
19
|
+
</table>
|
|
20
|
+
</div>
|
|
21
|
+
</div><!-- /.row -->
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class TweetInspector
|
|
2
|
+
include Sidekiq::Worker
|
|
3
|
+
|
|
4
|
+
# It analyzes a {Tweet} and creates an {Infraction} if necessary
|
|
5
|
+
def perform(id)
|
|
6
|
+
if (tweet = Tweet.find_by(id: id))
|
|
7
|
+
return if tweet.infraction
|
|
8
|
+
|
|
9
|
+
infraction = Infraction.build_from(tweet)
|
|
10
|
+
|
|
11
|
+
if infraction.save
|
|
12
|
+
puts "Great success!"
|
|
13
|
+
else
|
|
14
|
+
Rails.logger.info "Could not save Infraction: #{infraction.errors.messages}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/bin/bundle
ADDED
data/bin/rails
ADDED
data/bin/rake
ADDED
data/bin/setup
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'pathname'
|
|
3
|
+
|
|
4
|
+
# path to your application root.
|
|
5
|
+
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
|
|
6
|
+
|
|
7
|
+
Dir.chdir APP_ROOT do
|
|
8
|
+
# This script is a starting point to setup your application.
|
|
9
|
+
# Add necessary setup steps to this file:
|
|
10
|
+
|
|
11
|
+
puts "== Installing dependencies =="
|
|
12
|
+
system "gem install bundler --conservative"
|
|
13
|
+
system "bundle check || bundle install"
|
|
14
|
+
|
|
15
|
+
# puts "\n== Copying sample files =="
|
|
16
|
+
# unless File.exist?("config/database.yml")
|
|
17
|
+
# system "cp config/database.yml.sample config/database.yml"
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
puts "\n== Preparing database =="
|
|
21
|
+
system "bin/rake db:setup"
|
|
22
|
+
|
|
23
|
+
puts "\n== Removing old logs and tempfiles =="
|
|
24
|
+
system "rm -f log/*"
|
|
25
|
+
system "rm -rf tmp/cache"
|
|
26
|
+
|
|
27
|
+
puts "\n== Restarting application server =="
|
|
28
|
+
system "touch tmp/restart.txt"
|
|
29
|
+
end
|
data/bin/spring
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# This file loads spring without using Bundler, in order to be fast.
|
|
4
|
+
# It gets overwritten when you run the `spring binstub` command.
|
|
5
|
+
|
|
6
|
+
unless defined?(Spring)
|
|
7
|
+
require "rubygems"
|
|
8
|
+
require "bundler"
|
|
9
|
+
|
|
10
|
+
if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m)
|
|
11
|
+
Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq }
|
|
12
|
+
gem "spring", match[1]
|
|
13
|
+
require "spring/binstub"
|
|
14
|
+
end
|
|
15
|
+
end
|
data/config.ru
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rails/all'
|
|
4
|
+
|
|
5
|
+
# Require the gems listed in Gemfile, including any gems
|
|
6
|
+
# you've limited to :test, :development, or :production.
|
|
7
|
+
Bundler.require(*Rails.groups)
|
|
8
|
+
|
|
9
|
+
module Infractores
|
|
10
|
+
class Application < Rails::Application
|
|
11
|
+
# Settings in config/environments/* take precedence over those specified here.
|
|
12
|
+
# Application configuration should go into files in config/initializers
|
|
13
|
+
# -- all .rb files in that directory are automatically loaded.
|
|
14
|
+
|
|
15
|
+
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
|
16
|
+
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
|
17
|
+
config.time_zone = 'America/Argentina/Buenos_Aires'
|
|
18
|
+
|
|
19
|
+
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
|
20
|
+
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
|
21
|
+
config.i18n.default_locale = :es
|
|
22
|
+
config.middleware.insert_after ActionDispatch::Static, Rack::LiveReload if Rails.env.development?
|
|
23
|
+
|
|
24
|
+
# Do not swallow errors in after_commit/after_rollback callbacks.
|
|
25
|
+
config.active_record.raise_in_transactional_callbacks = true
|
|
26
|
+
end
|
|
27
|
+
end
|