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