TimeFeatures 1.0.12__tar.gz → 1.0.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/PKG-INFO +1 -1
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/PKG-INFO +1 -1
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/setup.py +1 -1
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owsavetodb.py +107 -18
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/LICENSE +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/README.md +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/SOURCES.txt +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/dependency_links.txt +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/entry_points.txt +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/top_level.txt +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/setup.cfg +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/__init__.py +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/graphgenerator.svg +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/savedatadb.svg +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/timefeature-xs.svg +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/timefeature.svg +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owtimefeaturesconstructor.py +0 -0
- {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owvardependencygraph.py +0 -0
|
@@ -21,7 +21,7 @@ setup(name="TimeFeatures",
|
|
|
21
21
|
packages=["timefeatures.widgets"],
|
|
22
22
|
package_data={"timefeatures.widgets": ["icons/*.svg", "icons/*.png"]},
|
|
23
23
|
entry_points={"orange.widgets": "Time-Features = timefeatures.widgets"},
|
|
24
|
-
version="1.0.
|
|
24
|
+
version="1.0.13",
|
|
25
25
|
author="Alejandro Rivas García",
|
|
26
26
|
author_email="alejandrorivasgarcia@gmail.com",
|
|
27
27
|
keywords=[
|
|
@@ -19,6 +19,12 @@ from PyQt5.QtGui import QPixmap, QStandardItem
|
|
|
19
19
|
from PyQt5.QtWidgets import QGridLayout, QLineEdit, QPushButton, QSizePolicy, QLabel
|
|
20
20
|
from orangewidget.utils.signals import Input
|
|
21
21
|
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
import smtplib, ssl, time
|
|
25
|
+
from email.mime.text import MIMEText
|
|
26
|
+
from email.mime.multipart import MIMEMultipart
|
|
27
|
+
|
|
22
28
|
MAX_DL_LIMIT = 1000000
|
|
23
29
|
|
|
24
30
|
|
|
@@ -131,6 +137,9 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
131
137
|
self.cols_label = QLabel()
|
|
132
138
|
self.cols_label.setText("Columns: 0")
|
|
133
139
|
layoutA.addWidget(self.cols_label, 2, 0)
|
|
140
|
+
self.emailDirection = QLineEdit(
|
|
141
|
+
placeholderText="Email... (Optional)", toolTip="Email direction")
|
|
142
|
+
layoutA.addWidget(self.emailDirection, 4, 0)
|
|
134
143
|
self.tableName = QLineEdit(
|
|
135
144
|
placeholderText="Table name...", toolTip="Table name")
|
|
136
145
|
layoutA.addWidget(self.tableName, 3, 0)
|
|
@@ -140,7 +149,7 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
140
149
|
)
|
|
141
150
|
self.btn_savedata.clicked.connect(self.saveData)
|
|
142
151
|
self.btn_savedata.setEnabled(False)
|
|
143
|
-
layoutA.addWidget(self.btn_savedata,
|
|
152
|
+
layoutA.addWidget(self.btn_savedata, 4, 2)
|
|
144
153
|
self._add_backend_controls()
|
|
145
154
|
|
|
146
155
|
def _add_backend_controls(self):
|
|
@@ -180,7 +189,7 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
180
189
|
self.Error.connection(str(ex))
|
|
181
190
|
|
|
182
191
|
def create_table(self, table_name):
|
|
183
|
-
|
|
192
|
+
start_time = time.time()
|
|
184
193
|
self.progressBarInit()
|
|
185
194
|
contBar = 0
|
|
186
195
|
contMetasOriginales = 0
|
|
@@ -246,35 +255,115 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
246
255
|
pass
|
|
247
256
|
except BackendError as ex:
|
|
248
257
|
self.Error.connection(str(ex))
|
|
249
|
-
|
|
258
|
+
|
|
259
|
+
self.progressBarFinished()
|
|
260
|
+
if str(self.emailDirection.text()) != "":
|
|
261
|
+
end_time = time.time()
|
|
262
|
+
time_elapsed = end_time - start_time
|
|
263
|
+
time_elapsed = round(time_elapsed, 3)
|
|
264
|
+
self.send_mail(str(self.emailDirection.text()), time_elapsed)
|
|
265
|
+
|
|
266
|
+
def send_mail(self, mail, time_elapsed):
|
|
267
|
+
|
|
268
|
+
# Configuración de la connexión
|
|
269
|
+
sender = 'savetodbodm@gmail.com'
|
|
270
|
+
password = 'arnj lakd lyol rakg'
|
|
271
|
+
server = 'smtp.gmail.com'
|
|
272
|
+
port = 587
|
|
273
|
+
|
|
274
|
+
# Configuración del destinatario
|
|
275
|
+
to = mail
|
|
276
|
+
|
|
277
|
+
# configuración de las cabeceras y del mensaje
|
|
278
|
+
message = MIMEMultipart("alternative")
|
|
279
|
+
|
|
280
|
+
current_datetime = datetime.now()
|
|
281
|
+
formatted_datetime = current_datetime.strftime('%d-%m-%Y %H:%M:%S')
|
|
282
|
+
|
|
283
|
+
message["Subject"] = "Upload completed - Save To DB - " + str(formatted_datetime)
|
|
284
|
+
message["From"] = sender
|
|
285
|
+
message["To"] = to
|
|
286
|
+
|
|
287
|
+
if self.data.domain.class_var:
|
|
288
|
+
class_name = self.data.domain.class_var.name
|
|
289
|
+
else:
|
|
290
|
+
class_name = None
|
|
291
|
+
|
|
292
|
+
body = f"""\
|
|
293
|
+
<html>
|
|
294
|
+
<head>
|
|
295
|
+
</head>
|
|
296
|
+
<body>
|
|
297
|
+
<h1>Save to DB - Widget</h1>
|
|
298
|
+
<p>Your data upload has been completed!</p>
|
|
299
|
+
<p>-Table information:</p>
|
|
300
|
+
<ul>
|
|
301
|
+
<li>Table name: {str(self.tableName.text())}.</li>
|
|
302
|
+
<li>{str(self.rows_label.text())}.</li>
|
|
303
|
+
<li>{str(self.cols_label.text())}.</li>
|
|
304
|
+
<li>Class name: {str(class_name)}</li>
|
|
305
|
+
<li>{str(self.target_label.text())}.</li>
|
|
306
|
+
</ul>
|
|
307
|
+
<p>-Connection information:</p>
|
|
308
|
+
<ul>
|
|
309
|
+
<li>Server name: {str(self.servertext.text())}</li>
|
|
310
|
+
<li>Database name: {str(self.databasetext.text())}</li>
|
|
311
|
+
<li>Time Elapsed: {str(time_elapsed)}s.</li>
|
|
312
|
+
</ul>
|
|
313
|
+
</body>
|
|
314
|
+
</html>
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
part = MIMEText(body, "html")
|
|
318
|
+
message.attach(part)
|
|
319
|
+
|
|
320
|
+
# Envío del mensaje
|
|
321
|
+
try:
|
|
322
|
+
context = ssl.create_default_context()
|
|
323
|
+
with smtplib.SMTP(server, port=port) as smtp:
|
|
324
|
+
smtp.starttls(context=context)
|
|
325
|
+
smtp.login(sender, password)
|
|
326
|
+
smtp.send_message(message)
|
|
327
|
+
except Exception as ex:
|
|
328
|
+
self.Error.connection(str(ex))
|
|
250
329
|
|
|
251
330
|
def saveData(self):
|
|
252
331
|
|
|
253
332
|
self.clear()
|
|
254
333
|
|
|
334
|
+
email_regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
|
|
335
|
+
|
|
255
336
|
if self.tableName.text() == "":
|
|
256
337
|
self.Error.connection("Table name must be filled.")
|
|
257
338
|
elif self.servertext.text() == "" or self.databasetext.text() == "":
|
|
258
339
|
self.Error.connection("Host and database fields must be filled.")
|
|
340
|
+
elif self.emailDirection.text() != "":
|
|
341
|
+
if not re.match(email_regex, self.emailDirection.text()):
|
|
342
|
+
self.Error.connection("The field email must be an email.")
|
|
343
|
+
else:
|
|
344
|
+
self.insert_data()
|
|
259
345
|
else:
|
|
260
|
-
self.
|
|
346
|
+
self.insert_data()
|
|
261
347
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
else:
|
|
265
|
-
class_name = None
|
|
348
|
+
def insert_data(self):
|
|
349
|
+
self.create_master_table()
|
|
266
350
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
351
|
+
if self.data.domain.class_var:
|
|
352
|
+
class_name = self.data.domain.class_var.name
|
|
353
|
+
else:
|
|
354
|
+
class_name = None
|
|
355
|
+
|
|
356
|
+
query = "INSERT INTO public.datasets (name, datetime, rows, cols, class, class_name) VALUES ('" + self.tableName.text().lower() + "','" + datetime.now().strftime(
|
|
357
|
+
'%Y-%m-%d %H:%M:%S') + "','" + str(self.rows) + "','" + str(self.cols) + "','" + str(
|
|
358
|
+
self.target) + "','" + str(class_name) + "');"
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
with self.backend.execute_sql_query(query):
|
|
362
|
+
pass
|
|
363
|
+
self.create_table(self.tableName.text().lower())
|
|
364
|
+
except BackendError as ex:
|
|
365
|
+
self.Error.connection(str(ex))
|
|
270
366
|
|
|
271
|
-
try:
|
|
272
|
-
with self.backend.execute_sql_query(query):
|
|
273
|
-
pass
|
|
274
|
-
self.create_table(self.tableName.text().lower())
|
|
275
|
-
except BackendError as ex:
|
|
276
|
-
self.Error.connection(str(ex))
|
|
277
|
-
|
|
278
367
|
def highlight_error(self, text=""):
|
|
279
368
|
err = ['', 'QLineEdit {border: 2px solid red;}']
|
|
280
369
|
self.servertext.setStyleSheet(err['server' in text or 'host' in text])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owtimefeaturesconstructor.py
RENAMED
|
File without changes
|
|
File without changes
|