diff --git a/.golangci.yaml b/.golangci.yaml index 4dfeeda..94f1a03 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -5,7 +5,7 @@ linters: disable: - gochecknoglobals - funlen - - wsl + - gomnd linters-settings: lll: line-length: 120 @@ -17,4 +17,4 @@ issues: - dupl - linters: - wsl - text: "declarations should never be cuddled" \ No newline at end of file + text: "declarations should never be cuddled" diff --git a/domains/fetcher/v1/exported.go b/domains/fetcher/v1/exported.go index f81bb99..acb1875 100644 --- a/domains/fetcher/v1/exported.go +++ b/domains/fetcher/v1/exported.go @@ -64,9 +64,11 @@ func New(cc *context.Context) { func Process() { uberDebug, _ = c.Flagger.GetBoolValue("fetcherDebug") forumID, _ := c.Flagger.GetIntValue("forum") + if forumID == 0 { dlog.Fatal().Msg("Номер форума не указан. Используйте ключ -forum XXX, чтобы указать номер форума") } + outputDirPathPrefix, _ := c.Flagger.GetStringValue("outputDir") dlog.Info().Int("forum ID", forumID).Msg("Получен ID форума, начинаем работу...") diff --git a/domains/fetcher/v1/fetcher.go b/domains/fetcher/v1/fetcher.go index bc89cfa..b25a66c 100644 --- a/domains/fetcher/v1/fetcher.go +++ b/domains/fetcher/v1/fetcher.go @@ -29,6 +29,7 @@ func download(topic *forumTopic) { 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("Не удалось загрузить страницу топика. Пропуск") diff --git a/domains/fetcher/v1/mover.go b/domains/fetcher/v1/mover.go index 13b5cba..bd17ef3 100644 --- a/domains/fetcher/v1/mover.go +++ b/domains/fetcher/v1/mover.go @@ -22,21 +22,26 @@ func moveFile(sourcePath, destPath string) error { if err != nil { return fmt.Errorf("couldn't open source file: %s", err) } + outputFile, err := os.Create(destPath) if err != nil { inputFile.Close() return fmt.Errorf("couldn't open destination file: %s", err) } defer outputFile.Close() + _, err = io.Copy(outputFile, inputFile) inputFile.Close() + if err != nil { return fmt.Errorf("writing to output file failed: %s", err) } + // The copy was successful, so now delete the original file err = os.Remove(sourcePath) if err != nil { return fmt.Errorf("failed removing original file: %s", err) } + return nil } diff --git a/domains/fetcher/v1/parser.go b/domains/fetcher/v1/parser.go index 6ec3f51..562b500 100644 --- a/domains/fetcher/v1/parser.go +++ b/domains/fetcher/v1/parser.go @@ -32,6 +32,7 @@ var ( // 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) { @@ -39,11 +40,13 @@ func checkLoginness(querier *goquery.Document) bool { } } }) + return authorized } func getDownloadLink(querier *goquery.Document) string { var downloadLink string + querier.Find("a[rel=nofollow]").Each(func(i int, sel *goquery.Selection) { if strings.Contains(sel.Text(), "Скачать") { href, _ := sel.Attr("href") @@ -61,7 +64,9 @@ func getForumName(querier *goquery.Document) string { func getLastModeratedDate(querier *goquery.Document) string { var dateValue time.Time var err error + haveDate := false + querier.Find("table.btTbl td.genmed").Each(func(i int, sel *goquery.Selection) { if strings.Contains(sel.Text(), "модератором") { date := strings.TrimPrefix(sel.Text(), " Оформление проверено модератором ") diff --git a/domains/fetcher/v1/querier.go b/domains/fetcher/v1/querier.go index a2feb1c..6bf1b30 100644 --- a/domains/fetcher/v1/querier.go +++ b/domains/fetcher/v1/querier.go @@ -37,7 +37,9 @@ func setQuerier(pageFile string, pageType string, page int) error { if !checkLoginness(querier) { return errors.New("получена анонимная страница") } + forumPages[page] = querier + default: return errors.New("неизвестный тип страницы") } diff --git a/domains/fetcher/v1/request.go b/domains/fetcher/v1/request.go index bbddf56..8bd18a4 100644 --- a/domains/fetcher/v1/request.go +++ b/domains/fetcher/v1/request.go @@ -19,6 +19,7 @@ func downloadAdditionalPages() { for i := range forumPagesLinks { forumPage, _ := strconv.Atoi(i) dlog.Info().Int("номер страницы", forumPage).Msg("Скачивается ещё одна страница форума") + pageFile, err := downloadFile("https://"+c.Config.URL+"/forum/"+forumPagesLinks[i], true) if err != nil { dlog.Fatal().Err(err).Msg("Не удалось загрузить страницу форума") @@ -33,12 +34,14 @@ func downloadFile(url string, transformEncoding bool) (string, error) { if err != nil { return "", err } + for i := range c.Cookies { req.AddCookie(c.Cookies[i]) } var resp *http.Response - retryCount := 0 + var retryCount int = 0 + for { if retryCount < 5 { resp, err = dclient.Do(req) @@ -46,6 +49,7 @@ func downloadFile(url string, transformEncoding bool) (string, error) { if uberDebug { dlog.Debug().Err(err).Int("попытка", retryCount+1).Msg("Не удалось получить данные, пытаемся ещё раз") } + time.Sleep(time.Second) retryCount++ } else { @@ -55,6 +59,7 @@ func downloadFile(url string, transformEncoding bool) (string, error) { return "", err } } + defer resp.Body.Close() tempF, err := ioutil.TempFile("", "massdl-*") @@ -65,6 +70,7 @@ func downloadFile(url string, transformEncoding bool) (string, error) { if transformEncoding { respInUTF8 := transform.NewReader(resp.Body, charmap.Windows1251.NewDecoder()) + _, err = io.Copy(tempF, respInUTF8) if err != nil { return "", err diff --git a/domains/loginer/v1/login.go b/domains/loginer/v1/login.go index 4e9045b..b6871fa 100644 --- a/domains/loginer/v1/login.go +++ b/domains/loginer/v1/login.go @@ -21,22 +21,28 @@ func login() { // First enter is site name, second and third are user credentials scanner := bufio.NewScanner(os.Stdin) scanline := 0 + for scanner.Scan() { scanline++ + switch { case scanline == 1: c.Config.URL = scanner.Text() + dlog.Info().Msg("Введите имя пользователя") case scanline == 2: c.Config.Username = scanner.Text() + dlog.Info().Msg("Введите пароль") default: c.Config.Password = scanner.Text() } + if scanline == 3 { break } } + if scanner.Err() != nil { dlog.Fatal().Err(scanner.Err()).Msg("Не удалось прочитать пользовательский ввод.") } @@ -78,19 +84,23 @@ func obtainCookies() { retryCount := 0 var resp *http.Response var err error + for { if retryCount == 10 { dlog.Fatal().Err(err).Msg("Не удалось отправить запрос на авторизацию в NNM-Club.") } + resp, err = client.Do(req) if err != nil { dlog.Debug().Err(err).Int("попытка", retryCount).Msg("Не удалось отправить запрос, попробуем ещё раз") retryCount++ + time.Sleep(2 * time.Second) } else { break } } + defer resp.Body.Close() if len(resp.Cookies()) == 0 { diff --git a/internal/context/context.go b/internal/context/context.go index d6ea6e6..998e75e 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -21,6 +21,7 @@ import ( // getMemoryUsage returns memory usage for logger. func (c *Context) getMemoryUsage(e *zerolog.Event, level zerolog.Level, message string) { var m runtime.MemStats + runtime.ReadMemStats(&m) e.Str("memalloc", fmt.Sprintf("%dMB", m.Alloc/1024/1024))