1 import os
, shutil
, re
, random
, threading
2 from urllib
import unquote
, unquote_plus
3 from urlparse
import urlparse
6 module_name
= '.'.join(['plugins', name
, name
])
7 module
= __import__(module_name
, globals(), locals(), name
)
8 plugin
= getattr(module
, module
.CLASS_NAME
)()
13 random_lock
= threading
.Lock()
17 def __new__(cls
, *args
, **kwds
):
18 it
= cls
.__dict
__.get('__it__')
21 cls
.__it
__ = it
= object.__new
__(cls
)
22 it
.init(*args
, **kwds
)
28 def send_file(self
, handler
, container
, name
):
29 o
= urlparse("http://fake.host" + handler
.path
)
30 path
= unquote_plus(o
[2])
31 handler
.send_response(200)
33 f
= file(container
['path'] + path
[len(name
)+1:], 'rb')
34 shutil
.copyfileobj(f
, handler
.wfile
)
36 def get_local_base_path(self
, handler
, query
):
38 subcname
= query
['Container'][0]
39 container
= handler
.server
.containers
[subcname
.split('/')[0]]
41 return container
['path']
43 def get_local_path(self
, handler
, query
):
45 subcname
= query
['Container'][0]
46 container
= handler
.server
.containers
[subcname
.split('/')[0]]
48 path
= container
['path']
49 for folder
in subcname
.split('/')[1:]:
52 path
= os
.path
.join(path
, folder
)
55 def item_count(self
, handler
, query
, cname
, files
):
56 """Return only the desired portion of the list, as specified by
57 ItemCount, AnchorItem and AnchorOffset
59 totalFiles
= len(files
)
62 if query
.has_key('ItemCount'):
63 count
= int(query
['ItemCount'][0])
65 if query
.has_key('AnchorItem'):
66 bs
= '/TiVoConnect?Command=QueryContainer&Container='
67 local_base_path
= self
.get_local_base_path(handler
, query
)
69 anchor
= query
['AnchorItem'][0]
70 if anchor
.startswith(bs
):
71 anchor
= anchor
.replace(bs
, '/')
72 anchor
= unquote(anchor
)
73 anchor
= anchor
.replace(os
.path
.sep
+ cname
, local_base_path
)
74 anchor
= os
.path
.normpath(anchor
)
77 index
= files
.index(anchor
)
79 print 'Anchor not found:', anchor
# just use index = 0
84 if query
.has_key('AnchorOffset'):
85 index
+= int(query
['AnchorOffset'][0])
89 files
= files
[index
:index
+ count
]
94 files
= files
[index
+ count
:index
]
100 files
= files
[:count
]
102 index
= count
% len(files
)
103 files
= files
[count
:]
105 return files
, totalFiles
, index
107 def get_files(self
, handler
, query
, filterFunction
=None):
108 subcname
= query
['Container'][0]
109 cname
= subcname
.split('/')[0]
110 path
= self
.get_local_path(handler
, query
)
112 files
= [ os
.path
.join(path
, file) for file in os
.listdir(path
)]
113 if query
.get('Recurse',['No'])[0] == 'Yes':
115 if os
.path
.isdir(file):
116 for new_file
in os
.listdir(file):
117 files
.append( os
.path
.join(file, new_file
) )
119 file_type
= query
.get('Filter', [''])[0]
121 files
= [file for file in files
if filterFunction(file, file_type
)]
123 totalFiles
= len(files
)
126 xdir
= os
.path
.isdir(os
.path
.join(path
, x
))
127 ydir
= os
.path
.isdir(os
.path
.join(path
, y
))
130 return name_sort(x
, y
)
135 numbername
= re
.compile(r
'(\d*)(.*)')
136 m
= numbername
.match(x
)
139 m
= numbername
.match(y
)
143 if xNumber
and yNumber
:
144 xNumber
, yNumber
= int(xNumber
), int(yNumber
)
145 if xNumber
== yNumber
:
146 return cmp(xStr
, yStr
)
148 return cmp(xNumber
, yNumber
)
154 return cmp(xStr
, yStr
)
156 if query
.get('SortOrder',['Normal'])[0] == 'Random':
157 seed
= query
.get('RandomSeed', ['1'])[0]
158 self
.random_lock
.acquire()
160 random
.shuffle(files
)
161 self
.random_lock
.release()
166 return self
.item_count(handler
, query
, cname
, files
)