dimzon 05.03.2011 22:46

СкриптыСкрипт, собирающий видеоколлекцию с разных винтов и группирующий по названию / году выхода

Я у себя в квартире активно использую сетевые медиаплееры класса ASUS O!Play и его собратьев от IconBit. Эти плееры по NFS монтируют шару, расположенную на NAS. К сожалению интерфейс этих плееров очень примитивен - все что может делать плеер это ходить по папкам шары (сортировка только по наименованию, поиска нет). Кроме того у меня много винтов (видны как отдельные папки в шаре) и поиск конкретного фильма может быть весьма нетривиален. Посему я написал данный скрипт. Что он делает:
Сканирует все указанные в настройках папки (хранилища фильмов) и собирает при помощи символических ссылок все фильмы в одну папку
Создает папки по первой букве из названия, складывает все фильмы туда (т.е. например папочка "А" и в ней все фильмы на букву "А")
Создаёт папки по году выхода (используется регулярное выражение для поиска "года" в имени папки), складывает фильмы туда (т.е. например папочка "2010" и в ней все фильмы, вышедшие в 2010 году)
Находит дубликаты (по полному совпадению наименования папки с фильмом) и записывает их в специальный файл


Что планируется на будущее:
Поддержка разбиения по жанрам (наличие волшебного файлика в папочке с фильмом, например "Комедия.genre" приведёт к появлению символической ссылки на фильм в соответствующей папочке)
Поддержка разбиения по характеристикам и форматам (SD/HD/DVD)


 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python 
# -*- coding: utf-8 -*-

## <config> ############################################
duplicateFilePath = u"/nas/020_VIDEO/duplicates-lin.txt"
locationFileName = u"ku-ku-lin.txt"
folderPathAll = u"/nas/020_VIDEO/090_All"
folderPathByFirstLetter = u"/nas/020_VIDEO/010_By_Letter"
folderPathByYear = u"/nas/020_VIDEO/050_By_Year"
sourceFolders = <\
u"/nas/080_DRIVES/DriveD/VIDEO", \
u"/nas/080_DRIVES/DriveE/VIDEO", \
u"/nas/080_DRIVES/DriveF/VIDEO/00-Sorted", \
u"/nas/080_DRIVES/DriveG/VIDEO", \
u"/nas/080_DRIVES/DriveH/video", \
u"/nas/080_DRIVES/DriveI/0001/Serials", \
u"/nas/080_DRIVES/DriveI/0001/VIDEO", \
u"/nas/080_DRIVES/DriveJ/VIDEO" >
## </config> ###########################################


import os,re

def os_symlink( a, b ):
rp = os.path.relpath(a,os.path.dirname(b))
os.symlink( rp , b )

def get_first_letter( fileName ):
ltr = fileName<0>.upper()
if "0123456789.,!@#$_()
{}-".count(ltr):
return "(0-9)"
return ltr

reYear = re.compile(r"(?<=\D)(?:19|20)\d{2}(?=\D)", re.UNICODE )

def get_years(fileName):
return reYear.findall( fileName )


def clean_symlinks( folderPath ):
for i in os.listdir( folderPath ):
j = os.path.join( folderPath, i )
if os.path.islink( j ):
os.unlink( j )
elif os.path.isdir( j ):
clean_symlinks( j )
if len( os.listdir( j ) ) == 0 :
os.rmdir( j )

print 'Processing...'

clean_symlinks( folderPathAll )
clean_symlinks( folderPathByFirstLetter )
clean_symlinks( folderPathByYear )

knownFilms = {}
for f in sourceFolders:
print f
for i in os.listdir( f ):
j = os.path.join( f, i )
if os.path.isdir( j ):
with open( os.path.join( j, locationFileName ) , 'w' ) as loc:
loc.write( j.encode('utf-8') )
key = i.upper( )
if key in knownFilms :
knownFilms<key><1>.append( j )
else:
knownFilms</key><key>=( i.strip() , < j > )

with open( duplicateFilePath , 'w' ) as loc:
for i in knownFilms.values():
if len(i<1>) != 1 :
loc.write( ('### ' + i<0> + '\n\r').encode('utf-8') )
for j in i<1> :
loc.write( (j + '\n\r').encode('utf-8') )
loc.write( '\n\r\n\r' )

for i in knownFilms.values():
os_symlink( i<1><0> , os.path.join( folderPathAll , i<0> ) )
f = os.path.join( folderPathByFirstLetter , get_first_letter( i<0> ) )
if not os.path.exists( f ) :
os.mkdir( f )
os_symlink( i<1><0> , os.path.join( f , i<0> ) )
dt = get_years( i<0> )
for y in dt :
f = os.path.join( folderPathByYear , y )
if not os.path.exists( f ) :
os.mkdir( f )
os_symlink( i<1><0> , os.path.join( f , i<0> ) )

print 'Done!'</key>



Тэги: NAS python
+ 4 -
Похожие Поделиться

uscr 06.03.2011 14:32 #
А почему if "0123456789.,!@#$_()<>{}-".count(ltr):
вместо if ltr in "0123456789.,!@#$_()<>{}-"?

И поясните, пожалуйста, что делает clean_symlinks? Я так и не понял.
dimzon 06.03.2011 16:33 #
  1. ну я как-бы не спец по питону, все синтаксические конструкции постоянно гуглю...

  2. clean_symlinks рекурсивно удаляет симлинки и пустые папки (задача - аккуратно погрохать то что создал скрипт прошлый раз чтобы пересоздать все заново)

uscr 06.03.2011 20:16 #
Да это я просто придрался. Метод .count возвращает количество вхождений подстроки в строку. После первого вхождения, перебор будет продолжаться до победного. А конструкция if ltr in "0123456789.,!@#$_()<>{}-" прекратит перебор после первого совпадения. Если скрипт будет работать с 1000 фильмами, разница будет заметна.
dimzon 07.03.2011 00:22 #
имхо узкое место при запуске скрипта это раскрутить винты...