2019-09-28 19:59:02 +04:00
|
|
|
|
// NNM-Club torrent filess mass downloader
|
|
|
|
|
// Created for Uploaders group
|
|
|
|
|
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
|
|
|
|
|
|
|
|
|
|
package fetcherv1
|
|
|
|
|
|
|
|
|
|
import (
|
2019-09-28 22:51:10 +04:00
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2019-09-28 19:59:02 +04:00
|
|
|
|
"strconv"
|
2019-09-28 20:20:23 +04:00
|
|
|
|
"time"
|
2019-09-28 22:51:10 +04:00
|
|
|
|
|
|
|
|
|
"github.com/anacrolix/torrent/metainfo"
|
|
|
|
|
"github.com/dustin/go-humanize"
|
|
|
|
|
"github.com/kennygrant/sanitize"
|
2019-09-28 19:59:02 +04:00
|
|
|
|
)
|
|
|
|
|
|
2019-09-28 22:51:10 +04:00
|
|
|
|
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 = os.Rename(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()
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-28 19:59:02 +04:00
|
|
|
|
func fetch(forumID int) {
|
|
|
|
|
startPage := "https://" + c.Config.URL + "/forum/viewforum.php?f=" + strconv.Itoa(forumID)
|
|
|
|
|
|
2019-09-28 20:20:23 +04:00
|
|
|
|
time.Sleep(5 * time.Second)
|
|
|
|
|
|
2019-09-28 22:51:10 +04:00
|
|
|
|
startPageFile, err := downloadFile(startPage, true)
|
2019-09-28 19:59:02 +04:00
|
|
|
|
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()
|
2019-09-28 22:51:10 +04:00
|
|
|
|
|
|
|
|
|
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("Работа завершена успешно. Загруженные торрент-файлы расположены в директории, указанной при старте.")
|
2019-09-28 19:59:02 +04:00
|
|
|
|
}
|