rawfeed 0.2.3 → 0.2.5
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 +4 -4
- data/_data/options.yml +12 -0
- data/_includes/layout/data.liquid +2 -0
- data/_includes/layout/head.html +7 -0
- data/_includes/layout/header.html +4 -0
- data/_layouts/default.html +8 -6
- data/_layouts/pub.html +51 -0
- data/_sass/layouts/_index.scss +1 -0
- data/_sass/layouts/_pub.scss +18 -0
- data/assets/images/avatar_back.png +0 -0
- data/assets/images/avatar_dark.png +0 -0
- data/assets/images/avatar_light.png +0 -0
- data/assets/images/favicon.png +0 -0
- data/assets/js/fallback/contact.js +91 -90
- data/lib/rawfeed/pub.rb +141 -0
- data/lib/rawfeed/version.rb +1 -1
- data/lib/rawfeed.rb +1 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cedeb842d14a644f5d8f81747b0414fac02509c4ac5f2548b82af13371ea4cfa
|
|
4
|
+
data.tar.gz: c1a185a440a5fe678666085b23df440702454b0b81ba832f2d98fedbee99bb8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e20abb9a11eb223aca026c3986756254e7bdea461f132fd2540cb6752b0c53137cb7a412f5200acf94474d63a4170962ba5a12050a1d3ebdf84be80f4d0b96d0
|
|
7
|
+
data.tar.gz: d0626b88db3902c752f1596b1936f1746b2b0347f6ad5f253c1598c70f1dea384c58354f6a79cba6a90abab173fd5d08f3bdcdbeb8a6323c13f3d114ba4ae496
|
data/_data/options.yml
CHANGED
|
@@ -59,14 +59,18 @@ head:
|
|
|
59
59
|
connect-src:
|
|
60
60
|
- https://www.google.com
|
|
61
61
|
- https://api.github.com
|
|
62
|
+
- https://script.google.com
|
|
63
|
+
- https://script.googleusercontent.com
|
|
62
64
|
img-src:
|
|
63
65
|
- https://www.google.com
|
|
64
66
|
- https://media0.giphy.com
|
|
65
67
|
- https://media4.giphy.com
|
|
68
|
+
- https://media.giphy.com
|
|
66
69
|
- https://github.githubassets.com
|
|
67
70
|
script-src:
|
|
68
71
|
- https://www.google.com
|
|
69
72
|
- https://www.gstatic.com
|
|
73
|
+
- https://script.google.com
|
|
70
74
|
- https://cdn.jsdelivr.net
|
|
71
75
|
- https://cdnjs.cloudflare.com
|
|
72
76
|
- https://giscus.app
|
|
@@ -147,6 +151,9 @@ header:
|
|
|
147
151
|
pixels:
|
|
148
152
|
emoji: "📷"
|
|
149
153
|
title: "pixels"
|
|
154
|
+
pub:
|
|
155
|
+
emoji: "📂"
|
|
156
|
+
title: "pub"
|
|
150
157
|
|
|
151
158
|
# section: [home]
|
|
152
159
|
home:
|
|
@@ -253,6 +260,11 @@ contact:
|
|
|
253
260
|
fail: "Verification failed. Please reload the page and try again."
|
|
254
261
|
error: "An error occurred while sending the message. Please try again."
|
|
255
262
|
|
|
263
|
+
# section: [pub]
|
|
264
|
+
pub:
|
|
265
|
+
path:
|
|
266
|
+
title: "Index of"
|
|
267
|
+
|
|
256
268
|
# section: [footer]
|
|
257
269
|
footer:
|
|
258
270
|
top_button:
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
{%- assign pixels_url = "/pixels/" | relative_url -%}
|
|
6
6
|
{%- assign search_url = "/blog/?search=open" | relative_url -%}
|
|
7
7
|
{%- assign tags_url = "/blog/tags/" | relative_url -%}
|
|
8
|
+
{%- assign pub_url = "/pub/" | relative_url -%}
|
|
8
9
|
{%- assign feed_url = "/feed.xml" | relative_url -%}
|
|
9
10
|
{%- assign head_ = site.data.options.head -%}
|
|
10
11
|
{%- assign site_title = site.data.options.title -%}
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
{%- assign contact_ = site.data.options.contact -%}
|
|
19
20
|
{%- assign footer_ = site.data.options.footer -%}
|
|
20
21
|
{%- assign socials_ = site.data.options.socials -%}
|
|
22
|
+
{%- assign pub_ = site.data.options.pub -%}
|
|
21
23
|
{%- assign datelang_ = site.data.options.datelang -%}
|
|
22
24
|
{%- assign maintenance_ = site.data.options.maintenance -%}
|
|
23
25
|
{%- assign reading_time_ = site.data.options.reading_time -%}
|
data/_includes/layout/head.html
CHANGED
|
@@ -87,6 +87,13 @@
|
|
|
87
87
|
{% comment %} load theme {% endcomment %}
|
|
88
88
|
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
|
|
89
89
|
|
|
90
|
+
{% comment %} custom theme {% endcomment %}
|
|
91
|
+
{%- assign file_path = '/assets/css/custom.css' -%}
|
|
92
|
+
{%- assign file_exists = site.static_files | where: "path", file_path | size -%}
|
|
93
|
+
{%- if file_exists > 0 -%}
|
|
94
|
+
<link rel="stylesheet" href="{{ '/assets/css/custom.css' | relative_url }}">
|
|
95
|
+
{%- endif -%}
|
|
96
|
+
|
|
90
97
|
{% comment %} feed {% endcomment %}
|
|
91
98
|
<link rel="alternate" type="application/atom+xml" title="{{ site_title }}" href="{{ '/feed.xml' | relative_url }}">
|
|
92
99
|
|
|
@@ -151,6 +151,10 @@
|
|
|
151
151
|
{%- endif -%}
|
|
152
152
|
{%- endfor -%}
|
|
153
153
|
{%- endif -%}
|
|
154
|
+
{%- assign files_in_pub = site.static_files | where_exp: "item", "item.path contains pub_url" -%}
|
|
155
|
+
{%- if files_in_pub.size > 0 -%}
|
|
156
|
+
<div class="menu-wrap-link">{{ header_.menu.pub.emoji | with_class: "spacer" }}<a href="{{ pub_url }}">{{ header_.menu.pub.title }}</a></div>
|
|
157
|
+
{%- endif -%}
|
|
154
158
|
</div>
|
|
155
159
|
{%- endif -%}
|
|
156
160
|
{%- endif -%}
|
data/_layouts/default.html
CHANGED
|
@@ -38,12 +38,14 @@
|
|
|
38
38
|
|
|
39
39
|
<!-- scripts -->
|
|
40
40
|
<script src="{{ '/assets/vendor/bootstrap/js/bootstrap.bundle.min.js' | relative_url }}"></script>
|
|
41
|
-
<script src="{{ '/assets/js/default.js' | relative_url }}"></script>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<script src="{{ '/assets/js/
|
|
46
|
-
<script src="{{ '/assets/js/
|
|
41
|
+
<script src="{{ '/assets/js/fallback/default.js' | relative_url }}"></script>
|
|
42
|
+
{%- if page.url contains '/blog/' -%}
|
|
43
|
+
<script src="{{ '/assets/vendor/simple-jekyll-search.min.js' | relative_url }}"></script>
|
|
44
|
+
{%- endif -%}
|
|
45
|
+
<script src="{{ '/assets/js/fallback/blog.js' | relative_url }}"></script>
|
|
46
|
+
<script src="{{ '/assets/js/fallback/home.js' | relative_url }}"></script>
|
|
47
|
+
<script src="{{ '/assets/js/fallback/page.js' | relative_url }}"></script>
|
|
48
|
+
<script src="{{ '/assets/js/fallback/contact.js' | relative_url }}"></script>
|
|
47
49
|
<!-- scripts -->
|
|
48
50
|
</body>
|
|
49
51
|
<!-- body -->
|
data/_layouts/pub.html
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{%- include layout/data.liquid -%}
|
|
2
|
+
|
|
3
|
+
{%- if maintenance_.enable != true -%}
|
|
4
|
+
{% assign current_path = page.permalink | default: '/' %}
|
|
5
|
+
|
|
6
|
+
<!DOCTYPE html>
|
|
7
|
+
<html id="top" lang="{{ default_.lang | default: 'en-US' }}" data-theme="light">
|
|
8
|
+
<!-- head -->
|
|
9
|
+
{%- include layout/head.html -%}
|
|
10
|
+
<!-- head -->
|
|
11
|
+
<body style="font-family: {{ default_.font.style }} !important;">
|
|
12
|
+
<div class="container-fluid">
|
|
13
|
+
<div class="row">
|
|
14
|
+
<main class="col-sm pub">
|
|
15
|
+
<h1 class="pub-path">{{ pub_.path.title | default: 'Index of' }} {{ current_path }}</h1>
|
|
16
|
+
<hr>
|
|
17
|
+
{% for item in page.directory_contents %}
|
|
18
|
+
<div class="row pub-line">
|
|
19
|
+
<div class="col-sm">
|
|
20
|
+
{% if item.type == 'directory' %}
|
|
21
|
+
<a href="{{ item.url }}">{{ item.name }}/</a>
|
|
22
|
+
{% elsif item.type == 'parent' %}
|
|
23
|
+
<a href="{{ item.url }}">{{ item.name }}</a>
|
|
24
|
+
{% else %}
|
|
25
|
+
<a href="{{ item.url }}">{{ item.name }}</a>
|
|
26
|
+
{% endif %}
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="col-sm">
|
|
30
|
+
{% if item.date %}
|
|
31
|
+
<span class="date">{{ item.date | date: "%Y-%m-%d %H:%M" }}</span>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="col-sm">
|
|
36
|
+
{% if item.type == 'file' %}
|
|
37
|
+
<span class="size">{{ item.size | divided_by: 1024.0 | round: 2 }} KB</span>
|
|
38
|
+
{% endif %}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
{% endfor %}
|
|
42
|
+
<hr>
|
|
43
|
+
</main>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
{%- include layout/footer.html -%}
|
|
47
|
+
</body>
|
|
48
|
+
</html>
|
|
49
|
+
{%- else -%}
|
|
50
|
+
{%- include layout/maintenance.html -%}
|
|
51
|
+
{%- endif -%}
|
data/_sass/layouts/_index.scss
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.pub {
|
|
2
|
+
font-size: 13px;
|
|
3
|
+
color: var(--text-color);
|
|
4
|
+
a {
|
|
5
|
+
color: var(--primary-color);
|
|
6
|
+
}
|
|
7
|
+
&-path {
|
|
8
|
+
font-size: 32px;
|
|
9
|
+
font-family: 'Times New Roman', Times, serif;
|
|
10
|
+
padding: 15px 0px;
|
|
11
|
+
font-weight: bold !important;
|
|
12
|
+
}
|
|
13
|
+
&-line {
|
|
14
|
+
@media (max-width: 575px) {
|
|
15
|
+
margin-bottom: 15px !important;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/assets/images/favicon.png
CHANGED
|
Binary file
|
|
@@ -5,112 +5,113 @@
|
|
|
5
5
|
|
|
6
6
|
document.addEventListener("DOMContentLoaded", () => {
|
|
7
7
|
const form = document.getElementById("contactForm");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
modalTitle.innerHTML = title;
|
|
31
|
-
modalBody.innerHTML = message;
|
|
32
|
-
|
|
33
|
-
const bsModal = new bootstrap.Modal(modalEl);
|
|
34
|
-
bsModal.show();
|
|
35
|
-
}
|
|
8
|
+
if (form) {
|
|
9
|
+
const submitButton = document.getElementById("submitButton");
|
|
10
|
+
const endpoint = "{{ head_.google.apps_script.url }}"; // URL Google Apps Script
|
|
11
|
+
|
|
12
|
+
// get modal
|
|
13
|
+
function showModal(title, message, type = 'success') {
|
|
14
|
+
const modalEl = document.getElementById('contactMessageModal');
|
|
15
|
+
const modalTitle = modalEl.querySelector('.modal-title');
|
|
16
|
+
const modalBody = modalEl.querySelector('.modal-body');
|
|
17
|
+
const modalContent = modalEl.querySelector('.modal-content');
|
|
18
|
+
|
|
19
|
+
modalContent.classList.remove('contact-message-success', 'contact-message-error', 'contact-message-warning');
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// Apply the color according to the type
|
|
23
|
+
if (type === 'success') {
|
|
24
|
+
modalContent.classList.add('contact-message-success');
|
|
25
|
+
} else if (type === 'error') {
|
|
26
|
+
modalContent.classList.add('contact-message-error');
|
|
27
|
+
} else if (type === 'warning') {
|
|
28
|
+
modalContent.classList.add('contact-message-warning');
|
|
29
|
+
}
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const recaptchaResponse = grecaptcha.getResponse();
|
|
41
|
-
if (!recaptchaResponse) {
|
|
42
|
-
showModal(
|
|
43
|
-
"{{ contact_.recaptcha.warning.title | default: 'Warning' }}",
|
|
44
|
-
`{{ contact_.recaptcha.warning.content | default: "Please tick the 'I'm not a robot' box." }}`,
|
|
45
|
-
"warning"
|
|
46
|
-
);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
31
|
+
modalTitle.innerHTML = title;
|
|
32
|
+
modalBody.innerHTML = message;
|
|
49
33
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (text.length < "{{ contact_.message.caracters.min }}" ) {
|
|
53
|
-
showModal(
|
|
54
|
-
"{{ contact_.message.caracters.warning.title | default: 'Warning' }}",
|
|
55
|
-
"{{ contact_.message.caracters.warning.content | default: 'The message must have at least 50 characters.' }}",
|
|
56
|
-
"warning"
|
|
57
|
-
);
|
|
58
|
-
return;
|
|
34
|
+
const bsModal = new bootstrap.Modal(modalEl);
|
|
35
|
+
bsModal.show();
|
|
59
36
|
}
|
|
60
37
|
|
|
61
|
-
|
|
62
|
-
|
|
38
|
+
form.addEventListener("submit", async (e) => {
|
|
39
|
+
e.preventDefault();
|
|
63
40
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
const response = await fetch(endpoint, {
|
|
69
|
-
method: "POST",
|
|
70
|
-
redirect: "follow",
|
|
71
|
-
body: JSON.stringify(data)
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const result = await response.json();
|
|
75
|
-
|
|
76
|
-
if (result.result === 'success') {
|
|
77
|
-
form.reset();
|
|
78
|
-
grecaptcha.reset();
|
|
41
|
+
const recaptchaResponse = grecaptcha.getResponse();
|
|
42
|
+
if (!recaptchaResponse) {
|
|
79
43
|
showModal(
|
|
80
|
-
"{{ contact_.
|
|
81
|
-
|
|
82
|
-
"
|
|
44
|
+
"{{ contact_.recaptcha.warning.title | default: 'Warning' }}",
|
|
45
|
+
`{{ contact_.recaptcha.warning.content | default: "Please tick the 'I'm not a robot' box." }}`,
|
|
46
|
+
"warning"
|
|
83
47
|
);
|
|
84
|
-
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const textarea = document.getElementById('textMessage');
|
|
52
|
+
const text = textarea.value.trim();
|
|
53
|
+
if (text.length < "{{ contact_.message.caracters.min }}" ) {
|
|
85
54
|
showModal(
|
|
86
|
-
"{{ contact_.message.
|
|
87
|
-
"{{ contact_.message.
|
|
88
|
-
"
|
|
55
|
+
"{{ contact_.message.caracters.warning.title | default: 'Warning' }}",
|
|
56
|
+
"{{ contact_.message.caracters.warning.content | default: 'The message must have at least 50 characters.' }}",
|
|
57
|
+
"warning"
|
|
89
58
|
);
|
|
90
|
-
|
|
59
|
+
return;
|
|
91
60
|
}
|
|
92
61
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
62
|
+
submitButton.disabled = true;
|
|
63
|
+
submitButton.textContent = "{{ contact_.message.status | default: 'Sending...Wait' }}";
|
|
64
|
+
|
|
65
|
+
const formData = new FormData(form);
|
|
66
|
+
const data = Object.fromEntries(formData.entries());
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(endpoint, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
redirect: "follow",
|
|
72
|
+
body: JSON.stringify(data)
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const result = await response.json();
|
|
76
|
+
|
|
77
|
+
if (result.result === 'success') {
|
|
78
|
+
form.reset();
|
|
79
|
+
grecaptcha.reset();
|
|
96
80
|
showModal(
|
|
97
|
-
"{{ contact_.message.
|
|
98
|
-
"{{ contact_.
|
|
99
|
-
"
|
|
81
|
+
"{{ contact_.message.success.title | default: 'Message Sent' }}",
|
|
82
|
+
"{{ contact_.message.success.content | default: 'Your message has been sent successfully!' }}",
|
|
83
|
+
"success"
|
|
100
84
|
);
|
|
101
|
-
|
|
85
|
+
} else {
|
|
102
86
|
showModal(
|
|
103
87
|
"{{ contact_.message.error.title | default: 'Error' }}",
|
|
104
|
-
"{{ contact_.
|
|
88
|
+
"{{ contact_.message.error.content | default: 'Something went wrong while sending your message.' }}",
|
|
105
89
|
"error"
|
|
106
90
|
);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
91
|
+
throw new Error(result.message || "{{ contact_.message.error.content | default: 'An unknown error has occurred.' }}");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error("Error sending:", error);
|
|
96
|
+
if (error.message.includes("reCAPTCHA")) {
|
|
97
|
+
showModal(
|
|
98
|
+
"{{ contact_.message.error.title | default: 'Error' }}",
|
|
99
|
+
"{{ contact_.recaptcha.fail | default: 'Verification failed. Please reload the page and try again.' }}",
|
|
100
|
+
"error"
|
|
101
|
+
);
|
|
102
|
+
} else {
|
|
103
|
+
showModal(
|
|
104
|
+
"{{ contact_.message.error.title | default: 'Error' }}",
|
|
105
|
+
"{{ contact_.recaptcha.error | default: 'An error occurred while sending the message. Please try again.' }}",
|
|
106
|
+
"error"
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
grecaptcha.reset();
|
|
115
110
|
|
|
111
|
+
} finally {
|
|
112
|
+
submitButton.disabled = false;
|
|
113
|
+
submitButton.textContent = "{{ contact_.button.text | default: 'Send!' }}";
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
116
117
|
});
|
data/lib/rawfeed/pub.rb
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# pub.rb
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
# Define a página que será gerada dinamicamente para cada diretório
|
|
5
|
+
class DirectoryListingPage < Page
|
|
6
|
+
def initialize(site, base, dir, files_and_dirs)
|
|
7
|
+
@site = site
|
|
8
|
+
@base = base
|
|
9
|
+
@dir = dir
|
|
10
|
+
@name = 'index.html'
|
|
11
|
+
@layout_name = 'pub.html'
|
|
12
|
+
|
|
13
|
+
self.process(@name)
|
|
14
|
+
self.read_yaml(File.join(base, '_layouts'), 'pub.html')
|
|
15
|
+
|
|
16
|
+
# Define o permalink correto para a página de índice
|
|
17
|
+
# Garante que 'pub/sub/index.html' tenha o permalink '/pub/sub/'
|
|
18
|
+
self.data['permalink'] = "/#{dir}/"
|
|
19
|
+
|
|
20
|
+
# Título (opcional, pode ser formatado no layout)
|
|
21
|
+
self.data['title'] = File.basename(dir).capitalize
|
|
22
|
+
|
|
23
|
+
# A MÁGICA: Injeta a lista de conteúdo no objeto da página
|
|
24
|
+
self.data['directory_contents'] = files_and_dirs
|
|
25
|
+
self.data['layout'] = 'pub'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# O gerador que executa o escaneamento recursivo
|
|
30
|
+
class DirectoryListingGenerator < Generator
|
|
31
|
+
safe true
|
|
32
|
+
priority :normal
|
|
33
|
+
|
|
34
|
+
# Diretório principal que você deseja listar
|
|
35
|
+
PUB_DIR = 'pub'
|
|
36
|
+
|
|
37
|
+
def generate(site)
|
|
38
|
+
# Pega todos os arquivos e diretórios dentro de PUB_DIR
|
|
39
|
+
# Exclui o PUB_DIR raiz em si.
|
|
40
|
+
all_paths = Dir.glob("#{PUB_DIR}/**/{" + '*' + ",.*}")
|
|
41
|
+
|
|
42
|
+
# Itera sobre cada item encontrado e agrupa por diretório pai
|
|
43
|
+
directory_map = {}
|
|
44
|
+
|
|
45
|
+
all_paths.each do |path|
|
|
46
|
+
# Ignora arquivos/diretórios que o Jekyll já processa ou ignora
|
|
47
|
+
next if path.start_with?('_') || path.start_with?('.')
|
|
48
|
+
next if File.basename(path) == 'index.html'
|
|
49
|
+
|
|
50
|
+
# Determina o diretório pai (o que vai ter o index.html gerado)
|
|
51
|
+
parent_dir = File.dirname(path)
|
|
52
|
+
parent_dir = PUB_DIR if parent_dir == '.'
|
|
53
|
+
|
|
54
|
+
# Inicializa a lista se for a primeira vez
|
|
55
|
+
directory_map[parent_dir] ||= []
|
|
56
|
+
|
|
57
|
+
# Determina o tipo e prepara os dados
|
|
58
|
+
if File.directory?(path)
|
|
59
|
+
# Se for um diretório, adiciona a barra final para URL
|
|
60
|
+
type = 'directory'
|
|
61
|
+
url = "/#{path}/"
|
|
62
|
+
size = ''
|
|
63
|
+
date = File.mtime(path)
|
|
64
|
+
# Adiciona apenas se o diretório não estiver vazio
|
|
65
|
+
directory_map[parent_dir] << {
|
|
66
|
+
'name' => File.basename(path),
|
|
67
|
+
'type' => type,
|
|
68
|
+
'url' => url,
|
|
69
|
+
'date' => date
|
|
70
|
+
} unless Dir.empty?(path)
|
|
71
|
+
else
|
|
72
|
+
# Se for um arquivo
|
|
73
|
+
type = 'file'
|
|
74
|
+
url = "/#{path}"
|
|
75
|
+
size = File.size(path) # Tamanho em bytes
|
|
76
|
+
date = File.mtime(path)
|
|
77
|
+
|
|
78
|
+
# Adiciona o item ao seu diretório pai
|
|
79
|
+
directory_map[parent_dir] << {
|
|
80
|
+
'name' => File.basename(path),
|
|
81
|
+
'type' => type,
|
|
82
|
+
'url' => url,
|
|
83
|
+
'size' => size,
|
|
84
|
+
'date' => date
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Cria as páginas de listagem dinamicamente
|
|
90
|
+
directory_map.each do |dir_path, contents|
|
|
91
|
+
# Classifica por tipo (diretórios primeiro), depois por nome
|
|
92
|
+
sorted_contents = contents.sort_by do |item|
|
|
93
|
+
[item['type'] == 'file' ? 1 : 0, item['name'].downcase]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Lógica para a entrada de navegação '..'
|
|
97
|
+
parent_url = nil
|
|
98
|
+
parent_name = '../'
|
|
99
|
+
|
|
100
|
+
if dir_path == PUB_DIR
|
|
101
|
+
# Caso especial: se estiver na raiz 'pub/', o pai é a raiz do site '/'
|
|
102
|
+
parent_url = '/'
|
|
103
|
+
else
|
|
104
|
+
# Para todos os outros subdiretórios (ex: pub/subpasta)
|
|
105
|
+
parent_dir = File.dirname(dir_path)
|
|
106
|
+
|
|
107
|
+
# Garante que 'pub' não se torne '.' e que o URL termine em barra
|
|
108
|
+
if parent_dir == PUB_DIR
|
|
109
|
+
parent_url = "/#{PUB_DIR}/"
|
|
110
|
+
else
|
|
111
|
+
parent_url = "/#{parent_dir}/"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Adiciona a entrada de navegação para o diretório pai
|
|
116
|
+
sorted_contents.unshift({
|
|
117
|
+
'name' => parent_name,
|
|
118
|
+
'type' => 'parent',
|
|
119
|
+
'url' => parent_url
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
# # Adiciona a página ".." para navegar de volta, exceto para o pub/ raiz
|
|
123
|
+
# unless dir_path == PUB_DIR
|
|
124
|
+
# parent_url = File.dirname(dir_path)
|
|
125
|
+
# parent_url = '/' if parent_url == '.'
|
|
126
|
+
# parent_url = "/#{parent_url}/" unless parent_url == '/'
|
|
127
|
+
|
|
128
|
+
# sorted_contents.unshift({
|
|
129
|
+
# 'name' => '../',
|
|
130
|
+
# 'type' => 'parent',
|
|
131
|
+
# 'url' => parent_url
|
|
132
|
+
# })
|
|
133
|
+
# end
|
|
134
|
+
|
|
135
|
+
# Cria a nova página e a adiciona ao site
|
|
136
|
+
page = DirectoryListingPage.new(site, site.source, dir_path, sorted_contents)
|
|
137
|
+
site.pages << page
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
data/lib/rawfeed/version.rb
CHANGED
data/lib/rawfeed.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rawfeed
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- William C. Canin
|
|
@@ -166,6 +166,7 @@ files:
|
|
|
166
166
|
- _layouts/pixel.html
|
|
167
167
|
- _layouts/pixels.html
|
|
168
168
|
- _layouts/post.html
|
|
169
|
+
- _layouts/pub.html
|
|
169
170
|
- _layouts/resume.html
|
|
170
171
|
- _layouts/tag.html
|
|
171
172
|
- _layouts/tag_posts.html
|
|
@@ -198,6 +199,7 @@ files:
|
|
|
198
199
|
- _sass/layouts/_pixel.scss
|
|
199
200
|
- _sass/layouts/_pixels.scss
|
|
200
201
|
- _sass/layouts/_post.scss
|
|
202
|
+
- _sass/layouts/_pub.scss
|
|
201
203
|
- _sass/layouts/_resume.scss
|
|
202
204
|
- _sass/layouts/_tag-posts.scss
|
|
203
205
|
- _sass/layouts/_tag.scss
|
|
@@ -295,6 +297,7 @@ files:
|
|
|
295
297
|
- lib/rawfeed/page.rb
|
|
296
298
|
- lib/rawfeed/pixel.rb
|
|
297
299
|
- lib/rawfeed/post.rb
|
|
300
|
+
- lib/rawfeed/pub.rb
|
|
298
301
|
- lib/rawfeed/reading_time.rb
|
|
299
302
|
- lib/rawfeed/resume.rb
|
|
300
303
|
- lib/rawfeed/typescript_liquid.rb
|