프로젝트

일반

사용자정보

개정판 26b3fef2

ID26b3fef29bacc2ff39f09b80bfff7edc82db715d
상위 688c2fca
하위 af79648d, 52599bc7

백흠경이(가) 약 4년 전에 추가함

issue #1396: 자동 업데이트 기능 추가

Change-Id: I2ad6dde79152bc08301ef82336df271d2c2bbafb

차이점 보기:

App.spec
1 1
# -*- mode: python -*-
2 2

  
3
winsparkle = '.venv\\Lib\\site-packages\\pywinsparkle\\libs\\x64\\WinSparkle.dll'
3 4
block_cipher = None
4 5

  
5 6
a = Analysis(['.\\DTI_PID\\DTI_PID\\App.py','.\\DTI_PID\\DTI_PID\\TrainingImageListDialog.py'],
......
7 8
	binaries=[('.\\DTI_PID\\DTI_PID\\bin64\\*.exe', 'bin64'),
8 9
	('.\\DTI_PID\\DTI_PID\\bin64\\*.dll', 'bin64'),
9 10
	('.\\DTI_PID\\DTI_PID\\potrace.exe', '.'),
11
	(winsparkle, '.')
10 12
	],
11 13
	datas=[('.\\DTI_PID\\DTI_PID\\*.qss', '.'),
12 14
	('.\\DTI_PID\\DTI_PID\\*.pdf', '.'),
DTI_PID/DTI_PID/App.py
2 2
""" This is application module """
3 3
import sys
4 4
import os
5
from pywinsparkle import pywinsparkle
5 6

  
6 7
if hasattr(sys, 'frozen'):
7 8
    os.environ['PATH'] = sys._MEIPASS + ";" + os.environ['PATH']
......
110 111
        return None
111 112

  
112 113

  
114
def no_update_found():
115
    """ when no update has been found, close the updater"""
116
    print("No update found")
117
    print("Setting flag to shutdown PassagesUpdater")
118

  
119

  
120
def found_update():
121
    """ log that an update was found """
122
    print("New Update Available")
123

  
124

  
125
def encountered_error():
126
    print("An error occurred")
127

  
128

  
129
def update_cancelled():
130
    """ when the update was cancelled, close the updater"""
131
    print("Update was cancelled")
132
    print("Setting flag to shutdown PassagesUpdater")
133

  
134

  
135
def shutdown():
136
    """ The installer is being launched signal the updater to shutdown """
137

  
138
    # actually shutdown the app here
139
    sys.exit(0)
140

  
141

  
142
def auto_update(update_url: str):
143
    """auto update PAP"""
144
    import time
145

  
146
    # register callbacks
147
    pywinsparkle.win_sparkle_set_did_find_update_callback(found_update)
148
    pywinsparkle.win_sparkle_set_error_callback(encountered_error)
149
    pywinsparkle.win_sparkle_set_update_cancelled_callback(update_cancelled)
150
    pywinsparkle.win_sparkle_set_did_not_find_update_callback(no_update_found)
151
    pywinsparkle.win_sparkle_set_shutdown_request_callback(shutdown)
152

  
153
    # set application details
154
    version = QCoreApplication.applicationVersion()
155
    pywinsparkle.win_sparkle_set_appcast_url(update_url)
156
    pywinsparkle.win_sparkle_set_app_details(App.COMPANY, App.NAME, version)
157

  
158
    """ DSA 공개키 설정
159
    if os.path.isfile('dsa_pub.pem'):
160
        with open('dsa_pub.pem', 'r') as file:
161
            pub_key = file.read()
162
        pywinsparkle.win_sparkle_set_dsa_pub_pem(pub_key)
163
    """
164

  
165
    # initialize
166
    pywinsparkle.win_sparkle_init()
167

  
168
    # check for updates
169
    pywinsparkle.win_sparkle_check_update_with_ui()
170

  
171

  
113 172
'''
114 173
    @history    18.04.23    Jeongwoo    Change method to execute ProjectDialog(dlg.exec_()→dlg.showDialog())
115 174
'''
......
120 179
    from MainWindow import MainWindow
121 180
    from ExceptionHandler import QExceptionHandler
122 181

  
182
    app_doc_data = AppDocData.instance()
183
    configs = app_doc_data.getAppConfigs('app', 'update_url')
184

  
123 185
    app = App(sys.argv)
186
    if configs and configs[0].value:
187
        auto_update(configs[0].value)
124 188
    
125 189
    """ log for unhandled exception """
126 190
    app.exception_handler = QExceptionHandler()
DTI_PID/DTI_PID/ProjectDialog.py
36 36
        self.ui.comboBoxProjectUnit.setHidden(True)
37 37
        self.ui.label_3.setHidden(True)
38 38

  
39
        app_doc_data = AppDocData.instance()
40
        configs = app_doc_data.getAppConfigs('app', 'update_url')
41
        if configs and configs[0].value:
42
            self.ui.lineEditUpdateURL.setText(configs[0].value)
43

  
39 44
    def initComboBox(self):
40 45
        from AppDocData import AppDocData
41 46

  
......
66 71

  
67 72
    def accept(self):
68 73
        """ accept project """
74
        from AppDocData import Config
75

  
76
        app_doc_data = AppDocData.instance()
77

  
69 78
        index = self.ui.comboBox.currentIndex()
70 79
        project = self.ui.comboBox.itemData(index)
71 80
        prj_desc = self.ui.lineEditProjectDesc.text()
......
85 94
                project.database.password = None
86 95
                project.database.file_path = os.path.join(project.getDbFilePath(), Project.DATABASE)
87 96

  
88
            AppDocData.instance().updateProjectUpdatedDate(project)
97
            app_doc_data.updateProjectUpdatedDate(project)
98

  
99
        configs = [Config('app', 'update_url', self.ui.lineEditUpdateURL.text())]
100
        app_doc_data.saveAppConfigs(configs)
89 101

  
90 102
        QDialog.accept(self)
91 103

  
DTI_PID/DTI_PID/Project_UI.py
2 2

  
3 3
# Form implementation generated from reading ui file '.\UI\Project.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.13.0
5
# Created by: PyQt5 UI code generator 5.15.4
6 6
#
7
# WARNING! All changes made in this file will be lost!
7
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
8
# run again.  Do not edit this file unless you know what you are doing.
8 9

  
9 10

  
10 11
from PyQt5 import QtCore, QtGui, QtWidgets
......
34 35
        self.buttonBox.setFont(font)
35 36
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
36 37
        self.buttonBox.setObjectName("buttonBox")
37
        self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1)
38
        self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
38 39
        self.groupBoxDBType = QtWidgets.QGroupBox(ProjectDialog)
39 40
        self.groupBoxDBType.setObjectName("groupBoxDBType")
40 41
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBoxDBType)
......
143 144
        self.label_3.setObjectName("label_3")
144 145
        self.gridLayout_4.addWidget(self.label_3, 2, 0, 1, 1)
145 146
        self.gridLayout.addLayout(self.gridLayout_4, 0, 0, 1, 1)
147
        self.gridLayout_5 = QtWidgets.QGridLayout()
148
        self.gridLayout_5.setObjectName("gridLayout_5")
149
        self.label_4 = QtWidgets.QLabel(ProjectDialog)
150
        self.label_4.setObjectName("label_4")
151
        self.gridLayout_5.addWidget(self.label_4, 0, 0, 1, 1)
152
        self.lineEditUpdateURL = QtWidgets.QLineEdit(ProjectDialog)
153
        self.lineEditUpdateURL.setObjectName("lineEditUpdateURL")
154
        self.gridLayout_5.addWidget(self.lineEditUpdateURL, 0, 1, 1, 1)
155
        self.gridLayout.addLayout(self.gridLayout_5, 2, 0, 1, 1)
146 156

  
147 157
        self.retranslateUi(ProjectDialog)
148 158
        self.buttonBox.rejected.connect(ProjectDialog.reject)
......
172 182
        self.label.setText(_translate("ProjectDialog", "Project Name"))
173 183
        self.label_2.setText(_translate("ProjectDialog", "Project Desc"))
174 184
        self.label_3.setText(_translate("ProjectDialog", "Project Unit"))
185
        self.label_4.setText(_translate("ProjectDialog", "Update URL : "))
175 186
import MainWindow_rc
DTI_PID/DTI_PID/UI/Project.ui
37 37
    <normaloff>:/newPrefix/project.png</normaloff>:/newPrefix/project.png</iconset>
38 38
  </property>
39 39
  <layout class="QGridLayout" name="gridLayout">
40
   <item row="2" column="0">
40
   <item row="3" column="0">
41 41
    <widget class="QDialogButtonBox" name="buttonBox">
42 42
     <property name="font">
43 43
      <font>
......
239 239
     </item>
240 240
    </layout>
241 241
   </item>
242
   <item row="2" column="0">
243
    <layout class="QGridLayout" name="gridLayout_5">
244
     <item row="0" column="0">
245
      <widget class="QLabel" name="label_4">
246
       <property name="text">
247
        <string>Update URL : </string>
248
       </property>
249
      </widget>
250
     </item>
251
     <item row="0" column="1">
252
      <widget class="QLineEdit" name="lineEditUpdateURL"/>
253
     </item>
254
    </layout>
255
   </item>
242 256
  </layout>
243 257
 </widget>
244 258
 <tabstops>
DTI_PID/DTI_PID/requirements.txt
13 13
pytesseract==0.3.7
14 14
requests==2.25.1
15 15
Shapely==1.7.1
16
xlrd==1.2.0
16
xlrd==1.2.0
17
pywinsparkle==1.6.0
ID2.wxs
460 460
            <Component Id="cmp876506411AF655401C5D9AD8E5F52EA6" Directory="INSTALLFOLDER" Guid="5E9F69D2-218E-4245-8C6E-78F29040E9F9" Win64="yes">
461 461
                <File Id="fil21DE3060A3015F241292520DDA49CBB4" KeyPath="yes" Source=".\dist\App\_tkinter.pyd" />
462 462
            </Component>
463
			
464
			<Component Id="cmp0523305FE9974D6F97EA71C8088909F7" Directory="INSTALLFOLDER" Guid="7810AA9F-65AF-4E37-AB35-98225176B378" Win64="yes">
465
                <File Id="fil48ADB7DBD1764E3D98DD5C89E42BA084" KeyPath="yes" Source=".\dist\App\WinSparkle.dll" />
466
            </Component>
467
			
463 468
            <Component Id="cmp4FA159BD48EFB80CD91D1617C562A2A0" Directory="dir59F9E3CEE744262828A1C345D9F97BD7" Guid="1579CFBB-9774-49DE-A00B-3BF3ACA189F6" Win64="yes">
464 469
                <File Id="filBFCFFFB1D57447308C4D28C64B320987" KeyPath="yes" Source=".\dist\App\certifi\cacert.pem" />
465 470
            </Component>
appcast.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
3
<channel>
4
    <title>HYTOS updates</title>
5
    <link>http://www.devdoftech.co.kr:8081/artifactory/ID2/appcast.xml</link>
6
    <description>Appcast for ID2 updates.</description>
7
    <language>en</language>
8
    <item>
9
      <title>Version 1.5.4</title>
10
      <sparkle:releaseNotesLink>http://devdoftech.co.kr:82/redmine/projects/id2/roadmap</sparkle:releaseNotesLink>
11
      <pubDate>Tue, 15 Sep 2012 18:11:12 +0200</pubDate>
12
      <enclosure url="http://www.devdoftech.co.kr:8081/artifactory/PAP/Setup/ID2-1.1.99.0.msi"
13
                 sparkle:version="1.1.99"
14
				 sparkle:dsaSignature="NEUCIB4lzlZTA5/rzWk7IWhw8I1vQPeFCHKLWZiZil4rm/fxAiEAtft5Aq79mhIZskVxvrFRQIjPaSnNsxNx+/kdFdS6mmM="
15
                 type="application/octet-stream"/>
16
    </item>
17
  </channel>
18
</rss>

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)