6 from urlparse
import urlparse
10 unquote
= urllib
.unquote_plus
12 quote
= lambda x
: urllib
.quote(x
.replace(os
.path
.sep
, '/'))
13 unquote
= lambda x
: urllib
.unquote_plus(x
).replace('/', os
.path
.sep
)
16 CONTENT_TYPE
= 'text/html'
20 module_name
= '.'.join(['plugins', name
, name
])
21 module
= __import__(module_name
, globals(), locals(), name
)
22 plugin
= getattr(module
, module
.CLASS_NAME
)()
25 print 'Error no', name
, 'plugin exists. Check the type ' \
26 'setting for your share.'
31 random_lock
= threading
.Lock()
35 def __new__(cls
, *args
, **kwds
):
36 it
= cls
.__dict
__.get('__it__')
39 cls
.__it
__ = it
= object.__new
__(cls
)
40 it
.init(*args
, **kwds
)
46 def send_file(self
, handler
, container
, name
):
47 o
= urlparse("http://fake.host" + handler
.path
)
49 handler
.send_response(200)
51 f
= open(container
['path'] + path
[len(name
) + 1:], 'rb')
52 shutil
.copyfileobj(f
, handler
.wfile
)
55 def get_local_base_path(self
, handler
, query
):
57 subcname
= query
['Container'][0]
58 container
= handler
.server
.containers
[subcname
.split('/')[0]]
60 return os
.path
.normpath(container
['path'])
62 def get_local_path(self
, handler
, query
):
64 subcname
= query
['Container'][0]
65 container
= handler
.server
.containers
[subcname
.split('/')[0]]
67 path
= os
.path
.normpath(container
['path'])
68 for folder
in subcname
.split('/')[1:]:
71 path
= os
.path
.join(path
, folder
)
74 def item_count(self
, handler
, query
, cname
, files
, last_start
=0):
75 """Return only the desired portion of the list, as specified by
76 ItemCount, AnchorItem and AnchorOffset. 'files' is either a
77 list of strings, OR a list of objects with a 'name' attribute.
79 def no_anchor(handler
, anchor
):
80 handler
.server
.logger
.warning('Anchor not found: ' + anchor
)
82 totalFiles
= len(files
)
85 if totalFiles
and 'ItemCount' in query
:
86 count
= int(query
['ItemCount'][0])
88 if 'AnchorItem' in query
:
89 bs
= '/TiVoConnect?Command=QueryContainer&Container='
90 local_base_path
= self
.get_local_base_path(handler
, query
)
92 anchor
= query
['AnchorItem'][0]
93 if anchor
.startswith(bs
):
94 anchor
= anchor
.replace(bs
, '/', 1)
95 anchor
= unquote(anchor
)
96 anchor
= anchor
.replace(os
.path
.sep
+ cname
, local_base_path
, 1)
97 if not '://' in anchor
:
98 anchor
= os
.path
.normpath(anchor
)
100 if type(files
[0]) == str:
103 filenames
= [x
.name
for x
in files
]
105 index
= filenames
.index(anchor
, last_start
)
109 index
= filenames
.index(anchor
, 0, last_start
)
111 no_anchor(handler
, anchor
)
113 no_anchor(handler
, anchor
) # just use index = 0
118 if 'AnchorOffset' in query
:
119 index
+= int(query
['AnchorOffset'][0])
123 files
= files
[index
:index
+ count
]
126 if index
+ count
< 0:
128 files
= files
[index
+ count
:index
]
131 else: # No AnchorItem
134 files
= files
[:count
]
136 index
= count
% len(files
)
137 files
= files
[count
:]
139 return files
, totalFiles
, index
141 def get_files(self
, handler
, query
, filterFunction
=None):
143 def build_recursive_list(path
, recurse
=True):
146 for f
in os
.listdir(path
):
147 if f
.startswith('.'):
149 f
= os
.path
.join(path
, f
)
150 if recurse
and os
.path
.isdir(f
):
151 files
.extend(build_recursive_list(f
))
153 if not filterFunction
or filterFunction(f
, file_type
):
159 subcname
= query
['Container'][0]
160 cname
= subcname
.split('/')[0]
161 path
= self
.get_local_path(handler
, query
)
163 file_type
= query
.get('Filter', [''])[0]
165 recurse
= query
.get('Recurse', ['No'])[0] == 'Yes'
166 files
= build_recursive_list(path
, recurse
)
168 totalFiles
= len(files
)
171 xdir
= os
.path
.isdir(os
.path
.join(path
, x
))
172 ydir
= os
.path
.isdir(os
.path
.join(path
, y
))
175 return name_sort(x
, y
)
183 return cmp(os
.stat(y
).st_mtime
, os
.stat(x
).st_mtime
)
185 if query
.get('SortOrder', ['Normal'])[0] == 'Random':
186 seed
= query
.get('RandomSeed', ['1'])[0]
187 self
.random_lock
.acquire()
189 random
.shuffle(files
)
190 self
.random_lock
.release()
191 elif query
.get('SortOrder', ['Normal'])[0] == '!CaptureDate':
192 files
.sort(date_sort
)
197 return self
.item_count(handler
, query
, cname
, files
)