departr 0.4 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40696450d3edaf3459d98c4b571d36420337fc50
4
+ data.tar.gz: ea3887c825338d06d7213b2ff8aefdcbaec8d5d7
5
+ SHA512:
6
+ metadata.gz: 63a264efb01f7aa9e446433f47a04385a4f434dc6d94e04228bc655970d3cd68adfdd2d1fa8ead0fbc454924a9c3e4bb0c45af852d18d355e0483854803bb30d
7
+ data.tar.gz: e8b0bb98b8aceaaff2e52747391d37d6560249f8cb32c46bf4fec59d03478748649e3cfb1a37a2ba78edb899d93479bad258a2fe3e3bc825476eb09c4f2fb147
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ config.ru
2
+ Gemfile.lock
3
+ .bundle
4
+ public/images
5
+ lib/images.msh
6
+ log
7
+ .DS_Store
data/README.md CHANGED
@@ -7,12 +7,18 @@ Departr is a smart and fast startpage to help you reach other web sites.
7
7
  It's up and running here http://departr.solt.biz/
8
8
 
9
9
  Anyway, it's look like that :
10
- ![Screenshot](https://github.com/florentsolt/departr/raw/master/screenshot.png)
10
+ ![Screenshot](https://github.com/florentsolt/departr/raw/master/screenshot.jpg)
11
11
 
12
12
  # How to install
13
13
 
14
14
  gem install departr
15
15
 
16
+ Then, run the departr-images to fetch backgrounds (you can run this task every day):
17
+
18
+ departr-images 500PX_CONSUMER_KEY 500PX_CONSUMER_SECRET 500PX_USERNAME 500PX_PASSWORD
19
+
20
+ You need to go there to regirster an application http://500px.com/settings/applications.
21
+
16
22
  All you need now it to open your favorite code editor and create a file `config.ru` that looks like https://github.com/florentsolt/departr/blob/master/config.ru.example
17
23
  Do not forget to create a RPX account on http://www.janrain.com/ and fill the config under the `rpx` section with your account infos.
18
24
 
@@ -22,4 +28,4 @@ Then run it :
22
28
 
23
29
  Or :
24
30
 
25
- rackup
31
+ rackup
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ require 'oauth'
3
+ require 'json'
4
+
5
+ if ARGV.size != 4
6
+ puts "Usage: #{$0} CONSUMER_KEY CONSUMER_SECRET USERNAME PASSWORD"
7
+ exit
8
+ end
9
+
10
+ CONSUMER_KEY = ARGV.shift
11
+ CONSUMER_SECRET = ARGV.shift
12
+ BASE_URL = 'https://api.500px.com'
13
+ USERNAME = ARGV.shift
14
+ PASSWORD = ARGV.shift
15
+
16
+
17
+ consumer = OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, {
18
+ :site => BASE_URL,
19
+ :request_token_path => "/v1/oauth/request_token",
20
+ :access_token_path => "/v1/oauth/access_token",
21
+ :authorize_path => "/v1/oauth/authorize"})
22
+
23
+ request_token = consumer.get_request_token()
24
+ access_token = consumer.get_access_token(request_token, {}, {
25
+ :x_auth_mode => 'client_auth',
26
+ :x_auth_username => USERNAME,
27
+ :x_auth_password => PASSWORD})
28
+
29
+ photos = []
30
+ 1.upto(4) do |page|
31
+ data = JSON.parse(access_token.get("/v1/photos?rpp=100&feature=editors&image_size=2048&only=Landscapes&page=#{page}").body)
32
+ photos += data['photos']
33
+ end
34
+
35
+ dir = File.join(__dir__, '..', 'public', 'images')
36
+ Dir.mkdir(dir) if not File.exists? dir
37
+
38
+ photos.delete_if do |photo|
39
+ photo['width'].to_i < 1200
40
+ end
41
+
42
+ photos.each do |photo|
43
+ file = File.join(dir, "#{photo['id']}.jpg")
44
+ if not File.exists? file
45
+ puts "Download #{file}"
46
+ system("curl -s '#{photo['image_url']}' -o #{file}")
47
+ system("jpegtran -optimize -copy none -progressive -outfile #{file} #{file}")
48
+ end
49
+ end
50
+
51
+ photos.delete_if do |photo|
52
+ file = File.join(dir, "#{photo['id']}.jpg")
53
+ md5 = `md5sum #{file}`.strip.split(' ').first
54
+ if md5 == '92ec602c88283582b9e322ba7dffccde'
55
+ # If the file is "Your image is loading..."
56
+ puts "Skipping #{file}"
57
+ File.unlink file
58
+ true
59
+ else
60
+ false
61
+ end
62
+ end
63
+
64
+ File.open(File.join(__dir__, '..', 'lib', 'images.msh'), 'w') do |fd|
65
+ fd.puts Marshal.dump(photos)
66
+ end
67
+
68
+ ids = photos.map do |photo|
69
+ photo['id'].to_i
70
+ end
71
+
72
+ Dir[File.join(dir, "*.jpg")].each do |file|
73
+ id = File.basename(file, '.jpg').to_i
74
+ if not ids.include? id
75
+ puts "Remove #{file}"
76
+ File.unlink(file)
77
+ end
78
+ end
data/chrome/logo.png ADDED
Binary file
@@ -0,0 +1,17 @@
1
+ {
2
+ "manifest_version": 2,
3
+
4
+ "name": "Departr",
5
+ "description": "Departr is a smart and fast startpage to help you reach other web sites..",
6
+ "version": "1.3",
7
+
8
+ "permissions": [ "cookies", "tabs", "http://departr.solt.biz/*" ],
9
+
10
+ "chrome_url_overrides": {
11
+ "newtab": "newtab.html"
12
+ },
13
+
14
+ "icons": {
15
+ "128": "logo.png"
16
+ }
17
+ }
@@ -0,0 +1,85 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2
+ <html>
3
+ <head>
4
+ <title>Departr</title>
5
+ <link href='/favicon.ico' rel='icon' type='image/png' />
6
+ <meta content='text/html; charset=utf-8' http-equiv='content-type' />
7
+ <script src='/newtab.js' type='text/javascript'></script>
8
+ <style>
9
+ * {
10
+ font-family: "trebuchet MS", verdana, sans-serif;
11
+ }
12
+
13
+ body {
14
+ padding: 0px;
15
+ margin: 0px;
16
+ height: 100%;
17
+ overflow: hidden;
18
+ background-color: rgba(238, 238, 238, 0.8);
19
+ }
20
+
21
+ html {
22
+ height: 100%;
23
+ overflow: hidden;
24
+ }
25
+
26
+ a, a:hover, a:link, a:visited {
27
+ color: inherit;
28
+ }
29
+
30
+ #background {
31
+ width: 100%;
32
+ height: 100%;
33
+ position: absolute;
34
+ top: 0px;
35
+ left: 0px;
36
+ color: transparent;
37
+ background-size: cover;
38
+ background-position: 50% 50%;
39
+ background-repeat: none;
40
+ background-image: url(http://departr.solt.biz/background.jpg);
41
+ z-index: -1;
42
+ }
43
+
44
+ #background:after {
45
+ width: 100%;
46
+ position: absolute;
47
+ font-size: 14px;
48
+ top: 0px;
49
+ bottom: 2em;
50
+ left: 0px;
51
+ content: "";
52
+ background-image: url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhJREFUeNpiYGBgePz//38GRhABAgABBgBFTAbfCBNE2AAAAABJRU5ErkJggg==");
53
+ }
54
+
55
+ #credits {
56
+ background-color: rgba(255, 255, 255, 0.4);
57
+ color: black;
58
+ opacity: 0.8;
59
+ filter: alpha(opacity=80);
60
+ font-size: 14px;
61
+ height: 2em;
62
+ line-height: 2em;
63
+ position: absolute;
64
+ left: 0px;
65
+ bottom: 0px;
66
+ z-index: 0;
67
+ width: 100%;
68
+ text-align: right;
69
+ }
70
+
71
+ #credits a {
72
+ text-decoration: none;
73
+ padding-right: 1em;
74
+ }
75
+
76
+ </style>
77
+ </head>
78
+ <body>
79
+ <div id='background'></div>
80
+ <div id='credits'>
81
+ <a id='credits_link' href=""></a>
82
+ </div>
83
+ </body>
84
+ </html>
85
+
data/chrome/newtab.js ADDED
@@ -0,0 +1,19 @@
1
+ window.onload = function() {
2
+
3
+ chrome.cookies.get({ url: 'http://departr.solt.biz', name: 'bg_id'},
4
+ function (cookie) {
5
+ if (cookie) {
6
+ var a = document.getElementById('credits_link')
7
+ a.href = "http://500px.com/photo/" + cookie.value;
8
+ }
9
+ });
10
+
11
+ chrome.cookies.get({ url: 'http://departr.solt.biz', name: 'bg_user'},
12
+ function (cookie) {
13
+ if (cookie) {
14
+ var a = document.getElementById('credits_link')
15
+ a.innerText = decodeURIComponent(cookie.value).replace(/\+/g," ");
16
+ }
17
+ });
18
+
19
+ }
data/departr.gemspec CHANGED
@@ -2,22 +2,23 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "departr"
5
- s.version = 0.4
6
- s.date = '2012-02-15'
5
+ s.version = "0.6"
6
+ s.date = '2014-02-20'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.author = "Florent Solt"
9
9
  s.email = "florent@solt.biz"
10
10
  s.homepage = "https://github.com/florentsolt/departr"
11
- s.summary = "Departr is a smart and fast startpage to help you reach other web sites."
11
+ s.summary = "Departr!"
12
+ s.description = "Departr is a smart and fast startpage to help you reach other web sites."
13
+ s.license = "MIT"
12
14
 
13
15
  s.files = `git ls-files`.split("\n")
14
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
18
  s.require_paths = ["lib"]
17
19
 
18
- s.add_runtime_dependency("json", ["~> 1.6"])
19
- s.add_runtime_dependency("tzinfo", ["~> 0.3"])
20
- s.add_runtime_dependency("haml", ["~> 3.1"])
21
- s.add_runtime_dependency("sass", ["~> 3.1"])
22
- s.add_runtime_dependency("sinatra", ["~> 1.3"])
20
+ s.add_runtime_dependency("haml", ["~> 4.0"])
21
+ s.add_runtime_dependency("sass", ["~> 3.2"])
22
+ s.add_runtime_dependency("sinatra", ["~> 1.4"])
23
+ s.add_runtime_dependency("oauth", ["~> 0.4"])
23
24
  end
@@ -14,15 +14,7 @@ module Departr
14
14
  if File.exists? filename(provider, user)
15
15
  File.mtime(filename(provider, user))
16
16
  else
17
- nil
18
- end
19
- end
20
-
21
- def etag(provider, user)
22
- begin
23
- Digest::MD5.hexdigest(time(provider, user).to_s)
24
- rescue
25
- '-no-command-file-'
17
+ Time.at(0)
26
18
  end
27
19
  end
28
20
 
@@ -10,19 +10,13 @@ module Departr
10
10
  :open_in_new_page => false,
11
11
  :default_search => "http://www.google.com/search?ie=UTF-8&oe=UTF-8&q=",
12
12
 
13
- :github => true,
14
- :calendar => true,
15
- :clock1 => "Europe/Paris",
16
- :clock2 => "America/New_York",
17
- :clock3 => "America/Los_Angeles",
18
-
19
13
  # Default commands
20
14
 
21
15
  :commands => [
22
16
  {'name' => "google search for {words}", 'url' => "http://www.google.com/search?rls=en&q={words}&ie=UTF-8&oe=UTF-8"},
23
17
  {'name' => "google search for {words} in {lang}", 'url' => "http://www.google.com/search?rls={lang}&q={words}&ie=UTF-8&oe=UTF-8"},
24
18
  {'name' => "wikipedia search for {words}", 'url' => "http://en.wikipedia.org/wiki/{words}"},
25
- {'name' => "twitter search for {words}", 'url' => "http://search.twitter.com/search?q={words}"},
19
+ {'name' => "twitter search for {words}", 'url' => "https://twitter.com/search?q={words}&src=typd"},
26
20
  {'name' => "youtube search for {words}", 'url' => "http://www.youtube.com/results?search_query={words}"},
27
21
  {'name' => "dailymotion search for {words}", 'url' => "http://www.dailymotion.com/relevance/search/{words}"},
28
22
  {'name' => "facebook search for {words}", 'url' => "http://www.facebook.com/search/?q={words}"},
@@ -11,23 +11,7 @@ module Departr
11
11
  super
12
12
  Departr::Config.instance_eval(&blk) if block_given?
13
13
  @config = Config
14
-
15
- # when called in the constructor, it remains persistant
16
- # if not, it's rebuild every time
17
- javascripts! if production?
18
- end
19
-
20
- def javascripts!
21
- return @javascripts if not @javascripts.nil?
22
- @javascripts = ''
23
- Dir[File.join(settings.root, 'public', 'javascripts', '*.js')].sort.delete_if do |file|
24
- not File.basename(file).match(/^\d+_/)
25
- end.each do |file|
26
- @javascripts << "\n/* #{File.basename(file)} */\n"
27
- @javascripts << File.read(file)
28
- end
29
- @javascripts_checksum = Digest::SHA1.hexdigest(@javascripts)
30
- @javascripts = JSMin.minify(@javascripts) if production?
14
+ @images = Marshal.load(File.read(File.join(__dir__, '..', 'images.msh')))
31
15
  end
32
16
 
33
17
  #-----------------------------------------------------------------------------
@@ -38,12 +22,12 @@ module Departr
38
22
 
39
23
  set :sass, {
40
24
  :cache_store => Sass::CacheStores::Memory.new,
41
- :style => production? ? :compressed : :expanded
25
+ :style => Server.production? && :compressed || :expanded
42
26
  }
43
27
 
44
28
  set :haml, {
45
29
  :format => :xhtml,
46
- :ugly => production?
30
+ :ugly => Server.production?
47
31
  }
48
32
 
49
33
  set :reload_templates, true if development?
@@ -74,16 +58,6 @@ module Departr
74
58
  end
75
59
  check
76
60
  end
77
-
78
- def clock_label(tz)
79
- return ''.to_json if not tz
80
- tz.split('/').last.gsub('_', ' ').to_json
81
- end
82
-
83
- def clock_offset(tz)
84
- return 0 if not tz
85
- TZInfo::Timezone.get(tz).current_period.utc_total_offset / 3600
86
- end
87
61
  end
88
62
 
89
63
  #-----------------------------------------------------------------------------
@@ -92,16 +66,29 @@ module Departr
92
66
 
93
67
  get '/javascripts/all.js' do
94
68
  content_type :js
95
- javascripts!
96
- etag "js-#{@javascripts_checksum}" if production?
97
- @javascripts
69
+
70
+ if not defined? @@javascripts or not Server.production?
71
+ @@javascripts = ''
72
+ @@javascripts_time = Time.at(0)
73
+ Dir[File.join(settings.root, 'public', 'javascripts', '*.js')].sort.delete_if do |file|
74
+ not File.basename(file).match(/^\d+_/)
75
+ end.each do |file|
76
+ @@javascripts << "\n/* #{File.basename(file)} */\n"
77
+ @@javascripts << File.read(file)
78
+ @@javascripts_time = File.mtime(file) if File.mtime(file) > @@javascripts_time
79
+ end
80
+ @@javascripts = JSMin.minify(@@javascripts) if Server.production?
81
+ end
82
+
83
+ last_modified @@javascripts_time
84
+ @@javascripts
98
85
  end
99
86
 
100
87
  get '/stylesheets/all.css' do
101
88
  content_type :css
102
- if production?
89
+ if Server.production?
103
90
  time = File.mtime(File.join(settings.root, 'views', 'style.sass'))
104
- etag "css-#{time.to_i}"
91
+ last_modified time
105
92
  end
106
93
  sass :style
107
94
  end
@@ -169,7 +156,7 @@ module Departr
169
156
  get '/command/all' do
170
157
  auth!
171
158
  content_type :json
172
- etag "command-" + Command.etag(@provider, @user) if production?
159
+ etag "command-" + Command.etag(@provider, @user) if Server.production?
173
160
  Command.get(@provider, @user).to_json
174
161
  end
175
162
 
@@ -181,18 +168,37 @@ module Departr
181
168
  haml :help
182
169
  end
183
170
 
184
- get '/' do
171
+ get '/background.jpg' do
172
+ background = @images.sample
173
+ response.set_cookie("bg_user", :value => background['user']['fullname'], :path => '/', :expires => Time.now + 60*60*24*365)
174
+ response.set_cookie("bg_id", :value => background['id'], :path => '/', :expires => Time.now + 60*60*24*365)
175
+ headers 'Cache-Control' => "no-cache, no-store, must-revalidate",
176
+ 'Pragma' => 'no-cache',
177
+ 'Expires' => '0'
178
+ redirect "/images/#{background['id']}.jpg"
179
+ end
180
+
181
+ get '/javascripts/context.js' do
182
+ content_type :js
185
183
  if auth?
186
- etag "index-#{Command.etag(@provider, @user)}-#{Settings.etag(@provider, @user)}" if production?
187
- @commands = Command.get(@provider, @user)
188
- @settings = Settings.get(@provider, @user)
184
+ last_modified [Command.time(@provider, @user), Settings.time(@provider, @user)].max if Server.production?
185
+ commands = Command.get(@provider, @user)
186
+ settings = Settings.get(@provider, @user)
189
187
  else
190
- etag "default-#{Digest::SHA1.hexdigest(Command.default.inspect)}" if production?
191
188
  response.delete_cookie("user")
192
189
  response.delete_cookie("session")
193
- @commands = Command.default
194
- @settings = Settings.default
190
+ commands = Command.default
191
+ settings = Settings.default
195
192
  end
193
+ "Command.data = #{commands.to_json};\n" +
194
+ "Settings = #{settings.to_json};"
195
+ end
196
+
197
+ get '/' do
198
+ dir = File.join(__dir__, '..', '..', 'views')
199
+ index = File.mtime(File.join(dir, 'index.haml')).to_i
200
+ layout = File.mtime(File.join(dir, 'layout.haml')).to_i
201
+ etag "#{layout}-#{index}" if Server.production?
196
202
  haml :index
197
203
  end
198
204
  end