Sleazy Fork is available in English.

Better pornolab.net posts

Make download link easier to find and click, add a textarea with the torrent title to easily edit a copy, torrent title gets cleaned up (removal of redundant websites, useless tags, characters not allowed in file names), add a link you can tab into from the textarea to quickly download the torrent. 2021-09-12 15:00:01

目前為 2021-09-12 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Better pornolab.net posts
// @namespace   Violentmonkey Scripts
// @match       *://pornolab.net/forum/viewtopic.php
// @grant       none
// @version     2.1.2
// @author      -
// @description Make download link easier to find and click, add a textarea with the torrent title to easily edit a copy, torrent title gets cleaned up (removal of redundant websites, useless tags, characters not allowed in file names), add a link you can tab into from the textarea to quickly download the torrent. 2021-09-12 15:00:01
// @run-at document-idle
// @inject-into page
// ==/UserScript==


// this.$ = this.jQuery = jQuery.noConflict(true); // disabled because it prevented uncollapsing collapsed posts
$("div#tor-reged").ready(function () {
  
  // make download link easier to find and click
  $("div#tor-reged a.dl-stub.dl-link").prepend("Download | ");
  $("div#tor-reged p").has("a.dl-stub").has("img").css("width", "100%").css("display", "block");
  $("div#tor-reged a.dl-stub").has("img").css("width", "100%").css("display", "block");
  $("div#tor-reged a.dl-stub img").css("width", "10em").css("height", "10em").css("image-rendering", "-moz-crisp-edges").css("border", "0.5em solid black").css("border-radius", "1em");
  
  // Try the following to stop smoothing in your browser:
  // image-rendering: optimizeSpeed;             /* STOP SMOOTHING, GIVE ME SPEED  */
  // image-rendering: -moz-crisp-edges;          /* Firefox                        */
  // image-rendering: -o-crisp-edges;            /* Opera                          */
  // image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
  // image-rendering: pixelated;                 /* Chrome */
  // image-rendering: optimize-contrast;         /* CSS3 Proposed                  */
  // -ms-interpolation-mode: nearest-neighbor;   /* IE8+                           */
  
  var title = $("h1.maintitle a").text();
  // $("h1.maintitle a").remove();
  
  function s(text, regex, replacement) {
    return text.replace(regex, replacement);
  }
  
  title = s(title, / \/ /g, ' ') // Remove slashes, not allowed in file names. Replace with spaces
  title = s(title, /\/ /g, ' ') // Remove slashes, not allowed in file names. Replace with spaces
  title = s(title, / \//g, ' ') // Remove slashes, not allowed in file names. Replace with spaces
  title = s(title, / \| /g, ' ') // Remove pipes. Replace with spaces
  title = s(title, / г./g, '') // Russian cyrillic shorthand for the word "year"
  title = s(title, /´|`|‘|’/g, "'") // Replace unicode apostrophes with ascii apostrophe
  title = s(title, /\?/g, "?") // Replace questionmark (illegal in file names) with Unicode full-width question mark (legal in file names)
  
  
  // Fix dates
  
  // Fix dates: dashes to periods
  title = s(title, /(\d\d)-(\d\d)-(\d\d)/, function fix_dashes(all, one, two, three) {
    return one + "." + two + "." + three
  })

  // Find a four-digit year
  year = null
  year_short = null
  matches = title.match(/[^\d\.](20(\d\d))[^\d\.]/)
  if (matches !== null) {
    year = matches[1]
    year_short = matches[2]
  }
  
  function make_year_regex(year_str) {
    year_regex_year_at_end   =                         "([^\\d])(\\d\\d)\\.(\\d\\d)\\." + year_str + "([^\\d])"
    year_regex_year_at_start = "([^\\d])" + year_str + "\\.(\\d\\d)\\.(\\d\\d)([^\\d])"
    // we want to prefer matches where the year is at the end, because that's the more common format
    year_regex = new RegExp(year_regex_year_at_end + "|" + year_regex_year_at_start)
    return year_regex
  }
  
  if ((year !== null ) && (year_short !== null)) {
    // Keep old title value to check if anything changed when we lengthened the year
    old_title = (' ' + title).slice(1) // create copy
    
    // Update two-digit years
    year_regex_short = make_year_regex(year_short)
    // note that either the first or second capture group will be == undefined
    title = s(title, year_regex_short, function update_short_year(match_all, match_year_at_end_prefix, match_year_at_end_1, match_year_at_end_2, match_year_at_end_suffix, match_year_at_start_prefix, match_year_at_start_1, match_year_at_start_2, match_year_at_start_suffix) {
      if(match_year_at_end_1 && match_year_at_end_2) {
        return (match_year_at_end_prefix + match_year_at_end_1 + "." + match_year_at_end_2 + "." + year + match_year_at_end_suffix)
      }
      if(match_year_at_start_1 && match_year_at_start_2) {
        return (match_year_at_start_prefix + year + "." + match_year_at_start_1 + "." + match_year_at_start_2 + match_year_at_start_suffix)
      }
      return match_all
    })
    
    year_regex = make_year_regex(year)
    if (year_regex.test(title)) {
      // Get rid of the year-only tag
      year_tag_regex = new RegExp("([^\\d])" + year + ", ")
      title = s(title, year_tag_regex, function get_rid_of_long_year_tag(match_all, match_prefix) {
        return match_prefix
      })
    }
  }
  
  // Fix stuff of the form [Foo.com] Performer - Title [Date, tag1, tag2, ...]
  // to look like [Foo.com] Performer (Title Date) [tag1, tag2, ...]
  matches = title.match(/(\[[^\]]+\] [^\[]+) - ([^\[]+) \[(\d\d\d\d\.\d\d\.\d\d|\d\d\.\d\d\.\d\d\d\d|\d\d\.\d\d\.\d\d), (.*)/)
  if (matches !== null) {
    title = matches[1] + " (" + matches[2] + " " + matches[3] + ") [" + matches[4]
  }
  
  // Fix stuff of the form [Foo.com] Performer - Title (Date) [tag1, tag2, ...]
  // to look like [Foo.com] Performer (Title Date) [tag1, tag2, ...]
  matches = title.match(/(\[[^\]]+\] [^\[]+) - ([^\[]+) \((\d\d\d\d\.\d\d\.\d\d|\d\d\.\d\d\.\d\d\d\d|\d\d\.\d\d\.\d\d)\) \[(.*)/)
  if (matches !== null) {
    title = matches[1] + " (" + matches[2] + " " + matches[3] + ") [" + matches[4]
  }
  
  // Parse out parts of title
  matches = title.match(/\[([^\]]+)\] ([^\[]+) \[(.*)\]/)
  if (matches !== null) {
    match_websites = matches[1]
    match_performer_scene = matches[2]
    match_tags = matches[3]
    
    websites = match_websites.split(" ")


    // Canonicize websites (eg add .com)
    website_full_domains = {
      "SisLovesMe": "SisLovesMe.com",
      "TeamSkeet": "TeamSkeet.com",
      "IKnowThatGirl": "IKnowThatGirl.com",
    }

    function l(str) {
      return str.toLocaleLowerCase()
    }

    websites = websites.map(function canonicize_websites_1(website) {
      Object.keys(website_full_domains).map(function canonicize_websites_2(key) {
        if (l(key) == l(website)) {
          website = website_full_domains[key]
        }
      })
      return website
    })

    // Capitalize websites

    // note: capitalize() is also used later in tag processing
    function capitalize(s) {
      const arr = s.split(" ")
      const arr2 = arr.map(word => word.substring(0, 1).toLocaleUpperCase() + l(word.substring(1)))
      return arr2.join(" ")
    }

    website_special_capitalization = [
      "SisLovesMe.com",
      "TeamSkeet.com",
      "IKnowThatGirl.com",
    ]

    websites = websites.map(function capitalize_websites(website) {
      chunks = website.split(".")
      main = capitalize(chunks[0])
      chunks[0] = main
      website = chunks.join(".")
      website_special_capitalization.map(function capitalize_websites_special(special) {
        if (l(special) == l(website)) {
          website = special
        }
      })
      return website
    })

    websites_redundant = websites.slice(0) // Don't change this, used by tags code later

    // Remove redundant websites
    website_redundancies = {
      "SisLovesMe.com": ["TeamSkeet.com"],
      "IKnowThatGirl.com": ["Mofos.com"],
    }

    website_redundancies_found = []
    websites.map(function remove_redundant_websites_1(website) {
      Object.keys(website_redundancies).map(function remove_redundant_websites_2(key) {
        if (l(key) == l(website)) {
          website_redundancies_found = website_redundancies_found.concat(website_redundancies[key])
        }
      })
    })

    website_redundancies_found = website_redundancies_found.map(x => l(x))
    websites = websites.filter(function remove_found_website_redundancies(website) {
      return ! website_redundancies_found.includes(l(website))
    })

    // Remove duplicate websites

    // note: deduplicate_list() is also used for tags, below.
    function deduplicate_list(list) {
      list2 = []
      list.map(function deduplicate_list_inner(element) {
        if (! list2.includes(element)) {
          list2.push(element)
        }
      })
      return list2
    }
    websites = deduplicate_list(websites)

    // Get rid of shitty tags
    const shitty_tags = [
      "1 On 1",
      "69",
      "All Sex",
      "Amateur",
      "Barefoot",
      "Bare Foot",
      "BBW",
      "Bedroom",
      "Bikini",
      "Blowjob",
      "Blow Job",
      "Boy Girl",
      "Bralette",
      "Camel Toe",
      "Casual Wear",
      "Caucasian",
      "Cinematic - Story",
      "Couch",
      "Cowgirl",
      "Crop Top",
      "Cum In Hair",
      "Cum In Mouth",
      "Cum on Ass",
      "Cum on Asshole",
      "Cum on Back",
      "Cum on Face",
      "Cum on Pussy",
      "Cum on Stomach",
      "Cum on Tits",
      "Cum Shot",
      "Cumshot Facial",
      "Cumshot",
      "Curvy",
      "Cute Little Butts",
      "Deep Throat",
      "Deepthroat",
      "Dick Play",
      "Dildo",
      "Disgusted Parenting",
      "Doggy",
      "Doggystyle",
      "Dress",
      "Facial",
      "Fetish",
      "Fingering",
      "Fingering (ass)",
      "Fingering (asshole)",
      "Fingering (pussy)",
      "Hand Job",
      "HandJob",
      "Hardcore",
      "Indoor",
      "Innie",
      "Innie Pussy",
      "Interracial",
      "Jeans",
      "Lingerie",
      "Living Room",
      "Masturbation",
      "Mature",
      "Medium Ass",
      "Medium Tits",
      "Mini Skirt",
      "Missionary",
      "Natural Tits",
      "Outie",
      "Outie Pussy",
      "Panties",
      "Piercings",
      "Pussy Licking",
      "Reality",
      "Reverse Cowgirl",
      "Roleplay",
      "Shaved Pussy",
      "Step Brother",
      "Step Bro",
      "Step Dad",
      "Step Father",
      "Swallow Cum",
      "Squirt",
      "Tank Top",
      "Tattoo",
      "Thick Top",
      "Thong",
      "Tit Play",
      "Trimmed Pussy",
      "Underwear",
      "Vibrator",
      "Wild",
      "White",
    ].map(s => l(s))

    match_tags = s(match_tags, /,([^\ \]])/g, function fix_tag_commas(all, suffix) {
      return ", " + suffix
    })

    tags = match_tags.split(", ")
    tags = tags.filter(function remove_shitty_tags(tag) {
      return ! shitty_tags.includes(l(tag))
    })

    // Fixme: see if there's a date in the tags, and if yes, place it inside the scene title,
    // but only if there isn't a longer date in the title. Also replace - with .,
    // and ensure the date is placed within the parentheses if they do exist,
    // or at the end of the scene title otherwise

    // Get rid of lower-case tags  
    tags = tags.map(t => capitalize(t)) // yes, I capitalize later when desynonymizing, so what.

    // Desynonymize tags  
    const tag_synonyms = {
      "Ass Licking": "Rimjob",
      "Asslicking": "Rimjob",
      "Rim Job": "Rimjob",
      "Red Head": "Redhead",
      "Stepsis": "Sister",
      "Stepsister": "Sister",
      "Step Sis": "Sister",
      "Step Sister": "Sister",
      "Stepmom": "Mom",
      "Stepmother": "Mom",
      "Step Mom": "Mom",
      "Step Mother": "Mom",
    }
    tags = tags.map(function desynonymize_tags(tag) {
      cap_tag = capitalize(tag)
      if (tag_synonyms.hasOwnProperty(cap_tag)) {
        return tag_synonyms[cap_tag]
      }
      return cap_tag
    })

    // Fix capitalization of some tags
    tag_special_cap = [
      "4K",
      "5K",
      "6K",
      "7K",
      "8K",
      "9K",
      "10K",
      "CFNM",
      "DAP",
      "DP",
      "DVDA",
      "FFM",
      "FMM",
      "FFMM",
      "FFFM",
      "FFFFM",
      "FFFFFM",
      "FFFFFFM",
      "MILF",
      "MILFs",
      "POV",
      "VR",
    ]

    tags = tags.map(function special_tag_capitalization(tag) {
      for (var i = 0; i < tag_special_cap.length; i++) {
        if (l(tag_special_cap[i]) == l(tag)) {
          return tag_special_cap[i]
        }
      }
      return tag
    })

    // Add tags based on other tags
    const tag_additions = {
      "Sister": ["Incest", "Family", "Taboo"],
      "Mom": ["Incest", "Family", "Taboo"],
      "Mother": ["Incest", "Family", "Taboo"],
      "Family": ["Incest", "Family", "Taboo"],
      "Incest": ["Incest", "Family", "Taboo"],
      "4K": ["2160p"],
      "2160p": ["4K"],
      "FFM": ["Threesome"],
      "FMM": ["Threesome"],
    }
    tags_temp = tags.slice(0) // Shallow copy

    tags_temp.map(function add_tags_1(tag) {
      if (tag_additions.hasOwnProperty(tag)) {
        tag_additions[tag].map(function add_tags_2(addition) {
          if (!tags.includes(addition)) {
            tags.push(addition)
          }
        })
      }
    })

    // Add tags based on websites
    const tag_website_additions = {
      "SisLovesMe.com": ["Sister", "Incest", "Family", "Taboo", "POV"],
    }
    websites_redundant.map(function add_tags_website_1(website) {
      if (tag_website_additions.hasOwnProperty(website)) {
        tag_website_additions[website].map(function add_tags_website_2(addition) {
          if (!tags.includes(addition)) {
            tags.push(addition)
          }
        })
      }
    })

    // Deduplicate tags
    tags = deduplicate_list(tags)

    tag_order_start = [
      "Blonde",
      "Redhead",
      "Black Hair",
      "Brunette",
      "Latina",
      "Asian",
      "Black",
      "Ebony",
      "Skinny",
      "Petite",
      "Tiny",
      "Abs",
      "Tiny Tits",
      "Big Naturals",
      "Natural Tits",
      "Big Tits",
      "Fake Tits",
      "Big Ass",
      "Nice Ass",
      "Teen",
      "Teens",
      "Babe",
      "MILF",
      "MILFs",
      "Sister",
      "Mother",
      "Incest",
      "Family",
      "Taboo",
      "Rimjob",
    ]
    tags_start = []
    tags_rest_1 = []
    tag_order_start.map(function split_tags_to_start_and_rest_1(start_tag) {
      if (tags.includes(start_tag)) {
        tags_start.push(start_tag)
      }
      return start_tag
    })
    tags.map(function split_tags_to_start_and_rest_2(tag) {
      if (!tags_start.includes(tag)) {
        tags_rest_1.push(tag)
      }
      return tag
    })

    tag_order_end = [
      "Throatpie",
      "Creampie",
      "POV",
      "4K",
      "5K",
      "6K",
      "7K",
      "8K",
      "9K",
      "10K",
      "1080p",
      "2160p",
      "VR",
    ]
    tags_end = []
    tags_rest_2 = []
    tag_order_end.map(function split_tags_to_end_and_rest_1(end_tag) {
      if (tags_rest_1.includes(end_tag)) {
        tags_end.push(end_tag)
      }
      return end_tag
    })
    tags_rest_1.map(function split_tags_to_end_and_rest_2(tag) {
      if (!tags_end.includes(tag)) {
        tags_rest_2.push(tag)
      }
      return tag
    })

    tags = [].concat(tags_start, tags_rest_2, tags_end)

    // Reconstruct title from parts
    title = "[" + websites.join(" ") + "] " + match_performer_scene + " [" + tags.join(", ") + "]"
  }
  
  // Get download link
  var dl = $("div#tor-reged a.dl-stub.dl-link").attr("href");
  
  // Add title near download link to edit and copy conveniently, and a download link to tab into
  $("div#tor-reged").prepend("<div id='better-plab-dl'><p><form><textarea style='font-size: 130%; width: calc(100% - 1em); padding: 0.5em' autocorrect='off' autocomplete='off' autocapitalize='off' spellcheck='false'>" + title + "</textarea></form></p><br/><br/><br/><br/><p><a href='" + dl + "' class='dl-stub dl-link' style='width: 100%; text-align: center; font-size: 7em'>Download Torrent File</a></p><br/><br/><br/><br/></div>");
});