ソースを参照

Koda refaktorings (stream0 u.c.)

Ivars 7 年 前
コミット
5ff5e469b2
共有32 個のファイルを変更した702 個の追加1349 個の削除を含む
  1. 14
    6
      ContentSources.py
  2. 2
    2
      PlayStream.py
  3. 138
    135
      PlayStream.wpr
  4. 0
    684
      PlayStream0.py
  5. 16
    13
      changelog.md
  6. 9
    1
      imake.bat
  7. 1
    1
      ipkg/CONTROL/control
  8. バイナリ
      ipkg/control.tar.gz
  9. バイナリ
      ipkg/data.tar.gz
  10. 18
    11
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/ContentSources.py
  11. 2
    2
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/PlayStream.py
  12. 1
    1
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/resolvers/hqqresolver.py
  13. 9
    13
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/SourceBase.py
  14. 36
    35
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/euronews.py
  15. 56
    55
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/iplayer.py
  16. 106
    106
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/ltc.py
  17. 4
    4
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/movieplace.py
  18. 35
    35
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/serialguru.py
  19. 13
    1
      ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/util.py
  20. バイナリ
      release/enigma2-plugin-extensions-playstream_0.5r.ipk
  21. バイナリ
      release/enigma2-plugin-extensions-playstream_0.5s.ipk
  22. 9
    13
      sources/SourceBase.py
  23. バイナリ
      sources/SourceBase.pyc
  24. 36
    35
      sources/euronews.py
  25. バイナリ
      sources/euronews.pyc
  26. 56
    55
      sources/iplayer.py
  27. バイナリ
      sources/iplayer.pyc
  28. 106
    106
      sources/ltc.py
  29. バイナリ
      sources/ltc.pyc
  30. バイナリ
      sources/movieplace.pyc
  31. 35
    35
      sources/serialguru.py
  32. バイナリ
      sources/serialguru.pyc

+ 14
- 6
ContentSources.py ファイルの表示

@@ -12,8 +12,6 @@ from  sources.SourceBase import stream_type
12 12
 import util
13 13
 
14 14
 
15
-stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {}, "desc":"", "img":"", "lang": "", "type": ""}
16
-
17 15
 class ContentSources(object):
18 16
     """Wrapper for content sources plugin"""
19 17
 
@@ -78,7 +76,7 @@ class ContentSources(object):
78 76
             if "::" in data:
79 77
                 data = data.split("::")[1]
80 78
             content = self.get_content(data)
81
-            stream = stream0.copy()
79
+            stream = util.item()
82 80
             stream["name"] = data
83 81
             stream["url"] = data
84 82
             stream["type"] = stream_type(data)
@@ -170,12 +168,16 @@ if __name__ == "__main__":
170 168
             cur = history.pop()
171 169
         elif sources.is_video(cur2[1]):
172 170
             if sources.stream_type(cur2[1]):
173
-                stream = stream0.copy()
171
+                stream = util.item()
174 172
                 stream["url"] = cur2[1]
175 173
                 stream["name"] = cur2[0]
176 174
                 streams = [stream]
177 175
             else:
178
-                streams = sources.get_streams(cur2[1])
176
+                try:
177
+                    streams = sources.get_streams(cur2[1])
178
+                except Exception as e:
179
+                    print str(e)
180
+                    streams = []
179 181
             if streams:
180 182
                 util.play_video(streams)
181 183
             else:
@@ -190,4 +192,10 @@ if __name__ == "__main__":
190 192
                 cur2 = (cur2[0],cur2[1].format(a),cur2[2],cur2[3])
191 193
             history.append(cur)
192 194
             cur = cur2
193
-        content = sources.get_content(cur[1])
195
+        try:
196
+            content = sources.get_content(cur[1])
197
+        except Exception as e:
198
+            print str(e)
199
+            raw_input("Continue?")
200
+
201
+

+ 2
- 2
PlayStream.py ファイルの表示

@@ -518,7 +518,7 @@ class MainScreen(Screen):
518 518
 
519 519
         elif self.sources.is_video(current[1]):
520 520
             if self.sources.stream_type(current[1]):
521
-                stream = stream0.copy()
521
+                stream = util.item()
522 522
                 stream["url"] = current[1]
523 523
                 stream["name"] = current[0]
524 524
                 streams = [stream]
@@ -711,7 +711,7 @@ class MainScreen(Screen):
711 711
 
712 712
     def download_video(self,current):
713 713
         if self.sources.stream_type(current[1]):
714
-            stream = stream0.copy()
714
+            stream = util.item()
715 715
             stream["url"] = current[1]
716 716
             stream["name"] = current[0]
717 717
             streams = [stream]

+ 138
- 135
PlayStream.wpr ファイルの表示

@@ -12,7 +12,7 @@ proj.directory-list = [{'dirloc': loc('.'),
12 12
                         'watch_for_changes': True}]
13 13
 proj.file-type = 'normal'
14 14
 proj.launch-config = {loc('ContentSources.py'): ('project',
15
-        (u'filmix::home',
15
+        (u'config::home',
16 16
          '')),
17 17
                       loc('filmix_decode2.py'): ('project',
18 18
         (u'XRHzQZe3yvH32Z5ly1b3XakY7RUw7LYl7L60yM2n2ZQLOZtlfZUT2mUW2jkw2xtv2W20fxEMOZcLfW50yM=Va02lynHeDSYPDWDwQWwgDLsL2ZEMyVnmizlgkzkCHEGSXabNmLlzOZA4205laSYIQZch',
@@ -49,7 +49,15 @@ proj.launch-config = {loc('ContentSources.py'): ('project',
49 49
          ''))}
50 50
 [user attributes]
51 51
 cache.last-mime-type = {loc('unknown:<untitled> #1'): 'text/x-diff'}
52
-debug.breakpoints = {loc('gstreamer/player-minimal.py'): {12: (0,
52
+debug.breakpoints = {loc('ContentSources.py'): {180L: (0,
53
+        None,
54
+        1,
55
+        0),
56
+        199L: (0,
57
+               None,
58
+               1,
59
+               0)},
60
+                     loc('gstreamer/player-minimal.py'): {12: (0,
53 61
         None,
54 62
         1,
55 63
         0)},
@@ -4966,9 +4974,9 @@ debug.err-values = {None: {},
4966 4974
                                     0)},
4967 4975
                     loc('test_sources.py'): {},
4968 4976
                     loc('viaplay/vialib.py'): {}}
4969
-debug.recent-run-args = {loc('ContentSources.py'): [u'filmix::home',
4977
+debug.recent-run-args = {loc('ContentSources.py'): [u'config::home',
4978
+        u'filmix::home',
4970 4979
         u'movieplace::home',
4971
-        u'config::home',
4972 4980
         u'config::movieplace',
4973 4981
         u'ltc::home',
4974 4982
         u'ltc::videonoma/raidijumi/littlest_pet_shop_s1e26?series',
@@ -5077,7 +5085,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5077 5085
                                    0],
5078 5086
                  'full-screen': False,
5079 5087
                  'notebook_display': 'normal',
5080
-                 'notebook_percent': 0.25,
5088
+                 'notebook_percent': 0.18151950718685828,
5081 5089
                  'override_title': None,
5082 5090
                  'pagelist': [('project',
5083 5091
                                'tall',
@@ -5112,7 +5120,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5112 5120
                                {})],
5113 5121
                  'primary_view_state': {'area': 'wide',
5114 5122
         'constraint': None,
5115
-        'current_pages': [1,
5123
+        'current_pages': [3,
5116 5124
                           0],
5117 5125
         'notebook_display': 'normal',
5118 5126
         'notebook_percent': 0.30000000000000004,
@@ -5228,21 +5236,14 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5228 5236
         -1,
5229 5237
         -1),
5230 5238
                        'attrib-starts': [],
5231
-                       'first-line': 17L,
5239
+                       'first-line': 0L,
5232 5240
                        'folded-linenos': [],
5233
-                       'history': {None: ['import urllib\n',
5234
-        'urllib.urlencode("~")\n',
5235
-        'urllib.quote("~")\n',
5236
-        'urllib.quote("=")\n',
5237
-        'urllib.quote(":")\n',
5238
-        'urllib.quote(" ")\n',
5239
-        "urllib.unquote('%20')\n",
5240
-        "urllib.unquote('%3A')\n"]},
5241
+                       'history': {},
5241 5242
                        'launch-id': None,
5242
-                       'sel-line': 25L,
5243
-                       'sel-line-start': 597L,
5244
-                       'selection_end': 597L,
5245
-                       'selection_start': 597L}),
5243
+                       'sel-line': 2L,
5244
+                       'sel-line-start': 146L,
5245
+                       'selection_end': 146L,
5246
+                       'selection_start': 146L}),
5246 5247
                      ('bookmarks',
5247 5248
                       'wide',
5248 5249
                       1,
@@ -5255,98 +5256,18 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5255 5256
                       'wide',
5256 5257
                       1,
5257 5258
                       {})],
5258
-        'primary_view_state': {'editor_states': ({'bookmarks': ([[loc('PlayStream.py'),
5259
-        {'attrib-starts': [('make_service',
5260
-                            54)],
5261
-         'first-line': 48L,
5259
+        'primary_view_state': {'editor_states': ({'bookmarks': ([[loc('sources/viaplay.py'),
5260
+        {'attrib-starts': [('Source',
5261
+                            26),
5262
+                           ('Source.get_streams',
5263
+                            308)],
5264
+         'first-line': 359L,
5262 5265
          'folded-linenos': [],
5263
-         'sel-line': 62L,
5264
-         'sel-line-start': 2423L,
5265
-         'selection_end': 2434L,
5266
-         'selection_start': 2431L},
5267
-        1484607010.339],
5268
-        [loc('resolver.py'),
5269
-         {'attrib-starts': [('resolve',
5270
-                             58)],
5271
-          'first-line': 63L,
5272
-          'folded-linenos': [],
5273
-          'sel-line': 77L,
5274
-          'sel-line-start': 2757L,
5275
-          'selection_end': 2775L,
5276
-          'selection_start': 2770L},
5277
-         1484607107.471],
5278
-        [loc('PlayStream.py'),
5279
-         {'attrib-starts': [('make_service',
5280
-                             54)],
5281
-          'first-line': 48L,
5282
-          'folded-linenos': [],
5283
-          'sel-line': 62L,
5284
-          'sel-line-start': 2423L,
5285
-          'selection_end': 2434L,
5286
-          'selection_start': 2431L},
5287
-         1484607110.911],
5288
-        [loc('resolver.py'),
5289
-         {'attrib-starts': [('resolve',
5290
-                             58)],
5291
-          'first-line': 0L,
5292
-          'folded-linenos': [],
5293
-          'sel-line': 78L,
5294
-          'sel-line-start': 2777L,
5295
-          'selection_end': 2800L,
5296
-          'selection_start': 2800L},
5297
-         1484607694.642],
5298
-        [loc('PlayStream.py'),
5299
-         {'attrib-starts': [('make_service',
5300
-                             54)],
5301
-          'first-line': 48L,
5302
-          'folded-linenos': [],
5303
-          'sel-line': 70L,
5304
-          'sel-line-start': 2693L,
5305
-          'selection_end': 2752L,
5306
-          'selection_start': 2749L},
5307
-         1484607716.008],
5308
-        [loc('resolvers/hqqresolver.py'),
5309
-         {'attrib-starts': [('resolve',
5310
-                             123)],
5311
-          'first-line': 19L,
5312
-          'folded-linenos': [],
5313
-          'sel-line': 186L,
5314
-          'sel-line-start': 7258L,
5315
-          'selection_end': 7304L,
5316
-          'selection_start': 7304L},
5317
-         1484607729.213],
5318
-        [loc('resolver.py'),
5319
-         {'attrib-starts': [('resolve',
5320
-                             58)],
5321
-          'first-line': 0L,
5322
-          'folded-linenos': [],
5323
-          'sel-line': 78L,
5324
-          'sel-line-start': 2777L,
5325
-          'selection_end': 2800L,
5326
-          'selection_start': 2800L},
5327
-         1484607731.627],
5328
-        [loc('PlayStream.py'),
5329
-         {'attrib-starts': [('make_service',
5330
-                             54)],
5331
-          'first-line': 55L,
5332
-          'folded-linenos': [],
5333
-          'sel-line': 70L,
5334
-          'sel-line-start': 2693L,
5335
-          'selection_end': 2752L,
5336
-          'selection_start': 2749L},
5337
-         1484608179.858],
5338
-        [loc('sources/viaplay.py'),
5339
-         {'attrib-starts': [('Source',
5340
-                             26),
5341
-                            ('Source.get_streams',
5342
-                             308)],
5343
-          'first-line': 359L,
5344
-          'folded-linenos': [],
5345
-          'sel-line': 363L,
5346
-          'sel-line-start': 17585L,
5347
-          'selection_end': 17617L,
5348
-          'selection_start': 17617L},
5349
-         1484608183.824],
5266
+         'sel-line': 363L,
5267
+         'sel-line-start': 17585L,
5268
+         'selection_end': 17617L,
5269
+         'selection_start': 17617L},
5270
+        1484608183.824],
5350 5271
         [loc('sources/viaplay.py'),
5351 5272
          {'attrib-starts': [('Source',
5352 5273
                              26),
@@ -5462,9 +5383,94 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5462 5383
           'sel-line-start': 1951L,
5463 5384
           'selection_end': 1951L,
5464 5385
           'selection_start': 1951L},
5465
-         1484645288.691]],
5386
+         1484645288.691],
5387
+        [loc('sources/filmix.py'),
5388
+         {'attrib-starts': [('Source',
5389
+                             24),
5390
+                            ('Source.get_content',
5391
+                             49)],
5392
+          'first-line': 70L,
5393
+          'folded-linenos': [],
5394
+          'sel-line': 75L,
5395
+          'sel-line-start': 2549L,
5396
+          'selection_end': 2549L,
5397
+          'selection_start': 2549L},
5398
+         1484681063.486],
5399
+        [loc('ContentSources.py'),
5400
+         {'attrib-starts': [('ContentSources',
5401
+                             14),
5402
+                            ('ContentSources.get_content',
5403
+                             47)],
5404
+          'first-line': 0L,
5405
+          'folded-linenos': [],
5406
+          'sel-line': 59L,
5407
+          'sel-line-start': 2432L,
5408
+          'selection_end': 2453L,
5409
+          'selection_start': 2453L},
5410
+         1484681485.732],
5411
+        [loc('sources/filmix.py'),
5412
+         {'attrib-starts': [('Source',
5413
+                             24),
5414
+                            ('Source.get_content',
5415
+                             49)],
5416
+          'first-line': 0L,
5417
+          'folded-linenos': [],
5418
+          'sel-line': 75L,
5419
+          'sel-line-start': 2549L,
5420
+          'selection_end': 2549L,
5421
+          'selection_start': 2549L},
5422
+         1484681490.881],
5423
+        [loc('ContentSources.py'),
5424
+         {'attrib-starts': [],
5425
+          'first-line': 154L,
5426
+          'folded-linenos': [],
5427
+          'sel-line': 179L,
5428
+          'sel-line-start': 6128L,
5429
+          'selection_end': 6163L,
5430
+          'selection_start': 6163L},
5431
+         1484682345.643],
5432
+        [loc('sources/serialguru.py'),
5433
+         {'attrib-starts': [('Source',
5434
+                             21),
5435
+                            ('Source.get_content',
5436
+                             45)],
5437
+          'first-line': 151L,
5438
+          'folded-linenos': [],
5439
+          'sel-line': 165L,
5440
+          'sel-line-start': 9363L,
5441
+          'selection_end': 9363L,
5442
+          'selection_start': 9363L},
5443
+         1484682357.737],
5444
+        [loc('ContentSources.py'),
5445
+         {'attrib-starts': [],
5446
+          'first-line': 176L,
5447
+          'folded-linenos': [],
5448
+          'sel-line': 198L,
5449
+          'sel-line-start': 6811L,
5450
+          'selection_end': 6811L,
5451
+          'selection_start': 6811L},
5452
+         1484683092.344],
5453
+        [loc('util.py'),
5454
+         {'attrib-starts': [('play_video',
5455
+                             49)],
5456
+          'first-line': 57L,
5457
+          'folded-linenos': [],
5458
+          'sel-line': 71L,
5459
+          'sel-line-start': 1951L,
5460
+          'selection_end': 1951L,
5461
+          'selection_start': 1951L},
5462
+         1484683112.755],
5463
+        [loc('ContentSources.py'),
5464
+         {'attrib-starts': [],
5465
+          'first-line': 176L,
5466
+          'folded-linenos': [],
5467
+          'sel-line': 198L,
5468
+          'sel-line-start': 6811L,
5469
+          'selection_end': 6812L,
5470
+          'selection_start': 6812L},
5471
+         1484683129.526]],
5466 5472
         20),
5467
-        'current-loc': loc('sources/filmix.py'),
5473
+        'current-loc': loc('ContentSources.py'),
5468 5474
         'editor-state-list': [(loc('plugin.py'),
5469 5475
                                {'attrib-starts': [('main',
5470 5476
         4)],
@@ -5484,22 +5490,19 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5484 5490
                                 'selection_end': 2982L,
5485 5491
                                 'selection_start': 2982L}),
5486 5492
                               (loc('ContentSources.py'),
5487
-                               {'attrib-starts': [('ContentSources',
5488
-        15),
5489
-        ('ContentSources.get_content',
5490
-         48)],
5491
-                                'first-line': 47L,
5493
+                               {'attrib-starts': [],
5494
+                                'first-line': 160L,
5492 5495
                                 'folded-linenos': [],
5493
-                                'sel-line': 60L,
5494
-                                'sel-line-start': 2605L,
5495
-                                'selection_end': 2626L,
5496
-                                'selection_start': 2626L}),
5496
+                                'sel-line': 198L,
5497
+                                'sel-line-start': 6811L,
5498
+                                'selection_end': 6812L,
5499
+                                'selection_start': 6812L}),
5497 5500
                               (loc('sources/filmix.py'),
5498 5501
                                {'attrib-starts': [('Source',
5499 5502
         24),
5500 5503
         ('Source.get_content',
5501 5504
          49)],
5502
-                                'first-line': 70L,
5505
+                                'first-line': 0L,
5503 5506
                                 'folded-linenos': [],
5504 5507
                                 'sel-line': 75L,
5505 5508
                                 'sel-line-start': 2549L,
@@ -5578,7 +5581,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5578 5581
                               (loc('util.py'),
5579 5582
                                {'attrib-starts': [('play_video',
5580 5583
         49)],
5581
-                                'first-line': 58L,
5584
+                                'first-line': 57L,
5582 5585
                                 'folded-linenos': [],
5583 5586
                                 'sel-line': 71L,
5584 5587
                                 'sel-line-start': 1951L,
@@ -5592,7 +5595,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5592 5595
                                 'sel-line-start': 21214L,
5593 5596
                                 'selection_end': 21230L,
5594 5597
                                 'selection_start': 21226L})],
5595
-        'has-focus': False,
5598
+        'has-focus': True,
5596 5599
         'locked': False},
5597 5600
         [loc('plugin.py'),
5598 5601
          loc('PlayStream.py'),
@@ -5607,21 +5610,21 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5607 5610
          loc('sources/SourceBase.py'),
5608 5611
          loc('util.py'),
5609 5612
          loc('sources/viaplay.py')]),
5610
-                               'open_files': [u'sources/iplayer.py',
5613
+                               'open_files': [u'PlayStream.py',
5611 5614
         u'playstreamproxy.py',
5612
-        u'sources/replay.py',
5613
-        u'sources/SourceBase.py',
5614 5615
         u'plugin.py',
5615
-        u'resolvers/hqqresolver.py',
5616 5616
         u'resolver.py',
5617
-        u'sources/viaplay.py',
5618
-        u'PlayStream.py',
5617
+        u'resolvers/hqqresolver.py',
5618
+        u'sources/SourceBase.py',
5619
+        u'sources/iplayer.py',
5619 5620
         u'sources/movieplace.py',
5620
-        u'ContentSources.py',
5621
+        u'sources/replay.py',
5622
+        u'sources/viaplay.py',
5623
+        u'sources/filmix.py',
5621 5624
         u'util.py',
5622
-        u'sources/filmix.py']},
5625
+        u'ContentSources.py']},
5623 5626
         'saved_notebook_display': None,
5624
-        'split_percents': {0: 0.5},
5627
+        'split_percents': {0: 0.3093198992443325},
5625 5628
         'splits': 2,
5626 5629
         'tab_location': 'top',
5627 5630
         'user_data': {}},
@@ -5634,9 +5637,9 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
5634 5637
                          52,
5635 5638
                          2408,
5636 5639
                          1390)}]}
5637
-guimgr.recent-documents = [loc('sources/filmix.py'),
5640
+guimgr.recent-documents = [loc('ContentSources.py'),
5638 5641
                            loc('util.py'),
5639
-                           loc('ContentSources.py'),
5642
+                           loc('sources/filmix.py'),
5640 5643
                            loc('sources/movieplace.py'),
5641 5644
                            loc('PlayStream.py'),
5642 5645
                            loc('sources/viaplay.py'),

+ 0
- 684
PlayStream0.py ファイルの表示

@@ -1,684 +0,0 @@
1
-#!/usr/bin/env python
2
-# coding=utf8
3
-#
4
-#
5
-# This file is part of PlayStream - enigma2 plugin to play video streams from various sources
6
-# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
7
-# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
8
-# Used fragments of code from enigma2-plugin-tv3play by Taapat (https://github.com/Taapat/enigma2-plugin-tv3play)
9
-#
10
-
11
-import os,time,sys,os,os.path
12
-import datetime,re
13
-
14
-from enigma import ePicLoad, eServiceReference, eTimer
15
-from Components.ActionMap import ActionMap,HelpableActionMap
16
-from Components.AVSwitch import AVSwitch
17
-from Components.Label import Label
18
-from Components.MenuList import MenuList
19
-from Components.Pixmap import Pixmap
20
-from Components.Sources.List import List
21
-from Components.Sources.StaticText import StaticText
22
-from Components.Button import Button
23
-from Plugins.Plugin import PluginDescriptor
24
-from Screens.InfoBar import MoviePlayer
25
-from Screens.MessageBox import MessageBox
26
-#from Screens.InputBox import InputBox
27
-from Screens.ChoiceBox import ChoiceBox
28
-from Screens.VirtualKeyBoard import VirtualKeyBoard
29
-from Components.Input import Input
30
-from Screens.Screen import Screen
31
-from Tools.BoundFunction import boundFunction
32
-from Tools.Directories import resolveFilename, SCOPE_PLUGINS
33
-from Tools.LoadPixmap import LoadPixmap
34
-from twisted.web.client import downloadPage,defer,reactor
35
-from Components.Task import job_manager
36
-
37
-import ContentSources
38
-from VideoDownload import downloadJob, HLSDownloadJob,VideoDownloadList
39
-#import enigma2_api
40
-
41
-TMPDIR = "/tmp/playstream/"
42
-e2 = None
43
-
44
-
45
-def make_service(stream):
46
-    url = stream["url"]
47
-    headers = []
48
-    if stream.has_key("headers"):
49
-        for h in stream["headers"]:
50
-            headers.append("%s=%s"%(h,stream["headers"][h]))
51
-    if headers:
52
-        headers ="&".jpin(headers)
53
-        url = url+"#"+headers
54
-    print url
55
-    url = url.encode("utf8")
56
-    service = eServiceReference(4097, 0, url)
57
-    service.setName( stream["name"])
58
-    return service
59
-
60
-#####################################################################################################################
61
-class TVPlayer(MoviePlayer):
62
-    def __init__(self, session, service):
63
-        
64
-        MoviePlayer.__init__(self, session, service)
65
-        self.skinName = "MoviePlayer"
66
-            
67
-
68
-    def leavePlayer(self):
69
-        self.close()
70
-        #self.session.openWithCallback(self.leavePlayerConfirmed, MessageBox, _("Stop playing?"))
71
-
72
-    def leavePlayerConfirmed(self, answer):
73
-        if answer:
74
-            self.close()
75
-
76
-    def doEofInternal(self, playing):
77
-        self.close()
78
-
79
-    #def getPluginList(self):
80
-        #from Components.PluginComponent import plugins
81
-        #list = []
82
-        #for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU):
83
-            #if p.name != _("TV Play"):
84
-                #list.append(((boundFunction(self.getPluginName, p.name),
85
-                    #boundFunction(self.runPlugin, p), lambda: True), None))
86
-        #return list
87
-
88
-    #def showMovies(self):
89
-        #pass
90
-
91
-#####################################################################################################################
92
-class PSPlayer(TVPlayer):
93
-    def __init__(self, session, streams):
94
-        self.session = session
95
-        self.streams = streams
96
-        self.cur_stream = self.streams[0] # TODO
97
-        self.selected = 0
98
-        
99
-        service = make_service(self.cur_stream)        
100
-        TVPlayer.__init__(self, session, service)
101
-        self["actions"] = ActionMap(["MoviePlayerActions","MovieSelectionActions","ColorActions","InfobarAudioSelectionActions"], {
102
-            "leavePlayer":self.leavePlayer,
103
-            "AudioSelection":self.select_stream,
104
-            "audioSelection":self.select_stream,
105
-            "green":self.select_stream,
106
-            "showEventInfo":self.service_info
107
-        })
108
-        self.skinName = "MoviePlayer"
109
-        
110
-    def play_service(self,service):
111
-        self.movieSelected(service)
112
-    
113
-    def service_info(self):
114
-        print "########[MoviePlayer] service_info"
115
-        from Tools import Notifications
116
-        text = "%s\n%s %s\n%s"%(self.cur_stream["name"],self.cur_stream["lang"],self.cur_stream["quality"],self.cur_stream["desc"])
117
-        text = text.encode("utf8")
118
-        #print text
119
-        type = MessageBox.TYPE_INFO
120
-        Notifications.AddPopup(text = text, type=None, timeout = 10)
121
-        #Notifications.MessageBox(self.session, text=text, type=MessageBox.TYPE_INFO, timeout=10, 
122
-                                #close_on_any_key=True, 
123
-                                #default=True, 
124
-                                #enable_input=True, 
125
-                                #msgBoxID=None, 
126
-                                #picon=False, 
127
-                                #simple=False, 
128
-                                #wizard=False, 
129
-                                #list=None, 
130
-                                #skin_name=None, 
131
-                                #timeout_default=None)
132
-        #return True
133
- 
134
-    def select_stream(self):
135
-        print "########[MoviePlayer] select_stream"
136
-        lst = []
137
-        title = "Select stream"
138
-        for i,s in enumerate(self.streams):
139
-            lst.append(("[%s,%s] %s"%(s["lang"],s["quality"],s["name"]),i))
140
-        self.session.openWithCallback(self.cb_select_stream, ChoiceBox, text = title, list = lst,selection = self.selected)
141
-
142
-    def cb_select_stream(self,answer):
143
-        #print "item_menu_selected",answer
144
-        if not answer:
145
-            return
146
-        self.selected = answer[1]
147
-        service = make_service(self.streams[self.selected])
148
-        self.play_service(service)
149
-
150
-        
151
-#####################################################################################################################
152
-class MainScreen(Screen):
153
-    skin = """
154
-<screen position="center,center" size="1015,570" title="Play Stream">
155
-    <eLabel position="5,0" size="1000,2" backgroundColor="#aaaaaa" />
156
-    <widget name="title" position="10,2" size="1000,38" font="Regular;30" />
157
-    <widget source="list" render="Listbox" position="10,55" size="580,470" \
158
-            scrollbarMode="showOnDemand" >
159
-            <convert type="TemplatedMultiContent" >
160
-            {
161
-                    "template": [MultiContentEntryText(pos=(10, 1), size=(560, 30), \
162
-                                    font=0, flags=RT_HALIGN_LEFT, text=0)],
163
-                    "fonts": [gFont("Regular", 20)],
164
-                    "itemHeight": 30
165
-            }
166
-            </convert>
167
-    </widget>
168
-    <widget name="pic" position="646,55" size="327,250" alphatest="on" />
169
-    <widget name="cur" position="610,310" size="400,250" halign="center" font="Regular;20"/>
170
-
171
-    <ePixmap name="red"    position="100,530"   zPosition="2" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
172
-    <widget name="key_red" position="100,530" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
173
-    <ePixmap name="green"  position="240,530" zPosition="2" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
174
-    <widget name="key_green" position="240,530" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
175
-    <ePixmap name="yellow" position="380,530" zPosition="2" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
176
-    <widget name="key_yellow" position="380,530" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
177
-    <ePixmap name="menu"   position="560,535" zPosition="2" size="140,40"  pixmap="skin_default/buttons/key_menu.png" transparent="1" alphatest="on" />
178
-    <widget name="key_menu" position="560,530" size="140,40" valign="center" halign="center" zPosition="4"  backgroundColor="blue" foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
179
-    
180
-</screen>"""
181
-
182
-    def __init__(self, session):
183
-        Screen.__init__(self, session)
184
-        #self.setTitle2("Home")
185
-        self.session = session
186
-        self.e2 = None
187
-        self["key_red"] = Button(_("Back"))
188
-        self["key_green"] = Button(_("Select"))
189
-        self["key_yellow"] = Button(_("Options"))
190
-        self["key_menu"] = Button("Menu" )
191
-        
192
-        self["actions"] = ActionMap(["OkCancelActions", "ColorActions","MenuActions", "NumberActions"],
193
-                                    {
194
-                                        "cancel": self.Cancel,
195
-                                        "ok": self.Ok,
196
-                                        "green": self.Ok,
197
-                                        "red": self.Back,
198
-                                        "yellow": self.options_screen,
199
-                                        "blue": self.download_list,
200
-                                        "menu": self.item_menu,
201
-                                    })
202
-        self["list"] = List([])
203
-        self["list"].onSelectionChanged.append(self.SelectionChanged)
204
-        self["pic"] = Pixmap()
205
-        self["cur"] = Label()
206
-        self["title"] = Label()
207
-        self.downloading = 0
208
-        self.activeDownloads = 0
209
-        if not os.path.exists(TMPDIR):
210
-            os.mkdir(TMPDIR)
211
-        self.onLayoutFinish.append(self.LayoutFinish)
212
-
213
-    def LayoutFinish(self):
214
-        self.cur_directory = os.path.dirname(os.path.realpath(__file__))
215
-        self.defimage = LoadPixmap(os.path.join(self.cur_directory,"PlayStream.png"))
216
-        #self.defimage = None
217
-        #sc = AVSwitch().getFramebufferScale()
218
-        #self.defimage0 = ePicLoad()
219
-        #self.defimage0.PictureData.get().append(boundFunction(self.FinishDecodeDef, os.path.join(self.cur_directory,"PlayStream.png")))
220
-        #self.defimage0.setPara((self["pic"].instance.size().width(),self["pic"].instance.size().height(),sc[0], sc[1], False, 0, "#00000000"))
221
-        #self.defimage0.startDecode("default")
222
-        
223
-        self.activeDownloads = 0
224
-        self.images = {}
225
-        self.images_url = {}
226
-        self.picloads = {}
227
-        self.history = []
228
-        
229
-        reload(ContentSources)
230
-        self.sources = ContentSources.ContentSources(os.path.join(self.cur_directory,"sources"))
231
-        self.config = self.sources.plugins["config"]
232
-        self.cur_menu = ("Home","config::home","","Sākums") #
233
-        try:
234
-            self.content = self.sources.get_content(self.cur_menu[1])
235
-        except Exception,e:               
236
-            self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
237
-            return
238
-        print self.content
239
-        self["list"].setList(self.content)
240
-        self["cur"].setText(self.content[0][3])
241
-        self.setTitle2(self.cur_menu[0])
242
-        self.ShowPic(self.content[0][2])
243
-
244
-
245
-    def SelectionChanged(self):
246
-        current = self["list"].getCurrent()
247
-        print "[PlayStream] SelectionChanged: current=",current
248
-        if not current: return
249
-        self["cur"].setText(current[3]) if current[3] else self["cur"].setText("")
250
-        if current[2]:
251
-            self.ShowPic(current[2])
252
-        else:
253
-            self.ShowDefPic()
254
-
255
-    def setTitle2(self,title):
256
-        #print self.keys()
257
-        self["title"].setText(title)
258
-        
259
-    def ShowDefPic(self):
260
-        if self.defimage:
261
-            self["pic"].instance.setPixmap(self.defimage)
262
-
263
-    def ShowPic(self,image_url):
264
-        if image_url == "default":
265
-            self.ShowDefPic()
266
-            return
267
-        elif self.images.has_key(image_url):
268
-            if self.images[image_url] in (-1,-2):
269
-                return
270
-            elif self.images[image_url] == -3:
271
-                self.ShowDefPic()
272
-                return
273
-            else:
274
-                self["pic"].instance.setPixmap(self.images[image_url])
275
-        else:
276
-            if image_url.startswith("http"):
277
-                fname = image_url.replace(":","-").replace("/","_")
278
-                image_path = os.path.join(TMPDIR, fname)
279
-                self.download_image(image_path, image_url)
280
-            else: # local file
281
-                image_path = os.path.join(self.cur_directory,image_url)
282
-                self.start_decode(image_path,image_url)
283
-            
284
-    def start_decode(self,image_path,image_url):
285
-        self.images[image_url] = -2
286
-        self.images_url[image_path] = image_url
287
-        sc = AVSwitch().getFramebufferScale()
288
-        if  not self.picloads.has_key(image_path):
289
-            self.picloads[image_path] = ePicLoad()
290
-            self.picloads[image_path].PictureData.get().append(boundFunction(self.FinishDecode, image_path))
291
-            self.picloads[image_path].setPara((self["pic"].instance.size().width(),
292
-                                          self["pic"].instance.size().height(),
293
-                                          sc[0], sc[1], False, 0, "#00000000"))
294
-            print image_path,image_url
295
-            self.picloads[image_path].startDecode(image_path)
296
-
297
-    def FinishDecode(self, image_path,picInfo = None):
298
-        image_url = self.images_url[image_path]
299
-        del self.images_url[image_path] #III
300
-        self.images[image_url] = self.picloads[image_path].getData()
301
-        self["pic"].instance.setPixmap(self.images[image_url])
302
-        del self.picloads[image_path]
303
-        if len(self.images)>30:
304
-            del self.images[self.images.keys()[0]]
305
-            # self.images.pop()
306
-            
307
-    #def FinishDecodeDef(self, image_path,picInfo = None):
308
-    #    self.defimage = self.defimage0.getData()
309
-    #    del self.defimage0
310
-    #    self["pic"].instance.setPixmap(self.defimage)
311
-        
312
-    def download_image(self,image_path,image_url):
313
-        print "Image download started",self.downloading,image_path,image_url
314
-        self.downloading += 1
315
-        self.images[image_url] = -1
316
-        downloadPage(image_url, image_path).addCallback(boundFunction(self.downloadFinished, image_path,image_url)).addErrback(boundFunction(self.downloadFailed, image_path,image_url))
317
-
318
-    def downloadFinished(self, image_path, image_url, result):
319
-        self.downloading -= 1
320
-        print "[TV Play] Image downloaded finished ",self.downloading,image_path, image_url,result
321
-        self.start_decode(image_path,image_url)       
322
-
323
-    def downloadFailed(self, image_path, image_url,result):
324
-        self.downloading -= 1
325
-        print "[TV Play] Image downloaded failed ",self.downloading,image_path, image_url,result
326
-        self.images[image_url] = -3
327
-
328
-
329
-    def Ok(self):
330
-        current = self["list"].getCurrent()
331
-        self.current = current
332
-        index = self["list"].getIndex()
333
-        self.index = index
334
-        print "[PlayStream] - menu selected ", current
335
-        #if len(current[1].split("::"))<2 or not current[1].split("::")[1]: #
336
-        #    return # TODO - kaut kā jēdzigak jāapstradā nederigs ieraksts (paziņojums?)
337
-        if self.sources.is_video(current[1]):
338
-            if self.sources.stream_type(current[1]):
339
-                stream = stream0
340
-                stream["url"] = cur2[1]
341
-                stream["name"] = cur2[0]
342
-                streams = [stream]
343
-            else:
344
-                try:
345
-                    streams = self.sources.get_streams(current[1])
346
-                except Exception,e:              
347
-                    self.msg("Error - %s"%str(e))
348
-                    return
349
-            
350
-            if streams:
351
-                print streams
352
-                self.session.open(PSPlayer, streams)
353
-            else:
354
-                self.msg("No stream found - %s"%(self.current[1]))
355
-                return
356
-            
357
-            #if not self.sources.stream_type(current[1]):
358
-                #current = self.sources.get_content(current[1])
359
-            #print "Item to play",current
360
-            #stream_type = self.sources.stream_type(current[1])
361
-            #url = current[1]
362
-            #title = current[0] 
363
-            #if not stream_type: # 
364
-                #print stream_type
365
-                #self.msg("No stream found - %s"%(self.current[1]))
366
-                #return
367
-            #self.playVideo(current)
368
-            
369
-        elif current[1] == "back":
370
-            cur_menu_old = self.cur_menu
371
-            self.cur_menu = self.history.pop()
372
-            new_content = self.sources.get_content(self.cur_menu[1])
373
-            try:
374
-                index = zip(*new_content)[1].index(cur_menu_old[1])
375
-            except:
376
-                index = 0
377
-            self.setTitle2(self.cur_menu[0])
378
-            self.show_content(new_content,index)
379
-            
380
-        else:
381
-            print "selected=",current
382
-            if "{0}" in current[1]:
383
-                self.session.openWithCallback(self.cb_input,VirtualKeyBoard, title="Enter value", text="")                 
384
-                #a = raw_input("Enter value:")
385
-                #a = "big bang"
386
-                #current = (current[0],current[1].format(a),current[2],current[3])
387
-                #self.get_content(current)
388
-            else:
389
-                self.get_content(current)
390
-                
391
-    def cb_input(self,value):
392
-        if not value:
393
-            return
394
-        current = self.current
395
-        current = (current[0],current[1].format(value),current[2],current[3])
396
-        self.get_content(current)
397
-    
398
-    def get_content(self,current):            
399
-            self.history.append(self.cur_menu)
400
-            self.cur_menu = current
401
-            try:
402
-                new_content = self.sources.get_content(self.cur_menu[1])
403
-            except Exception,e:
404
-                self.cur_menu = self.history.pop()                
405
-                self.session. open(MessageBox, "Error - %s"%str(e) , MessageBox.TYPE_INFO)
406
-                return
407
-            self.setTitle2(self.cur_menu[0])
408
-            self.show_content(new_content)
409
- 
410
-    def Back(self):
411
-        self["list"].setIndex(0)
412
-        self.Ok()
413
-
414
-    def show_content(self,content,index=0):
415
-        self["list"].setList(content)
416
-        self["list"].setIndex(index)
417
-        self.SelectionChanged()
418
-
419
-    def Cancel(self):
420
-        #if os.path.exists(TMPDIR):
421
-            #for name in os.listdir(TMPDIR):
422
-                #os.remove(os.path.join(TMPDIR, name))
423
-            #os.rmdir(TMPDIR)
424
-        self.close()
425
-            
426
-    def playVideo(self, current):
427
-        hlspath = current[1]
428
-        print "[TV Play] Play:", current
429
-        ##SERVICE 4097:0:0:0:0:0:0:0:0:0:http%3a//127.0.0.1%3a7777#Cookie1=test3&User-Agent=CustomUserAgent&Cookie=test4:test_headers
430
-        ref = eServiceReference(4097, 0, hlspath)
431
-        ref.setName(current[0])
432
-        self.session.open(TVPlayer, ref)
433
-    
434
-    def item_menu(self):
435
-        print "\n[PlayStream] options\n"
436
-        self.current = self["list"].getCurrent()
437
-        self.index = self["list"].getIndex()        
438
-        #self.session. open(MessageBox, "Item options - %s"%current[0] , MessageBox.TYPE_INFO)
439
-        #args=[current,self.cur_menu]
440
-        #self.session.open(ItemMenuScreen,current,index,self)
441
-        lst = [
442
-            ("Aditional information","info","Display additional information about item"),
443
-            ("Add to bouquet","bouquet","Add current item to Enigma2 bouquet"),
444
-            ("Add to favorites","favorites","Add current item to PlayStrem favorites"),
445
-            ("Download list","download_list","Show download list")
446
-        ]
447
-        if self.sources.is_video(self.current[1]):
448
-            lst.extend([
449
-            ("Download video","download","Download video in background"),
450
-            ])
451
-        if "config::" in self.cur_menu[1]:
452
-            lst.extend([
453
-            ("Rename item","rename","Rename list item"),
454
-            ("Move item","move","Move list item"),
455
-            ("Delete item","delete","Delete list item"),
456
-            ("Add submenu","add_list","Add submenu before selected item"), 
457
-            ])
458
-        title = self.current[0]
459
-        self.session.openWithCallback(self.cb_item_menu, ChoiceBox, text = title, list = lst) #TODO
460
-
461
-    def cb_item_menu(self,answer):
462
-        #print "item_menu_selected",answer
463
-        if not answer:
464
-            return
465
-
466
-        if answer[1] == "info":
467
-            self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)
468
-            pass # TODO parada papildus info
469
-        
470
-        elif answer[1] == "bouquet":
471
-            #if not e2:
472
-                #e2 = enigma2_api.DBServices()
473
-            #print "load_buuquets - ",e2._load_bouquets()
474
-            self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO)            
475
-            
476
-        elif answer[1] == "favorites":
477
-            lists = self.config.get_lists()
478
-            lists2 = [(l,l) for l in lists]            
479
-            self.session.openWithCallback(self.cb_favorites, ChoiceBox, text="Select menu item will be added",list = lists2) 
480
-                        
481
-        elif answer[1] == 'download':
482
-            current = self.current
483
-            if not self.sources.is_video(current[1]):
484
-                self.msg("Can not download listst (yet) - %s"%(current[1]))
485
-                return
486
-            #if not self.sources.stream_type(current[1]):
487
-                #current = self.sources.get_content(current[1])
488
-            try:
489
-                streams = self.sources.get_streams(current[1])
490
-            except Exception,e:              
491
-                self.msg("Error - %s"%str(e))
492
-                return
493
-            if not streams:
494
-                self.msg("No stream found to download - %s"%(self.current[1]))
495
-                return
496
-            if len(streams)>1:
497
-                stream = streams[0] # TODO iespeja izvelēties strīmu, ja to ir vairāki
498
-            else:
499
-                stream = streams[0]
500
-            stream_type = stream["type"] #self.sources.stream_type(stream["url"])
501
-            if not stream_type: # 
502
-                self.msg("Not supported stream type found to download - %s"%(self.current[1]))
503
-                return            
504
-            title = streams[0]["name"]
505
-            url = streams[0]["url"]
506
-            downloadDir = "/media/hdd/movie" #config.plugins.playstream.downloadDir.value TODO
507
-            if not os.path.exists(downloadDir):
508
-                self.msg(_('Sorry, download directory "%s" not exist!\nPlease specify in the settings existing directory'%downloadDir))
509
-                return
510
-            fname = re.sub("[/\n\r\t,]","_",title)+".mp4"
511
-            outputfile = os.path.join(downloadDir, fname)
512
-            if os.path.exists(outputfile):
513
-                self.msg( _('Sorry, this file already exists:\n%s') % outputfile)
514
-                return
515
-            print "Trying to download - ", current   
516
-            if stream_type in ("http","https"):  
517
-                print "\n**Download %s - %s"%(title,url)                
518
-                #reload(downloadJob)
519
-                job_manager.AddJob(downloadJob(url, outputfile, title[:20], self.video_download_stop))
520
-                self.activeDownloads += 1
521
-                self.msg(_('Video download started!'))
522
-            elif stream_type == "hls":
523
-                #self.msg("HLS stream download not yet implemented!")
524
-                print "\n**Download %s - %s"%(title,url)                
525
-                #reload(HLSDownloadJob)
526
-                print "HLSDownload", url,outputfile
527
-                job_manager.AddJob(HLSDownloadJob(url, outputfile, title[:20], self.video_download_stop))
528
-                self.activeDownloads += 1
529
-                self.msg(_('Video download started!'))
530
-                
531
-            elif stream_type == "rstp":
532
-                self.msg("RSTP stream download not yet implemented!")
533
-            else:
534
-                self.msg("Unkown stream type!")            
535
-            
536
-        elif answer[1] == 'download_list':
537
-            self.download_list()
538
-
539
-        elif answer[1] == "delete":
540
-            lst = self.cur_menu[1].replace("config::","")
541
-            #print lst
542
-            self.config.del_item(lst,self.index)
543
-            self.config.write_streams()
544
-            txt = "'%s' deleted from favourite stream list '%s'"%(self.current[0],lst)
545
-            self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=5)  
546
-            
547
-        elif answer[1] == "rename":
548
-            #name2 = "Renamed"
549
-            self.session.openWithCallback(self.cb_rename,VirtualKeyBoard, title="Enter new item name", text=self.current[0]) 
550
-            
551
-        elif answer[1] == "add_list":
552
-            self.session.open(MessageBox, "Not yet implemented!", MessageBox.TYPE_INFO,timeout=5)            
553
-            pass #TODO    
554
-        return
555
-    
556
-    def download_list(self):
557
-        self.session.open(VideoDownloadList)
558
-        
559
-    def cb_rename(self,value):
560
-        if not value:
561
-            return
562
-        lst = self.cur_menu[1].replace("config::","")
563
-        pos = self.index        
564
-        print value
565
-        item2 = list(self.current)
566
-        item2[0]=value
567
-        item2 = tuple(item2)
568
-        self.config.replace_item(lst,item2,pos)
569
-        self.config.write_streams()
570
-        txt = "'%s' renamed to '%s'"%(self.current[0],value)
571
-        self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=5)     
572
-        
573
-    def cb_favorites(self,answer):
574
-        print "cb_favorites",answer
575
-        if not answer:
576
-            return 
577
-        value = answer[1]
578
-        self.config.add_item(value,self.current)
579
-        self.config.write_streams()
580
-        txt = "'%s' added to favourite stream list '%s'"%(self.current[0],value)
581
-        self.session.open(MessageBox, txt, MessageBox.TYPE_INFO,timeout=3)
582
-        #self.session.openWithCallback(self.callMyMsg, MessageBox, _("Do you want to exit the plugin?"), MessageBox.TYPE_INFO)
583
-        
584
-    def options_screen(self):
585
-        source = self.cur_menu[1].split("::")[0]
586
-        options = self.sources.options_read(source)
587
-        print source
588
-        if not options:
589
-            self.session. open(MessageBox, "No options available for source %s (%s)"%(self.cur_menu[0],source) , MessageBox.TYPE_INFO)
590
-        else:
591
-            self.session.open(OptionsScreen,self)        
592
-        
593
-    def video_download_stop(self,title):
594
-        #self.activeDownloads -= 1
595
-        #self.msg("Download '%s'finished!"%title)
596
-        print "video_download_stop ", title
597
-        
598
-    def msg(self,msg,timeout=10):
599
-        self.session.open(MessageBox, msg, MessageBox.TYPE_INFO, timeout)
600
-##########################################################################
601
-from Components.config import config, ConfigSubsection, ConfigYesNo,\
602
-     getConfigListEntry, ConfigSelection, ConfigNumber, ConfigDirectory,ConfigText, ConfigSubDict
603
-from Components.ConfigList import ConfigListScreen
604
-#from Screens.LocationBox import LocationBox
605
-
606
-config.plugins.playstream = ConfigSubDict()
607
-
608
-class OptionsScreen(ConfigListScreen,Screen):
609
-    skin = """
610
-<screen position="center,center" size="560,400"  >
611
-	<ePixmap name="red"    position="0,0"   zPosition="2" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
612
-	<widget name="key_red" position="0,0" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
613
-	<ePixmap name="green"  position="140,0" zPosition="2" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
614
-	<widget name="key_green" position="140,0" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
615
-	<ePixmap name="yellow" position="280,0" zPosition="2" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
616
-	<widget name="key_yellow" position="280,0" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
617
-	<ePixmap name="blue"   position="420,0" zPosition="2" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
618
-	<widget name="key_blue" position="420,0" size="140,40" valign="center" halign="center" zPosition="4"  foregroundColor="white" font="Regular;20" transparent="1" shadowColor="background" shadowOffset="-2,-2" />
619
-
620
-	<widget name="config" position="10,40" size="540,340" scrollbarMode="showOnDemand" />
621
-</screen>"""
622
-
623
-    def __init__(self, session,*args):
624
-        self.session = session
625
-        Screen.__init__(self, session)
626
-        self.main = args[0]
627
-        self.setTitle(self.main.cur_menu[0]+" Options")
628
-        self.source = self.main.cur_menu[1].split("::")[0]
629
-        self.cfg = config.plugins.playstream
630
-        self.list = []       
631
-        self.options = self.main.sources.options_read(self.source)
632
-        if not self.options:
633
-            #self.session. open(MessageBox, "No options available for source %s (%s)"%(self.main.cur_menu[0],self.source) , MessageBox.TYPE_INFO)
634
-            self.close(False,self.session)
635
-        for k in self.options:
636
-            self.cfg[k]=ConfigText(default=self.options[k],fixed_size=False)
637
-            self.list.append(getConfigListEntry(k, self.cfg[k]))
638
-        ConfigListScreen.__init__(self, self.list, session = self.session)
639
-        
640
-        self["key_red"] = Button(_("Cancel"))
641
-        self["key_green"] = Button("Save")
642
-        self["key_yellow"] = Button("")
643
-        self["key_blue"] = Button("")
644
-        self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
645
-                                         {
646
-                                             "red": self.cancel,
647
-                                             "green": self.save,
648
-                                             "save": self.save,
649
-                                             "cancel": self.cancel,
650
-                                             "ok": self.ok,
651
-                                             }, -2)
652
-
653
-    def getCurrentEntry(self):
654
-        return self["config"].getCurrent()[0]
655
-
656
-    def getCurrentValue(self):
657
-        return str(self["config"].getCurrent()[1].getText())
658
-
659
-    def ok(self):
660
-        self.save()
661
-        #if self["config"].getCurrent()[1] == config.plugins.getpicons.folder:
662
-            #folder  = config.plugins.getpicons.folder.value
663
-            #self.session.openWithCallback(self.change_dir, LocationBox,"Select Folder")
664
-        #else:
665
-            
666
-
667
-    #def change_dir(self, folder, select=None):
668
-        #if folder:
669
-            ##print "change_dir to %s"%folder
670
-            #config.plugins.getpicons.folder.value = folder
671
-
672
-    def save(self):
673
-        print "saving"
674
-        #self.saveAll()
675
-        for k in self.options.keys():
676
-            self.options[k]=self.cfg[k].value
677
-            print "%s=%s"%(k,self.cfg[k].value)
678
-        self.main.sources.options_write(self.source,self.options)
679
-        self.close(True,self.session)
680
-
681
-    def cancel(self):
682
-        print "cancel"
683
-        self.close(False,self.session)
684
-

+ 16
- 13
changelog.md ファイルの表示

@@ -4,6 +4,9 @@
4 4
 - kodik, kapnob resolveri priekš movieplace.lv
5 5
 - u.c. labojumi
6 6
 
7
+**0.5s** (17.01.2016):
8
+- koda refaktorings/houskeepings
9
+
7 10
 **0.5n** (15.01.2016):
8 11
 - salabots filmix (tagad filmix.me)
9 12
 - .ts strīmus spēlē ar service_type = 1 (nevis 4097)
@@ -27,61 +30,61 @@
27 30
 **0.4d** (03.08.2016):
28 31
 - Euronews live un arhīvs
29 32
 .
30
-**0.4c** (26.07.2016):  
33
+**0.4c** (26.07.2016):
31 34
 - BBC iPlayer saturs (strādā tikai UK vai ar VPN/smartDNS)
32 35
 - lejupielādes foldera uzdošana
33 36
 - video saraksta lejupielāde (1 limenis zem menu)
34 37
 - subtitle lejupielāde (BBC)
35 38
 
36
-**0.4a** (12.07.2016):  
39
+**0.4a** (12.07.2016):
37 40
 - salabots/pārtaisīts lattelecom.tv atbilstoši jaunajam "produktam" (shortut) un API (1.4)
38 41
 - pārtaisīts iekšējais source pluginu API (var no sources dabūt vairākus strīmus)
39 42
 - iekš UI iespēja playerī imanīt strīmus (audio poga), paskatīties tekošā strīma info (Info poga)
40 43
 - citi nebūtiski labojumi
41 44
 
42
-**0.3e** (30.06.2016):  
45
+**0.3e** (30.06.2016):
43 46
 - izlabota kļūda saistībā ar nestrādāšanu ne openPLI imidžos
44 47
 
45
-**0.3c** (14.06.2016):  
48
+**0.3c** (14.06.2016):
46 49
 - izlabotas kļūdas saistība ar nesaderību ar dažādiem skiniem
47 50
 - iespēja saglabāt HLS strīmus un video failus (testa variants, var būt problēmas)
48 51
 
49
-**0.3b** (12.06.2016):  
52
+**0.3b** (12.06.2016):
50 53
 - Filmix.net saturs
51 54
 - Meklēšana replay, ltc,serialguru, tvdom, filmix.net portālos
52 55
 - Tekošā programma ltc TV strīmos
53 56
 - Dažādu kļūdu labojumi
54 57
 
55
-**0.3a** (09.06.2016):  
58
+**0.3a** (09.06.2016):
56 59
 - SerialGURU.ru saturs
57 60
 - Avotiem ar parolēm (ltc, ustvnow) Options logs paroļu ievadei
58 61
 - iespēja pievienot favorītu sarakstiem, sarakstu labošana (pagaidām ierobēžota)
59 62
 
60
-**0.2h**:  
63
+**0.2h**:
61 64
 - pievienots USTVNow live TV
62 65
 - izlabotas dažas kļūdas (idoja ārā uz skiniem, kuros nebija skinned loga veida)
63 66
 
64
-**0.2f**:  
67
+**0.2f**:
65 68
 - pievienots TVDom.tv
66 69
 - izlabotas dažas kļūdas LTC
67 70
 
68
-**0.2e** (22.05.2016):  
71
+**0.2e** (22.05.2016):
69 72
 - daļēji salabots lattelecom.tv
70 73
 - pievienots play24.tv (Riga24V) portāla saturs
71 74
 - pievienots FilmON live TV un video on demand saturs (pagaidām tikai bezmaksas saturs)
72 75
 
73
-**0.2b**04.05.2016):  
76
+**0.2b**04.05.2016):
74 77
 - strādā lattelecom.tv 360tv raidījumu videonoma
75 78
 
76
-**0.2a** (03.05.2016):  
79
+**0.2a** (03.05.2016):
77 80
 - pievienots lattelecom.tv saturs
78 81
 - novērstas vairākas kļūdas
79 82
 
80
-**0.1d** (26.04.2016):  
83
+**0.1d** (26.04.2016):
81 84
 - novērsta klūda replay.lv skatot YouTube kontentu (ziņu fragmenti), lidoja ārā
82 85
 - salabotas atkarības, lai ar roku nav jāinstalē vajadzīgās bibliotēkas
83 86
 - pievienota licences informācija un kredīti
84 87
 
85
-**0.1c** (26.04.2016):  
88
+**0.1c** (26.04.2016):
86 89
 - strādā  replay.lv YouTube saturs (pamatā sižeti no ziņu raidījumiem)
87 90
 - papildus python moduļi ipk (katram gadījumam, ja tie nav iekļauti defaultā)

+ 9
- 1
imake.bat ファイルの表示

@@ -2,7 +2,7 @@
2 2
 :=== Parameters ===
3 3
 
4 4
 if ()==(%1%) (
5
-    set ver=0.5p
5
+    set ver=0.5s
6 6
 	rem echo Please provide version
7 7
 	rem pause
8 8
 	rem GOTO:EOF
@@ -19,6 +19,7 @@ set ext_dir2=/usr/lib/enigma2/python/Plugins/Extensions/
19 19
 set script_dir=usr\script\
20 20
 set ipk_dir=ipkg\
21 21
 set release_dir=release\
22
+set feed_dir=w:\feed\
22 23
 
23 24
 set AR=\MinGW\bin\ar.exe
24 25
 set TAR=\MinGW\msys\1.0\bin\tar.exe
@@ -158,3 +159,10 @@ if exist %release_dir%%pack_name%_%ver%.ipk del %release_dir%%pack_name%_%ver%.i
158 159
 mv %release_dir%%pack_name%_%ver% %release_dir%%pack_name%_%ver%.ipk
159 160
 git add %release_dir%%pack_name%_%ver%.ipk
160 161
 
162
+copy %release_dir%%pack_name%_%ver%.ipk %feed_dir%%pack_name%_%ver%.ipk
163
+pushd  %feed_dir%
164
+python c:\Python27\Scripts\opkg-make-index . >Packages
165
+dos2unix Packages
166
+gzip Packages
167
+popd
168
+

+ 1
- 1
ipkg/CONTROL/control ファイルの表示

@@ -1,4 +1,4 @@
1
-Version: 0.5p
1
+Version: 0.5s
2 2
 Package: enigma2-plugin-extensions-playstream
3 3
 Description: Play online streams from various sources, mostly Latvian
4 4
 Architecture: all

バイナリ
ipkg/control.tar.gz ファイルの表示


バイナリ
ipkg/data.tar.gz ファイルの表示


+ 18
- 11
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/ContentSources.py ファイルの表示

@@ -7,25 +7,22 @@
7 7
 #
8 8
 
9 9
 import sys,os,re
10
-import urllib2
11 10
 sys.path.insert(0,os.path.dirname(os.path.abspath(__file__)))
12 11
 from  sources.SourceBase import stream_type
13 12
 import util
14 13
 
15 14
 
16
-stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":""}
17
-
18 15
 class ContentSources(object):
19 16
     """Wrapper for content sources plugin"""
20 17
 
21 18
     #----------------------------------------------------------------------
22
-    def __init__(self,plugin_path):
19
+    def __init__(self, plugin_path):
23 20
         self.plugins = {}
24
-        self.error_content = [("..atpakaļ","back",None,"Kļūda, atgriezties atpakaļ")]
21
+        self.error_content = [("..atpakaļ", "back", None, "Kļūda, atgriezties atpakaļ")]
25 22
         sys.path.insert(0, plugin_path)
26 23
         for f in os.listdir(plugin_path):
27 24
             fname, ext = os.path.splitext(f)
28
-            if fname == "__init__":continue
25
+            if fname == "__init__": continue
29 26
             if ext == '.py':
30 27
                 mod = __import__(fname)
31 28
                 reload(mod)
@@ -79,7 +76,7 @@ class ContentSources(object):
79 76
             if "::" in data:
80 77
                 data = data.split("::")[1]
81 78
             content = self.get_content(data)
82
-            stream = stream0.copy()
79
+            stream = util.item()
83 80
             stream["name"] = data
84 81
             stream["url"] = data
85 82
             stream["type"] = stream_type(data)
@@ -164,19 +161,23 @@ if __name__ == "__main__":
164 161
         cur2 = content[n-1]
165 162
 
166 163
         data0 = cur2[1].split("::")[1] if "::" in cur2[1] else cur2[1]
167
-        if (not data0):
164
+        if not data0:
168 165
             pass
169 166
 
170 167
         elif cur2[1] == "back":
171 168
             cur = history.pop()
172 169
         elif sources.is_video(cur2[1]):
173 170
             if sources.stream_type(cur2[1]):
174
-                stream = stream0.copy()
171
+                stream = util.item()
175 172
                 stream["url"] = cur2[1]
176 173
                 stream["name"] = cur2[0]
177 174
                 streams = [stream]
178 175
             else:
179
-                streams = sources.get_streams(cur2[1])
176
+                try:
177
+                    streams = sources.get_streams(cur2[1])
178
+                except Exception as e:
179
+                    print str(e)
180
+                    streams = []
180 181
             if streams:
181 182
                 util.play_video(streams)
182 183
             else:
@@ -191,4 +192,10 @@ if __name__ == "__main__":
191 192
                 cur2 = (cur2[0],cur2[1].format(a),cur2[2],cur2[3])
192 193
             history.append(cur)
193 194
             cur = cur2
194
-        content = sources.get_content(cur[1])
195
+        try:
196
+            content = sources.get_content(cur[1])
197
+        except Exception as e:
198
+            print str(e)
199
+            raw_input("Continue?")
200
+
201
+

+ 2
- 2
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/PlayStream.py ファイルの表示

@@ -518,7 +518,7 @@ class MainScreen(Screen):
518 518
 
519 519
         elif self.sources.is_video(current[1]):
520 520
             if self.sources.stream_type(current[1]):
521
-                stream = stream0.copy()
521
+                stream = util.item()
522 522
                 stream["url"] = current[1]
523 523
                 stream["name"] = current[0]
524 524
                 streams = [stream]
@@ -711,7 +711,7 @@ class MainScreen(Screen):
711 711
 
712 712
     def download_video(self,current):
713 713
         if self.sources.stream_type(current[1]):
714
-            stream = stream0.copy()
714
+            stream = util.item()
715 715
             stream["url"] = current[1]
716 716
             stream["name"] = current[0]
717 717
             streams = [stream]

+ 1
- 1
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/resolvers/hqqresolver.py ファイルの表示

@@ -21,7 +21,7 @@ try:
21 21
     import util
22 22
 except:
23 23
     pp = os.path.dirname(os.path.abspath(__file__))
24
-    sys.path.insert(0,os.sep.join(pp.split(os.sep)[:-1]))
24
+    sys.path.insert(0, os.sep.join(pp.split(os.sep)[:-1]))
25 25
     import util
26 26
 import requests
27 27
 

+ 9
- 13
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/SourceBase.py ファイルの表示

@@ -13,7 +13,7 @@ from collections import OrderedDict
13 13
 import ConfigParser
14 14
 
15 15
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
16
-stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":"","order":0}        
16
+stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":"","order":0}
17 17
 
18 18
 
19 19
 class SourceBase(object):
@@ -56,28 +56,28 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
56 56
         stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
57 57
         stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
58 58
         stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
59
-        stream["type"] = stream_type(content[1]).encode("utf8") 
59
+        stream["type"] = stream_type(content[1]).encode("utf8")
60 60
         return[stream]
61 61
 
62 62
     def options_read(self):
63 63
         if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
64 64
             return None
65
-        config = ConfigParser.ConfigParser()        
65
+        config = ConfigParser.ConfigParser()
66 66
         if os.path.exists(self.config_file):
67 67
             config.read(self.config_file)
68
-            self.options = OrderedDict(config.items(self.name))             
68
+            self.options = OrderedDict(config.items(self.name))
69 69
         else:
70 70
             self.options_write(self.options)
71 71
         return self.options
72 72
 
73
-    def options_write(self,options):        
74
-        config = ConfigParser.ConfigParser() 
73
+    def options_write(self,options):
74
+        config = ConfigParser.ConfigParser()
75 75
         config.add_section(self.name)
76 76
         for k in options.keys():
77 77
             config.set(self.name, k,options[k])
78 78
         with open(self.config_file,"w") as f:
79 79
             config.write(f)
80
-        self.options = OrderedDict(config.items(self.name))        
80
+        self.options = OrderedDict(config.items(self.name))
81 81
 
82 82
     def call(self, data,params=None,headers=None,lang=""):
83 83
         if not headers: headers = self.headers
@@ -94,14 +94,14 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
94 94
             raise "No data returned"
95 95
 
96 96
     def _http_request(self, url,params = None, headers=None):
97
-        if not headers: 
97
+        if not headers:
98 98
             headers = self.headers if "headers" in dir(self) else headers2dict("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")
99 99
         try:
100 100
             if params:
101 101
                 r = requests.post(url, data=params, headers=headers)
102 102
             else:
103 103
                 r = requests.get(url, headers=headers)
104
-            return r.content 
104
+            return r.content
105 105
         except Exception as ex:
106 106
             if "read" in ex:
107 107
                 content = ex.read()
@@ -113,10 +113,6 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
113 113
     def stream_type(data):
114 114
         return stream_type(data)
115 115
 
116
-    @staticmethod
117
-    def get_stream0():
118
-        return stream0.copy()
119
-
120 116
     @staticmethod
121 117
     def parse_data(data):
122 118
         if "::" in data:

+ 36
- 35
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/euronews.py ファイルの表示

@@ -14,13 +14,14 @@ import urllib2, urllib
14 14
 import datetime, time,re, sys,os
15 15
 from collections import OrderedDict
16 16
 from SourceBase import SourceBase
17
+import util
17 18
 
18 19
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19 20
 import HTMLParser
20 21
 h = HTMLParser.HTMLParser()
21
-    
22
+
22 23
 class Source(SourceBase):
23
-    
24
+
24 25
     def __init__(self,language="en"):
25 26
         self.name = "euronews"
26 27
         self.title = "Euronews"
@@ -42,10 +43,10 @@ Connection: keep-alive
42 43
             self.get_languages()
43 44
         except:
44 45
             pass
45
-        
46
+
46 47
     def login(self,user="",password=""):
47 48
         return True
48
-            
49
+
49 50
     def get_content(self, data):
50 51
         print "[%s] get_content:"%self.name, data
51 52
         source,data,path,plist,clist,params,qs = self.parse_data(data)
@@ -53,13 +54,13 @@ Connection: keep-alive
53 54
         lang = self.options["language"]
54 55
         if not lang in self.get_languages():
55 56
             raise Exception("Not valid default language - '%s'"%lang)
56
-    
57
+
57 58
         content=[]
58 59
         content.append(("..return", "back","","Return back"))
59
-        
60
+
60 61
         if clist=="home":
61 62
             content.extend([
62
-                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),                
63
+                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),
63 64
                 ("Live stream", "euronews::live?lang=%s"%lang,self.img,"Euronews live stream"),
64 65
                 ("Just in", "euronews::content/getTimeline?lang=%s&byPage=40&page=1"%lang,self.img,"News timeline"),
65 66
                 ("Top stories", "euronews::content/getTopStories?lang=%s"%lang,self.img,"Top stories timeline"),
@@ -71,16 +72,16 @@ Connection: keep-alive
71 72
                 ("Programs list", "euronews::content/getPrograms?lang=%s"%lang,self.img,"Programs list"),
72 73
              ])
73 74
             return content
74
-        
75 75
 
76
-        ### Video arhīvs ###  
76
+
77
+        ### Video arhīvs ###
77 78
         elif clist=="content":
78 79
             if "lang" in qs:
79 80
                 del qs["lang"]
80 81
             params = json.dumps(qs)
81
-            
82
+
82 83
             req = '{"methodName":"content.%s","apiKey":"androidPhoneEuronews-1.0","params":%s,"language":"%s"}'%(plist[1],params,lang)
83
-            r = self.call(req)    
84
+            r = self.call(req)
84 85
             if not r:
85 86
                 return content
86 87
             lst = r["timeline"] if "timeline" in r else\
@@ -93,7 +94,7 @@ Connection: keep-alive
93 94
                 []
94 95
             if not lst:
95 96
                 return content
96
-            
97
+
97 98
             for item in lst:
98 99
                 if plist[1] in ("getTimeline"):
99 100
                     article = item["article"]
@@ -104,7 +105,7 @@ Connection: keep-alive
104 105
                     article = item
105 106
                     atype = "article"
106 107
                 if plist[1]=="getPrograms":
107
-                    title = article["title"] 
108
+                    title = article["title"]
108 109
                     id = article["pId"]
109 110
                     desc = title
110 111
                     img = "http://static.euronews.com/articles/programs/533x360_%s"%article["img"]
@@ -115,7 +116,7 @@ Connection: keep-alive
115 116
                     if atype <> "article":
116 117
                         title = "[%s] %s"%(atype,title)
117 118
                     atime = datetime.datetime.fromtimestamp(int(article["uts"]))
118
-                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone) 
119
+                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone)
119 120
                     atime = atime.strftime("%Y-%m-%d %H:%M")
120 121
                     vert = self.vid[article["vId"]] if "vId" in article else ""
121 122
                     ptitle = article["pTitle"] if "pTitle" in article else ""
@@ -129,19 +130,19 @@ Connection: keep-alive
129 130
                     content.append((title,self.name+"::"+data2,img,desc))
130 131
             if "page=" in data:
131 132
                 data2 = re.sub("page=\d+","page=%s"%(int(qs["page"])+1),data)
132
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page")) 
133
-            return content            
133
+                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
134
+            return content
135
+
134 136
 
135
-    
136 137
     def is_video(self,data):
137
-        source,data,path,plist,clist,params,qs = self.parse_data(data)        
138
+        source,data,path,plist,clist,params,qs = self.parse_data(data)
138 139
         if path == "live":
139 140
             return True
140 141
         elif clist=="content" and plist[1]=="getArticle":
141 142
             return True
142 143
         else:
143 144
             return False
144
-        
145
+
145 146
     def get_streams(self, data):
146 147
         print "[euronews] get_streams:", data
147 148
         if not self.is_video(data):
@@ -150,10 +151,10 @@ Connection: keep-alive
150 151
         #lang = qs["lang"] if "lang" in qs else self.language
151 152
         lang = self.options["language"]
152 153
         if not lang in self.get_languages():
153
-            raise Exception("Not valid default language - '%s'"%lang)        
154
-        
154
+            raise Exception("Not valid default language - '%s'"%lang)
155
+
155 156
         streams = []
156
-        
157
+
157 158
         if path == "live":
158 159
             url = "http://www.euronews.com/api/watchlive.json"
159 160
             r = self._http_request(url)
@@ -169,11 +170,11 @@ Connection: keep-alive
169 170
                     raise Exception("No live stream found")
170 171
             except:
171 172
                 raise Exception("No live stream found")
172
-            
173
+
173 174
             slist = js["primary"]
174
-            
175
+
175 176
             for l in slist:
176
-                stream = self.get_stream0()
177
+                stream = util.item()
177 178
                 stream["url"]=slist[l]["hls"]
178 179
                 stream["lang"]=l
179 180
                 stream["quality"]="variant"
@@ -181,7 +182,7 @@ Connection: keep-alive
181 182
                 stream["desc"]=stream["name"]
182 183
                 stream["type"]="hls" #stream_type(url)
183 184
                 streams.append(stream)
184
-                
185
+
185 186
         elif clist=="content" and plist[1] == "getArticle":
186 187
             if "lang" in qs:
187 188
                 del qs["lang"]
@@ -189,14 +190,14 @@ Connection: keep-alive
189 190
             for lang in languages:
190 191
                 id = qs["id"]
191 192
                 req = '{"methodName":"content.getArticle","apiKey":"androidPhoneEuronews-1.0","params":{"id":"%s"},"language":"%s"}'%(id,lang)
192
-                r = self.call(req)    
193
+                r = self.call(req)
193 194
                 if not r:
194
-                    raise Exception("No live stream found") 
195
+                    raise Exception("No live stream found")
195 196
                 if not "articlelist" in r:
196 197
                     msg = r["label"] if "label" in r else "No article finde"
197 198
                     raise Exception(msg)
198 199
                 article = r["articlelist"]
199
-                stream = self.get_stream0()
200
+                stream = util.item()
200 201
                 stream["url"]=article["videoUri"] if "videoUri" in article else ""
201 202
                 if not stream["url"]:
202 203
                     return []
@@ -206,13 +207,13 @@ Connection: keep-alive
206 207
                 stream["desc"]=article["text"] if "text" in article else article["title"]
207 208
                 stream["type"]="http" #stream_type(url)
208 209
                 streams.append(stream)
209
-            
210
+
210 211
         else:
211 212
             raise Exception("No live stream found")
212
-           
213
+
213 214
         ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
214 215
         qlist = ["???","lq","mq","hq","hd","variant"]
215
-        llist = ["fr","en","ru","lv"]        
216
+        llist = ["fr","en","ru","lv"]
216 217
         for s in streams:
217 218
             if s["lang"]==self.options["language"]:
218 219
                 s["order"] = 10000
@@ -238,11 +239,11 @@ Connection: keep-alive
238 239
                 raise Exception("Can not get languages list")
239 240
         except:
240 241
             raise Exception("Can not get languages list")
241
-        
242
+
242 243
         slist = js["primary"]
243 244
         self.languages=slist.keys()
244 245
         return self.languages
245
-        
246
+
246 247
     def call(self, data,params = None, headers=None):
247 248
         if not headers: headers = self.headers
248 249
         #if not lang: lang = self.country
@@ -269,7 +270,7 @@ content-disposition: form-data; name=request
269 270
                 return None
270 271
         else:
271 272
             return None
272
-        
273
+
273 274
 
274 275
 if __name__ == "__main__":
275 276
     language= "en"

+ 56
- 55
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/iplayer.py ファイルの表示

@@ -13,22 +13,23 @@ import datetime
13 13
 import HTMLParser
14 14
 import json
15 15
 import datetime,time
16
-from SourceBase import SourceBase, stream_type, stream0
16
+from SourceBase import SourceBase, stream_type
17
+import util
17 18
 from collections import OrderedDict
18 19
 
19 20
 API_URL = 'https://m.lattelecom.tv/'
20 21
 user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
21 22
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
22 23
 h = HTMLParser.HTMLParser()
23
-    
24
+
24 25
 class Source(SourceBase):
25
-    
26
+
26 27
     def __init__(self):
27 28
         self.name = "iplayer"
28 29
         self.title = "BBC iPlayer"
29 30
         self.img = "http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png"
30 31
         self.desc = "BBC iPlayer portal content"
31
-        
32
+
32 33
         self.api_url = "http://ibl.api.bbci.co.uk/ibl/v1/"
33 34
         self.headers = headers2dict("""
34 35
 User-Agent: BBCiPlayer/4.19.0.3021 (SM-G900FD; Android 4.4.2)
@@ -38,7 +39,7 @@ Connection: Keep-Alive
38 39
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
39 40
 Connection: Keep-Alive
40 41
         """)
41
-        
42
+
42 43
         self.ch = []
43 44
         self.ch_id={}
44 45
         self.ch_id2={}
@@ -54,26 +55,26 @@ Connection: Keep-Alive
54 55
             "bbc_news24":"http://www.lyngsat-logo.com/hires/bb/bbc_news.png",
55 56
             "bbc_parliament":"http://www.lyngsat-logo.com/hires/bb/bbc_parliament.png",
56 57
             "bbc_alba":"http://www.lyngsat-logo.com/hires/bb/bbc_alba.png",
57
-            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"          
58
+            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"
58 59
         }
59 60
         cur_directory = os.path.dirname(os.path.abspath(__file__))
60 61
         self.config_file = os.path.join(cur_directory,self.name+".cfg")
61 62
         self.options = OrderedDict([("user","lietotajs"),("password","parole")])
62 63
         self.options_read()
63
-                     
64
+
64 65
     def get_content(self, data):
65 66
         print "[iplayer] get_content:", data
66 67
         if "::" in data:
67
-            data = data.split("::")[1] 
68
+            data = data.split("::")[1]
68 69
         path = data.split("?")[0]
69 70
         clist = path.split("/")[0]
70 71
         params = data[data.find("?"):] if "?" in data else ""
71 72
         qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
72 73
         #lang = qs["lang"] if "lang" in qs else self.country
73
-    
74
+
74 75
         content=[]
75 76
         content.append(("..return", "back","","Return back"))
76
-        
77
+
77 78
         ### Home ###
78 79
         if data=="home":
79 80
             content.extend([
@@ -82,11 +83,11 @@ Connection: Keep-Alive
82 83
                 ("Channels", "iplayer::channels","","Programmes by channel/date"),
83 84
                 ("Categories", "iplayer::categories","","Programmes by categories"),
84 85
                 ("A-Z", "iplayer::a-z","","All programmes by name"),
85
-                ("Highlights", "iplayer::home/highlights","","Current highlights"),             
86
-                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")            
86
+                ("Highlights", "iplayer::home/highlights","","Current highlights"),
87
+                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")
87 88
             ])
88 89
             return content
89
-        
90
+
90 91
         ### Search ###
91 92
         elif clist=="search":
92 93
             data_ = "search-suggest/?q=%s&rights=mobile&initial_child_count=1"%data.split("/")[1]
@@ -95,8 +96,8 @@ Connection: Keep-Alive
95 96
                 title,data2,img,desc = self.get_data_element(item)
96 97
                 content.append((title,self.name+"::"+data2,img,desc))
97 98
             return content
98
-                        
99
-        
99
+
100
+
100 101
         ### Live main ###
101 102
         elif data=="live":
102 103
             for ch in self.get_channels():
@@ -108,7 +109,7 @@ Connection: Keep-Alive
108 109
                 desc = ee[2]
109 110
                 content.append((title,self.name+"::"+data2,img,desc))
110 111
             return content
111
-        
112
+
112 113
         ### Categories ###
113 114
         elif data == "categories":
114 115
             r = self.call(data)
@@ -121,7 +122,7 @@ Connection: Keep-Alive
121 122
                 img = self.img
122 123
                 content.append((title,self.name+"::"+data2,img,desc))
123 124
             return content
124
-        
125
+
125 126
         ### Catetory root ###
126 127
         elif clist == "categories" and len(data.split("/"))==2:
127 128
             r = self.call(data)
@@ -132,7 +133,7 @@ Connection: Keep-Alive
132 133
             title = "%s - a-z (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
133 134
             content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=title&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
134 135
             return content
135
-        
136
+
136 137
         ### Program/episodes list ###
137 138
         elif   re.search("categories/([\w\-]+)/(highlights|programmes).+",data) or\
138 139
                re.search("programmes/(\w+)/episodes.+",data) or\
@@ -165,12 +166,12 @@ Connection: Keep-Alive
165 166
                 else:
166 167
                     title,data2,img,desc = self.get_data_element(el)
167 168
                 content.append((title,self.name+"::"+data2,img,desc))
168
-            
169
+
169 170
             if "&page=" in data and lst["page"]*lst["per_page"]<lst["count"]:
170 171
                 data2 = re.sub("&page=\d+","&page=%s"%(lst["page"]+1),data)
171
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page")) 
172
+                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
172 173
             return content
173
-        
174
+
174 175
         ### A-z root ###
175 176
         elif data=="a-z":
176 177
             url = "http://www.bbc.co.uk/programmes/a-z/by/x/all.json?page=1"
@@ -185,7 +186,7 @@ Connection: Keep-Alive
185 186
                 data2 = "atoz/%s/programmes?rights=mobile&page=1&per_page=40&initial_child_count=1&sort=title&sort_direction=asc&availability=available"%ch
186 187
                 content.append((title,self.name+"::"+data2,img,desc))
187 188
             return content
188
-        
189
+
189 190
         ###  Channels home ###
190 191
         elif data=="channels":
191 192
             for ch in self.get_channels():
@@ -197,26 +198,26 @@ Connection: Keep-Alive
197 198
                 desc = title
198 199
                 content.append((title,self.name+"::"+data2,img,desc))
199 200
             return content
200
-        
201
+
201 202
         ### Channel higlihts/progrmmes/days ###
202 203
         elif clist=="channels" and len(data.split("/"))==2:
203 204
             r = self.call(data)
204 205
             chid = data.split("/")[1]
205 206
             ch = self.get_channel_by_id(chid)
206
-            
207
+
207 208
             # Highlights
208 209
             title = ch["title"] + " - highlights"
209 210
             img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
210 211
             data2 = "channels/%s/highlights?lang=en&rights=mobile&availability=available"%ch["id"]
211 212
             desc = title
212 213
             content.append((title,self.name+"::"+data2,img,desc))
213
-            
214
+
214 215
             #AtoZ
215 216
             title = ch["title"] + " - programmes AtoZ"
216 217
             data2 = "channels/%s/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available"%ch["id"]
217 218
             desc = title
218 219
             content.append((title,self.name+"::"+data2,img,desc))
219
-            
220
+
220 221
             day0 = datetime.date.today()
221 222
             for i in range(10):
222 223
                 day = day0-datetime.timedelta(days=i)
@@ -228,11 +229,11 @@ Connection: Keep-Alive
228 229
                 desc = title
229 230
                 content.append((title,self.name+"::"+data2,img,desc))
230 231
             return content
231
-        
232
-            
232
+
233
+
233 234
     def get_streams(self, data):
234 235
         print "[iplayer] get_streams:", data
235
-        if "::" in data: data = data.split("::")[1]         
236
+        if "::" in data: data = data.split("::")[1]
236 237
         if not self.is_video(data):
237 238
             return []
238 239
         cmd = data.split("/")
@@ -265,7 +266,7 @@ Connection: Keep-Alive
265 266
                     sub["name"] = s["service"] if "service" in s else "captions (taff)"
266 267
                     sub["lang"] = "en"
267 268
                     captions.append(sub)
268
-                    
269
+
269 270
             if s["kind"] <> "video":
270 271
                 continue
271 272
             for c in s["connection"]:
@@ -277,9 +278,9 @@ Connection: Keep-Alive
277 278
                 if not r2: continue
278 279
                 slist = re.findall("#EXT-X-STREAM-INF:([^\n]+)\n([^\n]+)", r2, re.DOTALL)
279 280
                 if not slist:
280
-                    stream = stream0.copy()
281
+                    stream = util.item()
281 282
                     stream["url"]=url
282
-                    stream["name"]=title 
283
+                    stream["name"]=title
283 284
                     stream["desc"]=desc
284 285
                     stream["img"]=img
285 286
                     stream["type"]="hls"
@@ -299,9 +300,9 @@ Connection: Keep-Alive
299 300
                             uu = url.split("/")[:-1]
300 301
                             uu.append(url2)
301 302
                             url2 = "/".join(uu)
302
-                        stream = stream0.copy()
303
+                        stream = util.item()
303 304
                         stream["url"]=url2
304
-                        stream["name"]=title 
305
+                        stream["name"]=title
305 306
                         stream["desc"]=desc
306 307
                         stream["img"]=img
307 308
                         stream["type"]="hls"
@@ -315,7 +316,7 @@ Connection: Keep-Alive
315 316
                 s["subs"]=captions
316 317
         streams = sorted(streams,key=lambda item: item["order"],reverse=True)
317 318
         return streams
318
-        
319
+
319 320
     def is_video(self,data):
320 321
         if "::" in data:
321 322
             data = data.split("::")[1]
@@ -326,7 +327,7 @@ Connection: Keep-Alive
326 327
             return True
327 328
         else:
328 329
             return False
329
-        
330
+
330 331
     def get_data_element(self,item):
331 332
         if ("programme" in item["type"] or "group" in item["type"]) and item["count"]>1:
332 333
             ep = item.copy()
@@ -354,9 +355,9 @@ Connection: Keep-Alive
354 355
             title = "%s [%s episodes]"%(title,ep["count"])
355 356
         else:
356 357
             data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
357
-            title = "%s [%s episodes]"%(title,ep["count"])            
358
+            title = "%s [%s episodes]"%(title,ep["count"])
358 359
         return title,data2,img,desc
359
-    
360
+
360 361
     def get_epg_video(self,vid):
361 362
         data = "episodes/%s"%vid
362 363
         r = self.call(data)
@@ -378,7 +379,7 @@ Connection: Keep-Alive
378 379
             return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8"),vid.encode("utf8")
379 380
         else:
380 381
             raise Exception("No video info")
381
-    
382
+
382 383
     def get_epg_live(self,channelid):
383 384
         data = "channels/%s/highlights?live=true"%channelid
384 385
         r = self.call(data)
@@ -401,9 +402,9 @@ Connection: Keep-Alive
401 402
             title = r["channel_highlights"]["channel"]["title"]
402 403
             img = ""
403 404
             desc = title
404
-            
405
+
405 406
         return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8")
406
-        
407
+
407 408
     def get_channels(self):
408 409
         if self.ch:
409 410
             return self.ch
@@ -415,31 +416,31 @@ Connection: Keep-Alive
415 416
             self.ch_id2[item["master_brand_id"]]=i
416 417
             self.ch_name[item["title"]]=i
417 418
         return self.ch
418
-                
419
+
419 420
     def get_channel_by_id(self,chid):
420 421
         if not self.ch:
421 422
             self.get_channels()
422 423
         if not self.ch:
423 424
             return None
424 425
         return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
425
-    
426
+
426 427
     def get_channel_by_id2(self,chid):
427 428
         if not self.ch:
428 429
             self.get_channels()
429 430
         if not self.ch:
430 431
             return None
431 432
         return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
432
-     
433
+
433 434
     def get_channel_by_name(self,name):
434 435
         if not self.ch:
435 436
             self.get_channels()
436 437
         ch2 = self.get_channel_by_name2(name)
437 438
         if not ch2:
438 439
             return None
439
-        ch = self.get_channel_by_id2(ch2["id2"]) 
440
+        ch = self.get_channel_by_id2(ch2["id2"])
440 441
         return ch
441
-                
442
-        
442
+
443
+
443 444
     def call(self, data,params = None, headers=None):
444 445
         if not headers: headers = self.headers
445 446
         #if not lang: lang = self.country
@@ -453,7 +454,7 @@ Connection: Keep-Alive
453 454
                 return None
454 455
         else:
455 456
             return None
456
-        
457
+
457 458
     def call2(self, data,params = None, headers=None):
458 459
         if not headers: headers = self.headers2
459 460
         #if not lang: lang = self.country
@@ -467,7 +468,7 @@ Connection: Keep-Alive
467 468
         try:
468 469
             r = requests.get(url, headers=headers)
469 470
             return r.content
470
-        
471
+
471 472
         except Exception as ex:
472 473
             if ex.code==403:
473 474
                 return ex.read()
@@ -481,17 +482,17 @@ def gt(dt_str):
481 482
     #us= int(us.rstrip("Z"), 10)
482 483
     #r = dt + datetime.timedelta(microseconds=us)a
483 484
     return dt
484
-   
485
+
485 486
 if __name__ == "__main__":
486 487
     c = Source()
487 488
     from subprocess import call
488 489
     #ch = c.get_channels()
489 490
     #c.get_epg_live("bbc_two_england")
490
-    
491
+
491 492
     if len(sys.argv)>1 and  not "iplayer::" in sys.argv[1]:
492
-        
493
+
493 494
         vid = sys.argv[1]
494
-        print "login - %s"%c.login("ivars777","xxx")        
495
+        print "login - %s"%c.login("ivars777","xxx")
495 496
         vid = "1069"
496 497
         vid = "1462566072086"
497 498
         channelid="101"
@@ -499,9 +500,9 @@ if __name__ == "__main__":
499 500
         #data = c.get_stream_url(vid,"vod")
500 501
         #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
501 502
         pass
502
- 
503 503
 
504
-        
504
+
505
+
505 506
     else:
506 507
         if len(sys.argv)>1:
507 508
             data= sys.argv[1]

+ 106
- 106
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/ltc.py ファイルの表示

@@ -21,15 +21,15 @@ API_URL = 'https://m.lattelecom.tv/'
21 21
 user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
22 22
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23 23
 h = HTMLParser.HTMLParser()
24
-    
24
+
25 25
 class Source(SourceBase):
26
-    
26
+
27 27
     def __init__(self):
28 28
         self.name = "ltc"
29 29
         self.title = "Shortcut.lv (lattelecom.tv)"
30 30
         self.img = "picons/shortcut.png"
31 31
         self.desc = "Shortcut.lv (lattelecom.tv) satura skatīšanās"
32
-        
32
+
33 33
         self.token = "" # manstv.lattelecom.tv
34 34
         self.session_id = ""  # www.lattelecom.tv
35 35
         self.api_url = "https://manstv.lattelecom.tv/api/v1.4/get/"
@@ -46,7 +46,7 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0
46 46
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
47 47
 Accept-Language: en-US,en;q=0.8
48 48
         """)
49
-        
49
+
50 50
         self.channels = None
51 51
         ### specific service info ###
52 52
         self.ch=[]
@@ -60,38 +60,38 @@ Accept-Language: en-US,en;q=0.8
60 60
         self.epg_date={}
61 61
         self.epg_ch={}
62 62
         self.epgdates = []
63
-        
63
+
64 64
         self.today = datetime.date.today()
65
-        self.today2 = self.today.strftime("%d.%m.%Y") 
65
+        self.today2 = self.today.strftime("%d.%m.%Y")
66 66
 
67 67
         cur_directory = os.path.dirname(os.path.abspath(__file__))
68 68
         self.config_file = os.path.join(cur_directory,self.name+".cfg")
69 69
         self.options = OrderedDict([("user","lietotajs"),("password","parole")])
70 70
         self.options_read()
71
-               
71
+
72 72
     def get_content(self, data):
73 73
         print "[ltc] get_content:", data
74 74
         if "::" in data:
75
-            data = data.split("::")[1] 
75
+            data = data.split("::")[1]
76 76
         path = data.split("?")[0]
77 77
         clist = path.split("/")[0]
78 78
         params = data[data.find("?"):] if "?" in data else ""
79 79
         qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
80 80
         #lang = qs["lang"] if "lang" in qs else self.country
81
-    
81
+
82 82
         content=[]
83 83
         content.append(("..return", "back","","Return back"))
84
-        
84
+
85 85
         if clist=="home":
86 86
             content.extend([
87 87
                 ("Search TV", "ltc::search/{0}","","Search in TV archive"),
88 88
                 ("Search Video", "ltc::meklet?q={0}","","Search in video"),
89 89
                 ("Live streams", "ltc::tiesraide","","TV live streams"),
90 90
                 ("Archive", "ltc::arhivs","","TV live archive"),
91
-                ("Video", "ltc::videonoma","","Video on demand"),             
91
+                ("Video", "ltc::videonoma","","Video on demand"),
92 92
             ])
93 93
             return content
94
-        
94
+
95 95
         ### Meklēt TV (1.4 API)
96 96
         elif clist == "search": #TODO vod/search/{q}
97 97
             #r = self.call("vod/"+data)
@@ -100,12 +100,12 @@ Accept-Language: en-US,en;q=0.8
100 100
         ### Meklēsana video (www )###
101 101
         elif clist == "meklet": #TODO vod/search/{q}
102 102
             r = self.call2(data)
103
-            
103
+
104 104
             for res in re.findall('<div class="(program follow|movie forward)-link">(.+?</div></div>.*?)</div>', r, re.DOTALL):
105 105
                 r2 = res[1]
106 106
                 if "movie" in res[0]:
107 107
                     #if not "permalink" in r2:
108
-                        #continue                    
108
+                        #continue
109 109
                     m = re.search('<a class="title" href="([^"]+)/">([^<]+)</a>', r2, re.DOTALL)
110 110
                     if not m: continue
111 111
                     title = m.group(2)
@@ -118,7 +118,7 @@ Accept-Language: en-US,en;q=0.8
118 118
                     m = re.search('class="genre".+?>([^<]+)<', r2, re.DOTALL)
119 119
                     if m:
120 120
                         desc = m.group(1)+"\n"+desc
121
-                    
121
+
122 122
                 else:
123 123
                     m = re.search('<a href="/([^"]+)" class="title">([^<]+)</a>', r2, re.DOTALL)
124 124
                     if not m: continue
@@ -140,7 +140,7 @@ Accept-Language: en-US,en;q=0.8
140 140
                     desc = title
141 141
                 content.append((title,self.name+"::"+data2,img,desc))
142 142
             return content
143
-            
143
+
144 144
         ### Tiešraides kanānālu saraksts ###
145 145
         elif data=="tiesraide":
146 146
             r = self.call2(data)
@@ -159,7 +159,7 @@ Accept-Language: en-US,en;q=0.8
159 159
                     desc = title
160 160
                 content.append((title,self.name+"::"+data2,img,desc))
161 161
             return content
162
-            
162
+
163 163
         ### TV arhīva sākums ###
164 164
         elif data=="archive" or data=="arhivs":
165 165
             #self.get_epg()
@@ -169,7 +169,7 @@ Accept-Language: en-US,en;q=0.8
169 169
                 #("Archive - dates", "ltc::archive/dates","","TV live archive by dates"),
170 170
             ])
171 171
             return content
172
-                
172
+
173 173
         ### Arhīva kategorijas
174 174
         elif data=="archive/categories":
175 175
             #https://manstv.lattelecom.tv/api/v1.3/get/archive/records/?filter[category]=13&limit=10&until_id=1458681019238
@@ -182,7 +182,7 @@ Accept-Language: en-US,en;q=0.8
182 182
                 desc = title
183 183
                 content.append((title,self.name+"::"+data2,img,desc))
184 184
             return content
185
-        
185
+
186 186
         ### Arhīva kategoriju video
187 187
         elif "archive/records" in data:
188 188
             #https://manstv.lattelecom.tv/api/v1.3/get/archive/records/?filter[category]=13&limit=10&until_id=1458681019238
@@ -203,7 +203,7 @@ Accept-Language: en-US,en;q=0.8
203 203
                     if not item["channel_id"] in self.epg_ch:
204 204
                         self.epg_ch[item["channel_id"]]=[]
205 205
                     self.epg_ch[item["channel_id"]].append(index)
206
-                item = self.get_epg_id(item["id"])                     
206
+                item = self.get_epg_id(item["id"])
207 207
                 ch = self.get_channel_by_id2(item["channel_id"])
208 208
                 ch_name = ch["name"] if ch else item["channel_id"]
209 209
                 title = u"[%s %s-%s] %s - %s"%(item["date"],item["time_start2"].strftime("%H:%M"),item["time_stop2"].strftime("%H:%M"),ch_name,item["title"])
@@ -217,7 +217,7 @@ Accept-Language: en-US,en;q=0.8
217 217
                 data2 = re.sub("until_id=\d+","until_id="+item["id"],data)
218 218
             else:
219 219
                 data2 = data + "&until_id=%s"%item["id"]
220
-            content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
220
+            content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
221 221
             return content
222 222
 
223 223
         ### Arhīva kanānālu saraksts
@@ -232,7 +232,7 @@ Accept-Language: en-US,en;q=0.8
232 232
             return content
233 233
 
234 234
         ### Arhīva kanānāla video saraksta
235
-        elif "archive/channel/" in data: 
235
+        elif "archive/channel/" in data:
236 236
             chid = path.split("/")[2]
237 237
             for item in self.get_epg_date(qs["date"],chid):
238 238
                 #if item["is_archive"]=='0':continue
@@ -251,18 +251,18 @@ Accept-Language: en-US,en;q=0.8
251 251
                 data2 = re.sub("date=[\d-]+","date="+date2,data)
252 252
             else:
253 253
                 data2 = data + "&date=%s"%date2
254
-            content.append(("Previous day (%s)"%date2,self.name+"::"+data2,"","Go previous day"))                 
254
+            content.append(("Previous day (%s)"%date2,self.name+"::"+data2,"","Go previous day"))
255 255
             return content
256
-        
257
-        ### Arhīva datumi 
256
+
257
+        ### Arhīva datumi
258 258
         elif clist=="arhivs" and len(data.split("/"))==2: # TODO - pasreiz nestrada
259 259
             ch = data.split("/")[1]
260
-            r= self.call(data)            
260
+            r= self.call(data)
261 261
             m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
262 262
             if m:
263 263
                 ch_name = m.group(1)
264 264
             else:
265
-                ch_name = ""            
265
+                ch_name = ""
266 266
             today =  datetime.date.today()
267 267
             for i in range(7):
268 268
                 date = today-datetime.timedelta(i)
@@ -277,12 +277,12 @@ Accept-Language: en-US,en;q=0.8
277 277
         elif clist=="arhivs" and len(data.split("/"))==3: # TODO - nestrādā
278 278
             ch = data.split("/")[1]
279 279
             date = data.split("/")[2]
280
-            r= self.call(data) 
280
+            r= self.call(data)
281 281
             m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
282 282
             if m:
283 283
                 ch_name = m.group(1)
284 284
             else:
285
-                ch_name = ""                        
285
+                ch_name = ""
286 286
             for item in re.findall('(?i)href="/([^"]+?)" id="" class="archive_programm_a"><div class="archive_programm "><div class="chanel_time"><span>([^<]+)</span></div><div class="archive_programm_one"><span>([^<]+)', r):
287 287
                 title = "%s - %s"%(item[1],item[2])
288 288
                 data2 = item[0]
@@ -290,8 +290,8 @@ Accept-Language: en-US,en;q=0.8
290 290
                 desc = "%s (%s)\n%s"%(ch_name,date,title)
291 291
                 content.append((title,self.name+"::"+data2,img,desc))
292 292
             return content
293
-                
294
-        
293
+
294
+
295 295
         ### Videonoma galvenā
296 296
         elif data=="videonoma":
297 297
             content.extend([
@@ -315,7 +315,7 @@ Accept-Language: en-US,en;q=0.8
315 315
                 ("Koncerti - pēc nosaukuma", "ltc::videonoma?page=0&genre=19&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_koncerti.png","Koncerti pēc pēc nosaukuma"),
316 316
             ])
317 317
             return content
318
-        
318
+
319 319
         ### Videonomas saraksti
320 320
         elif path == "videonoma":
321 321
             url = "https://www.lattelecom.tv/movies-snippet.json"+params
@@ -328,19 +328,19 @@ Accept-Language: en-US,en;q=0.8
328 328
             for item in js["movies"]:
329 329
                 if not item["title"]:
330 330
                     continue
331
-                title = item["title"].encode("utf8") 
331
+                title = item["title"].encode("utf8")
332 332
                 data2 = item["url"][1:].encode("utf8")
333 333
                 if data2[-1]=="/": data2=data2[:-1]
334 334
                 if "/raidijumi/" in data2:
335 335
                     data2 += "?series"
336 336
                 img = "https://www.lattelecom.tv"+item["image"].encode("utf8")
337 337
                 desc = "%s\n%s"%(title,item["genre"].encode("utf8"))
338
-                content.append((title,self.name+"::"+data2,img,desc)) 
338
+                content.append((title,self.name+"::"+data2,img,desc))
339 339
             m = re.search("page=(\d+)",data)
340 340
             if m:
341 341
                 page = int(m.group(1))
342 342
                 data2 = re.sub("page=\d+","page=%s"%(page+1),data)
343
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
343
+                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
344 344
             return content
345 345
 
346 346
         ### Sērijas
@@ -353,7 +353,7 @@ Accept-Language: en-US,en;q=0.8
353 353
             raidijums = m.group(1) + " - " if m else ""
354 354
             m = re.search('data-bid="([^"]+)',r)
355 355
             if m:
356
-                url = "https://www.lattelecom.tv/episode-loader.json?bcast_ids=%s"%(m.group(1)) 
356
+                url = "https://www.lattelecom.tv/episode-loader.json?bcast_ids=%s"%(m.group(1))
357 357
                 r = self._http_request(url,headers=self.headers2)
358 358
                 i1 = r.find('{"total":')
359 359
                 i2 = r.find('}<div class=')
@@ -363,16 +363,16 @@ Accept-Language: en-US,en;q=0.8
363 363
                     data2 = item["url"][1:]
364 364
                     img = "https://www.lattelecom.tv"+item["img"]
365 365
                     desc = title
366
-                    content.append((title,self.name+"::"+data2,img,desc))                                     
366
+                    content.append((title,self.name+"::"+data2,img,desc))
367 367
             else:
368
-                for item in re.findall('(?si)<a class="elementxxx forward-link[^"]*" href="([^"]+)">.*?<img src="([^"]+)" class="img"><span class="titlez">([^<]+)</span><span class="epizode_number">([^<]+)</span>', r):                
368
+                for item in re.findall('(?si)<a class="elementxxx forward-link[^"]*" href="([^"]+)">.*?<img src="([^"]+)" class="img"><span class="titlez">([^<]+)</span><span class="epizode_number">([^<]+)</span>', r):
369 369
                     title = "%s%s (%s)"%(raidijums,item[2],item[3])
370 370
                     data2 = item[0][1:]
371 371
                     img = "https://www.lattelecom.tv"+item[1]
372 372
                     desc = title
373 373
                     content.append((title,self.name+"::"+data2,img,desc))
374
-            return content           
375
-            
374
+            return content
375
+
376 376
         ### Videonomas video
377 377
         elif clist=="videonoma" and len(data.split("/"))>1:
378 378
             ch = data.split("/")[1]
@@ -391,20 +391,20 @@ Accept-Language: en-US,en;q=0.8
391 391
             if m:
392 392
                 title = m.group(1)
393 393
             else:
394
-                title = ""  
394
+                title = ""
395 395
             desc = title
396 396
             content = (title,data2,"",desc)
397 397
             return content
398 398
 
399 399
         else:
400 400
             return content
401
-        
401
+
402 402
     def get_streams(self, data):
403 403
         print "[ltc] get_streams:", data
404
-        if "::" in data: data = data.split("::")[1]         
404
+        if "::" in data: data = data.split("::")[1]
405 405
         if not self.is_video(data):
406 406
             return []
407
-        
407
+
408 408
         ### Video nomas strīmus pagaidām dabu no mājas lapas TODO
409 409
         if data.split("/")[0]=="videonoma" and len(data.split("/"))>1:
410 410
             #video_id=data.split("/")[-1]
@@ -412,14 +412,14 @@ Accept-Language: en-US,en;q=0.8
412 412
         else:
413 413
             if not self.is_logedin():
414 414
                 if not self.login():
415
-                    return []   
415
+                    return []
416 416
             r = self.call(data)
417 417
             if not r: return []
418 418
             if "errors" in r:
419 419
                 return []
420 420
             self.refresh_token()
421 421
             token = "&auth_token=app_%s"%(self.token)
422
-            
422
+
423 423
             vid = data.split("/")[2].split("?")[0]
424 424
             vtype = data.split("/")[1]
425 425
             if vtype == "live-streams":
@@ -444,10 +444,10 @@ Accept-Language: en-US,en;q=0.8
444 444
                 date = epg["date"]
445 445
                 title = "%s (%s %s-%s)"%(title,date,t1,t2)
446 446
                 desc = epg["description"]
447
-    
447
+
448 448
             streams = []
449 449
             for s in r["data"]:
450
-                stream = stream0.copy()
450
+                stream = util.item()
451 451
                 stream["url"]=(s["attributes"]["stream-url"]+token.encode("utf8")).encode("utf8")
452 452
                 stream["name"]=title
453 453
                 stream["desc"]=desc
@@ -466,7 +466,7 @@ Accept-Language: en-US,en;q=0.8
466 466
             s["order"] = lv+qv
467 467
         streams = sorted(streams,key=lambda item: item["order"],reverse=True)
468 468
         return streams
469
-        
469
+
470 470
     def is_video(self,data):
471 471
         if "::" in data:
472 472
             data = data.split("::")[1]
@@ -481,7 +481,7 @@ Accept-Language: en-US,en;q=0.8
481 481
             return True
482 482
         else:
483 483
             return False
484
-    
484
+
485 485
     def get_channels(self):
486 486
         if self.ch:
487 487
             return self.ch
@@ -495,21 +495,21 @@ Accept-Language: en-US,en;q=0.8
495 495
             self.ch_id2[item["xprs_id"]]=i
496 496
             self.ch_name[item["name"]]=i
497 497
         return self.ch
498
-                
498
+
499 499
     def get_channel_by_id(self,chid):
500 500
         if not self.ch:
501 501
             self.get_channels()
502 502
         if not self.ch:
503 503
             return None
504 504
         return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
505
-    
505
+
506 506
     def get_channel_by_id2(self,chid):
507 507
         if not self.ch:
508 508
             self.get_channels()
509 509
         if not self.ch:
510 510
             return None
511 511
         return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
512
-    
512
+
513 513
     def get_channels2(self):
514 514
         if self.ch2:
515 515
             return self.ch2
@@ -522,7 +522,7 @@ Accept-Language: en-US,en;q=0.8
522 522
             ch["title"]=item[1]
523 523
             self.ch2.append(ch)
524 524
         return self.ch2
525
-    
525
+
526 526
     def get_channel_by_name2(self,name):
527 527
         if not self.ch2:
528 528
             self.get_channels2()
@@ -530,16 +530,16 @@ Accept-Language: en-US,en;q=0.8
530 530
             if c["name"]==name:
531 531
                 return c
532 532
         return None
533
-            
533
+
534 534
     def get_channel_by_name(self,name):
535 535
         if not self.ch:
536 536
             self.get_channels()
537 537
         ch2 = self.get_channel_by_name2(name)
538 538
         if not ch2:
539 539
             return None
540
-        ch = self.get_channel_by_id2(ch2["id2"]) 
540
+        ch = self.get_channel_by_id2(ch2["id2"])
541 541
         return ch
542
-        
542
+
543 543
     def get_epg(self,date=None,update=False):
544 544
         #https://manstv.lattelecom.tv/api/v1.3/get/tv/epg/?daynight=2016-05-19
545 545
         today=datetime.date.today()
@@ -569,10 +569,10 @@ Accept-Language: en-US,en;q=0.8
569 569
                 if not item["channel_id"] in self.epg_ch:
570 570
                     self.epg_ch[item["channel_id"]]=[]
571 571
                 self.epg_ch[item["channel_id"]].append(index)
572
-                              
572
+
573 573
         if not date in self.epgdates:
574 574
             self.epgdates.append(date)
575
-        
575
+
576 576
 
577 577
     def get_epg_id(self,epgid):
578 578
         if not self.epg:
@@ -581,7 +581,7 @@ Accept-Language: en-US,en;q=0.8
581 581
         if epgid in self.epg_id:
582 582
             return self.epg[self.epg_id[epgid]]
583 583
         return None
584
-    
584
+
585 585
     def get_epg_date(self,date,chid):
586 586
         if not date in self.epgdates:
587 587
             self.get_epg(date)
@@ -590,10 +590,10 @@ Accept-Language: en-US,en;q=0.8
590 590
         for it in self.epg_date[date]:
591 591
             item = self.epg[it]
592 592
             if item["channel_id"]==ch["xprs_id"]:
593
-                items.append(item)        
593
+                items.append(item)
594 594
         return items
595
-        
596
-        
595
+
596
+
597 597
     def call(self, data,params = None, headers=None):
598 598
         if not headers: headers = self.headers
599 599
         #if not lang: lang = self.country
@@ -607,7 +607,7 @@ Accept-Language: en-US,en;q=0.8
607 607
                 return None
608 608
         else:
609 609
             return None
610
-        
610
+
611 611
     def call2(self, data,params = None, headers=None):
612 612
         if not headers: headers = self.headers2
613 613
         #if not lang: lang = self.country
@@ -628,10 +628,10 @@ Accept-Language: en-US,en;q=0.8
628 628
 
629 629
     def login(self,user="",password=""):
630 630
         """Login in to site, get token"""
631
-        self.options_read()        
631
+        self.options_read()
632 632
         if not user: user=self.options["user"]
633 633
         if not password: password = self.options["password"]
634
-        
634
+
635 635
         # Dabūjam tokenu
636 636
         url = "https://manstv.lattelecom.tv/api/v1.3/post/user/login"
637 637
         params = "uid=7f777e938d35e017&password=%s&username=%s&"%(password,user)
@@ -639,7 +639,7 @@ Accept-Language: en-US,en;q=0.8
639 639
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
640 640
 User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G900FD Build/KOT49H)
641 641
 Host: manstv.lattelecom.tv
642
-""" )    
642
+""" )
643 643
         try:
644 644
             r = urllib2.Request(url, data=params, headers=headers)
645 645
             u = urllib2.urlopen(r)
@@ -653,7 +653,7 @@ Host: manstv.lattelecom.tv
653 653
             return True
654 654
         else:
655 655
             return False
656
-        
656
+
657 657
     def refresh_token(self):
658 658
         data = "user/refresh-token//%s"%self.token
659 659
         r = self.call(data)
@@ -663,7 +663,7 @@ Host: manstv.lattelecom.tv
663 663
         else:
664 664
             self.token = ""
665 665
             return False
666
-    
666
+
667 667
     def check_logedin(self):
668 668
         if not self.token:
669 669
             return False
@@ -672,18 +672,18 @@ Host: manstv.lattelecom.tv
672 672
                 return True
673 673
             else:
674 674
                 return False
675
-        
675
+
676 676
     def is_logedin(self):
677 677
         if self.token:
678 678
             return True
679 679
         else:
680 680
             return False
681
-                 
681
+
682 682
     #----------------------------------------------------------------------
683 683
     def get_tv_url(self,video_id):
684 684
         """Get m3u8 url for given live tv channel"""
685 685
         url = "https://m.lattelecom.tv/tiesraide/%s"%video_id
686
-        data = self.get_stream_url2("tiesraide/%s"%video_id)        
686
+        data = self.get_stream_url2("tiesraide/%s"%video_id)
687 687
         #headers = self.headers
688 688
         #headers["Cookie"] = "%s; %s; _hjIncludedInSample=0; MobBitr=1; MobRentBitr=%s; MobRentLang=%s;"%(self.session_id,self.mobtv_cache,data["quality"],data["language"])
689 689
         #response = urllib2.urlopen(urllib2.Request(url, headers=headers))
@@ -702,11 +702,11 @@ Host: manstv.lattelecom.tv
702 702
         #response = urllib2.urlopen(urllib2.Request(url, headers=headers))
703 703
         #m3u8 = response.read()
704 704
         return data["stream"] if data else None
705
-        
705
+
706 706
     #----------------------------------------------------------------------
707 707
     def get_arhivs_url(self,video_id):
708 708
         """Get m3u8 url for given archive video"""
709
-        data = self.get_video_data(video_id)                
709
+        data = self.get_video_data(video_id)
710 710
         #url = "https://m.lattelecom.tv/free_origin?show_origin=1&type=arhivs&event_id=%s&bitrate=mhq"%(video_id) #,data["quality"])
711 711
         #headers = self.headers
712 712
         #headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
@@ -727,7 +727,7 @@ Host: manstv.lattelecom.tv
727 727
             return None
728 728
         if not self.is_logedin():
729 729
             if not self.login():
730
-                return None       
730
+                return None
731 731
         r = self.call(data)
732 732
         if not r:
733 733
             return None
@@ -741,9 +741,9 @@ Host: manstv.lattelecom.tv
741 741
                 s["stream"] += token
742 742
                 hls["streams"].append(s)
743 743
         return hls
744
-            
744
+
745 745
     def get_stream_url2(self,data):
746
-        video_id=data[data.find("/")+1:]        
746
+        video_id=data[data.find("/")+1:]
747 747
         if not self.is_logedin2():
748 748
             if not self.login2():
749 749
                 return []
@@ -753,14 +753,14 @@ Host: manstv.lattelecom.tv
753 753
         if m:
754 754
             title = m.group(1)
755 755
         else:
756
-            title = ""  
756
+            title = ""
757 757
         desc = title
758
-          
758
+
759 759
         url = "https://www.lattelecom.tv/xmls/%s.xml"%video_id
760 760
         headers = self.headers2
761 761
         headers["Cookie"] = self.session_id
762 762
         response = urllib2.urlopen(urllib2.Request(url, headers=headers))
763
-        
763
+
764 764
         r = response.read()
765 765
         servers = re.findall("(?s)<origin>([^<]+)</origin>", r)
766 766
         streams_xml = re.findall('<stream quality="\w+">(mp4:\w+_(\w\w)_(\w\w).mp4)</stream>',r)
@@ -775,13 +775,13 @@ Host: manstv.lattelecom.tv
775 775
             sub["lang"] = s[0]
776 776
             sub["name"] = "captions (vtt)"
777 777
             sub["type"] = "vtt"
778
-            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0            
779
-            captions.append(sub)       
780
-        captions = sorted(captions,key=lambda item: item["order"],reverse=True)      
778
+            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
779
+            captions.append(sub)
780
+        captions = sorted(captions,key=lambda item: item["order"],reverse=True)
781 781
         for s in streams_xml:
782
-            for server in servers: 
782
+            for server in servers:
783 783
                 server2 = self.load_balancer(server)
784
-                url = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(server2,s[0],resource_id,token) 
784
+                url = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(server2,s[0],resource_id,token)
785 785
                 stream = util.item()
786 786
                 stream["url"]=url
787 787
                 stream["lang"]=s[1]
@@ -792,15 +792,15 @@ Host: manstv.lattelecom.tv
792 792
                 stream["subs"] = []
793 793
                 for c in captions:
794 794
                     c2= c.copy()
795
-                    #c2["url"] ="http://%s/mobile-vod/%s/%s?resource_id=%s&auth_token=%s"%(server2,s[0],c["url"],resource_id,token) 
796
-                    c2["url"] ="http://%s/mobile-vod/%s/%s"%(server2,s[0],c["url"]) 
795
+                    #c2["url"] ="http://%s/mobile-vod/%s/%s?resource_id=%s&auth_token=%s"%(server2,s[0],c["url"],resource_id,token)
796
+                    c2["url"] ="http://%s/mobile-vod/%s/%s"%(server2,s[0],c["url"])
797 797
                     stream["subs"].append(c2)
798 798
                     pass
799
-                streams.append(stream)        
799
+                streams.append(stream)
800 800
                 break # TODO ņem tikai pirmo serveri, varētu pārbaudit, kurš no tiem strādā, kurš ne
801 801
 
802 802
         return streams
803
-        
803
+
804 804
         #data = {}
805 805
         #data["server"] = re.findall("(?s)<origin>([^<]+)</origin>", r)[1]
806 806
         #data["language"]=re.findall('(?s)<language code="([^"]+)">', r)
@@ -809,12 +809,12 @@ Host: manstv.lattelecom.tv
809 809
         #data["qs"]=dict(data["qs"])
810 810
         #qs = data["qs"].keys()
811 811
         #data["quality"] = "hd" if "hd" in qs else "hq" if "hq" in qs else "mhq" if "mhq" in qs else "lq"
812
-        #data["mp4"] = data["qs"][data["quality"]]        
812
+        #data["mp4"] = data["qs"][data["quality"]]
813 813
         #data["token"] = re.search("(?s)<auth_token>([^<]+)</auth_token>", r).group(1)
814 814
         #data["resource_id"]=re.search("(?s)<resource_id>([^<]+)</resource_id>", r).group(1)
815 815
         #data["server"]=self.load_balancer(data["server"])
816
-        #data["hls"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"]) 
817
-        ##data["hls"]="http://%s/mobile-vod/mp4:%s/playlist.m3u8?resource_id=%s&auth_token=app_%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])  
816
+        #data["hls"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
817
+        ##data["hls"]="http://%s/mobile-vod/mp4:%s/playlist.m3u8?resource_id=%s&auth_token=app_%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
818 818
 
819 819
     ### wwww.lattelecom.tv izsaukumi
820 820
     def login2(self,user="",password=""):
@@ -905,10 +905,10 @@ Referer: https://www.lattelecom.tv/
905 905
             err = re.search('"error":"(.+?)"').group(1) if re.search('"error":"(.+?)"') else ""
906 906
             raise Exception(u"Kļūda ielogojoties - %s"%err)
907 907
         self.session_id = session_id
908
-        self.headers2["Cookie"] = "%s; "%(self.session_id)    
908
+        self.headers2["Cookie"] = "%s; "%(self.session_id)
909 909
         self.error = ""
910 910
         return True
911
-    
911
+
912 912
     def check_logedin2(self):
913 913
         if not self.session_id:
914 914
             return False
@@ -920,13 +920,13 @@ Referer: https://www.lattelecom.tv/
920 920
             else:
921 921
                 self.session_id = ""
922 922
                 return False
923
-        
923
+
924 924
     def is_logedin2(self):
925 925
         if self.session_id:
926 926
             return True
927 927
         else:
928 928
             return False
929
-    
929
+
930 930
     def load_balancer(self,server,streams=[]):
931 931
         headers = headers2dict("""
932 932
 Connection: keep-alive
@@ -950,7 +950,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
950 950
         except Exception as ex:
951 951
             print "hls failed: %s %s"%(ex.getcode(),url)
952 952
             return False
953
-        
953
+
954 954
         if response.code == 200:
955 955
             html = response.read()
956 956
             url0 = re.search("(http://[^/]+/)",url).group(1)
@@ -960,7 +960,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
960 960
             try:
961 961
                 response2 = urllib2.urlopen(urllib2.Request(url2, headers=headers))
962 962
             except Exception as ex:
963
-                print "hls chunk failed: %s %s"%(ex.getcode(),url2)                
963
+                print "hls chunk failed: %s %s"%(ex.getcode(),url2)
964 964
                 return False
965 965
             if response2.code == 200:
966 966
                 return True
@@ -968,15 +968,15 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
968 968
                 return False
969 969
         else:
970 970
             return False
971
-    
971
+
972 972
 if __name__ == "__main__":
973 973
     c = Source()
974 974
     from subprocess import call
975
-    
975
+
976 976
     if len(sys.argv)>1 and  not "ltc::" in sys.argv[1]:
977
-        
977
+
978 978
         vid = sys.argv[1]
979
-        print "login - %s"%c.login("ivars777","xxx")        
979
+        print "login - %s"%c.login("ivars777","xxx")
980 980
         vid = "1069"
981 981
         vid = "1462566072086"
982 982
         channelid="101"
@@ -984,19 +984,19 @@ if __name__ == "__main__":
984 984
         #data = c.get_stream_url(vid,"vod")
985 985
         #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
986 986
         pass
987
- 
988
-        print "login2 - %s"%c.login2("ivars777","xxx")         
987
+
988
+        print "login2 - %s"%c.login2("ivars777","xxx")
989 989
         #vid2 = "animation/ultimate_avengers_ii"
990 990
         #vid2 = "animation/ice_age"
991 991
         vid2 = "tiesraide/ltv1"
992 992
         #vid2 = "arhivs/1456521417815"
993 993
         data = c.get_stream_url2(vid2)
994
-        print data        
994
+        print data
995 995
         #for s in data:
996 996
         call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
997 997
         pass
998 998
 
999
-        
999
+
1000 1000
     else:
1001 1001
         if len(sys.argv)>1:
1002 1002
             data= sys.argv[1]

+ 4
- 4
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/movieplace.py ファイルの表示

@@ -23,7 +23,7 @@ h = HTMLParser.HTMLParser()
23 23
 
24 24
 class Source(SourceBase):
25 25
 
26
-    def __init__(self,country=""):
26
+    def __init__(self, country=""):
27 27
         self.name = "movieplace"
28 28
         self.title = "MoviePlace.lv"
29 29
         self.img = "http://movieplace.lv/images/logo.png"
@@ -44,8 +44,8 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
44 44
     ######### Entry point ########
45 45
     def get_content(self, data):
46 46
         print "[movieplace] get_content:", data
47
-        source,data,path,plist,clist,params,qs = self.parse_data(data)
48
-        content=[]
47
+        source, data, path, plist, clist, params, qs = self.parse_data(data)
48
+        content = []
49 49
         content.append(("..return", "back","","Return back"))
50 50
 
51 51
         if clist=="home":
@@ -93,7 +93,7 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
93 93
             else:
94 94
                 r = self.call(data)
95 95
             #r = r.decode("cp1251").encode("utf8")
96
-            if clist=="load":
96
+            if clist == "load":
97 97
                 result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="([^"]+)">.+?<div class="years">([^<]+)</div>\s+<div class="country">([^<]+)</div>', r, re.DOTALL)
98 98
             else:
99 99
                 result = re.findall(r' <a href="/([^"]+)" alt="([^"]+)"><img src="/([^"]+)" title="[^"]+">.+?<span>([^<]+)</span>\s*<div class="country">([^<]+)</div>', r, re.IGNORECASE | re.DOTALL)

+ 35
- 35
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/sources/serialguru.py ファイルの表示

@@ -18,9 +18,9 @@ from SourceBase import SourceBase
18 18
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19 19
 import HTMLParser
20 20
 h = HTMLParser.HTMLParser()
21
-    
21
+
22 22
 class Source(SourceBase):
23
-    
23
+
24 24
     def __init__(self,country=""):
25 25
         self.name = "serialguru"
26 26
         self.title = "SerialGURU.ru"
@@ -29,88 +29,88 @@ class Source(SourceBase):
29 29
         self.country=country
30 30
         self.headers = headers2dict("""
31 31
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
32
-Referer: http://serialguru.ru/        
32
+Referer: http://serialguru.ru/
33 33
 """)
34 34
         self.headers2 = headers2dict("""
35 35
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
36 36
 X-Requested-With: XMLHttpRequest
37 37
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
38
-Referer: http://serialguru.ru/        
38
+Referer: http://serialguru.ru/
39 39
 """)
40 40
         self.url = "http://serialguru.ru/"
41 41
         #self.login()
42
-        
42
+
43 43
     def login(self,user="",password=""):
44 44
         return True
45
-            
45
+
46 46
     def get_content(self, data):
47 47
         print "[tvdom] get_content:", data
48 48
         if "::" in data:
49
-            data = data.split("::")[1] 
49
+            data = data.split("::")[1]
50 50
         path = data.split("?")[0]
51 51
         clist = path.split("/")[0]
52 52
         params = data[data.find("?"):] if "?" in data else ""
53 53
         qs = dict(map(lambda x:x.split("="),re.findall("[%\w]+=\w+",params)))
54 54
         lang = qs["lang"] if "lang" in qs else self.country
55
-    
55
+
56 56
         content=[]
57 57
         content.append(("..return", "back","","Return back"))
58
-        
58
+
59 59
         if clist=="home":
60 60
             content.extend([
61
-                ("Search", "serialguru::search/{0}","","Search content"),                
62
-                ("Last", "serialguru::last","","Last series"),                
61
+                ("Search", "serialguru::search/{0}","","Search content"),
62
+                ("Last", "serialguru::last","","Last series"),
63 63
                 ("Series", "serialguru::serials","","TV Series"),
64 64
                 ("Shows", "serialguru::tv","","TV Shows"),
65 65
                 ("Animations", "serialguru::mult","","Animation series"),
66
-                
66
+
67 67
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
68 68
             ])
69 69
             return content
70
-    
71
-        elif data=="last":
70
+
71
+        elif data == "last":
72 72
             r = self.call("")
73 73
             for item in re.findall(r'<li><a href="(http://serialguru\.ru/[^"]+)"><i>([^<]+)</i>  <i>([^<]+)</i> <b>([^<]+)</b></a></li>', r, re.DOTALL):
74 74
                 title = item[1] + " - " + item[2]+"/"+item[3]
75 75
                 img = ""
76
-                data2 = item[0].replace(self.url,"")
76
+                data2 = item[0].replace(self.url, "")
77 77
                 desc = title
78
-                content.append((title,self.name+"::"+data2,img,desc))
78
+                content.append((title, self.name+"::"+data2, img, desc))
79 79
             return content
80 80
 
81 81
         elif data=="serials":
82 82
             content.extend([
83
-                ("All", "serialguru::serials?o=0&t=S","","All series"),                
84
-                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),                
83
+                ("All", "serialguru::serials?o=0&t=S","","All series"),
84
+                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),
85 85
                 ("English", "serialguru::serials?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=S","","English countries series"),
86 86
                 ("Europe", "serialguru::serials?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=S","","European countries series"),
87 87
                 ("Other", "serialguru::serials?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=S","","Other countries series"),
88 88
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
89 89
             ])
90 90
             return content
91
-        
91
+
92 92
         elif data=="tv":
93 93
             content.extend([
94
-                ("All", "serialguru::tv?o=0&t=S","","All series"),                
95
-                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),                
94
+                ("All", "serialguru::tv?o=0&t=S","","All series"),
95
+                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),
96 96
                 ("English", "serialguru::tv?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=P","","English countries TV shows"),
97 97
                 ("Europe", "serialguru::tv?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=P","","European countries TV shows series"),
98 98
                 ("Other", "serialguru::tv?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=P","","Other countries TV shows"),
99 99
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
100 100
             ])
101 101
             return content
102
-        
102
+
103 103
         elif data=="mult":
104 104
             content.extend([
105
-                ("All", "serialguru::mult?o=0&t=S","","All series"),                
106
-                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),                
105
+                ("All", "serialguru::mult?o=0&t=S","","All series"),
106
+                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),
107 107
                 ("English", "serialguru::mult?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=M","","English countries animantions"),
108 108
                 ("Europe", "serialguru::mult?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=M","","European countries animantions"),
109 109
                 ("Other", "serialguru::mult?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=M","","Other countries animantions"),
110 110
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
111 111
             ])
112 112
             return content
113
-        
113
+
114 114
         elif clist=="search":
115 115
             if data.split("/")>1:
116 116
                 term = data.split("/")[1]
@@ -128,7 +128,7 @@ Referer: http://serialguru.ru/
128 128
                 desc = title +"\nRating:%s (%s+/%s-)"%(rating,item["plus_cnt"].encode("utf8"),item["minus_cnt"].encode("utf8"))
129 129
                 content.append((title,self.name+"::"+data2,img,desc))
130 130
             return content
131
-                        
131
+
132 132
         elif path=="serials" or path=="tv" or path=="mult":
133 133
             if path=="serials" and not "cat%5B%5D" in data:
134 134
                 #content.append(("All", "serialguru::"+data+"&cat%5B%5D=","","All series"))
@@ -146,11 +146,11 @@ Referer: http://serialguru.ru/
146 146
                     content.append((title,self.name+"::"+data2,img,desc))
147 147
                 page=int(re.search("o=(\d+)",data).group(1))
148 148
                 data2 = re.sub("o=(\d+)","o=%s"%(page+15),data)
149
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
149
+                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
150 150
                 return content
151
-        
152
-        
153
-        ### Pārraide  
151
+
152
+
153
+        ### Pārraide
154 154
         else:
155 155
             r = self.call(clist)
156 156
             title0=re.search('<h2>(.+?)</h2>',r,re.DOTALL).group(1)
@@ -181,10 +181,10 @@ Referer: http://serialguru.ru/
181 181
                     img = img0
182 182
                     data2 = item["file"].encode("utf8")
183 183
                     desc = desc0
184
-                    content.append((title,data2,img,desc))               
184
+                    content.append((title,data2,img,desc))
185 185
             return content
186
- 
187
-            
186
+
187
+
188 188
     def is_video(self,data):
189 189
         if "::" in data:
190 190
             data = data.split("::")[1]
@@ -192,14 +192,14 @@ Referer: http://serialguru.ru/
192 192
             return True
193 193
         else:
194 194
             return False
195
-    
195
+
196 196
     def get_categories(self,data):
197 197
         r = self.call(data)
198 198
         r2 = re.search('<td class="category">(.+?)</td>', r, re.DOTALL).group(1)
199 199
         items = re.findall(r'<a href="#" data-id="(\d+)">([^<]+)</a>', r2, re.DOTALL)
200 200
         return items
201 201
 
202
-        
202
+
203 203
     def call(self, data,params = None, headers=None):
204 204
         if not headers: headers = self.headers
205 205
         #if not lang: lang = self.country

+ 13
- 1
ipkg/data/usr/lib/enigma2/python/Plugins/Extensions/PlayStream/util.py ファイルの表示

@@ -248,7 +248,19 @@ def ttaf2srt(s):
248 248
 
249 249
 
250 250
 def item():
251
-    stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":"","order":0}
251
+    stream0 = {
252
+        'name': '',
253
+        'url': '',
254
+        'quality': '?',
255
+        'surl': '',
256
+        'subs': [],
257
+        'headers': {},
258
+        "desc":"","img":"",
259
+        "lang":"",
260
+        "type":"",
261
+        "resolver":"",
262
+        "order":0
263
+        }
252 264
     return stream0
253 265
 
254 266
 class _StringCookieJar(cookielib.LWPCookieJar):

バイナリ
release/enigma2-plugin-extensions-playstream_0.5r.ipk ファイルの表示


バイナリ
release/enigma2-plugin-extensions-playstream_0.5s.ipk ファイルの表示


+ 9
- 13
sources/SourceBase.py ファイルの表示

@@ -13,7 +13,7 @@ from collections import OrderedDict
13 13
 import ConfigParser
14 14
 
15 15
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
16
-stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":"","order":0}        
16
+stream0 = {'name': '', 'url': '', 'quality': '???', 'surl': '', 'subs': '', 'headers': {},"desc":"","img":"","lang":"","type":"","order":0}
17 17
 
18 18
 
19 19
 class SourceBase(object):
@@ -56,28 +56,28 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
56 56
         stream["url"] = content[1].encode("utf8") if isinstance(content[1],unicode) else content[1]
57 57
         stream["img"] = content[2].encode("utf8") if isinstance(content[2],unicode) else content[2]
58 58
         stream["desc"] = content[3].encode("utf8") if isinstance(content[3],unicode) else content[3]
59
-        stream["type"] = stream_type(content[1]).encode("utf8") 
59
+        stream["type"] = stream_type(content[1]).encode("utf8")
60 60
         return[stream]
61 61
 
62 62
     def options_read(self):
63 63
         if not ("options" in dir(self) and self.options): # process options only if self.options defined, self.config_file should be defined too
64 64
             return None
65
-        config = ConfigParser.ConfigParser()        
65
+        config = ConfigParser.ConfigParser()
66 66
         if os.path.exists(self.config_file):
67 67
             config.read(self.config_file)
68
-            self.options = OrderedDict(config.items(self.name))             
68
+            self.options = OrderedDict(config.items(self.name))
69 69
         else:
70 70
             self.options_write(self.options)
71 71
         return self.options
72 72
 
73
-    def options_write(self,options):        
74
-        config = ConfigParser.ConfigParser() 
73
+    def options_write(self,options):
74
+        config = ConfigParser.ConfigParser()
75 75
         config.add_section(self.name)
76 76
         for k in options.keys():
77 77
             config.set(self.name, k,options[k])
78 78
         with open(self.config_file,"w") as f:
79 79
             config.write(f)
80
-        self.options = OrderedDict(config.items(self.name))        
80
+        self.options = OrderedDict(config.items(self.name))
81 81
 
82 82
     def call(self, data,params=None,headers=None,lang=""):
83 83
         if not headers: headers = self.headers
@@ -94,14 +94,14 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
94 94
             raise "No data returned"
95 95
 
96 96
     def _http_request(self, url,params = None, headers=None):
97
-        if not headers: 
97
+        if not headers:
98 98
             headers = self.headers if "headers" in dir(self) else headers2dict("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0")
99 99
         try:
100 100
             if params:
101 101
                 r = requests.post(url, data=params, headers=headers)
102 102
             else:
103 103
                 r = requests.get(url, headers=headers)
104
-            return r.content 
104
+            return r.content
105 105
         except Exception as ex:
106 106
             if "read" in ex:
107 107
                 content = ex.read()
@@ -113,10 +113,6 @@ User-Agent: Mozilla/5.0 (Linux; U; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWeb
113 113
     def stream_type(data):
114 114
         return stream_type(data)
115 115
 
116
-    @staticmethod
117
-    def get_stream0():
118
-        return stream0.copy()
119
-
120 116
     @staticmethod
121 117
     def parse_data(data):
122 118
         if "::" in data:

バイナリ
sources/SourceBase.pyc ファイルの表示


+ 36
- 35
sources/euronews.py ファイルの表示

@@ -14,13 +14,14 @@ import urllib2, urllib
14 14
 import datetime, time,re, sys,os
15 15
 from collections import OrderedDict
16 16
 from SourceBase import SourceBase
17
+import util
17 18
 
18 19
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19 20
 import HTMLParser
20 21
 h = HTMLParser.HTMLParser()
21
-    
22
+
22 23
 class Source(SourceBase):
23
-    
24
+
24 25
     def __init__(self,language="en"):
25 26
         self.name = "euronews"
26 27
         self.title = "Euronews"
@@ -42,10 +43,10 @@ Connection: keep-alive
42 43
             self.get_languages()
43 44
         except:
44 45
             pass
45
-        
46
+
46 47
     def login(self,user="",password=""):
47 48
         return True
48
-            
49
+
49 50
     def get_content(self, data):
50 51
         print "[%s] get_content:"%self.name, data
51 52
         source,data,path,plist,clist,params,qs = self.parse_data(data)
@@ -53,13 +54,13 @@ Connection: keep-alive
53 54
         lang = self.options["language"]
54 55
         if not lang in self.get_languages():
55 56
             raise Exception("Not valid default language - '%s'"%lang)
56
-    
57
+
57 58
         content=[]
58 59
         content.append(("..return", "back","","Return back"))
59
-        
60
+
60 61
         if clist=="home":
61 62
             content.extend([
62
-                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),                
63
+                ("Search", "euronews::content/getSearch?lang=%s&byPage=40&page=1&text={0}"%lang,self.img,"Top stories timeline"),
63 64
                 ("Live stream", "euronews::live?lang=%s"%lang,self.img,"Euronews live stream"),
64 65
                 ("Just in", "euronews::content/getTimeline?lang=%s&byPage=40&page=1"%lang,self.img,"News timeline"),
65 66
                 ("Top stories", "euronews::content/getTopStories?lang=%s"%lang,self.img,"Top stories timeline"),
@@ -71,16 +72,16 @@ Connection: keep-alive
71 72
                 ("Programs list", "euronews::content/getPrograms?lang=%s"%lang,self.img,"Programs list"),
72 73
              ])
73 74
             return content
74
-        
75 75
 
76
-        ### Video arhīvs ###  
76
+
77
+        ### Video arhīvs ###
77 78
         elif clist=="content":
78 79
             if "lang" in qs:
79 80
                 del qs["lang"]
80 81
             params = json.dumps(qs)
81
-            
82
+
82 83
             req = '{"methodName":"content.%s","apiKey":"androidPhoneEuronews-1.0","params":%s,"language":"%s"}'%(plist[1],params,lang)
83
-            r = self.call(req)    
84
+            r = self.call(req)
84 85
             if not r:
85 86
                 return content
86 87
             lst = r["timeline"] if "timeline" in r else\
@@ -93,7 +94,7 @@ Connection: keep-alive
93 94
                 []
94 95
             if not lst:
95 96
                 return content
96
-            
97
+
97 98
             for item in lst:
98 99
                 if plist[1] in ("getTimeline"):
99 100
                     article = item["article"]
@@ -104,7 +105,7 @@ Connection: keep-alive
104 105
                     article = item
105 106
                     atype = "article"
106 107
                 if plist[1]=="getPrograms":
107
-                    title = article["title"] 
108
+                    title = article["title"]
108 109
                     id = article["pId"]
109 110
                     desc = title
110 111
                     img = "http://static.euronews.com/articles/programs/533x360_%s"%article["img"]
@@ -115,7 +116,7 @@ Connection: keep-alive
115 116
                     if atype <> "article":
116 117
                         title = "[%s] %s"%(atype,title)
117 118
                     atime = datetime.datetime.fromtimestamp(int(article["uts"]))
118
-                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone) 
119
+                    #atime = datetime.datetime.fromtimestamp(int(article["uts"])-time.altzone)
119 120
                     atime = atime.strftime("%Y-%m-%d %H:%M")
120 121
                     vert = self.vid[article["vId"]] if "vId" in article else ""
121 122
                     ptitle = article["pTitle"] if "pTitle" in article else ""
@@ -129,19 +130,19 @@ Connection: keep-alive
129 130
                     content.append((title,self.name+"::"+data2,img,desc))
130 131
             if "page=" in data:
131 132
                 data2 = re.sub("page=\d+","page=%s"%(int(qs["page"])+1),data)
132
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page")) 
133
-            return content            
133
+                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
134
+            return content
135
+
134 136
 
135
-    
136 137
     def is_video(self,data):
137
-        source,data,path,plist,clist,params,qs = self.parse_data(data)        
138
+        source,data,path,plist,clist,params,qs = self.parse_data(data)
138 139
         if path == "live":
139 140
             return True
140 141
         elif clist=="content" and plist[1]=="getArticle":
141 142
             return True
142 143
         else:
143 144
             return False
144
-        
145
+
145 146
     def get_streams(self, data):
146 147
         print "[euronews] get_streams:", data
147 148
         if not self.is_video(data):
@@ -150,10 +151,10 @@ Connection: keep-alive
150 151
         #lang = qs["lang"] if "lang" in qs else self.language
151 152
         lang = self.options["language"]
152 153
         if not lang in self.get_languages():
153
-            raise Exception("Not valid default language - '%s'"%lang)        
154
-        
154
+            raise Exception("Not valid default language - '%s'"%lang)
155
+
155 156
         streams = []
156
-        
157
+
157 158
         if path == "live":
158 159
             url = "http://www.euronews.com/api/watchlive.json"
159 160
             r = self._http_request(url)
@@ -169,11 +170,11 @@ Connection: keep-alive
169 170
                     raise Exception("No live stream found")
170 171
             except:
171 172
                 raise Exception("No live stream found")
172
-            
173
+
173 174
             slist = js["primary"]
174
-            
175
+
175 176
             for l in slist:
176
-                stream = self.get_stream0()
177
+                stream = util.item()
177 178
                 stream["url"]=slist[l]["hls"]
178 179
                 stream["lang"]=l
179 180
                 stream["quality"]="variant"
@@ -181,7 +182,7 @@ Connection: keep-alive
181 182
                 stream["desc"]=stream["name"]
182 183
                 stream["type"]="hls" #stream_type(url)
183 184
                 streams.append(stream)
184
-                
185
+
185 186
         elif clist=="content" and plist[1] == "getArticle":
186 187
             if "lang" in qs:
187 188
                 del qs["lang"]
@@ -189,14 +190,14 @@ Connection: keep-alive
189 190
             for lang in languages:
190 191
                 id = qs["id"]
191 192
                 req = '{"methodName":"content.getArticle","apiKey":"androidPhoneEuronews-1.0","params":{"id":"%s"},"language":"%s"}'%(id,lang)
192
-                r = self.call(req)    
193
+                r = self.call(req)
193 194
                 if not r:
194
-                    raise Exception("No live stream found") 
195
+                    raise Exception("No live stream found")
195 196
                 if not "articlelist" in r:
196 197
                     msg = r["label"] if "label" in r else "No article finde"
197 198
                     raise Exception(msg)
198 199
                 article = r["articlelist"]
199
-                stream = self.get_stream0()
200
+                stream = util.item()
200 201
                 stream["url"]=article["videoUri"] if "videoUri" in article else ""
201 202
                 if not stream["url"]:
202 203
                     return []
@@ -206,13 +207,13 @@ Connection: keep-alive
206 207
                 stream["desc"]=article["text"] if "text" in article else article["title"]
207 208
                 stream["type"]="http" #stream_type(url)
208 209
                 streams.append(stream)
209
-            
210
+
210 211
         else:
211 212
             raise Exception("No live stream found")
212
-           
213
+
213 214
         ### TODO - sakārtot sarakstu, lai pirmais ir labakais video
214 215
         qlist = ["???","lq","mq","hq","hd","variant"]
215
-        llist = ["fr","en","ru","lv"]        
216
+        llist = ["fr","en","ru","lv"]
216 217
         for s in streams:
217 218
             if s["lang"]==self.options["language"]:
218 219
                 s["order"] = 10000
@@ -238,11 +239,11 @@ Connection: keep-alive
238 239
                 raise Exception("Can not get languages list")
239 240
         except:
240 241
             raise Exception("Can not get languages list")
241
-        
242
+
242 243
         slist = js["primary"]
243 244
         self.languages=slist.keys()
244 245
         return self.languages
245
-        
246
+
246 247
     def call(self, data,params = None, headers=None):
247 248
         if not headers: headers = self.headers
248 249
         #if not lang: lang = self.country
@@ -269,7 +270,7 @@ content-disposition: form-data; name=request
269 270
                 return None
270 271
         else:
271 272
             return None
272
-        
273
+
273 274
 
274 275
 if __name__ == "__main__":
275 276
     language= "en"

バイナリ
sources/euronews.pyc ファイルの表示


+ 56
- 55
sources/iplayer.py ファイルの表示

@@ -13,22 +13,23 @@ import datetime
13 13
 import HTMLParser
14 14
 import json
15 15
 import datetime,time
16
-from SourceBase import SourceBase, stream_type, stream0
16
+from SourceBase import SourceBase, stream_type
17
+import util
17 18
 from collections import OrderedDict
18 19
 
19 20
 API_URL = 'https://m.lattelecom.tv/'
20 21
 user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
21 22
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
22 23
 h = HTMLParser.HTMLParser()
23
-    
24
+
24 25
 class Source(SourceBase):
25
-    
26
+
26 27
     def __init__(self):
27 28
         self.name = "iplayer"
28 29
         self.title = "BBC iPlayer"
29 30
         self.img = "http://www.userlogos.org/files/logos/inductiveload/BBC_iPlayer_logo.png"
30 31
         self.desc = "BBC iPlayer portal content"
31
-        
32
+
32 33
         self.api_url = "http://ibl.api.bbci.co.uk/ibl/v1/"
33 34
         self.headers = headers2dict("""
34 35
 User-Agent: BBCiPlayer/4.19.0.3021 (SM-G900FD; Android 4.4.2)
@@ -38,7 +39,7 @@ Connection: Keep-Alive
38 39
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
39 40
 Connection: Keep-Alive
40 41
         """)
41
-        
42
+
42 43
         self.ch = []
43 44
         self.ch_id={}
44 45
         self.ch_id2={}
@@ -54,26 +55,26 @@ Connection: Keep-Alive
54 55
             "bbc_news24":"http://www.lyngsat-logo.com/hires/bb/bbc_news.png",
55 56
             "bbc_parliament":"http://www.lyngsat-logo.com/hires/bb/bbc_parliament.png",
56 57
             "bbc_alba":"http://www.lyngsat-logo.com/hires/bb/bbc_alba.png",
57
-            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"          
58
+            "s4cpbs":"http://www.lyngsat-logo.com/hires/ss/s4c_uk.png"
58 59
         }
59 60
         cur_directory = os.path.dirname(os.path.abspath(__file__))
60 61
         self.config_file = os.path.join(cur_directory,self.name+".cfg")
61 62
         self.options = OrderedDict([("user","lietotajs"),("password","parole")])
62 63
         self.options_read()
63
-                     
64
+
64 65
     def get_content(self, data):
65 66
         print "[iplayer] get_content:", data
66 67
         if "::" in data:
67
-            data = data.split("::")[1] 
68
+            data = data.split("::")[1]
68 69
         path = data.split("?")[0]
69 70
         clist = path.split("/")[0]
70 71
         params = data[data.find("?"):] if "?" in data else ""
71 72
         qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
72 73
         #lang = qs["lang"] if "lang" in qs else self.country
73
-    
74
+
74 75
         content=[]
75 76
         content.append(("..return", "back","","Return back"))
76
-        
77
+
77 78
         ### Home ###
78 79
         if data=="home":
79 80
             content.extend([
@@ -82,11 +83,11 @@ Connection: Keep-Alive
82 83
                 ("Channels", "iplayer::channels","","Programmes by channel/date"),
83 84
                 ("Categories", "iplayer::categories","","Programmes by categories"),
84 85
                 ("A-Z", "iplayer::a-z","","All programmes by name"),
85
-                ("Highlights", "iplayer::home/highlights","","Current highlights"),             
86
-                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")            
86
+                ("Highlights", "iplayer::home/highlights","","Current highlights"),
87
+                ("Most popular", "iplayer::groups/popular/episodes?per_page=40&page=1","","Most popular programmes")
87 88
             ])
88 89
             return content
89
-        
90
+
90 91
         ### Search ###
91 92
         elif clist=="search":
92 93
             data_ = "search-suggest/?q=%s&rights=mobile&initial_child_count=1"%data.split("/")[1]
@@ -95,8 +96,8 @@ Connection: Keep-Alive
95 96
                 title,data2,img,desc = self.get_data_element(item)
96 97
                 content.append((title,self.name+"::"+data2,img,desc))
97 98
             return content
98
-                        
99
-        
99
+
100
+
100 101
         ### Live main ###
101 102
         elif data=="live":
102 103
             for ch in self.get_channels():
@@ -108,7 +109,7 @@ Connection: Keep-Alive
108 109
                 desc = ee[2]
109 110
                 content.append((title,self.name+"::"+data2,img,desc))
110 111
             return content
111
-        
112
+
112 113
         ### Categories ###
113 114
         elif data == "categories":
114 115
             r = self.call(data)
@@ -121,7 +122,7 @@ Connection: Keep-Alive
121 122
                 img = self.img
122 123
                 content.append((title,self.name+"::"+data2,img,desc))
123 124
             return content
124
-        
125
+
125 126
         ### Catetory root ###
126 127
         elif clist == "categories" and len(data.split("/"))==2:
127 128
             r = self.call(data)
@@ -132,7 +133,7 @@ Connection: Keep-Alive
132 133
             title = "%s - a-z (%s programmes, %s episodes)"%(r["category"]["title"],r["category"]["child_programme_count"],r["category"]["child_episode_count"])
133 134
             content.append((title,self.name+"::"+data+"/programmes?rights=mobile&page=1&per_page=40&sort=title&sort_direction=asc&initial_child_count=1&availability=available",self.img,title))
134 135
             return content
135
-        
136
+
136 137
         ### Program/episodes list ###
137 138
         elif   re.search("categories/([\w\-]+)/(highlights|programmes).+",data) or\
138 139
                re.search("programmes/(\w+)/episodes.+",data) or\
@@ -165,12 +166,12 @@ Connection: Keep-Alive
165 166
                 else:
166 167
                     title,data2,img,desc = self.get_data_element(el)
167 168
                 content.append((title,self.name+"::"+data2,img,desc))
168
-            
169
+
169 170
             if "&page=" in data and lst["page"]*lst["per_page"]<lst["count"]:
170 171
                 data2 = re.sub("&page=\d+","&page=%s"%(lst["page"]+1),data)
171
-                content.append(("Next page",self.name+"::"+data2,self.img,"Next page")) 
172
+                content.append(("Next page",self.name+"::"+data2,self.img,"Next page"))
172 173
             return content
173
-        
174
+
174 175
         ### A-z root ###
175 176
         elif data=="a-z":
176 177
             url = "http://www.bbc.co.uk/programmes/a-z/by/x/all.json?page=1"
@@ -185,7 +186,7 @@ Connection: Keep-Alive
185 186
                 data2 = "atoz/%s/programmes?rights=mobile&page=1&per_page=40&initial_child_count=1&sort=title&sort_direction=asc&availability=available"%ch
186 187
                 content.append((title,self.name+"::"+data2,img,desc))
187 188
             return content
188
-        
189
+
189 190
         ###  Channels home ###
190 191
         elif data=="channels":
191 192
             for ch in self.get_channels():
@@ -197,26 +198,26 @@ Connection: Keep-Alive
197 198
                 desc = title
198 199
                 content.append((title,self.name+"::"+data2,img,desc))
199 200
             return content
200
-        
201
+
201 202
         ### Channel higlihts/progrmmes/days ###
202 203
         elif clist=="channels" and len(data.split("/"))==2:
203 204
             r = self.call(data)
204 205
             chid = data.split("/")[1]
205 206
             ch = self.get_channel_by_id(chid)
206
-            
207
+
207 208
             # Highlights
208 209
             title = ch["title"] + " - highlights"
209 210
             img = "http://static.bbci.co.uk/mobileiplayerappbranding/1.9/android/images/channels/tv-guide-wide-logo/layout_normal/xxhdpi/%s_tv-guide-wide-logo.png"%ch["id"]
210 211
             data2 = "channels/%s/highlights?lang=en&rights=mobile&availability=available"%ch["id"]
211 212
             desc = title
212 213
             content.append((title,self.name+"::"+data2,img,desc))
213
-            
214
+
214 215
             #AtoZ
215 216
             title = ch["title"] + " - programmes AtoZ"
216 217
             data2 = "channels/%s/programmes?rights=mobile&page=1&per_page=40&sort=recent&sort_direction=asc&initial_child_count=1&availability=available"%ch["id"]
217 218
             desc = title
218 219
             content.append((title,self.name+"::"+data2,img,desc))
219
-            
220
+
220 221
             day0 = datetime.date.today()
221 222
             for i in range(10):
222 223
                 day = day0-datetime.timedelta(days=i)
@@ -228,11 +229,11 @@ Connection: Keep-Alive
228 229
                 desc = title
229 230
                 content.append((title,self.name+"::"+data2,img,desc))
230 231
             return content
231
-        
232
-            
232
+
233
+
233 234
     def get_streams(self, data):
234 235
         print "[iplayer] get_streams:", data
235
-        if "::" in data: data = data.split("::")[1]         
236
+        if "::" in data: data = data.split("::")[1]
236 237
         if not self.is_video(data):
237 238
             return []
238 239
         cmd = data.split("/")
@@ -265,7 +266,7 @@ Connection: Keep-Alive
265 266
                     sub["name"] = s["service"] if "service" in s else "captions (taff)"
266 267
                     sub["lang"] = "en"
267 268
                     captions.append(sub)
268
-                    
269
+
269 270
             if s["kind"] <> "video":
270 271
                 continue
271 272
             for c in s["connection"]:
@@ -277,9 +278,9 @@ Connection: Keep-Alive
277 278
                 if not r2: continue
278 279
                 slist = re.findall("#EXT-X-STREAM-INF:([^\n]+)\n([^\n]+)", r2, re.DOTALL)
279 280
                 if not slist:
280
-                    stream = stream0.copy()
281
+                    stream = util.item()
281 282
                     stream["url"]=url
282
-                    stream["name"]=title 
283
+                    stream["name"]=title
283 284
                     stream["desc"]=desc
284 285
                     stream["img"]=img
285 286
                     stream["type"]="hls"
@@ -299,9 +300,9 @@ Connection: Keep-Alive
299 300
                             uu = url.split("/")[:-1]
300 301
                             uu.append(url2)
301 302
                             url2 = "/".join(uu)
302
-                        stream = stream0.copy()
303
+                        stream = util.item()
303 304
                         stream["url"]=url2
304
-                        stream["name"]=title 
305
+                        stream["name"]=title
305 306
                         stream["desc"]=desc
306 307
                         stream["img"]=img
307 308
                         stream["type"]="hls"
@@ -315,7 +316,7 @@ Connection: Keep-Alive
315 316
                 s["subs"]=captions
316 317
         streams = sorted(streams,key=lambda item: item["order"],reverse=True)
317 318
         return streams
318
-        
319
+
319 320
     def is_video(self,data):
320 321
         if "::" in data:
321 322
             data = data.split("::")[1]
@@ -326,7 +327,7 @@ Connection: Keep-Alive
326 327
             return True
327 328
         else:
328 329
             return False
329
-        
330
+
330 331
     def get_data_element(self,item):
331 332
         if ("programme" in item["type"] or "group" in item["type"]) and item["count"]>1:
332 333
             ep = item.copy()
@@ -354,9 +355,9 @@ Connection: Keep-Alive
354 355
             title = "%s [%s episodes]"%(title,ep["count"])
355 356
         else:
356 357
             data2 = "programmes/%s/episodes?per_page=40&page=1"%ep["id"]
357
-            title = "%s [%s episodes]"%(title,ep["count"])            
358
+            title = "%s [%s episodes]"%(title,ep["count"])
358 359
         return title,data2,img,desc
359
-    
360
+
360 361
     def get_epg_video(self,vid):
361 362
         data = "episodes/%s"%vid
362 363
         r = self.call(data)
@@ -378,7 +379,7 @@ Connection: Keep-Alive
378 379
             return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8"),vid.encode("utf8")
379 380
         else:
380 381
             raise Exception("No video info")
381
-    
382
+
382 383
     def get_epg_live(self,channelid):
383 384
         data = "channels/%s/highlights?live=true"%channelid
384 385
         r = self.call(data)
@@ -401,9 +402,9 @@ Connection: Keep-Alive
401 402
             title = r["channel_highlights"]["channel"]["title"]
402 403
             img = ""
403 404
             desc = title
404
-            
405
+
405 406
         return title.encode("utf8"),img.encode("utf8"),desc.encode("utf8")
406
-        
407
+
407 408
     def get_channels(self):
408 409
         if self.ch:
409 410
             return self.ch
@@ -415,31 +416,31 @@ Connection: Keep-Alive
415 416
             self.ch_id2[item["master_brand_id"]]=i
416 417
             self.ch_name[item["title"]]=i
417 418
         return self.ch
418
-                
419
+
419 420
     def get_channel_by_id(self,chid):
420 421
         if not self.ch:
421 422
             self.get_channels()
422 423
         if not self.ch:
423 424
             return None
424 425
         return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
425
-    
426
+
426 427
     def get_channel_by_id2(self,chid):
427 428
         if not self.ch:
428 429
             self.get_channels()
429 430
         if not self.ch:
430 431
             return None
431 432
         return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
432
-     
433
+
433 434
     def get_channel_by_name(self,name):
434 435
         if not self.ch:
435 436
             self.get_channels()
436 437
         ch2 = self.get_channel_by_name2(name)
437 438
         if not ch2:
438 439
             return None
439
-        ch = self.get_channel_by_id2(ch2["id2"]) 
440
+        ch = self.get_channel_by_id2(ch2["id2"])
440 441
         return ch
441
-                
442
-        
442
+
443
+
443 444
     def call(self, data,params = None, headers=None):
444 445
         if not headers: headers = self.headers
445 446
         #if not lang: lang = self.country
@@ -453,7 +454,7 @@ Connection: Keep-Alive
453 454
                 return None
454 455
         else:
455 456
             return None
456
-        
457
+
457 458
     def call2(self, data,params = None, headers=None):
458 459
         if not headers: headers = self.headers2
459 460
         #if not lang: lang = self.country
@@ -467,7 +468,7 @@ Connection: Keep-Alive
467 468
         try:
468 469
             r = requests.get(url, headers=headers)
469 470
             return r.content
470
-        
471
+
471 472
         except Exception as ex:
472 473
             if ex.code==403:
473 474
                 return ex.read()
@@ -481,17 +482,17 @@ def gt(dt_str):
481 482
     #us= int(us.rstrip("Z"), 10)
482 483
     #r = dt + datetime.timedelta(microseconds=us)a
483 484
     return dt
484
-   
485
+
485 486
 if __name__ == "__main__":
486 487
     c = Source()
487 488
     from subprocess import call
488 489
     #ch = c.get_channels()
489 490
     #c.get_epg_live("bbc_two_england")
490
-    
491
+
491 492
     if len(sys.argv)>1 and  not "iplayer::" in sys.argv[1]:
492
-        
493
+
493 494
         vid = sys.argv[1]
494
-        print "login - %s"%c.login("ivars777","xxx")        
495
+        print "login - %s"%c.login("ivars777","xxx")
495 496
         vid = "1069"
496 497
         vid = "1462566072086"
497 498
         channelid="101"
@@ -499,9 +500,9 @@ if __name__ == "__main__":
499 500
         #data = c.get_stream_url(vid,"vod")
500 501
         #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
501 502
         pass
502
- 
503 503
 
504
-        
504
+
505
+
505 506
     else:
506 507
         if len(sys.argv)>1:
507 508
             data= sys.argv[1]

バイナリ
sources/iplayer.pyc ファイルの表示


+ 106
- 106
sources/ltc.py ファイルの表示

@@ -21,15 +21,15 @@ API_URL = 'https://m.lattelecom.tv/'
21 21
 user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3"
22 22
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
23 23
 h = HTMLParser.HTMLParser()
24
-    
24
+
25 25
 class Source(SourceBase):
26
-    
26
+
27 27
     def __init__(self):
28 28
         self.name = "ltc"
29 29
         self.title = "Shortcut.lv (lattelecom.tv)"
30 30
         self.img = "picons/shortcut.png"
31 31
         self.desc = "Shortcut.lv (lattelecom.tv) satura skatīšanās"
32
-        
32
+
33 33
         self.token = "" # manstv.lattelecom.tv
34 34
         self.session_id = ""  # www.lattelecom.tv
35 35
         self.api_url = "https://manstv.lattelecom.tv/api/v1.4/get/"
@@ -46,7 +46,7 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0
46 46
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
47 47
 Accept-Language: en-US,en;q=0.8
48 48
         """)
49
-        
49
+
50 50
         self.channels = None
51 51
         ### specific service info ###
52 52
         self.ch=[]
@@ -60,38 +60,38 @@ Accept-Language: en-US,en;q=0.8
60 60
         self.epg_date={}
61 61
         self.epg_ch={}
62 62
         self.epgdates = []
63
-        
63
+
64 64
         self.today = datetime.date.today()
65
-        self.today2 = self.today.strftime("%d.%m.%Y") 
65
+        self.today2 = self.today.strftime("%d.%m.%Y")
66 66
 
67 67
         cur_directory = os.path.dirname(os.path.abspath(__file__))
68 68
         self.config_file = os.path.join(cur_directory,self.name+".cfg")
69 69
         self.options = OrderedDict([("user","lietotajs"),("password","parole")])
70 70
         self.options_read()
71
-               
71
+
72 72
     def get_content(self, data):
73 73
         print "[ltc] get_content:", data
74 74
         if "::" in data:
75
-            data = data.split("::")[1] 
75
+            data = data.split("::")[1]
76 76
         path = data.split("?")[0]
77 77
         clist = path.split("/")[0]
78 78
         params = data[data.find("?"):] if "?" in data else ""
79 79
         qs = dict(map(lambda x:x.split("="),re.findall("\w+=[\w-]+",params)))
80 80
         #lang = qs["lang"] if "lang" in qs else self.country
81
-    
81
+
82 82
         content=[]
83 83
         content.append(("..return", "back","","Return back"))
84
-        
84
+
85 85
         if clist=="home":
86 86
             content.extend([
87 87
                 ("Search TV", "ltc::search/{0}","","Search in TV archive"),
88 88
                 ("Search Video", "ltc::meklet?q={0}","","Search in video"),
89 89
                 ("Live streams", "ltc::tiesraide","","TV live streams"),
90 90
                 ("Archive", "ltc::arhivs","","TV live archive"),
91
-                ("Video", "ltc::videonoma","","Video on demand"),             
91
+                ("Video", "ltc::videonoma","","Video on demand"),
92 92
             ])
93 93
             return content
94
-        
94
+
95 95
         ### Meklēt TV (1.4 API)
96 96
         elif clist == "search": #TODO vod/search/{q}
97 97
             #r = self.call("vod/"+data)
@@ -100,12 +100,12 @@ Accept-Language: en-US,en;q=0.8
100 100
         ### Meklēsana video (www )###
101 101
         elif clist == "meklet": #TODO vod/search/{q}
102 102
             r = self.call2(data)
103
-            
103
+
104 104
             for res in re.findall('<div class="(program follow|movie forward)-link">(.+?</div></div>.*?)</div>', r, re.DOTALL):
105 105
                 r2 = res[1]
106 106
                 if "movie" in res[0]:
107 107
                     #if not "permalink" in r2:
108
-                        #continue                    
108
+                        #continue
109 109
                     m = re.search('<a class="title" href="([^"]+)/">([^<]+)</a>', r2, re.DOTALL)
110 110
                     if not m: continue
111 111
                     title = m.group(2)
@@ -118,7 +118,7 @@ Accept-Language: en-US,en;q=0.8
118 118
                     m = re.search('class="genre".+?>([^<]+)<', r2, re.DOTALL)
119 119
                     if m:
120 120
                         desc = m.group(1)+"\n"+desc
121
-                    
121
+
122 122
                 else:
123 123
                     m = re.search('<a href="/([^"]+)" class="title">([^<]+)</a>', r2, re.DOTALL)
124 124
                     if not m: continue
@@ -140,7 +140,7 @@ Accept-Language: en-US,en;q=0.8
140 140
                     desc = title
141 141
                 content.append((title,self.name+"::"+data2,img,desc))
142 142
             return content
143
-            
143
+
144 144
         ### Tiešraides kanānālu saraksts ###
145 145
         elif data=="tiesraide":
146 146
             r = self.call2(data)
@@ -159,7 +159,7 @@ Accept-Language: en-US,en;q=0.8
159 159
                     desc = title
160 160
                 content.append((title,self.name+"::"+data2,img,desc))
161 161
             return content
162
-            
162
+
163 163
         ### TV arhīva sākums ###
164 164
         elif data=="archive" or data=="arhivs":
165 165
             #self.get_epg()
@@ -169,7 +169,7 @@ Accept-Language: en-US,en;q=0.8
169 169
                 #("Archive - dates", "ltc::archive/dates","","TV live archive by dates"),
170 170
             ])
171 171
             return content
172
-                
172
+
173 173
         ### Arhīva kategorijas
174 174
         elif data=="archive/categories":
175 175
             #https://manstv.lattelecom.tv/api/v1.3/get/archive/records/?filter[category]=13&limit=10&until_id=1458681019238
@@ -182,7 +182,7 @@ Accept-Language: en-US,en;q=0.8
182 182
                 desc = title
183 183
                 content.append((title,self.name+"::"+data2,img,desc))
184 184
             return content
185
-        
185
+
186 186
         ### Arhīva kategoriju video
187 187
         elif "archive/records" in data:
188 188
             #https://manstv.lattelecom.tv/api/v1.3/get/archive/records/?filter[category]=13&limit=10&until_id=1458681019238
@@ -203,7 +203,7 @@ Accept-Language: en-US,en;q=0.8
203 203
                     if not item["channel_id"] in self.epg_ch:
204 204
                         self.epg_ch[item["channel_id"]]=[]
205 205
                     self.epg_ch[item["channel_id"]].append(index)
206
-                item = self.get_epg_id(item["id"])                     
206
+                item = self.get_epg_id(item["id"])
207 207
                 ch = self.get_channel_by_id2(item["channel_id"])
208 208
                 ch_name = ch["name"] if ch else item["channel_id"]
209 209
                 title = u"[%s %s-%s] %s - %s"%(item["date"],item["time_start2"].strftime("%H:%M"),item["time_stop2"].strftime("%H:%M"),ch_name,item["title"])
@@ -217,7 +217,7 @@ Accept-Language: en-US,en;q=0.8
217 217
                 data2 = re.sub("until_id=\d+","until_id="+item["id"],data)
218 218
             else:
219 219
                 data2 = data + "&until_id=%s"%item["id"]
220
-            content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
220
+            content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
221 221
             return content
222 222
 
223 223
         ### Arhīva kanānālu saraksts
@@ -232,7 +232,7 @@ Accept-Language: en-US,en;q=0.8
232 232
             return content
233 233
 
234 234
         ### Arhīva kanānāla video saraksta
235
-        elif "archive/channel/" in data: 
235
+        elif "archive/channel/" in data:
236 236
             chid = path.split("/")[2]
237 237
             for item in self.get_epg_date(qs["date"],chid):
238 238
                 #if item["is_archive"]=='0':continue
@@ -251,18 +251,18 @@ Accept-Language: en-US,en;q=0.8
251 251
                 data2 = re.sub("date=[\d-]+","date="+date2,data)
252 252
             else:
253 253
                 data2 = data + "&date=%s"%date2
254
-            content.append(("Previous day (%s)"%date2,self.name+"::"+data2,"","Go previous day"))                 
254
+            content.append(("Previous day (%s)"%date2,self.name+"::"+data2,"","Go previous day"))
255 255
             return content
256
-        
257
-        ### Arhīva datumi 
256
+
257
+        ### Arhīva datumi
258 258
         elif clist=="arhivs" and len(data.split("/"))==2: # TODO - pasreiz nestrada
259 259
             ch = data.split("/")[1]
260
-            r= self.call(data)            
260
+            r= self.call(data)
261 261
             m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
262 262
             if m:
263 263
                 ch_name = m.group(1)
264 264
             else:
265
-                ch_name = ""            
265
+                ch_name = ""
266 266
             today =  datetime.date.today()
267 267
             for i in range(7):
268 268
                 date = today-datetime.timedelta(i)
@@ -277,12 +277,12 @@ Accept-Language: en-US,en;q=0.8
277 277
         elif clist=="arhivs" and len(data.split("/"))==3: # TODO - nestrādā
278 278
             ch = data.split("/")[1]
279 279
             date = data.split("/")[2]
280
-            r= self.call(data) 
280
+            r= self.call(data)
281 281
             m = re.search('class="spac no_select">([^<]+)</span>', r, re.IGNORECASE)
282 282
             if m:
283 283
                 ch_name = m.group(1)
284 284
             else:
285
-                ch_name = ""                        
285
+                ch_name = ""
286 286
             for item in re.findall('(?i)href="/([^"]+?)" id="" class="archive_programm_a"><div class="archive_programm "><div class="chanel_time"><span>([^<]+)</span></div><div class="archive_programm_one"><span>([^<]+)', r):
287 287
                 title = "%s - %s"%(item[1],item[2])
288 288
                 data2 = item[0]
@@ -290,8 +290,8 @@ Accept-Language: en-US,en;q=0.8
290 290
                 desc = "%s (%s)\n%s"%(ch_name,date,title)
291 291
                 content.append((title,self.name+"::"+data2,img,desc))
292 292
             return content
293
-                
294
-        
293
+
294
+
295 295
         ### Videonoma galvenā
296 296
         elif data=="videonoma":
297 297
             content.extend([
@@ -315,7 +315,7 @@ Accept-Language: en-US,en;q=0.8
315 315
                 ("Koncerti - pēc nosaukuma", "ltc::videonoma?page=0&genre=19&sorts=title&cnt=40&clear=true&filter={}","https://www.lattelecom.tv/images/redesign/videonoma_dropdown_koncerti.png","Koncerti pēc pēc nosaukuma"),
316 316
             ])
317 317
             return content
318
-        
318
+
319 319
         ### Videonomas saraksti
320 320
         elif path == "videonoma":
321 321
             url = "https://www.lattelecom.tv/movies-snippet.json"+params
@@ -328,19 +328,19 @@ Accept-Language: en-US,en;q=0.8
328 328
             for item in js["movies"]:
329 329
                 if not item["title"]:
330 330
                     continue
331
-                title = item["title"].encode("utf8") 
331
+                title = item["title"].encode("utf8")
332 332
                 data2 = item["url"][1:].encode("utf8")
333 333
                 if data2[-1]=="/": data2=data2[:-1]
334 334
                 if "/raidijumi/" in data2:
335 335
                     data2 += "?series"
336 336
                 img = "https://www.lattelecom.tv"+item["image"].encode("utf8")
337 337
                 desc = "%s\n%s"%(title,item["genre"].encode("utf8"))
338
-                content.append((title,self.name+"::"+data2,img,desc)) 
338
+                content.append((title,self.name+"::"+data2,img,desc))
339 339
             m = re.search("page=(\d+)",data)
340 340
             if m:
341 341
                 page = int(m.group(1))
342 342
                 data2 = re.sub("page=\d+","page=%s"%(page+1),data)
343
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
343
+                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
344 344
             return content
345 345
 
346 346
         ### Sērijas
@@ -353,7 +353,7 @@ Accept-Language: en-US,en;q=0.8
353 353
             raidijums = m.group(1) + " - " if m else ""
354 354
             m = re.search('data-bid="([^"]+)',r)
355 355
             if m:
356
-                url = "https://www.lattelecom.tv/episode-loader.json?bcast_ids=%s"%(m.group(1)) 
356
+                url = "https://www.lattelecom.tv/episode-loader.json?bcast_ids=%s"%(m.group(1))
357 357
                 r = self._http_request(url,headers=self.headers2)
358 358
                 i1 = r.find('{"total":')
359 359
                 i2 = r.find('}<div class=')
@@ -363,16 +363,16 @@ Accept-Language: en-US,en;q=0.8
363 363
                     data2 = item["url"][1:]
364 364
                     img = "https://www.lattelecom.tv"+item["img"]
365 365
                     desc = title
366
-                    content.append((title,self.name+"::"+data2,img,desc))                                     
366
+                    content.append((title,self.name+"::"+data2,img,desc))
367 367
             else:
368
-                for item in re.findall('(?si)<a class="elementxxx forward-link[^"]*" href="([^"]+)">.*?<img src="([^"]+)" class="img"><span class="titlez">([^<]+)</span><span class="epizode_number">([^<]+)</span>', r):                
368
+                for item in re.findall('(?si)<a class="elementxxx forward-link[^"]*" href="([^"]+)">.*?<img src="([^"]+)" class="img"><span class="titlez">([^<]+)</span><span class="epizode_number">([^<]+)</span>', r):
369 369
                     title = "%s%s (%s)"%(raidijums,item[2],item[3])
370 370
                     data2 = item[0][1:]
371 371
                     img = "https://www.lattelecom.tv"+item[1]
372 372
                     desc = title
373 373
                     content.append((title,self.name+"::"+data2,img,desc))
374
-            return content           
375
-            
374
+            return content
375
+
376 376
         ### Videonomas video
377 377
         elif clist=="videonoma" and len(data.split("/"))>1:
378 378
             ch = data.split("/")[1]
@@ -391,20 +391,20 @@ Accept-Language: en-US,en;q=0.8
391 391
             if m:
392 392
                 title = m.group(1)
393 393
             else:
394
-                title = ""  
394
+                title = ""
395 395
             desc = title
396 396
             content = (title,data2,"",desc)
397 397
             return content
398 398
 
399 399
         else:
400 400
             return content
401
-        
401
+
402 402
     def get_streams(self, data):
403 403
         print "[ltc] get_streams:", data
404
-        if "::" in data: data = data.split("::")[1]         
404
+        if "::" in data: data = data.split("::")[1]
405 405
         if not self.is_video(data):
406 406
             return []
407
-        
407
+
408 408
         ### Video nomas strīmus pagaidām dabu no mājas lapas TODO
409 409
         if data.split("/")[0]=="videonoma" and len(data.split("/"))>1:
410 410
             #video_id=data.split("/")[-1]
@@ -412,14 +412,14 @@ Accept-Language: en-US,en;q=0.8
412 412
         else:
413 413
             if not self.is_logedin():
414 414
                 if not self.login():
415
-                    return []   
415
+                    return []
416 416
             r = self.call(data)
417 417
             if not r: return []
418 418
             if "errors" in r:
419 419
                 return []
420 420
             self.refresh_token()
421 421
             token = "&auth_token=app_%s"%(self.token)
422
-            
422
+
423 423
             vid = data.split("/")[2].split("?")[0]
424 424
             vtype = data.split("/")[1]
425 425
             if vtype == "live-streams":
@@ -444,10 +444,10 @@ Accept-Language: en-US,en;q=0.8
444 444
                 date = epg["date"]
445 445
                 title = "%s (%s %s-%s)"%(title,date,t1,t2)
446 446
                 desc = epg["description"]
447
-    
447
+
448 448
             streams = []
449 449
             for s in r["data"]:
450
-                stream = stream0.copy()
450
+                stream = util.item()
451 451
                 stream["url"]=(s["attributes"]["stream-url"]+token.encode("utf8")).encode("utf8")
452 452
                 stream["name"]=title
453 453
                 stream["desc"]=desc
@@ -466,7 +466,7 @@ Accept-Language: en-US,en;q=0.8
466 466
             s["order"] = lv+qv
467 467
         streams = sorted(streams,key=lambda item: item["order"],reverse=True)
468 468
         return streams
469
-        
469
+
470 470
     def is_video(self,data):
471 471
         if "::" in data:
472 472
             data = data.split("::")[1]
@@ -481,7 +481,7 @@ Accept-Language: en-US,en;q=0.8
481 481
             return True
482 482
         else:
483 483
             return False
484
-    
484
+
485 485
     def get_channels(self):
486 486
         if self.ch:
487 487
             return self.ch
@@ -495,21 +495,21 @@ Accept-Language: en-US,en;q=0.8
495 495
             self.ch_id2[item["xprs_id"]]=i
496 496
             self.ch_name[item["name"]]=i
497 497
         return self.ch
498
-                
498
+
499 499
     def get_channel_by_id(self,chid):
500 500
         if not self.ch:
501 501
             self.get_channels()
502 502
         if not self.ch:
503 503
             return None
504 504
         return self.ch[self.ch_id[chid]] if self.ch_id.has_key(chid) else None
505
-    
505
+
506 506
     def get_channel_by_id2(self,chid):
507 507
         if not self.ch:
508 508
             self.get_channels()
509 509
         if not self.ch:
510 510
             return None
511 511
         return self.ch[self.ch_id2[chid]] if self.ch_id2.has_key(chid) else None
512
-    
512
+
513 513
     def get_channels2(self):
514 514
         if self.ch2:
515 515
             return self.ch2
@@ -522,7 +522,7 @@ Accept-Language: en-US,en;q=0.8
522 522
             ch["title"]=item[1]
523 523
             self.ch2.append(ch)
524 524
         return self.ch2
525
-    
525
+
526 526
     def get_channel_by_name2(self,name):
527 527
         if not self.ch2:
528 528
             self.get_channels2()
@@ -530,16 +530,16 @@ Accept-Language: en-US,en;q=0.8
530 530
             if c["name"]==name:
531 531
                 return c
532 532
         return None
533
-            
533
+
534 534
     def get_channel_by_name(self,name):
535 535
         if not self.ch:
536 536
             self.get_channels()
537 537
         ch2 = self.get_channel_by_name2(name)
538 538
         if not ch2:
539 539
             return None
540
-        ch = self.get_channel_by_id2(ch2["id2"]) 
540
+        ch = self.get_channel_by_id2(ch2["id2"])
541 541
         return ch
542
-        
542
+
543 543
     def get_epg(self,date=None,update=False):
544 544
         #https://manstv.lattelecom.tv/api/v1.3/get/tv/epg/?daynight=2016-05-19
545 545
         today=datetime.date.today()
@@ -569,10 +569,10 @@ Accept-Language: en-US,en;q=0.8
569 569
                 if not item["channel_id"] in self.epg_ch:
570 570
                     self.epg_ch[item["channel_id"]]=[]
571 571
                 self.epg_ch[item["channel_id"]].append(index)
572
-                              
572
+
573 573
         if not date in self.epgdates:
574 574
             self.epgdates.append(date)
575
-        
575
+
576 576
 
577 577
     def get_epg_id(self,epgid):
578 578
         if not self.epg:
@@ -581,7 +581,7 @@ Accept-Language: en-US,en;q=0.8
581 581
         if epgid in self.epg_id:
582 582
             return self.epg[self.epg_id[epgid]]
583 583
         return None
584
-    
584
+
585 585
     def get_epg_date(self,date,chid):
586 586
         if not date in self.epgdates:
587 587
             self.get_epg(date)
@@ -590,10 +590,10 @@ Accept-Language: en-US,en;q=0.8
590 590
         for it in self.epg_date[date]:
591 591
             item = self.epg[it]
592 592
             if item["channel_id"]==ch["xprs_id"]:
593
-                items.append(item)        
593
+                items.append(item)
594 594
         return items
595
-        
596
-        
595
+
596
+
597 597
     def call(self, data,params = None, headers=None):
598 598
         if not headers: headers = self.headers
599 599
         #if not lang: lang = self.country
@@ -607,7 +607,7 @@ Accept-Language: en-US,en;q=0.8
607 607
                 return None
608 608
         else:
609 609
             return None
610
-        
610
+
611 611
     def call2(self, data,params = None, headers=None):
612 612
         if not headers: headers = self.headers2
613 613
         #if not lang: lang = self.country
@@ -628,10 +628,10 @@ Accept-Language: en-US,en;q=0.8
628 628
 
629 629
     def login(self,user="",password=""):
630 630
         """Login in to site, get token"""
631
-        self.options_read()        
631
+        self.options_read()
632 632
         if not user: user=self.options["user"]
633 633
         if not password: password = self.options["password"]
634
-        
634
+
635 635
         # Dabūjam tokenu
636 636
         url = "https://manstv.lattelecom.tv/api/v1.3/post/user/login"
637 637
         params = "uid=7f777e938d35e017&password=%s&username=%s&"%(password,user)
@@ -639,7 +639,7 @@ Accept-Language: en-US,en;q=0.8
639 639
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
640 640
 User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.4.2; SM-G900FD Build/KOT49H)
641 641
 Host: manstv.lattelecom.tv
642
-""" )    
642
+""" )
643 643
         try:
644 644
             r = urllib2.Request(url, data=params, headers=headers)
645 645
             u = urllib2.urlopen(r)
@@ -653,7 +653,7 @@ Host: manstv.lattelecom.tv
653 653
             return True
654 654
         else:
655 655
             return False
656
-        
656
+
657 657
     def refresh_token(self):
658 658
         data = "user/refresh-token//%s"%self.token
659 659
         r = self.call(data)
@@ -663,7 +663,7 @@ Host: manstv.lattelecom.tv
663 663
         else:
664 664
             self.token = ""
665 665
             return False
666
-    
666
+
667 667
     def check_logedin(self):
668 668
         if not self.token:
669 669
             return False
@@ -672,18 +672,18 @@ Host: manstv.lattelecom.tv
672 672
                 return True
673 673
             else:
674 674
                 return False
675
-        
675
+
676 676
     def is_logedin(self):
677 677
         if self.token:
678 678
             return True
679 679
         else:
680 680
             return False
681
-                 
681
+
682 682
     #----------------------------------------------------------------------
683 683
     def get_tv_url(self,video_id):
684 684
         """Get m3u8 url for given live tv channel"""
685 685
         url = "https://m.lattelecom.tv/tiesraide/%s"%video_id
686
-        data = self.get_stream_url2("tiesraide/%s"%video_id)        
686
+        data = self.get_stream_url2("tiesraide/%s"%video_id)
687 687
         #headers = self.headers
688 688
         #headers["Cookie"] = "%s; %s; _hjIncludedInSample=0; MobBitr=1; MobRentBitr=%s; MobRentLang=%s;"%(self.session_id,self.mobtv_cache,data["quality"],data["language"])
689 689
         #response = urllib2.urlopen(urllib2.Request(url, headers=headers))
@@ -702,11 +702,11 @@ Host: manstv.lattelecom.tv
702 702
         #response = urllib2.urlopen(urllib2.Request(url, headers=headers))
703 703
         #m3u8 = response.read()
704 704
         return data["stream"] if data else None
705
-        
705
+
706 706
     #----------------------------------------------------------------------
707 707
     def get_arhivs_url(self,video_id):
708 708
         """Get m3u8 url for given archive video"""
709
-        data = self.get_video_data(video_id)                
709
+        data = self.get_video_data(video_id)
710 710
         #url = "https://m.lattelecom.tv/free_origin?show_origin=1&type=arhivs&event_id=%s&bitrate=mhq"%(video_id) #,data["quality"])
711 711
         #headers = self.headers
712 712
         #headers["Cookie"] = "%s; %s; MobBitr=1; "%(self.session_id,self.mobtv_cache)
@@ -727,7 +727,7 @@ Host: manstv.lattelecom.tv
727 727
             return None
728 728
         if not self.is_logedin():
729 729
             if not self.login():
730
-                return None       
730
+                return None
731 731
         r = self.call(data)
732 732
         if not r:
733 733
             return None
@@ -741,9 +741,9 @@ Host: manstv.lattelecom.tv
741 741
                 s["stream"] += token
742 742
                 hls["streams"].append(s)
743 743
         return hls
744
-            
744
+
745 745
     def get_stream_url2(self,data):
746
-        video_id=data[data.find("/")+1:]        
746
+        video_id=data[data.find("/")+1:]
747 747
         if not self.is_logedin2():
748 748
             if not self.login2():
749 749
                 return []
@@ -753,14 +753,14 @@ Host: manstv.lattelecom.tv
753 753
         if m:
754 754
             title = m.group(1)
755 755
         else:
756
-            title = ""  
756
+            title = ""
757 757
         desc = title
758
-          
758
+
759 759
         url = "https://www.lattelecom.tv/xmls/%s.xml"%video_id
760 760
         headers = self.headers2
761 761
         headers["Cookie"] = self.session_id
762 762
         response = urllib2.urlopen(urllib2.Request(url, headers=headers))
763
-        
763
+
764 764
         r = response.read()
765 765
         servers = re.findall("(?s)<origin>([^<]+)</origin>", r)
766 766
         streams_xml = re.findall('<stream quality="\w+">(mp4:\w+_(\w\w)_(\w\w).mp4)</stream>',r)
@@ -775,13 +775,13 @@ Host: manstv.lattelecom.tv
775 775
             sub["lang"] = s[0]
776 776
             sub["name"] = "captions (vtt)"
777 777
             sub["type"] = "vtt"
778
-            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0            
779
-            captions.append(sub)       
780
-        captions = sorted(captions,key=lambda item: item["order"],reverse=True)      
778
+            sub["order"] = llist.index(sub["lang"])*10 if sub["lang"] in llist else 0
779
+            captions.append(sub)
780
+        captions = sorted(captions,key=lambda item: item["order"],reverse=True)
781 781
         for s in streams_xml:
782
-            for server in servers: 
782
+            for server in servers:
783 783
                 server2 = self.load_balancer(server)
784
-                url = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(server2,s[0],resource_id,token) 
784
+                url = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(server2,s[0],resource_id,token)
785 785
                 stream = util.item()
786 786
                 stream["url"]=url
787 787
                 stream["lang"]=s[1]
@@ -792,15 +792,15 @@ Host: manstv.lattelecom.tv
792 792
                 stream["subs"] = []
793 793
                 for c in captions:
794 794
                     c2= c.copy()
795
-                    #c2["url"] ="http://%s/mobile-vod/%s/%s?resource_id=%s&auth_token=%s"%(server2,s[0],c["url"],resource_id,token) 
796
-                    c2["url"] ="http://%s/mobile-vod/%s/%s"%(server2,s[0],c["url"]) 
795
+                    #c2["url"] ="http://%s/mobile-vod/%s/%s?resource_id=%s&auth_token=%s"%(server2,s[0],c["url"],resource_id,token)
796
+                    c2["url"] ="http://%s/mobile-vod/%s/%s"%(server2,s[0],c["url"])
797 797
                     stream["subs"].append(c2)
798 798
                     pass
799
-                streams.append(stream)        
799
+                streams.append(stream)
800 800
                 break # TODO ņem tikai pirmo serveri, varētu pārbaudit, kurš no tiem strādā, kurš ne
801 801
 
802 802
         return streams
803
-        
803
+
804 804
         #data = {}
805 805
         #data["server"] = re.findall("(?s)<origin>([^<]+)</origin>", r)[1]
806 806
         #data["language"]=re.findall('(?s)<language code="([^"]+)">', r)
@@ -809,12 +809,12 @@ Host: manstv.lattelecom.tv
809 809
         #data["qs"]=dict(data["qs"])
810 810
         #qs = data["qs"].keys()
811 811
         #data["quality"] = "hd" if "hd" in qs else "hq" if "hq" in qs else "mhq" if "mhq" in qs else "lq"
812
-        #data["mp4"] = data["qs"][data["quality"]]        
812
+        #data["mp4"] = data["qs"][data["quality"]]
813 813
         #data["token"] = re.search("(?s)<auth_token>([^<]+)</auth_token>", r).group(1)
814 814
         #data["resource_id"]=re.search("(?s)<resource_id>([^<]+)</resource_id>", r).group(1)
815 815
         #data["server"]=self.load_balancer(data["server"])
816
-        #data["hls"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"]) 
817
-        ##data["hls"]="http://%s/mobile-vod/mp4:%s/playlist.m3u8?resource_id=%s&auth_token=app_%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])  
816
+        #data["hls"] = "http://%s/mobile-vod/%s/playlist.m3u8?resource_id=%s&auth_token=%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
817
+        ##data["hls"]="http://%s/mobile-vod/mp4:%s/playlist.m3u8?resource_id=%s&auth_token=app_%s"%(data["server"],data["mp4"],data["resource_id"],data["token"])
818 818
 
819 819
     ### wwww.lattelecom.tv izsaukumi
820 820
     def login2(self,user="",password=""):
@@ -905,10 +905,10 @@ Referer: https://www.lattelecom.tv/
905 905
             err = re.search('"error":"(.+?)"').group(1) if re.search('"error":"(.+?)"') else ""
906 906
             raise Exception(u"Kļūda ielogojoties - %s"%err)
907 907
         self.session_id = session_id
908
-        self.headers2["Cookie"] = "%s; "%(self.session_id)    
908
+        self.headers2["Cookie"] = "%s; "%(self.session_id)
909 909
         self.error = ""
910 910
         return True
911
-    
911
+
912 912
     def check_logedin2(self):
913 913
         if not self.session_id:
914 914
             return False
@@ -920,13 +920,13 @@ Referer: https://www.lattelecom.tv/
920 920
             else:
921 921
                 self.session_id = ""
922 922
                 return False
923
-        
923
+
924 924
     def is_logedin2(self):
925 925
         if self.session_id:
926 926
             return True
927 927
         else:
928 928
             return False
929
-    
929
+
930 930
     def load_balancer(self,server,streams=[]):
931 931
         headers = headers2dict("""
932 932
 Connection: keep-alive
@@ -950,7 +950,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
950 950
         except Exception as ex:
951 951
             print "hls failed: %s %s"%(ex.getcode(),url)
952 952
             return False
953
-        
953
+
954 954
         if response.code == 200:
955 955
             html = response.read()
956 956
             url0 = re.search("(http://[^/]+/)",url).group(1)
@@ -960,7 +960,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
960 960
             try:
961 961
                 response2 = urllib2.urlopen(urllib2.Request(url2, headers=headers))
962 962
             except Exception as ex:
963
-                print "hls chunk failed: %s %s"%(ex.getcode(),url2)                
963
+                print "hls chunk failed: %s %s"%(ex.getcode(),url2)
964 964
                 return False
965 965
             if response2.code == 200:
966 966
                 return True
@@ -968,15 +968,15 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
968 968
                 return False
969 969
         else:
970 970
             return False
971
-    
971
+
972 972
 if __name__ == "__main__":
973 973
     c = Source()
974 974
     from subprocess import call
975
-    
975
+
976 976
     if len(sys.argv)>1 and  not "ltc::" in sys.argv[1]:
977
-        
977
+
978 978
         vid = sys.argv[1]
979
-        print "login - %s"%c.login("ivars777","xxx")        
979
+        print "login - %s"%c.login("ivars777","xxx")
980 980
         vid = "1069"
981 981
         vid = "1462566072086"
982 982
         channelid="101"
@@ -984,19 +984,19 @@ if __name__ == "__main__":
984 984
         #data = c.get_stream_url(vid,"vod")
985 985
         #call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
986 986
         pass
987
- 
988
-        print "login2 - %s"%c.login2("ivars777","xxx")         
987
+
988
+        print "login2 - %s"%c.login2("ivars777","xxx")
989 989
         #vid2 = "animation/ultimate_avengers_ii"
990 990
         #vid2 = "animation/ice_age"
991 991
         vid2 = "tiesraide/ltv1"
992 992
         #vid2 = "arhivs/1456521417815"
993 993
         data = c.get_stream_url2(vid2)
994
-        print data        
994
+        print data
995 995
         #for s in data:
996 996
         call([r"c:\Program Files\VideoLAN\VLC\vlc.exe",data["stream"]])
997 997
         pass
998 998
 
999
-        
999
+
1000 1000
     else:
1001 1001
         if len(sys.argv)>1:
1002 1002
             data= sys.argv[1]

バイナリ
sources/ltc.pyc ファイルの表示


バイナリ
sources/movieplace.pyc ファイルの表示


+ 35
- 35
sources/serialguru.py ファイルの表示

@@ -18,9 +18,9 @@ from SourceBase import SourceBase
18 18
 headers2dict = lambda  h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
19 19
 import HTMLParser
20 20
 h = HTMLParser.HTMLParser()
21
-    
21
+
22 22
 class Source(SourceBase):
23
-    
23
+
24 24
     def __init__(self,country=""):
25 25
         self.name = "serialguru"
26 26
         self.title = "SerialGURU.ru"
@@ -29,88 +29,88 @@ class Source(SourceBase):
29 29
         self.country=country
30 30
         self.headers = headers2dict("""
31 31
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
32
-Referer: http://serialguru.ru/        
32
+Referer: http://serialguru.ru/
33 33
 """)
34 34
         self.headers2 = headers2dict("""
35 35
 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36
36 36
 X-Requested-With: XMLHttpRequest
37 37
 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
38
-Referer: http://serialguru.ru/        
38
+Referer: http://serialguru.ru/
39 39
 """)
40 40
         self.url = "http://serialguru.ru/"
41 41
         #self.login()
42
-        
42
+
43 43
     def login(self,user="",password=""):
44 44
         return True
45
-            
45
+
46 46
     def get_content(self, data):
47 47
         print "[tvdom] get_content:", data
48 48
         if "::" in data:
49
-            data = data.split("::")[1] 
49
+            data = data.split("::")[1]
50 50
         path = data.split("?")[0]
51 51
         clist = path.split("/")[0]
52 52
         params = data[data.find("?"):] if "?" in data else ""
53 53
         qs = dict(map(lambda x:x.split("="),re.findall("[%\w]+=\w+",params)))
54 54
         lang = qs["lang"] if "lang" in qs else self.country
55
-    
55
+
56 56
         content=[]
57 57
         content.append(("..return", "back","","Return back"))
58
-        
58
+
59 59
         if clist=="home":
60 60
             content.extend([
61
-                ("Search", "serialguru::search/{0}","","Search content"),                
62
-                ("Last", "serialguru::last","","Last series"),                
61
+                ("Search", "serialguru::search/{0}","","Search content"),
62
+                ("Last", "serialguru::last","","Last series"),
63 63
                 ("Series", "serialguru::serials","","TV Series"),
64 64
                 ("Shows", "serialguru::tv","","TV Shows"),
65 65
                 ("Animations", "serialguru::mult","","Animation series"),
66
-                
66
+
67 67
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
68 68
             ])
69 69
             return content
70
-    
71
-        elif data=="last":
70
+
71
+        elif data == "last":
72 72
             r = self.call("")
73 73
             for item in re.findall(r'<li><a href="(http://serialguru\.ru/[^"]+)"><i>([^<]+)</i>  <i>([^<]+)</i> <b>([^<]+)</b></a></li>', r, re.DOTALL):
74 74
                 title = item[1] + " - " + item[2]+"/"+item[3]
75 75
                 img = ""
76
-                data2 = item[0].replace(self.url,"")
76
+                data2 = item[0].replace(self.url, "")
77 77
                 desc = title
78
-                content.append((title,self.name+"::"+data2,img,desc))
78
+                content.append((title, self.name+"::"+data2, img, desc))
79 79
             return content
80 80
 
81 81
         elif data=="serials":
82 82
             content.extend([
83
-                ("All", "serialguru::serials?o=0&t=S","","All series"),                
84
-                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),                
83
+                ("All", "serialguru::serials?o=0&t=S","","All series"),
84
+                ("Russian", "serialguru::serials?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=S","","Russian countries series"),
85 85
                 ("English", "serialguru::serials?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=S","","English countries series"),
86 86
                 ("Europe", "serialguru::serials?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=S","","European countries series"),
87 87
                 ("Other", "serialguru::serials?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=S","","Other countries series"),
88 88
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
89 89
             ])
90 90
             return content
91
-        
91
+
92 92
         elif data=="tv":
93 93
             content.extend([
94
-                ("All", "serialguru::tv?o=0&t=S","","All series"),                
95
-                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),                
94
+                ("All", "serialguru::tv?o=0&t=S","","All series"),
95
+                ("Russian", "serialguru::tv?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=P","","Russian countries TV shows"),
96 96
                 ("English", "serialguru::tv?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=P","","English countries TV shows"),
97 97
                 ("Europe", "serialguru::tv?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=P","","European countries TV shows series"),
98 98
                 ("Other", "serialguru::tv?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=P","","Other countries TV shows"),
99 99
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
100 100
             ])
101 101
             return content
102
-        
102
+
103 103
         elif data=="mult":
104 104
             content.extend([
105
-                ("All", "serialguru::mult?o=0&t=S","","All series"),                
106
-                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),                
105
+                ("All", "serialguru::mult?o=0&t=S","","All series"),
106
+                ("Russian", "serialguru::mult?c%5B%5D=53&c%5B%5D=61&c%5B%5D=33&c%5B%5D=42&c%5B%5D=31&o=0&t=M","","Russian countries animantions"),
107 107
                 ("English", "serialguru::mult?c%5B%5D=27&c%5B%5D=26&c%5B%5D=43&c%5B%5D=30&c%5B%5D=34&c%5B%5D=25&o=0&t=M","","English countries animantions"),
108 108
                 ("Europe", "serialguru::mult?c%5B%5D=29&c%5B%5D=66&c%5B%5D=44&c%5B%5D=28&c%5B%5D=51&c%5B%5D=65&c%5B%5D=62&c%5B%5D=40&c%5B%5D=45&c%5B%5D=68&c%5B%5D=59&c%5B%5D=39&c%5B%5D=35&c%5B%5D=47&o=0&t=M","","European countries animantions"),
109 109
                 ("Other", "serialguru::mult?c%5B%5D=36&c%5B%5D=32&c%5B%5D=67&c%5B%5D=63&c%5B%5D=60&c%5B%5D=64&c%5B%5D=38&c%5B%5D=52&c%5B%5D=41&c%5B%5D=58&c%5B%5D=57&c%5B%5D=37&c%5B%5D=50&c%5B%5D=46&o=0&t=M","","Other countries animantions"),
110 110
                 #("Archive - all", "tvdom::arhivs_all","","Video archive all"),
111 111
             ])
112 112
             return content
113
-        
113
+
114 114
         elif clist=="search":
115 115
             if data.split("/")>1:
116 116
                 term = data.split("/")[1]
@@ -128,7 +128,7 @@ Referer: http://serialguru.ru/
128 128
                 desc = title +"\nRating:%s (%s+/%s-)"%(rating,item["plus_cnt"].encode("utf8"),item["minus_cnt"].encode("utf8"))
129 129
                 content.append((title,self.name+"::"+data2,img,desc))
130 130
             return content
131
-                        
131
+
132 132
         elif path=="serials" or path=="tv" or path=="mult":
133 133
             if path=="serials" and not "cat%5B%5D" in data:
134 134
                 #content.append(("All", "serialguru::"+data+"&cat%5B%5D=","","All series"))
@@ -146,11 +146,11 @@ Referer: http://serialguru.ru/
146 146
                     content.append((title,self.name+"::"+data2,img,desc))
147 147
                 page=int(re.search("o=(\d+)",data).group(1))
148 148
                 data2 = re.sub("o=(\d+)","o=%s"%(page+15),data)
149
-                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))                 
149
+                content.append(("Next page",self.name+"::"+data2,"","Go to next page"))
150 150
                 return content
151
-        
152
-        
153
-        ### Pārraide  
151
+
152
+
153
+        ### Pārraide
154 154
         else:
155 155
             r = self.call(clist)
156 156
             title0=re.search('<h2>(.+?)</h2>',r,re.DOTALL).group(1)
@@ -181,10 +181,10 @@ Referer: http://serialguru.ru/
181 181
                     img = img0
182 182
                     data2 = item["file"].encode("utf8")
183 183
                     desc = desc0
184
-                    content.append((title,data2,img,desc))               
184
+                    content.append((title,data2,img,desc))
185 185
             return content
186
- 
187
-            
186
+
187
+
188 188
     def is_video(self,data):
189 189
         if "::" in data:
190 190
             data = data.split("::")[1]
@@ -192,14 +192,14 @@ Referer: http://serialguru.ru/
192 192
             return True
193 193
         else:
194 194
             return False
195
-    
195
+
196 196
     def get_categories(self,data):
197 197
         r = self.call(data)
198 198
         r2 = re.search('<td class="category">(.+?)</td>', r, re.DOTALL).group(1)
199 199
         items = re.findall(r'<a href="#" data-id="(\d+)">([^<]+)</a>', r2, re.DOTALL)
200 200
         return items
201 201
 
202
-        
202
+
203 203
     def call(self, data,params = None, headers=None):
204 204
         if not headers: headers = self.headers
205 205
         #if not lang: lang = self.country

バイナリ
sources/serialguru.pyc ファイルの表示