1
2
3
4
5
6
7
8
9
10
11
12
13 | # encoding: UTF-8
# api: streamtuner2
# title: Drag and Drop
# description: Copy streams/stations from and to other applications.
# depends: uikit >= 1.8, action >= 1.0
# version: 0.6
# type: feature
# config:
# { name: dnd_format, type: select, value: xspf, select: "pls|m3u|xspf|jspf|asx|smil|desktop|srv", description: "Default temporary file format for copying a station." }
# category: io
# priority: default
# support: experimental
# |
|
| 1
2
3
4
5
6
7
8
9
10
11
12
13 | # encoding: UTF-8
# api: streamtuner2
# title: Drag and Drop
# description: Copy streams/stations from and to other applications.
# depends: uikit >= 1.8, action >= 1.0
# version: 0.7
# type: feature
# config:
# { name: dnd_format, type: select, value: xspf, select: "pls|m3u|xspf|jspf|asx|smil|desktop|srv", description: "Default temporary file format for copying a station." }
# category: io
# priority: default
# support: experimental
# |
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 |
# Prepare new converter
cnv = action.save_playlist(source=r["listformat"], multiply=False)
# internal JSON row
if info >= 51:
buf = 'text', json.dumps(r)
# Pass M3U/PLS/XSPF as literal payload
elif info >= 20:
buf = 'text', cnv.export(urls=[r["url"]], row=r, dest=self.cnv_types[info])
# Direct server URL
elif info >= 10:
urls = action.convert_playlist(r["url"], r["listformat"], "srv", False, r)
#buf = 'uris', urls
buf = 'text', urls[0]
# Text sources are assumed to understand the literal URL or expect a description block
elif info >= 5:
buf = 'text', "{url}\n# Title: {title}\n# Homepage: {homepage}\n\n".format(**r)
# Direct URL as text/uri-list
elif conf.dnd_format == "srv":
buf = 'uris', [self.row.get("url")]
# Create temporary PLS file, because "text/uri-list" is widely misunderstood and just implemented for file:// IRLs
else:
title = re.sub("[^\w-]+", "_", r["title"]).strip()
tmpfn = "{}/{}.{}".format(conf.tmp, title, conf.dnd_format)
log.DND("tmpfn", tmpfn)
cnv.file(rows=[r], dest=conf.dnd_format, fn=tmpfn)
if info == 4:
buf = 'uris', ["file://{}".format(tmpfn)] |
>
>
>
>
>
|
>
| 189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 |
# Prepare new converter
cnv = action.save_playlist(source=r["listformat"], multiply=False)
# internal JSON row
if info >= 51:
buf = 'text', json.dumps(r)
# Pass M3U/PLS/XSPF as literal payload
elif info >= 20:
buf = 'text', cnv.export(urls=[r["url"]], row=r, dest=self.cnv_types[info])
# Direct server URL
elif info >= 10:
urls = action.convert_playlist(r["url"], r["listformat"], "srv", False, r)
#buf = 'uris', urls
buf = 'text', urls[0]
# Text sources are assumed to understand the literal URL or expect a description block
elif info >= 5:
buf = 'text', "{url}\n# Title: {title}\n# Homepage: {homepage}\n\n".format(**r)
# Direct URL as text/uri-list
elif conf.dnd_format == "srv":
buf = 'uris', [self.row.get("url")]
# Create temporary PLS file, because "text/uri-list" is widely misunderstood
# and just used for file:// IRLs in drag and drops
else:
title = re.sub("[^\w-]+", "_", r["title"]).strip()
tmpfn = "{}/{}.{}".format(conf.tmp, title, conf.dnd_format)
log.DND("tmpfn", tmpfn)
cnv.file(rows=[r], dest=conf.dnd_format, fn=tmpfn)
if info == 4:
buf = 'uris', ["file://{}".format(tmpfn)] |
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297 | log.DND("Received row in internal format, append+reload")
rows += [ json.loads(data) ]
# Convertible formats as direct payload
elif data and info >= 5:
log.DND("Converting direct payload playlist")
cnv = action.extract_playlist(data)
if info >= 20:
fmt = self.cnv_types[info]
else:
fmt = cnv.probe_fmt()
if fmt == "href": fmt = "raw"
add = cnv.rows(fmt)
rows += [ cnv.mkrow(row) for row in add ]
# Extract from playlist files, either passed as text/uri-list or single FILE_NAME
elif urls:
log.DND("Importing from playlist file")
for fn in urls or [data]:
if not re.match("^(scp|file)://(localhost)?/|/", fn):
continue
fn = compat2and3.urldecode(re.sub("^\w+://[^/]*", "", fn))
cnv = action.extract_playlist(fn=fn)
if cnv.src:
rows += [ cnv.mkrow(row) for row in cnv.rows() ]
# Insert and update view
if rows:
cn.insert_rows(rows, y)
cn.save()
# Show streamedit window if title is empty
if not len(rows[0].get("title", "")): |
>
>
>
>
>
>
>
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
| 272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319 | log.DND("Received row in internal format, append+reload")
rows += [ json.loads(data) ]
# Convertible formats as direct payload
elif data and info >= 5:
log.DND("Converting direct payload playlist")
cnv = action.extract_playlist(data)
# known DND info format
if info >= 20:
fmt = self.cnv_types[info]
# else probe content (which also works for URLs in plain text)
else:
fmt = cnv.probe_fmt()
if fmt == "href": fmt = "raw"
add = cnv.rows(fmt)
rows += [ cnv.mkrow(row) for row in add ]
# Extract from playlist files, either passed as text/uri-list or single FILE_NAME
elif urls:
log.DND("Importing from playlist file")
for fn in urls or [data]:
# Plain file urls
if re.match("^(scp|file)://(localhost)?/|/", fn):
# read and convert playlist files
fn = compat2and3.urldecode(re.sub("^\w+://[^/]*", "", fn))
cnv = action.extract_playlist(fn=fn)
if cnv.src:
rows += [ cnv.mkrow(row) for row in cnv.rows() ]
# Real resource links, http://server:8090/.mp3 etc
else:
# Action module can't query streaming servers yet,
# so append a stub entry of just the target url,
# which will bring up the streamedit dialog
rows += [ dict(url=fn, title="", playing="", genre="url") ]
# Insert and update view
if rows:
cn.insert_rows(rows, y)
cn.save()
# Show streamedit window if title is empty
if not len(rows[0].get("title", "")): |