From 45f386bbecfb814189bc889d2ba1cc14f67a2dd2 Mon Sep 17 00:00:00 2001 From: welsir <1824379011@qq.com> Date: Mon, 20 Nov 2023 19:12:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E6=A8=A1=E5=9D=97=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=8E=A8=E9=80=81=E6=90=81=E7=BD=AE[B=E7=AB=99?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../12caf4f8578395f745ba099d4b2c4e027862b923 | 4 +- .../4885847675d4f3a704edb124a828e4340f674392 | 18 ++- .../6417bd18fdf446f6d0a15544ef7bab1dedee7f4f | 3 - .../6c85b62adf0b3de350e6586ee1339d3834741c00 | 4 +- .../72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 | 3 - .../7b90b8c37305ca0f12222df871dabebe3584d94b | 10 +- .../845681e29b3f06f68189058bab0812a1d7dae32f | 34 ----- .../89d10cfc510ddc98aa08656e70db2bdfd8235fc1 | 6 - .../8a3ee6510b5a426e5111e59d19b97e3455f9236d | 11 -- .../94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe | 3 - .../a06ce55f8a041ce6d4ea47d2dd417155633b349e | 3 - .../b02cc5a085842500825d66a54a50be704e96f801 | 5 - .../b161b958f9df0eab7333d43b0c1873d1d8b7470d | 0 .../bdc9a1a690dede10638dc5fde7c53a699df673ae | 0 .../e764c2c3404b24eb859f1db104fc6fb2a6f9df4c | 0 .../ee93d719337eb765e48611981710da160c4df97a | 13 -- .../fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 | 29 +++-- .idea/sonarlint/issuestore/index.pb | 56 +++++++-- .../6417bd18fdf446f6d0a15544ef7bab1dedee7f4f | 0 .../72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 | 0 .../845681e29b3f06f68189058bab0812a1d7dae32f | 0 .../89d10cfc510ddc98aa08656e70db2bdfd8235fc1 | 0 .../8a3ee6510b5a426e5111e59d19b97e3455f9236d | 0 .../94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe | 0 .../ee93d719337eb765e48611981710da160c4df97a | 0 .idea/sonarlint/securityhotspotstore/index.pb | 56 +++++++-- chopperbot-account/pom.xml | 7 -- .../main/java/org/example/api/AccountApi.java | 12 ++ .../org/example/api/AccountChannelApi.java | 37 ------ .../main/java/org/example/api/ChannelApi.java | 37 ++++++ ...VideoPublishApi.java => VideoPushApi.java} | 14 ++- .../core/channel/AccountBindChannel.java | 71 +++++++---- .../org/example/core/exchange/Exchange.java | 98 ++++++++++----- .../example/core/guard/VideoPushGuard.java | 20 +-- .../example/core/route/DefaultRouteRuler.java | 24 ++-- .../init/AccountChannelPluginInitMachine.java | 26 ++++ .../example/mapper/AccountChannelMapper.java | 12 ++ .../java/org/example/pojo/AccountChannel.java | 2 +- .../main/java/org/example/pojo/Channel.java | 2 +- .../{VideoToPublish.java => VideoToPush.java} | 2 +- .../org/example/constpool/PluginName.java | 2 + .../java/org/example/ConsoleApplication.java | 2 + .../example/controller/AccountChannelApi.java | 44 +++++++ .../example/controller/AccountController.java | 13 ++ .../example/controller/VideoController.java | 32 +++++ .../service/AccountChannelService.java | 15 +++ .../org/example/service/AccountService.java | 2 + .../org/example/service/VideoService.java | 15 +++ .../impl/AccountChannelServiceImpl.java | 25 ++++ .../service/impl/AccountServiceImpl.java | 2 + .../service/impl/VideoPushServiceImpl.java | 25 ++++ ...ioPublishApi.java => VideoPublishApi.java} | 16 ++- .../factory/platformSelectionFactory.java | 14 +-- .../impl/BilibiliVideoPublisher.java | 2 + .../java/org/example/pojo/VideoToPublish.java | 13 +- .../config/Barrage/barrageModuleConfig.json | 18 +++ .../config/Creeper/creeperConfig.json | 28 +++++ .../config/Creeper/log/creeper-2023-11-19.log | 6 + .../config/Hot/hotModuleConfig.json | 14 +++ .../config/LiveRecord/liveConfig.json | 8 ++ chopperbot-test/config/chopperBotConfig.json | 44 +++++++ .../java/org/example/account/TiktokTest.java | 119 ++++++++++++++++++ .../org/example/account/bilibiliTest.java | 26 ++++ config/Barrage/barrageModuleConfig.json | 18 +++ config/Creeper/creeperConfig.json | 28 +++++ config/Creeper/log/creeper-2023-11-20.log | 6 + config/Hot/hotModuleConfig.json | 14 +++ config/LiveRecord/liveConfig.json | 8 ++ config/chopperBotConfig.json | 45 +++++++ database.db | Bin 86016 -> 110592 bytes 70 files changed, 944 insertions(+), 282 deletions(-) delete mode 100644 .idea/sonarlint/issuestore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f delete mode 100644 .idea/sonarlint/issuestore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 delete mode 100644 .idea/sonarlint/issuestore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f delete mode 100644 .idea/sonarlint/issuestore/8/9/89d10cfc510ddc98aa08656e70db2bdfd8235fc1 delete mode 100644 .idea/sonarlint/issuestore/8/a/8a3ee6510b5a426e5111e59d19b97e3455f9236d delete mode 100644 .idea/sonarlint/issuestore/9/4/94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe delete mode 100644 .idea/sonarlint/issuestore/a/0/a06ce55f8a041ce6d4ea47d2dd417155633b349e delete mode 100644 .idea/sonarlint/issuestore/b/0/b02cc5a085842500825d66a54a50be704e96f801 delete mode 100644 .idea/sonarlint/issuestore/b/1/b161b958f9df0eab7333d43b0c1873d1d8b7470d delete mode 100644 .idea/sonarlint/issuestore/b/d/bdc9a1a690dede10638dc5fde7c53a699df673ae delete mode 100644 .idea/sonarlint/issuestore/e/7/e764c2c3404b24eb859f1db104fc6fb2a6f9df4c delete mode 100644 .idea/sonarlint/issuestore/e/e/ee93d719337eb765e48611981710da160c4df97a delete mode 100644 .idea/sonarlint/securityhotspotstore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f delete mode 100644 .idea/sonarlint/securityhotspotstore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 delete mode 100644 .idea/sonarlint/securityhotspotstore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f delete mode 100644 .idea/sonarlint/securityhotspotstore/8/9/89d10cfc510ddc98aa08656e70db2bdfd8235fc1 delete mode 100644 .idea/sonarlint/securityhotspotstore/8/a/8a3ee6510b5a426e5111e59d19b97e3455f9236d delete mode 100644 .idea/sonarlint/securityhotspotstore/9/4/94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe delete mode 100644 .idea/sonarlint/securityhotspotstore/e/e/ee93d719337eb765e48611981710da160c4df97a delete mode 100644 chopperbot-account/src/main/java/org/example/api/AccountChannelApi.java create mode 100644 chopperbot-account/src/main/java/org/example/api/ChannelApi.java rename chopperbot-account/src/main/java/org/example/api/{VideoPublishApi.java => VideoPushApi.java} (59%) create mode 100644 chopperbot-account/src/main/java/org/example/init/AccountChannelPluginInitMachine.java create mode 100644 chopperbot-account/src/main/java/org/example/mapper/AccountChannelMapper.java rename chopperbot-account/src/main/java/org/example/pojo/{VideoToPublish.java => VideoToPush.java} (94%) create mode 100644 chopperbot-console/src/main/java/org/example/controller/AccountChannelApi.java create mode 100644 chopperbot-console/src/main/java/org/example/controller/VideoController.java create mode 100644 chopperbot-console/src/main/java/org/example/service/AccountChannelService.java create mode 100644 chopperbot-console/src/main/java/org/example/service/VideoService.java create mode 100644 chopperbot-console/src/main/java/org/example/service/impl/AccountChannelServiceImpl.java create mode 100644 chopperbot-console/src/main/java/org/example/service/impl/VideoPushServiceImpl.java rename chopperbot-publish/src/main/java/org/example/api/{VedioPublishApi.java => VideoPublishApi.java} (52%) create mode 100644 chopperbot-test/config/Barrage/barrageModuleConfig.json create mode 100644 chopperbot-test/config/Creeper/creeperConfig.json create mode 100644 chopperbot-test/config/Creeper/log/creeper-2023-11-19.log create mode 100644 chopperbot-test/config/Hot/hotModuleConfig.json create mode 100644 chopperbot-test/config/LiveRecord/liveConfig.json create mode 100644 chopperbot-test/config/chopperBotConfig.json create mode 100644 chopperbot-test/src/test/java/org/example/account/TiktokTest.java create mode 100644 config/Barrage/barrageModuleConfig.json create mode 100644 config/Creeper/creeperConfig.json create mode 100644 config/Creeper/log/creeper-2023-11-20.log create mode 100644 config/Hot/hotModuleConfig.json create mode 100644 config/LiveRecord/liveConfig.json create mode 100644 config/chopperBotConfig.json diff --git a/.idea/sonarlint/issuestore/1/2/12caf4f8578395f745ba099d4b2c4e027862b923 b/.idea/sonarlint/issuestore/1/2/12caf4f8578395f745ba099d4b2c4e027862b923 index 4c15817..4220bea 100644 --- a/.idea/sonarlint/issuestore/1/2/12caf4f8578395f745ba099d4b2c4e027862b923 +++ b/.idea/sonarlint/issuestore/1/2/12caf4f8578395f745ba099d4b2c4e027862b923 @@ -1,4 +1,2 @@ -{ java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(81 -g -java:S1128"ERemove this unused import 'org.springframework.stereotype.Component'.(Ѹ81 \ No newline at end of file +{ java:S120"ZRename this package name to match the regular expression '^[a-z_]+(\.[a-z_][a-z0-9_]*)*$'.(81 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/4/8/4885847675d4f3a704edb124a828e4340f674392 b/.idea/sonarlint/issuestore/4/8/4885847675d4f3a704edb124a828e4340f674392 index e054520..5694b6f 100644 --- a/.idea/sonarlint/issuestore/4/8/4885847675d4f3a704edb124a828e4340f674392 +++ b/.idea/sonarlint/issuestore/4/8/4885847675d4f3a704edb124a828e4340f674392 @@ -1,6 +1,18 @@ -m java:S116""XRename this field "pluginName_CN" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +s java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8־1 +m java:S116#"XRename this field "pluginName_CN" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +V +java:S5993'"9Change the visibility of this constructor to "protected".(ϸ8־1 +V +java:S5993/"9Change the visibility of this constructor to "protected".(8־1 +[ +java:S59935"9Change the visibility of this constructor to "protected".(8־1 C -java:S1948"(Make "needPlugins" private or transient.( +java:S1948"(Make "needPlugins" private or transient.( C -java:S1948"(Make "logger" transient or serializable.( \ No newline at end of file +java:S1948"(Make "logger" transient or serializable.( +k java:S100"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8־1 +p java:S100"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8־1 +b +java:S1128 +"@Remove this unused import 'org.example.plugin.SpringBootPlugin'.(ð8־1 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f b/.idea/sonarlint/issuestore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f deleted file mode 100644 index 6224a18..0000000 --- a/.idea/sonarlint/issuestore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f +++ /dev/null @@ -1,3 +0,0 @@ - -G -java:S1068$",Remove this unused "platform" private field.(ҩ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/6/c/6c85b62adf0b3de350e6586ee1339d3834741c00 b/.idea/sonarlint/issuestore/6/c/6c85b62adf0b3de350e6586ee1339d3834741c00 index b6e55f8..e8c4721 100644 --- a/.idea/sonarlint/issuestore/6/c/6c85b62adf0b3de350e6586ee1339d3834741c00 +++ b/.idea/sonarlint/issuestore/6/c/6c85b62adf0b3de350e6586ee1339d3834741c00 @@ -1,3 +1,3 @@ -x java:S116"\Rename this field "is_complete_match" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(8Ĵ1 -w java:S116"VRename this field "platform_id" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ʋ8Ĵ1 \ No newline at end of file +q java:S116"\Rename this field "is_complete_match" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +p java:S116"VRename this field "platform_id" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ʋ \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 b/.idea/sonarlint/issuestore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 deleted file mode 100644 index 8574b0e..0000000 --- a/.idea/sonarlint/issuestore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 +++ /dev/null @@ -1,3 +0,0 @@ - -H -java:S1172"+Remove this unused method parameter "name".(ɾ8ڻֽ1 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/7/b/7b90b8c37305ca0f12222df871dabebe3584d94b b/.idea/sonarlint/issuestore/7/b/7b90b8c37305ca0f12222df871dabebe3584d94b index 2e9f4e4..494452a 100644 --- a/.idea/sonarlint/issuestore/7/b/7b90b8c37305ca0f12222df871dabebe3584d94b +++ b/.idea/sonarlint/issuestore/7/b/7b90b8c37305ca0f12222df871dabebe3584d94b @@ -1,5 +1,9 @@ T -java:S5993"9Change the visibility of this constructor to "protected".( -Y -java:S1128">Remove this unused import 'org.example.log.ChopperLogFactory'.(揁 \ No newline at end of file +java:S5993"9Change the visibility of this constructor to "protected".( +E +java:S1185"(Remove this method to simply inherit it.(8־1 +H +java:S1168'"+Return an empty collection instead of null.(8־1 +a +java:S1128"?Remove this unused import 'org.example.sql.annotation.SQLInit'.(Ԓ8־1 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f b/.idea/sonarlint/issuestore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f deleted file mode 100644 index 982ecd6..0000000 --- a/.idea/sonarlint/issuestore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f +++ /dev/null @@ -1,34 +0,0 @@ - -k java:S1178"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -k java:S1179"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( -f java:S117;"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(Ő -f java:S117<"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(΄ -e java:S117B"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(زz -k java:S117H"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(ӆ -l java:S117"QRename this local variable to match the regular expression '^[a-z][a-zA-Z0-9]*$'.(֛ -k -java:S2095"MUse try-with-resources or close this "FileInputStream" in a "finally" clause.(ĭ81 -j -java:S2095^"MUse try-with-resources or close this "FileInputStream" in a "finally" clause.(81 -m -java:S3776&"RRefactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed.( -[ -java:S32527"EUse static access with "com.alibaba.fastjson.JSON" for "parseObject".(֗ -` -java:S3252A"EUse static access with "com.alibaba.fastjson.JSON" for "parseObject".( -` -java:S3252G"EUse static access with "com.alibaba.fastjson.JSON" for "parseObject".(ܪ -e -java:S2674_"JCheck the return value of the "read" call to see how many bytes were read.(Ʒ -N java:S106j"9Replace this use of System.out or System.err by a logger.(䵨 -? -java:S1481}")Remove this unused "res4" local variable.( -f -java:S2674"JCheck the return value of the "read" call to see how many bytes were read.( -a -java:S3252"EUse static access with "com.alibaba.fastjson.JSON" for "parseObject".(ꀹ -\ -java:S3252"EUse static access with "com.alibaba.fastjson.JSON" for "parseObject".( -O java:S106"9Replace this use of System.out or System.err by a logger.( -N java:S106"9Replace this use of System.out or System.err by a logger.( -R java:S125""9Replace this use of System.out or System.err by a logger.( -N java:S106@"9Replace this use of System.out or System.err by a logger.( \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/f/a/fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 b/.idea/sonarlint/issuestore/f/a/fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 index e73e4f8..976c19a 100644 --- a/.idea/sonarlint/issuestore/f/a/fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 +++ b/.idea/sonarlint/issuestore/f/a/fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 @@ -1,15 +1,30 @@ R -java:S2629O"7Use the built-in formatting to construct this argument.( +java:S2629W"7Use the built-in formatting to construct this argument.( M -java:S2629R"7Use the built-in formatting to construct this argument.(ʱ +java:S2629Z"7Use the built-in formatting to construct this argument.(ʱ +Y +java:S2629^"7Use the built-in formatting to construct this argument.(8־1 O -java:S5993#"9Change the visibility of this constructor to "protected".(ڎ +java:S5993+"9Change the visibility of this constructor to "protected".(ڎ > -java:S1948"(Make "needPlugins" private or transient.( +java:S1948"(Make "needPlugins" private or transient.( C -java:S1948"(Make "logger" transient or serializable.( +java:S1948"(Make "logger" transient or serializable.( \ -java:S3457O"AFormat specifiers should be used instead of string concatenation.( +java:S3457W"AFormat specifiers should be used instead of string concatenation.( W -java:S3457R"AFormat specifiers should be used instead of string concatenation.(ʱ \ No newline at end of file +java:S3457Z"AFormat specifiers should be used instead of string concatenation.(ʱ +c +java:S3457^"AFormat specifiers should be used instead of string concatenation.(8־1 +N +java:S1602u",Remove useless curly braces around statement(8־1 +O +java:S1602",Remove useless curly braces around statement(8־1 +O +java:S1602",Remove useless curly braces around statement(8־1 +` +java:S1128 ">Remove this unused import 'org.example.log.notice.NoticeType'.(8־1 +W +java:S1128 +";Remove this unused import 'org.example.sql.SQLInitMachine'.(f8־1 \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/index.pb b/.idea/sonarlint/issuestore/index.pb index c949d58..8ec4a59 100644 --- a/.idea/sonarlint/issuestore/index.pb +++ b/.idea/sonarlint/issuestore/index.pb @@ -12,29 +12,17 @@ Ichopperbot-file/src/main/java/org/example/service/NetworkDiskService.java,8\b\ p @chopperbot-file/src/main/java/org/example/api/SystemFileApi.java,3\c\3cb27b333f9f0a0ac71ed34663c147bedca03538 s -Cchopperbot-test/src/test/java/org/example/account/bilibiliTest.java,b\0\b02cc5a085842500825d66a54a50be704e96f801 -s Cchopperbot-hot/src/main/java/org/example/bean/HotModuleSetting.java,d\b\dbd0a78c1952a54ce2fc8da11f17dc14ffb6a72d w -Gchopperbot-account/src/main/java/org/example/api/AccountChannelApi.java,7\2\72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 -w Gchopperbot-hot/src/main/java/org/example/core/guard/HotModuleGuard.java,a\0\a041720980ce8572991a33b197c3d81b7cb2e69d -n ->chopperbot-account/src/main/java/org/example/pojo/Account.java,6\c\6c85b62adf0b3de350e6586ee1339d3834741c00 s Cchopperbot-account/src/main/java/org/example/pojo/vo/AccountVO.java,4\9\49d9462b9b83c1568667ea3227b54c5f54aeae81 v Fchopperbot-account/src/main/java/org/example/mapper/AccountMapper.java,a\3\a32502cfbace3f9128c1e380c40cb9b6567a12fa -p -@chopperbot-common/src/main/java/org/example/sql/SQLInitFunc.java,5\5\55e4b538fcebad2a77f4b658e6d9fd393a158b04 s Cchopperbot-common/src/main/java/org/example/sql/SQLiteInitFunc.java,4\b\4b7da9982efec0e5c426f794ccc9fcfbcb53cb2a w Gchopperbot-common/src/main/java/org/example/sql/annotation/SQLInit.java,4\d\4de63211fa1504d90fec33b101e394054f994740 -r -Bchopperbot-common/src/main/java/org/example/sql/SQLInitHelper.java,9\f\9f3f5e8d4f0d8f488ca7b92a30583cc53b568509 -r -Bchopperbot-common/src/main/java/org/example/aop/SQLInitAspect.java,4\2\426f5e6e23d68d4dfb8fbf8c5f61054a72ef4cd5  Rchopperbot-creeper/src/main/java/org/example/core/processor/AbstractProcessor.java,6\1\6197fc5d630b662f5f7a8447c2e64104ee798ff2  @@ -51,5 +39,47 @@ e 5chopperbot-account/src/main/java/org/example/App.java,d\a\dae8427b5b9598eecdbe492665882f394721a1c1 u Echopperbot-account/src/main/java/org/example/utils/GetScriptPath.java,9\3\934468a9e28c80a30870d60852f1b32c7dce9190 +q +Achopperbot-test/src/test/java/org/example/account/DouyinTest.java,1\1\118fb8d43e4078cbd6b3698277d7db3567fafc09 +J +chopperbot-publish/pom.xml,5\b\5bab9c92a88840e07bd3e8677691d0296509a5b2 p -@chopperbot-account/src/main/java/org/example/api/AccountApi.java,b\1\b161b958f9df0eab7333d43b0c1873d1d8b7470d \ No newline at end of file +@chopperbot-common/src/main/java/org/example/sql/SQLInitFunc.java,5\5\55e4b538fcebad2a77f4b658e6d9fd393a158b04 +r +Bchopperbot-common/src/main/java/org/example/aop/SQLInitAspect.java,4\2\426f5e6e23d68d4dfb8fbf8c5f61054a72ef4cd5 +t +Dchopperbot-common/src/main/java/org/example/plugin/CommonPlugin.java,f\a\fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 +x +Hchopperbot-common/src/main/java/org/example/plugin/SpringBootPlugin.java,7\b\7b90b8c37305ca0f12222df871dabebe3584d94b +r +Bchopperbot-common/src/main/java/org/example/sql/SQLInitHelper.java,9\f\9f3f5e8d4f0d8f488ca7b92a30583cc53b568509 +l +chopperbot-account/src/main/java/org/example/pojo/Account.java,6\c\6c85b62adf0b3de350e6586ee1339d3834741c00 + +Wchopperbot-publish/src/main/java/org/example/core/publisher/PlatformVideoPublisher.java,3\6\366e666da922fbd26c7f144aca970506741c8ab1 +v +Fchopperbot-account/src/main/java/org/example/mapper/ChannelMapper.java,1\1\11d6296138a0a5fb5bc922ab3e219c2285062fb6 + +Vchopperbot-account/src/main/java/org/example/init/AccountManagerPluginInitMachine.java,a\7\a780a957bdd3bfe1cb35bc2a23604ea97d5bb09b +w +Gchopperbot-common/src/main/java/org/example/init/CommonInitMachine.java,4\8\4885847675d4f3a704edb124a828e4340f674392 + +Pchopperbot-account/src/main/java/org/example/init/VideoPushGuardInitMachine.java,9\4\945d5bad8e0672d51408965fab61b8b92275805f +x +Hchopperbot-common/src/main/java/org/example/init/InitPluginRegister.java,5\a\5a133c519459ad4a22878928f82def26862acd31 +y +Ichopperbot-common/src/main/java/org/example/plugin/SpringGuardPlugin.java,b\a\ba5cb834162541080055eddad8765b2e20598fe1 \ No newline at end of file diff --git a/.idea/sonarlint/securityhotspotstore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f b/.idea/sonarlint/securityhotspotstore/6/4/6417bd18fdf446f6d0a15544ef7bab1dedee7f4f deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 b/.idea/sonarlint/securityhotspotstore/7/2/72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f b/.idea/sonarlint/securityhotspotstore/8/4/845681e29b3f06f68189058bab0812a1d7dae32f deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/8/9/89d10cfc510ddc98aa08656e70db2bdfd8235fc1 b/.idea/sonarlint/securityhotspotstore/8/9/89d10cfc510ddc98aa08656e70db2bdfd8235fc1 deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/8/a/8a3ee6510b5a426e5111e59d19b97e3455f9236d b/.idea/sonarlint/securityhotspotstore/8/a/8a3ee6510b5a426e5111e59d19b97e3455f9236d deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/9/4/94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe b/.idea/sonarlint/securityhotspotstore/9/4/94c6aaf6d57cda31cbe57ed7ae4c39cf01206efe deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/e/e/ee93d719337eb765e48611981710da160c4df97a b/.idea/sonarlint/securityhotspotstore/e/e/ee93d719337eb765e48611981710da160c4df97a deleted file mode 100644 index e69de29..0000000 diff --git a/.idea/sonarlint/securityhotspotstore/index.pb b/.idea/sonarlint/securityhotspotstore/index.pb index 08a96dc..dc289ba 100644 --- a/.idea/sonarlint/securityhotspotstore/index.pb +++ b/.idea/sonarlint/securityhotspotstore/index.pb @@ -12,25 +12,13 @@ Ichopperbot-file/src/main/java/org/example/service/NetworkDiskService.java,8\b\ p @chopperbot-file/src/main/java/org/example/api/SystemFileApi.java,3\c\3cb27b333f9f0a0ac71ed34663c147bedca03538 s -Cchopperbot-test/src/test/java/org/example/account/bilibiliTest.java,b\0\b02cc5a085842500825d66a54a50be704e96f801 -s Cchopperbot-hot/src/main/java/org/example/bean/HotModuleSetting.java,d\b\dbd0a78c1952a54ce2fc8da11f17dc14ffb6a72d w -Gchopperbot-account/src/main/java/org/example/api/AccountChannelApi.java,7\2\72a0b1cc7348a03e9bc701e0d29b2292d2ff08d8 -w Gchopperbot-hot/src/main/java/org/example/core/guard/HotModuleGuard.java,a\0\a041720980ce8572991a33b197c3d81b7cb2e69d -n ->chopperbot-account/src/main/java/org/example/pojo/Account.java,6\c\6c85b62adf0b3de350e6586ee1339d3834741c00 s Cchopperbot-account/src/main/java/org/example/pojo/vo/AccountVO.java,4\9\49d9462b9b83c1568667ea3227b54c5f54aeae81 v Fchopperbot-account/src/main/java/org/example/mapper/AccountMapper.java,a\3\a32502cfbace3f9128c1e380c40cb9b6567a12fa -r -Bchopperbot-common/src/main/java/org/example/aop/SQLInitAspect.java,4\2\426f5e6e23d68d4dfb8fbf8c5f61054a72ef4cd5 -r -Bchopperbot-common/src/main/java/org/example/sql/SQLInitHelper.java,9\f\9f3f5e8d4f0d8f488ca7b92a30583cc53b568509 -p -@chopperbot-common/src/main/java/org/example/sql/SQLInitFunc.java,5\5\55e4b538fcebad2a77f4b658e6d9fd393a158b04 s Cchopperbot-common/src/main/java/org/example/sql/SQLiteInitFunc.java,4\b\4b7da9982efec0e5c426f794ccc9fcfbcb53cb2a w @@ -51,5 +39,47 @@ e 5chopperbot-account/src/main/java/org/example/App.java,d\a\dae8427b5b9598eecdbe492665882f394721a1c1 u Echopperbot-account/src/main/java/org/example/utils/GetScriptPath.java,9\3\934468a9e28c80a30870d60852f1b32c7dce9190 +q +Achopperbot-test/src/test/java/org/example/account/DouyinTest.java,1\1\118fb8d43e4078cbd6b3698277d7db3567fafc09 +J +chopperbot-publish/pom.xml,5\b\5bab9c92a88840e07bd3e8677691d0296509a5b2 p -@chopperbot-account/src/main/java/org/example/api/AccountApi.java,b\1\b161b958f9df0eab7333d43b0c1873d1d8b7470d \ No newline at end of file +@chopperbot-common/src/main/java/org/example/sql/SQLInitFunc.java,5\5\55e4b538fcebad2a77f4b658e6d9fd393a158b04 +r +Bchopperbot-common/src/main/java/org/example/aop/SQLInitAspect.java,4\2\426f5e6e23d68d4dfb8fbf8c5f61054a72ef4cd5 +t +Dchopperbot-common/src/main/java/org/example/plugin/CommonPlugin.java,f\a\fa7c1c0ac4f71faff2d46fb4595b96b2be8e0634 +x +Hchopperbot-common/src/main/java/org/example/plugin/SpringBootPlugin.java,7\b\7b90b8c37305ca0f12222df871dabebe3584d94b +r +Bchopperbot-common/src/main/java/org/example/sql/SQLInitHelper.java,9\f\9f3f5e8d4f0d8f488ca7b92a30583cc53b568509 + +Schopperbot-account/src/main/java/org/example/core/account/AccountManagerPlugin.java,4\6\46bb29701603e77d8d5b9379ac3309e77e86e02f +l +chopperbot-account/src/main/java/org/example/pojo/Account.java,6\c\6c85b62adf0b3de350e6586ee1339d3834741c00 + +Wchopperbot-publish/src/main/java/org/example/core/publisher/PlatformVideoPublisher.java,3\6\366e666da922fbd26c7f144aca970506741c8ab1 +v +Fchopperbot-account/src/main/java/org/example/mapper/ChannelMapper.java,1\1\11d6296138a0a5fb5bc922ab3e219c2285062fb6 + +Pchopperbot-account/src/main/java/org/example/init/VideoPushGuardInitMachine.java,9\4\945d5bad8e0672d51408965fab61b8b92275805f + +Vchopperbot-account/src/main/java/org/example/init/AccountManagerPluginInitMachine.java,a\7\a780a957bdd3bfe1cb35bc2a23604ea97d5bb09b +w +Gchopperbot-common/src/main/java/org/example/init/CommonInitMachine.java,4\8\4885847675d4f3a704edb124a828e4340f674392 +x +Hchopperbot-common/src/main/java/org/example/init/InitPluginRegister.java,5\a\5a133c519459ad4a22878928f82def26862acd31 +y +Ichopperbot-common/src/main/java/org/example/plugin/SpringGuardPlugin.java,b\a\ba5cb834162541080055eddad8765b2e20598fe1 \ No newline at end of file diff --git a/chopperbot-account/pom.xml b/chopperbot-account/pom.xml index 84425c8..b311c93 100644 --- a/chopperbot-account/pom.xml +++ b/chopperbot-account/pom.xml @@ -38,13 +38,6 @@ org.example chopperbot-publish - - - - - - - com.hankcs hanlp diff --git a/chopperbot-account/src/main/java/org/example/api/AccountApi.java b/chopperbot-account/src/main/java/org/example/api/AccountApi.java index 3f9b3b7..e22aebf 100644 --- a/chopperbot-account/src/main/java/org/example/api/AccountApi.java +++ b/chopperbot-account/src/main/java/org/example/api/AccountApi.java @@ -1,7 +1,9 @@ package org.example.api; import org.example.core.account.AccountOperateCenter; +import org.example.core.channel.AccountBindChannel; import org.example.pojo.Account; +import org.example.pojo.Channel; import org.example.pojo.vo.AccountVO; import org.springframework.stereotype.Component; @@ -18,6 +20,8 @@ public class AccountApi { @Resource AccountOperateCenter accountOperator; + @Resource + AccountBindChannel channel; /* * 第一次登陆调用此方法将账号对应cookie存入数据库中 @@ -51,4 +55,12 @@ public class AccountApi { public void deleteUser(int uid){ accountOperator.deleteAccount(uid); } + + public void bindChannel(String userId,String channelId){ + channel.bindChannel(channelId,userId); + } + + public void unBindChannel(String userId,String channelId){ + channel.unbindChannel(channelId,userId); + } } diff --git a/chopperbot-account/src/main/java/org/example/api/AccountChannelApi.java b/chopperbot-account/src/main/java/org/example/api/AccountChannelApi.java deleted file mode 100644 index aecf5fc..0000000 --- a/chopperbot-account/src/main/java/org/example/api/AccountChannelApi.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.example.api; - -import org.example.core.channel.AccountChannel; -import org.example.util.Result; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -/** - * @Description - * @Author welsir - * @Date 2023/11/17 8:34 - */ -@Component -public class AccountChannelApi { - - @Resource - AccountChannel accountChannel; - - public Result addChannel(String name){ - return Result.success(accountChannel.addChannel(name)); - } - - public Result delChannel(String name){ - return Result.success(accountChannel.delChannel(name)); - } - - public Result getChannelAccounts(String name){ - - return Result.success(); - } - - public Result getChannels(){ - return Result.success(accountChannel.getChannelList()); - } - -} diff --git a/chopperbot-account/src/main/java/org/example/api/ChannelApi.java b/chopperbot-account/src/main/java/org/example/api/ChannelApi.java new file mode 100644 index 0000000..8a8b4f8 --- /dev/null +++ b/chopperbot-account/src/main/java/org/example/api/ChannelApi.java @@ -0,0 +1,37 @@ +package org.example.api; + + +import org.example.core.channel.AccountBindChannel; +import org.example.util.Result; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * @Description + * @Author welsir + * @Date 2023/11/17 8:34 + */ +@Component +public class ChannelApi { + + @Resource + AccountBindChannel accountChannel; + + public Result addChannel(String name,String route){ + return Result.success(accountChannel.addChannel(name,route)); + } + + public Result delChannel(String channelId){ + return Result.success(accountChannel.delChannel(channelId)); + } + + public Result getChannelAccounts(String channelId){ + return Result.success(accountChannel.getAccountList(channelId)); + } + + public Result getChannels(){ + return Result.success(accountChannel.getChannelList()); + } + +} diff --git a/chopperbot-account/src/main/java/org/example/api/VideoPublishApi.java b/chopperbot-account/src/main/java/org/example/api/VideoPushApi.java similarity index 59% rename from chopperbot-account/src/main/java/org/example/api/VideoPublishApi.java rename to chopperbot-account/src/main/java/org/example/api/VideoPushApi.java index f34a81c..d16c8ef 100644 --- a/chopperbot-account/src/main/java/org/example/api/VideoPublishApi.java +++ b/chopperbot-account/src/main/java/org/example/api/VideoPushApi.java @@ -1,5 +1,6 @@ package org.example.api; +import org.example.bean.section.PackageSection; import org.example.constpool.PluginName; import org.example.core.guard.VideoPushGuard; import org.example.init.InitPluginRegister; @@ -7,18 +8,21 @@ import org.example.plugin.CommonPlugin; import org.springframework.stereotype.Component; import org.springframework.util.Assert; +import javax.annotation.Resource; + /** * @Description 视频推送插件api * @Author welsir * @Date 2023/9/5 22:36 */ @Component -public class VideoPublishApi { +public class VideoPushApi { - public static void pushVideo(Object obj){ - VideoPushGuard plugin = InitPluginRegister.getPlugin(PluginName.VIDEO_PUSH_PLUGIN, VideoPushGuard.class); - Assert.isNull(plugin,"plugin is null!"); - plugin.sendVideo(obj); + @Resource + VideoPushGuard videoPushGuard; + + public void pushVideo(PackageSection obj){ + videoPushGuard.sendVideo(obj); } } diff --git a/chopperbot-account/src/main/java/org/example/core/channel/AccountBindChannel.java b/chopperbot-account/src/main/java/org/example/core/channel/AccountBindChannel.java index 563d2a7..8bb9f64 100644 --- a/chopperbot-account/src/main/java/org/example/core/channel/AccountBindChannel.java +++ b/chopperbot-account/src/main/java/org/example/core/channel/AccountBindChannel.java @@ -1,7 +1,9 @@ package org.example.core.channel; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; import lombok.extern.slf4j.Slf4j; +import org.example.mapper.AccountChannelMapper; import org.example.mapper.AccountMapper; import org.example.mapper.ChannelMapper; import org.example.plugin.SpringBootPlugin; @@ -46,9 +48,9 @@ public class AccountBindChannel extends SpringBootPlugin { return true; } - public boolean delChannel(String name){ + public boolean delChannel(String channelId){ try { - channelMapper.delete(new QueryWrapper().eq("name",name)); + channelMapper.deleteById(channelId); }catch (RuntimeException e){ log.debug("删除管道失败!"); return false; @@ -59,26 +61,26 @@ public class AccountBindChannel extends SpringBootPlugin { public List getChannelList(){ List channelList = channelMapper.selectList(null); for (Channel channel : channelList) { - channelRoute.put(channel.getName(),channel.getRoute()); + channelRoute.putIfAbsent(channel.getId().toString(),channel.getRoute()); } - return channelMapper.selectList(null); + return channelList; } - public List getAccountList(String name){ - List channels = channelMapper.selectList(new QueryWrapper().eq("name", name)); - Long channelId = channels.get(0).getId(); - return channelMapper.getChannelAccounts(channelId); + public List getAccountList(String channelId){ + Channel channel = channelMapper.selectById(channelId); + Long id = channel.getId(); + return channelMapper.getChannelAccounts(id); } - public void bindChannel(String channelId,String accountId){ + public void bindChannel (String channelId,String accountId){ try { - //todo: 需测试 - List accountList = channelAccount.get(channelId); - accountList.add(accountMapper.selectById(accountId)); AccountChannel accountChannel = new AccountChannel(); accountChannel.setAccountId(accountId); accountChannel.setChannelId(channelId); channelMapper.bindChannel(accountChannel); + channelAccount.putIfAbsent(channelId,new ArrayList<>()); + List accountList = channelAccount.get(channelId); + accountList.add(accountMapper.selectById(accountId)); }catch (RuntimeException e){ log.debug("账号绑定失败:"+e); } @@ -108,22 +110,37 @@ public class AccountBindChannel extends SpringBootPlugin { public boolean init() { channelAccount = new HashMap<>(); channelRoute = new HashMap<>(); - sqlInitHelper.initTable("channel","CREATE TABLE `account_channel` (\n" + - " `id` bigint NOT NULL,\n" + - " `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" + - " `route` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,\n" + - " PRIMARY KEY (`id`) USING BTREE,\n" + - " UNIQUE INDEX `name`(`name` ASC) USING BTREE\n" + - ")"+ - "INSERT INTO `account_channel` (`id`, `name`, `type`) VALUES (1, 'default', '*.*.*');"); - - sqlInitHelper.initTable("account_channel","CREATE TABLE `channel` (\n" + - " `id` bigint NOT NULL,\n" + - " `channel_id` bigint NULL DEFAULT NULL,\n" + - " `account_id` bigint NULL DEFAULT NULL,\n" + - " PRIMARY KEY (`id`) USING BTREE\n" + + sqlInitHelper.initTable("channel","CREATE TABLE `channel` (\n" + + " `id` INTEGER NOT NULL,\n" + + " `name` TEXT NOT NULL,\n" + + " `route` TEXT NOT NULL,\n" + + " PRIMARY KEY (id),\n" + + " UNIQUE (name)\n" + ")"); - + ArrayList channels = new ArrayList<>(); + Channel channel = new Channel(); + channel.setRoute("*.*.*"); + channel.setName("default"); + channel.setId(1L); + channels.add(channel); + sqlInitHelper.initData(channels,channelMapper); + sqlInitHelper.initTable("account_channel","CREATE TABLE `account_channel` (\n" + + " `id` INTEGER NOT NULL,\n" + + " `channel_id` TEXT ,\n" + + " `account_id` TEXT ,\n" + + " PRIMARY KEY (id)\n" + + ")"); + List channelList = channelMapper.selectList(null); + for (Channel channel1 : channelList) { + channelRoute.put(channel1.getId().toString(),channel1.getRoute()); + } + List accountChannels = channelMapper.queryAccountChannel(); + for (AccountChannel accountChannel : accountChannels) { + channelAccount.putIfAbsent(accountChannel.getChannelId(),new ArrayList<>()); + List accountList = channelAccount.get(accountChannel.getChannelId()); + Account account = accountMapper.selectById(accountChannel.getAccountId()); + accountList.add(account); + } return true; } diff --git a/chopperbot-account/src/main/java/org/example/core/exchange/Exchange.java b/chopperbot-account/src/main/java/org/example/core/exchange/Exchange.java index a82f77b..4e54ced 100644 --- a/chopperbot-account/src/main/java/org/example/core/exchange/Exchange.java +++ b/chopperbot-account/src/main/java/org/example/core/exchange/Exchange.java @@ -1,65 +1,95 @@ package org.example.core.exchange; -import org.example.api.VedioPublishApi; + + +import lombok.extern.slf4j.Slf4j; +import org.example.api.VideoPublishApi; import org.example.bean.section.PackageSection; +import org.example.core.channel.AccountBindChannel; import org.example.core.route.DefaultRouteRuler; -import org.example.pojo.Video; -import org.example.pojo.VideoQueue; + +import org.example.pojo.Account; import org.example.pojo.VideoToPublish; +import org.example.pojo.VideoToPush; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; import javax.annotation.Resource; +import java.nio.file.FileSystems; +import java.nio.file.Path; import java.util.*; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -import java.util.concurrent.TimeUnit; /** - * @Description + * @Description 视频管道交换机 * @Author welsir * @Date 2023/9/4 22:07 */ +@Component +@Slf4j public class Exchange { + //存储不同管道对应的切片集合 private final Map> channels = new HashMap<>(); + //存储管道的匹配规则 private Map channelRoute; @Resource DefaultRouteRuler defaultRouteRuler; + @Resource + AccountBindChannel channel; + @Resource + VideoPublishApi pushVideo; - ScheduledExecutorService task; - public Exchange() { - task = Executors.newScheduledThreadPool(1); + @Scheduled(fixedDelay = 5000) + public void publishVideo(){ + log.info("listen video to push..."); + Map> channelAccount = channel.getChannelAccount(); + channels.forEach((k,v)->{ + if(channels.get(k)==null){ + return; + } + log.debug("channel:"+k+" videos:"+ Arrays.toString(v.toArray())); + List accountList = channelAccount.get(k); + List packageSections = channels.get(k); + for (Account account : accountList) { + for (PackageSection packageSection : packageSections) { + VideoToPublish video = new VideoToPublish(); + video.setCookies(account.getCookies()); + video.setTitle(packageSection.getTitle()); + video.setDevicePath(getDevicePath(packageSection.getVideoPath())); + video.setVideoPath(packageSection.getVideoPath()); + video.setContent(packageSection.getContent()); + video.setCoverPath(packageSection.getCoverPath()); + video.setDescription(packageSection.getDescription()); + video.setLabels(packageSection.getLabels()); + video.setPlatform(packageSection.getPlatform()); + pushVideo.publishVideo(video); + } + } + channels.get(k).removeAll(v); + }); } - public void startListening() { - // 每5秒轮询一次消息队列 - // 检查消息队列并提取消息 - task.scheduleAtFixedRate(this::checkAndProcessMessages, 0, 5, TimeUnit.SECONDS); - } - private void checkAndProcessMessages() { - // 在这里检查消息队列,提取消息并调用publish方法 -// for (String channel : channels.keySet()) { -// List packageSections = channels.get(channel); -// for (PackageSection packageSection : packageSections) { -// VedioPublishApi.publishVideo(VideoToPublish.builder() -// .videoPath(packageSection.getVideoPath()).cookies().build()) -// } -// } - } - - public void publish(String routingKey,PackageSection packageSection) { + public void pushToQueue(String routingKey,PackageSection packageSection) { + channelRoute = channel.getChannelRoute(); for (String key : channelRoute.keySet()) { String route = channelRoute.get(key); boolean flag = defaultRouteRuler.matchRoute(routingKey, route); if (flag){ - if(channels.get(key)==null){ - channels.put(key,List.of(packageSection)); - }else { - List packageSections = channels.get(key); - packageSections.add(packageSection); - } + channels.putIfAbsent(key,new ArrayList<>()); + List packageSections = channels.get(key); + packageSections.add(packageSection); } } } + + private String getDevicePath(String filePath){ + Path path = FileSystems.getDefault().getPath(filePath); + String fileName = path.getFileName().toString(); + Path directoryPath = path.getParent(); + String directory = (directoryPath != null) ? directoryPath.toString() : "No Directory"; + return directory+"\\"+fileName+"\\"; + } + } diff --git a/chopperbot-account/src/main/java/org/example/core/guard/VideoPushGuard.java b/chopperbot-account/src/main/java/org/example/core/guard/VideoPushGuard.java index a9f1bec..b9e05a0 100644 --- a/chopperbot-account/src/main/java/org/example/core/guard/VideoPushGuard.java +++ b/chopperbot-account/src/main/java/org/example/core/guard/VideoPushGuard.java @@ -1,5 +1,6 @@ package org.example.core.guard; +import lombok.extern.slf4j.Slf4j; import org.example.bean.section.PackageSection; import org.example.core.exchange.Exchange; import org.example.mapper.AccountMapper; @@ -22,40 +23,41 @@ import java.util.concurrent.TimeUnit; * @Date 2023/9/4 22:10 */ @Component +@Slf4j public class VideoPushGuard extends SpringGuardPlugin { - private Exchange exchange; + private BlockingQueue receiveVideo; @Resource private AccountMapper accountMapper; @Resource ChannelMapper channelMapper; + @Resource + SQLInitHelper sqlInitHelper; + @Resource + Exchange exchange; @Override public boolean init() { - // 两件事情 - // 一注册队列 - // 二启动队列监听 - exchange = new Exchange(); - //建表 receiveVideo = new ArrayBlockingQueue<>(1024); return true; } public void start() { try { + log.debug("阻塞队列监听视频..."); Object videoMsg = receiveVideo.poll(5, TimeUnit.SECONDS); if (videoMsg instanceof PackageSection) { PackageSection video = (PackageSection) videoMsg; StringBuilder route = new StringBuilder(); for (String label : video.getLabels()) { - if(route.length()!=0) + if(route.length()!=0) { route.append("."); + } route.append(label); } - exchange.publish(route.toString(),video); + exchange.pushToQueue(route.toString(),video); } - exchange.startListening(); } catch (InterruptedException e) { throw new RuntimeException(e); } diff --git a/chopperbot-account/src/main/java/org/example/core/route/DefaultRouteRuler.java b/chopperbot-account/src/main/java/org/example/core/route/DefaultRouteRuler.java index 87bebb6..073c7ae 100644 --- a/chopperbot-account/src/main/java/org/example/core/route/DefaultRouteRuler.java +++ b/chopperbot-account/src/main/java/org/example/core/route/DefaultRouteRuler.java @@ -14,23 +14,21 @@ public class DefaultRouteRuler extends AbstractRouteRuler{ @Override public boolean matchRoute(String route,String channelRoute) { - String[] routes = route.split("\\."); - String[] channelRoutes = channelRoute.split("\\."); - - String label = routes[0]; - String anchor = routes[1]; - String plat = routes[2]; - - if(label.isEmpty()||anchor.isEmpty()||plat.isEmpty()){ - return false; + if ("*.*.*".equals(channelRoute)) { + return true; } - for (String s : channelRoutes) { - if(s.equals(label)||("\\*").equals(label)){ - continue; - } + String[] routes = route.split("\\."); + String[] channelRoutes = channelRoute.split("\\."); + if(routes.length!=channelRoutes.length){ return false; } + for (int i = 0; i < 3; i++) { + // 如果 channelRoute 的这一段不是 "*",则必须与 route 的相应段相等 + if (!"*".equals(channelRoutes[i]) && !channelRoutes[i].equals(routes[i])) { + return false; + } + } return true; } } diff --git a/chopperbot-account/src/main/java/org/example/init/AccountChannelPluginInitMachine.java b/chopperbot-account/src/main/java/org/example/init/AccountChannelPluginInitMachine.java new file mode 100644 index 0000000..5c5316b --- /dev/null +++ b/chopperbot-account/src/main/java/org/example/init/AccountChannelPluginInitMachine.java @@ -0,0 +1,26 @@ +package org.example.init; + +import org.example.constpool.ModuleName; +import org.example.constpool.PluginName; +import org.example.core.channel.AccountBindChannel; +import org.example.core.guard.VideoPushGuard; +import org.example.plugin.annotation.Plugin; +import org.example.pojo.AccountChannel; +import org.springframework.stereotype.Component; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 16:09 + */ +@Plugin(moduleName = ModuleName.ACCOUNT, + pluginName = PluginName.CHANNEL, + pluginName_CN = "账号管道插件", + pluginDescription = "用于对管道的CRUD以及账号绑定", + pluginClass= AccountBindChannel.class, + springBootPlugin = true, + ignore = true +) +@Component +public class AccountChannelPluginInitMachine extends SpringPlugInitMachine{ +} diff --git a/chopperbot-account/src/main/java/org/example/mapper/AccountChannelMapper.java b/chopperbot-account/src/main/java/org/example/mapper/AccountChannelMapper.java new file mode 100644 index 0000000..358ba0a --- /dev/null +++ b/chopperbot-account/src/main/java/org/example/mapper/AccountChannelMapper.java @@ -0,0 +1,12 @@ +package org.example.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.example.pojo.AccountChannel; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 11:29 + */ +public interface AccountChannelMapper extends BaseMapper { +} diff --git a/chopperbot-account/src/main/java/org/example/pojo/AccountChannel.java b/chopperbot-account/src/main/java/org/example/pojo/AccountChannel.java index 4ef2b58..47a7199 100644 --- a/chopperbot-account/src/main/java/org/example/pojo/AccountChannel.java +++ b/chopperbot-account/src/main/java/org/example/pojo/AccountChannel.java @@ -12,7 +12,7 @@ import lombok.Data; * @Date 2023/11/17 9:20 */ @Data -@TableName(value = "channel") +@TableName(value = "account_channel") public class AccountChannel { @TableId(value = "id", type = IdType.AUTO) diff --git a/chopperbot-account/src/main/java/org/example/pojo/Channel.java b/chopperbot-account/src/main/java/org/example/pojo/Channel.java index de7bbbe..f1806bb 100644 --- a/chopperbot-account/src/main/java/org/example/pojo/Channel.java +++ b/chopperbot-account/src/main/java/org/example/pojo/Channel.java @@ -16,7 +16,7 @@ import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor -@TableName("account_channel") +@TableName("channel") public class Channel { @TableId(value = "id", type = IdType.AUTO) diff --git a/chopperbot-account/src/main/java/org/example/pojo/VideoToPublish.java b/chopperbot-account/src/main/java/org/example/pojo/VideoToPush.java similarity index 94% rename from chopperbot-account/src/main/java/org/example/pojo/VideoToPublish.java rename to chopperbot-account/src/main/java/org/example/pojo/VideoToPush.java index 952c702..1fb3090 100644 --- a/chopperbot-account/src/main/java/org/example/pojo/VideoToPublish.java +++ b/chopperbot-account/src/main/java/org/example/pojo/VideoToPush.java @@ -15,7 +15,7 @@ import lombok.NoArgsConstructor; @Builder @AllArgsConstructor @NoArgsConstructor -public class VideoToPublish { +public class VideoToPush { private String videoPath; private String cookies; diff --git a/chopperbot-common/src/main/java/org/example/constpool/PluginName.java b/chopperbot-common/src/main/java/org/example/constpool/PluginName.java index 2159aa8..3fa23ac 100644 --- a/chopperbot-common/src/main/java/org/example/constpool/PluginName.java +++ b/chopperbot-common/src/main/java/org/example/constpool/PluginName.java @@ -49,6 +49,8 @@ public class PluginName { public static final String LABEL_MANAGER = "LabelManager"; + public static final String CHANNEL = "channel"; + public static final String LIVE_CONFIG_PLUGIN= "LiveConfig"; public static final String LIVE_MANAGER_PLUGIN= "LiveDownLoadManager"; diff --git a/chopperbot-console/src/main/java/org/example/ConsoleApplication.java b/chopperbot-console/src/main/java/org/example/ConsoleApplication.java index ff3df19..25b6ccd 100644 --- a/chopperbot-console/src/main/java/org/example/ConsoleApplication.java +++ b/chopperbot-console/src/main/java/org/example/ConsoleApplication.java @@ -3,6 +3,7 @@ package org.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; /** * @author Genius @@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; **/ @SpringBootApplication +@EnableScheduling public class ConsoleApplication { public static void main(String[] args) { diff --git a/chopperbot-console/src/main/java/org/example/controller/AccountChannelApi.java b/chopperbot-console/src/main/java/org/example/controller/AccountChannelApi.java new file mode 100644 index 0000000..cdb06e5 --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/controller/AccountChannelApi.java @@ -0,0 +1,44 @@ +package org.example.controller; + +import org.apache.ibatis.annotations.Delete; +import org.example.service.AccountChannelService; +import org.example.service.AccountService; +import org.example.service.impl.AccountChannelServiceImpl; +import org.example.util.Result; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 11:04 + */ +@RestController +@RequestMapping("/channel") +public class AccountChannelApi { + + @Resource + AccountChannelService channelService; + + @PostMapping("/{name}/{route}") + public Result addChannel(@PathVariable String name, @PathVariable String route){ + return Result.success(channelService.channelApi().addChannel(name,route)); + } + + @DeleteMapping("/{channelId}") + public Result delChannel(@PathVariable String channelId){ + return Result.success(channelService.channelApi().delChannel(channelId)); + } + + @GetMapping("/") + public Result getChannelList(){ + return Result.success(channelService.channelApi().getChannels()); + } + + @GetMapping("/accounts/{channelId}") + public Result getChannelAccounts(@PathVariable String channelId){ + return Result.success(channelService.channelApi().getChannelAccounts(channelId)); + } + +} diff --git a/chopperbot-console/src/main/java/org/example/controller/AccountController.java b/chopperbot-console/src/main/java/org/example/controller/AccountController.java index d1acc00..336e6b8 100644 --- a/chopperbot-console/src/main/java/org/example/controller/AccountController.java +++ b/chopperbot-console/src/main/java/org/example/controller/AccountController.java @@ -97,4 +97,17 @@ public class AccountController { public Result updateLabel(@RequestBody VideoLabel label){ return Result.success(Map.of("success",accountService.labelManagerPlugin().updateLabel(label))); } + + @PostMapping("/bind/{userId}/{channelId}") + public Result bindAccount(@PathVariable String channelId, @PathVariable String userId){ + accountService.accountPlugin().bindChannel(userId,channelId); + return Result.success(); + } + + @DeleteMapping("/bind/{userId}/{channelId}") + public Result unBindAccount(@PathVariable String channelId, @PathVariable String userId){ + accountService.accountPlugin().unBindChannel(userId,channelId); + return Result.success(); + } + } diff --git a/chopperbot-console/src/main/java/org/example/controller/VideoController.java b/chopperbot-console/src/main/java/org/example/controller/VideoController.java new file mode 100644 index 0000000..8313894 --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/controller/VideoController.java @@ -0,0 +1,32 @@ +package org.example.controller; + +import org.example.bean.section.PackageSection; +import org.example.pojo.VideoToPublish; +import org.example.service.VideoService; +import org.example.util.Result; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 17:38 + */ +@RestController +@RequestMapping("/video") +public class VideoController { + + @Resource + VideoService videoService; + + @PostMapping("/") + public Result pushVideo(@RequestBody PackageSection video){ + videoService.videoApi().pushVideo(video); + return Result.success(); + } + +} diff --git a/chopperbot-console/src/main/java/org/example/service/AccountChannelService.java b/chopperbot-console/src/main/java/org/example/service/AccountChannelService.java new file mode 100644 index 0000000..58e6e2f --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/service/AccountChannelService.java @@ -0,0 +1,15 @@ +package org.example.service; + +import org.example.api.ChannelApi; +import org.example.controller.AccountChannelApi; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 11:05 + */ +public interface AccountChannelService { + + ChannelApi channelApi(); + +} diff --git a/chopperbot-console/src/main/java/org/example/service/AccountService.java b/chopperbot-console/src/main/java/org/example/service/AccountService.java index 14487ed..93fbe58 100644 --- a/chopperbot-console/src/main/java/org/example/service/AccountService.java +++ b/chopperbot-console/src/main/java/org/example/service/AccountService.java @@ -3,6 +3,7 @@ package org.example.service; import org.example.api.AccountApi; +import org.example.api.ChannelApi; import org.example.api.LabelManagerPluginApi; import org.example.api.OpenAPIPluginApi; @@ -18,4 +19,5 @@ public interface AccountService { OpenAPIPluginApi chatGptPlugin(); LabelManagerPluginApi labelManagerPlugin(); + } diff --git a/chopperbot-console/src/main/java/org/example/service/VideoService.java b/chopperbot-console/src/main/java/org/example/service/VideoService.java new file mode 100644 index 0000000..6e8d9a9 --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/service/VideoService.java @@ -0,0 +1,15 @@ +package org.example.service; + +import org.example.api.VideoPublishApi; +import org.example.api.VideoPushApi; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 17:39 + */ +public interface VideoService { + + VideoPushApi videoApi(); + +} diff --git a/chopperbot-console/src/main/java/org/example/service/impl/AccountChannelServiceImpl.java b/chopperbot-console/src/main/java/org/example/service/impl/AccountChannelServiceImpl.java new file mode 100644 index 0000000..ff50eff --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/service/impl/AccountChannelServiceImpl.java @@ -0,0 +1,25 @@ +package org.example.service.impl; + +import org.example.api.ChannelApi; +import org.example.controller.AccountChannelApi; +import org.example.service.AccountChannelService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 11:07 + */ +@Service +public class AccountChannelServiceImpl implements AccountChannelService { + + @Resource + ChannelApi channelApi; + + @Override + public ChannelApi channelApi() { + return channelApi; + } +} diff --git a/chopperbot-console/src/main/java/org/example/service/impl/AccountServiceImpl.java b/chopperbot-console/src/main/java/org/example/service/impl/AccountServiceImpl.java index 0056fac..4768db4 100644 --- a/chopperbot-console/src/main/java/org/example/service/impl/AccountServiceImpl.java +++ b/chopperbot-console/src/main/java/org/example/service/impl/AccountServiceImpl.java @@ -2,6 +2,7 @@ package org.example.service.impl; import org.example.api.AccountApi; +import org.example.api.ChannelApi; import org.example.api.LabelManagerPluginApi; import org.example.api.OpenAPIPluginApi; @@ -40,4 +41,5 @@ public class AccountServiceImpl implements AccountService { public LabelManagerPluginApi labelManagerPlugin() { return labelManagerPluginApi; } + } diff --git a/chopperbot-console/src/main/java/org/example/service/impl/VideoPushServiceImpl.java b/chopperbot-console/src/main/java/org/example/service/impl/VideoPushServiceImpl.java new file mode 100644 index 0000000..b6704ae --- /dev/null +++ b/chopperbot-console/src/main/java/org/example/service/impl/VideoPushServiceImpl.java @@ -0,0 +1,25 @@ +package org.example.service.impl; + +import org.example.api.VideoPublishApi; +import org.example.api.VideoPushApi; +import org.example.service.VideoService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @Description + * @Author welsir + * @Date 2023/11/20 17:40 + */ +@Service +public class VideoPushServiceImpl implements VideoService { + + @Resource + VideoPushApi videoPushApi; + + @Override + public VideoPushApi videoApi() { + return videoPushApi; + } +} diff --git a/chopperbot-publish/src/main/java/org/example/api/VedioPublishApi.java b/chopperbot-publish/src/main/java/org/example/api/VideoPublishApi.java similarity index 52% rename from chopperbot-publish/src/main/java/org/example/api/VedioPublishApi.java rename to chopperbot-publish/src/main/java/org/example/api/VideoPublishApi.java index 0d04b58..c8802da 100644 --- a/chopperbot-publish/src/main/java/org/example/api/VedioPublishApi.java +++ b/chopperbot-publish/src/main/java/org/example/api/VideoPublishApi.java @@ -3,19 +3,23 @@ package org.example.api; import org.example.core.factory.platformSelectionFactory; import org.example.core.publisher.PlatformVideoPublisher; import org.example.pojo.VideoToPublish; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +import java.util.Map; /** * @Description * @Author welsir * @Date 2023/10/13 17:14 */ -public class VedioPublishApi { +@Component +public class VideoPublishApi { - public static void publishVideo(VideoToPublish videoEntity){ - PlatformVideoPublisher publisher = platformSelectionFactory.creatPlatformPublisher(videoEntity.getPlatform().getId()); - publisher.publishVideo(videoEntity); + public void publishVideo(VideoToPublish video){ + PlatformVideoPublisher publisher = platformSelectionFactory.creatPlatformPublisher(video.getPlatform()); + + publisher.publishVideo(video); } - - } diff --git a/chopperbot-publish/src/main/java/org/example/core/factory/platformSelectionFactory.java b/chopperbot-publish/src/main/java/org/example/core/factory/platformSelectionFactory.java index cf81807..2d74822 100644 --- a/chopperbot-publish/src/main/java/org/example/core/factory/platformSelectionFactory.java +++ b/chopperbot-publish/src/main/java/org/example/core/factory/platformSelectionFactory.java @@ -10,14 +10,12 @@ import org.example.core.publisher.impl.DouyinVideoPublisher; * @Date 2023/10/13 21:09 */ public class platformSelectionFactory { - public static PlatformVideoPublisher creatPlatformPublisher(int platformId) { - switch (platformId){ - case 2: - return new BilibiliVideoPublisher(); - case 3: - return new DouyinVideoPublisher(); - default: - throw new IllegalArgumentException("平台参数不正确!"); + public static PlatformVideoPublisher creatPlatformPublisher(String platform) { + if("BILIBILI".equals(platform)){ + return new BilibiliVideoPublisher(); + }else if(platform.equals("DOUYIN")){ + return new DouyinVideoPublisher(); } + return null; } } diff --git a/chopperbot-publish/src/main/java/org/example/core/publisher/impl/BilibiliVideoPublisher.java b/chopperbot-publish/src/main/java/org/example/core/publisher/impl/BilibiliVideoPublisher.java index b34b3eb..f02ca17 100644 --- a/chopperbot-publish/src/main/java/org/example/core/publisher/impl/BilibiliVideoPublisher.java +++ b/chopperbot-publish/src/main/java/org/example/core/publisher/impl/BilibiliVideoPublisher.java @@ -23,6 +23,8 @@ import org.example.utils.VideoDeviceUtil; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; import java.time.LocalTime; import java.util.*; diff --git a/chopperbot-publish/src/main/java/org/example/pojo/VideoToPublish.java b/chopperbot-publish/src/main/java/org/example/pojo/VideoToPublish.java index ccbd992..4a03c1c 100644 --- a/chopperbot-publish/src/main/java/org/example/pojo/VideoToPublish.java +++ b/chopperbot-publish/src/main/java/org/example/pojo/VideoToPublish.java @@ -2,6 +2,8 @@ package org.example.pojo; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; +import org.example.bean.section.PackageSection; /** * @Description @@ -9,17 +11,12 @@ import lombok.Data; * @Date 2023/10/13 19:02 */ +@EqualsAndHashCode(callSuper = true) @Data -@Builder -public class VideoToPublish { +public class VideoToPublish extends PackageSection { - private String videoPath; private String cookies; - private PlatformType platform; - private String coverPath; - private String devicePath; - private String tag; private String title; - private String type; + private String devicePath; } diff --git a/chopperbot-test/config/Barrage/barrageModuleConfig.json b/chopperbot-test/config/Barrage/barrageModuleConfig.json new file mode 100644 index 0000000..036168b --- /dev/null +++ b/chopperbot-test/config/Barrage/barrageModuleConfig.json @@ -0,0 +1,18 @@ +{ + "data":{ + "popularRange":{}, + "barrageScoreCurve":{ + "duration":5000, + "scoreStrategy":"SCORING", + "splitStrategy":"ORDER", + "basicBarrageScore":5 + }, + "InstantSlicing":{ + "ScheduleTime":{ + "duration":1800000 + }, + "handler":"ScheduleTime" + } + }, + "updateTime":"2023-11-19 15:26:27" +} \ No newline at end of file diff --git a/chopperbot-test/config/Creeper/creeperConfig.json b/chopperbot-test/config/Creeper/creeperConfig.json new file mode 100644 index 0000000..c8bd665 --- /dev/null +++ b/chopperbot-test/config/Creeper/creeperConfig.json @@ -0,0 +1,28 @@ +{ + "data":{ + "taskCenter":{ + "queueCapacity":50, + "threads":10, + "waitingTime":1000 + }, + "spiderConfig":{ + "bilibili":{ + "emptySleepTime":100, + "retrySleepTime":100, + "retryTimes":3, + "sleepTime":100, + "threadCnt":5, + "userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48" + }, + "douyu":{ + "emptySleepTime":100, + "retrySleepTime":100, + "retryTimes":3, + "sleepTime":100, + "threadCnt":5, + "userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48" + } + } + }, + "updateTime":"2023-11-19 15:26:26" +} \ No newline at end of file diff --git a/chopperbot-test/config/Creeper/log/creeper-2023-11-19.log b/chopperbot-test/config/Creeper/log/creeper-2023-11-19.log new file mode 100644 index 0000000..a928f05 --- /dev/null +++ b/chopperbot-test/config/Creeper/log/creeper-2023-11-19.log @@ -0,0 +1,6 @@ +{ + "data":{ + "task":[] + }, + "updateTime":"2023-11-19 15:26:26" +} \ No newline at end of file diff --git a/chopperbot-test/config/Hot/hotModuleConfig.json b/chopperbot-test/config/Hot/hotModuleConfig.json new file mode 100644 index 0000000..b1cc2ec --- /dev/null +++ b/chopperbot-test/config/Hot/hotModuleConfig.json @@ -0,0 +1,14 @@ +{ + "data":{ + "HotGuard":{ + "GuardNum":10 + }, + "LiverFollower":{ + "focusLive":1, + "checkTime":60000, + "focusBarrage":1, + "focusRecord":1 + } + }, + "updateTime":"2023-11-19 15:26:27" +} \ No newline at end of file diff --git a/chopperbot-test/config/LiveRecord/liveConfig.json b/chopperbot-test/config/LiveRecord/liveConfig.json new file mode 100644 index 0000000..8434c49 --- /dev/null +++ b/chopperbot-test/config/LiveRecord/liveConfig.json @@ -0,0 +1,8 @@ +{ + "data":{ + "LiveDownload":{ + "showDownloadTable":false + } + }, + "updateTime":"2023-11-19 15:26:26" +} \ No newline at end of file diff --git a/chopperbot-test/config/chopperBotConfig.json b/chopperbot-test/config/chopperBotConfig.json new file mode 100644 index 0000000..5a64e74 --- /dev/null +++ b/chopperbot-test/config/chopperBotConfig.json @@ -0,0 +1,44 @@ +{ + "data":{ + "src":{ + "Account":"./config/Account", + "Creeper":"./config/Creeper", + "LiveRecord":"./config/LiveRecord", + "SectionWork":"./config/SectionWork", + "Hot":"./config/Hot", + "Section":"./config/Section", + "Barrage":"./config/Barrage", + "Publish":"./config/Publish" + }, + "pluginStart":{ + "HotGuard":true, + "SectionWorkShop":true, + "BarrageConfig":true, + "BarrageEvent":true, + "BarrageFileListen":false, + "LiveConfig":true, + "EmotionAnalysis":false, + "BarrageScoreCurve":true, + "FileCacheManager":true, + "LiverFollower":true, + "TaskMonitor":true, + "HotConfig":true, + "TaskCenter":true, + "CreeperManager":true, + "DescriptionGenerate":true, + "InstantSlicing":true, + "LiveDownLoadManager":true, + "BarragePopularRange":true, + "HotRecommendation":true, + "NoticePlugin":true, + "TitleGenerate":true, + "LabelGenerate":true, + "VideoPush":true, + "AccountManager":true, + "LabelManager":true, + "CreeperConfig":true, + "OpenAPI":true + } + }, + "updateTime":"2023-11-19 22:38:29" +} \ No newline at end of file diff --git a/chopperbot-test/src/test/java/org/example/account/TiktokTest.java b/chopperbot-test/src/test/java/org/example/account/TiktokTest.java new file mode 100644 index 0000000..cb18018 --- /dev/null +++ b/chopperbot-test/src/test/java/org/example/account/TiktokTest.java @@ -0,0 +1,119 @@ +package org.example.account; + +import org.example.ConsoleApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.By; +import org.openqa.selenium.Cookie; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @Description + * @Author welsir + * @Date 2023/11/19 15:18 + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = ConsoleApplication.class,webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class TiktokTest { + + @Test + public void pushVideo() throws Exception { + System.setProperty("webdriver.chrome.driver", "D:\\downLoad\\chromedriver_win32\\chromedriver.exe"); + ChromeOptions options = new ChromeOptions(); + options.setBinary("C:\\Program Files (x86)\\Chromebrowser\\Chrome.exe"); + ChromeDriver webDriver = new ChromeDriver(options); + String url = "https://www.tiktok.com/"; + webDriver.get(url); + webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + Scanner scanner = new Scanner(System.in); + scanner.next(); + Set cookies = webDriver.manage().getCookies(); + baocun(cookies); + webDriver.quit(); + ChromeDriver chromeDriver = new ChromeDriver(options); + chromeDriver.get(url); + chromeDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + Set cookieSet = read(); + chromeDriver.manage().deleteAllCookies(); + for (Cookie cookie : cookieSet) { + chromeDriver.manage().addCookie(cookie); + } + chromeDriver.navigate().refresh(); + WebElement uploadButton = chromeDriver.findElement(By.xpath("//*[@id=\"app-header\"]/div/div[3]/div[1]/a")); + uploadButton.click(); + WebDriverWait wait = new WebDriverWait(chromeDriver, 10); + WebElement iframe = wait.until(ExpectedConditions.visibilityOfElementLocated + (By.xpath("/html/body/div/div[2]/div[2]/div/div/iframe"))); + chromeDriver.switchTo().frame(iframe); + System.out.println(iframe); + WebElement file = wait.until(ExpectedConditions.visibilityOfElementLocated + (By.xpath("/html/body/div[1]/div/div/div/div/div/div/div/div/div[4]/button"))); + System.out.println(file); + String filePath = "D:\\soft\\QQ\\1824379011\\FileRecv\\MobileFile\1_1.mp4"; + file.sendKeys(filePath); + WebElement upload = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div/div/div/div/div[2]/div[2]/div[8]/div[2]/button"))); + upload.click(); + } + + @Test + public void updateUser() throws Exception { + System.setProperty("webdriver.chrome.driver", "D:\\downLoad\\chromedriver_win32\\chromedriver.exe"); + ChromeOptions options = new ChromeOptions(); + options.setBinary("C:\\Program Files (x86)\\Chromebrowser\\Chrome.exe"); +// ChromeDriver webDriver = new ChromeDriver(options); + String url = "https://www.tiktok.com/"; + ChromeDriver chromeDriver = new ChromeDriver(options); + chromeDriver.get(url); + chromeDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); + Set cookieSet = read(); + chromeDriver.manage().deleteAllCookies(); + for (Cookie cookie : cookieSet) { + chromeDriver.manage().addCookie(cookie); + } + chromeDriver.navigate().refresh(); + String account = "@user616845559"; + chromeDriver.get(url+account); + WebDriverWait wait = new WebDriverWait(chromeDriver, 10); + WebElement update = wait.until(ExpectedConditions.elementToBeClickable + (By.xpath("/html/body/div[1]/div[2]/div[2]/div/div/div[1]/div[1]/div[2]/div/button"))); + update.click(); + WebElement form = wait.until(ExpectedConditions.elementToBeClickable + (By.xpath("/html/body/div[6]/div/div[2]/div/div/div[2]/div/div/section"))); + WebElement text = wait.until(ExpectedConditions.elementToBeClickable + (By.xpath("/html/body/div[6]/div/div[2]/div/div/div[2]/div/div/section/div/div[2]/div[4]/div[2]/textarea"))); + text.clear(); + text.sendKeys("hahahahaha"); + WebElement save = wait.until(ExpectedConditions.elementToBeClickable + (By.xpath("/html/body/div[6]/div/div[2]/div/div/div[2]/div/div/section/div/div[3]/button[2]"))); + save.click(); + Thread.sleep(10000L); + chromeDriver.navigate().refresh(); + } + public static void baocun(Set cookies) throws Exception { + ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("d:\\4.txt")); + objectOutputStream.writeObject(cookies); + } + + public static Set read() throws Exception { + ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("d:\\4.txt")); + HashSet cookies = (HashSet) objectInputStream.readObject(); + return cookies; + } +} diff --git a/chopperbot-test/src/test/java/org/example/account/bilibiliTest.java b/chopperbot-test/src/test/java/org/example/account/bilibiliTest.java index ac0ec1e..246d160 100644 --- a/chopperbot-test/src/test/java/org/example/account/bilibiliTest.java +++ b/chopperbot-test/src/test/java/org/example/account/bilibiliTest.java @@ -9,6 +9,8 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.nio.file.FileSystems; +import java.nio.file.Path; import java.util.*; import java.util.concurrent.TimeUnit; @@ -80,4 +82,28 @@ public class bilibiliTest { return cookies; } + @Test + public void testFile(){ + String filePath = "D://file//a.mp4"; + + // 使用 Paths.get 方法创建 Path 对象 + Path path = FileSystems.getDefault().getPath(filePath); + + // 获取文件名 + String fileName = path.getFileName().toString(); + System.out.println("File Name: " + fileName); + + // 获取目录路径 + Path directoryPath = path.getParent(); + String directory = (directoryPath != null) ? directoryPath.toString() : "No Directory"; // 处理根目录的情况 + System.out.println("Directory: " + directory); + + + HashMap> objectObjectHashMap = new HashMap<>(); + objectObjectHashMap.putIfAbsent("123",new ArrayList<>()); + List strings = objectObjectHashMap.get("123"); + strings.add("zzzz"); + System.out.println(objectObjectHashMap.get("123")); + } + } diff --git a/config/Barrage/barrageModuleConfig.json b/config/Barrage/barrageModuleConfig.json new file mode 100644 index 0000000..8d872b7 --- /dev/null +++ b/config/Barrage/barrageModuleConfig.json @@ -0,0 +1,18 @@ +{ + "data":{ + "barrageScoreCurve":{ + "scoreStrategy":"SCORING", + "splitStrategy":"ORDER", + "basicBarrageScore":5, + "duration":5000 + }, + "InstantSlicing":{ + "handler":"ScheduleTime", + "ScheduleTime":{ + "duration":1800000 + } + }, + "popularRange":{} + }, + "updateTime":"2023-11-20 11:19:28" +} \ No newline at end of file diff --git a/config/Creeper/creeperConfig.json b/config/Creeper/creeperConfig.json new file mode 100644 index 0000000..ed26207 --- /dev/null +++ b/config/Creeper/creeperConfig.json @@ -0,0 +1,28 @@ +{ + "data":{ + "taskCenter":{ + "queueCapacity":50, + "threads":10, + "waitingTime":1000 + }, + "spiderConfig":{ + "douyu":{ + "emptySleepTime":100, + "retrySleepTime":100, + "retryTimes":3, + "sleepTime":100, + "threadCnt":5, + "userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48" + }, + "bilibili":{ + "emptySleepTime":100, + "retrySleepTime":100, + "retryTimes":3, + "sleepTime":100, + "threadCnt":5, + "userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48" + } + } + }, + "updateTime":"2023-11-20 11:19:28" +} \ No newline at end of file diff --git a/config/Creeper/log/creeper-2023-11-20.log b/config/Creeper/log/creeper-2023-11-20.log new file mode 100644 index 0000000..aff4eff --- /dev/null +++ b/config/Creeper/log/creeper-2023-11-20.log @@ -0,0 +1,6 @@ +{ + "data":{ + "task":[] + }, + "updateTime":"2023-11-20 11:19:28" +} \ No newline at end of file diff --git a/config/Hot/hotModuleConfig.json b/config/Hot/hotModuleConfig.json new file mode 100644 index 0000000..802e745 --- /dev/null +++ b/config/Hot/hotModuleConfig.json @@ -0,0 +1,14 @@ +{ + "data":{ + "LiverFollower":{ + "checkTime":60000, + "focusBarrage":1, + "focusRecord":1, + "focusLive":1 + }, + "HotGuard":{ + "GuardNum":10 + } + }, + "updateTime":"2023-11-20 11:19:28" +} \ No newline at end of file diff --git a/config/LiveRecord/liveConfig.json b/config/LiveRecord/liveConfig.json new file mode 100644 index 0000000..b3f0bc5 --- /dev/null +++ b/config/LiveRecord/liveConfig.json @@ -0,0 +1,8 @@ +{ + "data":{ + "LiveDownload":{ + "showDownloadTable":false + } + }, + "updateTime":"2023-11-20 11:19:28" +} \ No newline at end of file diff --git a/config/chopperBotConfig.json b/config/chopperBotConfig.json new file mode 100644 index 0000000..aebabaf --- /dev/null +++ b/config/chopperBotConfig.json @@ -0,0 +1,45 @@ +{ + "data":{ + "src":{ + "Account":"./config/Account", + "Creeper":"./config/Creeper", + "LiveRecord":"./config/LiveRecord", + "SectionWork":"./config/SectionWork", + "Hot":"./config/Hot", + "Barrage":"./config/Barrage", + "Section":"./config/Section", + "Publish":"./config/Publish" + }, + "pluginStart":{ + "HotGuard":true, + "SectionWorkShop":true, + "BarrageConfig":true, + "BarrageFileListen":false, + "BarrageEvent":true, + "channel":true, + "LiveConfig":true, + "BarrageScoreCurve":true, + "EmotionAnalysis":false, + "FileCacheManager":true, + "LiverFollower":true, + "TaskMonitor":true, + "HotConfig":true, + "TaskCenter":true, + "CreeperManager":true, + "DescriptionGenerate":true, + "InstantSlicing":true, + "LiveDownLoadManager":true, + "BarragePopularRange":true, + "HotRecommendation":true, + "NoticePlugin":true, + "TitleGenerate":true, + "LabelGenerate":true, + "VideoPush":true, + "AccountManager":true, + "LabelManager":true, + "CreeperConfig":true, + "OpenAPI":true + } + }, + "updateTime":"2023-11-20 19:09:52" +} \ No newline at end of file diff --git a/database.db b/database.db index af607e4eacd68c7b2d5cc832f67adaa07093d217..ac8e05ae98d5b338f0e37552f05b773d7b5bfa26 100644 GIT binary patch literal 110592 zcmeI*e{d65egJUE@(*l+m%IFM2$MNs!VwY{_P16ro~e;#!W}rl*iImKBUZaBTUeGH zOCpfAGq%BCV~kDs6|lpvga8Q!k`OSqft&m5I_-bGNv|`V&Lq{YscbarW1H`+cAHcEx*ombPr(7>udTK%}ijiaA-^LYv)g`!lE0X0t6v z|1C!UWtLL3lAqZ?|F>J#@3*?#wrb1v1;p=c&)CatrJoRYO1IDdqIB_s&r2@OzcMdX z(pus!$t(J=qSb|G3u1-ALMH!sf!Fbs!<%=`{yTfQ{jctq@i(`>Xl{o?35Zo!41cxo)G^xjnsiyVLo6iPO0~sBCv`sHyX=_trXVUaoW2 z)NkCl5+4XlE$Vh>o%c1g&$_=Y5|7Pv;Fa19n<{I!I)Ccj>U=(^tiYMn*KF8a?{z+p z^IB1|f_$d1ta7p477Q!uuIL*fRI5HI9*Y>;zI0$dI=!;ElqPRS$lowC0h~o0-?r2PHDKDN<6UF7R-L0y*du2(nC8+0dR?f=$ zx|cW9plfdO*3=>Uj^$68m<1+gSPJcq2BYaXrQFT3+*qd^#qm0w##MshnA)he<+PAY z#Lk$yE0%jij;aIsrjD;;>JB_$;q|ZHBRJLrHy>q@1X)G8Esp&AS>rdszXg&1J zfUbPpyysRMVK%nLe9h|a^#7j74KBUcj0>GLLv6;}LNn}bi74t!`vdW?91BLmQ<6BV zyw#QU8|$3QQG1S|t1eI9g6Q6R;z9RbIzS(tUU{-(?LxCjR~V(+8C2AWFC_WZkY)7; zxuvumd2kIF`S@^y&uP@@SW#;(H_o{4VN0u-xv}#NPXAr(E_ z(aW{mG?}P1B*pNH`1G2e`T)z6B(%VIX6+%2l0;Rb&HGxVw&q~Camr?CZpo$`eQ<*` zYqM2~S)vUEcdBiZ!TY7QHmOnd1%e@qLriL%JVlXWmP47+W{+DcYvxwlSypV^b9>@O zaRU)K9`zYvSXN7Ni)lGBy@=+^uW>(37AE^dw%l%Qk;n|SVmTqVFxf0{);R>yPAMi? z)KF`{FYwcwRrX0mPpx}=4@`aW;vaj^jcGCPv6hVm{QTJ_V=T!Y<4b0njJ713-I;P;Z~Bx-V<3`Qn>V%cG6$yDUFP3hmP$ZbWp5oU|A0zCuN!gnsyTVn zW~(deKfW=-1Myp@U8x^(;=i0{YTzz{gDASL7-9KW0Kt&!q4bMYl2^vl%@N1}41ZH8us6Xos^3-K>lKmY_l00ck)1V8`;KmY_l00ck)1iq^RCAeVF|NpL5FO&-eKmY_l z00ck)1V8`;KmY_l00ayH{QiFdanVMkh~E&uB5t8oSU>;-KmY_l00ck)1V8`;KmY_l z00jPj1WF4WON%Xk)=cC(mK9t7EVtC*SUS)0hm)mwjwSZVKWHg@%I=`;GyHu9?*A7O zZ`gY>4u;eFpLP`6o;CCF2SY*pU;4-sdBwIT z%_B|m-BNll+G8s-_u_ow>D_q#elNnXYH8@ z0*-l(C+)_ZfO(FxVq+SBG5^2xjt%wuPY^z0Md`nx4Ol<`1V8`;KmY_l00ck)1V8`; zK;YXXz!etR>K8p;Y!m!}K!EY{q@uD4$q9arlvsf$X_@CF)JE)DAltlLQx6GE}j)gzrvzaE>$5#KO>MbE4pM^a#Io~X1eJp z9g~OBJ&DuNiXymak@O3SL~6oO1_a!rM`>6)N>he4WRYWO#ZRiV zD3Ba4q2PFyA_bQux+ItC=M>K9{G&uL|Nq<6pdl6z009sH0T2KI5C8!X009sH0T6f; z0X)zD!Sny|`~UF$e~)4dX+Qu3KmY_l00ck)1V8`;KmY_lVD1Ru_y3{)KX>X2A_V~u z009sH0T2KI5C8!X009sHfkzR5{{N$>K^hPM0T2KI5C8!X009sH0T2KI5SUv6(Ep!X z^###_00@8p2!H?xfB*=900@8p2!Oz&2*BU}KZ+Wp0Ra#I0T2KI5C8!X009sH0T2Lz zxg~)6|Mrr%Z0H9T5C8!X009sH0T2KI5cm@c9QgCz-;e#_mmiD{pzpd`dhB(ApjpZ# zQat5m_}B4wVfl8*u?kU=0|G<)12oG^G%t&^#H)Tm3b+`77kSrOr@E^(*rrA+w8NLQ zuHltVT6FUIP`8tz7|u!YYZ&xHJ3U+K);e3ISX0I7wN53{A_c=0t1{oXwMve(taSQ) z;drcqc2N}PVi-4{oAuxz%G&Lu>2%(LkvF%7=Vz05m8z)qQMGMDRRt%~6#jNGCO7}D z7kYeWP~j?g*5l@=Y7go1u$5$$r@ES?y)K6Ix`b-BT5yY0Wwo0Vc%GyfmZlksa+A4H z+_#k6Y)a|JVfX^A6#-5WTmiSAlPOer3QM_Zx8ILeX^E0m#XZZ5&WhIW3q^xUMYY%E zW$0?Rj~3T?J(R~Kdbo$yIF6UCpu{Sa)-94e<*6pUqK6^f0{S92j&%tf?{-zwH0$O$ znhJ&k5&4f9yDuI`p|e%Ir>d$-AlYi3A$i^-pf7o=qA8LW(09xUC+& zJ($}tvyGmaO_fbHOrK9~-lXsqBFC#VrK+kV1<;q){W0&bE#56#sw(R$D@2+WC`M+N zF&^55S2>np&<6U_KF+m_sr1vH9aWoZg0YCZmU-#TPy@Zb>L-yp|CS9L8`<5km9C0; zsjV#yyEc0~>+4w6zq!GqsOl?ky}I*NA^4N#ms&&3&088m?m9oSD=yc!dL=3psr4#s zZMfl$+8s@AZEfb))i6yP zZB&)xZR*;UPTa!zxDerD?3A15Yh?d(iiY?9|Aa4bkTnQ^00@8p2!H?xfB*=900@8p z2z*NfaR0xc^dD@*uZRKSHR2hx3JVB;00@8p2!H?xfB*=900@8p2+Sz~?tjqohs5YW ze!i`KSwK)#QRG~tEHNU%7QrQ|1fwL6#1)T=Vr&O@mei87jW!?Au+kpux< zTa`(-U!+LIA8^s4>zf^l@T+cydF3$v z{J#R?IU8|_c!l^2;@4;u77zdd5C8!X009sH0T2KI5C8!X_+ARU=%~-1&FI13Kf5p= zpF5ke0(7nepF5k80d#I2K6f^w0q9&iK6f@F0KfV9Lc7`jziK1?mH3=U5Wgg@elM#S z3Jn4v00JNY0w4eaAOHd&00JNY0^cHm#~sV^t#cIchy&hdoq2#q78W=b<(u;f@Yn&~ zGG__k(E;O_@!mh~{~MqGM;x}HA6P&D1V8`;KmY_l00ck)1V8`;KmY{3DS;MyLDW~a zIND6^YOJq{y{yzWZr&Jde2b}~R8FoG(BBbow8}A}t1{pTpwDU)*U=vI`KVN&DHdyu zu35c05>}u#z+qDL@W6He>?H-HuM7v z2!H?xfB*=900@8p2!H?xfB*=9z;{WY#Id+I-Tyb<|DXSB8~T9-1V8`;KmY_l00ck) z1VCU83Usfq7uW_iEYi>JpE&`8slp&#neuJ;F(YG?qMdbze*ALk(5=KskN$4E^vl(L>3jw-7!8PmYbJdPenkFPO;M#d~^thd$JFOUX0Csf+t2&L7tLPN7TS7|!0-`>vwk%^=aG&G59h zjqtMZ7&)UjaqI0KF!R&~Mzrx`$)WM&0B-ro?tRIQkMPQs543@9?amQgo1b;0&K=ax zpTO*ytD88;P5<%eh+hgB{r}Q0ZRiIU5C8!X009sH0T2KI5C8!X009t~ z!vdX;_x^tL%-?;AJ{rHkwzup@(+3(7BS-K+!%(j|NP&9esf(S7@e`pwiv-hno)101P)gJ{S=>)xlI9>AjsdvBugEOVS9_q3yE%nS9>jR6-lkaQN0 zKN&+IseAZPdMIJ29SufIw0EMbn8Oz4IcO|HyK^3mr{Gb!tDj{DQ?erw=4sghi1ctn z*UiM(as9+ut?N@9wlN~3AHS`i>qeQI{r^#0>F6A;Vh9}sKmY_l00ck)1V8`;KmY_l z;5#hP>B0T^zg%RUGLZUguYT)e)XOz{@~L|RsR1-&VpKc)4(gVhJ%6)Xj^D92-%cMp zX}$xWo}rLCZNcnOqnQQf>;~Ke??0Kkcirfg_oDabQ9nGLu>UZcXn#Nggk$I;~A8SDD07goKn z5RC&YE>qNi6c5GF_No`~=l|ys3H15@=oc&?00JNY0w4eaAOHd&00JNY0w4eab5>xX RW0~DL5|D>K|35tl@V`1d+MWOa delta 1115 zcmYk3OKclO9L9INyI$|w-f?1EPLxD)32ju8N%v{*3ZwwNqz9x5#IbT`cW0>;W0%A( z@&TMj53K;HWh4RxRYB!K1v%IyJfwyYRS3bQQYF*_2NZ>*fH<@SDIAa(Cjn)pd3^KV z-}m30Z}#Wt?2>q8pl6WdxGWq0J<8QF(;no;UpSkDyIe*XTu#IsHO8Ahl8jd!&+@ z&nBhZ=qOmgl#daiieD!52u#zHa)xR!4rcb$by=n(FewDMzF%I6nUPqWex@D+3Hp<| z!RD`_BP8c@68$~)7>H3-{)@h%9H(PSLW`Hh)UrF?-*D|YN~jb2j{ zf;=A)=}jdMqVxx4gU!ovgO^SV)KiZGk-n)O;}@m@-HdA>(#a;)0pRJ7dV)%7nioz+ z*#23WXK}{5k+z=}G=+zEIQRhGhj&;;D=^c`^TWcSdpLC_&(r%8s3V?VS6h}|bP2JL zWBCrU3{yj{RV0YmnyFzE>jm4Xzgn*Q=WwNBi4yl>e_G}=9AeF}UF2JYAj=6nggw_r znjIDm*9dh|!1eM}y*AaQgab-9-GXL#2J!+8Bg?f3a$2FGA;a)O$H9!%jiA58BM?+djoTBODK(}nKTq$=4f5mKhchF6cfg*q%WO1!7=K zI=ijd*>+w?-4ODrgaB7L_z-TudvKLq_%eJRUi^M%jpwS}>l}Ope}tQGo%y!mM4CS; z9JcHRndJM0eMhDuUA1q>6xgfn`ArTn)d6clUWAu9c$xXNV6*|mnbOGO;sn65Ic}qR zW7?~I{`Uk(q(s=q!9Mny3gO(DH+H_+{q5dYOF-lnMi(De!CiUloiDdOytMhn?7#0= BNxJ|5