1
uploader_tools/internal/services/fetcher/fetcher.go

132 lines
4.8 KiB
Go
Raw Normal View History

// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2020 Vladimir "fat0troll" Hodakov
package fetcher
import (
"fmt"
"os"
"path/filepath"
"strconv"
2019-09-28 20:20:23 +04:00
"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("Скачивается топик")
2020-02-22 18:33:33 +04:00
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 := fmt.Sprintf("https://%s/forum/viewforum.php?f=%d", c.Config.URL, forumID)
2019-09-28 20:20:23 +04:00
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("Определён форум для загрузки")
downloadAdditionalPages(forumID)
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("Работа завершена успешно. Загруженные торрент-файлы расположены в директории, указанной при старте.")
}