Migrate to markdown, add rss feed
This commit is contained in:
parent
a4e952773b
commit
83a4c483c7
|
@ -1,4 +1,6 @@
|
||||||
import { defineConfig } from 'astro/config'
|
import { defineConfig } from 'astro/config'
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({})
|
export default defineConfig({
|
||||||
|
site: 'https://comfycamp.space'
|
||||||
|
})
|
||||||
|
|
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -9,6 +9,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.3.0",
|
"@astrojs/check": "^0.3.0",
|
||||||
|
"@astrojs/rss": "^3.0.0",
|
||||||
"astro": "^3.5.2",
|
"astro": "^3.5.2",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
|
@ -128,6 +129,15 @@
|
||||||
"node": ">=18.14.1"
|
"node": ">=18.14.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@astrojs/rss": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-PMX8iqByk9gtOrusikten/oF5uHjOCZigL6RuXFBUu+xtdKQxXzfIohJ99V2haA4FJjVDyibDTGzXR81POBMxQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-xml-parser": "^4.2.7",
|
||||||
|
"kleur": "^4.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@astrojs/telemetry": {
|
"node_modules/@astrojs/telemetry": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.4.tgz",
|
||||||
|
@ -2118,6 +2128,27 @@
|
||||||
"node": ">=8.6.0"
|
"node": ">=8.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-xml-parser": {
|
||||||
|
"version": "4.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz",
|
||||||
|
"integrity": "sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/NaturalIntelligence"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/naturalintelligence"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"strnum": "^1.0.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"fxparser": "src/cli/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.15.0",
|
"version": "1.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
||||||
|
@ -5603,6 +5634,11 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/strnum": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.3.0",
|
"@astrojs/check": "^0.3.0",
|
||||||
|
"@astrojs/rss": "^3.0.0",
|
||||||
"astro": "^3.5.2",
|
"astro": "^3.5.2",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
|
|
1
public/icons/rss.svg
Normal file
1
public/icons/rss.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>RSS</title><path fill="white" d="M19.199 24C19.199 13.467 10.533 4.8 0 4.8V0c13.165 0 24 10.835 24 24h-4.801zM3.291 17.415c1.814 0 3.293 1.479 3.293 3.295 0 1.813-1.485 3.29-3.301 3.29C1.47 24 0 22.526 0 20.71s1.475-3.294 3.291-3.295zM15.909 24h-4.665c0-6.169-5.075-11.245-11.244-11.245V8.09c8.727 0 15.909 7.184 15.909 15.91z"/></svg>
|
After Width: | Height: | Size: 414 B |
|
@ -1,4 +1,28 @@
|
||||||
<footer>
|
<footer>
|
||||||
|
<h2>Сайт</h2>
|
||||||
|
<div class="list">
|
||||||
|
<a href="/rss.xml">
|
||||||
|
<img
|
||||||
|
src="/icons/rss.svg"
|
||||||
|
width="18px"
|
||||||
|
height="18px"
|
||||||
|
alt="RSS logo"
|
||||||
|
/>
|
||||||
|
RSS
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/ordinary-dev/comfycamp/issues/new" target="_blank">
|
||||||
|
<img
|
||||||
|
src="/icons/github.svg"
|
||||||
|
width="18px"
|
||||||
|
height="18px"
|
||||||
|
alt="Github logo"
|
||||||
|
/>
|
||||||
|
Обратная связь
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Автор</h2>
|
||||||
|
<div class="list">
|
||||||
<a href="https://m.comfycamp.space/@lumin" rel="me" target="_blank">
|
<a href="https://m.comfycamp.space/@lumin" rel="me" target="_blank">
|
||||||
<img
|
<img
|
||||||
src="/icons/mastodon.svg"
|
src="/icons/mastodon.svg"
|
||||||
|
@ -26,15 +50,7 @@
|
||||||
/>
|
/>
|
||||||
admin@comfycamp.space
|
admin@comfycamp.space
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ordinary-dev/comfycamp/issues/new" target="_blank">
|
</div>
|
||||||
<img
|
|
||||||
src="/icons/github.svg"
|
|
||||||
width="18px"
|
|
||||||
height="18px"
|
|
||||||
alt="Github logo"
|
|
||||||
/>
|
|
||||||
Обратная связь
|
|
||||||
</a>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -46,14 +62,15 @@
|
||||||
padding-bottom: 40px;
|
padding-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer > a {
|
.list {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer div > a {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer svg {
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
date: string
|
|
||||||
title: string
|
|
||||||
href: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const { date, title, href } = Astro.props
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class="note">
|
|
||||||
<div class="date">{ date }</div>
|
|
||||||
<div class="dash">—</div>
|
|
||||||
<a href={href}>{ title }</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.note {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.dash {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 600px) {
|
|
||||||
.note {
|
|
||||||
display: flex;
|
|
||||||
gap: 6px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
.dash {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
interface Props {
|
|
||||||
createdAt: string
|
|
||||||
updatedAt: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const { createdAt, updatedAt } = Astro.props
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class="metadata">
|
|
||||||
<p>Дата создания: { createdAt }</p>
|
|
||||||
{ updatedAt !== createdAt && <p>Последнее обновление: { updatedAt }</p> }
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.metadata {
|
|
||||||
color: #aaa;
|
|
||||||
margin-top: 16px;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
.metadata p {
|
|
||||||
margin-top: 6px;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
</style>
|
|
15
src/content/config.ts
Normal file
15
src/content/config.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { z, defineCollection } from 'astro:content'
|
||||||
|
|
||||||
|
const notesCollection = defineCollection({
|
||||||
|
type: 'content',
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
pubDate: z.date(),
|
||||||
|
updatedAt: z.date().optional(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const collections = {
|
||||||
|
'notes': notesCollection,
|
||||||
|
}
|
34
src/content/notes/carefree-mountain.md
Normal file
34
src/content/notes/carefree-mountain.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
title: "Беспечная Гляденовская гора"
|
||||||
|
description: "Путешествие до Гляденовской горы."
|
||||||
|
pubDate: 2023-10-16
|
||||||
|
---
|
||||||
|
|
||||||
|
Гляденовская гора - это красивый лес в Перми, за которым прячется деревянная часовня.
|
||||||
|
Здесь не будет рассказов про историю горы, ведь я не являюсь ни историком, ни археологом,
|
||||||
|
оставлю это занятие более компетентным людям.
|
||||||
|
Я всего лишь хочу показать вам это место от лица обывателя,
|
||||||
|
и, может быть, это сподвигнет вас отправиться когда-нибудь в небольшое путешествие.
|
||||||
|
|
||||||
|
![Фотография поля с видом на пермский аэропорт](/carefree-mountain/1.webp)
|
||||||
|
|
||||||
|
Гляденовская гора находится недалеко от пермского аэропорта.
|
||||||
|
Если до него самого добраться не составит большого труда, то дальше придётся идти вдоль дороги, хоть и совсем недолго.
|
||||||
|
Вскоре вы зайдете в лес, тогда идти станет проще и интереснее.
|
||||||
|
|
||||||
|
Теперь, когда мы наконец-то в лесу, где нет проезжающих мимо машин, можно расслабиться.
|
||||||
|
Дальнейший путь представляет из себя череду деревянных ступенек.
|
||||||
|
Спускаться по ним довольно легко, но ещё проще подскользнуться.
|
||||||
|
|
||||||
|
![Деревянные ступеньки в лесу](/carefree-mountain/2.webp)
|
||||||
|
![Белочка](/carefree-mountain/3.webp)
|
||||||
|
![Деревянные ступеньки в лесу](/carefree-mountain/4.webp)
|
||||||
|
|
||||||
|
В конце пути нас ожидает деревянная церковь.
|
||||||
|
Теперь можно неспеша осмотреться вокруг.
|
||||||
|
В таких местах почти ничего не просиходит, внешнего мира как будто не существует.
|
||||||
|
Он остался там, за горой, здесь же царит тишина и спокойствие.
|
||||||
|
|
||||||
|
![Деревянная церковь в лесу](/carefree-mountain/5.webp)
|
||||||
|
|
||||||
|
*Удивительное рядом.*
|
119
src/content/notes/self-hosting.md
Normal file
119
src/content/notes/self-hosting.md
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
---
|
||||||
|
title: "Свободные альтернативы популярным сервисам"
|
||||||
|
description: "Список самых популярных независимых альтернатив коммерческим социальным сетям и сервисам."
|
||||||
|
pubDate: 2023-08-27
|
||||||
|
updatedAt: 2023-10-01
|
||||||
|
---
|
||||||
|
|
||||||
|
Это статья для тех, кто никогда не слышал про альтернативы современным социальным сетям и сервисам.
|
||||||
|
|
||||||
|
Мы стали слишком сильно полагаться на централизованные сервисы, такие как vk, youtube, telegram или twitter.
|
||||||
|
Если у вас начали появляться претензии, будь то цензура, отсутствие нужных функций или
|
||||||
|
пренебрежительное отношение к личным данным, я предлагаю вам обратить внимание на альтернативы,
|
||||||
|
которые вы можете запустить на своем сервере.
|
||||||
|
|
||||||
|
Хотя, строго говоря, иметь свой сервер вовсе не обязательно,
|
||||||
|
но в таком случае вы должны доверять владельцу сервера, ведь именно он будет хранить ваши данные.
|
||||||
|
Это не особо касается социальных сетей без личных сообщений, там всё и так публично.
|
||||||
|
Мессенджеры, поддерживающие шифрование, защищают вас от лишних глаз, можете без опасений выбирать публичный сервер.
|
||||||
|
А вот хранить файлы у незнакомцев я бы не стал.
|
||||||
|
|
||||||
|
## Социальные сети - Fediverse
|
||||||
|
|
||||||
|
![Скриншот fediverse.party](/selfhosted/fediverse-party.webp)
|
||||||
|
|
||||||
|
Fediverse - это группа из нескольких социальных сетей, представляющие аналоги популярным сервисам.
|
||||||
|
|
||||||
|
| Оригинальный сервис | Альтернативы |
|
||||||
|
| --- | --- |
|
||||||
|
| Twitter | [Mastodon](https://joinmastodon.org/), [Misskey](https://misskey-hub.net/en/) и [Pleroma](https://pleroma.social/) |
|
||||||
|
| Vk, Facebook | [Friendica](https://friendi.ca/) |
|
||||||
|
| Instagram | [Pixelfed](https://pixelfed.org/) |
|
||||||
|
| Reddit | [Lemmy](https://join-lemmy.org/) |
|
||||||
|
| YouTube | [Peertube](https://joinpeertube.org/) |
|
||||||
|
| Soundcloud | [Funkwhale](https://funkwhale.audio/) |
|
||||||
|
|
||||||
|
Создать свой сервер может любой желающий, и его пользователи смогут общаться с пользователями на других серверах.
|
||||||
|
Зачастую можно общаться даже с пользователями других платформ.
|
||||||
|
|
||||||
|
Если вы ищете простое место для старта, рекомендую обратить внимание на mastodon.
|
||||||
|
Выберите сервер, на котором вы хотите зарегистрироваться,
|
||||||
|
в этом вам может помочь [каталог русскоязычных серверов](https://ru.index.community/communities).
|
||||||
|
|
||||||
|
Вот парочка советов:
|
||||||
|
* Ознакомтесь с правилами сервера. На разных серверах модераторы могут запрещать разные вещи.
|
||||||
|
* Не регистрируйтесь на больших серверах. Вы не получите от этого особых плюсов, а лишь усилите централизацию.
|
||||||
|
|
||||||
|
У меня есть свой [сервер mastodon](https://m.comfycamp.space), жду вас в гости!
|
||||||
|
|
||||||
|
## Мессенджеры - Matrix, XMPP
|
||||||
|
|
||||||
|
![Скриншот matirx.org](/selfhosted/matrix.webp)
|
||||||
|
|
||||||
|
В мире децентрализованного общения сейчас популярны 2 протокола: xmpp (ранее jabber) и matrix.
|
||||||
|
Идея такая же, как и в случае с fediverse: любой желающий может поднять свой сервер, а пользователи разных серверов могут общаться между собой.
|
||||||
|
|
||||||
|
По сравнению с другими платформами, например telegram или whatsapp,
|
||||||
|
вы получаете end-to-end шифрование на всех устройствах и множество клиентов с открытым исходным кодом,
|
||||||
|
а для регистрации не нужно указывать номер телефона.
|
||||||
|
|
||||||
|
Какой из них вам понравится больше - сказать тяжело. Попробуйте оба.
|
||||||
|
|
||||||
|
## Облако - Nextcloud
|
||||||
|
|
||||||
|
![Скриншот менеджера файлов в nextcloud](/selfhosted/nextcloud.webp)
|
||||||
|
|
||||||
|
[Nextcloud](https://nextcloud.com/) - это больше, чем просто облако.
|
||||||
|
Это и хранилище файлов, и календарь, и задачи, и контакты, и ещё много всего.
|
||||||
|
Своим функционалом nextcloud способен заменить целые экосистемы.
|
||||||
|
|
||||||
|
При желании к nextcloud можно подключить офисный редакторор, например onlyoffice, тогда nextcloud превращается ещё и в альтернативу Google Docs.
|
||||||
|
Это может быть очень кстати для разных компаний.
|
||||||
|
|
||||||
|
Список контактов, календари и задачи можно синхронизировать между своими устройствами.
|
||||||
|
Для этого используются обычные протоколы сaldav и carddav.
|
||||||
|
|
||||||
|
## Стриминг - Jellyfin
|
||||||
|
|
||||||
|
![Скриншот jellyfin с открытой страницей фильма](/selfhosted/jellyfin.webp)
|
||||||
|
|
||||||
|
[Jellyin](https://jellyfin.org/) - это ваш личный стриминговый сервис.
|
||||||
|
|
||||||
|
Вы просто указываете путь до вашей медиатеки и получаете возможность смотреть и слушать её онлайн.
|
||||||
|
Jellyfin поддерживает фильмы, сериалы, музыку, аудиокниги и комиксы.
|
||||||
|
|
||||||
|
Jellyfin может перекодировать файлы на лету, если посчитает, что ваше устройство не поддерживает исходный формат.
|
||||||
|
Это зачастую необходимо для браузеров, так как они могут воспроизодить только самые простые форматы.
|
||||||
|
Если вы хотите снизить нагрузку на сервер, можно найти клиенты, позволяющие транслировать видео напрямую в ваш плеер
|
||||||
|
(см. [jellyfin-mpv-shim](https://github.com/jellyfin/jellyfin-mpv-shim).
|
||||||
|
|
||||||
|
Jellyfin поддерживает DLNA, а это значит, что в пару кликов можно включить любой фильм на телевизоре, который находится в той же сети, что и сервер.
|
||||||
|
А ещё можно организовывать комнаты для просмотра и синхронизировать воспроизведение на нескольких устройствах, если вы хотите посмотреть
|
||||||
|
что-нибудь в компании.
|
||||||
|
|
||||||
|
Jellyfin - это не обязательно синоним пиратства.
|
||||||
|
Вы можете стримить легально приобретенный контент, если у вас есть такое желание.
|
||||||
|
|
||||||
|
## Фото и видео - Photoprism
|
||||||
|
|
||||||
|
![Скриншот photoprism, на котором видно несколько фотографий](/selfhosted/photoprism.webp)
|
||||||
|
|
||||||
|
Многие пользуются сервисами от Apple или Google, чтобы хранить личные фотографии и видео.
|
||||||
|
Если вам становится некомфортно от мысли, что компании, владеющие рекламными сетями,
|
||||||
|
имеют доступ к вашим фотографиям, можно обратиться к [Photoprism](https://www.photoprism.app/).
|
||||||
|
|
||||||
|
Photoprism позволяет легко просматривать фото в браузере, редактировать метатеги,
|
||||||
|
и даже умеет распознавать объекты на фото (хотя, честно говоря, эта функция работает не идеально).
|
||||||
|
Вы можете создавать альбомы и делиться ими с другими людьми.
|
||||||
|
|
||||||
|
Загружать фото можно через веб-интерфейс, импортировать с директории на вашем сервере или же
|
||||||
|
загружать их по протоколу webdav с того же nextcloud.
|
||||||
|
|
||||||
|
Photoprism умеет конвертировать фотографии формата raw, чтобы их можно было открыть в браузере.
|
||||||
|
Также вы без проблем можете загрузить свои видео, они при необходимости будут сконвертированы.
|
||||||
|
|
||||||
|
## Вместо заключения - Awesome Selfhosted
|
||||||
|
|
||||||
|
Один из самых популярных репозиториев на Github: [Awesome Selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted).
|
||||||
|
Это большой список всевозможных сервисов, которые вы можете запустить на своем сервере.
|
||||||
|
В этой статье я не покрыл и 10% доступных вариантов. Однако, надеюсь, что я смог хотя бы приоткрыть дверь в эту кроличью нору.
|
38
src/content/notes/strelka.md
Normal file
38
src/content/notes/strelka.md
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
title: "Мыс Стрелка"
|
||||||
|
description: "Фотографии с путешествия на мыс Стрелка."
|
||||||
|
pubDate: 2023-11-11
|
||||||
|
---
|
||||||
|
|
||||||
|
*Некоторые вещи стоят того, чтобы встать в 6 утра в воскресенье.*
|
||||||
|
|
||||||
|
## Куда мы едем?
|
||||||
|
|
||||||
|
Мыс Стрелка - это скала, у которой соединяются 2 реки: Кама и Чусовая.
|
||||||
|
Находится она недалеко от города, добраться до ближайших деревень можно на электричке,
|
||||||
|
а дальше нужно пару километров пройти пешком.
|
||||||
|
|
||||||
|
Точную дорогу мы заранее не посмотрели и пришли не на скалу, а к её основанию.
|
||||||
|
Подняться, как оказалось, можно и у самой скалы, в самом тяжёлом месте есть верёвка.
|
||||||
|
|
||||||
|
![Вершина скалы](/strelka/1.jpg)
|
||||||
|
![Вид с мыса Стрелка](/strelka/2.jpg)
|
||||||
|
![Вид с мыса Стрелка](/strelka/3.jpg)
|
||||||
|
|
||||||
|
На вершине скалы довольно ветрено, но красиво.
|
||||||
|
Совсем рядом находятся макушки деревьев, а дальше только вода.
|
||||||
|
|
||||||
|
Спустившись буквально на пару шагов можно укрыться от ветра и отдохнуть.
|
||||||
|
Если вы оказались здесь осенью, то чай будет очень кстати.
|
||||||
|
|
||||||
|
![Пьем чай на скале](/strelka/4.jpg)
|
||||||
|
|
||||||
|
## Путь обратно
|
||||||
|
|
||||||
|
У нас оставалось несколько часов до электрички, поэтому мы отправились изучать ближайшие деревни.
|
||||||
|
Вроде бы мы находились совсем недалеко от города, но атмосфера уже другая.
|
||||||
|
|
||||||
|
![Железная дорога в деревне](/strelka/5.jpg)
|
||||||
|
|
||||||
|
Наши похождения закончились довольно быстро, но на станции можно спокойно дождаться электрички.
|
||||||
|
В итоге получилось короткое, но запоминающееся путешествие.
|
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
|
@ -1 +1,2 @@
|
||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
---
|
---
|
||||||
import Layout from '../layouts/Layout.astro'
|
import Layout from '../layouts/Layout.astro'
|
||||||
import Note from '../components/Note.astro'
|
import { getCollection } from 'astro:content'
|
||||||
|
|
||||||
|
const notes = await getCollection('notes')
|
||||||
|
notes.sort((a, b) => {
|
||||||
|
if (a.data.pubDate < b.data.pubDate) return 1
|
||||||
|
if (a.data.pubDate > b.data.pubDate) return -1
|
||||||
|
return 0
|
||||||
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Уютный домик">
|
<Layout title="Уютный домик">
|
||||||
|
@ -14,22 +21,31 @@ import Note from '../components/Note.astro'
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>Заметки</h2>
|
<h2>Заметки</h2>
|
||||||
<Note
|
{notes.map(note => (
|
||||||
date="11 ноября 2023"
|
<div class="note">
|
||||||
title="Мыс Стрелка"
|
<div class="date">{note.data.pubDate.toLocaleDateString("ru", {year: "numeric", month: "long", day: "numeric"})}</div>
|
||||||
href="/notes/strelka/"
|
<div class="dash">—</div>
|
||||||
/>
|
<a href={`/notes/${note.slug}/`}>{ note.data.title }</a>
|
||||||
<Note
|
</div>
|
||||||
date="16 октября 2023"
|
))}
|
||||||
title="Беспечная Гляденовская гора"
|
|
||||||
href="/notes/carefree-mountain/"
|
|
||||||
/>
|
|
||||||
<Note
|
|
||||||
date="27 августа 2023"
|
|
||||||
title="Свободные альтернативы популярным сервисам"
|
|
||||||
href="/notes/self-hosting/"
|
|
||||||
/>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.note {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.dash {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.note {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.dash {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
54
src/pages/notes/[...slug].astro
Normal file
54
src/pages/notes/[...slug].astro
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
import Layout from '../../layouts/Layout.astro'
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const blogEntries = await getCollection('notes')
|
||||||
|
return blogEntries.map(entry => ({
|
||||||
|
params: { slug: entry.slug },
|
||||||
|
props: { entry },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
const { entry } = Astro.props
|
||||||
|
const { Content } = await entry.render()
|
||||||
|
const formatDate = (date: Date) => {
|
||||||
|
return date.toLocaleDateString("ru", {year: "numeric", month: "long", day: "numeric"})
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={entry.data.title} description={entry.data.description}>
|
||||||
|
<h1>{entry.data.title}</h1>
|
||||||
|
<div class="metadata">
|
||||||
|
<p>Дата создания: { formatDate(entry.data.pubDate) }</p>
|
||||||
|
{ entry.data.updatedAt !== undefined && entry.data.updatedAt !== entry.data.pubDate && (
|
||||||
|
<p>Последнее обновление: { formatDate(entry.data.updatedAt) }</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<Content />
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.metadata {
|
||||||
|
color: #aaa;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
.metadata p {
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #eee;
|
||||||
|
padding: 6px 10px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,123 +0,0 @@
|
||||||
---
|
|
||||||
import Layout from '../../layouts/Layout.astro'
|
|
||||||
import NoteMetadata from '../../components/NoteMetadata.astro'
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title="Беспечная Гляденовская гора">
|
|
||||||
<h1>Беспечная Гляденовская гора</h1>
|
|
||||||
|
|
||||||
<NoteMetadata createdAt="16 октября 2023" updatedAt="16 октября 2023" />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Гляденовская гора - это красивый лес в Перми, за которым прячется деревянная часовня.
|
|
||||||
Здесь не будет рассказов про историю горы, ведь я не являюсь ни историком, ни археологом,
|
|
||||||
оставлю это занятие более компетентным людям.
|
|
||||||
Я всего лишь хочу показать вам это место от лица обывателя,
|
|
||||||
и, может быть, это сподвигнет вас отправиться когда-нибудь в небольшое путешествие.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/carefree-mountain/1.webp"
|
|
||||||
alt="Фотография поля с видом на пермский аэропорт"
|
|
||||||
class="wideImg"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p>
|
|
||||||
Гляденовская гора находится недалеко от пермского аэропорта.
|
|
||||||
Если до него самого добраться не составит большого труда, то дальше придётся идти вдоль дороги, хоть и совсем недолго.
|
|
||||||
Вскоре вы зайдете в лес, тогда идти станет проще и интереснее.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Теперь, когда мы наконец-то в лесу, где нет проезжающих мимо машин, можно расслабиться.
|
|
||||||
Дальнейший путь представляет из себя череду деревянных ступенек.
|
|
||||||
Спускаться по ним довольно легко, но ещё проще подскользнуться.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<div class="firstPhotoGroup">
|
|
||||||
<div>
|
|
||||||
<img
|
|
||||||
src="/carefree-mountain/2.webp"
|
|
||||||
alt="Деревянные ступеньки в лесу"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img
|
|
||||||
src="/carefree-mountain/3.webp"
|
|
||||||
alt="Белочка"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img
|
|
||||||
src="/carefree-mountain/4.webp"
|
|
||||||
alt="Деревянные ступеньки в лесу"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
В конце пути нас ожидает деревянная церковь.
|
|
||||||
Теперь можно неспеша осмотреться вокруг.
|
|
||||||
В таких местах почти ничего не просиходит, внешнего мира как будто не существует.
|
|
||||||
Он остался там, за горой, здесь же царит тишина и спокойствие.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/carefree-mountain/5.webp"
|
|
||||||
alt="Деревянная церковь в лесу"
|
|
||||||
class="wideImg"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p><i>Удивительное рядом.</i></p>
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.wideImg {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firstPhotoGroup {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
grid-template-rows: 450px 310px;
|
|
||||||
grid-template-areas:
|
|
||||||
"first first"
|
|
||||||
"second third";
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
|
||||||
.firstPhotoGroup {
|
|
||||||
grid-template-rows: 450px 450px 450px;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"first"
|
|
||||||
"second"
|
|
||||||
"third";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.firstPhotoGroup > div {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firstPhotoGroup > div > img {
|
|
||||||
object-fit: cover;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firstPhotoGroup > div:nth-child(1) {
|
|
||||||
grid-area: first;
|
|
||||||
}
|
|
||||||
.firstPhotoGroup > div:nth-child(2) {
|
|
||||||
grid-area: second;
|
|
||||||
}
|
|
||||||
.firstPhotoGroup > div:nth-child(3) {
|
|
||||||
grid-area: third;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,258 +0,0 @@
|
||||||
---
|
|
||||||
import Layout from '../../layouts/Layout.astro'
|
|
||||||
import NoteMetadata from '../../components/NoteMetadata.astro'
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title="Свободные альтернативы популярным сервисам">
|
|
||||||
<h1>Свободные альтернативы популярным сервисам</h1>
|
|
||||||
|
|
||||||
<NoteMetadata createdAt="27 августа 2023" updatedAt="1 октября 2023" />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Это статья для тех, кто никогда не слышал про альтернативы современным социальным сетям и сервисам.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Мы стали слишком сильно полагаться на централизованные сервисы, такие как vk, youtube, telegram или twitter.
|
|
||||||
Если у вас начали появляться претензии, будь то цензура, отсутствие нужных функций или
|
|
||||||
пренебрежительное отношение к личным данным, я предлагаю вам обратить внимание на альтернативы,
|
|
||||||
которые вы можете запустить на своем сервере.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Хотя, строго говоря, иметь свой сервер вовсе не обязательно,
|
|
||||||
но в таком случае вы должны доверять владельцу сервера, ведь именно он будет хранить ваши данные.
|
|
||||||
Это не особо касается социальных сетей без личных сообщений, там всё и так публично.
|
|
||||||
Мессенджеры, поддерживающие шифрование, защищают вас от лишних глаз, можете без опасений выбирать публичный сервер.
|
|
||||||
А вот хранить файлы у незнакомцев я бы не стал.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Социальные сети - Fediverse</h2>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/selfhosted/fediverse-party.webp"
|
|
||||||
alt="Скриншот fediverse.party"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p class="attribution">Скриншот <a href="https://fediverse.party" target="_blank">fediverse.party</a>.</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Fediverse - это группа из нескольких социальных сетей, представляющие аналоги популярным сервисам.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>Оригинальный сервис</th>
|
|
||||||
<th>Альтернативы</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Twitter</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://joinmastodon.org/" target="_blank">Mastodon</a>,
|
|
||||||
<a href="https://misskey-hub.net/en/" target="_blank">misskey</a> и
|
|
||||||
<a href="https://pleroma.social/" target="_blank">pleroma</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Vk, facebook</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://friendi.ca/" target="_blank">Friendica</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Instagram</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://pixelfed.org/" target="_blank">Pixelfed</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Reddit</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://join-lemmy.org/" target="_blank">Lemmy</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>YouTube</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://joinpeertube.org/" target="_blank">Peertube</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Soundcloud</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://funkwhale.audio/" target="_blank">Funkwhale</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Создать свой сервер может любой желающий, и его пользователи смогут общаться с пользователями на других серверах.
|
|
||||||
Зачастую можно общаться даже с пользователями других платформ.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Если вы ищете простое место для старта, рекомендую обратить внимание на mastodon.
|
|
||||||
Выберите сервер, на котором вы хотите зарегистрироваться,
|
|
||||||
в этом вам может помочь <a href="https://ru.index.community/communities" target="_blank">каталог русскоязычных серверов</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Вот парочка советов:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Ознакомтесь с правилами сервера. На разных серверах модераторы могут запрещать разные вещи.</li>
|
|
||||||
<li>Не регистрируйтесь на больших серверах. Вы не получите от этого особых плюсов, а лишь усилите централизацию.</li>
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
У меня есть <a href="https://m.comfycamp.space" target="_blank">свой сервер mastodon</a>, жду вас в гости!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Мессенджеры - Matrix, XMPP</h2>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/selfhosted/matrix.webp"
|
|
||||||
alt="Скриншот matirx.org"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p class="attribution">Скриншот <a href="https://matrix.org/" target="_blank">matrix.org</a>.</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
В мире децентрализованного общения сейчас популярны 2 протокола: xmpp (ранее jabber) и matrix.
|
|
||||||
Идея такая же, как и в случае с fediverse: любой желающий может поднять свой сервер, а пользователи разных серверов могут общаться между собой.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
По сравнению с другими платформами, например telegram или whatsapp,
|
|
||||||
вы получаете end-to-end шифрование на всех устройствах и множество клиентов с открытым исходным кодом,
|
|
||||||
а для регистрации не нужно указывать номер телефона.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Какой из них вам понравится больше - сказать тяжело. Попробуйте оба.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Облако - Nextcloud</h2>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/selfhosted/nextcloud.webp"
|
|
||||||
alt="Скриншот менеджера файлов в nextcloud"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://nextcloud.com/" target="_blank">Nextcloud</a> - это больше, чем просто облако.
|
|
||||||
Это и хранилище файлов, и календарь, и задачи, и контакты, и ещё много всего.
|
|
||||||
Своим функционалом nextcloud способен заменить целые экосистемы.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
При желании к nextcloud можно подключить офисный редакторор, например onlyoffice, тогда nextcloud превращается ещё и в альтернативу Google Docs.
|
|
||||||
Это может быть очень кстати для разных компаний.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Список контактов, календари и задачи можно синхронизировать между своими устройствами.
|
|
||||||
Для этого используются обычные протоколы сaldav и carddav.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Стриминг - Jellyfin</h2>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/selfhosted/jellyfin.webp"
|
|
||||||
alt="Скриншот jellyfin с открытой страницей фильма Taxi Driver"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="https://jellyfin.org/" target="_blank">Jellyfin</a> - это ваш личный стриминговый сервис.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Вы просто указываете путь до вашей медиатеки и получаете возможность смотреть и слушать её онлайн.
|
|
||||||
Jellyfin поддерживает фильмы, сериалы, музыку, аудиокниги и комиксы.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Jellyfin может перекодировать файлы на лету, если посчитает, что ваше устройство не поддерживает исходный формат.
|
|
||||||
Это зачастую необходимо для браузеров, так как они могут воспроизодить только самые простые форматы.
|
|
||||||
Если вы хотите снизить нагрузку на сервер, можно найти клиенты, позволяющие транслировать видео напрямую в ваш плеер
|
|
||||||
(см. <a href="https://github.com/jellyfin/jellyfin-mpv-shim" target="_blank">jellyfin-mpv-shim</a>).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Jellyfin поддерживает DLNA, а это значит, что в пару кликов можно включить любой фильм на телевизоре, который находится в той же сети, что и сервер.
|
|
||||||
А ещё можно организовывать комнаты для просмотра и синхронизировать воспроизведение на нескольких устройствах, если вы хотите посмотреть
|
|
||||||
что-нибудь в компании.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Jellyfin - это не обязательно синоним пиратства.
|
|
||||||
Вы можете стримить легально приобретенный контент, если у вас есть такое желание.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Фото и видео - Photoprism</h2>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/selfhosted/photoprism.webp"
|
|
||||||
alt="Скриншот photoprism, на котором видно несколько фотографий"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Многие пользуются сервисами от Apple или Google, чтобы хранить личные фотографии и видео.
|
|
||||||
Если вам становится некомфортно от мысли, что компании, владеющие рекламными сетями,
|
|
||||||
имеют доступ к вашим фотографиям, можно обратиться к <a href="https://www.photoprism.app/" target="_blank">Photoprism</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Photoprism позволяет легко просматривать фото в браузере, редактировать метатеги,
|
|
||||||
и даже умеет распознавать объекты на фото (хотя, честно говоря, эта функция работает не идеально).
|
|
||||||
Вы можете создавать альбомы и делиться ими с другими людьми.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Загружать фото можно через веб-интерфейс, импортировать с директории на вашем сервере или же
|
|
||||||
загружать их по протоколу webdav с того же nextcloud.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Photoprism умеет конвертировать фотографии формата raw, чтобы их можно было открыть в браузере.
|
|
||||||
Также вы без проблем можете загрузить свои видео, они при необходимости будут сконвертированы.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Вместо заключения - Awesome Selfhosted</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Один из самых популярных репозиториев на Github: <a href="https://github.com/awesome-selfhosted/awesome-selfhosted" target="_blank">Awesome Selfhosted</a>.
|
|
||||||
Это большой список всевозможных сервисов, которые вы можете запустить на своем сервере.
|
|
||||||
В этой статье я не покрыл и 10% доступных вариантов. Однако, надеюсь, что я смог хотя бы приоткрыть дверь в эту кроличью нору.
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attribution {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-style: italic;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
table, td, th {
|
|
||||||
border: 1px solid #676767;
|
|
||||||
}
|
|
||||||
|
|
||||||
td, th {
|
|
||||||
padding: 6px 8px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,89 +0,0 @@
|
||||||
---
|
|
||||||
import Layout from '../../layouts/Layout.astro'
|
|
||||||
import NoteMetadata from '../../components/NoteMetadata.astro'
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout title="Мыс Стрелка">
|
|
||||||
<h1>Мыс Стрелка</h1>
|
|
||||||
|
|
||||||
<NoteMetadata createdAt="11 ноября 2023" updatedAt="11 ноября 2023" />
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<i>Некоторые вещи стоят того, чтобы встать в 6 утра в воскресенье.</i>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Куда мы едем?</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Мыс Стрелка - это скала, у которой соединяются 2 реки: Кама и Чусовая.
|
|
||||||
Находится она недалеко от города, добраться до ближайших деревень можно на электричке,
|
|
||||||
а дальше нужно пару километров пройти пешком.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Точную дорогу мы заранее не посмотрели и пришли не на скалу, а к её основанию.
|
|
||||||
Подняться, как оказалось, можно и у самой скалы, в самом тяжёлом месте есть верёвка.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/strelka/1.jpg"
|
|
||||||
alt="Вершина скалы"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<img
|
|
||||||
src="/strelka/2.jpg"
|
|
||||||
alt="Вид с мыса Стрелка"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="/strelka/3.jpg"
|
|
||||||
alt="Вид с мыса Стрелка"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
На вершине скалы довольно ветрено, но красиво.
|
|
||||||
Совсем рядом находятся макушки деревьев, а дальше только вода.
|
|
||||||
<p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Спустившись буквально на пару шагов можно укрыться от ветра и отдохнуть.
|
|
||||||
Если вы оказались здесь осенью, то чай будет очень кстати.
|
|
||||||
</p>
|
|
||||||
<img
|
|
||||||
src="/strelka/4.jpg"
|
|
||||||
alt="Пьем чай на скале"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<h2>Путь обратно</h2>
|
|
||||||
<p>
|
|
||||||
У нас оставалось несколько часов до электрички, поэтому мы отправились изучать ближайшие деревни.
|
|
||||||
Вроде бы мы находились совсем недалеко от города, но атмосфера уже другая.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src="/strelka/5.jpg"
|
|
||||||
alt="Железная дорога в деревне"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Наши похождения закончились довольно быстро, но на станции можно спокойно дождаться электрички.
|
|
||||||
В итоге получилось короткое, но запоминающееся путешествие.
|
|
||||||
</p>
|
|
||||||
</Layout>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
gap: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
|
||||||
.row {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
23
src/pages/rss.xml.ts
Normal file
23
src/pages/rss.xml.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import type { APIContext } from 'astro'
|
||||||
|
import rss from '@astrojs/rss'
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
|
||||||
|
export async function GET(context: APIContext) {
|
||||||
|
const notes = await getCollection('notes')
|
||||||
|
notes.sort((a, b) => {
|
||||||
|
if (a.data.pubDate < b.data.pubDate) return 1
|
||||||
|
if (a.data.pubDate > b.data.pubDate) return -1
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
return rss({
|
||||||
|
title: 'Уютный домик',
|
||||||
|
description: 'Заметки с сайта comfycamp.space',
|
||||||
|
site: context.site || "https://comfycamp.space",
|
||||||
|
items: notes.map((note) => ({
|
||||||
|
title: note.data.title,
|
||||||
|
pubDate: note.data.pubDate,
|
||||||
|
description: note.data.description,
|
||||||
|
link: `/notes/${note.slug}/`,
|
||||||
|
})),
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue