JavaRush /Блоги Java /Random-TG /Илова кардани муштарӣ ба мақолаҳо - "Лоиҳаи Java аз A то ...
Roman Beekeeper
Сатҳи

Илова кардани муштарӣ ба мақолаҳо - "Лоиҳаи Java аз A то Я"

Дар гурӯҳ нашр шудааст
Салом ба хама, дустони азизам. Қадам ба қадам мо ба ҳадафи худ наздик шуда истодаем - шудан MVP лоиҳаи мо - JavaRush Telegram Bot. Чунон ки дар маколаи гузашта гуфтам, 5 вазифа мондааст. Имрӯз мо дутои онҳоро баррасӣ хоҳем кард. "Лоиҳаи Java аз A то Я": Илова кардани муштарӣ ба мақолаҳо - 1Мехоҳам такрор кунам, ки лоиҳа дар ин ҷо тамом намешавад. Ман то ҳол як тонна ғояҳо ва дидгоҳҳо дорам, ки ин лоиҳа чӣ гуна бояд инкишоф ёбад, ба он чӣ чизҳои нав илова кардан мумкин аст ва чӣ беҳтар кардан мумкин аст. Пеш аз MVP, мо дар мавзӯи рефакторинг мақолаи алоҳида хоҳем дод, яъне дар бораи беҳтар кардани сифати code бидуни тағир додани функсияи он. То он вакт тамоми лоиха намоён мешавад ва маълум мешавад, ки чиро ва дар кучо бехтар кардан мумкин аст. Дар ҳолати мо, мо аз вайрон кардани функсия ба ҳадди аксар муҳофизат карда мешавем, зеро бисёр санҷишҳо навишта шудаанд. Мо инчунин дар бораи он чизе, ки мо мехостем ва дар ниҳоят чӣ ба даст овардем, ретроспективӣ менависем. Ин чизи хеле муфид аст: биёед бубинем, ки чӣ тавр ҳама чиз шаш моҳ пеш дуруст дида мешуд. Ҳадди ақал ин барои ман хеле ҷолиб аст. Агар касе мехоҳад худро ҳамчун озмоишгари дастӣ санҷад, ба мо нависед ва мо ҳамкорӣ хоҳем кард. Биёед ин лоиҳаро якҷоя беҳтар созем! Ҳамин тавр, инҳоянд: ду вазифае, ки шаш моҳ пеш тавсиф шудаанд: JRTB-8 ва JRTB-9 . Ман ба дидани он, ки барои ин вазифаҳо чӣ кор кардан лозим аст, оғоз кардам ва фаҳмидам, ки дар робита ба оғози фармонҳо ҳама чиз аллакай омода аст. Ин рӯй медиҳад...) Дар ин ҷо шумо метавонед ба StartCommand , усули иҷро нигаред :
@Override
public void execute(Update update) {
   String chatId = update.getMessage().getChatId().toString();

   telegramUserService.findByChatId(chatId).ifPresentOrElse(
           user -> {
               user.setActive(true);
               telegramUserService.save(user);
           },
           () -> {
               TelegramUser telegramUser = new TelegramUser();
               telegramUser.setActive(true);
               telegramUser.setChatId(chatId);
               telegramUserService.save(telegramUser);
           });

   sendBotMessageService.sendMessage(chatId, START_MESSAGE);
}
Мантиқ дар ин ҷо кор мекунад: агар базаи мо аллакай чунин корбарро аз рӯи chatId дошта бошад, мо танҳо майдони фаъол = ҳақиқиро барои ӯ муқаррар мекунем. Ва агар чунин корбар вуҷуд надошта бошад, мо корбари нав эҷод мекунем. Айнан барои фармони /stop дар StopCommand :
@Override
public void execute(Update update) {
   telegramUserService.findByChatId(update.getMessage().getChatId().toString())
           .ifPresent(it -> {
               it.setActive(false);
               telegramUserService.save(it);
           });
   sendBotMessageService.sendMessage(update.getMessage().getChatId().toString(), STOP_MESSAGE);
}
Мумкин аст, ки ҳангоми даъвати ин фармон барои корбар танҳо майдони фаъол = false муқаррар карда мешавад. Ва ин ҳама аст: обунаҳои ӯ зиндагӣ хоҳанд кард ва интизор мешаванд, вақте корбар бори дигар тасмим мегирад, ки сӯҳбатро бо бот фаъол кунад. Ва чунин ба назар мерасад, ки вазифа аллакай иҷро шудааст ва метавонад баста шавад. Аммо он ҷо набуд. Вазифаи аз ҳама муҳим эҷод кардани огоҳӣ дар бораи мақолаҳои нав дар обуна мебошад. Дар ин ҷо ин вазифаҳо пурра нав карда мешаванд ва анҷом дода мешаванд. Яъне, то он даме, ки мо огоҳии мақолаҳои навро амалӣ накунем, онро пӯшидан мумкин нест. Аз ин рӯ, биёед вазифаи JRTB-4-ро иҷро кунем - ҳар 20 дақиқа чек ва огоҳӣ дар бораи мақолаҳои нав эҷод кунем. Рафикон! Оё шумо мехоҳед фавран бидонед, ки рамзи нав барои лоиҳа кай бароварда мешавад? Мақолаи нав кай мебарояд? Ба канали ман обуна шавед tg . Дар он ҷо ман мақолаҳо, андешаҳои ман ва рушди сарчашмаи кушодаи худро якҷоя ҷамъ мекунам.

Мо JRTB-4-ро татбиқ мекунем

Мо бояд дар доираи ин вазифа чӣ кор кунем:
  1. Кореро эҷод кунед, ки давра ба давра ба ҳамаи гурӯҳҳое, ки мо дар базаи онҳо обуна ҳастем, боздид кунад, мақолаҳоро аз рӯи санаи интишор ҷудо кунед ва санҷед, ки оё ID-и нашри охирин ба арзиш дар GroupSub мувофиқат мекунад. Агар он мувофиқат накунад, шумо бояд дақиқ фаҳмед, ки аз замони охир чанд мақола нашр шудааст. Мо last_article_id-ро дар GroupSub7 ба ҳолати кунунӣ навсозӣ мекунем.

  2. Вақте ки мо рӯйхати мақолаҳои нашршударо пайдо кардем, мо ҳамаи корбарони ФАЪОЛро барои ин гурӯҳҳо пайдо мекунем ва ба онҳо дар бораи мақолаҳои нав огоҳӣ мефиристем.

Барои ин, мо чунин чизеро ба мисли Scheduler Springs истифода мебарем. Ин механизм дар чаҳорчӯбаи баҳор аст, ки бо он шумо метавонед вазифаҳоеро эҷод кунед, ки дар вақти муайян иҷро карда мешаванд. Ё ҳар 15-20-40 дақиқа, ё ҳар рӯзи панҷшанбе соати 15:30 ё ягон варианти дигар. Онҳо инчунин аз забони англисӣ коғази пайгирӣ номида мешаванд - joba. Дар ҳоле ки мо ин вазифаро иҷро мекунем, ман дидаву дониста дар ҷустуҷӯи мақолаҳои нав як камбудӣ мегузорам. Ин хеле кам аст ва танҳо дар вазъияте пайдо шуд, ки ман кори ин вазифаро дастӣ санҷидам. Барои ин ба шумо лозим аст, ки муштарӣ барои ҷустуҷӯи мақолаҳо нависед. Барои ин, мо API-и Swagger-ро , ки аллакай ба мо шинос аст, истифода мебарем . Пост-контроллер мавҷуд аст. Мо танҳо ба ҷустуҷӯи маҷмӯаи мақолаҳо бо истифода аз филтрҳои муайян манфиатдорем:
/api/1.0/rest/posts Паёмҳоро аз рӯи филтрҳо гиред
Мо бо ин дархост кор хоҳем кард. Дар он ба мо чӣ лозим аст? Рӯйхати мақолаҳоеро, ки ба гурӯҳи мушаххас тааллуқ доранд, гиред ва онҳо бояд аз рӯи санаи нашр мураттаб карда шаванд. Ҳамин тариқ, мо метавонем 15 мақолаи охиринро гирем ва тафтиш кунем, ки оё нашрияҳои нав дар асоси lastArticleId аз базаи мо нашр шудаанд . Агар мавҷуд бошад, мо онҳоро барои коркард ва фиристодан ба корбар мегузорем. Пас, мо бояд JavaRushPostClient нависем .

Мо JavaRushPostClient менависем

Дар ин ҷо мо кӯшиш намекунем, ки ҳамаи дархостҳоеро, ки дар API ба мо фиристода шудаанд, фаро гирем ва танҳо як дархостеро, ки ба мо лозим аст, эҷод мекунем. Бо ин амал мо якбора ба ду ҳадаф ноил мешавем:
  1. Мо раванди навиштани аризаи худро суръат мебахшем.

  2. Мо ин корро ба онҳое вогузорем, ки мехоҳанд ба ҷомеаи мо кӯмак расонанд ва тасмим гирифтанд, ки худро ҳамчун таҳиякунанда санҷанд. Ман барои ин вазифаҳо хоҳам гузошт, ки пас аз MVP иҷро карда шаванд.

Пас биёед ин корро кунем. Барои пурсиши бахши Моделҳо дар Swagger UI, мо DTO-ҳои зеринро эҷод мекунем:"Лоиҳаи Java аз A то Я": Илова кардани муштарӣ ба мақолаҳо - 2

BaseUserInfo:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

import lombok.Data;

/**
* DTO, which represents base user information.
*/
@Data
public class BaseUserInfo {
   private String city;
   private String country;
   private String displayName;
   private Integer id;
   private String job;
   private String key;
   private Integer level;
   private String pictureUrl;
   private String position;
   private UserPublicStatus publicStatus;
   private String publicStatusMessage;
   private Integer rating;
   private Integer userId;
}

Забон:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents languages.
*/
public enum Language {
   UNKNOWN,
   ENGLISH,
   GERMAN,
   SPANISH,
   HINDI,
   FRENCH,
   PORTUGUESE,
   POLISH,
   BENGALI,
   PUNJABI,
   CHINESE,
   ITALIAN,
   INDONESIAN,
   MARATHI,
   TAMIL,
   TELUGU,
   JAPANESE,
   KOREAN,
   URDU,
   TAIWANESE,
   NETHERLANDS,
   RUSSIAN,
   UKRAINIAN
}

LikesInfo:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents like's information.
*/
public class LikesInfo {

   private Integer count;
   private LikeStatus status;
}

LikeStatus:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents like's status.
*/
public enum LikeStatus {

   UNKNOWN,
   LIKE,
   HOT,
   FOLLOW,
   FAVORITE,
   SOLUTION,
   HELPFUL,
   ARTICLE,
   OSCAR,
   DISLIKE,
   WRONG,
   SPAM,
   ABUSE,
   FOUL,
   TROLLING,
   OFFTOPIC,
   DUPLICATE,
   DIRTY,
   OUTDATED,
   BORING,
   UNCLEAR,
   HARD,
   EASY,
   FAKE,
   SHAM,
   AWFUL
}

Навъи пост:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents post types.
*/
public enum PostType {
   UNKNOWN, USUAL, INNER_LINK, OUTER_LINK
}

UserPublicStatus:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents user public status.
*/
public enum UserPublicStatus {
   UNKNOWN,
   BEGINNER,
   ACTIVE,
   STRONG,
   GRADUATED,
   INTERNSHIP_IN_PROGRESS,
   INTERNSHIP_COMPLETED,
   RESUME_COMPLETED,
   LOOKING_FOR_JOB,
   HAVE_JOB;
}

VisibilityStatus:
package com.github.javarushcommunity.jrtb.javarushclient.dto;

/**
* DTO, which represents visibility status.
*/
public enum VisibilityStatus {
   UNKNOWN,
   RESTRICTED,
   PUBLIC,
   PROTECTED,
   PRIVATE,
   DISABLED,
   DELETED
}
Дар асоси ҳамаи ин DTO-ҳо, биёед як синфи асосиро барои гирифтани мақолаҳо нависед:

PostInfo:

package com.github.javarushcommunity.jrtb.javarushclient.dto;

import lombok.Data;

/**
* DTO, which represents post information.
*/
@Data
public class PostInfo {

   private BaseUserInfo authorInfo;
   private Integer commentsCount;
   private String content;
   private Long createdTime;
   private String description;
   private GroupInfo groupInfo;
   private Integer id;
   private String key;
   private Language language;
   private LikesInfo likesInfo;
   private GroupInfo originalGroupInfo;
   private String pictureUrl;
   private Double rating;
   private Integer ratingCount;
   private String title;
   private PostType type;
   private Long updatedTime;
   private UserDiscussionInfo userDiscussionInfo;
   private Integer views;
   private VisibilityStatus visibilityStatus;

}
Акнун биёед интерфейси кор бо он ва татбиқи онро созем. Барои кор бо мақолаҳо ба мо танҳо як усул лозим аст:

JavaRushPostClient:

package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;

import java.util.List;

/**
* Client for Javarush Open API corresponds to Posts.
*/
public interface JavaRushPostClient {

   /**
    * Find new posts since lastPostId in provided group.
    *
    * @param groupId provided group ID.
    * @param lastPostId provided last post ID.
    * @return the collection of the new {@link PostInfo}.
    */
   List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId);
}
findNewPosts ду далел мегирад: ID-и гурӯҳ ва ID охирини мақолае, ки бот аллакай интишор кардааст. Аз ин рӯ, ҳама мақолаҳое, ки дертар аз мақола бо lastPostId нашр шудаанд, интиқол дода мешаванд . Ва татбиқи он:
package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import kong.unirest.GenericType;
import kong.unirest.Unirest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class JavaRushPostClientImpl implements JavaRushPostClient {

   private final String javarushApiPostPath;

   public JavaRushPostClientImpl(@Value("${javarush.api.path}") String javarushApi) {
       this.javarushApiPostPath = javarushApi + "/posts";
   }

   @Override
   public List<PostInfo> findNewPosts(Integer groupId, Integer lastPostId) {
       List<PostInfo> lastPostsByGroup = Unirest.get(javarushApiPostPath)
               .queryString("order", "NEW")
               .queryString("groupKid", groupId)
               .queryString("limit", 15)
               .asObject(new GenericType<List<PostInfo>>() {
               }).getBody();
       List<PostInfo> newPosts = new ArrayList<>();
       for (PostInfo post : lastPostsByGroup) {
           if (lastPostId.equals(post.getId())) {
               return newPosts;
           }
           newPosts.add(post);
       }
       return newPosts;
   }
}
Мо ба дархост якчанд филтрҳо илова мекунем:
  • фармоиш = НАВ - ба тавре ки рӯйхат аввал навҳоро дар бар гирад;
  • groupKid = groupId - танҳо барои гурӯҳҳои муайян ҷустуҷӯ кунед;
  • маҳдудият = 15 - мо шумораи мақолаҳоро дар як дархост маҳдуд мекунем. Басомади мо 15-20 дақиқа аст ва интизорем, ки дар ин муддат ЗИЁДА аз 15 (!) навишта намешавад.
Баъдан, вақте ки мо мақолаҳоро ёфтем, мо рӯйхатро аз назар мегузаронем ва мақолаҳои нав меҷӯем. Алгоритм оддӣ ва беихтиёрона аст. Агар шумо онро беҳтар кардан хоҳед, нависед). Биёед барои ин муштарӣ як санҷиши оддӣ нависем:
package com.github.javarushcommunity.jrtb.javarushclient;

import com.github.javarushcommunity.jrtb.javarushclient.dto.PostInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.List;

import static com.github.javarushcommunity.jrtb.javarushclient.JavaRushGroupClientTest.JAVARUSH_API_PATH;

@DisplayName("Integration-level testing for JavaRushPostClient")
class JavaRushPostClientTest {

   private final JavaRushPostClient postClient = new JavaRushPostClientImpl(JAVARUSH_API_PATH);

   @Test
   public void shouldProperlyGetNew15Posts() {
       //when
       List<PostInfo> newPosts = postClient.findNewPosts(30, 2935);

       //then
       Assertions.assertEquals(15, newPosts.size());
   }
}
Ин як санҷиши хеле соддаест, ки тафтиш мекунад, ки оё бо муштарӣ ягон иртибот вуҷуд дорад ё не. Вай дар гурӯҳи лоиҳаҳои Java 15 мақолаи нав пайдо мекунад, зеро ман ба ӯ ID-и мақолаи аввалро дар ин гурӯҳ медиҳам ва аллакай зиёда аз 15 адад ҳастанд... Аллакай 22 адад! Ман ҳатто фикр намекардам, ки онҳо ин қадар зиёд мешаванд. Чӣ тавр ман зуд фаҳмидам? Шумо фикр мекунед, ки ӯ барои ҳисоб кардани онҳо рафт? Не) Ман свагерро истифода бурда, шумораи мақолаҳоро барои як гурӯҳи муайян дидам. Дар омади гап, шумо метавонед дар дигарон ин тавр назар кунед ... Ва дар гурӯҳи RANDOM чанд мақола вуҷуд дорад?... Ҳоло ба шумо мегӯям: 1062 адад! Маблағи ҷиддӣ.

Охири қисми якум

Дар ин ҷо мо кор бо муштарӣ аз рӯи мақола илова кардем. Мо аллакай ҳама чизро анҷом додем, ин дафъа ман фикр мекунам, ки ҳама чиз бояд оддӣ ва зуд бошад. Дар мақолаи навбатӣ мо баҳор Scheduler илова мекунем ва FindNewArticleService -ро менависем . Хуб, чун маъмул, лайк - обуна шавед - занг занед , ба лоиҳаи мо ситора диҳед , шарҳҳо нависед ва ба мақола баҳо диҳед! Ташаккур ба ҳама барои хондан - ба зудӣ вохӯред!

Рӯйхати ҳамаи маводҳои силсила дар аввали ин мақола аст.

Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION