diff --git a/build.xml b/build.xml
index 72e02c0f..de98ba49 100644
--- a/build.xml
+++ b/build.xml
@@ -656,15 +656,6 @@
-
-
-
-
-
-
-
-
-
diff --git a/website/scripts/.htaccess b/website/scripts/.htaccess
deleted file mode 100644
index e6fa4a5f..00000000
--- a/website/scripts/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-options +indexes
-
-redirect 301 /scripts/utorrent-postprocess.groovy /scripts/amc.groovy
\ No newline at end of file
diff --git a/website/scripts/amc.groovy b/website/scripts/amc.groovy
deleted file mode 100644
index e306a19e..00000000
--- a/website/scripts/amc.groovy
+++ /dev/null
@@ -1,385 +0,0 @@
-// filebot -script "fn:amc" --output "X:/media" --action copy --conflict override --def subtitles=en music=y artwork=y "ut_dir=%D" "ut_file=%F" "ut_kind=%K" "ut_title=%N" "ut_label=%L" "ut_state=%S"
-def input = []
-def failOnError = _args.conflict == 'fail'
-
-// print input parameters
-_args.bindings?.each{ _log.fine("Parameter: $it.key = $it.value") }
-args.each{ _log.fine("Argument: $it") }
-args.findAll{ !it.exists() }.each{ throw new Exception("File not found: $it") }
-
-// check user-defined pre-condition
-if (tryQuietly{ !(ut_state ==~ ut_state_allow) }) {
- throw new Exception("Invalid state: ut_state = $ut_state (expected $ut_state_allow)")
-}
-
-// check ut mode vs standalone mode
-if ((args.size() > 0 && (tryQuietly{ ut_dir }?.size() > 0 || tryQuietly{ ut_file }?.size() > 0)) || (args.size() == 0 && (tryQuietly{ ut_dir } == null && tryQuietly{ ut_file } == null))) {
- throw new Exception("Conflicting arguments: pass in either file arguments or ut_dir/ut_file parameters but not both")
-}
-
-// enable/disable features as specified via --def parameters
-def music = tryQuietly{ music.toBoolean() }
-def subtitles = tryQuietly{ subtitles.toBoolean() ? ['en'] : subtitles.split(/[ ,|]+/).findAll{ it.length() >= 2 } }
-def artwork = tryQuietly{ artwork.toBoolean() }
-def backdrops = tryQuietly{ backdrops.toBoolean() }
-def clean = tryQuietly{ clean.toBoolean() }
-def exec = tryQuietly{ exec.toString() }
-
-// array of xbmc/plex hosts
-def xbmc = tryQuietly{ xbmc.split(/[ ,|]+/) }
-def plex = tryQuietly{ plex.split(/[ ,|]+/) }
-
-// extra options, myepisodes updates and email notifications
-def deleteAfterExtract = tryQuietly{ deleteAfterExtract.toBoolean() }
-def excludeList = tryQuietly{ new File(_args.output, excludeList) }
-def myepisodes = tryQuietly{ myepisodes.split(':', 2) }
-def gmail = tryQuietly{ gmail.split(':', 2) }
-def pushover = tryQuietly{ pushover.toString() }
-
-// user-defined filters
-def minFileSize = tryQuietly{ minFileSize.toLong() }; if (minFileSize == null) { minFileSize = 0 };
-
-// series/anime/movie format expressions
-def format = [
- tvs: tryQuietly{ seriesFormat } ?: '''TV Shows/{n}/{episode.special ? "Special" : "Season "+s.pad(2)}/{n} - {episode.special ? "S00E"+special.pad(2) : s00e00} - {t.replaceAll(/[`´‘’ʻ]/, "'").replaceAll(/[!?.]+$/).replacePart(', Part $1')}{".$lang"}''',
- anime: tryQuietly{ animeFormat } ?: '''Anime/{n}/{n} - {sxe} - {t.replaceAll(/[!?.]+$/).replaceAll(/[`´‘’ʻ]/, "'").replacePart(', Part $1')}''',
- mov: tryQuietly{ movieFormat } ?: '''Movies/{n} ({y})/{n} ({y}){" CD$pi"}{".$lang"}''',
- music: tryQuietly{ musicFormat } ?: '''Music/{n}/{album+'/'}{pi.pad(2)+'. '}{artist} - {t}'''
-]
-
-
-// force movie/series/anime logic
-def forceMovie(f) {
- tryQuietly{ ut_label } =~ /^(?i:Movie|Couch.Potato)/ || f.dir.path =~ /\b(?i:Movies)\b/ || f.path =~ /(?<=tt)\\d{7}/ || tryQuietly{ f.metadata?.object?.class.name =~ /Movie/ }
-}
-
-def forceSeries(f) {
- tryQuietly{ ut_label } =~ /^(?i:TV|Kids.Shows)/ || f.dir.path =~ /\b(?i:TV.Shows)\b/ || parseEpisodeNumber(f.path) || parseDate(f.path) || f.path =~ /(?i:Season)\D?[0-9]{1,2}\D/ || tryQuietly{ f.metadata?.object?.class.name =~ /Episode/ }
-}
-
-def forceAnime(f) {
- tryQuietly{ ut_label } =~ /^(?i:Anime)/ || f.dir.path =~ /\b(?i:Anime)\b/ || (f.isVideo() && (f.name =~ "[\\(\\[]\\p{XDigit}{8}[\\]\\)]" || getMediaInfo(file:f, format:'''{media.AudioLanguageList} {media.TextCodecList}''').tokenize().containsAll(['Japanese', 'ASS'])))
-}
-
-def forceIgnore(f) {
- tryQuietly{ ut_label } =~ /^(?i:ebook|other|ignore)/ || f.path =~ tryQuietly{ ignore }
-}
-
-
-// specify how to resolve input folders, e.g. grab files from all folders except disk folders
-def resolveInput(f) {
- if (f.isDirectory() && !f.isDisk())
- return f.listFiles().toList().findResults{ resolveInput(it) }
- else
- return f
-}
-
-// collect input fileset as specified by the given --def parameters
-if (args.empty) {
- // assume we're called with utorrent parameters (account for older and newer versions of uTorrents)
- if (ut_kind == 'single' || (ut_kind != 'multi' && ut_dir && ut_file)) {
- input += new File(ut_dir, ut_file) // single-file torrent
- } else {
- input += resolveInput(ut_dir as File) // multi-file torrent
- }
-} else {
- // assume we're called normally with arguments
- input += args.findResults{ resolveInput(it) }
-}
-
-
-// flatten nested file structure
-input = input.flatten()
-
-// extract archives (zip, rar, etc) that contain at least one video file
-def extractedArchives = []
-def tempFiles = []
-input = input.flatten{ f ->
- if (f.isArchive() || f.hasExtension('001')) {
- def extractDir = new File(f.dir, f.nameWithoutExtension)
- def extractFiles = extract(file: f, output: new File(extractDir, f.dir.name), conflict: 'skip', filter: { it.isArchive() || it.isVideo() || it.isSubtitle() || (music && it.isAudio()) }, forceExtractAll: true) ?: []
-
- if (extractFiles.size() > 0) {
- extractedArchives += f
- tempFiles += extractDir
- tempFiles += extractFiles
- }
- return extractFiles
- }
- return f
-}
-
-// sanitize input
-input = input.findAll{ it?.exists() }.collect{ it.canonicalFile }.unique()
-
-// process only media files
-input = input.findAll{ f -> (f.isVideo() && !tryQuietly{ f.hasExtension('iso') && !f.isDisk() }) || f.isSubtitle() || (f.isDirectory() && f.isDisk()) || (music && f.isAudio()) }
-
-// ignore clutter files
-input = input.findAll{ f -> !(f.path =~ /\b(?i:sample|trailer|extras|music.video|scrapbook|behind.the.scenes|extended.scenes|deleted.scenes|s\d{2}c\d{2}|mini.series)\b/ || (f.isFile() && f.length() < minFileSize)) }
-
-// check and update exclude list (e.g. to make sure files are only processed once)
-if (excludeList) {
- // check excludes from previous runs
- def excludePathSet = excludeList.exists() ? excludeList.text.split('\n') as HashSet : []
- input = input.findAll{ f -> !excludePathSet.contains(f.path) }
-
- // update excludes with input of this run
- excludePathSet += input
- excludePathSet.join('\n').saveAs(excludeList)
-}
-
-// print input fileset
-input.each{ f -> _log.finest("Input: $f") }
-
-// artwork/nfo utility
-if (artwork || xbmc || plex) { include('fn:lib/htpc') }
-
-// group episodes/movies and rename according to XBMC standards
-def groups = input.groupBy{ f ->
- // skip auto-detection if possible
- if (forceIgnore(f))
- return []
- if (f.isAudio() && !f.isVideo()) // PROCESS MUSIC FOLDER BY FOLDER
- return [music: f.dir.name]
- if (forceMovie(f))
- return [mov: detectMovie(f, false)]
- if (forceSeries(f))
- return [tvs: detectSeriesName(f) ?: detectSeriesName(f.dir.listFiles{ it.isVideo() })]
- if (forceAnime(f))
- return [anime: detectSeriesName(f) ?: detectSeriesName(f.dir.listFiles{ it.isVideo() })]
-
-
- def tvs = detectSeriesName(f)
- def mov = detectMovie(f, false)
- _log.fine("$f.name [series: $tvs, movie: $mov]")
-
- // DECIDE EPISODE VS MOVIE (IF NOT CLEAR)
- if (tvs && mov) {
- def norm = { s -> s.ascii().normalizePunctuation().lower().space(' ') }
- def dn = norm(guessMovieFolder(f)?.name ?: '')
- def fn = norm(f.nameWithoutExtension)
- def sn = norm(tvs)
- def mn = norm(mov.name)
-
- /**
- println '--- EPISODE FILTER (POS) ---'
- println parseEpisodeNumber(fn, true) || parseDate(fn)
- println ([dn, fn].find{ it =~ sn && matchMovie(it, true) == null } && (parseEpisodeNumber(stripReleaseInfo(fn.after(sn), false), false) || fn.after(sn) =~ /\D\d{1,2}\D{1,3}\d{1,2}\D/) && matchMovie(fn, true) == null)
- println (fn.after(sn) ==~ /.{0,3} - .+/ && matchMovie(fn, true) == null)
- println f.dir.listFiles{ it.isVideo() && (dn =~ sn || norm(it.name) =~ sn) && it.name =~ /\d{1,3}/}.findResults{ it.name.matchAll(/\d{1,3}/) as Set }.unique().size() >= 10
- println '--- EPISODE FILTER (NEG) ---'
- println (mov.year >= 1950 && f.listPath().reverse().take(3).find{ it.name =~ mov.year })
- println (mn =~ sn && [dn, fn].find{ it =~ /(19|20)\d{2}/ })
- println '--- MOVIE FILTER (POS) ---'
- println (similarity(mn, fn) >= 0.8 || [dn, fn].find{ it.findAll( ~/\d{4}/ ).findAll{ y -> [mov.year-1, mov.year, mov.year+1].contains(y.toInteger()) }.size() > 0 } != null)
- println ([dn, fn].find{ it =~ mn && !(it.after(mn) =~ /\b\d{1,3}\b/) && (similarity(it, mn) > 0.2 + similarity(it, sn)) } != null)
- println (detectMovie(f, true) && [dn, fn].find{ it =~ /(19|20)\d{2}/ } != null)
- **/
-
- // S00E00 | 2012.07.21 | One Piece 217 | Firefly - Serenity | [Taken 1, Taken 2, Taken 3, Taken 4, ..., Taken 10]
- if ((parseEpisodeNumber(fn, true) || parseDate(fn) || ([dn, fn].find{ it =~ sn && matchMovie(it, true) == null } && (parseEpisodeNumber(stripReleaseInfo(fn.after(sn), false), false) || fn.after(sn) =~ /\D\d{1,2}\D{1,3}\d{1,2}\D/) && matchMovie(fn, true) == null) || (fn.after(sn) ==~ /.{0,3} - .+/ && matchMovie(fn, true) == null) || f.dir.listFiles{ it.isVideo() && (dn =~ sn || norm(it.name) =~ sn) && it.name =~ /\d{1,3}/}.findResults{ it.name.matchAll(/\d{1,3}/) as Set }.unique().size() >= 10 || mov.year < 1900) && !( (mov.year >= 1950 && f.listPath().reverse().take(3).find{ it.name =~ mov.year }) || (mn =~ sn && [dn, fn].find{ it =~ /(19|20)\d{2}/ }) ) ) {
- _log.fine("Exclude Movie: $mov")
- mov = null
- } else if ((similarity(mn, fn) >= 0.8 || [dn, fn].find{ it.findAll( ~/\d{4}/ ).findAll{ y -> [mov.year-1, mov.year, mov.year+1].contains(y.toInteger()) }.size() > 0 } != null) || ([dn, fn].find{ it =~ mn && !(it.after(mn) =~ /\b\d{1,3}\b/) && (similarity(it, mn) > 0.2 + similarity(it, sn)) } != null) || (detectMovie(f, true) && [dn, fn].find{ it =~ /(19|20)\d{2}/ } != null)) {
- _log.fine("Exclude Series: $tvs")
- tvs = null
- }
- }
-
- // CHECK CONFLICT
- if (((mov && tvs) || (!mov && !tvs))) {
- if (failOnError) {
- throw new Exception("Media detection failed")
- } else {
- _log.fine("Unable to differentiate: [$f.name] => [$tvs] VS [$mov]")
- return [tvs: null, mov: null, anime: null]
- }
- }
-
- return [tvs: tvs, mov: mov, anime: null]
-}
-
-// log movie/series/anime detection results
-groups.each{ group, files -> _log.finest("Group: $group => ${files*.name}") }
-
-// process each batch
-groups.each{ group, files ->
- // fetch subtitles (but not for anime)
- if (subtitles && !group.anime && files.findAll{ it.isVideo() }.size() > 0) {
- subtitles.each{ languageCode ->
- def subtitleFiles = getMissingSubtitles(file:files, output:'srt', encoding:'UTF-8', lang:languageCode, strict:true) ?: []
- files += subtitleFiles
- tempFiles += subtitleFiles // if downloaded for temporarily extraced files delete later
- }
- }
-
- // EPISODE MODE
- if ((group.tvs || group.anime) && !group.mov) {
- // choose series / anime config
- def config = group.tvs ? [name:group.tvs, format:format.tvs, db:'TheTVDB', seasonFolder:true ]
- : [name:group.anime, format:format.anime, db:'AniDB', seasonFolder:false]
- def dest = rename(file: files, format: config.format, db: config.db)
- if (dest && artwork) {
- dest.mapByFolder().each{ dir, fs ->
- _log.finest "Fetching artwork for $dir from TheTVDB"
- def sxe = fs.findResult{ eps -> parseEpisodeNumber(eps) }
- def options = TheTVDB.search(detectSeriesName(fs), _args.locale)
- if (options.isEmpty()) {
- _log.warning "TV Series not found: $config.name"
- return
- }
- options = options.sortBySimilarity(config.name, { s -> s.name })
- fetchSeriesArtworkAndNfo(config.seasonFolder ? dir.dir : dir, dir, options[0], sxe && sxe.season > 0 ? sxe.season : 1)
- }
- }
- if (dest == null && failOnError) {
- throw new Exception("Failed to rename series: $config.name")
- }
- }
-
- // MOVIE MODE
- else if (group.mov && !group.tvs && !group.anime) {
- def dest = rename(file:files, format:format.mov, db:'TheMovieDB')
- if (dest && artwork) {
- dest.mapByFolder().each{ dir, fs ->
- _log.finest "Fetching artwork for $dir from TheMovieDB"
- def movieFile = fs.findAll{ it.isVideo() }.sort{ it.length() }.reverse().findResult{ it }
- fetchMovieArtworkAndNfo(dir, detectMovie(movieFile), movieFile, backdrops)
- }
- }
- if (dest == null && failOnError) {
- throw new Exception("Failed to rename movie: $group.mov")
- }
- }
-
- // MUSIC MODE
- else if (group.music) {
- def dest = rename(file:files, format:format.music, db:'AcoustID')
- if (dest == null && failOnError) {
- throw new Exception("Failed to rename music: $group.music")
- }
- }
-}
-
-// skip notifications if nothing was renamed anyway
-if (getRenameLog().isEmpty()) {
- return
-}
-
-// run program on newly processed files
-if (exec) {
- getRenameLog().each{ from, to ->
- def command = getMediaInfo(format: exec, file: to)
- _log.finest("Execute: $command")
- execute(command)
- }
-}
-
-// make XMBC scan for new content and display notification message
-if (xbmc) {
- xbmc.each{ host ->
- _log.info "Notify XBMC: $host"
- _guarded{
- showNotification(host, 9090, 'FileBot', "Finished processing ${tryQuietly { ut_title } ?: input*.dir.name.unique()} (${getRenameLog().size()} files).", 'http://www.filebot.net/images/icon.png')
- scanVideoLibrary(host, 9090)
- }
- }
-}
-
-// make Plex scan for new content
-if (plex) {
- plex.each{
- _log.info "Notify Plex: $it"
- refreshPlexLibrary(it)
- }
-}
-
-// mark episodes as 'acquired'
-if (myepisodes) {
- _log.info 'Update MyEpisodes'
- executeScript('fn:update-mes', [login:myepisodes.join(':'), addshows:true], getRenameLog().values())
-}
-
-if (pushover) {
- // include webservice utility
- include('fn:lib/ws')
-
- _log.info 'Sending Pushover notification'
- Pushover(pushover).send("Finished processing ${tryQuietly { ut_title } ?: input*.dir.name.unique()} (${getRenameLog().size()} files).")
-}
-
-// send status email
-if (gmail) {
- // ant/mail utility
- include('fn:lib/ant')
-
- // send html mail
- def renameLog = getRenameLog()
- def emailTitle = tryQuietly { ut_title } ?: input*.dir.name.unique()
-
- sendGmail(
- subject: "[FileBot] ${emailTitle}",
- message: XML {
- html {
- body {
- p("FileBot finished processing ${emailTitle} (${renameLog.size()} files).");
- hr(); table {
- th("Parameter"); th("Value")
- _args.bindings.findAll{ param -> param.key =~ /^ut_/ }.each{ param ->
- tr { [param.key, param.value].each{ td(it)} }
- }
- }
- hr(); table {
- th("Original Name"); th("New Name"); th("New Location")
- renameLog.each{ from, to ->
- tr { [from.name, to.name, to.parent].each{ cell -> td{ nobr{ code(cell) } } } }
- }
- }
- hr(); small("// Generated by ${net.sourceforge.filebot.Settings.applicationIdentifier} on ${new Date().dateString} at ${new Date().timeString}")
- }
- }
- },
- messagemimetype: 'text/html',
- to: tryQuietly{ mailto } ?: gmail[0] + '@gmail.com', // mail to self by default
- user: gmail[0], password: gmail[1]
- )
-}
-
-if (deleteAfterExtract) {
- extractedArchives.each{ a ->
- _log.finest("Delete archive $a")
- a.delete()
- a.dir.listFiles().toList().findAll{ v -> v.name.startsWith(a.nameWithoutExtension) && v.extension ==~ /r\d+/ }.each{ v ->
- _log.finest("Delete archive volume $v")
- v.delete()
- }
- }
-}
-
-// clean empty folders, clutter files, etc after move
-if (clean) {
- if (['COPY', 'HARDLINK'].find{ it.equalsIgnoreCase(_args.action) } && tempFiles.size() > 0) {
- _log.info 'Clean temporary extracted files'
- // delete extracted files
- tempFiles.findAll{ it.isFile() }.sort().each{
- _log.finest "Delete $it"
- it.delete()
- }
- // delete remaining empty folders
- tempFiles.findAll{ it.isDirectory() }.sort().reverse().each{
- _log.finest "Delete $it"
- if (it.getFiles().isEmpty()) it.deleteDir()
- }
- }
-
- // deleting remaining files only makes sense after moving files
- if ('MOVE'.equalsIgnoreCase(_args.action)) {
- def cleanerInput = !args.empty ? args : ut_kind == 'multi' && ut_dir ? [ut_dir as File] : []
- cleanerInput = cleanerInput.findAll{ f -> f.exists() }
- if (cleanerInput.size() > 0) {
- _log.info 'Clean clutter files and empty folders'
- executeScript('fn:cleaner', args.empty ? [root:true] : [root:false], cleanerInput)
- }
- }
-}
diff --git a/website/scripts/artwork.tmdb.groovy b/website/scripts/artwork.tmdb.groovy
deleted file mode 100644
index 73f38af4..00000000
--- a/website/scripts/artwork.tmdb.groovy
+++ /dev/null
@@ -1,53 +0,0 @@
-// filebot -script fn:artwork.tmdb /path/to/movies/
-def override = _args.conflict == 'override'
-
-/*
- * Fetch movie artwork. The movie is determined using the parent folders name.
- */
-
-// artwork/nfo helpers
-include('lib/htpc')
-
-
-args.eachMediaFolder{ dir ->
- // fetch only missing artwork by default
- if (!override && dir.hasFile{it.name == 'movie.nfo'} && dir.hasFile{it.name == 'poster.jpg'} && dir.hasFile{it.name == 'fanart.jpg'}) {
- println "Skipping $dir"
- return
- }
-
- def videos = dir.listFiles{ it.isVideo() }
- def query = _args.query
- def options = []
-
- if (query) {
- // manual search
- options = TheMovieDB.searchMovie(query, _args.locale)
- // sort by relevance
- options = options.sortBySimilarity(query, { it.name })
- } else {
- // auto-detection
- options = net.sourceforge.filebot.media.MediaDetection.detectMovie(videos[0], null, TheMovieDB, _args.locale, true)
- }
-
- if (options.isEmpty()) {
- println "Movie not found: $query"
- return
- }
-
- // auto-select movie
- def movie = options[0]
-
- // maybe require user input
- if (options.size() != 1 && !_args.nonStrict && !java.awt.GraphicsEnvironment.headless) {
- movie = javax.swing.JOptionPane.showInputDialog(null, 'Please select Movie:', dir.path, 3, null, options.toArray(), movie)
- if (movie == null) return null
- }
-
- println "$dir => $movie"
- try {
- fetchMovieArtworkAndNfo(dir, movie, dir.getFiles{ it.isVideo() }.sort{ it.length() }.reverse().findResult{ it }, true, override)
- } catch(e) {
- println "${e.class.simpleName}: ${e.message}"
- }
-}
diff --git a/website/scripts/artwork.tvdb.groovy b/website/scripts/artwork.tvdb.groovy
deleted file mode 100644
index eb1b187a..00000000
--- a/website/scripts/artwork.tvdb.groovy
+++ /dev/null
@@ -1,52 +0,0 @@
-// filebot -script fn:artwork.tvdb /path/to/media/
-def override = _args.conflict == 'override'
-
-/*
- * Fetch series and season banners for all tv shows. Series name is auto-detected if possible or the folder name is used.
- */
-
-// artwork/nfo helpers
-include('lib/htpc')
-
-
-args.eachMediaFolder{ dir ->
- // fetch only missing artwork by default
- if (!override && dir.hasFile{it.name == 'banner.jpg'}) {
- println "Skipping $dir"
- return
- }
-
- def videos = dir.listFiles{ it.isVideo() }
- def query = _args.query ?: detectSeriesName(videos, _args.locale)
- def sxe = videos.findResult{ parseEpisodeNumber(it) }
-
- if (query == null) {
- query = dir.dir.hasFile{ it.name =~ /Season/ && it.isDirectory() } ? dir.dir.name : dir.name
- }
-
- println "$dir => Search by $query"
- def options = TheTVDB.search(query, _args.locale)
- if (options.isEmpty()) {
- println "TV Series not found: $query"
- return
- }
-
- // sort by relevance
- options = options.sortBySimilarity(query, { it.name })
-
- // auto-select series
- def series = options[0]
-
- // maybe require user input
- if (options.size() != 1 && !_args.nonStrict && !java.awt.GraphicsEnvironment.headless) {
- series = javax.swing.JOptionPane.showInputDialog(null, 'Please select TV Show:', dir.path, 3, null, options.toArray(), series)
- if (series == null) return
- }
-
- // auto-detect structure
- def seriesDir = [dir.dir, dir].sortBySimilarity(series.name, { it.name })[0]
- def season = sxe && sxe.season > 0 ? sxe.season : 1
-
- println "$dir => $series"
- fetchSeriesArtworkAndNfo(seriesDir, dir, series, season, override)
-}
diff --git a/website/scripts/chkall.groovy b/website/scripts/chkall.groovy
deleted file mode 100644
index c56e181a..00000000
--- a/website/scripts/chkall.groovy
+++ /dev/null
@@ -1,9 +0,0 @@
-// filebot -script fn:chkall
-
-/*
- * Check all sfv/md5/sha1 files and stop if a conflict is found
- */
-args.getFiles().findAll { it.isVerification() }.each {
- if (!check(file:it))
- throw new Exception("*ERROR*")
-}
diff --git a/website/scripts/cleaner.groovy b/website/scripts/cleaner.groovy
deleted file mode 100644
index 37c6b122..00000000
--- a/website/scripts/cleaner.groovy
+++ /dev/null
@@ -1,41 +0,0 @@
-// filebot -script fn:cleaner [--action test] /path/to/media/
-def deleteRootFolder = tryQuietly{ root.toBoolean() }
-
-/*
- * Delete orphaned "clutter" files like nfo, jpg, etc and sample files
- */
-def isClutter(f) {
- // white list
- def ignore = tryQuietly{ ignore } ?: /extrathumbs/
- if (f.path =~ "(?i)\\b($ignore)\\b") return false
-
- // black list
- def exts = tryQuietly{ exts } ?: /jpg|jpeg|png|gif|nfo|xml|htm|html|log|srt|sub|idx|md5|sfv|txt|rtf|url|db|dna|log/
- def terms = tryQuietly{ terms } ?: /sample|trailer|extras|deleted.scenes|music.video|scrapbook/
- def maxsize = tryQuietly{ maxsize as Long } ?: 100 * 1024 * 1024
-
- // path contains blacklisted terms or extension is blacklisted
- return (f.extension ==~ "(?i)($exts)" || f.path =~ "(?i)\\b($terms)\\b") && f.length() < maxsize
-}
-
-
-def clean(f) {
- println "Delete $f"
-
- // do a dry run via --action test
- if (_args.action == 'test') {
- return false
- }
-
- return f.isDirectory() ? f.deleteDir() : f.delete()
-}
-
-
-// memoize media folder status for performance
-def hasMediaFiles = { dir -> dir.getFiles().find{ (it.isVideo() || it.isAudio()) && !isClutter(it) } }.memoize()
-
-// delete clutter files in orphaned media folders
-args.getFiles{ isClutter(it) && !hasMediaFiles(it.dir) }.each { clean(it) }
-
-// delete empty folders but exclude given args
-args.getFolders().sort().reverse().each { if (it.listFiles().length == 0) { if (deleteRootFolder || !args.contains(it)) clean(it) } }
diff --git a/website/scripts/configure.login.groovy b/website/scripts/configure.login.groovy
deleted file mode 100644
index 8d93c785..00000000
--- a/website/scripts/configure.login.groovy
+++ /dev/null
@@ -1,26 +0,0 @@
-// OpenSubtitles
-console.print('Enter OpenSubtitles username: ')
-def osdbUser = console.readLine()
-console.print('Enter OpenSubtitles password: ')
-def osdbPwd = console.readLine()
-
-
-setLogin('osdb.user', osdbUser, osdbPwd)
-
-
-/* --------------------------------------------------------------------- */
-
-import net.sourceforge.filebot.*
-
-if (osdbUser) {
- console.print('Testing OpenSubtitles... ')
- WebServices.OpenSubtitles.setUser(osdbUser, osdbPwd)
- WebServices.OpenSubtitles.login()
- console.println('OK')
-}
-
-/* --------------------------------------------------------------------- */
-
-def setLogin(key, user, pwd) {
- Settings.forPackage(WebServices.class).put(key, [user, pwd].join(':'))
-}
diff --git a/website/scripts/escape.groovy b/website/scripts/escape.groovy
deleted file mode 100644
index a01d009c..00000000
--- a/website/scripts/escape.groovy
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-def escapeShell(String arg) {
- return '"' + arg.replaceAll(/["$`<>^\\"]/, /\\$0/) + '"'
-}
-
-
-
-if (java.awt.GraphicsEnvironment.headless && console != null) {
- // CLI mode
- console.printf('Enter: ')
- def s = console.readLine()
- console.println('\n' + escapeShell(s) + '\n')
- System.exit(0)
-} else {
- // GUI mode
- new groovy.swing.SwingBuilder().edt{
- frame(title: 'Escape Tool', size: [350, 230], show: true, defaultCloseOperation: javax.swing.JFrame.EXIT_ON_CLOSE) {
- gridLayout(cols: 1, rows: 2)
- scrollPane{
- textArea id: 'value', lineWrap: true, font: new java.awt.Font('Monospaced', 0, 16)
- }
- scrollPane{
- textArea id: 'escape', lineWrap: true, text: bind(source:value, sourceProperty:'text', converter: { escapeShell(it) }), font: new java.awt.Font('Monospaced', 0, 16)
- }
- }
- }
- System.in.read() // wait for GUI to close
-}
diff --git a/website/scripts/extract.groovy b/website/scripts/extract.groovy
deleted file mode 100644
index 7995dadb..00000000
--- a/website/scripts/extract.groovy
+++ /dev/null
@@ -1,10 +0,0 @@
-// filebot -script fn:extract
-
-/*
- * Auto-extract all zip and rar archives.
- */
-args.getFiles{ it.isArchive() }.each {
- def output = extract(file:it)
-
- output.each{ println "Extracted: " + it.path }
-}
diff --git a/website/scripts/history.groovy b/website/scripts/history.groovy
deleted file mode 100644
index d6ef2b11..00000000
--- a/website/scripts/history.groovy
+++ /dev/null
@@ -1,16 +0,0 @@
-// filebot -script fn:history --format "$from => $to"
-
-// use --format parameter to specify your own output format
-def format = _args.format ?: '[$from.name] => [$to.name]'
-def template = new groovy.text.GStringTemplateEngine().createTemplate(format)
-
-// use args to list history only for the given folders if desired
-def accept(from, to) {
- args.empty ? true : args.find{ to.absolutePath.startsWith(it.absolutePath) } && to.exists()
-}
-
-
-getRenameLog(true).each { from, to ->
- if (accept(from, to))
- println template.make(from:from, to:to)
-}
diff --git a/website/scripts/housekeeping.groovy b/website/scripts/housekeeping.groovy
deleted file mode 100644
index c24f343a..00000000
--- a/website/scripts/housekeeping.groovy
+++ /dev/null
@@ -1,33 +0,0 @@
-// filebot -script fn:housekeeping /path/to/folder/ --output /output/folder/ --format
-
-/*
- * Watch folder for new tv shows and automatically move/rename new episodes
- */
-
-// check for new media files once every 5 minutes
-def updateFrequency = 5 * 60 * 1000
-
-// spawn daemon thread
-Thread.startDaemon {
- while (sleep(updateFrequency) || true) {
- // extract all
- if (_args.extract) {
- extract(file:args.getFiles{ it.isArchive() }, output:'.')
- }
-
- // subtitles for all
- if (_args.getSubtitles) {
- getMissingSubtitles(file:args.getFiles{ it.isVideo() }, output:'srt')
- }
-
- // rename all
- if (_args.rename) {
- args.eachMediaFolder {
- rename(folder:it)
- }
- }
- }
-}
-
-println "Press ENTER to abort"
-console.readLine() // keep script running until aborted by user
diff --git a/website/scripts/lib/ant.groovy b/website/scripts/lib/ant.groovy
deleted file mode 100644
index 82c05802..00000000
--- a/website/scripts/lib/ant.groovy
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/**
- * Log into a remote host and run a given command.
- *
- * e.g.
- * sshexec(command: "ps", host: "filebot.sf.net", username: "rednoah", password: "correcthorsebatterystaple")
- */
-def sshexec(param) {
- param << [trust: true] // auto-trust remote hosts
-
- _guarded {
- ant().sshexec(param)
- }
-}
-
-
-/**
- * Send email via smtp.
- *
- * e.g.
- * sendmail(mailhost:'smtp.gmail.com', mailport:'587', ssl:'no', enableStartTLS:'yes', user:'rednoah@gmail.com', password:'correcthorsebatterystaple', from:'rednoah@gmail.com', to:'someone@gmail.com', subject:'Hello Ant World', message:'Dear Ant, ...')
- */
-def sendmail(param) {
- def sender = param.remove('from')
- def recipient = param.remove('to')
-
- _guarded {
- ant().mail(param) {
- from(address:sender)
- to(address:recipient)
- }
- }
-}
-
-
-/**
- * Send email using gmail default settings.
- *
- * e.g.
- * sendGmail(subject:'Hello Ant World', message:'Dear Ant, ...', to:'someone@gmail.com', user:'rednoah', password:'correcthorsebatterystaple')
- */
-def sendGmail(param) {
- param << [mailhost:'smtp.gmail.com', mailport:'587', ssl:'no', enableStartTLS:'yes']
- param << [user:param.username ? param.remove('username') + '@gmail.com' : param.user]
- param << [from: param.from ?: param.user]
-
- sendmail(param)
-}
-
-
-def ant() {
- return new AntBuilder()
-}
diff --git a/website/scripts/lib/htpc.groovy b/website/scripts/lib/htpc.groovy
deleted file mode 100644
index 20f2bdff..00000000
--- a/website/scripts/lib/htpc.groovy
+++ /dev/null
@@ -1,286 +0,0 @@
-import static net.sourceforge.filebot.WebServices.*
-import static groovy.json.StringEscapeUtils.*
-
-import groovy.xml.*
-import net.sourceforge.filebot.mediainfo.*
-
-
-/**
- * XBMC helper functions
- */
-def scanVideoLibrary(host, port) {
- _guarded {
- telnet(host, port) { writer, reader ->
- writer.println("""{"jsonrpc":"2.0","method":"VideoLibrary.Scan","id":1}""")
- }
- }
-}
-
-def showNotification(host, port, title, message, image) {
- _guarded {
- telnet(host, port) { writer, reader ->
- writer.println("""{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"${escapeJavaScript(title)}","message":"${escapeJavaScript(message)}", "image":"${escapeJavaScript(image)}"},"id":1}""")
- }
- }
-}
-
-
-
-/**
- * Plex helpers
- */
-def refreshPlexLibrary(server, port = 32400) {
- _guarded {
- new URL("http://$server:$port/library/sections/all/refresh").get()
- }
-}
-
-
-
-/**
- * TheTVDB artwork/nfo helpers
- */
-def fetchSeriesBanner(outputFile, series, bannerType, bannerType2, season, override, locale) {
- if (outputFile.exists() && !override) {
- _log.finest "Banner already exists: $outputFile"
- return outputFile
- }
-
- // select and fetch banner
- def banner = [locale, null].findResult { TheTVDB.getBanner(series, [BannerType:bannerType, BannerType2:bannerType2, Season:season, Language:it]) }
- if (banner == null) {
- _log.finest "Banner not found: $outputFile / $bannerType:$bannerType2"
- return null
- }
- _log.finest "Fetching $outputFile => $banner"
- return banner.url.saveAs(outputFile)
-}
-
-def fetchSeriesFanart(outputFile, series, type, season, override, locale) {
- if (outputFile.exists() && !override) {
- _log.finest "Fanart already exists: $outputFile"
- return outputFile
- }
-
- def fanart = [locale, null].findResult{ lang -> FanartTV.getSeriesArtwork(series.seriesId).find{ type == it.type && (season == null || season == it.season) && (lang == null || lang == it.language) }}
- if (fanart == null) {
- _log.finest "Fanart not found: $outputFile / $type"
- return null
- }
- _log.finest "Fetching $outputFile => $fanart"
- return fanart.url.saveAs(outputFile)
-}
-
-def fetchSeriesNfo(outputFile, seriesInfo, override, locale) {
- def i = seriesInfo
- XML {
- tvshow {
- title(i.name)
- sorttitle([i.name, i.firstAired as String].findAll{ it?.length() > 0 }.join('::'))
- year(i.firstAired?.year)
- rating(i.rating)
- votes(i.ratingCount)
- plot(i.overview)
- runtime(i.runtime)
- mpaa(i.contentRating)
- id(i.id)
- episodeguide {
- url(cache:"${i.id}.xml", "http://www.thetvdb.com/api/1D62F2F90030C444/series/${i.id}/all/${locale.language}.zip")
- }
- genre(i.genres?.size() > 0 ? i.genres[0] : null)
- thumb(i.bannerUrl)
- premiered(i.firstAired)
- status(i.status)
- studio(i.network)
- i.actors?.each{ n ->
- actor {
- name(n)
- }
- }
- tvdb(id:i.id, "http://www.thetvdb.com/?tab=series&id=${i.id}")
- }
- }
- .saveAs(outputFile)
-}
-
-def fetchSeriesArtworkAndNfo(seriesDir, seasonDir, series, season, override = false, locale = _args.locale) {
- _guarded {
- // fetch nfo
- def seriesInfo = TheTVDB.getSeriesInfo(series, locale)
- fetchSeriesNfo(seriesDir['tvshow.nfo'], seriesInfo, override, locale)
-
- // fetch series banner, fanart, posters, etc
- ["680x1000", null].findResult{ fetchSeriesBanner(seriesDir['poster.jpg'], series, "poster", it, null, override, locale) }
- ["graphical", null].findResult{ fetchSeriesBanner(seriesDir['banner.jpg'], series, "series", it, null, override, locale) }
-
- // fetch highest resolution fanart
- ["1920x1080", "1280x720", null].findResult{ fetchSeriesBanner(seriesDir["fanart.jpg"], series, "fanart", it, null, override, locale) }
-
- // fetch season banners
- if (seasonDir != seriesDir) {
- fetchSeriesBanner(seasonDir["poster.jpg"], series, "season", "season", season, override, locale)
- fetchSeriesBanner(seasonDir["banner.jpg"], series, "season", "seasonwide", season, override, locale)
- }
-
- // fetch fanart
- fetchSeriesFanart(seriesDir['clearart.png'], series, 'clearart', null, override, locale)
- fetchSeriesFanart(seriesDir['logo.png'], series, 'clearlogo', null, override, locale)
- fetchSeriesFanart(seriesDir['landscape.jpg'], series, 'tvthumb', null, override, locale)
-
- // fetch season fanart
- if (seasonDir != seriesDir) {
- fetchSeriesFanart(seasonDir['landscape.jpg'], series, 'seasonthumb', season, override, locale)
- }
- }
-}
-
-
-
-/**
- * TheMovieDB artwork/nfo helpers
- */
-def fetchMovieArtwork(outputFile, movieInfo, category, override, locale) {
- if (outputFile.exists() && !override) {
- _log.finest "Artwork already exists: $outputFile"
- return outputFile
- }
-
- // select and fetch artwork
- def artwork = TheMovieDB.getArtwork(movieInfo.id as String)
- def selection = [locale.language, 'en', null].findResult{ l -> artwork.find{ (l == it.language || l == null) && it.category == category } }
- if (selection == null) {
- _log.finest "Artwork not found: $outputFile"
- return null
- }
- _log.finest "Fetching $outputFile => $selection"
- return selection.url.saveAs(outputFile)
-}
-
-def fetchAllMovieArtwork(outputFolder, movieInfo, category, override, locale) {
- // select and fetch artwork
- def artwork = TheMovieDB.getArtwork(movieInfo.id as String)
- def selection = [locale.language, 'en', null].findResults{ l -> artwork.findAll{ (l == it.language || l == null) && it.category == category } }.flatten().findAll{ it?.url }.unique()
- if (selection == null) {
- _log.finest "Artwork not found: $outputFolder"
- return null
- }
- selection.eachWithIndex{ s, i ->
- def outputFile = new File(outputFolder, "$category-${(i+1).pad(2)}.jpg")
- if (outputFile.exists() && !override) {
- _log.finest "Artwork already exists: $outputFile"
- } else {
- _log.finest "Fetching $outputFile => $s"
- s.url.saveAs(outputFile)
- }
- }
-}
-
-def fetchMovieFanart(outputFile, movieInfo, type, diskType, override, locale) {
- if (outputFile.exists() && !override) {
- _log.finest "Fanart already exists: $outputFile"
- return outputFile
- }
-
- def fanart = [locale, null].findResult{ lang -> FanartTV.getMovieArtwork(movieInfo.id).find{ type == it.type && (diskType == null || diskType == it.diskType) && (lang == null || lang == it.language) }}
- if (fanart == null) {
- _log.finest "Fanart not found: $outputFile / $type"
- return null
- }
- _log.finest "Fetching $outputFile => $fanart"
- return fanart.url.saveAs(outputFile)
-}
-
-def fetchMovieNfo(outputFile, movieInfo, movieFile, override) {
- def i = movieInfo
- def mi = _guarded{ movieFile ? MediaInfo.snapshot(movieFile) : null }
- XML {
- movie {
- title(i.name)
- originaltitle(i.originalName)
- sorttitle([i.collection, i.name, i.released as String].findAll{ it?.length() > 0 }.join('::'))
- set(i.collection)
- year(i.released?.year)
- rating(i.rating)
- votes(i.votes)
- mpaa(i.certification)
- id("tt" + (i.imdbId ?: 0).pad(7))
- plot(i.overview)
- tagline(i.tagline)
- runtime(i.runtime)
- genre(i.genres?.size() > 0 ? i.genres[0] : null)
- director(i.director)
- i.cast?.each{ a ->
- actor {
- name(a.name)
- role(a.character)
- }
- }
- i.trailers?.each{ t ->
- t.sources.each { s, v ->
- trailer(type:t.type, name:t.name, size:s, v)
- }
- }
- fileinfo {
- streamdetails {
- mi?.each { kind, streams ->
- def section = kind.toString().toLowerCase()
- streams.each { s ->
- if (section == 'video') {
- video {
- codec((s.'Encoded_Library/Name' ?: s.'CodecID/Hint' ?: s.'Format').replaceAll(/[ ].+/, '').trim())
- aspect(s.'DisplayAspectRatio')
- width(s.'Width')
- height(s.'Height')
- }
- }
- if (section == 'audio') {
- audio {
- codec((s.'CodecID/Hint' ?: s.'Format').replaceAll(/\p{Punct}/, '').trim())
- language(s.'Language/String3')
- channels(s.'Channel(s)')
- }
- }
- if (section == 'text') {
- subtitle {
- language(s.'Language/String3')
- }
- }
- }
- }
- }
- }
- imdb(id:"tt" + (i.imdbId ?: 0).pad(7), "http://www.imdb.com/title/tt" + (i.imdbId ?: 0).pad(7))
- tmdb(id:i.id, "http://www.themoviedb.org/movie/${i.id}")
- }
- }
- .saveAs(outputFile)
-}
-
-def fetchMovieArtworkAndNfo(movieDir, movie, movieFile = null, fetchAll = false, override = false, locale = _args.locale) {
- _guarded {
- def movieInfo = TheMovieDB.getMovieInfo(movie, locale)
-
- // fetch nfo
- fetchMovieNfo(movieDir['movie.nfo'], movieInfo, movieFile, override)
-
- // generate url files
- [[db:'imdb', id:movieInfo.imdbId, url:"http://www.imdb.com/title/tt" + (movieInfo.imdbId ?: 0).pad(7)], [db:'tmdb', id:movieInfo.id, url:"http://www.themoviedb.org/movie/${movieInfo.id}"]].each{
- if (it.id > 0) {
- def content = "[InternetShortcut]\nURL=${it.url}\n"
- content.saveAs(new File(movieDir, "${it.db}.url"))
- }
- }
-
- // fetch series banner, fanart, posters, etc
- fetchMovieArtwork(movieDir['poster.jpg'], movieInfo, 'posters', override, locale)
- fetchMovieArtwork(movieDir['fanart.jpg'], movieInfo, 'backdrops', override, locale)
-
- fetchMovieFanart(movieDir['clearart.png'], movieInfo, 'movieart', null, override, locale)
- fetchMovieFanart(movieDir['logo.png'], movieInfo, 'movielogo', null, override, locale)
- ['bluray', 'dvd', null].findResult { diskType -> fetchMovieFanart(movieDir['disc.png'], movieInfo, 'moviedisc', diskType, override, locale) }
-
- if (fetchAll) {
- fetchAllMovieArtwork(movieDir['backdrops'], movieInfo, 'backdrops', override, locale)
- }
- }
-}
diff --git a/website/scripts/lib/scraper.groovy b/website/scripts/lib/scraper.groovy
deleted file mode 100644
index 76fd8f23..00000000
--- a/website/scripts/lib/scraper.groovy
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
- * MyEpisodes
- * http://www.myepisodes.com
- ****************************************************************************/
-import org.jsoup.Jsoup
-import org.jsoup.Connection.Method
-import net.sourceforge.filebot.Cache
-
-def MyEpisodes(username, password) {
- return new MyEpisodesScraper(username:username, password:password)
-}
-
-class MyEpisodesScraper {
- def username
- def password
-
- def cache = Cache.getCache('web-datasource-lv2')
- def session = [:]
-
- def login = {
- def response = Jsoup.connect('http://www.myepisodes.com/login.php').data('username', username, 'password', password, 'action', 'Login', 'u', '').method(Method.POST).execute()
- session << response.cookies()
- return response.parse()
- }
-
- def get = { url ->
- if (session.isEmpty()) {
- login()
- }
-
- def response = Jsoup.connect(url).cookies(session).method(Method.GET).execute()
- session << response.cookies()
- def html = response.parse()
-
- if (html.select('#frmLogin')) {
- session.clear()
- throw new Exception('Login failed')
- }
-
- return html
- }
-
- def getShows = {
- def shows = cache.get('MyEpisodes.Shows')
- if (shows == null) {
- shows = ['other', 'A'..'Z'].flatten().findResults{ section ->
- get("http://myepisodes.com/shows.php?list=${section}").select('a').findResults{ a ->
- try {
- return [id:a.absUrl('href').match(/showid=(\d+)/).toInteger(), name:a.text().trim()]
- } catch(e) {
- return null
- }
- }
- }.flatten().sort{ it.name }
- cache.put('MyEpisodes.Shows', shows)
- }
- return shows
- }
-
- def getShowList = {
- get("http://www.myepisodes.com/shows.php?type=manage").select('option').findResults{ option ->
- try {
- return [id:option.attr('value').toInteger(), name:option.text().trim()]
- } catch(e) {
- return null
- }
- }
- }
-
- def addShow = { showid ->
- get("http://www.myepisodes.com/views.php?type=manageshow&mode=add&showid=${showid}")
- }
-
- def update = { showid, season, episode, tick = 'acquired', value = '1' ->
- get("http://www.myepisodes.com/myshows.php?action=Update&showid=${showid}&season=${season}&episode=${episode}&${tick}=${value}")
- }
-
-}
diff --git a/website/scripts/lib/ws.groovy b/website/scripts/lib/ws.groovy
deleted file mode 100644
index dc0bcae4..00000000
--- a/website/scripts/lib/ws.groovy
+++ /dev/null
@@ -1,22 +0,0 @@
-/****************************************************************************
- * Pushover
- * https://pushover.net
- ****************************************************************************/
-def Pushover(user, token = 'wcckDz3oygHSU2SdIptvnHxJ92SQKK') {
- new PushoverClient(user:user, token:token)
-}
-
-class PushoverClient {
- def user
- def token
-
- def endpoint = new URL('https://api.pushover.net/1/messages.xml')
-
- def send = { text, parameters = [:] ->
- // inject default post parameters
- parameters << [token:token, user:user, message:text as String]
-
- // post and process response
- endpoint.post(parameters).text.xml
- }
-}
diff --git a/website/scripts/mi.groovy b/website/scripts/mi.groovy
deleted file mode 100644
index 7e2c9f80..00000000
--- a/website/scripts/mi.groovy
+++ /dev/null
@@ -1,27 +0,0 @@
-// filebot -script fn:mi /path/to/media/ "MediaIndex.csv"
-
-/*
- * Print media info of all video files to CSV file
- */
-def model = '''Name;Container;Resolution;Video Codec;Video Format;Audio Codec;Audio Format;Audio Language(s);Duration;File Size;Folder Size;Folder Count;Path'''
-def template = '''{fn};{cf};{resolution};{vc};{vf};{ac};{af};{media.AudioLanguageList};{media.DurationString3};{file.length()};{folder.listFiles().sum{ it.length() }};{folder.listFiles().sum{ it.isFile() ? 1 : 0 }};{file.getCanonicalPath()}'''
-
-// sanity check
-if (args.size() != 2) throw new Exception('Invalid arguments:' + args)
-
-// open destination file (writing files requires -trust-script)
-args[1].withWriter{ output ->
- // print header
- output.writeLine(model)
-
- // print info for each video file (sorted by filename)
- args[0].getFiles{ it.isVideo() }.sort{ a, b -> a.name.compareToIgnoreCase(b.name) }.each{
- def mi = getMediaInfo(file:it, format:template)
-
- // print to console
- println mi
-
- // append to file
- output.writeLine(mi)
- }
-}
diff --git a/website/scripts/renall.groovy b/website/scripts/renall.groovy
deleted file mode 100644
index 2fb1b8f1..00000000
--- a/website/scripts/renall.groovy
+++ /dev/null
@@ -1,16 +0,0 @@
-// filebot -script fn:renall --def target=[file|folder]
-
-/*
- * Rename all tv shows, anime or movies folder by folder using given or default options.
- */
-def target = tryQuietly{ target } ?: 'file' // target files by default
-
-args.eachMediaFolder {
- if (it.isDisk())
- return rename(file:it) // rename disk folders instead of files regardless of mode
-
- switch(target) {
- case 'file' : return rename(folder:it) // rename files within each folder
- case 'folder' : return rename(file:it) // rename folders as if they were files
- }
-}
diff --git a/website/scripts/replace.groovy b/website/scripts/replace.groovy
deleted file mode 100644
index 6a1ea021..00000000
--- a/website/scripts/replace.groovy
+++ /dev/null
@@ -1,28 +0,0 @@
-// filebot -script fn:replace --action copy --filter "[.]srt$" --def "e=[.](eng|english)" "r=.en"
-
-// imports
-import net.sourceforge.filebot.StandardRenameAction
-
-// parameters
-def action = StandardRenameAction.forName(_args.action)
-def accept = { f -> _args.filter ? f.path =~ _args.filter : true }
-
-// rename
-args.getFiles{ accept(it) }.each{
- if (it.path =~ e) {
- def nfile = new File(it.path.replaceAll(e, r))
-
- // override files only when --conflict override is set
- if (!it.equals(nfile)) {
- if (nfile.exists() && _args.conflict == 'override' && action != StandardRenameAction.TEST) {
- nfile.delete() // resolve conflict
- }
-
- if (!nfile.exists()) {
- println action.rename(it, nfile)
- } else {
- println "Skipped $nfile"
- }
- }
- }
-}
diff --git a/website/scripts/revert.groovy b/website/scripts/revert.groovy
deleted file mode 100644
index 8ab55fc0..00000000
--- a/website/scripts/revert.groovy
+++ /dev/null
@@ -1,24 +0,0 @@
-// filebot -script fn:revert
-
-
-def accept(from, to) {
- args.find{ to.absolutePath.startsWith(it.absolutePath) } && to.exists()
-}
-
-def revert(from, to) {
- def action = net.sourceforge.filebot.StandardRenameAction.forName(_args.action)
-
- println "[$action] Revert [$from] to [$to]"
- if (!from.canonicalFile.equals(to.canonicalFile)) {
- action.rename(from, to) // reverse-rename only if path has changed
- }
-
- // reset extended attributes
- tryQuietly{ to.xattr.clear() }
-}
-
-
-getRenameLog(true).reverseEach { from, to ->
- if (accept(from, to))
- revert(to, from)
-}
diff --git a/website/scripts/sortivo.groovy b/website/scripts/sortivo.groovy
deleted file mode 100644
index b4457682..00000000
--- a/website/scripts/sortivo.groovy
+++ /dev/null
@@ -1,50 +0,0 @@
-// filebot -script fn:sortivo --output path/to/folder [-non-strict]
-
-// process only media files
-def input = args.getFiles{ it.isVideo() || it.isSubtitle() }
-
-// ignore clutter files
-input = input.findAll{ !(it.path =~ /\b(?i:sample|trailer|extras|deleted.scenes|music.video|scrapbook)\b/) }
-
-// print input fileset
-input.each{ println "Input: $it" }
-
-/*
- * Move/Rename a mix of episodes and movies that are all in the same folder.
- */
-def groups = input.groupBy{ f ->
- def tvs = detectSeriesName(f)
- def mov = (parseEpisodeNumber(f) || parseDate(f)) ? null : detectMovie(f, false) // skip movie detection if we can already tell it's an episode
- println "$f.name [series: $tvs, movie: $mov]"
-
- // DECIDE EPISODE VS MOVIE (IF NOT CLEAR)
- if (tvs && mov) {
- def norm = { s -> s.lower().space(' ') }
- def fn = norm(f.nameWithoutExtension)
- def sn = norm(tvs)
- def mn = norm(mov.name)
-
- // S00E00 | 2012.07.21 | One Piece 217 | Firefly - Serenity | [Taken 1, Taken 2, Taken 3, Taken 4, ..., Taken 10]
- if (parseEpisodeNumber(fn, true) || parseDate(fn) || (fn =~ sn && parseEpisodeNumber(fn.after(sn), false)) || fn.after(sn) =~ / - .+/ || f.dir.listFiles{ it.isVideo() && norm(it.name) =~ sn && it.name =~ /\b\d{1,3}\b/}.size() >= 10) {
- println "Exclude Movie: $mov"
- mov = null
- } else if ((detectMovie(f, true) && fn =~ /(19|20)\d{2}/) || (fn =~ mn && !(fn.after(mn) =~ /\b\d{1,3}\b/))) {
- println "Exclude Series: $tvs"
- tvs = null
- }
- }
-
- return [tvs:tvs, mov:mov]
-}
-
-groups.each{ group, files ->
- // EPISODE MODE
- if (group.tvs && !group.mov) {
- rename(file:files, format:'TV Shows/{n}/{episode.special ? "Special" : "Season "+s}/{n} - {episode.special ? "S00E"+special.pad(2) : s00e00} - {t}', db:'TheTVDB')
- }
-
- // MOVIE MODE
- if (group.mov && !group.tvs) {
- rename(file:files, format:'Movies/{n} ({y})/{n} ({y}){" CD$pi"}', db:'TheMovieDB')
- }
-}
diff --git a/website/scripts/sorty.groovy b/website/scripts/sorty.groovy
deleted file mode 100644
index 5eca93dc..00000000
--- a/website/scripts/sorty.groovy
+++ /dev/null
@@ -1,65 +0,0 @@
-// PERSONALIZED SETTINGS
-def episodeDir = '''/in/TV'''
-def episodeFormat = '''/out/TV/{n}/{"Season ${s.pad(2)}"}/{n} - {s00e00} - {t}'''
-def movieDir = '''/in/Movies'''
-def movieFormat = '''/out/Movies/{n} ({y})/{n} ({y}){" CD$pi"}'''
-
-// XBMC ON LOCAL MACHINE
-def xbmc = ['localhost'] // (use [] to not notify any XBMC instances about updates)
-
-
-
-// ignore chunk, part, par and hidden files
-def incomplete(f) { f.name =~ /[.]incomplete|[.]chunk|[.]par$|[.]dat$/ }
-
-
-// extract completed multi-volume rar files
-[episodeDir, movieDir].getFolders{ !it.hasFile{ incomplete(it) } && it.hasFile{ it =~ /[.]rar$/ } }.each{ dir ->
- // extract all archives found in this folder
- def paths = extract(folder:dir)
-
- // delete original archive volumes after successful extraction
- if (paths != null && !paths.isEmpty()) {
- dir.listFiles{ it =~ /[.]rar$|[.]r[\d]+$/ }*.delete()
- }
-}
-
-
-/*
- * Fetch subtitles and sort into folders
- */
-episodeDir.getFolders{ !it.hasFile{ incomplete(it) } && it.hasFile{ it.isVideo() } }.each{ dir ->
- println "Processing $dir"
- def files = dir.listFiles{ it.isVideo() }
-
- // fetch subtitles
- files += getSubtitles(file:files)
-
- // sort episodes / subtitles
- rename(file:files, db:'TheTVDB', format:episodeFormat)
-}
-
-movieDir.getFolders{ !it.hasFile{ incomplete(it) } && it.hasFile{ it.isVideo() } }.each{ dir ->
- println "Processing $dir"
- def files = dir.listFiles{ it.isVideo() }
-
- // fetch subtitles
- files += getSubtitles(file:files)
-
- // sort movies / subtitles
- rename(file:files, db:'TheMovieDB', format:movieFormat)
-}
-
-
-// make XBMC scan for new content
-xbmc.each { host ->
- telnet(host, 9090) { writer, reader ->
- // API call for latest XBMC release
- def msg = '{"id":1,"method":"VideoLibrary.Scan","params":[],"jsonrpc":"2.0"}'
-
- // API call for XBMC Dharma-Release or older
- // def msg = '{"id":1,"method":"VideoLibrary.ScanForContent","params":[],"jsonrpc":"2.0"}'
-
- writer.println(msg)
- }
-}
diff --git a/website/scripts/src.groovy b/website/scripts/src.groovy
deleted file mode 100644
index 1f832ff7..00000000
--- a/website/scripts/src.groovy
+++ /dev/null
@@ -1,13 +0,0 @@
-// filebot -script fn:src
-
-/*
- * Fetch subtitles, rename and calculate checksums for all video files
- */
-args.eachMediaFolder {
-
- getMissingSubtitles(folder:it)
-
- def renamedFiles = rename(folder:it)
-
- compute(file:renamedFiles.findAll{ it.isVideo() })
-}
diff --git a/website/scripts/suball.groovy b/website/scripts/suball.groovy
deleted file mode 100644
index 5cc54242..00000000
--- a/website/scripts/suball.groovy
+++ /dev/null
@@ -1,8 +0,0 @@
-// filebot -script fn:suball
-
-/*
- * Get subtitles for all your media files
- */
-args.eachMediaFolder {
- getMissingSubtitles(folder:it)
-}
diff --git a/website/scripts/sysenv.groovy b/website/scripts/sysenv.groovy
deleted file mode 100644
index ba9a860c..00000000
--- a/website/scripts/sysenv.groovy
+++ /dev/null
@@ -1,11 +0,0 @@
-// filebot -script fn:sysenv
-
-println '# Java System Properties #'
-_system.each{
- println "$it.key: $it.value"
-}
-
-println '# Environment Variables #'
-_environment.each{
- println "$it.key: $it.value"
-}
diff --git a/website/scripts/sysinfo.groovy b/website/scripts/sysinfo.groovy
deleted file mode 100644
index 08d7d3d4..00000000
--- a/website/scripts/sysinfo.groovy
+++ /dev/null
@@ -1,98 +0,0 @@
-// filebot -script fn:sysinfo
-
-// FileBot 2.62 (r993)
-println net.sourceforge.filebot.Settings.applicationIdentifier
-
-// JNA Native: 3.5.0
-try {
- print 'JNA Native: '
- println com.sun.jna.Native.nativeVersion
-} catch(Throwable error) {
- println error.cause
-}
-
-// MediaInfo: MediaInfoLib - v0.7.48
-try {
- print 'MediaInfo: '
- println net.sourceforge.filebot.mediainfo.MediaInfo.version()
-} catch(Throwable error) {
- println error.cause
-}
-
-// 7-Zip-JBinding: OK
-try {
- print '7-Zip-JBinding: '
- net.sourceforge.filebot.archive.SevenZipLoader.requireNativeLibraries() // load 7-Zip-JBinding native libs
- println 'OK'
-} catch(Throwable error) {
- println error
-}
-
-// chromaprint-tools
-try {
- print 'chromaprint-tools: '
- def fpcalc = System.getProperty('net.sourceforge.filebot.AcoustID.fpcalc', 'fpcalc')
- def version = [fpcalc, '-version'].execute().text.trim() ?: 'fpcalc -version failed'
- println "$version ($fpcalc)"
-} catch(Throwable error) {
- println error
-}
-
-// Extended File Attributes
-try {
- print 'Extended Attributes: '
- if (net.sourceforge.filebot.Settings.useExtendedFileAttributes()){
- // create new temp file
- def f = new File(net.sourceforge.filebot.Settings.applicationFolder, '.xattr-test')
- f.createNewFile() && f.deleteOnExit()
-
- // xattr write, read and verify
- def xattr = new net.sourceforge.filebot.media.MetaAttributes(f)
- def payload = new Date()
- xattr.setObject(payload)
- assert xattr.getObject() == payload
- println 'OK'
- } else {
- println 'DISABLED'
- }
-} catch(Throwable error) {
- println error
-}
-
-// GIO and GVFS
-try {
- if (net.sourceforge.filebot.Settings.useGVFS()) {
- print 'GVFS: '
- assert net.sourceforge.filebot.gio.GVFS.defaultVFS != null
- println 'OK'
- }
-} catch(Throwable error) {
- println error
-}
-
-// Groovy Engine: 2.1.7
-println 'Groovy Engine: ' + groovy.lang.GroovySystem.version
-
-// Java(TM) SE Runtime Environment 1.6.0_30 (headless)
-println net.sourceforge.filebot.Settings.javaRuntimeIdentifier
-
-// 32-bit Java HotSpot(TM) Client VM
-println String.format('%d-bit %s', com.sun.jna.Platform.is64Bit() ? 64 : 32, _system['java.vm.name'])
-
-// Windows 7 (x86)
-println String.format('%s (%s)', _system['os.name'], _system['os.arch'])
-
-
-
-// check for updates
-try {
- def update = new XmlSlurper().parse('http://filebot.net/update.xml')
- def latestRev = update.revision.text() as int
- def latestApp = update.name.text()
-
- if (latestRev > net.sourceforge.filebot.Settings.applicationRevisionNumber) {
- println "\n--- UPDATE AVAILABLE: $latestApp (r$latestRev) ---\n"
- }
-} catch(Throwable error) {
- // ignore
-}
diff --git a/website/scripts/update-mes.groovy b/website/scripts/update-mes.groovy
deleted file mode 100644
index e9b2a07f..00000000
--- a/website/scripts/update-mes.groovy
+++ /dev/null
@@ -1,38 +0,0 @@
-// filebot -script fn:update-mes "X:/path/to/episodes" --def login=user:pwd addshows=y tick=acquired
-
-def mesacc = login.split(':')
-def mesadd = tryQuietly{ addshows.toBoolean() }
-def mesupdate = tryQuietly { tick } ?: 'acquired'
-def mesvalue = tryQuietly { value } ?: '1'
-
-// import myepisodes scraper
-include('lib/scraper')
-
-def mes = MyEpisodes(mesacc[0], mesacc[1])
-def myshows = mes.getShowList()
-
-// series name => series key (e.g. Doctor Who (2005) => doctorwho)
-def collationKey = { s -> s == null ? '' : s.replaceAll(/^(?i)(The|A)\b/, '').replaceAll(/(?
- def show = myshows.find{ collationKey(it.name) == collationKey(series) }
- if (show == null && mesadd) {
- show = mes.getShows().find{ collationKey(it.name) == collationKey(series) }
- if (show == null) {
- println "[failure] '$series' not found"
- return
- }
- mes.addShow(show.id)
- println "[added] $show.name"
- }
-
- files.each{
- if (show != null) {
- def sxe = parseEpisodeNumber(it)
- mes.update(show.id, sxe.season, sxe.episode, mesupdate, mesvalue)
- println "[$mesupdate] $show.name $sxe [$it.name]"
- } else {
- println "[failure] '$series' has not been added [$it.name]"
- }
- }
-}
diff --git a/website/scripts/watcher.groovy b/website/scripts/watcher.groovy
deleted file mode 100644
index 74047770..00000000
--- a/website/scripts/watcher.groovy
+++ /dev/null
@@ -1,22 +0,0 @@
-// filebot -script fn:watcher /path/to/folder/ --output /output/folder/ --format
-
-// watch folders and print files that were added/modified
-def watchman = args.watch { changes ->
- // extract all
- if (_args.extract)
- changes += extract(file:changes.findAll{ it.isArchive() }, output:'.')
-
- // subtitles for all
- if (_args.getSubtitles)
- changes += getMissingSubtitles(file:changes.findAll{ it.isVideo() }, output:'srt')
-
- // rename all
- if (_args.rename)
- rename(file:changes)
-}
-
-watchman.commitDelay = 5 * 1000 // default = 5s
-watchman.commitPerFolder = true // default = true
-
-println "Waiting for events"
-if (console) { console.readLine() } else { sleep(Long.MAX_VALUE) } // keep running and watch for changes
\ No newline at end of file
diff --git a/website/scripts/xattr.groovy b/website/scripts/xattr.groovy
deleted file mode 100644
index 0cf4b6ee..00000000
--- a/website/scripts/xattr.groovy
+++ /dev/null
@@ -1,13 +0,0 @@
-// filebot -script fn:xattr --action clear /path/to/files
-
-args.getFiles{ it.xattr.size() > 0 }.each{
- println it
- it.xattr.each{ k, v ->
- println "\t$k: $v"
- }
- // clear xattr mode
- if (_args.action == 'clear') {
- it.xattr.clear()
- println '*** CLEARED ***'
- }
-}