Социальная подкаст-платформа
Рассмотрение сервисов, позволяющих прослушивать подкасты. Разработка платформы, сочетающей в себе функции для удобного поиска подкастов и возможность их обсуждения с ведущими и другими слушателями. Оценка удобства работы с пользовательским интерфейсом.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 14.12.2019 |
Размер файла | 2,7 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
package discasst.da;
import discasst.entity.Tweet;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface TweetRepository extends PagingAndSortingRepository<Tweet, Long> {
Page<Tweet> findAllByPodcastIdOrderByIdDesc(long id, Pageable pageable);
Page<Tweet> findAllByPodcastIdInOrderByIdDesc(long[] podcastIds, Pageable pageable);
void deleteAllByPodcastId(long id);
}
Файл: Discasst\src\main\java\discasst\da\UserRepository.java
package discasst.da;
import discasst.entity.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface UserRepository extends CrudRepository<User, Long> {
User findByUsername(String username);
List<User> findAllByIdIn(long[] list);
List<User> findAllByCreationDate(String date);
@Query("select a from User a where a.creationDate like:monthAndYear")
List<User> findAllInThisMonth(@Param("monthAndYear") String monthAndYear);
}
Файл: Discasst\src\main\java\discasst\entity\CoauthorsEntity.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
public class CoauthorsEntity {
@Id
@GeneratedValue
private long id;
private long podcastId;
private long userId;
public CoauthorsEntity(long podcastId, long userId) {
this.podcastId = podcastId;
this.userId = userId;
}
}
Файл: Discasst\src\main\java\discasst\entity\Episode.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.text.SimpleDateFormat;
import java.util.Date;
@Entity
@Data
public class Episode {
@Id
@GeneratedValue
private long id;
private long podcastId;
private String name;
@Column(columnDefinition = "TEXT")
private String description;
private String podsterLink;
private String date;
public long getPodcastId() {
return podcastId;
}
public Episode(long podcastId, String name,
String description, String podsterLink, Date date) {
this.podcastId = podcastId;
this.name = name;
this.description = description;
this.podsterLink = podsterLink;
this.date = new SimpleDateFormat("dd.MM.yy").format(date);
}
public void setDate(Date date) {
this.date = new SimpleDateFormat("dd.MM.yy").format(date);
}
}
Файл: Discasst\src\main\java\discasst\entity\Genre.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
public class Genre {
@Id
@GeneratedValue
private long id;
@Column(unique = true)
private String name;
public Genre(String name) {
this.name = name;
}
}
Файл: Discasst\src\main\java\discasst\entity\Podcast.java
package discasst.entity;
import lombok.Data;
import javax.persistence.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@Entity
@Data
@Table(name = "podcast")
public class Podcast {
@Id
@GeneratedValue
private long id;
@Column(unique = true)
private String name;
private long authorId;
@Column(columnDefinition="TEXT")
private String description;
private String itunesLink = "";
private String vkLink = "";
private String twitterLink = "";
private String facebookLink = "";
private Integer episodeCount = 0;
private Integer subscribersCount = 0;
private long genreId;
private Integer rating = 0;
private String creationDate;
public Podcast(String name, String description, Integer rating, Integer genreId, int episodeCount) {
this.name = name;
this.description = description;
this.rating = rating;
this.genreId = genreId;
this.episodeCount = episodeCount;
}
public Podcast(String name, String description, String itunesLink, String vkLink, String twitterLink,
String facebookLink, Integer episodeCount, long genreId, Integer rating, Integer subscribersCount, long authorId) {
this.name = name;
this.description = description;
this.itunesLink = itunesLink;
this.vkLink = vkLink;
this.twitterLink = twitterLink;
this.facebookLink = facebookLink;
this.episodeCount = episodeCount;
this.genreId = genreId;
this.rating = rating;
this.subscribersCount = subscribersCount;
this.authorId = authorId;
}
public Integer getEpisodeCount() {
return episodeCount;
}
public void setEpisodeCount(Integer episodeCount) {
this.episodeCount = episodeCount;
}
public void setCreationDate(Date date) {
this.creationDate = new SimpleDateFormat("dd.MM.yy").format(date);
}
public long getAuthorId() {
return authorId;
}
public void ratingInc() {
this.rating++;
}
public void ratingDec() {
this.rating--;
}
public void subscribersCountDec() {
this.subscribersCount--;
}
public void subscribersCountInc() {
this.subscribersCount++;
}
}
Файл: Discasst\src\main\java\discasst\entity\RatingEntity.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
public class RatingEntity {
@Id
@GeneratedValue
private long id;
private long userId;
private long podcastId;
private boolean decision;
public RatingEntity(long userId, long podcastId, boolean decision) {
this.userId = userId;
this.podcastId = podcastId;
this.decision = decision;
}
public long getUserId() {
return userId;
}
public long getPodcastId() {
return podcastId;
}
public void setDecision(boolean decision) {
this.decision = decision;
}
public boolean isDecision() {
return decision;
}
}
Файл: Discasst\src\main\java\discasst\entity\Role.java
package discasst.entity;
import org.springframework.security.core.GrantedAuthority;
public enum Role implements GrantedAuthority {
ROLE_USER, ROLE_ADMIN;
@Override
public String getAuthority() {
return name();
}
}
Файл: Discasst\src\main\java\discasst\entity\SubscribeEntity.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
public class SubscribeEntity {
@Id
@GeneratedValue
private long id;
private long userId;
private long podcastId;
private boolean isSubscribed;
public SubscribeEntity(long userId, long podcastId, boolean sub) {
this.userId = userId;
this.podcastId = podcastId;
this.isSubscribed = sub;
}
public boolean isSubscribed() {
return isSubscribed;
}
public void setSubscribed(boolean subscribed) {
isSubscribed = subscribed;
}
}
Файл: Discasst\src\main\java\discasst\entity\Tweet.java
package discasst.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
@Data
@Entity
public class Tweet {
@Id
@GeneratedValue
private long id;
private long podcastId;
private long authorId;
private String authorUsername;
private String text;
private String creationDate;
public Tweet(String text) {
Random r = new Random();
int v = r.nextInt(3);
this.podcastId = 21;
this.authorId = v == 0 ? 17: v == 1 ? 18: 19;
this.text = text;
this.creationDate = new SimpleDateFormat("dd.MM.yy HH:mm").format(new Date());
this.authorUsername = v == 0 ? "vedensky": v == 1 ? "istishev": "ilyaliya";
}
public long getAuthorId() {
return authorId;
}
public String getAuthorNickName() {
return authorUsername;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public void setCreationDate() {
this.creationDate = new SimpleDateFormat("dd.MM.yy HH:mm").format(new Date());
}
}
Файл: Discasst\src\main\java\discasst\entity\User.java
package discasst.entity;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@Entity
@Data
public class User implements UserDetails {
@Id
@GeneratedValue
private long id;
@Transient
private List<Role> authorities = new ArrayList<Role>(){{add(Role.ROLE_USER);}};
private boolean accountNonExpired = true;
private boolean accountNonLocked = true;
private boolean credentialsNonExpired = true;
private boolean enabled = true;
@Column(unique = true)
private String username;
private String password;
private String email;
private String name;
private String creationDate;
public User(String username, String email, String password, String name) {
this.username = username;
this.email = email;
this.password = password;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public void setCreationDate(Date date) {
this.creationDate = new SimpleDateFormat("dd.MM.yy").format(date);
}
}
Файл: Discasst\src\main\java\discasst\loaders\DatabaseLoader.java
package discasst.loaders;
import discasst.da.*;
import discasst.entity.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Component
public class DatabaseLoader implements CommandLineRunner {
@Autowired
private UserRepository userRepository;
@Autowired
private PodcastRepository podcastRepository;
@Autowired
private GenreRepository genreRepository;
@Autowired
private EpisodeRepository episodeRepository;
@Autowired
private TweetRepository tweetRepository;
@Autowired
private CoauthorsRepository coauthorsRepository;
@Override
public void run(String... strings) {
List<String> genres = Arrays.asList("Обо всем", "Авто", "Аудиокниги", "Бизнес и карьера", "Интернет и технологии"
, "Кино и музыка", "Красота и здоровье", "Культура и искусство", "Наука и образование", "Политика"
, "Отношения", "Путешествия", "Спорт", "Видеоигры");
for (String name: genres) {
this.genreRepository.save(new Genre(name));
}
this.userRepository.save(new User("finch", "sal0212@mail.ru", new BCryptPasswordEncoder().encode("finch"), "FINCH"));
this.userRepository.save(new User("q", "qqq@mail.ru", new BCryptPasswordEncoder().encode("q"), "bigQ"));
this.userRepository.save(new User("vedensky", "vedensky@gmail.com", new BCryptPasswordEncoder().encode("vedensky"), "Борис Веденский"));
this.userRepository.save(new User("istishev", "istishev@mail.ru", new BCryptPasswordEncoder().encode("istishev"), "Валерий Истишев"));
this.userRepository.save(new User("ilyaliya", "ilyaliya@gmail.com", new BCryptPasswordEncoder().encode("ilyaliya"), "Илья Рябов"));
String podDesc = "Завтракаст один из самых популярных подкастов про игры, медиа, кино, сериалы и технологии в России. Его ведущими являются три очень разных человека маркетолог Тимур, технический директор Дима и видеопродюсер Максим. Их объединяет любовь к играм, книгам, сериалам, кино, новым технологиям, трендам в интернете и интересным событиям вокруг нас.";
this.podcastRepository.save(new Podcast("Завтракаст", podDesc, 404, 13, 0));
podDesc = "Раз в неделю Борис Веденский, Валерий Истишев и Илья Рябов соберутся, чтобы сжечь несколько ведьм, разоблачить пару заговоров, обсудить последние новости интернета, технологий, кино и видеоигр в неформальной обстановке.";
this.podcastRepository.save(new Podcast("Droider Cast", podDesc, "https://itunes.apple.com/ru/podcast/droider-cast/id1057019371?mt=2", "https://vk.com/droider_ru", "https://twitter.com/vedensky", "https://www.facebook.com/Droider", 12, 4, 509, 217, 17));
this.podcastRepository.save(new Podcast("Newочём", "Мы переводим и озвучиваем всё самое интересное, что появляется в зарубежном Интернете.", 342, 0, 0));
podDesc = "Рассказываем обо всём, что можно «взломать»: о здоровье, работе и технологиях, об образовании, спорте и отдыхе, об отношениях, финансах и мотивации. Помогаем решить проблемы или упростить ситуации, с которыми вы сталкиваетесь каждый день. Отвечаем на вопросы и призываем посмотреть на привычные вещи другими глазами.";
this.podcastRepository.save(new Podcast("Подкаст «Лайфхакера»", podDesc, 15, 0, 0));
podDesc = "Наше психологическое радио о простых и сложных переживаниях, о психологии эмоций, личной эффективности и личностном развитии, о саногенном мышлении, мы рассказываем на простых примерах, как пережить те или иные эмоции, как то: страх, гнев, стыд, обида или вина, либо вообще их угасить. Наши подкастырассказывают как контролируемое спокойствие влияет на результаты в бизнесе, спорте, развитии личности и личной жизни. Приятного прослушивания! ";
this.podcastRepository.save(new Podcast("Психология: мифы и реальность.", podDesc, 221, 8, 0));
podDesc = "Программа о том, как выучить английский язык быстро и без лишних усилий. Вы узнаете, как пополнить словарный запас, разобраться в правилах грамматики, поставить произношение. А самое главное -- освоить логику английского языка и научиться думать на нём.";
this.podcastRepository.save(new Podcast("Учим английский с Don't Speak", podDesc, 159, 8, 0));
podDesc = "Что может быть лучше душевной беседы? Только душевная беседа двух рыжих чуваков. Каждое воскресенье Константин Тростенюк и Денис Карамышев экспертно анализируют всё, что достойно экспертного анализа.";
this.podcastRepository.save(new Podcast("Душевный подкаст", podDesc, 407, 13, 0));
this.podcastRepository.save(new Podcast("Вечерние чтения", "Озвучиваю самое интересное из прочитанного за день.", 93, 2, 0));
podDesc = "Радио ENERGY, частота в Москве 104.2 FM, получила официальное разрешение на использование всемирно известного товарного знака NRJ / Energy, которым владеет французская медиагруппа «Эн Эр Жи» («NRJ Group»). Это стало возможным в результате переговоров, проходивших в 2006 году между представителями Группы и «ВКПМ». NRJ создает специальные проекты, самым известным из которых является ежегодная музыкальная премия NRJ Music Awards. Радиостанции с торговой маркой NRJ / Energy работают в Австрии, Бельгии, Болгарии, Германии, Дании, Норвегии, Финляндии, Швейцарии, Швеции, а также в Ливане и на Украине.\n\nСетевое издание ENERGYFM.RU, свидетельство о регистрации СМИ Эл № ФС77-50193 от 15.06.2012, выдано Федеральной службой по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор).";
this.podcastRepository.save(new Podcast("NRJ RUSSIA", podDesc, 213, 5, 0));
this.podcastRepository.save(new Podcast("Предназначение. Дело Жизни", "Обсуждаются такие вопросы:\nПредназначение\nМотивация\nЭмоциональное выгорание\nЛень и прокрастинация\nCамоопределение\nКак найти себяПрофориентация\nПризвание\nКем быть в жизни\nДело Жизни\nПродуктивность\n\nВ эфире:\nИстории раскрытия и монетизации дела жизни. Короткие практики и медитации для самостоятельной работы. Методики и модели раскрытия предназначения. Записи выступлений и вебинаров Павла Кочкина. Ответы на вопросы подписчиков.", 277, 8, 0));
this.podcastRepository.save(new Podcast("Игровой Батискаф", "Лучшее со дна игровой индустрии в исполнении знатных водолазов.", 407, 13, 0));
this.episodeRepository.save(new Episode(21, "Droider Cast 1", "1 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/50", new Date(2018, 9, 22)));
this.episodeRepository.save(new Episode(21, "Droider Cast 2", "2 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/51", new Date(2018, 10, 12)));
this.episodeRepository.save(new Episode(21, "Droider Cast 3", "3 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/52", new Date(2018, 10, 22)));
this.episodeRepository.save(new Episode(21, "Droider Cast 4", "4 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 10, 27)));
this.episodeRepository.save(new Episode(21, "Droider Cast 5", "5 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 11, 2)));
this.episodeRepository.save(new Episode(21, "Droider Cast 6", "6 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 11, 12)));
this.episodeRepository.save(new Episode(21, "Droider Cast 7", "7 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 11, 21)));
this.episodeRepository.save(new Episode(21, "Droider Cast 8", "8 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 12, 2)));
this.episodeRepository.save(new Episode(21, "Droider Cast 9", "9 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 12, 9)));
this.episodeRepository.save(new Episode(21, "Droider Cast 10", "10 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 12, 16)));
this.episodeRepository.save(new Episode(21, "Droider Cast 11", "11 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2018, 12, 24)));
this.episodeRepository.save(new Episode(21, "Droider Cast 12", "12 выпуск подкаста \"Droider Cast\"", "https://droidercast.podster.fm/53", new Date(2019, 1, 5)));
for (int i = 1; i <= 25; i++) {
this.tweetRepository.save(new Tweet("Droider Cast Твит " + i + "!"));
}
this.coauthorsRepository.save(new CoauthorsEntity(21, 18));
this.coauthorsRepository.save(new CoauthorsEntity(21, 19));
}
}
Файл: Discasst\src\main\java\discasst\service\PodcastService.java
package discasst.service;
import com.google.gson.Gson;
import discasst.da.*;
import discasst.entity.CoauthorsEntity;
import discasst.entity.Episode;
import discasst.entity.Genre;
import discasst.entity.Podcast;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
@RestController
public class PodcastService {
@Autowired
private GenreRepository genreRepository;
@Autowired
private PodcastRepository podcastRepository;
@Autowired
private EpisodeRepository episodeRepository;
@Autowired
private CoauthorsRepository coauthorsRepository;
@Autowired
private SubscribeRepository subscribeRepository;
@Autowired
private TweetRepository tweetRepository;
@Autowired
private RatingRepository ratingRepository;
@RequestMapping(value = "/getGenres", method = RequestMethod.GET)
public List<Genre> getGenres() {
List<Genre> genres = genreRepository.findAll();
if (genres != null) return genres;
else throw new UsernameNotFoundException("Genres not found!");
}
@RequestMapping(value = "/createPodcast")
public @ResponseBody
void createPodcast(@RequestBody String podcast) {
Gson g = new Gson();
Podcast pod = g.fromJson(podcast, Podcast.class);
pod.setCreationDate(new Date());
podcastRepository.save(pod);
}
@Transactional
@RequestMapping(value = "/removePodcast", method = RequestMethod.POST)
public @ResponseBody
void removePodcast(@RequestParam(value = "id") long id) {
episodeRepository.deleteAllByPodcastId(id);
coauthorsRepository.deleteAllByPodcastId(id);
tweetRepository.deleteAllByPodcastId(id);
subscribeRepository.deleteAllByPodcastId(id);
ratingRepository.deleteAllByPodcastId(id);
podcastRepository.deleteById(id);
}
@RequestMapping(value = "/getPodcastsByUserId")
public @ResponseBody
List<Podcast> getPodcastsByUserId(@RequestParam(value = "id") long id) {
return podcastRepository.findAllByAuthorId(id);
}
@RequestMapping(value = "/getPodcastsByUserIdInCoauthors")
public @ResponseBody
List<Podcast> getPodcastsByUserIdInCoauthors(@RequestParam(value = "id") long id) {
long[] ids = coauthorsRepository.findAllByUserId(id);
return podcastRepository.findAllByIdIn(ids);
}
@RequestMapping(value = "/createEpisode")
public @ResponseBody
void createEpisode(@RequestBody String episode) {
Gson g = new Gson();
Episode newEpisode = g.fromJson(episode, Episode.class);
newEpisode.setDate(new Date());
episodeRepository.save(newEpisode);
Podcast pod = podcastRepository.findById(newEpisode.getPodcastId());
pod.setEpisodeCount(pod.getEpisodeCount() + 1);
podcastRepository.save(pod);
}
@RequestMapping(value = "/getEpisodesByPodcastIdInPage")
public @ResponseBody
Page<Episode> getAllEpisodesByPodcastIdInPage(
@RequestParam(value = "id") long id, Pageable pageable) {
return episodeRepository.findAllByPodcastIdOrderByIdDesc(id, pageable);
}
@Transactional
@RequestMapping(value = "/getEpisodesInFeedByUserIdInPage")
public @ResponseBody
Page<Episode> getEpisodesInFeedByUserIdInPage(@RequestParam(value = "id") long id, Pageable pageable) {
long[] subs = subscribeRepository.findAllByUserId(id);
return episodeRepository.findAllByPodcastIdInOrderByIdDesc(subs, pageable);
}
@RequestMapping(value = "/getEpisodesCountToday")
public @ResponseBody
int getEpisodesCountToday() throws ParseException {
String today = new SimpleDateFormat("dd.MM.yy").format(new Date());
return episodeRepository.findAllByDate(today).size();
}
@RequestMapping(value = "/getEpisodesCountThisMounth")
public @ResponseBody
int getEpisodesCountThisMounth() throws ParseException {
String today = new SimpleDateFormat("MM.yy").format(new Date());
return episodeRepository.findAllInThisMonth("%" + today + "%").size();
}
@RequestMapping(value = "/getPodcastsCountToday")
public @ResponseBody
int getPodcastsCountToday() throws ParseException {
String today = new SimpleDateFormat("dd.MM.yy").format(new Date());
return podcastRepository.findAllByCreationDate(today).size();
}
@RequestMapping(value = "/getPodcastsCountThisMounth")
public @ResponseBody
int getPodcastsCountThisMounth() throws ParseException {
String today = new SimpleDateFormat("MM.yy").format(new Date());
return podcastRepository.findAllInThisMonth("%" + today + "%").size();
}
@Transactional
@RequestMapping(value = "/addCoauthors")
public @ResponseBody
void addCoauthors(@RequestBody String authorsIdsJSON, @RequestParam(value = "podcastId") long podcastId) {
Gson g = new Gson();
int[] authorsIds = g.fromJson(authorsIdsJSON, int[].class);
coauthorsRepository.deleteAllByPodcastId(podcastId);
for (int i: authorsIds) {
coauthorsRepository.save(new CoauthorsEntity(podcastId, i));
}
}
@RequestMapping(value = "/getCoauthors")
public @ResponseBody
List<CoauthorsEntity> getCoauthors(@RequestParam(value = "podcastId") long podcastId) {
return coauthorsRepository.findAllByPodcastId(podcastId);
}
}
Файл: Discasst\src\main\java\discasst\service\RatingService.java
package discasst.service;
import com.google.gson.Gson;
import discasst.da.PodcastRepository;
import discasst.da.RatingRepository;
import discasst.entity.Podcast;
import discasst.entity.RatingEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
@Service
@RestController
public class RatingService {
@Autowired
private PodcastRepository podcastRepository;
@Autowired
private RatingRepository ratingRepository;
@Transactional
@RequestMapping(value = "/vote", method = RequestMethod.POST)
public @ResponseBody
void vote(@RequestBody String rateStr) {
Gson g = new Gson();
RatingEntity newrate = g.fromJson(rateStr, RatingEntity.class);
RatingEntity oldrate = ratingRepository.findByPodcastIdAndUserId(newrate.getPodcastId(), newrate.getUserId());
Podcast podcast = podcastRepository.findById(newrate.getPodcastId());
//если пользователь уже голосовал
if (oldrate != null) {
//если оценка отличается
if (oldrate.isDecision() != newrate.isDecision()) {
//если оценка положительная
if (newrate.isDecision()) {
podcast.ratingInc();
podcast.ratingInc();
oldrate.setDecision(true);
} else {
podcast.ratingDec();
podcast.ratingDec();
oldrate.setDecision(false);
}
ratingRepository.save(oldrate);
}
} else {
ratingRepository.save(newrate);
if (newrate.isDecision()) {
podcast.ratingInc();
} else {
podcast.ratingDec();
}
}
podcastRepository.save(podcast);
}
@RequestMapping(value = "/getMyVote", method = RequestMethod.GET)
public @ResponseBody
int getMyVote(@RequestParam(value = "userId") long userId, @RequestParam(value = "podcastId") long podcastId) {
RatingEntity oldrate = ratingRepository.findByPodcastIdAndUserId(podcastId, userId);
//если пользователь уже голосовал
if (oldrate != null) {
//если оценка положительная
if (oldrate.isDecision()) {
return 1;
} else {
return -1;
}
} else {
return 0;
}
}
}
Файл: Discasst\src\main\java\discasst\service\RequestService.java
package discasst.service;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Класс для бинда первого входа на сайт (первая загрузка сайта не через реакт роутер)
*/
@Controller
public class RequestService {
@RequestMapping(value = "/signin")
public String signinPage() {
return "MainHTML";
}
@RequestMapping(value = "/register")
public String registerPage() {
return "MainHTML";
}
@RequestMapping(value = "/search")
public String searchPage() {
return "MainHTML";
}
@RequestMapping(value = "/feed")
public String feed() {
return "MainHTML";
}
@RequestMapping(value = "/statistics")
public String statisticsPage() {
return "MainHTML";
}
@RequestMapping(value = "/")
public String mainPage() {
return "MainHTML";
}
@RequestMapping(value = "/user/{username}")
public String userProfilePage() {
return "MainHTML";
}
@RequestMapping(value = "/podcast/{podcastId}")
public String podcastPage() {
return "MainHTML";
}
@RequestMapping(value = "/createNewPodcast")
public String createNewPodcastPage() {
return "MainHTML";
}
@RequestMapping(value = "/createNewEpisode/{podcastId}")
public String createNewEpisodePage() {
return "MainHTML";
}
@RequestMapping(value = "/addCoauthors/{podcastId}")
public String addCoauthorsPage() {
return "MainHTML";
}
}
Файл: Discasst\src\main\java\discasst\service\SearchService.java
package discasst.service;
import com.google.gson.Gson;
import discasst.da.GenreRepository;
import discasst.da.PodcastRepository;
import discasst.entity.Genre;
import discasst.entity.Podcast;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Service
@RestController
public class SearchService {
@Autowired
private PodcastRepository podcastRepository;
@Autowired
private GenreRepository genreRepository;
@RequestMapping(value = "/getPodcastsInPage", method = RequestMethod.POST)
public Page<Podcast> getPodcastsInPage(@RequestBody String json, Pageable pageable) {
Gson g = new Gson();
FilterAndGenres filterAndGenres = g.fromJson(json, FilterAndGenres.class);
if (filterAndGenres.byRating) {
return podcastRepository.findByNameContainsIgnoreCaseAndGenreIdNotInOrderByRatingDesc(filterAndGenres.filter, filterAndGenres.genres, pageable);
} else {
return podcastRepository.findByNameContainsIgnoreCaseAndGenreIdNotInOrderByIdDesc(filterAndGenres.filter, filterAndGenres.genres, pageable);
}
}
@RequestMapping(value = "/getPodcastById", method = RequestMethod.GET)
public Podcast getPodcastById(@RequestParam(value = "id", required = true) long id) {
return podcastRepository.findById(id);
}
@RequestMapping(value = "/getAllGenres", method = RequestMethod.GET)
public List<Genre> getAllGenres() {
return genreRepository.findAll();
}
class FilterAndGenres {
public String filter = "";
public long[] genres;
public boolean byRating;
}
}
Файл: Discasst\src\main\java\discasst\service\SubscribeService.java
package discasst.service;
import discasst.da.PodcastRepository;
import discasst.da.SubscribeRepository;
import discasst.entity.Podcast;
import discasst.entity.SubscribeEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import javax.transaction.Transactional;
@Service
@RestController
public class SubscribeService {
@Autowired
private SubscribeRepository subscribeRepository;
@Autowired
private PodcastRepository podcastRepository;
@Transactional
@RequestMapping(value = "/subscribe", method = RequestMethod.GET)
public @ResponseBody
void subscribe(@RequestParam(value = "userId") long userId, @RequestParam(value = "podcastId") long podcastId) {
SubscribeEntity subs = subscribeRepository.findByPodcastIdAndUserId(podcastId, userId);
Podcast podcast = podcastRepository.findById(podcastId);
//если запись с таким пользователем и подкастом существует
if (subs != null) {
subs.setSubscribed(!subs.isSubscribed());
subscribeRepository.save(subs);
if (subs.isSubscribed()) {
podcast.subscribersCountInc();
} else {
podcast.subscribersCountDec();
}
} else {
subscribeRepository.save(new SubscribeEntity(userId, podcastId, true));
podcast.subscribersCountInc();
}
podcastRepository.save(podcast);
}
@RequestMapping(value = "/getMySubscribe", method = RequestMethod.GET)
public @ResponseBody
boolean getMyVote(@RequestParam(value = "userId") long userId, @RequestParam(value = "podcastId") long podcastId) {
SubscribeEntity subs = subscribeRepository.findByPodcastIdAndUserId(podcastId, userId);
//если запись с таким пользователем и подкастом существует
if (subs != null) {
return subs.isSubscribed();
} else {
return false;
}
}
}
Файл: Discasst\src\main\java\discasst\service\TweetService.java
package discasst.service;
import com.google.gson.Gson;
import discasst.da.SubscribeRepository;
import discasst.da.TweetRepository;
import discasst.entity.Tweet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
@Service
@RestController
public class TweetService {
@Autowired
private TweetRepository tweetRepository;
@Autowired
private SubscribeRepository subscribeRepository;
@RequestMapping(value = "/addTweet", method = RequestMethod.POST, headers = {"Content-type=application/json"})
public void create(@RequestBody String tweetJson) {
Gson g = new Gson();
Tweet newTwit = g.fromJson(tweetJson, Tweet.class);
newTwit.setCreationDate();
newTwit.setCreationDate();
this.tweetRepository.save(newTwit);
System.out.println("new tweet added:" + newTwit.getText());
}
@RequestMapping(value = "/deleteTweet", method = RequestMethod.POST)
public void deleteById(@RequestParam(value = "tweetId") Long tweetId) {
this.tweetRepository.deleteById(tweetId);
}
public Tweet getById(int id) {
return null;
}
@RequestMapping(value = "/getAllTwitsByPodcastId")
public Page<Tweet> getAllTwitsByUserId(@RequestParam(value = "id") Long id, Pageable pageable) {
return tweetRepository.findAllByPodcastIdOrderByIdDesc(id, pageable);
}
@RequestMapping(value = "/getAllTwitsByUserIdFeed")
public Page<Tweet> getAllTwitsByUserIdFeed(@RequestParam(value = "id") Long id, Pageable pageable) {
long[] subs = subscribeRepository.findAllByUserId(id);
return tweetRepository.findAllByPodcastIdInOrderByIdDesc(subs, pageable);
}
}
Файл: Discasst\src\main\java\discasst\service\UserService.java
package discasst.service;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import discasst.da.UserRepository;
import discasst.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
@RestController
public class UserService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findByUsername(s);
if (user != null) return user;
else throw new UsernameNotFoundException("User " + s + " not found!");
}
@RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
public User getUserInfo(@RequestParam(value = "username", required = true) String username) {
User user = userRepository.findByUsername(username);
if (user != null) return user;
else throw new UsernameNotFoundException("User " + username + " not found!");
}
@RequestMapping(value = "/addUser", method = RequestMethod.POST)
public void addUser(@RequestParam(value = "username", required = true) String username,
@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "email", required = true) String email,
@RequestParam(value = "password", required = true) String password,
HttpServletRequest request, HttpServletResponse response) {
User newUser = new User(username, email, new BCryptPasswordEncoder().encode(password), name);
try {
newUser.setCreationDate(new Date());
userRepository.save(newUser);
System.out.println("new user added: " + username);
response.setHeader("newUserStatus", "ok");
} catch (Exception e) {
System.out.println("error on adding new user: " + e.getMessage());
if (e.getCause().getCause().getMessage().contains("Нарушение уникального индекса или первичного ключа"))
response.setHeader("newUserStatus", "usernameError");
else response.setHeader("newUserStatus", "unknownError");
}
}
@RequestMapping(value = "/updateProfile", method = RequestMethod.POST)
public void updateProfile(@RequestParam(value = "name", required = true) String name,
@RequestParam(value = "username", required = true) String username,
HttpServletRequest request, HttpServletResponse response) {
try {
User updatedUser = userRepository.findByUsername(username);
updatedUser.setName(name);
userRepository.save(updatedUser);
System.out.println("profile updated: " + name);
response.setHeader("updateProfileStatus", "ok");
} catch (Exception e) {
System.out.println("profile update error: " + e.getMessage());
response.setHeader("updateProfileStatus", "error");
}
}
@RequestMapping(value = "/getUsersCountToday")
public @ResponseBody
int getUsersCountToday() throws ParseException {
String today = new SimpleDateFormat("dd.MM.yy").format(new Date());
return userRepository.findAllByCreationDate(today).size();
}
@RequestMapping(value = "/getUsersCountThisMounth")
public @ResponseBody
int getUsersCountThisMounth() throws ParseException {
String today = new SimpleDateFormat("MM.yy").format(new Date());
return userRepository.findAllInThisMonth("%" + today + "%").size();
}
@RequestMapping(value = "/getCoauthorsByIdList", method = RequestMethod.POST)
public @ResponseBody
List<User> getCoauthorsByIdList(@RequestBody String coauthorsIdsJSON) {
Gson g = new Gson();
JsonElement json = new JsonPrimitive(coauthorsIdsJSON);
long[] coauthorsIds = g.fromJson(coauthorsIdsJSON, Ids.class).ids;
return userRepository.findAllByIdIn(coauthorsIds);
}
@RequestMapping(value = "/loginCheck", method = RequestMethod.POST)
public @ResponseBody
int loginCheck() {
return 200;
}
public class Ids {
long[] ids;
}
}
Исходный код клиентской части проекта:
Файл: Discasst\src\main\resources\templates\MainHTML.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8"/>
<title>Discasst</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/css/discasst.css">
</head>
<body style="background-color: #e6ecf0">
<div id="root"></div>
<script src="/generated/bundle.js" type="text/javascript"></script>
</body>
</html>
Файл: Discasst\src\main\resources\static\css\discasst.css
body {
height: 100%;
}
.hr10 {
height: 10px;
visibility: hidden
}
.hr100 {
height: 100px;
visibility: hidden
}
.hr15 {
height: 15px;
visibility: hidden
}
.hr30 {
height: 30px;
visibility: hidden
}
.hr60 {
height: 60px;
visibility: hidden
}
.btn:focus,.btn:active:focus,.btn.active:focus,
.btn.focus,.btn:active.focus,.btn.active.focus {
outline: none;
box-shadow: none;
}
.icon-button {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
outline: none;
border: 0;
background: transparent;
}
/* navbar */
.navbar-nav.navbar-center {
position: absolute;
left: 50%;
transform: translatex(-50%);
}
a:hover {
cursor: pointer;
}
/* searchPanel */
.search-list.btn:focus {
outline: 0
}
.search-list.list-group-item:focus {
outline: 0
}
/* signin */
.form-control-signin-css {
position: relative;
box-sizing: border-box;
height: auto;
padding: 10px;
font-size: 16px;
}
#signinUser {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
#signinPass {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
Файл: Discasst\src\main\resources\static\package.json
{
"name": "discasst",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack -d --watch"
},
"author": "",
"license": "ISC",
"dependencies": {
"bootstrap": "^4.1.1",
"css-loader": "^1.0.1",
"jquery": "^3.3.1",
"react": "^16.4.1",
"react-bootstrap": "^0.32.4",
"react-dom": "^16.4.1",
"react-router-dom": "^4.3.1",
"reactstrap": "^6.3.1",
"requirejs": "^2.3.5",
"rest": "^2.0.0",
"rest-js": "^1.1.3",
"style-loader": "^0.23.1",
"react-disqus-comments": "^1.4.0"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"webpack": "^4.16.3",
"webpack-cli": "^3.1.0"
}
}
Файл: Discasst\src\main\resources\static\app\app.js
import SigninPage from "./components/login/SigninPage";
import RegisterPage from "./components/login/RegisterPage"
import SearchPage from "./components/searchPage/SearchPage"
import UserProfilePage from "./components/userPage/UserProfilePage"
import PodcastPage from "./components/podcastPage/PodcastPage";
import CreateNewPodcastPage from "./components/userPage/CreateNewPodcastPage";
import CreateNewEpisodePage from "./components/userPage/CreateNewEpisodePage";
import StatisticsPage from "./components/statistics/StatisticsPage";
import AddCoauthorsPage from "./components/userPage/AddCoauthorsPage";
import FeedPage from "./components/feedPage/FeedPage";
import {BrowserRouter, Route, Switch} from 'react-router-dom';
const React = require('react');
const ReactDOM = require('react-dom');
export default class App extends React.Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={SearchPage}/>
<Route path='/signin' component={SigninPage}/>
<Route path='/register' component={RegisterPage}/>
<Route path='/search' component={SearchPage}/>
<Route path='/feed' component={FeedPage}/>
<Route path='/statistics' component={StatisticsPage}/>
<Route path='/createNewPodcast' component={CreateNewPodcastPage}/>
<Route path='/podcast/:podcastId' component={PodcastPage}/>
<Route path='/createNewEpisode/:podcastId' component={CreateNewEpisodePage}/>
<Route path='/user/:username' component={UserProfilePage}/>
<Route path='/addCoauthors/:podcastId' component={AddCoauthorsPage}/>
</Switch>
</BrowserRouter>
)
}
}
const el = document.getElementById('root');
ReactDOM.render(<App/>, el);
Файл: Discasst\src\main\resources\static\app\components\Helper.js
export function getCookie(name) {
var matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]): undefined;
}
export function getFullCSRFParam() {
const token = getCookie('XSRF-TOKEN');
return `_csrf=${token}`;
}
export function saveCookie(cookieName, value) {
document.cookie = `${cookieName}=${value}; path=/`;
}
export function deleteCookie(cookieName) {
document.cookie = `${cookieName}=${""}; path=/; expires=-1`;
}
export function saveAllCookie(username, id, email, creationDate, name, bio) {
saveCookie("username", username);
saveCookie("userId", id);
saveCookie("userEmail", email);
saveCookie("userCreationDate", creationDate);
saveCookie("name", name);
saveCookie("bio", bio);
}
export function deleteAllCookie() {
deleteCookie("username");
deleteCookie("userId");
deleteCookie("userEmail");
deleteCookie("userCreationDate");
deleteCookie("name");
deleteCookie("bio");
deleteCookie("XSRF-TOKEN");
}
export function isUserSignedIn() {
let username = getCookie("username");
return (username !== "" && username !== undefined);
}
export const getGenres = () =>
fetch("/getAllGenres").then(response => response.json());
Файл: Discasst\src\main\resources\static\app\components\Navbar.js
const React = require('react');
import {deleteAllCookie, getCookie, getFullCSRFParam} from "./Helper";
export default class Navbar extends React.Component {
constructor(props) {
super(props);
this.state = {
isSignedIn: false
};
}
componentDidMount() {
this.isUserLogIn();
}
loginout = () => {
if (this.state.isSignedIn) {
deleteAllCookie();
this.props.history.push(`/signin?logout`);
}
else {
this.props.history.push(`/signin`);
}
};
toStats = () => {
this.props.history.push(`/statistics`);
};
toMyProfile = () => {
this.props.history.push(`/user/${getCookie("username")}`);
};
toFeed = () => {
this.props.history.push(`/feed`);
};
toNotifications = () => {
this.props.history.push(`/notifications`);
};
toHome = () => {
this.props.history.push(`/`);
};
toSignIn = () => {
this.props.history.push(`/signin`);
};
isUserLogIn() {
let username = getCookie("username");
if (username === "" || username === undefined) return false;
fetch(`/loginCheck?${getFullCSRFParam()}`, {
method: 'POST'
}).then((response) => {
if (response.status === 200 && !response.redirected) this.setState({isSignedIn: true});
});
}
onFilterSubmit = () => {
const filter = document.getElementById("topSearch").value;
this.props.history.push({
pathname: '/search',
state: {filterValue: filter}
})
};
render() {
return (
<div>
<nav className="navbar navbar-default" style={{backgroundColor: '#ffffff'}} role="navigation">
<div className="container-fluid centered">
<div className="navbar-header">
<a onClick={() => {
this.toHome()
}} className="navbar-brand" style={{height: '64px', display: 'flex', alignItems: 'center'}}>
<img src="/images/discasst.png" height='36'></img>
</a>
</div>
<div>
<ul className="nav navbar-nav"
style={{height: '64px', display: 'flex', alignItems: 'center'}}>
<li><a onClick={() => {
!this.state.isSignedIn ? this.toSignIn(): this.toFeed()
}}>
<span className="glyphicon glyphicon-align-justify"></span> Feed</a>
</li>
<li><a onClick={() => {
!this.state.isSignedIn ? this.toSignIn(): this.toMyProfile()
}}>
<span className="glyphicon glyphicon-user"></span> My Profile</a>
</li>
<li><a onClick={() => {
this.toStats()
}}>
<span className="glyphicon glyphicon-stats"></span></a>
</li>
</ul>
{!this.props.isSearchOff && <ul className="nav navbar-nav navbar-center">
<li>
<a>
<form onSubmit={this.onFilterSubmit}>
<div className="input-group" style={{width: '300px'}}>
<input id="topSearch" type="text" className="form-control"/>
<span className="input-group-btn">
<button className="btn btn-info" type="button"
onClick={this.onFilterSubmit}
>
<span className="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</form>
</a>
</li>
</ul>}
<ul className="nav navbar-nav navbar-right">
<li>
<a><button className="btn btn-info" type="button" onClick={this.loginout}>
<span
className="glyphicon glyphicon-log-out"></span> {this.state.isSignedIn ? "Sign Out": "Sign In"}
</button></a>
</li>
</ul>
</div>
</div>
</nav>
</div>
)
}
}
Файл: Discasst\src\main\resources\static\app\components\feedPage\FeedPage.js
import Navbar from '../Navbar';
import PodcastPageContent from "../podcastPage/PodcastPageContent";
const React = require('react');
export default class FeedPage extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<Navbar history={this.props.history}/>
<div className="container-fluid">
<div style={{display: "flex",}}>
<div style={{width: "25%"}}>
</div>
<div style={{width: "50%", textAlign: "center"}}>
<PodcastPageContent
history={this.props.history}
feed={true}
/>
</div>
<div style={{width: "25%"}}>
</div>
</div>
</div>
</div>
)
}
}
Файл: Discasst\src\main\resources\static\app\components\login\RegisterPage.js
const React = require('react');
import {getFullCSRFParam} from "../Helper";
var errorEnum = {
NONE: "",
UNKNOWN: "Unknown error. Try again.",
USERNAME_TAKEN: "This login is already taken.",
LONG_USERNAME: "Login is too long (max length: 16).",
LONG_NAME: "Name is too long (max length: 16).",
WRONG_NAME: "Wrong name (allowed characters: a-Z, а-Я, 0-9, ' ').",
WRONG_USERNAME: "Wrong login (allowed characters: a-Z, 0-9, _).",
WRONG_EMAIL: "Wrong email (exemple: abc-42@xyz.com).",
WRONG_PASS: "Wrong password (allowed characters: a-Z, а-Я, 0-9).",
WRONG_PASS_LENGTH: "Password length must be 4-20 characters.",
WRONG_PASS_REPEAT: "Passwords don't match.",
};
export default class RegisterPage extends React.Component {
constructor(props) {
super(props);
this.state = {
password: '',
username: '',
name: '',
email: '',
success: false,
error: errorEnum.NONE
};
}
componentDidMount() {
$('form').submit(false);
}
onChangeUsername(event) {
this.setState({username: event.target.value});
}
onChangePass(event) {
this.setState({password: event.target.value});
}
onChangeName(event) {
this.setState({name: event.target.value});
}
onChangeEmail(event) {
this.setState({email: event.target.value});
}
register() {
if (!this.fullCheckPass()) return;
fetch(`/addUser?` +
`username=${this.state.username}` + `&` +
`password=${this.state.password}` + `&` +
`name=${this.state.name}` + `&` +
`email=${this.state.email}` + `&` +
getFullCSRFParam(), {
method: 'POST'
}).then((response) => {
let status = response.headers.get("newUserStatus");
if (status === "ok") {
this.setState({success: true, error: errorEnum.NONE});
setTimeout(() => {
this.props.history.push(`/signin`);
}, 1500)
}
else if (status === "usernameError") {
this.setState({success: false, error: errorEnum.USERNAME_TAKEN});
document.getElementById("login").focus();
}
else this.setState({success: false, error: errorEnum.UNKNOWN});
});
}
fullCheckPass() {
this.setState({error: errorEnum.NONE});
if (!this.validUsername()) return false;
if (!this.validName()) return false;
if (!this.validPassword()) return false;
if (!this.validEmail()) return false;
return true;
}
validUsername() {
var usernameRegex = /^[a-zA-Z0-9_]+$/;
var login = this.state.username;
if (login.length > 16) {
this.setState({error: errorEnum.LONG_USERNAME});
document.getElementById("login").focus();
return false;
}
var res = login.match(usernameRegex);
if (res === null) {
this.setState({error: errorEnum.WRONG_USERNAME});
document.getElementById("login").focus();
return false;
}
return true;
}
validPassword() {
var passRegex = /^[a-zA-Zа-яА-Я0-9]+$/;
var pass = this.state.password;
if (pass.length > 20 || pass.length < 4) {
this.setState({error: errorEnum.WRONG_PASS_LENGTH});
document.getElementById("pass").focus();
return false;
}
var res = pass.match(passRegex);
if (res === null) {
this.setState({error: errorEnum.WRONG_PASS});
document.getElementById("pass").focus();
return false;
}
return true;
}
validName() {
var nameRegex = /^[a-zA-Zа-яА-Я0-9 ]+$/;
var name = this.state.name;
if (name.length > 16) {
this.setState({error: errorEnum.LONG_NAME});
document.getElementById("name").focus();
return false;
}
var res = name.match(nameRegex);
if (res === null) {
this.setState({error: errorEnum.WRONG_NAME});
document.getElementById("name").focus();
return false;
}
return true;
}
validEmail() {
var emailRegex = /^[a-z0-9-\\.]+@[a-z-]+.[a-z]+$/;
var email = this.state.email;
var res = email.match(emailRegex);
if (res === null) {
this.setState({error: errorEnum.WRONG_EMAIL});
document.getElementById("email").focus();
return false;
}
return true;
}
render() {
const tss = this.state.success;
const tse = this.state.error;
return (
<div className="center-block main-center" style={{maxWidth: 500}}>
<hr className="hr100"/>
<div className="panel panel-info">
<div className="panel-body center-block" style={{maxWidth: 400}}>
<form onSubmit={this.register.bind(this)} className="form-signin">
<hr className="hr10"/>
<div className="input-group">
<span className="input-group-addon">Login</span>
<input id="login" className="form-control" required autoFocus
onChange={this.onChangeUsername.bind(this)}/>
</div>
<hr className="hr15"/>
<div className="input-group">
<span className="input-group-addon">Password</span>
<input id="pass" type="password" className="form-control" required
onChange={this.onChangePass.bind(this)}/>
</div>
<hr className="hr15"/>
<...
Подобные документы
Обзор существующих технологий разработки программного обеспечения. Описание платформы NET Framework. Принцип работы платформы: компиляция исходного кода; процесс загрузки и исполнения кода; IL-код и верификация. Новые возможности платформы NET Framework.
реферат [30,7 K], добавлен 01.03.2011Последовательность разработки информационного обеспечения очного и дистанционного обучения через просмотры и прослушивание подкастов. Создание веб-сайта или модуля существующей системы. Описание интерфейсов системы. Настройка прав доступа к подкастам.
дипломная работа [2,3 M], добавлен 19.11.2010Знакомство с особенностями и этапами разработки приложения для платформы Android. Рассмотрение функций персонажа: бег, прыжок, взаимодействие с объектами. Анализ блок-схемы алгоритма генерации платформ. Способы настройки функционала рабочей области.
дипломная работа [3,4 M], добавлен 19.01.2017Основы работы с многооконным графическим пользовательским интерфейсом операционной системы Windows95/NT. Основы работы с прикладными программами Windows и DOS. Разработка простого приложения для Windows при помощи средства разработки приложений DELPHI.
контрольная работа [281,0 K], добавлен 15.01.2009Облачные технологии - использование приложения, расположенного на удаленных серверах, посредством удобного пользовательского интерфейса. История и перспективы их развития. Платформы обслуживания "облаков". Положительные и отрицательные стороны сервисов.
презентация [770,2 K], добавлен 14.03.2017Отличительные черты смартфонов и коммуникаторов от обычных мобильных телефонов, их дополнительные возможности. Назначение и конфигурация платформы J2ME, ее функции. Порядок проектирования приложения для мобильного телефона на основе платформы J2ME.
дипломная работа [3,6 M], добавлен 05.09.2009Анализ хозяйственной деятельности организации и ее состояния. Особенности работы мобильной платформы. Реквизитный состав документов. Программная реализация и оценка эффективности приложения. Безопасность работы с приложением и безопасность данных.
дипломная работа [1,0 M], добавлен 13.06.2014Рассмотрение поисковых систем интернета как программно-аппаратного комплекса с веб-интерфейсом, предоставляющего возможность поиска информации. Виды поисковых систем: Archie, Wandex, Aliweb, WebCrawler, AltaVista, Yahoo!, Google, Яндекс, Bing и Rambler.
реферат [24,3 K], добавлен 10.05.2013База знаний интеллектуальной справочной системы по алгебре дробей со стандартными набором информационно-поисковых операций, пользовательским интерфейсом. Тестирование на стандартных вопросах и шаблонах поиска. Интеграция со смежными предметными областями.
курсовая работа [12,3 M], добавлен 06.05.2011Описание языков программирования Java и JavaFX. Среда разработки NetBeans и класс численных методов. Архитектура и принцип работы апплета с понятным пользовательским интерфейсом. Разработка алгоритма программы на примере модели межвидовой конкуренции.
курсовая работа [1023,2 K], добавлен 19.09.2012Понятие и функциональные особенности Java Card как версии Java-платформы для устройств с крайне ограниченными вычислительными ресурсами, оценка ее возможностей и необходимых ресурсов. Анализ степени безопасности платформы, взаимодействие компонентов.
презентация [1,0 M], добавлен 19.05.2014Описание платформы Deductor, ее назначение. Организационная структура аналитической платформы Deductor, состав модулей. Принципы работы программы, импорт и экспорт данных. Визуализация информации, сценарная последовательность и мастер обработки.
курсовая работа [3,7 M], добавлен 19.04.2014Рассмотрение и анализ моделей и алгоритмов семантического поиска в мультиагентной системе поддержки пользователей. Ознакомление с интерфейсом чата с ботом. Изучение и характеристика экспериментальных оценок релевантности и пертинентности запросов.
дипломная работа [3,0 M], добавлен 13.10.2017Изучение информационной базы клиента "Управление торговлей". Выбор и изучение платформы для построения сайта. Выбор технологии и среды разработки. Разработка основных алгоритмов решения задач и хранения данных. Проектирование интерфейса пользователя.
дипломная работа [1,1 M], добавлен 20.05.2017Разработка базы данных средней сложности с типовым пользовательским интерфейсом, а в частности, разработка базы данных СНАБЖЕНИЕ МАГАЗИНОВ на основе реляционной системы управления базами данных Microsoft Access, входящей в комплект Microsoft Office.
курсовая работа [2,1 M], добавлен 02.12.2012Разработка компьютерного приложения "Кипящая жидкость" с применением навыков программирования на языке Java. Проектирование алгоритма для решения поставленной задачи, его предметная область. Создание приложения с графическим пользовательским интерфейсом.
отчет по практике [3,0 M], добавлен 29.10.2015Возможности среды программирования delphi при разработке приложения с визуальным интерфейсом. Разработка спецификации программного обеспечения и на ее основе кода программного продукта. Отладка программы "трассировкой", ее тестирование и оптимизация.
курсовая работа [501,4 K], добавлен 07.12.2016Возможность поиска информации в режиме продвинутого диалога на естественном языке. Системы с интеллектуальным интерфейсом. Экспертные, самообучающиеся и адаптивные системы. Интеллектуальные базы данных. Системы контекстной и когнитивной помощи.
презентация [224,2 K], добавлен 16.10.2013Средства поиска информации в сети Интернет. Основные требования и методика поиска информации. Структура и характеристика поисковых сервисов. Глобальные поисковые машины WWW (World Wide Web). Планирование поиска и сбора информации в сети Интернет.
реферат [32,2 K], добавлен 02.11.2010Создание информационной системы работы такси с целью обеспечения диспетчерам более быстрого и удобного поиска необходимой информации. Создание таблиц и связей для работы с базами данных в среде Microsoft Access 2007. разработка запросов и отчетов.
курсовая работа [3,1 M], добавлен 06.05.2013