├── .gitignore
├── Gemfile
├── Gemfile.lock
├── README.md
├── app.rb
└── config.ru
/.gitignore:
--------------------------------------------------------------------------------
1 | db/*
2 | tmp/*
3 | *.log
4 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 | gem 'sinatra'
3 | gem 'dragonfly'
4 | gem 'rmagick', :require => 'RMagick'
5 | gem 'data_mapper'
6 |
7 | group :production do
8 | gem 'pg'
9 | gem 'dm-postgres-adapter'
10 | end
11 |
12 | group :development, :test do
13 | gem 'sqlite3'
14 | gem 'dm-sqlite-adapter'
15 | end
16 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | addressable (2.3.5)
5 | bcrypt-ruby (3.1.2)
6 | data_mapper (1.2.0)
7 | dm-aggregates (~> 1.2.0)
8 | dm-constraints (~> 1.2.0)
9 | dm-core (~> 1.2.0)
10 | dm-migrations (~> 1.2.0)
11 | dm-serializer (~> 1.2.0)
12 | dm-timestamps (~> 1.2.0)
13 | dm-transactions (~> 1.2.0)
14 | dm-types (~> 1.2.0)
15 | dm-validations (~> 1.2.0)
16 | data_objects (0.10.13)
17 | addressable (~> 2.1)
18 | dm-aggregates (1.2.0)
19 | dm-core (~> 1.2.0)
20 | dm-constraints (1.2.0)
21 | dm-core (~> 1.2.0)
22 | dm-core (1.2.1)
23 | addressable (~> 2.3)
24 | dm-do-adapter (1.2.0)
25 | data_objects (~> 0.10.6)
26 | dm-core (~> 1.2.0)
27 | dm-migrations (1.2.0)
28 | dm-core (~> 1.2.0)
29 | dm-postgres-adapter (1.2.0)
30 | dm-do-adapter (~> 1.2.0)
31 | do_postgres (~> 0.10.6)
32 | dm-serializer (1.2.2)
33 | dm-core (~> 1.2.0)
34 | fastercsv (~> 1.5)
35 | json (~> 1.6)
36 | json_pure (~> 1.6)
37 | multi_json (~> 1.0)
38 | dm-sqlite-adapter (1.2.0)
39 | dm-do-adapter (~> 1.2.0)
40 | do_sqlite3 (~> 0.10.6)
41 | dm-timestamps (1.2.0)
42 | dm-core (~> 1.2.0)
43 | dm-transactions (1.2.0)
44 | dm-core (~> 1.2.0)
45 | dm-types (1.2.2)
46 | bcrypt-ruby (~> 3.0)
47 | dm-core (~> 1.2.0)
48 | fastercsv (~> 1.5)
49 | json (~> 1.6)
50 | multi_json (~> 1.0)
51 | stringex (~> 1.4)
52 | uuidtools (~> 2.1)
53 | dm-validations (1.2.0)
54 | dm-core (~> 1.2.0)
55 | do_postgres (0.10.13)
56 | data_objects (= 0.10.13)
57 | do_sqlite3 (0.10.13)
58 | data_objects (= 0.10.13)
59 | dragonfly (1.0.1)
60 | multi_json (~> 1.0)
61 | rack
62 | fastercsv (1.5.5)
63 | json (1.8.1)
64 | json_pure (1.8.1)
65 | multi_json (1.8.2)
66 | pg (0.17.1)
67 | rack (1.5.2)
68 | rack-protection (1.5.1)
69 | rack
70 | rmagick (2.13.2)
71 | sinatra (1.4.4)
72 | rack (~> 1.4)
73 | rack-protection (~> 1.4)
74 | tilt (~> 1.3, >= 1.3.4)
75 | sqlite3 (1.3.8)
76 | stringex (1.5.1)
77 | tilt (1.4.1)
78 | uuidtools (2.1.4)
79 |
80 | PLATFORMS
81 | ruby
82 |
83 | DEPENDENCIES
84 | data_mapper
85 | dm-postgres-adapter
86 | dm-sqlite-adapter
87 | dragonfly
88 | pg
89 | rmagick
90 | sinatra
91 | sqlite3
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Image Cache Logger
2 |
3 | A simple tool to see when other services/clients like Gmail open an image and test if they are storing it within their cache.
4 |
5 | ## Running Demo
6 |
7 | Feel free to use this as a demo or in actual testing.
8 |
9 | Image link (replace slug with anything):
10 | http://cache-logger.herokuapp.com/change-me-to-anything
11 |
12 | To check the logs without opening the image, append a /log to the end:
13 | http://cache-logger.herokuapp.com/change-me-to-anything/log
14 |
15 | You can also do */destroy* to delete all logs from an image and */remove* to delete the last log, but will have to make those calls using curl:
16 |
17 | curl -X DELETE http://cache-logger.herokuapp.com/change-me-to-anything/destroy
18 | curl -X DELETE http://cache-logger.herokuapp.com/change-me-to-anything/remove
19 |
20 | ## Setup your own instance
21 |
22 | Assuming you have git, ruby, bundler, and heroku setup... you can simply do:
23 |
24 | git clone https://github.com/kale/image-cache-logger
25 | cd image-cache-logger
26 | bundle install
27 | heroku create
28 | git push heroku master
29 |
30 | ## License
31 |
32 | Copyright (c) 2013 Kale Davis
33 |
34 | Permission is hereby granted, free of charge, to any person obtaining
35 | a copy of this software and associated documentation files (the
36 | "Software"), to deal in the Software without restriction, including
37 | without limitation the rights to use, copy, modify, merge, publish,
38 | distribute, sublicense, and/or sell copies of the Software, and to
39 | permit persons to whom the Software is furnished to do so, subject to
40 | the following conditions:
41 |
42 | The above copyright notice and this permission notice shall be
43 | included in all copies or substantial portions of the Software.
44 |
45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 |
--------------------------------------------------------------------------------
/app.rb:
--------------------------------------------------------------------------------
1 | require 'sinatra'
2 | require 'dragonfly'
3 | require 'RMagick'
4 | require 'data_mapper'
5 |
6 | DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/db/app.db")
7 | app = Dragonfly.app
8 |
9 | Dragonfly.app.configure do
10 | plugin :imagemagick
11 | end
12 |
13 | class ImageLogger
14 | include DataMapper::Resource
15 | property :id, Serial
16 | property :slug, String
17 | property :data, Text
18 | property :created_at, DateTime
19 | end
20 |
21 | DataMapper.auto_upgrade!
22 |
23 | get '/' do
24 | "Create an image by just a string after the url."
25 | end
26 |
27 | get "/:slug" do |slug|
28 | background_colors = %w(#EEEEEE #F2F2F2 #F5B7AB #EE836E #FFE8AA #FEDE88 #C5E5DE #95D1C4 #B1E0EC #6DC5DC)
29 |
30 | ImageLogger.create(:slug => slug, :data => "#{Time.now.to_s}\n#{request.user_agent}\n#{request.ip}\n", :created_at => Time.now)
31 | logs = ImageLogger.all(:slug => slug)
32 | data = []
33 | logs.each {|l| data << l['data']}
34 | Dragonfly.app.generate(
35 | :text,
36 | "#{slug}\n\n#{data.join("\n")}",
37 | "font-size" => 14,
38 | "padding" => '10',
39 | "background-color" => background_colors[rand(background_colors.count)]
40 | ).to_response(env)
41 | end
42 |
43 | get "/:slug/log" do |slug|
44 | logs = ImageLogger.all(:slug => slug)
45 | data = []
46 | logs.each {|l| data << l['data'].gsub("\n", "
")}
47 | "#{data.join("
")}"
48 | end
49 |
50 | #remove all logs
51 | delete "/:slug/destroy" do |slug|
52 | logs = ImageLogger.all(:slug => slug)
53 | logs.destroy
54 | redirect "/#{slug}/log"
55 | end
56 |
57 | #remove the last log
58 | delete "/:slug/remove" do |slug|
59 | log = ImageLogger.last(:slug => slug)
60 | log.destroy
61 | redirect "/#{slug}/log"
62 | end
63 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | require './app'
2 | run Sinatra::Application
3 |
--------------------------------------------------------------------------------