<commit_before>import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

import { CmsService, HalDoc } from '../core';
import { ModalService, TabService, ToastrService } from 'ngx-prx-styleguide';
import { SeriesImportService } from './series-import.service';
import { SeriesModel, SeriesImportModel } from '../shared';
import { NEW_SERIES_VALIDATIONS } from '../shared/model/series.model';

import { map, throttle, takeUntil } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer';

@Component({
  providers: [TabService],
  selector: 'publish-series',
  styleUrls: ['series.component.css'],
  templateUrl: 'series.component.html'
})

export class SeriesComponent implements OnInit {

  private _onDestroy = new Subject();

  id: number;
  base: string;
  series: SeriesModel;
  storyCount: number;
  storyNoun: string;

  // podcast imports
  fromImport = false;

  constructor(
    public cms: CmsService,
    private modal: ModalService,
    public toastr: ToastrService,
    private route: ActivatedRoute,
    private importLoader: SeriesImportService,
    private router: Router
  ) {}

  ngOnInit() {
    this.route.params.forEach(params => {
     this.id = +params['id'];
     this.base = '/series/' + (this.id || 'new');
     this.loadSeries();
   });
  }

  ngOnDestroy() {
    this._onDestroy.next();
  }

  loadSeries() {
    if (this.id) {
      this.cms.auth.follow('prx:series', {id: this.id}).subscribe(
        s => {
          s.follow('prx:account').subscribe(a => {
            this.setSeries(a, s);
          });
        },
        err => {
          if (err.status === 404 && err.name === 'HalHttpError') {
            this.toastr.error('No series found. Redirecting to new series page');
            console.error(`Series with id ${this.id} not found`);
            setTimeout(() => this.router.navigate(['/series', 'new']), 3000);
          } else {
            throw(err);
          }
        }
      );
    } else {
      this.cms.defaultAccount.subscribe(a => this.setSeries(a, null));
    }
  }

  buildSeries(parent: any, series: any) {
    let newSeries = new SeriesModel(parent, series) 
    // Because the series state is split between component and model, make the
    // loadSeries method idempotent and preserve the podcast import polling 
    // state with each call. Then refresh the series model based on import 
    // status polling intervals.
    if(this.series){
      newSeries.seriesImports = this.series.seriesImports;
    }
    return newSeries;
  }

  setSeries(parent: any, series: any) {
    this.series = this.buildSeries(parent, series);
    if (series) {
      this.storyCount = series.count('prx:stories');
      this.storyNoun = this.storyCount === 1 ? 'Episode' : 'Episodes';
      this.setImportState();
      this.setSeriesValidationStrategy();
    } else {
      this.storyCount = null;
    }
    this.checkSeriesVersion();
  }

  checkSeriesVersion() {
    if (!this.series.isV4()) {
      let oldLink = `https://www.prx.org/series/${this.id}`;
      this.modal.alert(
        'Cannot Edit Series',
        `This series was created in the older PRX.org app, and must be
        edited there. <a target="_blank" href="${oldLink}">Click here</a> to view it.`,
        () => { window.history.back(); }
      );
    }
  }

  setImportState() {
    this.fromImport = this.series.doc.count('prx:podcast-imports') > 0;
    if (this.fromImport){
      this.pollForImportState();
    }
  }

  pollForImportState() {
    if(this.series.seriesImports !== null){
      return this.series.seriesImports;
    }

    this.series.seriesImports = this.importLoader.fetchImportsForSeries(this.series)
      .pipe(
        map((seriesImports) => {
          return seriesImports.map((si) => {
            return this.importLoader.pollForChanges(si);
          });
        })
      );

    // start up your pollers!
    this.series.seriesImports
      .takeUntil(this._onDestroy)
      .subscribe((seriesImports) => {
        seriesImports.map((siObservable) => {
          siObservable
            .pipe(
              takeUntil(this._onDestroy),
              throttle(() => timer(5000), {leading: true, trailing: true})
            )
            .subscribe((si) => {
              this.seriesImportStateChanged(si);
            });
        });
      });

    return this.series.seriesImports;
  }<commit_msg>use auditTime instead of throttle<commit_after>import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

import { CmsService, HalDoc } from '../core';
import { ModalService, TabService, ToastrService } from 'ngx-prx-styleguide';
import { SeriesImportService } from './series-import.service';
import { SeriesModel, SeriesImportModel } from '../shared';
import { NEW_SERIES_VALIDATIONS } from '../shared/model/series.model';

import { map, auditTime, takeUntil } from 'rxjs/operators';
import { timer } from 'rxjs/observable/timer';

@Component({
  providers: [TabService],
  selector: 'publish-series',
  styleUrls: ['series.component.css'],
  templateUrl: 'series.component.html'
})

export class SeriesComponent implements OnInit {

  private _onDestroy = new Subject();

  id: number;
  base: string;
  series: SeriesModel;
  storyCount: number;
  storyNoun: string;

  // podcast imports
  fromImport = false;

  constructor(
    public cms: CmsService,
    private modal: ModalService,
    public toastr: ToastrService,
    private route: ActivatedRoute,
    private importLoader: SeriesImportService,
    private router: Router
  ) {}

  ngOnInit() {
    this.route.params.forEach(params => {
     this.id = +params['id'];
     this.base = '/series/' + (this.id || 'new');
     this.loadSeries();
   });
  }

  ngOnDestroy() {
    this._onDestroy.next();
  }

  loadSeries() {
    if (this.id) {
      this.cms.auth.follow('prx:series', {id: this.id}).subscribe(
        s => {
          s.follow('prx:account').subscribe(a => {
            this.setSeries(a, s);
          });
        },
        err => {
          if (err.status === 404 && err.name === 'HalHttpError') {
            this.toastr.error('No series found. Redirecting to new series page');
            console.error(`Series with id ${this.id} not found`);
            setTimeout(() => this.router.navigate(['/series', 'new']), 3000);
          } else {
            throw(err);
          }
        }
      );
    } else {
      this.cms.defaultAccount.subscribe(a => this.setSeries(a, null));
    }
  }

  buildSeries(parent: any, series: any) {
    let newSeries = new SeriesModel(parent, series) 
    // Because the series state is split between component and model, make the
    // loadSeries method idempotent and preserve the podcast import polling 
    // state with each call. Then refresh the series model based on import 
    // status polling intervals.
    if(this.series){
      newSeries.seriesImports = this.series.seriesImports;
    }
    return newSeries;
  }

  setSeries(parent: any, series: any) {
    this.series = this.buildSeries(parent, series);
    if (series) {
      this.storyCount = series.count('prx:stories');
      this.storyNoun = this.storyCount === 1 ? 'Episode' : 'Episodes';
      this.setImportState();
      this.setSeriesValidationStrategy();
    } else {
      this.storyCount = null;
    }
    this.checkSeriesVersion();
  }

  checkSeriesVersion() {
    if (!this.series.isV4()) {
      let oldLink = `https://www.prx.org/series/${this.id}`;
      this.modal.alert(
        'Cannot Edit Series',
        `This series was created in the older PRX.org app, and must be
        edited there. <a target="_blank" href="${oldLink}">Click here</a> to view it.`,
        () => { window.history.back(); }
      );
    }
  }

  setImportState() {
    this.fromImport = this.series.doc.count('prx:podcast-imports') > 0;
    if (this.fromImport){
      this.pollForImportState();
    }
  }

  pollForImportState() {
    if(this.series.seriesImports !== null){
      return this.series.seriesImports;
    }

    this.series.seriesImports = this.importLoader.fetchImportsForSeries(this.series)
      .pipe(
        map((seriesImports) => {
          return seriesImports.map((si) => {
            return this.importLoader.pollForChanges(si);
          });
        })
      );

    // start up your pollers!
    this.series.seriesImports
      .takeUntil(this._onDestroy)
      .subscribe((seriesImports) => {
        seriesImports.map((siObservable) => {
          siObservable
            .pipe(
              takeUntil(this._onDestroy),
              auditTime(5000)
            )
            .subscribe((si) => {
              this.seriesImportStateChanged(si);
            });
        });
      });

    return this.series.seriesImports;
  }
{'fraction_non_alphanumeric': 0.1396125584502338, 'fraction_numerical': 0.0031173458027165444, 'mean_word_length': 2.5746120175089535, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 34, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2957752', 'n_tokens_mistral': 2742, 'n_tokens_neox': 2683, 'n_words': 599}