departr 0.4 → 0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/README.md +8 -2
- data/bin/departr-images +78 -0
- data/chrome/logo.png +0 -0
- data/chrome/manifest.json +17 -0
- data/chrome/newtab.html +85 -0
- data/chrome/newtab.js +19 -0
- data/departr.gemspec +9 -8
- data/lib/departr/commands.rb +1 -9
- data/lib/departr/config.rb +1 -7
- data/lib/departr/server.rb +48 -42
- data/lib/departr/settings.rb +7 -5
- data/public/javascripts/2_autocomplete.js +6 -2
- data/public/javascripts/{5_appliction.js → 4_appliction.js} +0 -24
- data/public/javascripts/{6_command.js → 5_command.js} +26 -9
- data/public/javascripts/9_run.js +11 -0
- data/screenshot.jpg +0 -0
- data/views/help.haml +9 -6
- data/views/index.haml +3 -54
- data/views/layout.haml +1 -0
- data/views/settings.haml +0 -32
- data/views/style.sass +74 -147
- metadata +58 -51
- data/Gemfile.lock +0 -30
- data/public/javascripts/4_coolclock.js +0 -325
- data/screenshot.png +0 -0
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
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.
|
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
|
data/bin/departr-images
ADDED
@@ -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
|
+
}
|
data/chrome/newtab.html
ADDED
@@ -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.
|
6
|
-
s.date = '
|
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
|
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("
|
19
|
-
s.add_runtime_dependency("
|
20
|
-
s.add_runtime_dependency("
|
21
|
-
s.add_runtime_dependency("
|
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
|
data/lib/departr/commands.rb
CHANGED
@@ -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
|
-
|
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
|
|
data/lib/departr/config.rb
CHANGED
@@ -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' => "
|
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}"},
|
data/lib/departr/server.rb
CHANGED
@@ -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?
|
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
|
-
|
96
|
-
|
97
|
-
|
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
|
-
|
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
|
-
|
187
|
-
|
188
|
-
|
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
|
-
|
194
|
-
|
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
|