Я недавно обнаружил, что пишу в твиттер десять лет с перерывами.
Подумал и решил их переложить на свой сайт, а там уже разобраться, что оставлять, что удалять.
Для этого пришлось выкачать архив Твиттера, открыть в нём tweet.js и исправить этот файл на JSON (удалив начало). В итоге в нём получается массив из твитов, с которыми можно делать что угодно.
Вот так выглядит один твит:
{
"retweeted" : false,
"source" : "<a href=\"https://tapbots.com/software/tweetbot/mac\" rel=\"nofollow\">Tweetbot for Mac</a>",
"entities" : {
"hashtags" : [ ],
"symbols" : [ ],
"user_mentions" : [ ],
"urls" : [ ]
},
"display_text_range" : [ "0", "140" ],
"favorite_count" : "11",
"id_str" : "924968941260242944",
"truncated" : false,
"retweet_count" : "1",
"id" : "924968941260242944",
"created_at" : "Mon Oct 30 11:59:15 +0000 2017",
"favorited" : false,
"full_text" : "Подходит математик к трём логикам:\n— Что, все пойдём бухать?\n— Не знаю, — говорит первый\n— Не знаю, — говорит второй\n— Да! — говорит третий.",
"lang" : "ru"
}
Я решил сконвертировать каждый твит в заметку, оставив ссылку на твиттер, но не конвертируя лайки/ретвиты. Получился вот такой несложный скрипт на джаваскрипте:
// всякие зависимости
const exec = require('child_process').execSync
const mkdirp = (path) => { exec('mkdir -p ' + path) }
const fs = require('fs')
// достаю интересующие меня части твита
function tweet2note(tweet) {
let date = new Date(tweet.created_at)
// путь к файлу: 2019/12/17/id_твита/index.md
let path = date.toISOString()
.split('T')[0] // 2019-12-17
.replace(/-/g, '/') +
'/' + tweet.id_str
let note = {
text: tweet.full_text,
meta: {
lang: tweet.lang,
publishing_software: tweet.source,
date: date.toISOString(),
syndicated: {
twitter: `https://twitter.com/marinintim/status/${tweet.id_str}`
},
},
path: path,
}
if (tweet.entities && tweet.entities.media) {
for (let m of tweet.entities.media) {
if (m.type === 'photo') {
// пока что просто вставляю <img> с src твиттера
note.text += `
<img src="${m.media_url_https}" />`
}
}
}
if (tweet.in_reply_to_status_id_str) {
// добавляю ссылку на твит, на который отвечаю
note.meta.in_reply_to = `https://twitter.com/_/status/${tweet.in_reply_to_status_id_str}`
note.meta.in_reply_to_text = 'твит @' + tweet.in_reply_to_screen_name
}
return note
}
// преобразую в текст файла index.md, который 11ty превратит в HTML.
function note2file(note) {
const meta = note.meta
return `---
layout: note.njk
tags:
- note
- twitter_pesos
lang: ${meta.lang}
author: Тим
date: ${meta.date}
syndicated:
twitter: ${meta.syndicated.twitter}
publishing_software: '${meta.publishing_software}'
${
meta.in_reply_to
? `in_reply_to: "${meta.in_reply_to}"
in_reply_to_text: "${meta.in_reply_to_text}"`
: ''}
---
${note.text}
`
}
console.log(`Total tweets: ${tweets.length}`)
let i = 0;
for (let tweet of tweets) {
let note = tweet2note(tweet)
mkdirp(note.path)
// делаю синхронно, потому что иначе нода умирала,
// а разбираться почему было лень
fs.writeFileSync(note.path + '/index.md', note2file(note))
console.log(`[${++i} / ${tweets.length}] ${note.path + '/index.md'}`)
}
В итоге оказалось, что твитов в том архиве было больше восьми тысяч, и 11ty начал несколько захлёбываться, пытаясь их засунуть на одну страницу и сделать авто-линковку.
Oh well. Пока что добавил большую часть из них в .eleventyignore
,
но потом непременно включу в общий сайт. На /notes пока отрисовываются 100 последних заметок, в будущем я добавлю архивы
по месяцам.
В результате работы скрипта я получил восемь тысяч файлов, вот пример одного из них:
---
layout: note.njk
tags:
- note
- twitter_pesos
lang: en
author: Тим
date: 2018-01-10T17:59:56.000Z
syndicated:
twitter: https://twitter.com/marinintim/status/951151635073519616
publishing_software: '<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>'
---
[AT THE THINGS-NAMING FACILITY BACK IN THE DAY]
*looks at the paper with an article about man biting the dog*
- Is it about something new? Let's call it news. *stamp* Next!
*looks at the strip of photos w/ jumping horse*
- Pictures are moving? Let's call it movies. *stamp* Next!
И вот пример вёрстки, которая получается в итоге:
<article class="h-entry">
<span class="u-author h-card">
<img class="avatar u-photo" src="https://marinintim.fra1.digitaloceanspaces.com/tim_and_green.jpg" alt="">
<a class="u-url h-card" href="https://marinintim.com">Тим</a>
</span>
·
<a href="/notes/2018/01/10/951151635073519616/" class="u-url">
<time datetime="2018-01-10T17:59:56.000Z">10 января</time>
</a>
<div class="e-content p-name">
<p>[AT THE THINGS-NAMING FACILITY BACK IN THE DAY]
<em>looks at the paper with an article about man biting the dog</em></p>
<ul>
<li>Is it about something new? Let's call it news. <em>stamp</em> Next!</li>
</ul>
<p><em>looks at the strip of photos w/ jumping horse</em></p>
<ul>
<li>Pictures are moving? Let's call it movies. <em>stamp</em> Next!</li>
</ul>
</div>
Эта же заметка <a class="u-syndication" href="https://twitter.com/marinintim/status/951151635073519616">в твиттере</a>
</article>
В архиве также есть папка tweet_media
, где лежат
все загруженные картинки, и их можно сопоставить с твитами
по айдишнику.
Примерно по этому же принципу можно сохранить свои посты из любой соцсети:
- Раздобыть архив или сохранить через API все посты
- Написать скрипт, который переделает архив в контент сайта
- Шага три нет. Хотя нет, можно переписать скрипт из шага 2 ещё раз.
На днях я собираюсь утащить свои посты из ВК, о чём напишу на индивеб-вики/VK.
Если всё ещё кажется, что «мне нечего писать на своём сайте», то попробуй импортировать свой твиттер или инстаграм и обнаружишь, что тебе есть, что сказать или показать миру: так почему бы не со своего сайта?
Пока я не собираюсь удалять свой твиттер-аккаунт, но бэкапы — это всегда хорошо, а когда они ещё и доступны для просмотра — ещё лучше.