XNXX - Search Filters

Various search filters

当前为 2018-12-16 提交的版本,查看 最新版本

// ==UserScript==
// @name          XNXX - Search Filters
// @namespace     brazenvoid
// @version       2.0.0
// @author        brazenvoid
// @license       GPL-3.0-only
// @description   Various search filters
// @include       https://www.xnxx.com/*
// @require       https://greasyfork.org/scripts/375557-brazenvoid-s-base-resource/code/Brazenvoid's%20Base%20Resource.js?version=654020
// @run-at        document-idle
// ==/UserScript==

// Settings & Defaults

let settings = {
  blacklist: [ // case-insensitive
    'urin',
    'arab',
    'muslim',
    'desi',
    'squirt',
    'fake',
    'pregnant',
    'pee',
  ],
  sanitize: { // Substitutes values with key (case-insensitive)
    ' ': ['neighbor', 'step'],
    'Boyfriend': ['brother', 'bro', 'daddy', 'dad'],
    'Girlfriend': ['daughter', 'mom', 'mother', 'sister', 'sis']
  },
  duration: [120, 0], // In Seconds
  resolution: '720p', // SD / 480p / 720p / 1080p
  views: [0, 0],
  showUIAlways: false, // Desktop/Tablet
  debugLogging: false
}

// Base Resources Initialization

let logger = new Logger(settings.debugLogging)
let selectorGenerator = new SelectorGenerator('xnxx-sui-')
let statistics = new StatisticsRecorder(logger, selectorGenerator)
let uiGenerator = new UIGenerator(settings.showUIAlways, selectorGenerator)

let filters = new Filters(logger, statistics)
filters.blacklist = settings.blacklist
filters.sanitizationRules = settings.sanitize
filters.init()

// Filters
// -- Duration validation

let validateDuration = function (duration) {

  if (settings.duration[0] > 0 || settings.duration[1] > 0) {

    duration = duration.split(' ')

    if (duration[1] === 'min') {
      duration[0] *= 60
    }
    return filters.validateRange('Duration', duration[0], settings.duration)
  }
  return true
}

// -- Resolution validation

let validateResolution = function (resolution) {

  let validationCheck = true

  if (settings.resolution !== 'SD') {

    switch (settings.resolution) {

      case '480p':
        validationCheck = resolution !== 'SD'
        break

      case '720p':
        validationCheck = resolution !== 'SD' && resolution !== '480p'
        break

      case '1080p':
        validationCheck = resolution !== 'SD' && resolution !== '480p' && resolution !== '720p'
        break
    }
    statistics.record('Resolution', validationCheck)
  }
  return validationCheck
}

// -- Video name sanitation

let sanitizeVideoPage = function () {

  let videoTitle = document.querySelector('.inlineFree')
  if (videoTitle !== null) {

    let sanitizedVideoName = filters.sanitize(videoTitle.textContent)
    videoTitle.textContent = sanitizedVideoName
    document.title = sanitizedVideoName
  }

}
let sanitizeVideoItem = function (videoItem, videoName) {

  videoItem.querySelector('.thumb-under > p:nth-child(1) > a:nth-child(1)').textContent = filters.sanitize(videoName)
}

// -- View count validation

let validateViews = function (views) {

  let validationCheck = true;

  if (settings.views[0] > 0 || settings.views[1] > 0) {
    validationCheck = filters.validateRange('Views', views, settings.views)
  }
  return validationCheck
}

// -- Compliance logic

let complianceCallback = function (target) {

  let videoItems = target.querySelectorAll('.thumb-block')
  let videoDuration, videoComplies, videoMetadata, videoName, videoResolution, videoViews

  for (let videoItem of videoItems) {

    videoMetadata = videoItem.querySelector('.metadata').textContent.split('-')
    videoDuration = videoMetadata[0].trim()

    if (typeof videoMetadata[1] === 'undefined') {
      videoResolution = 'SD'
      videoViews = 0
    } else if (videoMetadata[1].includes('hits')) {
      videoResolution = typeof videoMetadata[2] === 'undefined' ? 'SD' : videoMetadata[2].trim()
      videoViews = videoMetadata[1].trim().replace(' hits', '').replace(',', '')
    } else {
      videoResolution = videoMetadata[1].trim()
    }

    videoName = videoItem.querySelector('.thumb-under > p:nth-child(1) > a:nth-child(1)').textContent
    logger.logVideoCheck(videoName)

    videoComplies =
      validateResolution(videoResolution) &&
      filters.validateBlackList(videoName) &&
      validateDuration(videoDuration) &&
      validateViews(videoViews)

    if (videoComplies) {
      videoItem.style.display = 'inline-block'
      sanitizeVideoItem(videoItem, videoName)
    } else {
      videoItem.style.display = 'none'
    }
    logger.logSeparator()
  }
  statistics.updateUI()
}

// UI Composition
// -- Control Panel

let section = uiGenerator.createSection('settings', '#ffa31a', [
  uiGenerator.createSettingsFormGroup('Min Duration', settings.duration[0].toString()),
  uiGenerator.createSettingsFormGroup('MIn Resolution', settings.resolution.toString()),
  uiGenerator.createSettingsFormGroup('Min Views', settings.views[0].toString()),
  uiGenerator.createFormButton('Apply', function () {

    settings.duration[0] = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Duration')).value
    settings.resolution = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Resolution')).value
    settings.views[0] = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Views')).value

    statistics.reset()
    complianceCallback(document.querySelector('.mozaique'))
  }),
  uiGenerator.createSeparator(),
  uiGenerator.createStatisticsFormGroup('Duration', 'Short'),
  uiGenerator.createStatisticsFormGroup('Resolution', 'Low Resolution'),
  uiGenerator.createStatisticsFormGroup('Views', 'By Views'),
  uiGenerator.createStatisticsFormGroup('Blacklist', 'Blacklisted'),
  uiGenerator.createStatisticsFormGroup('Total', ''),
  uiGenerator.createFormButton('Hide', function () {
    document.getElementById(selectorGenerator.getSelector('settings')).style.display = 'none'
  })
])
section.style.width = '220px'
uiGenerator.appendToBody(section)

let labels = section.getElementsByTagName('label');
for (let label of labels) {
  label.style.margin = '0';
}

// -- Settings Button
// -- -- Composition

let controlButton = document.createElement('button')
controlButton.textContent = 'Show Settings UI'
controlButton.style.margin = '2px 5px'
controlButton.style.padding = '2px 5px'
controlButton.style.backgroundColor = '#ffa31a'
controlButton.style.border = '0'

controlButton.addEventListener('click', function () {

  let settingsUI = document.getElementById(selectorGenerator.getSelector('settings'))
  settingsUI.style.display = settingsUI.style.display === 'none' ? 'block' : 'none'
})

// -- -- Placement

let controlListItem = document.createElement('div')
controlListItem.appendChild(controlButton)

let filtersBar = document.querySelector('#listing-page-filters-block')
filtersBar.appendChild(controlButton)

logger.logTaskCompletion('Building UI')

// Script run
// -- Initial compliance run & observer attachment

let videoItemsObserver = new ChildObserver(complianceCallback)
videoItemsObserver.observe(document.querySelector('.mozaique'), true)

sanitizeVideoPage()

logger.logTaskCompletion('Initial run and observer attachment.')