133 lines
4.8 KiB
Go
133 lines
4.8 KiB
Go
// NNM-Club torrent filess mass downloader
|
||
// Created for Uploaders group
|
||
// Copyright (c) 2012-2020 Vladimir "fat0troll" Hodakov
|
||
|
||
package fetcherv1
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"strconv"
|
||
"time"
|
||
|
||
"github.com/anacrolix/torrent/metainfo"
|
||
"github.com/dustin/go-humanize"
|
||
"github.com/kennygrant/sanitize"
|
||
)
|
||
|
||
func createOutputDir(prefix string, forumID int) {
|
||
path, _ := filepath.Abs(filepath.Join(prefix, strconv.Itoa(forumID)))
|
||
if err := os.Mkdir(path, os.ModePerm); err != nil {
|
||
dlog.Fatal().Str("путь создания", path).Err(err).Msg("Невозможно создать поддиректорию для торрент-файлов")
|
||
}
|
||
|
||
outputDirPath = path
|
||
}
|
||
|
||
func download(topic *forumTopic) {
|
||
forumTopicInProgress++
|
||
|
||
dlog.Info().Str("название топика", topic.Name).Int("количество топиков", len(forumTopics)).
|
||
Int("номер топика", forumTopicInProgress).Msg("Скачивается топик")
|
||
|
||
fileName, err := downloadFile(topic.Link, true)
|
||
if err != nil {
|
||
dlog.Error().Err(err).Str("название топика", topic.Name).Msg("Не удалось загрузить страницу топика. Пропуск")
|
||
return
|
||
}
|
||
|
||
querier, err := obtainQuerier(fileName)
|
||
if err != nil {
|
||
dlog.Error().Err(err).Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Не удалось получить обработчик для страницы топика. Пропуск")
|
||
return
|
||
}
|
||
|
||
lastModified := getLastModeratedDate(querier)
|
||
if lastModified == "" {
|
||
dlog.Warn().Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Топик не проверен модератором. Пропуск")
|
||
return
|
||
}
|
||
|
||
downloadLink := getDownloadLink(querier)
|
||
if downloadLink == "" {
|
||
dlog.Warn().Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Не найдена ссылка для скачивания торрента. Пропуск")
|
||
return
|
||
}
|
||
|
||
tempF, err := downloadFile("https://"+c.Config.URL+"/forum/"+downloadLink, false)
|
||
if err != nil {
|
||
dlog.Warn().Err(err).Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Не удалось скачать торрент-файл через несколько попыток. Пропуск")
|
||
return
|
||
}
|
||
|
||
result := outputDirPath + "/" + lastModified + "-" + sanitize.BaseName(topic.Name) + ".torrent"
|
||
|
||
err = moveFile(tempF, result)
|
||
if err != nil {
|
||
dlog.Warn().Err(err).Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Не удалось сохранить торрент-файл. Пропуск")
|
||
return
|
||
}
|
||
|
||
f, _ := os.Open(result)
|
||
defer f.Close()
|
||
|
||
// Check downloaded torrent and get some metadata
|
||
metadata, err := metainfo.Load(f)
|
||
if err != nil {
|
||
dlog.Warn().Err(err).Str("название топика", topic.Name).Str("ссылка на топик", topic.Link).
|
||
Msg("Скачанный файл не является торрент-файлом. Пропуск")
|
||
return
|
||
}
|
||
|
||
unmarshalledMetadata, _ := metadata.UnmarshalInfo()
|
||
totalLength += unmarshalledMetadata.TotalLength()
|
||
}
|
||
|
||
func fetch(forumID int) {
|
||
startPage := "https://" + c.Config.URL + "/forum/viewforum.php?f=" + strconv.Itoa(forumID)
|
||
|
||
time.Sleep(5 * time.Second)
|
||
|
||
startPageFile, err := downloadFile(startPage, true)
|
||
if err != nil {
|
||
dlog.Error().Err(err).Msg("Не удалось получить данные с форума")
|
||
}
|
||
|
||
if uberDebug {
|
||
dlog.Info().Str("имя файла", startPageFile).Msg("Получена стартовая страница форума")
|
||
}
|
||
|
||
err = setQuerier(startPageFile, "forumPage", 1)
|
||
if err != nil {
|
||
dlog.Fatal().Err(err).Msg("Не удалось создать обработчик для страницы")
|
||
}
|
||
|
||
dlog.Info().Str("название форума", getForumName(forumPages[1])).Msg("Определён форум для загрузки")
|
||
|
||
getNavigation(forumPages[1])
|
||
|
||
downloadAdditionalPages()
|
||
|
||
for _, forumPage := range forumPages {
|
||
getTopics(forumPage)
|
||
}
|
||
|
||
dlog.Info().Int("топиков для скачивания", len(forumTopics)).Msg("Определены все топики для скачивания")
|
||
|
||
for _, forumTopic := range forumTopics {
|
||
download(forumTopic)
|
||
}
|
||
}
|
||
|
||
func printStats() {
|
||
dlog.Info().Int("топиков обработано", len(forumTopics)).
|
||
Str("объём раздела при полном скачивании", humanize.Bytes(uint64(totalLength))).
|
||
Str("директория с торрент-файлами", outputDirPath).
|
||
Msg("Работа завершена успешно. Загруженные торрент-файлы расположены в директории, указанной при старте.")
|
||
}
|