Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Add "save password", "speed limit" and "new dir"
Browse files Browse the repository at this point in the history
add three new feature and fix program crash while downloads same file in the same time
  • Loading branch information
YangLeiSX committed Apr 11, 2020
1 parent 271ef02 commit 25e8c94
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 45 deletions.
2 changes: 1 addition & 1 deletion source/captcha.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class Captcha(QtWidgets.QDialog, Ui_Captcha):
def __init__(self, captcha):
def __init__(self):
super(Captcha, self).__init__()
self.setupUi(self)
log_dir = os.path.join(
Expand Down
8 changes: 3 additions & 5 deletions source/credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from requests.exceptions import RequestException
from tenacity import retry, retry_if_exception_type, wait_fixed

# from autocaptcha import autocaptcha
from utils import (re_search, get_timestamp)
from utils import (RetryRequest, AutomataError)

Expand Down Expand Up @@ -47,7 +46,7 @@ def _bypass_captcha(session, url):
with open(os.path.join(log_dir, 'captcha.jpeg'), 'wb') as f:
f.write(captcha.content)
qDebug("out captcha")
return captcha
return None


@retry(retry=retry_if_exception_type(RequestException), wait=wait_fixed(3))
Expand Down Expand Up @@ -95,9 +94,8 @@ def login(url, parent=None, username=None, password=None):
captcha_id += get_timestamp()
captcha_url = 'https://jaccount.sjtu.edu.cn/jaccount/captcha?' +\
captcha_id
# code = _bypass_captcha(session, captcha_url, useocr)
captcha = _bypass_captcha(session, captcha_url)
check = Captcha(captcha)
_bypass_captcha(session, captcha_url)
check = Captcha()
if not check.exec_():
session.close()
return None
Expand Down
Binary file added source/dog.ico
Binary file not shown.
62 changes: 62 additions & 0 deletions source/download_queue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from PyQt5 import QtCore
import os
from time import sleep


class DownloadQueue(QtCore.QThread):
def __init__(self, parent, did, session, path, name,
url, force=False, speed=500):
super(DownloadQueue, self).__init__()
self.parent = parent
self.session = session
self.path = path
self.name = name
self.url = url
self.force = force
self.speed = speed
self.did = did

def run(self):
if not self.force:
self.parent.LogInfo.emit("[MSG]ID:{}\tBegin Download {}\n"
.format(self.did, self.name))
target = os.path.join(self.path, self.name)
r = self.session.get(self.url, stream=True)
if not self.force:
try:
with open("{}".format(target), 'xb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
if self.speed != 0:
sleep(1/self.speed)
except FileExistsError:
self.parent.LogInfo.emit("[ERROR]ID:{}\tFile Already Exists!\n"
.format(self.did))
self.parent.dq.pop(self.did)
self.parent.ExistedFile.emit(self.path, self.name, self.url)
return
else:
self.parent.LogInfo.emit("[MSG]ID:{}\tDownloads Finish\n"
.format(self.did))
self.parent.dq.pop(self.did)
self.parent.DownloadFinish.emit()
return
else:
self.parent.LogInfo.emit("[MSG]ID:{}\tWaiting to Download {}...\n"
.format(self.did, self.name))
while(len(self.parent.dq)) > 1:
sleep(1)
self.parent.LogInfo.emit("[MSG]Begin to Downloads {}\n"
.format(self.name))
with open("{}".format(target), 'wb') as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
if self.speed != 0:
sleep(1/self.speed)
self.parent.LogInfo.emit("[MSG]ID:{}\tReplace Finish!\n"
.format(self.did))
self.parent.dq.pop(self.did)
self.parent.DownloadFinish.emit()
return
90 changes: 77 additions & 13 deletions source/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,35 @@
import sys
import os
import json
from PyQt5.QtGui import QIcon
import time
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtCore import qDebug, QFileInfo
from PyQt5.QtCore import pyqtSignal as Signal
from PyQt5.QtCore import pyqtSlot as Slot
from PyQt5.QtWidgets import QApplication, QMainWindow,\
QFileDialog, QTreeWidgetItem, QFileIconProvider
from PyQt5.QtWidgets import QMessageBox, QFileIconProvider
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWidgets import QFileDialog, QTreeWidgetItem
from PyQt5.QtWidgets import QInputDialog, QLineEdit
from ui_mainwindow import Ui_MainWindow
# from captcha import Captcha
from credential import login
from canvas_update import CanvasUpdate
from downoad_queue import DownoadQueue
from download_queue import DownloadQueue


class MainWindow(QMainWindow, Ui_MainWindow):
LogInfo = Signal(str)
FetchFinish = Signal()
DownloadFinish = Signal()
ExistedFile = Signal(str, str, str)

def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("CanvasUpdater")
icon = QIcon()
icon.addPixmap(QPixmap("dog.ico"), QIcon.Normal, QIcon.Off)

self.setWindowIcon(icon)
self.session = None
self.cu = None
self.path = None
Expand All @@ -36,6 +45,7 @@ def __init__(self):
self.FetchFinish.connect(self.parseRemote)
self.LogInfo.connect(self.logInfo)
self.DownloadFinish.connect(self.parseLocal)
self.ExistedFile.connect(self.coverFile)

self.initRender()
if self.parseRemote():
Expand All @@ -44,16 +54,25 @@ def __init__(self):
def initRender(self):
self.setupUi(self)
self.LocalPath.setText("Select Your Local Path")
self.LocalPath.setReadOnly(True)
self.Log.setPlainText("[DEBUG]System Begin\n")
self.progress.setValue(0)
self.isSave.setChecked(False)
self.Speed.setText("500")
if os.path.exists(os.path.join(self.log_dir, 'loginInfo.json')):
with open(os.path.join(self.log_dir, 'loginInfo.json'), 'r') as f:
loginInfo = json.loads(f.read())
self.Jaccount.setText(loginInfo['jaccount'])
self.Password.setText(loginInfo['password'])
try:
self.Jaccount.setText(loginInfo['jaccount'])
self.Password.setText(loginInfo['password'])
except KeyError:
pass
else:
self.isSave.setChecked(True)

@Slot()
def on_LoginBtn_clicked(self):
self.LogInfo.emit("[MSG]Log in...\n")
if self.session:
self.session.close()
self.seesion = None
Expand All @@ -64,12 +83,13 @@ def on_LoginBtn_clicked(self):
qDebug(jaccount)
qDebug(password)
self.session = login(url="https://oc.sjtu.edu.cn/login/openid_connect",
parent=self, username=jaccount, password=password)
parent=self, username=jaccount, password=password,)
if self.session:
self.LogInfo.emit("[MSG]Log in Successfully!\n")
loginInfo = {}
loginInfo['jaccount'] = jaccount
loginInfo['password'] = password
if self.isSave.isChecked():
loginInfo['jaccount'] = jaccount
loginInfo['password'] = password
with open(os.path.join(self.log_dir, 'loginInfo.json'), 'w') as f:
f.write(json.dumps(loginInfo))
else:
Expand Down Expand Up @@ -104,20 +124,42 @@ def on_DownloadsBtn_clicked(self):
self.LogInfo.emit("[ERROR]Please select path!\n")
return
selectList = self.RemoteFile.selectedItems()
down_speed = int(self.Speed.text())
try:
file_path = self.LocalFile.selectedItems()[0].text(1)
except IndexError:
file_path = self.path
for selected in selectList:
did = len(self.dq)
did = len(self.dq)+1
while did in self.dq:
did = did+1
dq = DownoadQueue(self, did=did, session=self.session,
path=file_path, name=selected.text(0),
url=selected.text(1))
dq = DownloadQueue(self, did=did, session=self.session,
path=file_path, name=selected.text(0),
url=selected.text(1), force=False,
speed=down_speed)
self.dq[did] = dq
dq.start()

@Slot(QTreeWidgetItem, int)
def on_LocalFile_itemDoubleClicked(self, item, num):
# qDebug("clicked")
qDebug(item.text(0))
# qDebug(item.text(1))
if item.text(0) == "<NEW DIR>":
input_name, _ = QInputDialog.getText(self, "input", "input name",
QLineEdit.Normal, "")
if not _ or not input_name:
return
qDebug(input_name)
qDebug(item.text(1))
os.mkdir(os.path.join(item.text(1), input_name))
self.DownloadFinish.emit()
self.LogInfo.emit("[MSG]Create New Dir!\n")
else:
self.path = item.text(1)
self.LocalPath.setText(item.text(1))
self.parseLocal()

def logInfo(self, message):
raw = self.Log.toPlainText()
self.Log.setPlainText(str(raw)+message)
Expand Down Expand Up @@ -172,6 +214,9 @@ def parseLocal(self):
root = QTreeWidgetItem(self.LocalFile)
root.setText(0, "Local Files")
root.setText(1, localpath)
tmp = QTreeWidgetItem(root)
tmp.setText(0, "<NEW DIR>")
tmp.setText(1, localpath)
for item in os.listdir(localpath):
item_path = os.path.join(localpath, item)
if os.path.isdir(item_path):
Expand All @@ -187,6 +232,9 @@ def parseLocalDir(self, parent, name, path):
tmp.setIcon(0, QIcon(icon))
tmp.setText(0, name)
tmp.setText(1, path)
new = QTreeWidgetItem(tmp)
new.setText(0, "<NEW DIR>")
new.setText(1, path)
for item in os.listdir(path):
item_path = os.path.join(path, item)
if os.path.isdir(item_path):
Expand All @@ -205,6 +253,22 @@ def parseLocalFile(self, parent, name, path):
tmp.setText(0, name)
tmp.setText(1, os.path.split(path)[0])

def coverFile(self, path, name, url):
reply = QMessageBox.question(self, "File Already Exist!",
"Target Filel is Already Exist!\
Do you want to downloads again?\
(It will start after finishing other jobs.)",
QMessageBox.Yes | QMessageBox.Cancel)
if reply == QMessageBox.Yes:
did = len(self.dq)+1
while did in self.dq:
did = did+1
dq = DownloadQueue(self, did=did, session=self.session,
path=path, name=name,
url=url, force=True)
self.dq[did] = dq
dq.start()


if __name__ == "__main__":
app = QApplication([])
Expand Down
Loading

0 comments on commit 25e8c94

Please sign in to comment.