servel 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61283059635d7f385d05267c238bc0594697e227
4
- data.tar.gz: d48cdd82439abf2a4f0d9377b0e1c76b438c9a67
3
+ metadata.gz: e91e5efe5fb7ebf0a803c7b8651d84188582b93c
4
+ data.tar.gz: db7b14fbe9096a17722164c6b389fc324268b0c0
5
5
  SHA512:
6
- metadata.gz: '08f68881ff271c9f5a2af6a78d3105f2bcacdd33e616547e6809deb3ccc661c061e6551a95e6c9f31054d10ca5f54be47ac81fd0f89ef01e9814ba4642a129b8'
7
- data.tar.gz: 80bd1ff843f20e00958765c8669b8ce3ff9f46dc96668b98f6eb17faffa9e732e01b1b4fd3b0bfbf5b8585a8d894f78900b1101db28afa541582b15d4ec4c498
6
+ metadata.gz: b56fedb3ecc2caf4f023a58d5bec0d817256d268991d78051c9bdbed8d2f76e8ee40174c4f14c71cc5308a89cddacef9e7fabf4ba273bdabfb6c85ee947275a3
7
+ data.tar.gz: fbb024ed53a80cb97f9d4d407f69dc9b5840709517b50a9454bc37076893363f3b4084c50a43ba15f70a20da403eed495a1f7c10098dff67c753a5ed7558d071
data/.gitignore CHANGED
File without changes
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
File without changes
data/Rakefile CHANGED
File without changes
@@ -2,6 +2,7 @@ require 'rack'
2
2
  require 'rack/handler/puma'
3
3
  require 'haml'
4
4
  require 'naturalsorter'
5
+ require 'active_support/all'
5
6
 
6
7
  require 'json'
7
8
  require 'pathname'
@@ -13,6 +14,5 @@ require "servel/version"
13
14
  require "servel/core_ext/pathname"
14
15
  require "servel/haml_context"
15
16
  require "servel/index_view"
16
- require "servel/gallery_view"
17
17
  require "servel/middleware"
18
18
  require "servel/servel"
@@ -2,4 +2,8 @@ class Pathname
2
2
  def image?
3
3
  file? && extname && %w(.jpg .jpeg .png .gif).include?(extname.downcase)
4
4
  end
5
+
6
+ def video?
7
+ file? && extname && %w(.webm).include?(extname.downcase)
8
+ end
5
9
  end
@@ -1,4 +1,6 @@
1
1
  class Servel::HamlContext
2
+ include ActiveSupport::NumberHelper
3
+
2
4
  ENGINE_OPTIONS = { remove_whitespace: true, escape_html: true, ugly: true }
3
5
 
4
6
  def initialize()
File without changes
@@ -20,13 +20,7 @@ class Servel::Middleware
20
20
 
21
21
  url_path << "/" if url_path != "" && !url_path.end_with?("/")
22
22
 
23
- klass = if env['QUERY_STRING'] == "gallery"
24
- Servel::GalleryView
25
- else
26
- Servel::IndexView
27
- end
28
-
29
- [200, {}, StringIO.new(klass.new(url_path, fs_path).render(@haml_context))]
23
+ [200, {}, StringIO.new(Servel::IndexView.new(url_path, fs_path).render(@haml_context))]
30
24
  end
31
25
 
32
26
  def url_path_for(url_path)
File without changes
@@ -0,0 +1,7 @@
1
+ %img#image.hidden
2
+ %video#video.hidden{autoplay: true, controls: true}
3
+ #page-back.paginator ◀
4
+ #page-next.paginator ▶
5
+ #page-back-10.paginator ◀◀
6
+ #page-next-10.paginator ▶▶
7
+ #page-toggle-size.paginator ❌
@@ -0,0 +1,27 @@
1
+ %h1 Directory Listing of #{url_path}
2
+ %table
3
+ %thead
4
+ %tr
5
+ %th Name
6
+ %th Size
7
+ %th Modified
8
+ %tbody
9
+ - unless url_path == "/"
10
+ %tr
11
+ %td
12
+ (Dir)&nbsp;
13
+ %a{href: "../"} ../
14
+ %td
15
+ %td
16
+ - (directories + files).each do |file|
17
+ - relative_path = file.relative_path_from(fs_path)
18
+ %tr
19
+ %td
20
+ - if file.directory?
21
+ (Dir)&nbsp;
22
+ %a{href: relative_path, class: "#{"viewable" if file.image? || file.video?} #{"image" if file.image?} #{"video" if file.video?}", target: "_blank"}
23
+ - extname = relative_path.extname
24
+ - basename = relative_path.basename(extname)
25
+ #{basename.to_s.truncate(50)}#{extname}
26
+ %td= number_to_human_size(file.size)
27
+ %td= file.mtime.strftime("%e %b %Y %l:%M %p")
@@ -4,6 +4,9 @@
4
4
 
5
5
  body {
6
6
  padding: 0;
7
+ font-family: 'Open Sans', Helvetica, Arial, sans-serif;
8
+ font-size: 16px;
9
+ line-height: 1.4;
7
10
 
8
11
  -webkit-user-select: none;
9
12
  -moz-user-select: none;
@@ -1,19 +1,21 @@
1
- html, body {
2
- height: 100%;
1
+ #gallery {
2
+ padding: 20px;
3
+ background: #333;
4
+ transform: translateZ(0px);
3
5
  }
4
6
 
5
- body {
6
- background-color: #333333;
7
+ .hidden {
8
+ display: none !important;
7
9
  }
8
10
 
9
- #image {
11
+ #image, #video {
10
12
  display: block;
11
13
  max-width: 100%;
12
14
  margin: 0 auto 0 auto;
13
15
  }
14
16
 
15
17
  @media (min-width: 992px) {
16
- #image {
18
+ #image, #video {
17
19
  max-height: 100%;
18
20
  }
19
21
  }
@@ -83,4 +85,11 @@ body {
83
85
  right: 0;
84
86
  height: 100px;
85
87
  z-index: 10001;
88
+ }
89
+
90
+ #page-toggle-size {
91
+ top: 0;
92
+ left: 0;
93
+ height: 100px;
94
+ z-index: 10001;
86
95
  }
@@ -1,9 +1,21 @@
1
+ var pages = null;
1
2
  var currentPage = 1;
2
3
 
4
+ function loadPages() {
5
+ pages = [];
6
+
7
+ var links = document.querySelectorAll("#listing a.viewable");
8
+ for(var i = 0; i < links.length; i++) {
9
+ var link = links[i];
10
+ var type = link.classList.contains("image") ? "image" : "video";
11
+ pages.push({ url: link.href, type: type });
12
+ }
13
+ }
14
+
3
15
  function page(index) {
4
16
  if(arguments.length == 1) {
5
17
  if(isNaN(index) || index < 1) index = 1;
6
- if(index > imagePaths.length) index = imagePaths.length;
18
+ if(index > pages.length) index = pages.length;
7
19
 
8
20
  currentPage = index;
9
21
  showCurrentPage();
@@ -36,6 +48,10 @@ function initPaginator() {
36
48
  e.stopPropagation();
37
49
  page(page() + 10);
38
50
  });
51
+ document.querySelector("#page-toggle-size").addEventListener("click", function(e) {
52
+ e.stopPropagation();
53
+ document.body.classList.toggle("split-screen");
54
+ });
39
55
 
40
56
  window.addEventListener("keydown", function(event) {
41
57
  if(event.keyCode == 39 || ((event.keyCode == 32 || event.keyCode == 13) && atBottom())) {
@@ -51,13 +67,46 @@ function initPaginator() {
51
67
 
52
68
  function showCurrentPage() {
53
69
  window.scrollTo(0, 0);
54
- document.querySelector("#image").src = imagePaths[currentPage - 1];
55
- if(currentPage < imagePaths.length) (new Image()).src = imagePaths[currentPage];
70
+ var page = pages[currentPage - 1];
71
+ if(!page) return;
72
+
73
+ if(page.type == "image") {
74
+ document.querySelector("#gallery #video").classList.add("hidden");
75
+ document.querySelector("#gallery #image").classList.remove("hidden");
76
+ document.querySelector("#gallery #image").src = page.url;
77
+ }
78
+ else {
79
+ document.querySelector("#gallery #image").classList.add("hidden");
80
+ document.querySelector("#gallery #video").classList.remove("hidden");
81
+ document.querySelector("#gallery #video").src = page.url;
82
+ }
83
+
84
+ //if(currentPage < imageUrls.length) (new Image()).src = imageUrls[currentPage];
56
85
  }
57
86
 
58
- function init() {
87
+ function openLink(event) {
88
+ event.preventDefault();
89
+
90
+ for(var i = 0; i < pages.length; i++) {
91
+ if(pages[i].url == this.href) {
92
+ page(i + 1);
93
+ return;
94
+ }
95
+ }
96
+ }
97
+
98
+ function initGallery() {
99
+ if(!document.querySelector("#gallery")) return;
100
+
59
101
  initPaginator();
60
- showCurrentPage();
102
+ loadPages();
103
+
104
+ document.body.addEventListener("click", function(e) {
105
+ console.log("clicked, e: ", e);
106
+ if(e.target && e.target.matches("a.viewable")) openLink.call(e.target, e);
107
+ });
108
+
109
+ page(1);
61
110
  }
62
111
 
63
- window.addEventListener("DOMContentLoaded", init);
112
+ window.addEventListener("DOMContentLoaded", initGallery);
@@ -1,3 +1,36 @@
1
- #container {
2
- padding: 20px;
3
- }
1
+ html, body, #gallery {
2
+ height: 100%;
3
+ }
4
+
5
+ body.split-screen #listing {
6
+ height: 100%;
7
+ width: 50%;
8
+ float: left;
9
+ overflow: auto;
10
+ }
11
+
12
+ body.split-screen #gallery {
13
+ width: 50%;
14
+ float: right;
15
+ }
16
+ /*
17
+ @media screen and (min-width: 1800px) {
18
+ #listing {
19
+ float: left;
20
+ width: 800px;
21
+ height: 100%;
22
+ overflow: auto;
23
+ }
24
+
25
+ #gallery {
26
+ margin-left: 800px;
27
+ }
28
+
29
+ body.gallery-expanded #listing {
30
+ display: none;
31
+ }
32
+
33
+ body.gallery-expanded #gallery {
34
+ margin-left: 0;
35
+ }
36
+ }*/
@@ -7,20 +7,12 @@
7
7
  #{include('normalize.css')}
8
8
  #{include('common.css')}
9
9
  #{include('index.css')}
10
+ #{include('listing.css')}
11
+ #{include('gallery.css')}
12
+
13
+ :javascript
14
+ #{include('gallery.js')}
10
15
  %body
11
- #container
12
- %h1 Directory Listing of #{url_path}
13
- %ul
14
- - if show_gallery
15
- %li
16
- %a{href: "#{url_path}?gallery"} Gallery
17
- - unless url_path == "/"
18
- %li
19
- %a{href: "../"} ../
20
- - (directories + files).each do |file|
21
- - relative_path = file.relative_path_from(fs_path).to_s
22
- %li
23
- - if file.directory?
24
- (Dir)&nbsp;
25
- %a{href: relative_path}
26
- = relative_path
16
+ - if show_gallery
17
+ #gallery!= partial('gallery')
18
+ #listing!= partial('listing', { url_path: url_path, fs_path: fs_path, directories: directories, files: files })
@@ -0,0 +1,22 @@
1
+ #listing {
2
+ padding: 20px;
3
+ }
4
+
5
+ #listing h1 {
6
+ margin-top: 0;
7
+ }
8
+
9
+ table {
10
+ width: 100%;
11
+ border-collapse: collapse;
12
+ border: 1px solid #ddd;
13
+ }
14
+
15
+ th, td {
16
+ padding: 5px;
17
+ border: 1px solid #ddd;
18
+ }
19
+
20
+ tbody > tr:nth-of-type(odd) {
21
+ background-color: #f9f9f9;
22
+ }
File without changes
@@ -1,3 +1,3 @@
1
1
  module Servel
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "puma"
28
28
  spec.add_dependency "naturalsorter"
29
29
  spec.add_dependency "haml", "~> 4"
30
+ spec.add_dependency "activesupport"
30
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: servel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brenton "B-Train" Fletcher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-21 00:00:00.000000000 Z
11
+ date: 2017-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: Serves files and directories over HTTP.
98
112
  email:
99
113
  - i@bloople.net
@@ -112,17 +126,18 @@ files:
112
126
  - bin/setup
113
127
  - lib/servel.rb
114
128
  - lib/servel/core_ext/pathname.rb
115
- - lib/servel/gallery_view.rb
116
129
  - lib/servel/haml_context.rb
117
130
  - lib/servel/index_view.rb
118
131
  - lib/servel/middleware.rb
119
132
  - lib/servel/servel.rb
133
+ - lib/servel/templates/_gallery.haml
134
+ - lib/servel/templates/_listing.haml
120
135
  - lib/servel/templates/common.css
121
136
  - lib/servel/templates/gallery.css
122
- - lib/servel/templates/gallery.haml
123
137
  - lib/servel/templates/gallery.js
124
138
  - lib/servel/templates/index.css
125
139
  - lib/servel/templates/index.haml
140
+ - lib/servel/templates/listing.css
126
141
  - lib/servel/templates/normalize.css
127
142
  - lib/servel/version.rb
128
143
  - servel.gemspec
@@ -1,24 +0,0 @@
1
- class Servel::GalleryView
2
- def initialize(url_path, fs_path)
3
- @url_path = url_path
4
- @fs_path = fs_path
5
- end
6
-
7
- def render(haml_context)
8
- haml_context.render('gallery.haml', locals)
9
- end
10
-
11
- def locals
12
- image_paths = @fs_path.children.select { |child| child.image? }
13
-
14
- {
15
- url_path: @url_path,
16
- fs_path: @fs_path,
17
- image_paths: sort_paths(image_paths)
18
- }
19
- end
20
-
21
- def sort_paths(paths)
22
- Naturalsorter::Sorter.sort(paths.map(&:to_s), true).map { |path| Pathname.new(path) }
23
- end
24
- end
@@ -1,21 +0,0 @@
1
- !!!
2
- %html
3
- %head
4
- %meta{charset: 'utf-8'}
5
- %title Gallery for #{url_path}
6
- :css
7
- #{include('normalize.css')}
8
- #{include('common.css')}
9
- #{include('gallery.css')}
10
-
11
- :javascript
12
- var imagePaths = #{image_paths.map { |file| file.relative_path_from(fs_path).to_s }.to_json};
13
- #{include('gallery.js')}
14
-
15
- %body
16
- #container
17
- %img#image
18
- #page-back.paginator ◀
19
- #page-next.paginator ▶
20
- #page-back-10.paginator ◀◀
21
- #page-next-10.paginator ▶▶