Ivars 5 년 전
부모
커밋
efd8f2f2f7
4개의 변경된 파일242개의 추가작업 그리고 212개의 파일을 삭제
  1. 1
    1
      addon.xml
  2. 90
    39
      kmake.bat
  3. 44
    72
      project.wpr
  4. 107
    100
      wingdbstub.py

+ 1
- 1
addon.xml 파일 보기

@@ -1,5 +1,5 @@
1 1
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
-<addon version="0.1.15" id="plugin.image.photostation" name="PhotoStation" provider-name="ivars777"  >
2
+<addon version="0.1.16" id="plugin.image.photostation" name="PhotoStation" provider-name="ivars777"  >
3 3
   <requires>
4 4
     <import addon="xbmc.python" version="2.1.0"/>
5 5
     <import addon="script.module.requests" />

+ 90
- 39
kmake.bat 파일 보기

@@ -1,43 +1,47 @@
1 1
 @echo off
2
-:=== Parameters ===
3
-
4
-:--- Pull content submodule ---
5
-rem pushd resources\lib\content
6
-rem git checkout .
7
-rem git pull
8
-rem popd
9 2
 
10
-python get_version.py addon.xml >version.txt
3
+:=== Parameters ===
4
+python -c "import re,sys; print re.search('<addon.+?version=""([^""]+)""',open('addon.xml').read()).group(1)" >version.txt
11 5
 set /p ver=<version.txt
12
-echo %ver%
6
+python -c "import re,sys; print re.search('<addon.+?id=""([^""]+)""',open('addon.xml').read()).group(1)" >id.txt
7
+set /p pack_name=<id.txt
8
+echo %pack_name% %ver%
13 9
 pause
14 10
 
15
-set prog=PhotoStation
16
-set pack_name=plugin.image.photostation
17
-set desc=Play Synology PhotoStation media
18
-
19
-set ipk_dir=ipkg\
20 11
 set release_dir=release\
21
-set repo_dir=..\repo\
22
-set feed_dir=q:\web\repo\
12
+set repo_dir=q:\web\repo\
13
+:set feed_dir=q:\web\repo\
23 14
 
24 15
 set AR=\MinGW\bin\ar.exe
25 16
 set TAR=\MinGW\msys\1.0\bin\tar.exe
17
+set CP=\MinGW\msys\1.0\bin\cp.exe
18
+set ZIP=
26 19
 rem set ZIP=\Program Files (x86)\Gow\bin\zip.exe
27 20
 
28
-:=== data files ===
21
+
22
+:=== Pull content submodule ===
23
+pushd resources\lib\content
24
+git commit -a -m labojumi
25
+git checkout .
26
+git pull
27
+popd
28
+
29
+
30
+:=== Create package zip file ===
29 31
 if exist "%pack_name%" rm -r -f "%pack_name%"
30 32
 mkdir "%pack_name%""
31 33
 if not exist %release_dir% mkdir %release_dir%
32
-if not exist %repo_dir% mkdir %repo_dir%
33
-if not exist  %repo_dir%%pack_name% mkdir  %repo_dir%%pack_name%
34
-if not exist  %pack_name% mkdir %pack_name%
34
+echo Copying files to %pack_name%
35 35
 
36 36
 for %%f in (
37 37
 readme.md
38 38
 changelog.md
39 39
 addon.xml
40 40
 addon.py
41
+context_menu.py
42
+context_download.py
43
+downloadqueue.py
44
+service.py
41 45
 icon.png
42 46
 kodiswift\*.py
43 47
 resources\__init__.py
@@ -45,31 +49,78 @@ resources\settings.xml
45 49
 resources\icon.png
46 50
 resources\language\English\*
47 51
 resources\lib\__init__.py
48
-resources\lib\photostation_api.py
52
+resources\lib\content\__init__.py
53
+resources\lib\content\ContentSources.py
54
+resources\lib\content\playstreamproxy.py
55
+resources\lib\content\Downloader.py
56
+resources\lib\content\resolver.py
57
+resources\lib\content\util.py
58
+resources\lib\content\run.py
59
+resources\lib\content\file.py
60
+resources\lib\content\demjson.py
61
+resources\lib\content\ordereddict.py
62
+resources\lib\content\sources\__init__.py
63
+resources\lib\content\sources\SourceBase.py
64
+resources\lib\content\sources\cinemalive.py
65
+resources\lib\content\sources\config.py
66
+resources\lib\content\sources\euronews.py
67
+resources\lib\content\sources\filmix.py
68
+resources\lib\content\sources\filmon.py
69
+resources\lib\content\sources\iplayer.py
70
+resources\lib\content\sources\movieplace.py
71
+resources\lib\content\sources\ltc.py
72
+resources\lib\content\sources\mtgplay.py
73
+resources\lib\content\sources\xtv.py
74
+resources\lib\content\sources\replay.py
75
+resources\lib\content\sources\lmt.py
76
+resources\lib\content\sources\serialguru.py
77
+resources\lib\content\sources\tvdom.py
78
+resources\lib\content\sources\ustvnow.py
79
+resources\lib\content\sources\viaplay.py
80
+resources\lib\content\sources\filmas.py
81
+resources\lib\content\sources\tvplay.py
82
+resources\lib\content\sources\enigma2.py
83
+resources\lib\content\sources\YouTubeVideoUrl.py
84
+resources\lib\content\sources\jsinterp.py
85
+resources\lib\content\sources\swfinterp.py
86
+resources\lib\content\sources\streams.cfg
87
+resources\lib\content\resolvers\__init__.py
88
+resources\lib\content\resolvers\aadecode.py
89
+resources\lib\content\resolvers\hqqresolver.py
90
+resources\lib\content\resolvers\openload3.py
91
+resources\lib\content\resolvers\hdgo.py
92
+resources\lib\content\resolvers\kapnob.py
93
+resources\lib\content\resolvers\kodik.py
94
+resources\lib\content\resolvers\cloudsany.py
95
+resources\lib\content\resolvers\youtuberesolver.py
49 96
 ) do echo f| xcopy %%f %pack_name%\%%f
50 97
 
98
+xcopy /y /q resources\lib\content\picons\* %pack_name%\resources\picons\
99
+
100
+echo Creating %release_dir%%pack_name%-%ver%.zip
51 101
 if exist  %release_dir%%pack_name%-%ver%.zip rm %release_dir%%pack_name%-%ver%.zip
52
-rem zip  -r %release_dir%%pack_name%-%ver%.zip %pack_name%
53
-"C:\Program Files\WinRAR\winrar.exe" a -afzip -r %release_dir%%pack_name%-%ver%.zip %pack_name%
54
-copy  addon.xml  %repo_dir%%pack_name%\addon.xml /Y
55
-copy  %release_dir%%pack_name%-%ver%.zip  %repo_dir%%pack_name%\%pack_name%-%ver%.zip /Y
56
-python -c "import hashlib; print hashlib.md5(open(r'%repo_dir%%pack_name%\%pack_name%-%ver%.zip','r').read()).hexdigest()" >%repo_dir%%pack_name%\%pack_name%-%ver%.zip.md5
102
+7za a -r -tzip -bb0 -bsp1 -bso0 %release_dir%%pack_name%-%ver%.zip %pack_name%
103
+if exist %pack_name% rm -r -f %pack_name%
57 104
 
105
+if ()==(%1%) (
106
+    GOTO :EOF
107
+)
108
+:=== Add to git ===
109
+echo Adding to git
58 110
 git add %release_dir%%pack_name%-%ver%.zip
59
-rm -r -f "%pack_name%"
111
+git commit -m %ver%
112
+git tag -d %ver%
113
+git tag %ver%
114
+git push
60 115
 
61
-if not ()==(%1%) (
62
-    git commit -m %ver%
63
-    git tag -d "%ver%"
64
-    git tag %ver%
65
-    git push
66 116
 
67
-    pushd  %repo_dir%..
68
-    call update_repo.bat
69
-    rem xcopy /s /y /u repo %feed_dir%
70
-    robocopy repo %feed_dir%  addons.* /copy:dat
71
-    robocopy repo\%pack_name% q:\web\repo\%pack_name% /copy:DAT /xo
72
-    popd
117
+:=== Copy package to repo ===
118
+echo Copying  %release_dir%%pack_name%-%ver%.zip to %repo_dir%%pack_name%
119
+if not exist %repo_dir% mkdir %repo_dir%
120
+if not exist  %repo_dir%%pack_name% mkdir  %repo_dir%%pack_name%
121
+cp  addon.xml  %repo_dir%%pack_name%\addon.xml -fpv
122
+cp  %release_dir%%pack_name%-%ver%.zip  %repo_dir%%pack_name%\%pack_name%-%ver%.zip -fpv
123
+python -c "import hashlib; print hashlib.md5(open(r'%repo_dir%%pack_name%\%pack_name%-%ver%.zip','r').read()).hexdigest()" >%repo_dir%%pack_name%\%pack_name%-%ver%.zip.md5
124
+python ..\generate_repo.py %repo_dir%
73 125
 )
74
-pause
75 126
 

+ 44
- 72
project.wpr 파일 보기

@@ -52,27 +52,7 @@ proj.launch-config = {loc('../../../../Python27/Lib/site-packages/xbmcswift2/plu
52 52
                                        (u'run interactive',
53 53
         ''))}
54 54
 [user attributes]
55
-debug.breakpoints = {loc('addon.py'): {15L: (0,
56
-        None,
57
-        1,
58
-        0),
59
-                                       131L: (0,
60
-        None,
61
-        1,
62
-        0),
63
-                                       140L: (0,
64
-        None,
65
-        1,
66
-        0),
67
-                                       185L: (0,
68
-        None,
69
-        1,
70
-        0),
71
-                                       302L: (0,
72
-        None,
73
-        1,
74
-        0),
75
-                                       307L: (0,
55
+debug.breakpoints = {loc('addon.py'): {185L: (0,
76 56
         None,
77 57
         1,
78 58
         0)},
@@ -204,7 +184,7 @@ debug.var-col-widths = [0.5823244552058111,
204 184
 guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
205 185
                             'windows': [{'name': 'F8FpRDICw7YHXG3HV2rBc63asU'\
206 186
         'LBT7JH',
207
-        'size-state': '',
187
+        'size-state': 'maximized',
208 188
         'type': 'dock',
209 189
         'view': {'area': 'tall',
210 190
                  'constraint': None,
@@ -220,7 +200,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
220 200
                                {'tree-state': {'file-sort-method': 'by name',
221 201
         'list-files-first': 0,
222 202
         'tree-states': {'deep': {'expanded-nodes': [(0,),
223
-        (7,)],
203
+        (15,)],
224 204
                                  'selected-nodes': [],
225 205
                                  'top-node': (0,)}},
226 206
         'tree-style': 'deep'}}),
@@ -627,18 +607,18 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
627 607
         'top-node': [('generic attribute',
628 608
                       loc('../../../Python27/Lib/site-packages/win32com/client/dynamic.py'),
629 609
                       'ALL_INVOKE_TYPES')]},
630
-        loc('unknown:<untitled> #3'): {'expanded-nodes': [],
610
+        loc('unknown:<untitled> #5'): {'expanded-nodes': [],
631 611
                                        'selected-nodes': [],
632 612
                                        'top-node': None},
633 613
         loc('unknown:<untitled> #4'): {'column-widths': [1.0],
634 614
                                        'expanded-nodes': [],
635 615
                                        'selected-nodes': [],
636 616
                                        'top-node': None},
637
-        loc('unknown:<untitled> #6'): {'column-widths': [1.0],
617
+        loc('unknown:<untitled> #3'): {'column-widths': [1.0],
638 618
                                        'expanded-nodes': [],
639 619
                                        'selected-nodes': [],
640 620
                                        'top-node': None},
641
-        loc('unknown:<untitled> #5'): {'expanded-nodes': [],
621
+        loc('unknown:<untitled> #6'): {'expanded-nodes': [],
642 622
                                        'selected-nodes': [],
643 623
                                        'top-node': None}},
644 624
                                 'browse_mode': u'Current Module',
@@ -694,7 +674,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
694 674
                                        'fInterpretBackslashes': False,
695 675
                                        'fMatchCase': False,
696 676
                                        'fOmitBinary': True,
697
-                                       'fRegexFlags': 46,
677
+                                       'fRegexFlags': 42,
698 678
                                        'fReplaceText': '',
699 679
                                        'fReverse': False,
700 680
                                        'fSearchText': u'page',
@@ -723,7 +703,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
723 703
                                        'fInterpretBackslashes': False,
724 704
                                        'fMatchCase': False,
725 705
                                        'fOmitBinary': True,
726
-                                       'fRegexFlags': 46,
706
+                                       'fRegexFlags': 42,
727 707
                                        'fReplaceText': '',
728 708
                                        'fReverse': False,
729 709
                                        'fSearchText': u'(o',
@@ -767,21 +747,14 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
767 747
         -1,
768 748
         -1),
769 749
                        'attrib-starts': [],
770
-                       'first-line': 22L,
750
+                       'first-line': 0L,
771 751
                        'folded-linenos': [],
772
-                       'history': {None: ['plugin.request\n',
773
-        'plugin.request.url\n',
774
-        'plugin.request.path\n',
775
-        'plugin.request.query_string\n',
776
-        'sys.argv\n',
777
-        'sys.argv[0]\n',
778
-        'sys.argv[2]\n',
779
-        'len(sys.argv)\n']},
752
+                       'history': {None: ['data2\n']},
780 753
                        'launch-id': None,
781
-                       'sel-line': 31L,
782
-                       'sel-line-start': 866L,
783
-                       'selection_end': 866L,
784
-                       'selection_start': 866L,
754
+                       'sel-line': 2L,
755
+                       'sel-line-start': 224L,
756
+                       'selection_end': 224L,
757
+                       'selection_start': 224L,
785 758
                        'zoom': 0L}),
786 759
                      ('debug-watch',
787 760
                       'wide',
@@ -815,9 +788,9 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
815 788
                        'history': {},
816 789
                        'launch-id': None,
817 790
                        'sel-line': 2L,
818
-                       'sel-line-start': 174L,
819
-                       'selection_end': 174L,
820
-                       'selection_start': 174L,
791
+                       'sel-line-start': 163L,
792
+                       'selection_end': 163L,
793
+                       'selection_start': 163L,
821 794
                        'zoom': 0L}),
822 795
                      ('debug-modules',
823 796
                       'wide',
@@ -833,17 +806,6 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
833 806
         1.0,
834 807
         ({'bookmarks': ([[loc('addon.py'),
835 808
                           {'attrib-starts': [('main',
836
-        37)],
837
-                           'first-line': 43L,
838
-                           'folded-linenos': [228L],
839
-                           'sel-line': 52L,
840
-                           'sel-line-start': 1782L,
841
-                           'selection_end': 1798L,
842
-                           'selection_start': 1794L,
843
-                           'zoom': 0L},
844
-                          1531953967.139],
845
-                         [loc('addon.py'),
846
-                          {'attrib-starts': [('main',
847 809
         37)],
848 810
                            'first-line': 43L,
849 811
                            'folded-linenos': [228L],
@@ -1056,9 +1018,19 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1056 1018
                            'selection_end': 384L,
1057 1019
                            'selection_start': 384L,
1058 1020
                            'zoom': 0L},
1059
-                          1531954540.55]],
1021
+                          1531954540.55],
1022
+                         [loc('addon.xml'),
1023
+                          {'attrib-starts': [],
1024
+                           'first-line': 0L,
1025
+                           'folded-linenos': [],
1026
+                           'sel-line': 1L,
1027
+                           'sel-line-start': 57L,
1028
+                           'selection_end': 79L,
1029
+                           'selection_start': 79L,
1030
+                           'zoom': 0L},
1031
+                          1549828587.4]],
1060 1032
                         20),
1061
-          'current-loc': loc('addon.xml'),
1033
+          'current-loc': loc('addon.py'),
1062 1034
           'editor-state-list': [(loc('addon.xml'),
1063 1035
                                  {'attrib-starts': [],
1064 1036
                                   'first-line': 0L,
@@ -1069,13 +1041,14 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1069 1041
                                   'selection_start': 79L,
1070 1042
                                   'zoom': 0L}),
1071 1043
                                 (loc('addon.py'),
1072
-                                 {'attrib-starts': [],
1073
-                                  'first-line': 9L,
1044
+                                 {'attrib-starts': [('play_video',
1045
+        300)],
1046
+                                  'first-line': 297L,
1074 1047
                                   'folded-linenos': [228L],
1075
-                                  'sel-line': 14L,
1076
-                                  'sel-line-start': 384L,
1077
-                                  'selection_end': 384L,
1078
-                                  'selection_start': 384L,
1048
+                                  'sel-line': 306L,
1049
+                                  'sel-line-start': 12264L,
1050
+                                  'selection_end': 12264L,
1051
+                                  'selection_start': 12264L,
1079 1052
                                   'zoom': 0L}),
1080 1053
                                 (loc('resources/lib/photostation_api.py'),
1081 1054
                                  {'attrib-starts': [('PhotoStationAPI',
@@ -1171,7 +1144,7 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1171 1144
                                   'selection_end': 13246L,
1172 1145
                                   'selection_start': 13246L,
1173 1146
                                   'zoom': 0L})],
1174
-          'has-focus': True,
1147
+          'has-focus': False,
1175 1148
           'locked': False},
1176 1149
          [loc('addon.xml'),
1177 1150
           loc('addon.py'),
@@ -1420,17 +1393,17 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1420 1393
           loc('settings.xml'),
1421 1394
           loc('../../../../Python27/Lib/site-packages/xbmcswift2/mockxbmc/xbmcgui.py'),
1422 1395
           loc('../../../../Python27/Lib/site-packages/kodiswift/listitem.py')])),
1423
-                               'open_files': [u'changelog.md',
1396
+                               'open_files': [u'addon.xml',
1397
+        u'changelog.md',
1424 1398
         u'kodiswift/cli/app.py',
1425 1399
         u'kodiswift/listitem.py',
1426 1400
         u'kodiswift/mockxbmc/xbmcgui.py',
1401
+        u'kodiswift/plugin.py',
1427 1402
         u'kodiswift/xbmcmixin.py',
1428 1403
         u'resources/language/English/strings.xml',
1429 1404
         u'resources/lib/photostation_api.py',
1430 1405
         u'resources/settings.xml',
1431
-        u'kodiswift/plugin.py',
1432 1406
         u'addon.py',
1433
-        u'addon.xml',
1434 1407
         u'../../../../Python27/Lib/site-packages/kodiswift/listitem.py',
1435 1408
         u'../../../../Python27/Lib/site-packages/xbmcswift2/mockxbmc/xbmcgui.py',
1436 1409
         u'addon.py',
@@ -1450,13 +1423,12 @@ guimgr.overall-gui-state = {'windowing-policy': 'combined-window',
1450 1423
                  'user_data': {}},
1451 1424
         'window-alloc': (167,
1452 1425
                          0,
1453
-                         2417,
1426
+                         2441,
1454 1427
                          1462)}]}
1455
-guimgr.recent-documents = [loc('addon.xml'),
1456
-                           loc('addon.py'),
1457
-                           loc('kodiswift/request.py'),
1458
-                           loc('kodiswift/plugin.py'),
1428
+guimgr.recent-documents = [loc('addon.py'),
1459 1429
                            loc('resources/settings.xml'),
1430
+                           loc('addon.xml'),
1431
+                           loc('kodiswift/plugin.py'),
1460 1432
                            loc('resources/lib/photostation_api.py'),
1461 1433
                            loc('changelog.md'),
1462 1434
                            loc('kodiswift/xbmcmixin.py'),

+ 107
- 100
wingdbstub.py 파일 보기

@@ -1,54 +1,46 @@
1 1
 #########################################################################
2
-""" wingdbstub.py    -- Debug stub for debuggifying Python programs
2
+""" wingdbstub.py -- Start debugging Python programs from outside of Wing
3 3
 
4
-Copyright (c) 1999-2001, Archaeopteryx Software, Inc.  All rights reserved.
4
+Copyright (c) 1999-2018, Archaeopteryx Software, Inc.  All rights reserved.
5 5
 
6 6
 Written by Stephan R.A. Deibel and John P. Ehresman
7 7
 
8 8
 Usage:
9 9
 -----
10 10
 
11
-This is the file that Wing DB users copy into their python project 
12
-directory if they want to be able to debug programs that are launched
13
-outside of the IDE (e.g., CGI scripts, in response to a browser page
14
-load).
15
-
16
-To use this, edit the configuration values below to match your 
17
-Wing installation and requirements of your project.
18
-
19
-Then, add the following line to your code:
11
+This file is used to initiate debug in Python code without launching
12
+that code from Wing.  To use it, edit the configuration values below,
13
+start Wing and configure it to listen for outside debug connections,
14
+and then add the following line to your code:
20 15
 
21 16
   import wingdbstub
22 17
 
23
-Debugging will start immediately after this import statements.
24
-
25
-Next make sure that your IDE is running and that it's configured to accept
26
-connections from the host the debug program will be running on.
18
+Debugging will start immediately after this import statement is reached.
27 19
 
28
-Now, invoking your python file should run the code within the debugger.
29
-Note, however, that Wing will not stop in the code unless a breakpoint
30
-is set.
31
-
32
-If the debug process is started before the IDE, or is not listening
33
-at the time this module is imported then the program will run with
34
-debugging until an attach request is seen.  Attaching only works 
35
-if the .wingdebugpw file is present; see the manual for details.
36
-
37
-On win32, you either need to edit WINGHOME in this script or
38
-pass in an environment variable called WINGHOME that points to
39
-the Wing installation directory.
20
+For details, see Debugging Externally Launched Code in the manual.
40 21
 
41 22
 """
42 23
 #########################################################################
43 24
 
44 25
 import sys
45 26
 import os
46
-import imp
27
+if sys.version_info >= (3, 7):
28
+  import importlib
29
+else:
30
+  import imp
47 31
 
32
+#------------------------------------------------------------------------
33
+# Required configuration values (some installers set this automatically)
34
+
35
+# This should be the full path to your Wing installation.  On OS X, use
36
+# the full path of the Wing application bundle, for example
37
+# /Applications/WingIDE.app.  When set to None, the environment variable
38
+# WINGHOME is used instead.
39
+WINGHOME = r"C:\Program Files (x86)\Wing IDE 6.1"
48 40
 
49 41
 #------------------------------------------------------------------------
50
-# Default configuration values:  Note that the named environment 
51
-# variables, if set, will override these settings.
42
+# Optional configuration values:  The named environment variables, if set,
43
+# will override these settings.
52 44
 
53 45
 # Set this to 1 to disable all debugging; 0 to enable debugging
54 46
 # (WINGDB_DISABLED environment variable)
@@ -60,30 +52,33 @@ kWingDebugDisabled = 0
60 52
 kWingHostPort = 'localhost:50005'
61 53
 
62 54
 # Port on which to listen for connection requests, so that the
63
-# IDE can (re)attach to the debug process after it has started.
55
+# IDE can attach or reattach to the debug process after it has started.
64 56
 # Set this to '-1' to disable listening for connection requests.
65 57
 # This is only used when the debug process is not attached to
66 58
 # an IDE or the IDE has dropped its connection. The configured
67 59
 # port can optionally be added to the IDE's Common Attach Hosts
68
-# preference. Note that a random port is used instead if this 
69
-# port is already in use!
60
+# preference. Note that a random port is used instead if the given
61
+# port is already in use.
70 62
 # (WINGDB_ATTACHPORT environment variable)
71 63
 kAttachPort = '50015'
72 64
 
73 65
 # Set this to a filename to log verbose information about the debugger
74 66
 # internals to a file.  If the file does not exist, it will be created
75
-# as long as its enclosing directory exists and is writeable.  Use 
76
-# "<stderr>" or "<stdout>".  Note that "<stderr>" may cause problems 
77
-# on win32 if the debug process is not running in a console.
67
+# as long as its enclosing directory exists and is writeable.  Use
68
+# "<stderr>" or "<stdout>" to write to stderr or stdout.  Note that
69
+# "<stderr>" may cause problems on Windows if the debug process is not
70
+# running in a console.
78 71
 # (WINGDB_LOGFILE environment variable)
79 72
 kLogFile = None
80 73
 
81
-# Set to get a tremendous amount of logging from the debugger internals
82
-# (WINGDB_LOGVERYVERBOSE)
74
+# Produce a tremendous amount of logging from the debugger internals.
75
+# Do not set this unless instructed to do so by Wingware support.  It
76
+# will slow the debugger to a crawl.
77
+# (WINGDB_LOGVERYVERBOSE environment variable)
83 78
 kLogVeryVerbose = 0
84 79
 
85 80
 # Set this to 1 when debugging embedded scripts in an environment that
86
-# creates and reuses a Python instance across multiple script invocations:  
81
+# creates and reuses a Python instance across multiple script invocations.
87 82
 # It turns off automatic detection of program quit so that the debug session
88 83
 # can span multiple script invocations.  When this is turned on, you may
89 84
 # need to call ProgramQuit() on the debugger object to shut down the
@@ -92,49 +87,49 @@ kLogVeryVerbose = 0
92 87
 # only the first one will be able to debug unless it terminates debug
93 88
 # and the environment variable WINGDB_ACTIVE is unset before importing
94 89
 # this module in the second or later Python instance.  See the Wing
95
-# IDE manual for details.
96
-kEmbedded = 0
90
+# manual for details.
91
+# (WINGDB_EMBEDDED environment variable)
92
+kEmbedded = 1
97 93
 
98 94
 # Path to search for the debug password file and the name of the file
99
-# to use.  The password file contains the encryption type and connect 
100
-# password for all connections to the IDE and must match the wingdebugpw
101
-# file in the profile dir used by the IDE.  Any entry of '$<winguserprofile>' 
102
-# is replaced by the wing user profile directory for the user that the 
103
-# current process is running as
95
+# to use.  The password file contains a security token for all
96
+# connections to the IDE and must match the wingdebugpw file in the
97
+# User Settngs directory used by the IDE. '$<winguserprofile>'
98
+# is replaced by the User Settings directory for the user that
99
+# is running the process.
104 100
 # (WINGDB_PWFILEPATH environment variable)
105 101
 kPWFilePath = [os.path.dirname(__file__), '$<winguserprofile>']
106 102
 kPWFileName = 'wingdebugpw'
107 103
 
108
-# Whether to exit if the debugger fails to run or to connect with an IDE
109
-# for whatever reason
104
+# Whether to exit when the debugger fails to run or to connect with the IDE
105
+# By default, execution continues without debug or without connecting to
106
+# the IDE.
107
+# (WINGDB_EXITONFAILURE environment variable)
110 108
 kExitOnFailure = 0
111 109
 
112 110
 #------------------------------------------------------------------------
113 111
 # Find Wing debugger installation location
114 112
 
115
-# Edit this to point to your Wing installation or set to None to use env WINGHOME
116
-# On OS X this must be set to name of the Wing application bundle
117
-# (for example, /Applications/WingIDE.app)
118
-WINGHOME = None
119
-
120 113
 if sys.hexversion >= 0x03000000:
121 114
   def has_key(o, key):
122 115
     return key in o
123 116
 else:
124 117
   def has_key(o, key):
125 118
     return o.has_key(key)
126
-    
119
+
127 120
 # Check environment:  Must have WINGHOME defined if still == None
128 121
 if WINGHOME == None:
129 122
   if has_key(os.environ, 'WINGHOME'):
130 123
     WINGHOME=os.environ['WINGHOME']
131 124
   else:
132
-    sys.stdout.write("*******************************************************************\n")
133
-    sys.stdout.write("Error: Could not find Wing installation!  You must set WINGHOME or edit\n")
134
-    sys.stdout.write("wingdbstub.py where indicated to point it to the location where\n")
135
-    sys.stdout.write("Wing is installed.\n")
136
-    sys.exit(1)
137
-
125
+    msg = '\n'.join(["*******************************************************************",
126
+                     "Error: Could not find Wing installation!  You must set WINGHOME or edit",
127
+                     "wingdbstub.py where indicated to point it to the location where",
128
+                     "Wing is installed.\n"])
129
+    sys.stderr.write(msg)
130
+    raise ImportError(msg)
131
+
132
+WINGHOME = os.path.expanduser(WINGHOME)
138 133
 kPWFilePath.append(WINGHOME)
139 134
 
140 135
 # The user settings dir where per-user settings & patches are located.  Will be
@@ -142,35 +137,35 @@ kPWFilePath.append(WINGHOME)
142 137
 kUserSettingsDir = None
143 138
 if kUserSettingsDir is None:
144 139
   kUserSettingsDir = os.environ.get('WINGDB_USERSETTINGS')
145
-  
140
+
146 141
 def _FindActualWingHome(winghome):
147 142
   """ Find the actual directory to use for winghome.  Needed on OS X
148 143
   where the .app directory is the preferred dir to use for WINGHOME and
149 144
   .app/Contents/MacOS is accepted for backward compatibility. """
150
-  
145
+
151 146
   if sys.platform != 'darwin':
152 147
     return winghome
153
-  
148
+
154 149
   app_dir = None
155 150
   if os.path.isdir(winghome):
156 151
     if winghome.endswith('/'):
157 152
       wo_slash = winghome[:-1]
158 153
     else:
159 154
       wo_slash = winghome
160
-      
155
+
161 156
     if wo_slash.endswith('.app'):
162 157
       app_dir = wo_slash
163 158
     elif wo_slash.endswith('.app/Contents/MacOS'):
164 159
       app_dir = wo_slash[:-len('/Contents/MacOS')]
165
-    
160
+
166 161
   if app_dir and os.path.isdir(os.path.join(app_dir, 'Contents', 'Resources')):
167 162
     return os.path.join(app_dir, 'Contents', 'Resources')
168
-  
163
+
169 164
   return winghome
170
-  
165
+
171 166
 def _ImportWingdb(winghome, user_settings=None):
172 167
   """ Find & import wingdb module. """
173
-  
168
+
174 169
   try:
175 170
     exec_dict = {}
176 171
     execfile(os.path.join(winghome, 'bin', '_patchsupport.py'), exec_dict)
@@ -181,16 +176,29 @@ def _ImportWingdb(winghome, user_settings=None):
181 176
   dir_list.extend([os.path.join(winghome, 'bin'), os.path.join(winghome, 'src')])
182 177
   for path in dir_list:
183 178
     try:
184
-      f, p, d = imp.find_module('wingdb', [path])
185
-      try:
186
-        return imp.load_module('wingdb', f, p, d)
187
-      finally:
188
-        if f is not None:
189
-          f.close()
190
-      break
179
+      if sys.version_info >= (3, 7):
180
+        import importlib.machinery
181
+        import importlib.util
182
+
183
+        spec = importlib.machinery.PathFinder.find_spec('wingdb', [path])
184
+        if spec is not None:
185
+          mod = importlib.util.module_from_spec(spec)
186
+          if mod is not None:
187
+            spec.loader.exec_module(mod)
188
+            return mod
189
+      else:
190
+        f, p, d = imp.find_module('wingdb', [path])
191
+        try:
192
+          return imp.load_module('wingdb', f, p, d)
193
+        finally:
194
+          if f is not None:
195
+            f.close()
196
+
191 197
     except ImportError:
192 198
       pass
193 199
 
200
+  return None
201
+
194 202
 #------------------------------------------------------------------------
195 203
 # Set debugger if it hasn't been set -- this is to handle module reloading
196 204
 # In the reload case, the debugger variable will be set to something
@@ -198,7 +206,7 @@ try:
198 206
   debugger
199 207
 except NameError:
200 208
   debugger = None
201
-  
209
+
202 210
 # Unset WINGDB_ACTIVE env if it was inherited from another process
203 211
 # XXX Would be better to be able to call getpid() on dbgtracer but can't access it yet
204 212
 if 'WINGDB_ACTIVE' in os.environ and os.environ['WINGDB_ACTIVE'] != str(os.getpid()):
@@ -207,15 +215,15 @@ if 'WINGDB_ACTIVE' in os.environ and os.environ['WINGDB_ACTIVE'] != str(os.getpi
207 215
 # Start debugging if not disabled and this module has never been imported
208 216
 # before
209 217
 if (not kWingDebugDisabled and debugger is None
210
-    and not has_key(os.environ, 'WINGDB_DISABLED') and 
218
+    and not has_key(os.environ, 'WINGDB_DISABLED') and
211 219
     not has_key(os.environ, 'WINGDB_ACTIVE')):
212 220
 
213 221
   exit_on_fail = 0
214
-  
222
+
215 223
   try:
216 224
     # Obtain exit if fails value
217 225
     exit_on_fail = os.environ.get('WINGDB_EXITONFAILURE', kExitOnFailure)
218
-    
226
+
219 227
     # Obtain configuration for log file to use, if any
220 228
     logfile = os.environ.get('WINGDB_LOGFILE', kLogFile)
221 229
     if logfile == '-' or logfile == None or len(logfile.strip()) == 0:
@@ -224,31 +232,31 @@ if (not kWingDebugDisabled and debugger is None
224 232
     very_verbose_log = os.environ.get('WINGDB_LOGVERYVERBOSE', kLogVeryVerbose)
225 233
     if type(very_verbose_log) == type('') and very_verbose_log.strip() == '':
226 234
       very_verbose_log = 0
227
-      
235
+
228 236
     # Determine remote host/port where the IDE is running
229 237
     hostport = os.environ.get('WINGDB_HOSTPORT', kWingHostPort)
230 238
     colonpos = hostport.find(':')
231 239
     host = hostport[:colonpos]
232 240
     port = int(hostport[colonpos+1:])
233
-  
241
+
234 242
     # Determine port to listen on locally for attach requests
235 243
     attachport = int(os.environ.get('WINGDB_ATTACHPORT', kAttachPort))
236
-  
244
+
237 245
     # Check if running embedded script
238 246
     embedded = int(os.environ.get('WINGDB_EMBEDDED', kEmbedded))
239
-  
247
+
240 248
     # Obtain debug password file search path
241 249
     if has_key(os.environ, 'WINGDB_PWFILEPATH'):
242 250
       pwfile_path = os.environ['WINGDB_PWFILEPATH'].split(os.pathsep)
243 251
     else:
244 252
       pwfile_path = kPWFilePath
245
-    
253
+
246 254
     # Obtain debug password file name
247 255
     if has_key(os.environ, 'WINGDB_PWFILENAME'):
248 256
       pwfile_name = os.environ['WINGDB_PWFILENAME']
249 257
     else:
250 258
       pwfile_name = kPWFileName
251
-    
259
+
252 260
     # Load wingdb.py
253 261
     actual_winghome = _FindActualWingHome(WINGHOME)
254 262
     wingdb = _ImportWingdb(actual_winghome, kUserSettingsDir)
@@ -257,13 +265,13 @@ if (not kWingDebugDisabled and debugger is None
257 265
       sys.stdout.write("Error: Cannot find wingdb.py in $(WINGHOME)/bin or $(WINGHOME)/src\n")
258 266
       sys.stdout.write("Error: Please check the WINGHOME definition in wingdbstub.py\n")
259 267
       sys.exit(2)
260
-    
268
+
261 269
     # Find the netserver module and create an error stream
262 270
     netserver = wingdb.FindNetServerModule(actual_winghome, kUserSettingsDir)
263 271
     err = wingdb.CreateErrStream(netserver, logfile, very_verbose_log)
264
-    
272
+
265 273
     # Start debugging
266
-    debugger = netserver.CNetworkServer(host, port, attachport, err, 
274
+    debugger = netserver.CNetworkServer(host, port, attachport, err,
267 275
                                         pwfile_path=pwfile_path,
268 276
                                         pwfile_name=pwfile_name,
269 277
                                         autoquit=not embedded)
@@ -271,7 +279,7 @@ if (not kWingDebugDisabled and debugger is None
271 279
     os.environ['WINGDB_ACTIVE'] = str(os.getpid())
272 280
     if debugger.ChannelClosed():
273 281
       raise ValueError('Not connected')
274
-    
282
+
275 283
   except:
276 284
     if exit_on_fail:
277 285
       raise
@@ -281,19 +289,19 @@ if (not kWingDebugDisabled and debugger is None
281 289
 def Ensure(require_connection=1, require_debugger=1):
282 290
   """ Ensure the debugger is started and attempt to connect to the IDE if
283 291
   not already connected.  Will raise a ValueError if:
284
-  
292
+
285 293
   * the require_connection arg is true and the debugger is unable to connect
286 294
   * the require_debugger arg is true and the debugger cannot be loaded
287
-  
295
+
288 296
   If SuspendDebug() has been called through the low-level API, calling
289 297
   Ensure() resets the suspend count to zero and additional calls to
290 298
   ResumeDebug() will be ignored until SuspendDebug() is called again.
291
-  
299
+
292 300
   Note that a change to the host & port to connect to will only
293 301
   be use if a new connection is made.
294
-  
302
+
295 303
   """
296
-  
304
+
297 305
   if debugger is None:
298 306
     if require_debugger:
299 307
       raise ValueError("No debugger")
@@ -303,18 +311,17 @@ def Ensure(require_connection=1, require_debugger=1):
303 311
   colonpos = hostport.find(':')
304 312
   host = hostport[:colonpos]
305 313
   port = int(hostport[colonpos+1:])
306
-  
314
+
307 315
   resumed = debugger.ResumeDebug()
308 316
   while resumed > 0:
309 317
     resumed = debugger.ResumeDebug()
310
-  
311
-  debugger.SetClientAddress((host, port))  
312
-  
318
+
319
+  debugger.SetClientAddress((host, port))
320
+
313 321
   if not debugger.DebugActive():
314 322
     debugger.StartDebug()
315 323
   elif debugger.ChannelClosed():
316 324
     debugger.ConnectToClient()
317
-    
325
+
318 326
   if require_connection and debugger.ChannelClosed():
319 327
     raise ValueError('Not connected')
320
-