From fb6848decc0fdf3ddacbc9e57692f1fe0314df93 Mon Sep 17 00:00:00 2001
From: cshenfu <men883234@gmail.com>
Date: 星期五, 06 十二月 2024 13:34:40 +0800
Subject: [PATCH] shipinhao_btn

---
 /dev/null                                                                |  329 -------------------------
 .idea/deploymentTargetSelector.xml                                       |    3 
 未命名                                                                      |    0 
 app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt |  233 +++++++++++++++++
 app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt  |  173 +++++++++++++
 .idea/appInsightsSettings.xml                                            |    6 
 6 files changed, 412 insertions(+), 332 deletions(-)

diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml
new file mode 100644
index 0000000..6bbe2ae
--- /dev/null
+++ b/.idea/appInsightsSettings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="AppInsightsSettings">
+    <option name="selectedTabId" value="Android Vitals" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index fd67af8..f0ded44 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -13,9 +13,6 @@
         </DropdownSelection>
         <DialogSelection />
       </SelectionState>
-      <SelectionState runConfigName="SessionProfileActivity">
-        <option name="selectionMode" value="DROPDOWN" />
-      </SelectionState>
     </selectionStates>
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/other.xml b/.idea/other.xml
deleted file mode 100644
index 104e542..0000000
--- a/.idea/other.xml
+++ /dev/null
@@ -1,329 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="direct_access_persist.xml">
-    <option name="deviceSelectionList">
-      <list>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="27" />
-          <option name="brand" value="DOCOMO" />
-          <option name="codename" value="F01L" />
-          <option name="id" value="F01L" />
-          <option name="manufacturer" value="FUJITSU" />
-          <option name="name" value="F-01L" />
-          <option name="screenDensity" value="360" />
-          <option name="screenX" value="720" />
-          <option name="screenY" value="1280" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="28" />
-          <option name="brand" value="DOCOMO" />
-          <option name="codename" value="SH-01L" />
-          <option name="id" value="SH-01L" />
-          <option name="manufacturer" value="SHARP" />
-          <option name="name" value="AQUOS sense2 SH-01L" />
-          <option name="screenDensity" value="480" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2160" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="Lenovo" />
-          <option name="codename" value="TB370FU" />
-          <option name="id" value="TB370FU" />
-          <option name="manufacturer" value="Lenovo" />
-          <option name="name" value="Tab P12" />
-          <option name="screenDensity" value="340" />
-          <option name="screenX" value="1840" />
-          <option name="screenY" value="2944" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="31" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="a51" />
-          <option name="id" value="a51" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy A51" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="akita" />
-          <option name="id" value="akita" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 8a" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="b0q" />
-          <option name="id" value="b0q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy S22 Ultra" />
-          <option name="screenDensity" value="600" />
-          <option name="screenX" value="1440" />
-          <option name="screenY" value="3088" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="32" />
-          <option name="brand" value="google" />
-          <option name="codename" value="bluejay" />
-          <option name="id" value="bluejay" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 6a" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="caiman" />
-          <option name="id" value="caiman" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 9 Pro" />
-          <option name="screenDensity" value="360" />
-          <option name="screenX" value="960" />
-          <option name="screenY" value="2142" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="comet" />
-          <option name="id" value="comet" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 9 Pro Fold" />
-          <option name="screenDensity" value="390" />
-          <option name="screenX" value="2076" />
-          <option name="screenY" value="2152" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="29" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="crownqlteue" />
-          <option name="id" value="crownqlteue" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy Note9" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="2220" />
-          <option name="screenY" value="1080" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="dm3q" />
-          <option name="id" value="dm3q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy S23 Ultra" />
-          <option name="screenDensity" value="600" />
-          <option name="screenX" value="1440" />
-          <option name="screenY" value="3088" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="e1q" />
-          <option name="id" value="e1q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy S24" />
-          <option name="screenDensity" value="480" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2340" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="google" />
-          <option name="codename" value="felix" />
-          <option name="id" value="felix" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel Fold" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="2208" />
-          <option name="screenY" value="1840" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="felix" />
-          <option name="id" value="felix" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel Fold" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="2208" />
-          <option name="screenY" value="1840" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="google" />
-          <option name="codename" value="felix_camera" />
-          <option name="id" value="felix_camera" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel Fold (Camera-enabled)" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="2208" />
-          <option name="screenY" value="1840" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="gts8uwifi" />
-          <option name="id" value="gts8uwifi" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy Tab S8 Ultra" />
-          <option name="screenDensity" value="320" />
-          <option name="screenX" value="1848" />
-          <option name="screenY" value="2960" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="husky" />
-          <option name="id" value="husky" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 8 Pro" />
-          <option name="screenDensity" value="390" />
-          <option name="screenX" value="1008" />
-          <option name="screenY" value="2244" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="30" />
-          <option name="brand" value="motorola" />
-          <option name="codename" value="java" />
-          <option name="id" value="java" />
-          <option name="manufacturer" value="Motorola" />
-          <option name="name" value="G20" />
-          <option name="screenDensity" value="280" />
-          <option name="screenX" value="720" />
-          <option name="screenY" value="1600" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="komodo" />
-          <option name="id" value="komodo" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 9 Pro XL" />
-          <option name="screenDensity" value="360" />
-          <option name="screenX" value="1008" />
-          <option name="screenY" value="2244" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="google" />
-          <option name="codename" value="lynx" />
-          <option name="id" value="lynx" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 7a" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="31" />
-          <option name="brand" value="google" />
-          <option name="codename" value="oriole" />
-          <option name="id" value="oriole" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 6" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="google" />
-          <option name="codename" value="panther" />
-          <option name="id" value="panther" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 7" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="q5q" />
-          <option name="id" value="q5q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy Z Fold5" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1812" />
-          <option name="screenY" value="2176" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="samsung" />
-          <option name="codename" value="q6q" />
-          <option name="id" value="q6q" />
-          <option name="manufacturer" value="Samsung" />
-          <option name="name" value="Galaxy Z Fold6" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1856" />
-          <option name="screenY" value="2160" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="30" />
-          <option name="brand" value="google" />
-          <option name="codename" value="r11" />
-          <option name="id" value="r11" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel Watch" />
-          <option name="screenDensity" value="320" />
-          <option name="screenX" value="384" />
-          <option name="screenY" value="384" />
-          <option name="type" value="WEAR_OS" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="30" />
-          <option name="brand" value="google" />
-          <option name="codename" value="redfin" />
-          <option name="id" value="redfin" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 5" />
-          <option name="screenDensity" value="440" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2340" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="shiba" />
-          <option name="id" value="shiba" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 8" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2400" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="33" />
-          <option name="brand" value="google" />
-          <option name="codename" value="tangorpro" />
-          <option name="id" value="tangorpro" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel Tablet" />
-          <option name="screenDensity" value="320" />
-          <option name="screenX" value="1600" />
-          <option name="screenY" value="2560" />
-        </PersistentDeviceSelectionData>
-        <PersistentDeviceSelectionData>
-          <option name="api" value="34" />
-          <option name="brand" value="google" />
-          <option name="codename" value="tokay" />
-          <option name="id" value="tokay" />
-          <option name="manufacturer" value="Google" />
-          <option name="name" value="Pixel 9" />
-          <option name="screenDensity" value="420" />
-          <option name="screenX" value="1080" />
-          <option name="screenY" value="2424" />
-        </PersistentDeviceSelectionData>
-      </list>
-    </option>
-  </component>
-</project>
\ No newline at end of file
diff --git a/app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt b/app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt
new file mode 100644
index 0000000..8dee10a
--- /dev/null
+++ b/app/src/main/java/com/shsening/autouploadvideos/action/ActionBilibili.kt
@@ -0,0 +1,233 @@
+package com.shsening.autouploadvideos
+
+
+import android.app.Instrumentation
+import android.content.Context
+import android.os.SystemClock
+import android.os.Handler
+import com.shsening.autouploadvideos.UploadSessionActivity
+import com.shsening.autouploadvideos.utils.Utils
+import com.shsening.autouploadvideos.WebviewUtils
+import com.shsening.autouploadvideos.action.PlatformActionInterface
+
+class ActionBilibili (private var activity: UploadSessionActivity, private var threadHandler: Handler, private var videoInfo: Utils.VideoUploadTaskInfo) :
+    PlatformActionInterface {
+
+
+    private var webView = activity.sessionProfileWebView
+
+
+    var jsCode_CheckContentLoaded = """
+        document.querySelector('#video-up-app > div.video-entrance > div.upload-body > div > div.upload-wrp > div.bcc-upload.upload > div > input[type=file]') !== null
+    """.trimIndent()
+    var jsCode_CheckVideoUploadFinished = """
+        document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.video-upload > div.upload-queue > div > div.file-list > div.drag-list > div > div > div.file-item-content > div.file-item-content-detail > div.file-item-content-operate > div > div') !==null
+    """.trimIndent()
+    var jsCode_PublishVideo_Finished ="document.querySelector('#video-up-app > div.video-entrance > div.upload-body > div > div.banner-entry > div.banner-entry-right > div') !== null"
+
+    var jsPath_PublishVideo ="#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(17) > div > div > span"
+
+
+
+    private fun updatePostDescription(){
+
+        WebviewUtils.addValueToInput(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div.form-item.form-item-short-margin > div > div.video-title-content > div.input.input-container > div > input",videoInfo.title+videoInfo.datetime)
+
+        WebviewUtils.addValueToDiv(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(7) > div > div.desc-text-wrp > div > div.editor.ql-container > div.ql-editor.ql-blank",videoInfo.description)
+
+
+        WebviewUtils.simpleElementClick(webView,"#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div")
+        val datetime1 = videoInfo.datetime.substring(0,8)
+        val datetime2 = videoInfo.datetime.substring(8)
+        setDatePickerInput("#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div",datetime1)
+        setTimePickerInput("#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(3) > div",datetime2)
+
+        // 鍦ㄤ富绾跨▼涓缃欢杩熸墽琛�
+        threadHandler.postDelayed(Runnable {
+            startToPublishVideo()
+        }, 5000)
+    }
+
+
+    override fun checkIfContentLoaded() {
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_CheckContentLoaded) { result ->
+                if (result == "true") {
+                    simulateSwipeAndUploadVideo()
+                } else {
+                    webView.postDelayed({
+                        checkIfContentLoaded()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+    private fun startToPublishVideo(){
+        WebviewUtils.simpleElementClick(webView, jsPath_PublishVideo)
+
+        checkVideoPublishFinished()
+    }
+
+    private fun checkVideoUploadFinished(){
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_CheckVideoUploadFinished) { result ->
+                if (result == "true") {
+                    // 绛夊緟瑙嗛妫�娴嬪拰鐢熸垚灏侀潰
+                    threadHandler.postDelayed({updatePostDescription()},3000)
+
+                } else {
+                    // 鍏冪礌涓嶅瓨鍦紝1绉掑悗鍐嶆妫�鏌�
+                    webView.postDelayed({
+                        checkVideoUploadFinished()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+    private fun checkVideoPublishFinished(){
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_PublishVideo_Finished) { result ->
+                if (result == "true") {
+
+                    // video published successfully!!!
+                    activity.checkAndStartNextTask()
+
+
+                } else {
+                    // 鍏冪礌涓嶅瓨鍦紝1绉掑悗鍐嶆妫�鏌�
+                    webView.postDelayed({
+                        checkVideoPublishFinished()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+    private fun setDatePickerInput(jsPath: String, targetValue: String) {
+        var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return
+        var dpPanelText = datetimes[0].toString()+"骞�"+datetimes[1].toString()+"鏈�";
+        var dateRowColum = Utils.getDatePosition(datetimes[0],datetimes[1],datetimes[2])?:return;
+
+        val jsCode = """
+       try {
+           var dp = document.querySelector('${jsPath}');
+           dp.focus(); // 纭繚杈撳叆妗嗚幏寰楃劍鐐�
+           dp.click();
+           
+           // need time to popup date-picker
+           setTimeout(() => {
+               var dpPanel = document.querySelector('.date-picker-container');
+               var dpPanelSpan = dpPanel.querySelector('div > p');
+               if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){
+                  document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div.date-picker-container > div.date-picker-nav-wrp > svg.next-btn-day.icon-sprite.icon-sprite-ic_into').click();               
+               }
+               document.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click()
+               
+               //switch to time selection
+               document.querySelector('#video-up-app > div.video-basic-wrp > div.video-basic > div.form > div:nth-child(8) > div > div.time-switch-wrp > div.time-picker > div > div > div:nth-child(2) > div.date-picker-container > div.date-picker-nav-wrp > svg.next-btn-day.icon-sprite.icon-sprite-ic_into').click();
+               setTimeout(() => {
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click();
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click();
+               }, 500);
+           }, 500);
+            } catch (error) {
+                console.error('璁剧疆鏃ユ湡鏃跺彂鐢熼敊璇�:', error);
+            }
+        """.trimIndent()
+
+        // 鍦� WebView 涓墽琛� JavaScript 浠g爜
+        webView.evaluateJavascript(jsCode, null)
+    }
+
+    private fun setTimePickerInput(jsPath: String, targetValue: String) {
+        // 瑙f瀽鍒嗙瀛楃涓诧紝鍋囪鏍煎紡涓� "MMSS"
+        val minutes = targetValue.substring(0, 2).toIntOrNull() ?: return // 鑾峰彇鍓嶄袱涓瓧绗︿綔涓哄垎閽燂紝濡傛灉杞崲澶辫触鍒欒繑鍥�
+        val seconds = targetValue.substring(2, 4).toIntOrNull() ?: return // 鑾峰彇鍚庝袱涓瓧绗︿綔涓虹锛屽鏋滆浆鎹㈠け璐ュ垯杩斿洖
+
+        // 鏋勫缓瑕佹墽琛岀殑 JavaScript 浠g爜
+        val jsCode = """
+            try {
+    
+                setTimeout(() => {
+                    var minuteSelector = document.querySelector('.minute-selector-class');
+                    var secondSelector = document.querySelector('.second-selector-class');
+    
+                    if (minuteSelector && secondSelector) {
+                        minuteSelector.value = ${minutes};
+                        secondSelector.value = ${seconds};
+                    }
+                }, 500); // 寤惰繜鏃堕棿鍙兘闇�瑕佹牴鎹疄闄呮儏鍐佃皟鏁�
+            } catch (error) {
+                console.error('璁剧疆鏃堕棿鏃跺彂鐢熼敊璇�:', error);
+            }
+        """.trimIndent()
+
+        // 鍦� WebView 涓墽琛� JavaScript 浠g爜
+        webView.evaluateJavascript(jsCode, null)
+    }
+    private fun addValueToDatePickerInput(first:Boolean, jsPath: String, targetValue: String) {
+
+        var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return
+
+        var dpPanelText = datetimes[0].toString()+"骞� "+datetimes[1].toString()+"鏈�";
+
+        var dateRowColum = Utils.getDatePosition(datetimes[0], datetimes[1], datetimes[2]) ?:return;
+
+        val jsCode = """
+       try {
+           var dp = document.querySelector('${jsPath}');
+           dp.focus(); // 纭繚杈撳叆妗嗚幏寰楃劍鐐�
+           dp.click();
+           
+           // need time to popup date-picker
+           setTimeout(() => {
+               var dpPanel = document.querySelector('.semi-popover-content');
+               var dpPanelSpan = dpPanel.querySelector('div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > div > button > span > span');
+               if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){
+                  dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > button:nth-child(3)').click();               
+               }
+               dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click()
+               
+               //switch to time selection
+               dpPanel.querySelector('div > div > div > div > div.semi-datepicker-switch > div.semi-datepicker-switch-time').click();
+               setTimeout(() => {
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click();
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click();
+               }, 500);
+           }, 500);
+       } catch (error) {
+        console.error('鍙戠敓閿欒:', error);
+       }
+    """
+        webView.evaluateJavascript(jsCode,null)
+
+
+    }
+
+
+    private fun simulateSwipeAndUploadVideo() {
+        val instrumentation = Instrumentation()
+        val displayMetrics = activity.resources.displayMetrics
+        val width = displayMetrics.widthPixels
+        val height = displayMetrics.heightPixels
+
+        val startX = width.toFloat() * 0.9f // 浠庡彸渚ф粦鍔�
+        val endX = width.toFloat() * 0.1f // 婊戝姩鍒板乏渚�
+        val y = height / 3f // Y 鍧愭爣鍦ㄥ睆骞曚腑闂�
+
+        Thread {
+            Utils.instrumentationSwipe(instrumentation, startX, y, endX, y)
+            SystemClock.sleep(500)
+            Utils.instrumentationSwipe(instrumentation, startX, y, endX, y)
+            SystemClock.sleep(500)
+            Utils.instrumentationClick(instrumentation, width / 2f, height * 2 / 4f)
+            // back to main thread
+            threadHandler.post {
+                checkVideoUploadFinished()
+            }
+        }.start()
+    }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt b/app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt
new file mode 100644
index 0000000..5c11e4f
--- /dev/null
+++ b/app/src/main/java/com/shsening/autouploadvideos/action/ActionRedbook.kt
@@ -0,0 +1,173 @@
+package com.shsening.autouploadvideos
+
+
+import android.app.Instrumentation
+import android.content.Context
+import android.os.SystemClock
+import android.os.Handler
+import android.os.Bundle
+import android.os.Looper
+import androidx.appcompat.app.AppCompatActivity
+import com.shsening.autouploadvideos.action.PlatformActionInterface
+import com.shsening.autouploadvideos.utils.Utils
+
+class ActionRedbook (private var activity: UploadSessionActivity, private var threadHandler: Handler, private var videoInfo: Utils.VideoUploadTaskInfo):
+    PlatformActionInterface {
+
+
+    private var webView = activity.sessionProfileWebView
+
+
+    var jsCode_CheckContentLoaded = """
+        document.querySelector('input[type="file"][class="upload-input"]') !== null
+    """.trimIndent()
+    var jsCode_CheckVideoUploadFinished = """
+        document.querySelector("#publish-container > div.post-page > div.body > div.content > div.media-area-new > div > div > div.content > div.operator > span:nth-child(1)") !==null
+    """.trimIndent()
+    var jsCode_PublishVideo_Finished ="document.querySelector('#web > div > div > div > div.upload-content > div.tips-wrapper > div:nth-child(3) > div > p:nth-child(3)') !== null"
+
+    var jsPath_PublishVideo ="button.publishBtn"
+
+
+
+    private fun updatePostDescription(){
+        WebviewUtils.addValueToInput(webView,"#publish-container > div > div.body > div.content > div.input.titleInput > div.d-input-wrapper.d-inline-block.c-input_inner > div > input",videoInfo.title)
+        WebviewUtils.addValueToDiv(webView,"#quillEditor > div > p",videoInfo.description)
+        WebviewUtils.simpleElementClick(webView,"#topicBtn")
+        SystemClock.sleep(500)
+        WebviewUtils.simpleElementClick(webView,"#quill-mention-item-0")
+        WebviewUtils.simpleElementClick(webView,"#topicBtn")
+        SystemClock.sleep(500)
+        WebviewUtils.simpleElementClick(webView,"#quill-mention-item-1")
+
+//        WebviewUtils.simpleElementClick(webView,"#el-id-3410-26 > label:nth-child(1)")
+        WebviewUtils.simpleElementClick(webView,"html > body > div:nth-of-type(1) > div > div:nth-of-type(2) > div > div:nth-of-type(2) > main > div:nth-of-type(3) > div > div > div:nth-of-type(1) > div > div > div > div:nth-of-type(2) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(10) > div > div:nth-of-type(5) > div:nth-of-type(2) > label:nth-of-type(2)")
+        addValueToDatePickerInput(true,"html > body > div:nth-of-type(1) > div > div:nth-of-type(2) > div > div:nth-of-type(2) > main > div:nth-of-type(3) > div > div > div:nth-of-type(1) > div > div > div > div:nth-of-type(2) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(10) > div > div:nth-of-type(5) > div:nth-of-type(2) > div > div:nth-of-type(1) > div",videoInfo.datetime)
+        // 鍦ㄤ富绾跨▼涓缃欢杩熸墽琛�
+        threadHandler.postDelayed(Runnable {
+            startToPublishVideo()
+        }, 5000)
+    }
+
+
+    override fun checkIfContentLoaded() {
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_CheckContentLoaded) { result ->
+                if (result == "true") {
+                    simulateSwipeAndUploadVideo()
+                } else {
+                    webView.postDelayed({
+                        checkIfContentLoaded()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+    private fun startToPublishVideo(){
+        WebviewUtils.simpleElementClick(webView,jsPath_PublishVideo)
+
+        checkVideoPublishFinished()
+    }
+
+    private fun checkVideoUploadFinished(){
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_CheckVideoUploadFinished) { result ->
+                if (result == "true") {
+                    // 绛夊緟瑙嗛妫�娴嬪拰鐢熸垚灏侀潰
+                    threadHandler.postDelayed({updatePostDescription()},3000)
+
+                } else {
+                    // 鍏冪礌涓嶅瓨鍦紝1绉掑悗鍐嶆妫�鏌�
+                    webView.postDelayed({
+                        checkVideoUploadFinished()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+    private fun checkVideoPublishFinished(){
+        webView.postDelayed({
+            webView.evaluateJavascript(jsCode_PublishVideo_Finished) { result ->
+                if (result == "true") {
+
+                    // video published successfully!!!
+                    activity.checkAndStartNextTask()
+
+
+                } else {
+                    // 鍏冪礌涓嶅瓨鍦紝1绉掑悗鍐嶆妫�鏌�
+                    webView.postDelayed({
+                        checkVideoPublishFinished()
+                    }, 1000) // 1绉掑悗鍐嶆妫�鏌�
+                }
+            }
+        }, 1000) // 姣忕妫�鏌ヤ竴娆�
+    }
+
+
+    private fun addValueToDatePickerInput(first:Boolean, jsPath: String, targetValue: String) {
+
+        var datetimes = Utils.validateAndReturnDateTime(targetValue) ?: return
+
+        var dpPanelText = datetimes[0].toString()+"骞� "+datetimes[1].toString()+"鏈�";
+
+        var dateRowColum = Utils.getDatePosition(datetimes[0],datetimes[1],datetimes[2])?:return;
+
+        val jsCode = """
+       try {
+           var dp = document.querySelector('${jsPath}');
+           dp.focus(); // 纭繚杈撳叆妗嗚幏寰楃劍鐐�
+           dp.click();
+           
+           // need time to popup date-picker
+           setTimeout(() => {
+               var dpPanel = document.querySelector('.semi-popover-content');
+               var dpPanelSpan = dpPanel.querySelector('div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > div > button > span > span');
+               if (dpPanelSpan && dpPanelSpan.textContent != '${dpPanelText}'){
+                  dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-navigation > button:nth-child(3)').click();               
+               }
+               dpPanel.querySelector('div > div > div > div > div:nth-child(1) > div.semi-datepicker-month > div.semi-datepicker-weeks > div:nth-child(${dateRowColum[0]}) > div:nth-child(${dateRowColum[1]})').click()
+               
+               //switch to time selection
+               dpPanel.querySelector('div > div > div > div > div.semi-datepicker-switch > div.semi-datepicker-switch-time').click();
+               setTimeout(() => {
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-hour > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[3]+1)})').click();
+                  dpPanel.querySelector('div > div > div > div.semi-datepicker-tpk > div > div > div.semi-scrolllist-body > div.semi-scrolllist-item-wheel.undefined-list-minute > div.semi-scrolllist-list-outer > ul > li:nth-child(${(datetimes[4]+1)})').click();
+               }, 500);
+           }, 500);
+       } catch (error) {
+        console.error('鍙戠敓閿欒:', error);
+       }
+    """
+        webView.evaluateJavascript(jsCode,null)
+
+
+    }
+
+
+    private fun simulateSwipeAndUploadVideo() {
+        val instrumentation = Instrumentation()
+        val displayMetrics = activity.resources.displayMetrics
+        val width = displayMetrics.widthPixels
+        val height = displayMetrics.heightPixels
+
+        val startX = width.toFloat() * 0.9f // 浠庡彸渚ф粦鍔�
+        val endX = width.toFloat() * 0.1f // 婊戝姩鍒板乏渚�
+        val y = height / 3f // Y 鍧愭爣鍦ㄥ睆骞曚腑闂�
+
+        Thread {
+            Utils.instrumentationSwipe(instrumentation, startX, y, endX, y)
+            SystemClock.sleep(500)
+            Utils.instrumentationSwipe(instrumentation, startX, y, endX, y)
+            SystemClock.sleep(500)
+            Utils.instrumentationClick(instrumentation, width / 2f, height * 2 / 4f)
+            // back to main thread
+            threadHandler.post {
+                checkVideoUploadFinished()
+            }
+        }.start()
+    }
+
+}
\ No newline at end of file
diff --git "a/\346\234\252\345\221\275\345\220\215" "b/\346\234\252\345\221\275\345\220\215"
new file mode 100644
index 0000000..72b9359
--- /dev/null
+++ "b/\346\234\252\345\221\275\345\220\215"
Binary files differ

--
Gitblit v1.9.1