From 23ed2e43cc23c914375f82e6f8bb1b410d3a75f5 Mon Sep 17 00:00:00 2001 From: lunaticbum <> Date: Fri, 11 Oct 2024 17:17:57 +0900 Subject: [PATCH] ... --- build.gradle.kts | 1 + .../back/lun/controllers/Telegram.kt | 190 +++++++++------ .../lunaticbum/back/lun/model/BumsPrivate.kt | 230 +++++++++++++++++- src/main/resources/static/css/blog.css | 23 ++ src/main/resources/static/css/common.css | 45 +++- .../templates/content/blog/write.html | 33 ++- 6 files changed, 428 insertions(+), 94 deletions(-) create mode 100644 src/main/resources/static/css/blog.css diff --git a/build.gradle.kts b/build.gradle.kts index d01bc82..7814a65 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -43,6 +43,7 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") implementation("org.springframework.boot:spring-boot-starter-thymeleaf") implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") + implementation ("org.jsoup:jsoup:1.18.1") implementation("org.springframework.boot:spring-boot-starter-security") compileOnly("org.projectlombok:lombok") runtimeOnly("org.mariadb.jdbc:mariadb-java-client") diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt b/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt index 7274ef4..c40d756 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt @@ -2,21 +2,22 @@ package kr.lunaticbum.back.lun.controllers import com.google.gson.Gson import jakarta.servlet.http.HttpServletRequest +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch import kr.lunaticbum.back.lun.configs.GlobalEnvironment -import kr.lunaticbum.back.lun.model.CurrentWeather -import kr.lunaticbum.back.lun.model.Message -import kr.lunaticbum.back.lun.model.TelegramMsgService -import kr.lunaticbum.back.lun.model.TelegramUpdate +import kr.lunaticbum.back.lun.model.* import kr.lunaticbum.back.lun.utils.LogService +import org.jsoup.Jsoup import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.scheduling.annotation.Scheduled import org.springframework.web.bind.annotation.* import org.springframework.web.reactive.function.client.WebClient +import java.text.SimpleDateFormat import java.util.* @@ -32,18 +33,56 @@ class Telegram { @Autowired lateinit var logService: LogService + @Autowired + lateinit var locationLogService: LocationLogService + @ResponseBody @GetMapping("hello") fun hello(): String { return "hello1212" } + @Autowired + lateinit var rssDataService: RssDataService + @ResponseBody @PostMapping("webhook") - fun test(httpServletRequest: HttpServletRequest, @RequestBody update : TelegramUpdate?) { + fun test(httpServletRequest: HttpServletRequest, @RequestBody update : kr.lunaticbum.back.lun.model.Result) : String { try { - logService.log("test strat ${update}") + logService.log("test strat ${Gson().toJson(update)}") +// logService.log("test strat ${Gson().toJson(update)}") logService.log("test strat ${httpServletRequest.requestURI}") + update?.message?.let { + if(it.text?.startsWith("/") == true) { + it.text?.split(" ")?.let { cmds -> + cmds[0].let { cmd -> + when(cmd.trim()) { + "/get" ->{} + "/jf" ->{ + CoroutineScope(Dispatchers.IO).launch { + logService.log("${cmd[0]} Start ${cmd[1]}") + String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService) } + logService.log("${cmd[0]} END ${cmd[1]}") + } + CoroutineScope(Dispatchers.IO).launch { + logService.log("on Cmd JF with SO") + logService.log("${cmd[0]} Start ${cmd[1]}") + String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmd[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService)} + logService.log("${cmd[0]} END ${cmd[1]}") + } + } + else -> {} + } + } + } + if (it.text?.contains(" ") == true) { + + } else { + + } + } + if (it.text?.contains("어디") == true) { it.from?.id?.let { sendMsg(it.toString()) } } + } // val client0 = WebClient.create() // client0.get() // .uri("https://api.telegram.org/bot7934509464:AAE_xUbICxMdywLGnxo7BkeIqA1nVza4P9w/getUpdates") @@ -71,8 +110,8 @@ class Telegram { // fun test(@RequestBody str : String) { // println("path >>> $str") //>>>>>>> ab915d0a416c69708f1df1ad76d7a14c779c1f59 - } + return "Success" } @@ -110,76 +149,79 @@ class Telegram { } - @Bean - @Scheduled(cron = "0 0/2 * * * *") // - fun pollingTelegramUpdate() { - try { - logService.log("pollingTelegramUpdate telegramBotKey >>>> ${globalEvv.telegramBotKey}") - logService.log("pollingTelegramUpdate telegramMyId >>>> ${globalEvv.telegramMyId}") - logService.log("pollingTelegramUpdate weatherApiKey >>>> ${globalEvv.weatherApiKey}") - if ( - ((globalEvv.weatherApiKey?.length ?: 0) > 3 )&& - ((globalEvv.telegramBotKey?.length ?: 0) > 3 )&& - ((globalEvv.telegramMyId?.length ?: 0) > 3) - ) { - val client0 = WebClient.create() - val result = client0.get() - .uri("https://api.telegram.org/${globalEvv.telegramBotKey}/getUpdates") - .retrieve() - .bodyToMono(String::class.java).block() ?: "FAIL" - logService.log("pollingTelegramUpdate result >>>> $result") - Gson().fromJson(result, TelegramUpdate::class.java)?.let { sss -> - logService.log("pollingTelegramUpdate sss >>>> $sss") - if (sss.isSucces()) { - sss.result?.filter { - ((it.message?.date ?: 0L) * 1000L) > before5Min() - }?.forEach { - logService.log("pollingTelegramUpdate before Query doOnSuccess m >>>> ${it}") - it.message?.let { msg -> - logService.log("pollingTelegramUpdate before Query doOnSuccess m >>>> ${msg.message_id}") - qns(msg.message_id,msg) - } - } - } - } - } - }catch (e : Exception) { - e.printStackTrace() - } - } +// @Bean +// @Scheduled(cron = "0 0/2 * * * *") // +// fun pollingTelegramUpdate() { +// try { +// logService.log("pollingTelegramUpdate telegramBotKey >>>> ${globalEvv.telegramBotKey}") +// logService.log("pollingTelegramUpdate telegramMyId >>>> ${globalEvv.telegramMyId}") +// logService.log("pollingTelegramUpdate weatherApiKey >>>> ${globalEvv.weatherApiKey}") +// if ( +// ((globalEvv.weatherApiKey?.length ?: 0) > 3 )&& +// ((globalEvv.telegramBotKey?.length ?: 0) > 3 )&& +// ((globalEvv.telegramMyId?.length ?: 0) > 3) +// ) { +// val client0 = WebClient.create() +// val result = client0.get() +// .uri("https://api.telegram.org/${globalEvv.telegramBotKey}/getUpdates") +// .retrieve() +// .bodyToMono(String::class.java).block() ?: "FAIL" +// logService.log("pollingTelegramUpdate result >>>> $result") +// Gson().fromJson(result, TelegramUpdate::class.java)?.let { sss -> +// logService.log("pollingTelegramUpdate sss >>>> $sss") +// if (sss.isSucces()) { +// sss.result?.filter { +// ((it.message?.date ?: 0L) * 1000L) > before5Min() +// }?.forEach { +// logService.log("pollingTelegramUpdate before Query doOnSuccess m >>>> ${it}") +// it.message?.let { msg -> +// logService.log("pollingTelegramUpdate before Query doOnSuccess m >>>> ${msg.message_id}") +// qns(msg.message_id,msg) +// } +// } +// } +// } +// } +// }catch (e : Exception) { +// e.printStackTrace() +// } +// } - fun qns(it : String, msg : Message) { - var doSave = true - telegramService.findById(it)?.subscribe( { m -> - logService.log("pollingTelegramUpdate doOnSuccess m >>>> $m") - if (m != null) { - if (msg.text?.contains("어디") == true) { +// fun qns(it : String, msg : Message) { +// var doSave = true +// telegramService.findById(it)?.subscribe( { m -> +// logService.log("pollingTelegramUpdate doOnSuccess m >>>> $m") +// if (m != null) { +// if (msg.text?.contains("어디") == true) { +// +// } else { +// logService.log(msg.text ?: "NONE") +// } +// } else { +// doSave = false +// } +// },{ e -> +// e.printStackTrace() +// },{ +// if (doSave) { +// telegramService.save(msg) +// if (msg.text?.contains("어디") == true || msg.text?.startsWith("\"") == true) { +// sendMsg() +// } +// } +// logService.log("pollingTelegramUpdate doOnSuccess comp") +// }) +// } - } else { - logService.log(msg.text ?: "NONE") - } - } else { - doSave = false - } - },{ e -> - e.printStackTrace() - },{ - if (doSave) { - telegramService.save(msg) - if (msg.text?.contains("어디") == true || msg.text?.startsWith("\"") == true) { - sendMsg() - } - } - logService.log("pollingTelegramUpdate doOnSuccess comp") - }) - } - - fun sendMsg() { + fun sendMsg(target : String) { val client = WebClient.create() - client.get() - .uri("https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage?chat_id=${globalEvv.telegramMyId}&text=/g_mustShareLocation") - .retrieve() - .bodyToMono(String::class.java).block() ?: "FAIL" + locationLogService.getLocationLog()?.let { + client.get() + .uri("https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage?chat_id=${target}&text=${SimpleDateFormat("yyyy/MM/dd-HH:mm:ss").format(Date(it.time))}\n${it.mAddressLines.first()}") + .retrieve() + .bodyToMono(String::class.java).block() ?: "FAIL" + } + } diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/model/BumsPrivate.kt b/src/main/kotlin/kr/lunaticbum/back/lun/model/BumsPrivate.kt index f3ac359..0124c16 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/model/BumsPrivate.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/model/BumsPrivate.kt @@ -1,15 +1,23 @@ package kr.lunaticbum.back.lun.model +import com.google.gson.Gson import kr.lunaticbum.back.lun.utils.LogService import lombok.AllArgsConstructor import lombok.Data import lombok.NoArgsConstructor +import org.jsoup.Jsoup import org.springframework.beans.factory.annotation.Autowired +import org.springframework.data.annotation.Id +import org.springframework.data.domain.Page import org.springframework.data.mongodb.core.mapping.Document import org.springframework.data.mongodb.repository.ReactiveMongoRepository import org.springframework.stereotype.Repository import org.springframework.stereotype.Service import reactor.core.publisher.Mono +import java.text.SimpleDateFormat +import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.List class BumsPrivate { } @@ -64,7 +72,7 @@ class LocationLog { @Repository interface LocationLogRepository : ReactiveMongoRepository { - + fun findFirstByOrderByTimeDesc() : Mono fun save(log: LocationLog): Mono } interface LocationService { @@ -79,6 +87,9 @@ class LocationLogService : LocationService { @Autowired private lateinit var logRepository: LocationLogRepository + fun getLocationLog() : LocationLog? { + return logRepository.findFirstByOrderByTimeDesc().block() + } fun save(log: LocationLog) { @@ -88,4 +99,221 @@ class LocationLogService : LocationService { }) } +} + +interface RssDataInterface { + fun title() : String + fun thumbnailUrl() : String + fun originPage() : String + fun description() : String + fun pubDate() : Long + fun category() : RssDataType + fun getCho() : String? + +} +enum class RssDataType { + NO_DATA, + YOUTUBE, + NewsFeed, + GURU, + Most, + TAGS, + REDDIT, + REDDIT_nsfw, + Dotax, + FmKorae, + DcInside, + RuliWeb, + Clien, + TheQoo, + Arca; + +// fun getResId() = when (this) { +// YOUTUBE -> R.drawable.youtube +// REDDIT, REDDIT_nsfw -> R.drawable.reddit +// Dotax -> R.drawable.daum +// FmKorae -> R.drawable.fmk +// DcInside -> R.drawable.dcinside +// Arca -> R.drawable.arca +// else -> { +// 0 +// } +// } + + fun defaultImgSize() = when (this) { + YOUTUBE -> 200 + REDDIT_nsfw,GURU,Most -> 360 + else -> { 120 } + } + +// fun getDefaultVisibiliy() = when (this) { +// REDDIT_nsfw,GURU,Most,NewsFeed -> View.GONE +// else -> { View.VISIBLE } +// } +} +class RssData : RssDataInterface { + + @Id + var originPage : String? = null + var title : String? = null + var description : String? = null + var thumbnail : String? = null + var pubDate : Long = 0L + var category : String? = null + + var chosung : String? = null + + + var mRssDataType : RssDataType? = null + override fun title(): String { + return when(category()){ + RssDataType.NewsFeed -> { + if(title?.length ?: 0 > 30) title?.substring(0,30).plus("...") else title ?: "" + } + else -> title ?: "" + }.apply { +// chosung = JamoUtils.split(this).joinToString("") + } + } + + override fun thumbnailUrl(): String { + return thumbnail ?: "" + } + + override fun originPage(): String { + return originPage ?: "" + } + + override fun description(): String { + + return when(category()){ + RssDataType.YOUTUBE -> { + if(description?.contains("게시자") == true) description!!.split("게시자")[0] else description ?: "" + } + RssDataType.NewsFeed -> { + category().name + } + else -> description.plus(" / ").plus(category().name) + } + } + + override fun pubDate(): Long { + return pubDate + } + + override fun category(): RssDataType { + if (mRssDataType == null) + mRssDataType = RssDataType.valueOf(category!!) + return mRssDataType!! + } + + override fun getCho(): String? { + return chosung + } +} + + +val USAGT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15" +fun String.getJ() = Jsoup.connect(this).userAgent(USAGT).get() +object FeedParseManager { + val parsers = listOf(QVZTb2dpcmw,SkFWTW9zdA) + fun parse(doc : org.jsoup.nodes.Document, service: RssDataService) { + try { + parsers.filter { doc.title().contains(it.getName()) }.first()?.let { + it.parse(doc,service) + } + } catch (e : Exception) { + + e.printStackTrace() + } + } +} +interface SoInterface{ + fun getName() : String + fun parse(doc : org.jsoup.nodes.Document,service: RssDataService) +} +object QVZTb2dpcmw : SoInterface { + override fun getName(): String { + return String(Base64.getMimeDecoder().decode(this.javaClass.simpleName.plus("==").toByteArray())) + } + override fun parse(doc : org.jsoup.nodes.Document, service : RssDataService) { + doc.getElementsByTag("article").forEach { article -> + + val title = article.getElementsByTag("a").get(0).attr("title") + val href = article.getElementsByTag("a").get(0).attr("href") + val img = article.getElementsByTag("img").get(0).attr("data-src") + service.save(RssData().apply { + this.originPage = href + this.title = title + this.description = "Sogirl" + this.thumbnail = img + this.pubDate = Date().time + this.category = RssDataType.GURU.name + }) + } + } +} + +object SkFWTW9zdA : SoInterface { + var dmy = SimpleDateFormat("dd-MM-yyyy") + override fun getName(): String { + return String(Base64.getMimeDecoder().decode(this.javaClass.simpleName.plus("==").toByteArray())) + } + override fun parse(doc: org.jsoup.nodes.Document, service: RssDataService) { + doc.getElementsByClass("card").forEach { card -> + var thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("src") else "" + if (thumb.contains("No+Poster")) thumb = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("data-src") else thumb + var model = if(card.getElementsByTag("img").size > 0) card.getElementsByTag("img").get(0).attr("alt") else "" + if(card.getElementsByClass("card-block").size > 0) if(card.getElementsByClass("card-block").size > 0) { + val link = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("href") + val title = card.getElementsByClass("card-block").get(0).getElementsByTag("a").get(0).attr("title") + val date = card.getElementsByTag("span").get(0).text() + service.save(RssData().apply { + description = model + thumbnail = thumb + originPage = link + this.title = title + try { + pubDate = dmy.parse(date).time + }catch (e : Exception) {e.printStackTrace()} + }) + } + } + } +} +@Repository +interface RssDataRepository : ReactiveMongoRepository { + fun findFirstByOriginPageEquals(originPage : String): Mono + fun findAllByOrderByPubDate() : Mono> + fun save(log: RssData): Mono +} + +@Service +class RssDataService { + @Autowired + private lateinit var logService: LogService + + @Autowired + private lateinit var rssDataRepository: RssDataRepository + fun hasItem(originPage : String) { + + } + fun getLocationLog() : List? { + return rssDataRepository.findAllByOrderByPubDate().block() + } + + + fun save(log: RssData) { + println("saved msg before ${Gson().toJson(log)}") + log.originPage?.let { + if(rssDataRepository.findFirstByOriginPageEquals(it).block() == null) { + rssDataRepository.save(log) + .subscribe({ println("saved msg after ${it}") }, { e -> e.printStackTrace() }, { + println("saved msg comp") + }) + } else { + println("있어???") + } + } + } } \ No newline at end of file diff --git a/src/main/resources/static/css/blog.css b/src/main/resources/static/css/blog.css new file mode 100644 index 0000000..326e028 --- /dev/null +++ b/src/main/resources/static/css/blog.css @@ -0,0 +1,23 @@ +:root{ + --ButtonWidth:45%; + --ButtonHeight:45px; +} + + +#save { + right: 0; + position: absolute; + width: var(--ButtonWidth); + height: var(--ButtonHeight); +} +.layer > * { + height: var(--ButtonHeight); +} +input { + width: 100%; +} +select , #hashtag{ + margin-left: 1%; + width: fit-content; + margin-right: 1%; +} diff --git a/src/main/resources/static/css/common.css b/src/main/resources/static/css/common.css index 3b0205a..e93d26b 100644 --- a/src/main/resources/static/css/common.css +++ b/src/main/resources/static/css/common.css @@ -1,38 +1,63 @@ :root { - --WindowFull : 100svh; - --TopHeight: 50px; - --FooterHeight: 120px; + --WindowFull : 100%; + --TopHeight: 160px; + --FooterHeight: 160px; + --ContentVerticalMargin: 5px; +} +input, select ,button{ + color: white; + background: #2d2f34; + border: black; + border-width: 1px; + padding: 0; + margin: 0; + position: relative; } - body, html { background-color: black; margin: 0px; - margin-left: 2.5%; - margin-right: 2.5%; height: 100lvh; - width: 95%; } header { + width: 100%; align-content: center; position: relative; background-color: Gray; height: var(--TopHeight); + background-image: url("../blog/post/images/42cc3207-42a4-4ceb-8a2f-f5f7a89496fc.jpg"); + background-repeat: revert; + background-size: contain; + background-origin: revert; } #content { + margin-left: 2.5%; + margin-right: 2.5%; position: relative; + overflow-y: auto; + overflow-x: clip; + background: black; + min-height: calc((var(--TopHeight) + var(--FooterHeight)) * 2); height: calc(var(--WindowFull) - calc(var(--FooterHeight) + var(--TopHeight))); + background-image: url("../blog/post/images/bb109b5a-f907-4da1-9c4f-55533395ed6e.jpg"); + background-repeat: revert; + background-size: contain; + background-origin: revert; } #content > * { - margin-top: 5px; - margin-bottom: 5px; + margin-top: var(--ContentVerticalMargin); + margin-bottom: var(--ContentVerticalMargin); } footer { + width: 100%; align-content: center; position: relative; height: var(--FooterHeight); - background-color: aquamarine; + background-image: url("../blog/post/images/42cc3207-42a4-4ceb-8a2f-f5f7a89496fc.jpg"); + background-repeat: revert; + background-size: contain; + transform: scaleY(-1); } \ No newline at end of file diff --git a/src/main/resources/templates/content/blog/write.html b/src/main/resources/templates/content/blog/write.html index 12295de..7b32e75 100644 --- a/src/main/resources/templates/content/blog/write.html +++ b/src/main/resources/templates/content/blog/write.html @@ -7,20 +7,33 @@ + - +
- +
+ +
-
+
-
- +
+