Unified · Split
| @@ -1,5 +1,5 @@ | |||
| 1 | -- This script automatically loads playlist entries before and after the | 1 | -- This script automatically loads playlist entries before and after the |
| 2 | -- the currently played file. It does so by scanning the directory a file is | 2 | -- currently played file. It does so by scanning the directory a file is |
| 3 | -- located in when starting playback. It sorts the directory entries | 3 | -- located in when starting playback. It sorts the directory entries |
| 4 | -- alphabetically, and adds entries before and after the current file to | 4 | -- alphabetically, and adds entries before and after the current file to |
| 5 | -- the internal playlist. (It stops if it would add an already existing | 5 | -- the internal playlist. (It stops if it would add an already existing |
| @@ -32,8 +32,8 @@ ignore_patterns=^~,^bak-,%.bak$ · 26 unmodified lines | |||
| 32 | 32 | ||
| 33 | --]] | 33 | --]] |
| 34 | 34 | ||
| 35 | local MAXENTRIES = 5000 | 35 | local MAX_ENTRIES = 5000 |
| 36 | local MAXDIRSTACK = 20 | 36 | local MAX_DIR_STACK = 20 |
| 37 | 37 | ||
| 38 | local msg = require 'mp.msg' | 38 | local msg = require 'mp.msg' |
| 39 | local options = require 'mp.options' | 39 | local options = require 'mp.options' |
| @@ -53,7 +53,7 @@ local o = { · 13 unmodified lines | |||
| 53 | ignore_patterns = "" | 53 | ignore_patterns = "" |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | local function Set (t) | 56 | local function Set(t) |
| 57 | local set = {} | 57 | local set = {} |
| 58 | for _, v in pairs(t) do set[v] = true end | 58 | for _, v in pairs(t) do set[v] = true end |
| 59 | return set | 59 | return set |
| @@ -74,24 +74,21 @@ local EXTENSIONS_IMAGES_DEFAULT = Set { · 14 unmodified lines | |||
| 74 | 'svg', 'tga', 'tif', 'tiff', 'webp' | 74 | 'svg', 'tga', 'tif', 'tiff', 'webp' |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | local EXTENSIONS | 77 | local EXTENSIONS, EXTENSIONS_VIDEO, EXTENSIONS_AUDIO, EXTENSIONS_IMAGES |
| 78 | local EXTENSIONS_VIDEO | ||
| 79 | local EXTENSIONS_AUDIO | ||
| 80 | local EXTENSIONS_IMAGES | ||
| 81 | 78 | ||
| 82 | local function SetUnion (a,b) | 79 | local function SetUnion(a, b) |
| 83 | for k in pairs(b) do a[k] = true end | 80 | for k in pairs(b) do a[k] = true end |
| 84 | return a | 81 | return a |
| 85 | end | 82 | end |
| 86 | 83 | ||
| 87 | -- Returns first and last positions in string or past-to-end indices | 84 | -- Returns first and last positions in string or past-to-end indices |
| 88 | local function FindOrPastTheEnd (string, pattern, start_at) | 85 | local function FindOrPastTheEnd(string, pattern, start_at) |
| 89 | local pos1, pos2 = string.find(string, pattern, start_at) | 86 | local pos1, pos2 = string:find(pattern, start_at) |
| 90 | return pos1 or #string + 1, | 87 | return pos1 or #string + 1, |
| 91 | pos2 or #string + 1 | 88 | pos2 or #string + 1 |
| 92 | end | 89 | end |
| 93 | 90 | ||
| 94 | local function Split (list) | 91 | local function Split(list) |
| 95 | local set = {} | 92 | local set = {} |
| 96 | 93 | ||
| 97 | local item_pos = 1 | 94 | local item_pos = 1 |
| @@ -192,16 +189,15 @@ local function add_files(files) · 94 unmodified lines | |||
| 192 | end | 189 | end |
| 193 | 190 | ||
| 194 | local function get_extension(path) | 191 | local function get_extension(path) |
| 195 | return string.match(path, "%.([^%.]+)$" ) or "nomatch" | 192 | return path:match("%.([^%.]+)$") or "nomatch" |
| 196 | end | 193 | end |
| 197 | 194 | ||
| 198 | local function is_ignored(file) | 195 | local function is_ignored(file) |
| 199 | for pattern, _ in pairs(o.ignore_patterns) do | 196 | for pattern in pairs(o.ignore_patterns) do |
| 200 | if string.match(file, pattern) then | 197 | if file:match(pattern) then |
| 201 | return true | 198 | return true |
| 202 | end | 199 | end |
| 203 | end | 200 | end |
| 204 | |||
| 205 | return false | 201 | return false |
| 206 | end | 202 | end |
| 207 | 203 | ||
| @@ -225,12 +221,12 @@ local function alphanumsort(filenames) · 17 unmodified lines | |||
| 225 | return filenames | 221 | return filenames |
| 226 | end | 222 | end |
| 227 | 223 | ||
| 228 | local autoloaded = nil | 224 | local autoloaded |
| 229 | local added_entries = {} | 225 | local added_entries = {} |
| 230 | local autoloaded_dir = nil | 226 | local autoloaded_dir |
| 231 | 227 | ||
| 232 | local function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_files, extensions) | 228 | local function scan_dir(path, current_file, dir_mode, separator, dir_depth, total_files, extensions) |
| 233 | if dir_depth == MAXDIRSTACK then | 229 | if dir_depth == MAX_DIR_STACK then |
| 234 | return | 230 | return |
| 235 | end | 231 | end |
| 236 | msg.trace("scanning: " .. path) | 232 | msg.trace("scanning: " .. path) |
| @@ -238,7 +234,7 @@ local function scan_dir(path, current_file, dir_mode, separator, dir_depth, tota · 1 unmodified line | |||
| 238 | local dirs = dir_mode ~= "ignore" and utils.readdir(path, "dirs") or {} | 234 | local dirs = dir_mode ~= "ignore" and utils.readdir(path, "dirs") or {} |
| 239 | local prefix = path == "." and "" or path | 235 | local prefix = path == "." and "" or path |
| 240 | 236 | ||
| 241 | local filter = function(t, iter) | 237 | local function filter(t, iter) |
| 242 | for i = #t, 1, -1 do | 238 | for i = #t, 1, -1 do |
| 243 | if not iter(t[i]) then | 239 | if not iter(t[i]) then |
| 244 | table.remove(t, i) | 240 | table.remove(t, i) |
| @@ -246,11 +242,11 @@ local function scan_dir(path, current_file, dir_mode, separator, dir_depth, tota · 1 unmodified line | |||
| 246 | end | 242 | end |
| 247 | end | 243 | end |
| 248 | 244 | ||
| 249 | filter(files, function (v) | 245 | filter(files, function(v) |
| 250 | -- The current file could be a hidden file, ignoring it doesn't load other | 246 | -- The current file could be a hidden file, ignoring it doesn't load other |
| 251 | -- files from the current directory. | 247 | -- files from the current directory. |
| 252 | local current = prefix .. v == current_file | 248 | local current = prefix .. v == current_file |
| 253 | if o.ignore_hidden and not current and string.match(v, "^%.") then | 249 | if o.ignore_hidden and not current and v:match("^%.") then |
| 254 | return false | 250 | return false |
| 255 | end | 251 | end |
| 256 | if not current and is_ignored(v) then | 252 | if not current and is_ignored(v) then |
| @@ -258,13 +254,10 @@ local function scan_dir(path, current_file, dir_mode, separator, dir_depth, tota · 1 unmodified line | |||
| 258 | end | 254 | end |
| 259 | 255 | ||
| 260 | local ext = get_extension(v) | 256 | local ext = get_extension(v) |
| 261 | if ext == nil then | 257 | return ext and extensions[ext:lower()] |
| 262 | return false | ||
| 263 | end | ||
| 264 | return extensions[string.lower(ext)] | ||
| 265 | end) | 258 | end) |
| 266 | filter(dirs, function(d) | 259 | filter(dirs, function(d) |
| 267 | return not ((o.ignore_hidden and string.match(d, "^%."))) | 260 | return not (o.ignore_hidden and d:match("^%.")) |
| 268 | end) | 261 | end) |
| 269 | alphanumsort(files) | 262 | alphanumsort(files) |
| 270 | alphanumsort(dirs) | 263 | alphanumsort(dirs) |
| @@ -273,7 +266,7 @@ local function scan_dir(path, current_file, dir_mode, separator, dir_depth, tota · 2 unmodified lines | |||
| 273 | files[i] = prefix .. file | 266 | files[i] = prefix .. file |
| 274 | end | 267 | end |
| 275 | 268 | ||
| 276 | local append = function(t1, t2) | 269 | local function append(t1, t2) |
| 277 | local t1_size = #t1 | 270 | local t1_size = #t1 |
| 278 | for i = 1, #t2 do | 271 | for i = 1, #t2 do |
| 279 | t1[t1_size + i] = t2[i] | 272 | t1[t1_size + i] = t2[i] |
| @@ -316,15 +309,13 @@ local function find_and_add_entries() · 36 unmodified lines | |||
| 316 | local this_ext = get_extension(filename) | 309 | local this_ext = get_extension(filename) |
| 317 | -- check if this is a manually made playlist | 310 | -- check if this is a manually made playlist |
| 318 | if (pl_count > 1 and autoloaded == nil) or | 311 | if (pl_count > 1 and autoloaded == nil) or |
| 319 | (pl_count == 1 and EXTENSIONS[string.lower(this_ext)] == nil) then | 312 | (pl_count == 1 and EXTENSIONS[this_ext:lower()] == nil) then |
| 320 | msg.debug("stopping: manually made playlist") | 313 | msg.debug("stopping: manually made playlist") |
| 321 | return | 314 | return |
| 322 | else | 315 | elseif pl_count == 1 then |
| 323 | if pl_count == 1 then | 316 | autoloaded = true |
| 324 | autoloaded = true | 317 | autoloaded_dir = dir |
| 325 | autoloaded_dir = dir | 318 | added_entries = {} |
| 326 | added_entries = {} | ||
| 327 | end | ||
| 328 | end | 319 | end |
| 329 | 320 | ||
| 330 | local extensions | 321 | local extensions |
| @@ -346,11 +337,10 @@ local function find_and_add_entries() · 15 unmodified lines | |||
| 346 | utils.to_string(pl))) | 337 | utils.to_string(pl))) |
| 347 | 338 | ||
| 348 | local files = {} | 339 | local files = {} |
| 349 | do | 340 | scan_dir(autoloaded_dir, path, |
| 350 | local dir_mode = o.directory_mode or mp.get_property("directory-mode", "lazy") | 341 | o.directory_mode or mp.get_property("directory-mode", "lazy"), |
| 351 | local separator = mp.get_property_native("platform") == "windows" and "\\" or "/" | 342 | mp.get_property_native("platform") == "windows" and "\\" or "/", |
| 352 | scan_dir(autoloaded_dir, path, dir_mode, separator, 0, files, extensions) | 343 | 0, files, extensions) |
| 353 | end | ||
| 354 | 344 | ||
| 355 | if next(files) == nil then | 345 | if next(files) == nil then |
| 356 | msg.debug("no other files or directories in directory") | 346 | msg.debug("no other files or directories in directory") |
| @@ -365,7 +355,7 @@ local function find_and_add_entries() · 8 unmodified lines | |||
| 365 | break | 355 | break |
| 366 | end | 356 | end |
| 367 | end | 357 | end |
| 368 | if current == nil then | 358 | if not current then |
| 369 | return | 359 | return |
| 370 | end | 360 | end |
| 371 | msg.trace("current file position in files: "..current) | 361 | msg.trace("current file position in files: "..current) |
| @@ -378,7 +368,7 @@ local function find_and_add_entries() · 6 unmodified lines | |||
| 378 | 368 | ||
| 379 | local append = {[-1] = {}, [1] = {}} | 369 | local append = {[-1] = {}, [1] = {}} |
| 380 | for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1 | 370 | for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1 |
| 381 | for i = 1, MAXENTRIES do | 371 | for i = 1, MAX_ENTRIES do |
| 382 | local pos = current + i * direction | 372 | local pos = current + i * direction |
| 383 | local file = files[pos] | 373 | local file = files[pos] |
| 384 | if file == nil or file[1] == "." then | 374 | if file == nil or file[1] == "." then |
| @@ -398,12 +388,13 @@ local function find_and_add_entries() · 13 unmodified lines | |||
| 398 | mp.commandv("loadfile", file, "append") | 388 | mp.commandv("loadfile", file, "append") |
| 399 | end | 389 | end |
| 400 | end | 390 | end |
| 391 | added_entries[file] = true | ||
| 401 | end | 392 | end |
| 402 | added_entries[file] = true | ||
| 403 | end | 393 | end |
| 404 | if pl_count == 1 and direction == -1 and #append[-1] > 0 then | 394 | if pl_count == 1 and direction == -1 and #append[-1] > 0 then |
| 405 | for i = 1, #append[-1] do | 395 | local load = append[-1] |
| 406 | mp.commandv("loadfile", append[-1][i][1], "append") | 396 | for i = 1, #load do |
| 397 | mp.commandv("loadfile", load[i][1], "append") | ||
| 407 | end | 398 | end |
| 408 | mp.commandv("playlist-move", 0, current) | 399 | mp.commandv("playlist-move", 0, current) |
| 409 | end | 400 | end |