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.
Files changed (18) hide show
  1. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/PKG-INFO +1 -1
  2. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/PKG-INFO +1 -1
  3. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/setup.py +1 -1
  4. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owsavetodb.py +107 -18
  5. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/LICENSE +0 -0
  6. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/README.md +0 -0
  7. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/SOURCES.txt +0 -0
  8. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/dependency_links.txt +0 -0
  9. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/entry_points.txt +0 -0
  10. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/TimeFeatures.egg-info/top_level.txt +0 -0
  11. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/setup.cfg +0 -0
  12. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/__init__.py +0 -0
  13. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/graphgenerator.svg +0 -0
  14. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/savedatadb.svg +0 -0
  15. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/timefeature-xs.svg +0 -0
  16. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/icons/timefeature.svg +0 -0
  17. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owtimefeaturesconstructor.py +0 -0
  18. {TimeFeatures-1.0.12 → TimeFeatures-1.0.13}/timefeatures/widgets/owvardependencygraph.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TimeFeatures
3
- Version: 1.0.12
3
+ Version: 1.0.13
4
4
  Summary: Timefeatures add-on for Orange 3 data mining software.
5
5
  Home-page: https://github.com/alervgr/Orange-TimeFeatures
6
6
  Author: Alejandro Rivas García
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: TimeFeatures
3
- Version: 1.0.12
3
+ Version: 1.0.13
4
4
  Summary: Timefeatures add-on for Orange 3 data mining software.
5
5
  Home-page: https://github.com/alervgr/Orange-TimeFeatures
6
6
  Author: Alejandro Rivas García
@@ -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.12",
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, 3, 2)
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
- self.progressBarFinished()
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.create_master_table()
346
+ self.insert_data()
261
347
 
262
- if self.data.domain.class_var:
263
- class_name = self.data.domain.class_var.name
264
- else:
265
- class_name = None
348
+ def insert_data(self):
349
+ self.create_master_table()
266
350
 
267
- query = "INSERT INTO public.datasets (name, datetime, rows, cols, class, class_name) VALUES ('" + self.tableName.text().lower() + "','" + datetime.now().strftime(
268
- '%Y-%m-%d %H:%M:%S') + "','" + str(self.rows) + "','" + str(self.cols) + "','" + str(
269
- self.target) + "','" + str(class_name) + "');"
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