1

Add fetcher, support for downloading forum pages

This commit is contained in:
2019-09-28 19:59:02 +04:00
parent 52fad7cf47
commit a504299150
11 changed files with 260 additions and 15 deletions

View File

@@ -0,0 +1,62 @@
// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
package fetcherv1
import (
"net/http"
"github.com/PuerkitoBio/goquery"
"github.com/rs/zerolog"
"gitlab.com/pztrn/flagger"
"gitlab.com/fat0troll/uploader_tools/internal/context"
)
var (
c *context.Context
dclient http.Client
dlog zerolog.Logger
forumPages map[int]*goquery.Document
forumPagesLinks map[string]string
uberDebug bool
)
// New initializes package
func New(cc *context.Context) {
c = cc
dlog = c.Logger.With().Str("модуль", "fetcher").Int("версия", 1).Logger()
_ = c.Flagger.AddFlag(&flagger.Flag{
Name: "forum",
Description: "Номер форума, торренты с которого нужно скачать",
Type: "int",
DefaultValue: 0,
})
_ = c.Flagger.AddFlag(&flagger.Flag{
Name: "fetcherDebug",
Description: "Запустить модуль fetcher в дебаг-режиме",
Type: "bool",
DefaultValue: false,
})
forumPages = make(map[int]*goquery.Document)
forumPagesLinks = make(map[string]string)
dlog.Info().Msg("Модуль инициализирован")
}
// Process handles authorization
func Process() {
uberDebug, _ = c.Flagger.GetBoolValue("fetcherDebug")
forumID, _ := c.Flagger.GetIntValue("forum")
if forumID == 0 {
dlog.Fatal().Msg("Номер форума не указан. Используйте ключ -forum XXX, чтобы указать номер форума")
}
dlog.Info().Int("forum ID", forumID).Msg("Получен ID форума, начинаем работу...")
fetch(forumID)
}

View File

@@ -0,0 +1,33 @@
// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
package fetcherv1
import (
"strconv"
)
func fetch(forumID int) {
startPage := "https://" + c.Config.URL + "/forum/viewforum.php?f=" + strconv.Itoa(forumID)
startPageFile, err := dumpForumPage(startPage)
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()
}

View File

@@ -0,0 +1,39 @@
// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
package fetcherv1
import (
"strings"
"github.com/PuerkitoBio/goquery"
)
// checkLoginness checks if downloaded page belongs to user
func checkLoginness(querier *goquery.Document) bool {
authorized := false
querier.Find(".mainmenu").Each(func(i int, sel *goquery.Selection) {
if strings.Contains(sel.Text(), "Выход") {
if strings.Contains(sel.Text(), c.Config.Username) {
authorized = true
}
}
})
return authorized
}
func getForumName(querier *goquery.Document) string {
return querier.Find("h1").First().Text()
}
func getNavigation(querier *goquery.Document) {
querier.Find("td[align=right] .nav a").Each(func(i int, sel *goquery.Selection) {
if !strings.Contains(sel.Text(), "След") {
href, _ := sel.Attr("href")
forumPagesLinks[sel.Text()] = href
}
})
dlog.Info().Int("количество страниц", len(forumPagesLinks)+1).Msg("Определено количество страниц")
}

View File

@@ -0,0 +1,37 @@
// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
package fetcherv1
import (
"errors"
"os"
"github.com/PuerkitoBio/goquery"
)
func setQuerier(pageFile string, pageType string, page int) error {
f, err := os.Open(pageFile)
if err != nil {
return err
}
defer f.Close()
querier, err := goquery.NewDocumentFromReader(f)
if err != nil {
return err
}
switch pageType {
case "forumPage":
if !checkLoginness(querier) {
return errors.New("получена анонимная страница")
}
forumPages[page] = querier
default:
return errors.New("неизвестный тип страницы")
}
return nil
}

View File

@@ -0,0 +1,58 @@
// NNM-Club torrent filess mass downloader
// Created for Uploaders group
// Copyright (c) 2012-2019 Vladimir "fat0troll" Hodakov
package fetcherv1
import (
"io"
"io/ioutil"
"net/http"
"strconv"
"golang.org/x/text/encoding/charmap"
"golang.org/x/text/transform"
)
func downloadAdditionalPages() {
for i := range forumPagesLinks {
forumPage, _ := strconv.Atoi(i)
dlog.Info().Int("номер страницы", forumPage).Msg("Скачивается ещё одна страница форума")
pageFile, err := dumpForumPage("https://" + c.Config.URL + "/forum/" + forumPagesLinks[i])
if err != nil {
dlog.Fatal().Err(err).Msg("Не удалось загрузить страницу форума")
}
_ = setQuerier(pageFile, "forumPage", forumPage)
}
}
func dumpForumPage(url string) (string, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return "", err
}
for i := range c.Cookies {
req.AddCookie(c.Cookies[i])
}
resp, err := dclient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
tempF, err := ioutil.TempFile("", "massdl-*")
if err != nil {
return "", err
}
defer tempF.Close()
respInUTF8 := transform.NewReader(resp.Body, charmap.Windows1251.NewDecoder())
_, err = io.Copy(tempF, respInUTF8)
if err != nil {
return "", err
}
return tempF.Name(), nil
}