Bladeren bron

add_reset_pwd

ming 3 jaren geleden
bovenliggende
commit
db3a2d3f90

BIN
api/__pycache__/mailer.cpython-38.pyc


BIN
api/__pycache__/models.cpython-38.pyc


+ 18 - 0
api/mailer.py

@@ -55,3 +55,21 @@ def register_verify(msg_in,email):
     except:
         traceback.print_exc()
 
+def send(msg_in, email):
+    to = [email]
+    msg = MIMEMultipart()
+    msg['Subject'] = '驗證您的信箱'
+    
+    msgAlternative = MIMEMultipart('alternative')
+    msg.attach(msgAlternative)
+    text = MIMEText(msg_in,'html','utf-8')
+    msgAlternative.attach(text)
+    try:
+        server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
+        server.ehlo()
+        server.login(gmail_user, gmail_password)
+        server.sendmail(sent_from, to, msg.as_string())
+        server.close()
+    except:
+        traceback.print_exc()
+

+ 31 - 3
api/main.py

@@ -149,8 +149,8 @@ async def user_profile(token: str = Depends(oauth2_scheme)):
     video_info_list = []
     statement = 'SELECT * FROM history_input WHERE user_id='+str(user_obj['id'])
     for row in db.query(statement):
-        video_info_list.append({'id':row['id'],'title':row['name'],'duration':row['duration'],'url':row['url']})
-    dic_return = {'user_info':{'userName':user_obj['username'],'email':user_obj['email'],'video_num':video_num,'total_sec':total_sec,'left_sec':user_obj['left_time']},'video_info':video_info_list}
+        video_info_list.append({'id':row['id'],'title':row['name'],'duration':row['duration'],'url':row['link'],'time_stamp':row['timestamp']})
+    dic_return = {'user_info':{'id':user_id,'userName':user_obj['username'],'email':user_obj['email'],'video_num':video_num,'total_sec':total_sec,'left_sec':user_obj['left_time']},'video_info':video_info_list}
     str_return = json.dumps(dic_return)
     return str_return
 
@@ -249,13 +249,41 @@ def logout(request: Request, Authorize: AuthJWT = Depends()):
     return {"msg": "ok"}
 
 @app.get('/verify_email')
-async def logout(code):
+async def verify_email(code):
     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
     veri_obj = first(db.query('SELECT * FROM register_veri_code where code ="'+str(code)+'"'))
     if veri_obj != None:
         db['register_veri_code'].delete(code=code)
     return {"msg": "ok"}
 
+@app.get("/reset_pwd_page_email")
+async def reset_pwd_page():
+    return FileResponse('static/reset_pwd.html')
+
+@app.get("/reset_pwd_page")
+async def reset_pwd_page():
+    return FileResponse('static/reset_pwd.html')
+
+@app.get('/send_reset_pwd')
+async def reset_password(user_id):
+    code = str(time.time()).replace('.','')
+    db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
+    db['reset_pw_code'].insert({'code':code,'user_id':user_id})
+    msg = '請至點擊網址以重設密碼 : https://www.choozmo.com:8887/reset_password?code='+code
+    msg =msg.encode(encoding='utf-8')
+    user_dict = next(iter(db.query('SELECT * FROM users where id ="'+str(user_id)+'"')))
+    mailer.send(msg, user_dict['email'])
+    return {'msg':'ok'}
+
+@app.post('/reset_pwd')
+async def reset_password(req :models.reset_pwd):
+    db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
+    veri_obj = next(iter(db.query('SELECT * FROM reset_pw_code where code ="'+str(req.code)+'"')))
+    if veri_obj != None:
+        db['reset_pw_code'].delete(code=req.code)
+    val = db.query('UPDATE users SET password = '+'"'+get_password_hash(req.password)+'" where id ='+str(veri_obj['user_id']))
+    return {"msg": "ok"}
+
 @app.get("/gen_avatar")
 async def avatar():
     return FileResponse('static/gen_avatar.html')

+ 4 - 0
api/models.py

@@ -62,3 +62,7 @@ class register_req(BaseModel):
     email: str
     password: str
 
+class reset_pwd(BaseModel):
+    code: str
+    password: str
+

+ 108 - 0
api/static/reset_pwd.html

@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>AI ANCHOR GO</title>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
+  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp"
+    crossorigin="anonymous">
+  <link rel="stylesheet"
+    href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt"
+    crossorigin="anonymous">
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet"> 
+  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
+  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.18/dist/sweetalert2.min.css">
+  <link rel="stylesheet" href="static/style.css">
+  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
+  <style>
+    body {
+      font-family: "Lato", sans-serif;
+    }
+    .sidenav {
+      height: 100%;
+      width: 250px;
+      position: fixed;
+      z-index: 1;
+      top: 0;
+      left: 0;
+      background: linear-gradient(to bottom, #1C7CE0, #150051);
+      overflow-x: hidden;
+      transition: 0.5s;
+      padding-top: 20px;
+    }
+    
+    .sidenav a {
+      padding: 8px 8px 8px 32px;
+      text-decoration: none;
+      font-size: 25px;
+      color: #818181;
+      display: block;
+      transition: 0.3s;
+    }
+    
+    .sidenav a:hover {
+      color: #f1f1f1;
+    }
+    
+    .sidenav .closebtn {
+      position: absolute;
+      top: 0;
+      right: 25px;
+      font-size: 36px;
+      margin-left: 50px;
+    }
+    
+    @media screen and (max-height: 450px) {
+      .sidenav {padding-top: 15px;}
+      .sidenav a {font-size: 18px;}
+    }
+    </style>
+</head>
+<body>
+  <div class="container-fluid">
+    <div id="mySidenav" class="sidenav">
+      <!-- <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a> -->
+      <h2 class="go_title">reset_pwd</h2>
+      <ul class="nav-list">
+        <li class="nav-list-item pb-1 mb-3" data-bs-toggle="modal" data-bs-target="#howto"><i class="fas fa-book-open me-2"></i>使用說明</li>
+        <li class="nav-list-item pb-1" data-bs-toggle="modal" data-bs-target="#history" onclick="openNav()"><i class="fas fa-history me-2"></i>歷史紀錄</li>
+      </ul>
+      <p class="right-text text-white d-inline-block">Choozmo All Rights Reserved</p>
+    </div>
+    <!-- <span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; 過去紀錄</span> -->
+    <div class="content ms-auto">
+      <form id="msform">
+        <fieldset id='imgSrc'>
+          <h3 class="fs-subtitle" style="display: inline-block;">影像連結<img class="ms-1" src="static/img/question.png" alt="" data-bs-toggle="tooltip" data-bs-placement="right" title="僅接受png, jpg, mp4格式"></h3><br/>
+          <input type="text" name='m1' class='imgsrc imgsrc1' value="" placeholder="1" /><input id="img1" type="file" class="img_uploader img_up"><label for="img1" class="upload-btn">上傳檔案</label><br/>
+        
+          <input id="checker" type="button" class="gen_avatar action-button" value="送出" />
+
+        </fieldset>
+      </form>
+      <!-- <div style="width: 80%;margin: 0 auto;"><iframe src="http://www.choozmo.com:8168/ai_anchor_video/16250306886652043.mp4" frameborder="0" style="width: 100%;height: 400px;"></iframe></div> -->
+    </div>
+    
+
+
+  </div>
+  
+  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
+  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js'></script>
+
+  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
+  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" integrity="sha384-Atwg2Pkwv9vp0ygtn1JAojH0nYbwNJLPhwyoVbhoPwBhjQPR5VtM2+xf0Uwh9KtT" crossorigin="anonymous"></script> 
+  <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.18/dist/sweetalert2.all.min.js"></script>
+  <script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.13.1/validate.min.js"></script>
+  <script src="static/reset_pwd.js"></script>
+
+
+  <body>
+
+</div>
+
+</body>
+</html>

+ 174 - 0
api/static/reset_pwd.js

@@ -0,0 +1,174 @@
+
+$('input[type=file]').on('change', prepareUpload);
+
+// Grab the files and set them to our variable
+function prepareUpload(event) {
+  files = event.target.files;
+  var data = new FormData();
+  //data.append('file', $('.img_up1').prop('files')[0]);
+  data.append('file', files[0]);
+  // append other variables to data if you want: data.append('field_name_x', field_value_x);
+  $(this).next().text('');
+  $(this).next().html('<img src="static/img/Spinner-1s-181px.gif">');
+  $.ajax({
+    type: 'POST',
+    processData: false, // important
+    contentType: false, // important
+    data: data,
+    url: 'uploadfile',
+    dataType: 'json',
+    success: function (jsonData) {
+      event.target.previousSibling.value =jsonData.msg;
+      $(this).prev().val(jsonData.msg);
+      event.target.nextSibling.innerHTML = '';
+      event.target.nextSibling.textContent = '上傳檔案';
+      //console.log($(this).next());
+      //$(this).next().html('上傳檔案');
+      //$(this).next().text('上傳檔案');
+    },
+    error: function (error) {
+      event.target.nextSibling.innerHTML = '';
+      event.target.nextSibling.textContent = '上傳檔案';
+      alert('圖片錯誤');
+    }
+  });
+}
+const button = document.querySelector('.next');
+
+$(".next").click(function () {
+  button.setAttribute('disabled', '');
+  setTimeout(function () {
+    button.removeAttribute('disabled')
+  }, 4000);
+
+  dataOBJ = { "name": name_title, "text_content": txtARR, "image_urls": imgARR, "avatar": avatar, "client_id": client_id }
+  objstr = JSON.stringify(dataOBJ);
+  console.log(dataOBJ)
+  //alert('資料已送出! 請耐心等候')
+  $.ajax({
+    url: '/make_anchor_video_v2',
+    //url: 'http://www.choozmo.com:8888/qqreq',
+    dataType : 'json', // 預期從server接收的資料型態
+    contentType : 'application/json; charset=utf-8', // 要送到server的資料型態
+    type: 'post',
+    data: objstr,
+    success: function(suc_data) {
+      Swal.fire({
+        title: "資料已送出",
+        icon: 'success',
+        text: `${suc_data.msg}`,
+        confirmButtonColor: '#3085d6',
+      });  
+      },
+    //data:JSON.stringify({n1:"12",n2:"22"}),
+    error: function (error) {
+      console.error(error)
+    }
+  });
+  
+  });
+
+$(".gen_avatar").click(function () {
+
+  dataOBJ = { "imgurl": $('.imgsrc').val() }
+  objstr = JSON.stringify(dataOBJ);
+  console.log(dataOBJ)
+  //alert('資料已送出! 請耐心等候')
+  $.ajax({
+    url: '192.168.1.106:8887/swapFace',
+    dataType: 'json', // 預期從server接收的資料型態
+    contentType: 'application/json; charset=utf-8', // 要送到server的資料型態
+    type: 'post',
+    data: objstr,
+    success: function (suc_data) {
+      alert(suc_data.msg)
+    },
+    //data:JSON.stringify({n1:"12",n2:"22"}),
+    error: function (error) {
+      console.error(error)
+    }
+  });
+
+});
+
+var loaded_data = ''
+function openNav() {
+  document.getElementById("mySidenav").style.width = "250px";
+  document.querySelector('.loader').style.display = "block";
+  $.get("192.168.1.106:8887/history_input", function (data, status) {
+    console.log(data)
+    loaded_data = data
+    for (var obj of data) {
+      var historyList = document.querySelector('.historyList');
+      var list = document.createElement('li');
+      list.id = obj.id;
+      // div-imgfr
+      var divImgfr = document.createElement('div');
+      divImgfr.classList.add('item_imgfr');
+      var img = document.createElement('img');
+      img.setAttribute('src', obj['image_urls'][0]);
+      divImgfr.appendChild(img);
+      // div-content
+      var contentBox = document.createElement('div');
+      contentBox.classList.add('content-box');
+      var boxTitle = document.createElement('p');
+      boxTitle.classList.add('box-title');
+      boxTitle.textContent = obj.name;
+      boxTitle.id = obj.id;
+      boxTitle.setAttribute('onclick', 'load_data()');
+
+      var boxLink = document.createElement('span');
+      boxLink.classList.add('box-link');
+      boxLink.setAttribute("data-url", obj.link);
+      boxLink.setAttribute('onclick', 'view()');
+      boxLink.innerHTML = '<i class="fas fa-play-circle me-1"></i>觀看影片';
+      contentBox.appendChild(boxTitle);
+      contentBox.appendChild(boxLink);
+      list.classList.add("historyList-item");
+      list.setAttribute('onclick', 'load_data()');
+      list.appendChild(divImgfr);
+      list.appendChild(contentBox);
+      historyList.appendChild(list);
+    }
+    document.querySelector('.loader').style.display = "none";
+  });
+}
+function closeNav() {
+  document.getElementById("mySidenav").style.width = "250px";
+}
+
+function view() {
+  event.stopPropagation();
+  console.log(event.target);
+  if(event.target.nodeName === 'I') {
+    return;
+  } else {
+    window.open(`http://${event.target.dataset.url}`, '_blank');
+  }
+}
+
+
+function load_data() {
+  var title = document.getElementById("title");
+  var linker = document.getElementById("linker");
+
+  myModal.hide()
+  tid = event.srcElement.id
+  console.log(tid);
+  linker.setAttribute('href', `http://${loaded_data.find(item => item.id == tid).link}`)
+  linker.setAttribute('target', '_blank')
+  $("#linker").html(`http://${loaded_data.find(item => item.id == tid).link}`)
+  $("#linker").show();
+  $(".linker__box").show();
+
+  $(".title_new").val(loaded_data.find(item => item.id == tid).name)
+  var step;
+  for (step = 1; step <= 10; step++) {
+    $(".txtsrc" + step).val(loaded_data.find(item => item.id == tid).text_content[step - 1])
+  }
+  var step2;
+  for (step2 = 1; step2 <= 10; step2++) {
+    $(".imgsrc" + step2).val(loaded_data.find(item => item.id == tid).image_urls[step2 - 1])
+  }
+
+}

+ 108 - 0
api/static/reset_pwd_email.html

@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>AI ANCHOR GO</title>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
+  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp"
+    crossorigin="anonymous">
+  <link rel="stylesheet"
+    href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt"
+    crossorigin="anonymous">
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet"> 
+  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
+  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.18/dist/sweetalert2.min.css">
+  <link rel="stylesheet" href="static/style.css">
+  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
+  <style>
+    body {
+      font-family: "Lato", sans-serif;
+    }
+    .sidenav {
+      height: 100%;
+      width: 250px;
+      position: fixed;
+      z-index: 1;
+      top: 0;
+      left: 0;
+      background: linear-gradient(to bottom, #1C7CE0, #150051);
+      overflow-x: hidden;
+      transition: 0.5s;
+      padding-top: 20px;
+    }
+    
+    .sidenav a {
+      padding: 8px 8px 8px 32px;
+      text-decoration: none;
+      font-size: 25px;
+      color: #818181;
+      display: block;
+      transition: 0.3s;
+    }
+    
+    .sidenav a:hover {
+      color: #f1f1f1;
+    }
+    
+    .sidenav .closebtn {
+      position: absolute;
+      top: 0;
+      right: 25px;
+      font-size: 36px;
+      margin-left: 50px;
+    }
+    
+    @media screen and (max-height: 450px) {
+      .sidenav {padding-top: 15px;}
+      .sidenav a {font-size: 18px;}
+    }
+    </style>
+</head>
+<body>
+  <div class="container-fluid">
+    <div id="mySidenav" class="sidenav">
+      <!-- <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a> -->
+      <h2 class="go_title">reset_pwd</h2>
+      <ul class="nav-list">
+        <li class="nav-list-item pb-1 mb-3" data-bs-toggle="modal" data-bs-target="#howto"><i class="fas fa-book-open me-2"></i>使用說明</li>
+        <li class="nav-list-item pb-1" data-bs-toggle="modal" data-bs-target="#history" onclick="openNav()"><i class="fas fa-history me-2"></i>歷史紀錄</li>
+      </ul>
+      <p class="right-text text-white d-inline-block">Choozmo All Rights Reserved</p>
+    </div>
+    <!-- <span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; 過去紀錄</span> -->
+    <div class="content ms-auto">
+      <form id="msform">
+        <fieldset id='imgSrc'>
+          <h3 class="fs-subtitle" style="display: inline-block;">影像連結<img class="ms-1" src="static/img/question.png" alt="" data-bs-toggle="tooltip" data-bs-placement="right" title="僅接受png, jpg, mp4格式"></h3><br/>
+          <input type="text" name='m1' class='imgsrc imgsrc1' value="" placeholder="1" /><input id="img1" type="file" class="img_uploader img_up"><label for="img1" class="upload-btn">上傳檔案</label><br/>
+        
+          <input id="checker" type="button" class="gen_avatar action-button" value="送出" />
+
+        </fieldset>
+      </form>
+      <!-- <div style="width: 80%;margin: 0 auto;"><iframe src="http://www.choozmo.com:8168/ai_anchor_video/16250306886652043.mp4" frameborder="0" style="width: 100%;height: 400px;"></iframe></div> -->
+    </div>
+    
+
+
+  </div>
+  
+  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
+  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js'></script>
+
+  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
+  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" integrity="sha384-Atwg2Pkwv9vp0ygtn1JAojH0nYbwNJLPhwyoVbhoPwBhjQPR5VtM2+xf0Uwh9KtT" crossorigin="anonymous"></script> 
+  <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11.0.18/dist/sweetalert2.all.min.js"></script>
+  <script src="//cdnjs.cloudflare.com/ajax/libs/validate.js/0.13.1/validate.min.js"></script>
+  <script src="static/reset_pwd.js"></script>
+
+
+  <body>
+
+</div>
+
+</body>
+</html>

+ 142 - 0
api/static/reset_pwd_email.js

@@ -0,0 +1,142 @@
+
+$('input[type=file]').on('change', prepareUpload);
+
+// Grab the files and set them to our variable
+function prepareUpload(event) {
+  files = event.target.files;
+  var data = new FormData();
+  //data.append('file', $('.img_up1').prop('files')[0]);
+  data.append('file', files[0]);
+  // append other variables to data if you want: data.append('field_name_x', field_value_x);
+  $(this).next().text('');
+  $(this).next().html('<img src="static/img/Spinner-1s-181px.gif">');
+  $.ajax({
+    type: 'POST',
+    processData: false, // important
+    contentType: false, // important
+    data: data,
+    url: 'uploadfile',
+    dataType: 'json',
+    success: function (jsonData) {
+      event.target.previousSibling.value =jsonData.msg;
+      $(this).prev().val(jsonData.msg);
+      event.target.nextSibling.innerHTML = '';
+      event.target.nextSibling.textContent = '上傳檔案';
+      //console.log($(this).next());
+      //$(this).next().html('上傳檔案');
+      //$(this).next().text('上傳檔案');
+    },
+    error: function (error) {
+      event.target.nextSibling.innerHTML = '';
+      event.target.nextSibling.textContent = '上傳檔案';
+      alert('圖片錯誤');
+    }
+  });
+}
+const button = document.querySelector('.next');
+
+
+$(".gen_avatar").click(function () {
+
+  dataOBJ = { "imgurl": $('.imgsrc').val() }
+  objstr = JSON.stringify(dataOBJ);
+  console.log(dataOBJ)
+  //alert('資料已送出! 請耐心等候')
+  $.ajax({
+    url: '/swapFace',
+    dataType: 'json', // 預期從server接收的資料型態
+    contentType: 'application/json; charset=utf-8', // 要送到server的資料型態
+    type: 'post',
+    data: objstr,
+    success: function (suc_data) {
+      alert(suc_data.msg)
+    },
+    //data:JSON.stringify({n1:"12",n2:"22"}),
+    error: function (error) {
+      console.error(error)
+    }
+  });
+
+});
+
+var loaded_data = ''
+function openNav() {
+  document.getElementById("mySidenav").style.width = "250px";
+  document.querySelector('.loader').style.display = "block";
+  $.get("192.168.1.106:8887/history_input", function (data, status) {
+    console.log(data)
+    loaded_data = data
+    for (var obj of data) {
+      var historyList = document.querySelector('.historyList');
+      var list = document.createElement('li');
+      list.id = obj.id;
+      // div-imgfr
+      var divImgfr = document.createElement('div');
+      divImgfr.classList.add('item_imgfr');
+      var img = document.createElement('img');
+      img.setAttribute('src', obj['image_urls'][0]);
+      divImgfr.appendChild(img);
+      // div-content
+      var contentBox = document.createElement('div');
+      contentBox.classList.add('content-box');
+      var boxTitle = document.createElement('p');
+      boxTitle.classList.add('box-title');
+      boxTitle.textContent = obj.name;
+      boxTitle.id = obj.id;
+      boxTitle.setAttribute('onclick', 'load_data()');
+
+      var boxLink = document.createElement('span');
+      boxLink.classList.add('box-link');
+      boxLink.setAttribute("data-url", obj.link);
+      boxLink.setAttribute('onclick', 'view()');
+      boxLink.innerHTML = '<i class="fas fa-play-circle me-1"></i>觀看影片';
+      contentBox.appendChild(boxTitle);
+      contentBox.appendChild(boxLink);
+      list.classList.add("historyList-item");
+      list.setAttribute('onclick', 'load_data()');
+      list.appendChild(divImgfr);
+      list.appendChild(contentBox);
+      historyList.appendChild(list);
+    }
+    document.querySelector('.loader').style.display = "none";
+  });
+}
+function closeNav() {
+  document.getElementById("mySidenav").style.width = "250px";
+}
+
+function view() {
+  event.stopPropagation();
+  console.log(event.target);
+  if(event.target.nodeName === 'I') {
+    return;
+  } else {
+    window.open(`http://${event.target.dataset.url}`, '_blank');
+  }
+}
+
+
+function load_data() {
+  var title = document.getElementById("title");
+  var linker = document.getElementById("linker");
+
+  myModal.hide()
+  tid = event.srcElement.id
+  console.log(tid);
+  linker.setAttribute('href', `http://${loaded_data.find(item => item.id == tid).link}`)
+  linker.setAttribute('target', '_blank')
+  $("#linker").html(`http://${loaded_data.find(item => item.id == tid).link}`)
+  $("#linker").show();
+  $(".linker__box").show();
+
+  $(".title_new").val(loaded_data.find(item => item.id == tid).name)
+  var step;
+  for (step = 1; step <= 10; step++) {
+    $(".txtsrc" + step).val(loaded_data.find(item => item.id == tid).text_content[step - 1])
+  }
+  var step2;
+  for (step2 = 1; step2 <= 10; step2++) {
+    $(".imgsrc" + step2).val(loaded_data.find(item => item.id == tid).image_urls[step2 - 1])
+  }
+
+}

+ 34 - 0
api/test.py

@@ -0,0 +1,34 @@
+import util.user
+import dataset
+import models
+from passlib.context import CryptContext
+import time
+import mailer
+import first
+pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
+
+def get_password_hash(password):
+    return pwd_context.hash(password)
+
+code = str(time.time()).replace('.','')
+
+def reset_password1(code,user_id):
+    db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
+    db['reset_pw_code'].insert({'code':code,'user_id':user_id})
+    msg = '請至點擊網址以重設密碼 : https://www.choozmo.com:8887/reset_password?code='+code
+    msg =msg.encode(encoding='utf-8')
+    user_dict = next(iter(db.query('SELECT * FROM users where id ="'+str(user_id)+'"')))
+    mailer.send(msg, user_dict['email'])
+    return {'msg':'ok'}
+
+def reset_password2(code, pwd):
+    
+    db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
+    veri_obj = next(iter(db.query('SELECT * FROM reset_pw_code where code ="'+str(code)+'"')))
+    if veri_obj != None:
+        db['reset_pw_code'].delete(code=code)
+    val = db.query('UPDATE users SET password = '+'"'+get_password_hash(pwd)+'" where id ='+str(veri_obj['user_id']))
+    return {"msg": "ok"}
+
+reset_password1(code,36)
+reset_password2(code,'mingming')

BIN
api/util/__pycache__/user.cpython-38.pyc


+ 2 - 3
api/util/user.py

@@ -81,9 +81,8 @@ def get_user_id( username):
 def email_veri_pass(name):
     db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/AI_anchor?charset=utf8mb4')
     user_dict = next(iter(db.query('SELECT * FROM users where username ="'+name+'"')))
-    print(user_dict)
     user_obj = first(db.query('SELECT * FROM register_veri_code where user_id ="'+str(user_dict['id'])+'"'))
     if user_obj == None:
-        return False
+        return True
     else:
-        return True
+        return False