<repo_name>keenkit/FullStack<file_sep>/springmvc/README.md
## Description

MVC login page with Capture

## Screenshot

1 . Login page

![Login](assets/login.png "Login")

2 . Registration page

![registration](assets/registration.png "registration")

3 . After login

![dummy](assets/dummy.png "dummy")


## How to run in intellij?

1 . Folder structure

![set1](assets/set1.png "set1")

2 . Project settings

![set2](assets/set2.png "set2")

3 . Embed tomcat

![set3](assets/set3.png "set3")

![set4](assets/set4.png "set4")<file_sep>/springboot/src/main/resources/schema.sql
CREATE TABLE tb_user (
  user_id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY,
  name VARCHAR(50) not null,
  email VARCHAR(50) not null,
  username VARCHAR(50) unique not null,
  password VARCHAR(60) not null,
  admin boolean not null default FALSE
);<file_sep>/AngularVideoPlayer/src/app/models/player.model.ts

export enum PlayerEvent {
  PLAY,
  PAUSE,
  MUTE,
  STOP,
  VOLUME_CHANGE,
  LIKE,
  UNLIKE,
}

export class VideoPlayer {
  isMuted = true;
  isPlaying = false;

  volumeDisplay = '100%';

  muted = false;
  volume = 1;
  currentTime = 0;
  duration = 0;
  src = '';

  play(): void {}
  pause(): void {}
  timeupdate(): void {}
}
<file_sep>/007Mysql/README.md
## Assignment

Questions

1. **What should be done to make users pair insertion unique i.e. to avoid duplicate user relationship creation?**

   Answer: Set user_one_id, user_two_id as primary key in table relationship.

   

2. **What will be the insert query to insert a new Friend request sent by user 1 to user 2?**

   Answer: 

   ```sql
   Insert into relationship values (1, 2, 0, 1);
   ```

   

3. **What will be the query to update the status of the friend request i.e. accepting friend request sent to user 2 by user 1?**

   Answer:

   ```sql
   Update relationship set status = 1, action_user_id = 2 where user_one_id = 1 and user_two_id = 2;
   ```

   

4. **What will be the query to check if any two users are friends?**

   Answer:

   ```sql
   Select * from relationship where ((user_one_id = <user1> and user_two_id = <user2>) or (user_one_id = <user2> and user_two_id = <user1>)) and status = 1;
   ```

   

5. **What will be the query to retrieve all the users’friends? Here user 1 is the logged in user.**

   Answer:

   ```sql
   Select * from relationship where (user_one_id = 1 or user_two_id = 1) and status = 1;
   ```

   

6. **What will be the query to get the entire pending user request for the user from other users? Here user 1 is logged in**

   Answer:

   ```sql
   Select * from relationship where user_two_id = 1 and status = 0;
   ```

   

7. **What will be the query to retrieve the friend request status when the logged in user visits the profile of another user? Here, user 1 is the logged in user. User 1 visits the profile of user7**

   Answer:

   ```sql
   Select status from relationship where (user_one_id = 1 and user_two_id = 7) or (user_one_id = 7 and user_two_id = 1);
   ```

   

<file_sep>/springboot/src/main/resources/data.sql
insert into tb_user(name,email,username,password,admin) values
('admin', '<EMAIL>', 'admin', 'admin', TRUE),
('john', '<EMAIL>', 'john', 'john', FALSE);
<file_sep>/AngularVideoPlayer/src/app/models/video.model.ts
export class Video {
  id = 0;
  title = '';
  url = '';
  like = 0;
  unlike = 0;
}
<file_sep>/AngularVideoPlayer/src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PlayerComponent } from './modules/player/player.component';
import { ControlsComponent } from './modules/controls/controls.component';
import { PlaylistComponent } from './modules/playlist/playlist.component';
import { ModulesComponent } from './modules/modules.component';
import { ManagementComponent } from './modules/management/management.component';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    PlayerComponent,
    ControlsComponent,
    PlaylistComponent,
    ManagementComponent,
    ModulesComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    NgxDatatableModule,
    HttpClientModule,
    FormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
<file_sep>/springboot/src/main/java/com/ibm/demo/service/UserService.java
package com.ibm.demo.service;

import com.ibm.demo.domain.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;

public interface UserService extends UserDetailsService {

    List<User> findAllUsers();

    User findByUsername(String username);

    void updateUser(User user);

    UserDetails loadUserByUsername(String username);

    User saveUser(User user);
}
<file_sep>/springboot/README.md
## Description

Springboot login page with Capture

## Repository
https://github.com/keenkit/FullStack/tree/master/springboot

## Screenshot

1 . Login page

![Login](assets/login.png "Login")

2 . Registration page

![registration](assets/registration.png "registration")

3 . After login

![dummy](assets/dummy.png "dummy")<file_sep>/react-video-player/src/components/Playlist.js
import React from 'react';
import emitter from "../services/playerService";
import videoService from '../services/videoService';

class Playerlist extends React.Component {
  constructor () {
    super()
    this.state = {
      videos: []
    }
  }
  
  componentWillMount() {
    this.getVideos();
    // Listen to the event from (adding/removing/editing videos)
    this.eventEmitter = emitter.addListener("onRefreshVideos", (videos) => {
      this.setState({
        videos: videos
      })
    })
  }

  getVideos() {
    videoService.getVideos()
    .then(response => response.json())
    .then(videos => {
      this.setState({
        videos: videos
      })
    })
  }

  onPlay(video) {
    this.setState({
      isPlaying: true
    })
    console.log(video);
    emitter.emit("switch", video);
  }

  render() {
    return (
      <div className="media-player-list">
      <h2>Play list</h2>
      <ul className="list-group list-group-flush">
        {
          this.state.videos.map(
            video => 
            <li className="list-group-item" key={video.id} onClick={() => this.onPlay(video)}>
              <i className="fas fa-video playlistItem"></i>
              {video.title}
          </li>
          )
        }
      </ul>
    </div>
    );
  }
}

export default Playerlist;<file_sep>/AngularVideoPlayer/README.md
# AngularVideoPlayer

The Angualr project for Video Player

Git: https://github.com/keenkit/FullStack/tree/master/AngularVideoPlayer

# How to run?

```
npm install

# Start the json-server:
json-server --watch db.json

# Start the app
ng serve

# Open the browser http://localhost:4200
```

# Demo

![Screenshot](assets/Player_Demo.png "Screenshot")


![Screenshot](assets/Management_Demo.png "Screenshot")<file_sep>/SalaryPredictor/src/assignment4/Increment.java
package assignment4;

import java.math.BigDecimal;

public class Increment extends AbstractSalary {

  private int numberOfIncrements;
  private BigDecimal incrementPercent;
  private BigDecimal incrementAmount;

  public Increment(double startingSalary, double incrementPercent, int numberOfIncrements) {
    super(startingSalary);
    this.incrementPercent = new BigDecimal(incrementPercent).setScale(2, BigDecimal.ROUND_HALF_UP);
    this.numberOfIncrements = numberOfIncrements;
    this.incrementAmount = BigDecimal.ZERO;
    calcDeltaAmount();
  }

  private void calcDeltaAmount() {
    BigDecimal currSal = startingSalary;
    for (int i = 0; i<numberOfIncrements; i++) {
      currSal = currSal.multiply(incrementPercent.add(HUNDRED).divide(HUNDRED));
    }
    this.incrementAmount = currSal.subtract(startingSalary).setScale(2, BigDecimal.ROUND_HALF_UP);
  }

  public int getNumberOfIncrements() {
    return numberOfIncrements;
  }

  public BigDecimal getIncrementPercent() {
    return incrementPercent;
  }

  public BigDecimal getIncrementAmount() {
    return incrementAmount;
  }
}
<file_sep>/react-video-player/README.md
# Description

The React project for Video Player
URL : https://github.com/keenkit/FullStack/tree/master/react-video-player

# How to run?

```
npm install

# Start the json-server:
json-server -p 4000 db.json

# Start the app
npm start
# Open localhost:3000
```
# Demo
![Screenshot](assets/demo.png "Screenshot")<file_sep>/AngularVideoPlayer/src/app/modules/player/player.component.ts
import { Component, OnInit, OnDestroy, ElementRef } from '@angular/core';
import { PlayerService } from 'src/app/services/player.service';
import { PlayerEvent, VideoPlayer } from 'src/app/models/player.model';
import { Subscription } from 'rxjs';
import { Video } from 'src/app/models/video.model';

@Component({
  selector: 'app-player',
  templateUrl: './player.component.html',
  styleUrls: ['./player.component.scss']
})
export class PlayerComponent implements OnInit, OnDestroy {

  private controlEventsSubscribe: Subscription;
  private siwtchVideoEventSubscribe: Subscription;

  public videoSourceUrl = 'http://vjs.zencdn.net/v/oceans.mp4';  // Default URL
  public currentPlayingVideo: Video = new Video();

  constructor(
    private el: ElementRef,
    private playerService: PlayerService) {}

  ngOnInit() {
    // Add event for timeupdate during playing video
    this.el.nativeElement.querySelector('.media-video').addEventListener('timeupdate', () => {
      const percentage = Math.floor((100 / this.playerService.VideoPlayer.duration)
      * this.playerService.VideoPlayer.currentTime);
      this.playerService.videoPercentageUpdateEvent.emit(percentage);
    });

    // Set up the videoPlayer instance in playerService
    this.playerService.VideoPlayer = this.el.nativeElement.querySelector('.media-video');

    this.controlEventsSubscribe = this.playerService.controlEvents.subscribe((event: PlayerEvent) => {
    switch (event) {
      case PlayerEvent.PLAY:
        // Need to set to `muted` for autoplaying, otherwise will throw error.
        // See more from
        // https://stackoverflow.com/questions/40276718/how-to-handle-uncaught-in-promise-domexception-the-play-request-was-interru
        this.playerService.VideoPlayer.muted = true;
        this.playerService.VideoPlayer.play();
        break;

      case PlayerEvent.PAUSE:
        this.playerService.VideoPlayer.pause();
        break;

      case PlayerEvent.STOP:
        this.handleStopEvent();
        break;

      case PlayerEvent.MUTE:
        this.handleMuteEvent();
        break;

      case PlayerEvent.VOLUME_CHANGE:
        this.handleVolumeChange();
        break;
      }
    });

    this.siwtchVideoEventSubscribe = this.playerService.switchVideoEvent.subscribe((video: Video) => {
      this.handleSwitchVideoEvent(video);
    });

  }

  ngOnDestroy() {
    this.controlEventsSubscribe.unsubscribe();
    this.siwtchVideoEventSubscribe.unsubscribe();
  }

  private handleMuteEvent() {
    this.playerService.VideoPlayer.muted = !this.playerService.VideoPlayer.muted;
  }

  private handleVolumeChange() {
    this.playerService.VideoPlayer.volume = this.playerService.Volume;
  }

  private handleStopEvent() {
    this.playerService.VideoPlayer.pause();
    this.playerService.VideoPlayer.currentTime = 0;
  }

  private handleSwitchVideoEvent(video: Video) {
    this.currentPlayingVideo = video;
    this.playerService.VideoPlayer.src = video.url;
    this.handleStopEvent();
    this.playerService.controlEvents.emit(PlayerEvent.PLAY);
    this.playerService.VideoPlayer.isPlaying = true;  // For buttons style
  }

}
<file_sep>/springboot/src/main/java/com/ibm/demo/service/UserServiceImpl.java
package com.ibm.demo.service;

import com.ibm.demo.dao.UserDao;
import com.ibm.demo.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

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

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private PasswordEncoder encoder;

    @Override
    public List<User> findAllUsers() {
        return userDao.findAll();
    }

    @Override
    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = this.findByUsername(username);

        if (user == null) {
            throw new UsernameNotFoundException("User does not exist.");
        }

        GrantedAuthority roleUser = new SimpleGrantedAuthority("ROLE_USER");

        Collection<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
        grantedAuths.add(roleUser);

        if (user.isAdmin()) {
            GrantedAuthority roleAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");
            grantedAuths.add(roleAdmin);
        }

        return new org.springframework.security.core.userdetails.User(username, user.getPassword(), grantedAuths);

    }

    @Override
    public User saveUser(User user) {
        user.setPassword(encoder.encode(user.getPassword()));
        return userDao.save(user);
    }

    @Override
    public void updateUser(User user) {
        user.setPassword(encoder.encode(user.getPassword()));
        userDao.save(user);
    }
}
<file_sep>/SalaryPredictor/src/assignment4/PredictionReport.java
package assignment4;

public class PredictionReport extends AbstractReport {

  private static final String INCREMENT_AMOUNT = "Increment Amount";
  private static final String DEDUCTION_AMOUNT = "Deduction Amount";
  private static final String SALARY_GROWTH = "Salary Growth";

  private Prediction[] predictions;

  public PredictionReport(Prediction[] predictions) {
    super(predictions.length);
    this.predictions = predictions;
    addToHeader(INCREMENT_AMOUNT);
    addToHeader(DEDUCTION_AMOUNT);
    addToHeader(SALARY_GROWTH);
  }

  public void print() {
    printDivider();
    printHeader();
    printDivider();
    for (int i = 0; i < year; i++) {
      printLine(i + 1, predictions[i]);
      printDivider();
    }
  }

  private void printLine(int year, Prediction pred) {
    printLine(year, new String[]{
        pred.getStartingSalary().toPlainString(),
        pred.getIncrementAmount().toPlainString(),
        pred.getDeductionAmount().toPlainString(),
        pred.getSalaryGrowth().toPlainString(),
    });
  }
}
<file_sep>/001VideoPlayer/README.md
## Description

Video Player for demo.

## Demo

![Screenshot](assets/example.png "Screenshot")
<file_sep>/springboot/src/main/java/com/ibm/demo/config/WebSecurityConfig.java
package com.ibm.demo.config;

import javax.servlet.Filter;
import javax.sql.DataSource;

import com.ibm.demo.security.KaptchaAuthenticationFilter;
import com.ibm.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userService;

    @Autowired
    private DataSource dataSource;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        tokenRepository.setCreateTableOnStartup(false);
        return tokenRepository;

    }
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        Filter filter = new KaptchaAuthenticationFilter("/login", "/login?error");
        http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);

        //allow same origin request from h2 console
        http.headers().frameOptions().sameOrigin();

        http
            .authorizeRequests()

            // Common locations for static resources.
            .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()

            .antMatchers("/","/register", "/captcha_image**", "/h2/**").permitAll()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasRole("USER")

            // every request requires the user to be authenticated
            .anyRequest().authenticated()

            .and()

            // form based authentication is supported
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/user", true)

            // we need to instruct Spring Security to allow anyone to access the /login URL
            .permitAll()

            .and()

            // remember me
            .rememberMe()
            .tokenRepository(persistentTokenRepository())
            .tokenValiditySeconds(3600 * 24)
            .userDetailsService(userService)

            .and()

            // logout().permitAll() allows any user to request logout and view logout success URL.
            .logout().permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
        auth.authenticationProvider(authenticationProvider());
    }
}
<file_sep>/001VideoPlayer/player.js
window.onload = function() {
	var videoPlayer = document.getElementById('media-video');
	
  var playBtn = document.getElementById('play-button');
  var pauseBtn = document.getElementById('play-pause-button');
  var muteBtn = document.getElementById('mute-button');
  var progressBar = document.getElementById('progress-bar');

  var likeBtn = document.getElementById('like-button');
  var unlikeBtn = document.getElementById('unlike-button');
	var likeSpan = document.getElementById('video-like');
  var unlikeSpan = document.getElementById('video-unlike');
  
  var volume = document.getElementById('video-volume');
  var volUpBtn = document.getElementById('volume-up-button');
  var volDownBtn = document.getElementById('volume-down-button');
  var stopBtn = document.getElementById('stop-button');
  var volume;
  volume.innerText = '100%';

	// disable default controls
  videoPlayer.controls = false;
  
  playBtn.addEventListener('click', function() {
    videoPlayer.play();
    playBtn.disable = true;
    pauseBtn.disable = false;
  });

  pauseBtn.addEventListener('click', function() {
    videoPlayer.pause();
    playBtn.disable = false;
    pauseBtn.disable = true;
  });

  muteBtn.addEventListener('click', function() {
    if (videoPlayer.muted) {
      muteBtn.innerHTML = '<i id="mute-icon" class="fas fa-volume-down">';
      videoPlayer.muted = false;
    } else {
      muteBtn.innerHTML = '<i id="mute-icon" class="fas fa-volume-mute">';
      videoPlayer.muted = true;
    }
  });

  volUpBtn.addEventListener('click', function() {
    if (videoPlayer.volume === 1) {
      return;
    }
    videoPlayer.volume = videoPlayer.volume + 0.1;
    videoPlayer.volume = parseFloat(videoPlayer.volume).toFixed(1);
    volume.innerText = videoPlayer.volume * 100 + '%' ;
  });

  volDownBtn.addEventListener('click', function() {
    if (videoPlayer.volume === 0) {
      return;
    }
    videoPlayer.volume = videoPlayer.volume - 0.1;
    videoPlayer.volume = parseFloat(videoPlayer.volume).toFixed(1);
    volume.innerText = videoPlayer.volume * 100 + '%';
  });  

  stopBtn.addEventListener('click', function() {
    videoPlayer.pause();
    videoPlayer.currentTime = 0;
    playBtn.disable = true;
    pauseBtn.disable = false;
    stopBtn.disable = true;
  });

	videoPlayer.addEventListener('timeupdate', function() {
    var percentage = Math.floor((100 / videoPlayer.duration) * videoPlayer.currentTime);
    progressBar.setAttribute("style", "width: "+percentage + "%;");
    progressBar.setAttribute("aria-valuenow", percentage);
	  progressBar.innerHTML = percentage + '% played';
  }, false);

  videoPlayer.addEventListener('ended', function() { 
    this.pause(); 
  }, false);

  likeBtn.addEventListener('click', function() {
    if (localStorage.getItem('like')) {
      localStorage.setItem('like', parseFloat(localStorage.getItem('like')) + 1);
      likeSpan.innerText = localStorage.getItem('like');
    } else {
      localStorage.setItem('like', 0);
    }
  });

  unlikeBtn.addEventListener('click', function() {
    if (localStorage.getItem('unlike')) {
      localStorage.setItem('unlike', parseFloat(localStorage.getItem('unlike')) + 1);
      unlikeSpan.innerText = localStorage.getItem('unlike');
    } else {
      localStorage.setItem('unlike', 0);
    }
  });

  resetLikeAndUnlike(likeSpan, 'like');
  resetLikeAndUnlike(unlikeSpan, 'unlike');

  /**
   * The following code just for demo's purpose.
   * All the data will be load automatically from JSON in real scenarios.
   */
  var video1 = document.getElementById('video1');
  var video2 = document.getElementById('video2');
  var video3 = document.getElementById('video3');

  video1.addEventListener('click', function() {
    loadVideo(this, videoPlayer);
    document.getElementById('media-player').style.height = "700px";
  });

  video2.addEventListener('click', function() {
    loadVideo(this, videoPlayer);
    document.getElementById('media-player').style.height = "700px";
  });

  video3.addEventListener('click', function() {
    loadVideo(this, videoPlayer);
    document.getElementById('media-player').style.height = "550px";
  }); 
};

function resetLikeAndUnlike(elem, key) {
  if (!localStorage.getItem(key)) {
    localStorage.setItem(key, 0);
  }
  elem.innerText = localStorage.getItem(key);
}

function loadVideo(video, videoPlayer) {
  videoPlayer.src = video.title;
  videoPlayer.load();
  videoPlayer.play();
}
<file_sep>/AngularVideoPlayer/src/app/models/constant.model.ts
export class Constants {
  public static readonly VIDEO_URL = 'http://localhost:3000/videos';
}
<file_sep>/README.md
# FullStack

Remote git address:
https://github.com/keenkit/FullStack

For UI Assignment 1:
https://github.com/keenkit/FullStack/tree/master/001VideoPlayer

For UI Assignment 2:
https://github.com/keenkit/FullStack/tree/master/AngularVideoPlayer

For UI Assignment 3:
https://github.com/keenkit/FullStack/tree/master/react-video-player

For UI Assignment 4:
https://github.com/keenkit/FullStack/tree/master/SalaryPredictor

For UI Assignment 5:
https://github.com/keenkit/FullStack/tree/master/springmvc

For UI Assignment 6:
https://github.com/keenkit/FullStack/tree/master/springboot

For UI Assignment 7:
https://github.com/keenkit/FullStack/tree/master/007Mysql
<file_sep>/react-video-player/src/components/Management.js
import React from 'react';
import videoService from '../services/videoService';
import emitter from "../services/playerService";

class Management extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      videos: [],
      id: '',
      title: '',
      url: '',
      isCurrentRowEditable: false
    }
    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
  }

  handleChange(event) {
    this.setState({ 
      [event.target.name]: event.target.value
    })
  }

  handleSubmit(event) {
    const newVideo = {
      id: Number(this.state.id),
      title: this.state.title,
      url: this.state.url,
      like: 0,
      unlike: 0
    }
    videoService.createVideo(newVideo)
      .then(response => {
        this.resetInput();
        this.refreshVideos();
      });
    event.preventDefault();
  }

  resetInput = () => {
    this.setState({
      id: '',
      title: '',
      url: ''
    });
  }

  componentWillMount() {
    this.refreshVideos();
  }

  refreshVideos() {
    videoService.getVideos()
    .then(response => response.json())
    .then(videos => {
      this.setState({
        videos: videos
      })
      // Notify the PlayList to update the video list.
      emitter.emit('onRefreshVideos', videos);
    })
  }

  onEditRow(video){
    this.setState({
      isCurrentRowEditable: true,
      currentRowId: video.id,
    });
  }

  onDeleteVideo(video) {
    if (window.confirm(`Are you sure to remove the video ${video.title}?`)) {
      videoService.deleteVideo(video.id)
        .then(response => this.refreshVideos());
    }
  }

  onApprove(video) {
    const title = this.state.rowTitle || video.title; 
    const url = this.state.rowUrl || video.url;

    const currentRowId = Number(this.state.currentRowId);
    let toBeUpdatedVideo = this.state.videos.filter(v => v.id === currentRowId)[0];

    toBeUpdatedVideo.title = title;
    toBeUpdatedVideo.url = url;
    console.log(toBeUpdatedVideo);
    videoService.updateVideo(toBeUpdatedVideo.id, toBeUpdatedVideo)
      .then(response => {
        this.refreshVideos()
        this.setState({
          isCurrentRowEditable: false
        });
      });
  }

  render() {
    return (
      <div>
        <h2>Add new video</h2>
        <div className="row">
          <div className="col-lg-6 mt-2 mb-5">
            <form onSubmit={this.handleSubmit}>
              <div className="form-group">
                <label>ID:</label>
                <input type="text" className="form-control" 
                  value={this.state.id} name="id" onChange={this.handleChange} placeholder="Enter ID" />
              </div>  
              <div className="form-group">
                <label>Title:</label>
                <input type="text" className="form-control" 
                  value={this.state.title} name="title" onChange={this.handleChange} placeholder="Enter Title" />
              </div>
              <div className="form-group">
                <label>Youtube URL:</label>
                <input type="url" className="form-control" 
                  value={this.state.url} name="url" onChange={this.handleChange} autoComplete="off" placeholder="Enter URL" />
              </div>
              <button type="submit" className="btn btn-primary">Add Video</button>
            </form>
          </div>
        </div>        
        <div className="row">
          <table className="table table-dark">
            <thead>
              <tr>
                <th scope="col">S.no</th>
                <th scope="col">Title</th>
                <th scope="col">Url</th>
                <th scope="col">Actions</th>
              </tr>
            </thead>
            <tbody>
              {
                this.state.videos.map(
                  video => 
                  <tr key={video.id}>
                    <th scope="row">
                      <label>{video.id}</label>
                    </th>
                    <td>
                      {
                        this.state.isCurrentRowEditable && video.id === this.state.currentRowId 
                        ? 
                        <input className="form-control" type="text" name="rowTitle"
                          onChange={this.handleChange} 
                          value={this.state.rowTitle ? this.state.rowTitle : video.title} />
                        :
                        <label>{video.title}</label>
                      }
                    </td>
                    <td>
                    {
                        this.state.isCurrentRowEditable && video.id === this.state.currentRowId 
                        ? 
                        <input className="form-control" type="text" name="rowUrl"
                          onChange={this.handleChange} 
                          value={this.state.rowUrl ? this.state.rowUrl : video.url} />
                        :
                        <label>{video.url}</label>
                      }
                    </td>
                    <td>
                      <div className="actions-container">
                        <div className="action">
                          <button className="btn btn-light" type="button" onClick={(e) => this.onEditRow(video)}>
                            Edit</button>
                        </div>
                        <div className="action">
                          <button className="btn btn-danger" type="button" onClick={() => this.onDeleteVideo(video)}>
                            Delete</button>
                        </div>
                        <div className="action">
                          <button className="btn btn-primary" 
                            disabled={!(this.state.isCurrentRowEditable && video.id === this.state.currentRowId) } 
                            type="button" onClick={(e) => this.onApprove(video)}>
                            Approve</button>
                        </div>  
                      </div>  
                    </td>
                  </tr>
                )
              }
            </tbody>
          </table>            
        </div>  
      </div>      
    );
  }
}

export default Management;<file_sep>/AngularVideoPlayer/src/app/services/video.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { Video } from '../models/video.model';
import { Constants } from '../models/constant.model';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class VideoService {

  constructor(
    private http: HttpClient,
  ) { }

  public getVideos(): Observable<Video[]> {
    return this.http.get<Video[]>(Constants.VIDEO_URL)
      .pipe(
        tap(_ => console.log('Got vidoes')),
        catchError(this.handleError<Video[]>('getVideos', []))
      );
  }

  public getVideo(id: number): Observable<Video> {
    const url = `${Constants.VIDEO_URL}/${id}`;
    return this.http.get<Video>(url)
      .pipe(
        tap(_ => console.log(`Got vidoes id=${id}`)),
        catchError(this.handleError<Video>('getVideo'))
      );
  }

  public addVideo(video: Video): Observable<any> {
    return this.http.post(Constants.VIDEO_URL, video, httpOptions)
      .pipe(
        tap((newVideo: Video) => console.log(`Added video w/ id=${newVideo.id}`)),
        catchError(this.handleError<any>('updateVideo'))
      );
  }

  public updateVideo(video: Video): Observable<any> {
    const id = typeof video === 'number' ? video : video.id;
    const url = `${Constants.VIDEO_URL}/${id}`;
    return this.http.put(url, video, httpOptions)
      .pipe(
        tap(_ => console.log(`Updated video id=${video.id}`)),
        catchError(this.handleError<any>('updateVideo'))
      );
  }

  public deleteVideo(video: Video | number): Observable<Video> {
    const id = typeof video === 'number' ? video : video.id;
    const url = `${Constants.VIDEO_URL}/${id}`;
    return this.http.delete<Video>(url, httpOptions)
      .pipe(
        tap(_ => console.log(`Deleted video id=${id}`)),
        catchError(this.handleError<Video>('deleteVideo'))
      );
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error); // log to console instead
      return of(result as T);
    };
  }

}
<file_sep>/AngularVideoPlayer/src/app/services/player.service.ts
import { Injectable, Output, EventEmitter } from '@angular/core';
import { PlayerEvent, VideoPlayer } from '../models/player.model';
import { Video } from '../models/video.model';

@Injectable({
  providedIn: 'root'
})
export class PlayerService {

  /**
   * Handling control events
   */
  controlEvents: EventEmitter<PlayerEvent> = new EventEmitter();

  /**
   * Handling percentage update event during playing video.
   */
  videoPercentageUpdateEvent: EventEmitter<number> = new EventEmitter();

  /**
   * Handling switching video event
   */
  switchVideoEvent: EventEmitter<Video> = new EventEmitter();

  constructor() { }

  private videoPlayer: VideoPlayer = new VideoPlayer();

  public get VideoPlayer(): VideoPlayer {
    return this.videoPlayer;
  }

  public set VideoPlayer(value: VideoPlayer) {
    this.videoPlayer = value;
  }

  public get Volume(): number {
    return this.videoPlayer.volume;
  }

  public set Volume(value: number) {
    this.videoPlayer.volume = parseFloat(value.toFixed(1));
  }

  public get VolumeDisplay(): string {
    return this.videoPlayer.volume * 100 + '%';
  }

}
<file_sep>/AngularVideoPlayer/src/app/modules/management/management.component.ts
import { Component, OnInit } from '@angular/core';
import { VideoService } from 'src/app/services/video.service';
import { Video } from 'src/app/models/video.model';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
// import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-management',
  templateUrl: './management.component.html',
  styleUrls: ['./management.component.scss']
})
export class ManagementComponent implements OnInit {

  public videos: Video[];
  isEditable = {};
  public addVideoFormGroup: FormGroup;

  constructor(
    private videoService: VideoService,
    private formBuilder: FormBuilder,
  ) { }

  ngOnInit() {
    this.loadVideos();
    this.buildFormGroup();
  }

  // TODO Need to add validations
  private buildFormGroup() {
    this.addVideoFormGroup = this.formBuilder.group({
      id: new FormControl('', [
        Validators.required,
        Validators.pattern('[0-9]*'),
      ]),
      title: new FormControl('', Validators.required),
      url: new FormControl('http://', [
        Validators.required,
        Validators.pattern(/https?:\/\/\w+/),
      ])
    });
  }

  get id() { return this.addVideoFormGroup.get('id'); }
  get title() { return this.addVideoFormGroup.get('title'); }
  get url() { return this.addVideoFormGroup.get('url'); }

  private loadVideos() {
    this.videoService.getVideos().subscribe(
      videos => this.videos = videos
    );
  }

  delete(row, rowIndex) {
    this.videoService.deleteVideo(row.id).subscribe(
      () => this.loadVideos()
    );
  }

  // Save row
  save(row, rowIndex) {
    this.isEditable[rowIndex] = !this.isEditable[rowIndex];
    this.videoService.updateVideo(row).subscribe(
      () => this.loadVideos()
    );
  }

  addNewVideo() {
    if (this.addVideoFormGroup.valid) {
      const newVideo: Video = {
        id: Number(this.getFormValue('id')),
        title: this.getFormValue('title'),
        url: this.getFormValue('url'),
        like: 0,
        unlike: 0
      };
      this.videoService.addVideo(newVideo).subscribe(
        () => this.loadVideos()
      );
      this.addVideoFormGroup.reset({ url: 'http://' });
    }
  }

  private getFormValue(controlName) {
    return this.addVideoFormGroup.controls[controlName].value;
  }
}
<file_sep>/AngularVideoPlayer/src/app/modules/controls/controls.component.ts
import { Component, OnInit, ElementRef, OnDestroy } from '@angular/core';
import { PlayerEvent, VideoPlayer } from 'src/app/models/player.model';
import { PlayerService } from 'src/app/services/player.service';
import { Subscription } from 'rxjs';
import { Video } from 'src/app/models/video.model';
import { VideoService } from 'src/app/services/video.service';

@Component({
  selector: 'app-controls',
  templateUrl: './controls.component.html',
  styleUrls: ['./controls.component.scss']
})
export class ControlsComponent implements OnInit, OnDestroy {

  public playerInstance: VideoPlayer;
  // Set up default Video, will be overrided by loadFirstVideo()
  public currentPlayingVideo: Video = new Video();
  private videoPercentageUpdateEventSubscribe: Subscription;
  private siwtchVideoEventSubscribe: Subscription;

  constructor(
    private el: ElementRef,
    private playerService: PlayerService,
    private videoService: VideoService,
  ) { }

  ngOnInit() {
    this.loadFirstVideo();

    this.playerInstance = this.playerService.VideoPlayer;
    this.playerInstance.volumeDisplay = '100%'; // Default volume
    this.playerInstance.isMuted = true;

    this.videoPercentageUpdateEventSubscribe = this.playerService.videoPercentageUpdateEvent
    .subscribe((percentage: number) => {
      const progressBar = this.el.nativeElement.querySelector('#progress-bar');
      progressBar.setAttribute('style', 'width: ' + percentage + '%;');
      progressBar.setAttribute('aria-valuenow', percentage);
      progressBar.innerHTML = percentage + '% played';
    });

    // Subscribe the SwitchVideoEvent to set up number of `like` & `unlike`
    this.siwtchVideoEventSubscribe = this.playerService.switchVideoEvent.subscribe((video: Video) => {
      this.currentPlayingVideo = video;
    });
  }

  private loadFirstVideo() {
    this.videoService.getVideos().subscribe(
      (videos: Video[]) => {
        if (videos.length > 0) {
          this.currentPlayingVideo = videos[0];
          this.playerService.switchVideoEvent.emit(videos[0]);  // Start to play
        }
      });
  }

  ngOnDestroy() {
    this.videoPercentageUpdateEventSubscribe.unsubscribe();
    this.siwtchVideoEventSubscribe.unsubscribe();
  }

  onPlay() {
    this.playerService.controlEvents.emit(PlayerEvent.PLAY);
    this.playerInstance.isPlaying = true;
  }

  onPause() {
    this.playerService.controlEvents.emit(PlayerEvent.PAUSE);
    this.playerInstance.isPlaying = false;
  }

  onMute() {
    this.playerService.controlEvents.emit(PlayerEvent.MUTE);
    this.playerInstance.isMuted = true;
  }

  onUnMute() {
    this.playerService.controlEvents.emit(PlayerEvent.MUTE);
    this.playerInstance.isMuted = false;
  }

  onStop() {
    this.playerService.controlEvents.emit(PlayerEvent.STOP);
    this.playerInstance.isPlaying = false;
  }

  onLike() {
    this.currentPlayingVideo.like += 1;
    this.videoService.updateVideo(this.currentPlayingVideo).subscribe(
      (video) => this.currentPlayingVideo.like = video.like
    );
  }

  onUnlike() {
    this.currentPlayingVideo.unlike += 1;
    this.videoService.updateVideo(this.currentPlayingVideo).subscribe(
      (video) => this.currentPlayingVideo.unlike = video.unlike
    );
  }

  onVolumeUp() {
    this.playerService.controlEvents.emit(PlayerEvent.VOLUME_CHANGE);
    this.changeVolume(true);
  }

  onVolumeDown() {
    this.playerService.controlEvents.emit(PlayerEvent.VOLUME_CHANGE);
    this.changeVolume(false);
  }

  private changeVolume(up: boolean) {
    // Do not increase the volume if already 1.
    // Do not decrease the volume if already 0.
    if (
      ( up && this.playerService.Volume === 1)
      ||
      (!up && this.playerService.Volume === 0)
    ) {
      return;
    }

    const plusMinus = up ? 1 : -1;
    const delta = 0.1 * plusMinus;
    this.playerService.Volume += delta;
    this.playerInstance.volumeDisplay = this.playerService.VolumeDisplay;
  }
}
<file_sep>/react-video-player/src/components/Player.js
import React from 'react';
import emitter from "../services/playerService";

class Player extends React.Component {
  videoPlayerRef = React.createRef();
  constructor(props) {
    super(props);
    this.state = {
        msg: null,
    };
  }
  componentDidMount() {
    this.eventEmitter = emitter.addListener("onPlay", () => {
      this.videoPlayerRef.current.play();
    }).addListener("onPause", () => {
      this.videoPlayerRef.current.pause();
    }).addListener("onStop", () => {
      this.videoPlayerRef.current.pause();
      this.videoPlayerRef.current.currentTime = 0;
    }).addListener("onVolumeUp", (state) => {
      this.videoPlayerRef.current.volume = state.volume;
    }).addListener("onVolumeDown", (state) => {
      this.videoPlayerRef.current.volume = state.volume;
    }).addListener("onMute", () => {
      this.videoPlayerRef.current.muted = true;
    }).addListener("onUnMute", () => {
      this.videoPlayerRef.current.muted = false;
    }).addListener("switch", (video) => {
      this.videoPlayerRef.current.src = video.url;
      this.videoPlayerRef.current.play();
    })
  }

  onTimeUpdate() {
    const percentage = Math.floor((100 / this.videoPlayerRef.current.duration)
      * this.videoPlayerRef.current.currentTime);
    emitter.emit('timeupdate', percentage); 
  }

  componentWillUnmount(){
    emitter.removeListener(this.eventEmitter);
  }

  render() {
    return (
      <div className="playerWrapper">
        { this.state.msg }
        <video loop autoPlay muted className="media-video" 
          onTimeUpdate={()=>this.onTimeUpdate()} ref={this.videoPlayerRef} >
          <source src="http://vjs.zencdn.net/v/oceans.mp4" />
        </video>
      </div>
    );
  }
}

export default Player;<file_sep>/AngularVideoPlayer/src/app/modules/playlist/playlist.component.ts
import { Component, OnInit } from '@angular/core';
import { Video } from 'src/app/models/video.model';
import { VideoService } from 'src/app/services/video.service';
import { PlayerService } from 'src/app/services/player.service';

@Component({
  selector: 'app-playlist',
  templateUrl: './playlist.component.html',
  styleUrls: ['./playlist.component.scss']
})
export class PlaylistComponent implements OnInit {

  public videos: Video[];
  constructor(
    private videoService: VideoService,
    private playerService: PlayerService) { }

  ngOnInit() {
    this.loadVideos();
  }

  private loadVideos() {
    this.videoService.getVideos().subscribe(
      videos => this.videos = videos
    );
  }

  onPlay(video: Video) {
    this.videoService.getVideo(video.id).subscribe(
      respVideo => this.playerService.switchVideoEvent.emit(respVideo)
    );
  }

}
<file_sep>/007Mysql/Assignment7_2.sql
show databases;
create database if not exists testdb;
use testdb;
create table if not exists users(
	user_id INT auto_increment comment 'userId PK',
    username VARCHAR(256) NOT NULL,
    email VARCHAR(256),
    password VARCHAR(256) NOT NULL,
    Primary Key (user_id),
    UNIQUE KEY (username) USING BTREE
);

Select count(*) from relationship where (user_one_id = 1 and user_two_id = 2 and status = 1) 
OR (user_one_id = 2 and user_two_id = 1 and status = 1);

Select count(*) from relationship where (user_one_id = 1 and user_two_id = 7 and status = 1) 
OR (user_one_id = 7 and user_two_id = 1 and status = 1);

Select user_two_id from relationship where user_one_id = 1 and status = 1;

Select user_one_id from relationship where user_two_id = 1 and status = 1;

Select * from users where user_id in (
 (Select user_two_id from relationship where user_one_id = 1 and status = 1)
    UNION
    (Select user_one_id from relationship where user_two_id = 1 and status = 1)
);

Select * from users where user_id in (
 Select user_two_id from relationship where user_one_id = 1 and status = 1
)
OR user_id in (
    Select user_one_id from relationship where user_two_id = 1 and status = 1
);

-- 6
select * from relationship where user_two_id = 1 and status = 0;

-- 7
select status from relationship where user_one_id = 1 and user_two_id = 7;
<file_sep>/SalaryPredictor/src/assignment4/Deduction.java
package assignment4;

import java.math.BigDecimal;

public class Deduction extends AbstractSalary {

  private BigDecimal deductionAmount;
  private int numberOfDeductions;
  private BigDecimal deductionPercent;

  public Deduction(double startingSalary, double deductionAmount, int numberOfDeductions) {
    super(startingSalary);
    this.deductionAmount = new BigDecimal(deductionAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
    this.numberOfDeductions = numberOfDeductions;
    calcDeductionPerc();
  }

  private void calcDeductionPerc() {
    deductionPercent = deductionAmount.multiply(HUNDRED).divide(startingSalary, 2, BigDecimal.ROUND_HALF_UP);
  }

  public int getNumberOfDeductions() {
    return numberOfDeductions;
  }

  public BigDecimal getDeductionPercent() {
    return deductionPercent;
  }

  public BigDecimal getDeductionAmount() {
    return deductionAmount;
  }
}
<file_sep>/react-video-player/src/VideoPlayer.js
import React from 'react';
import './VideoPlayer.css';
import Player from './components/Player';
import Controller from './components/Controller';
import Playerlist from './components/Playlist';
import Management from './components/Management';

class VideoPlayer extends React.Component {
  render() {
    return (
      <div className="container">
        <div className="container-fluid">
          <div className="row">
            <div className="col-lg-9">
              <h2>React video player</h2>
              <Player />
              <Controller />
            </div>
            <div className="col-lg-3">
              <Playerlist />
            </div>
          </div>
          <Management />
        </div>
      </div>
    );
  }
}

export default VideoPlayer;<file_sep>/SalaryPredictor/src/assignment4/IncrementReport.java
package assignment4;

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

public class IncrementReport extends AbstractReport {

  private Increment increment;

  public IncrementReport(Increment increment, int year) {
    super(year);
    this.increment = increment;
    addToHeader("Number of Increments");
    addToHeader("Increment %");
    addToHeader("Increment Amount");
  }

  public void print() {
    incrLst.clear();
    printDivider();
    printHeader();
    printDivider();
    Increment currInc = increment;
    for (int i = 0; i < year; i++) {
      printLine(i + 1, currInc);
      printDivider();
      double nextSal = currInc.getStartingSalary().add(currInc.getIncrementAmount()).doubleValue();
      currInc = new Increment(nextSal,
          currInc.getIncrementPercent().doubleValue(),
          currInc.getNumberOfIncrements());
    }
  }

  private void printLine(int year, Increment incr) {
    incrLst.add(incr);
    printLine(year, new String[] {
        incr.getStartingSalary().toString(),
        String.valueOf(incr.getNumberOfIncrements()),
        incr.getIncrementPercent().toPlainString(),
        incr.getIncrementAmount().toPlainString(),
    });
  }

  private List<Increment> incrLst = new ArrayList<>();

  public List<Increment> getIncrements() {
    return incrLst;
  }
}
