JavaRush /Java блогу /Random-KY /Макалаларга кардарды кошуу - "Адан Яга чейин Java долбоор...
Roman Beekeeper
Деңгээл

Макалаларга кардарды кошуу - "Адан Яга чейин Java долбоору"

Группада жарыяланган
Баарыңарга салам, кымбаттуу досторум. Кадам сайын биз максатыбызга - JavaRush Telegram Bot долбоорубуздун MVP болууга жакындап келе жатабыз. Өткөн макалада айткандай, 5 гана тапшырма калды. Бүгүн биз алардын экөөнө токтолобуз. "Java долбоору Адан Яга": Макалаларга кардарды кошуу - 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 боюнча ушундай колдонуучу бар болсо, биз ага жөн гана активдүү = чыныгы талааны коебуз. Ал эми андай колдонуучу жок болсо, биз жаңысын түзөбүз. StopCommand ичиндеги /stop буйругу үчүн да ушундай :
@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);
}
Бул команданы чакырганда колдонуучу үчүн активдүү = жалган талаа гана коюлганын көрүүгө болот. Болгону ушул: анын жазылуулары жашайт жана колдонуучу бот менен чатты кайра жандандырууну чечкенде, канатта күтөт. Ал эми бул тапшырма эчак эле аткарылган жана жабылышы мүмкүн окшойт. Бирок ал жерде болгон эмес. Эң маанилүү милдет - жазылууда жаңы макалалар жөнүндө эскертүү түзүү. Бул жерде бул милдеттер толугу менен жаңыртылып, аткарылат. Башкача айтканда, биз жаңы макалалар жөнүндө кабарлоону ишке ашырмайынча, аны жабууга болбойт. Ошондуктан, келгиле, JRTB-4 тапшырмасына кам көрөлү - ар бир 20 мүнөт сайын чек түзүү жана жаңы макалалар жөнүндө эскертмелер. Достор! Долбоордун жаңы codeу качан чыгарылганын дароо билгиңиз келеби? Жаңы макала качан чыгат? Менин tg каналыма кошулунуз . Ал жерде мен өзүмдүн макалаларымды, ойлорумду, ачык булактагы өнүгүүмдү чогуу чогултам.

Биз JRTB-4 ишке ашырабыз

Бул иштин бир бөлүгү катары эмне кылышыбыз керек:
  1. Маалымат базасында жазылуулары бар бардык топторго мезгил-мезгor менен кирип турган жумушту түзүңүз, макалаларды жарыяланган датасы боюнча сорттоп, акыркы басылманын ID'си GroupSub ичиндеги мааниге дал келгенин текшериңиз. Эгер дал келбесе, анда акыркы жолу канча макала жарыяланганын так түшүнүшүңүз керек. GroupSub7 ичиндеги last_article_id'ди учурдагы абалга жаңыртабыз.

  2. Жарыяланган макалалардын тизмесин тапкандан кийин, биз бул топтордун бардык АКТИВДҮҮ ​​колдонуучуларын табабыз жана аларга жаңы макалалар жөнүндө эскертмелерди жөнөтөбүз.

Бул үчүн, биз Spring Scheduler сыяктуу нерсени колдонобуз. Бул Spring Framework механизми, аны менен сиз белгилүү бир убакта аткарыла турган тапшырмаларды түзө аласыз. Же 15-20-40 мүнөт сайын, же ар бейшемби күнү саат 15:30да же башка вариантта. Алар англис тorнен калька деп да аталат - joba. Биз бул тапшырманы аткарып жатып, мен атайылап жаңы макалаларды издөөдө бир кемчorкти калтырам. Бул өтө сейрек кездешет жана мен бул тапшырманын иштешин кол менен сынап көргөндө гана пайда болду. Бул үчүн сиз макалаларды издөө үчүн кардар жазуу керек. Бул үчүн, биз мурунтан эле бизге тааныш болгон Swagger API колдонобуз . Пост-контроллер бар. Биз белгилүү бир чыпкаларды колдонуу менен макалалар жыйнагын издөөгө гана кызыкдарбыз:
/api/1.0/rest/posts Фильтрлер боюнча билдирүүлөрдү алыңыз
Биз бул өтүнүч менен иштейбиз. Анда бизге эмне керек? Белгилүү бир топко кирген макалалардын тизмесин алыңыз жана алар жарыяланган датасы боюнча иреттелиши керек. Мына ушундай жол менен биз акыркы 15 макаланы алып, биздин маалымат базасынан lastArticleId негизинде жаңы басылмалар жарыяланганын текшере алабыз . Эгерде бар болсо, биз аларды иштеп чыгуу жана колдонуучуга жөнөтүү үчүн өткөрүп беребиз. Ошентип, биз JavaRushPostClient жазышыбыз керек .

Биз JavaRushPostClient жазабыз

Бул жерде биз APIде бизге жөнөтүлгөн бардык сурамдарды жабууга аракет кылбайбыз жана бизге керектүүсүн гана түзөбүз. Муну менен биз бир эле учурда эки максатка жетебиз:
  1. Биз арызыбызды жазуу процессин тездетебиз.

  2. Бул ишти биздин коомго жардам берүүнү каалагандарга калтырып, өздөрүн иштеп чыгуучу катары сынап көрүүнү чечтик. Мен бул үчүн MVPден кийин аткарыла турган тапшырмаларды берем.

Анда эмесе жасайлы. Swagger UIдеги Моделдер бөлүмүн суроо үчүн биз төмөнкү DTOларды түзөбүз:"Java долбоору Адан Яга": Макалаларга кардарды кошуу - 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
}

PostType:

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 эки аргументти алат: топтун идентификатору жана бот буга чейин жайгаштырган макаланын акыркы идентификатору. Ошондуктан, 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тен (!) КӨП жазылbyte деп күтөбүз.
Андан кийин, биз макалаларды тапкандан кийин, тизмени карап чыгып, жаңыларын издейбиз. Алгоритм жөнөкөй жана интуитивдик. Жакшырткыңыз келсе жазыңыз). Бул кардар үчүн жөнөкөй тест жазалы:
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 жаңы макала табат, анткени мен ага бул топтун биринчи макаласынын идентификаторун берем жана алардын саны 15тен ашык... Алардын 22си бар! Мынчалык көп болот деп ойлогон эмесмин. Кантип тез эле билдим? Кандай деп ойлойсуң, ал аларды санаганы кеттиби? Жок) Мен свегерди колдонуп, белгилүү бир топ үчүн макалалардын санын карадым. Айтмакчы, башкаларда да ушундай караса болот... Ал эми RANDOM тобунда канча макала бар?... Мен азыр айтам: алардын 1062си бар! Олуттуу сумма.

Биринчи бөлүктүн аягы

Бул жерде биз берене боюнча кардар менен иштөөнү коштук. Биз буга чейин баарын жасадык, бул жолу мен баары жөнөкөй жана тез болушу керек деп ойлойм. Кийинки макалада Spring Scheduler кошобуз жана FindNewArticleService жазабыз . Адаттагыдай эле, лайк басыңыз - жазылыңыз - коңгуроону басыңыз , биздин долбоорго жылдыз бериңиз , комментарий жазыңыз жана макаланы баалаңыз! Окуганыңыз үчүн рахмат - жакында көрүшкөнчө!

Сериядагы бардык материалдардын тизмеси ушул макаланын башында.

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION