From 7c4d5cde6949dd31ff7715209485bf43b5a3e75b Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Thu, 27 Feb 2025 17:08:15 +0900 Subject: [PATCH] .... --- build.gradle.kts | 5 + .../kr/lunaticbum/back/lun/LunApplication.kt | 7 +- .../back/lun/controllers/Telegram.kt | 340 +++++++++--------- .../lunaticbum/back/lun/model/PlaceGoogle.kt | 173 ++++++--- .../back/lun/model/TelegramUpdate.kt | 4 +- .../back/lun/utils/CompressStringUtil.kt | 99 +++++ 6 files changed, 422 insertions(+), 206 deletions(-) create mode 100644 src/main/kotlin/kr/lunaticbum/back/lun/utils/CompressStringUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index 9e7d482..f70b70c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,6 +53,11 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-security") compileOnly("org.projectlombok:lombok") +// implementation(platform("com.google.cloud:libraries-bom: 26.55.0")) +// implementation("com.google.cloud:google-cloud-apikeys") + implementation ("com.google.maps:google-maps-services:2.2.0") + implementation ("org.slf4j:slf4j-simple:1.7.25") + implementation("io.jsonwebtoken:jjwt-api:0.11.5") implementation("io.jsonwebtoken:jjwt-impl:0.11.5") implementation("io.jsonwebtoken:jjwt-jackson:0.11.5") diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/LunApplication.kt b/src/main/kotlin/kr/lunaticbum/back/lun/LunApplication.kt index b9d245a..eecad44 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/LunApplication.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/LunApplication.kt @@ -4,6 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.web.reactive.function.client.WebClient +import java.io.IOException +import java.util.concurrent.ExecutionException +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException @EnableScheduling // 추가 @@ -20,6 +24,8 @@ class LunApplication { } + + } @@ -30,4 +36,3 @@ fun main(args: Array) { } runApplication(*args) } - \ No newline at end of file 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 a58c2c4..3e65820 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/controllers/Telegram.kt @@ -1,12 +1,18 @@ package kr.lunaticbum.back.lun.controllers +import bums.lunatic.launcher.utils.CompressStringUtil import com.google.gson.Gson -import com.google.gson.JsonObject import com.google.gson.annotations.SerializedName +import com.google.maps.GeoApiContext +import com.google.maps.PendingResult +import com.google.maps.PlacesApi +import com.google.maps.model.LatLng +import com.google.maps.model.PlaceType +import com.google.maps.model.PlacesSearchResult +import com.google.maps.model.RankBy import jakarta.servlet.http.HttpServletRequest import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async import kotlinx.coroutines.launch import kr.lunaticbum.back.lun.configs.GlobalEnvironment import kr.lunaticbum.back.lun.model.* @@ -14,22 +20,18 @@ 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.http.HttpStatus import org.springframework.http.MediaType import org.springframework.scheduling.annotation.Scheduled +import org.springframework.ui.ModelMap import org.springframework.web.bind.annotation.* -import org.springframework.web.reactive.function.BodyInserter import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.WebClient -import org.springframework.web.reactive.function.client.bodyToMono import java.math.BigDecimal import java.math.RoundingMode -import java.net.URLEncoder -import java.text.DateFormat import java.text.SimpleDateFormat import java.time.Duration import java.util.* -import kotlin.collections.ArrayList +import java.util.prefs.Preferences @RestController @@ -56,120 +58,179 @@ class Telegram { @Autowired lateinit var rssDataService: RssDataService + + + @ResponseBody + @GetMapping("kesy/{path}") + fun getEncode(@PathVariable path: String): ModelMap { + var returnModelMap = ModelMap() + var comp = CompressStringUtil.compressString(path) + println("comp >>> $comp") + + val keyworkd = arrayListOf("I0Z","dcBEW", "TGyG", "U=Qu", "Bm=s") + val keyworkd2 = arrayListOf("x-n", "Y_D", "u", "uoo", "dfhZ", "gSKY") + var chunked = Math.abs(Random().nextInt() % 3) + 1 + chunked = if (chunked % 2 == 1) chunked + 1 else chunked + comp = comp?.chunked(chunked) { + return@chunked it.padStart(chunked,'=') + }?.joinToString("")?.reversed().plus("$chunked").plus(Char(Math.abs(Random().nextInt() % 57) + 65)) + + + + println("comp >>> $comp") + var word = if (System.currentTimeMillis() % 2L == 0L) { + keyworkd.get(chunked) + } else { + comp = comp.plus(Char(Math.abs(Random().nextInt() % 57) + 65)) + keyworkd2.get(chunked) + } + + comp = (word).plus(comp) + returnModelMap.put("C",comp) + var doubleIpmt = false + keyworkd2.forEach { if(comp?.startsWith(it) == true) { + doubleIpmt = true + } } + var charChunked = comp?.lastOrNull() + println("comp?.removeSuffix(charChunked!!.toString()) ${comp?.removeSuffix(charChunked!!.toString())}") + comp = comp?.removeSuffix(charChunked!!.toString()) + if (doubleIpmt) { + charChunked = comp?.lastOrNull() + comp = comp?.removeSuffix(charChunked!!.toString()) + } + charChunked = comp?.lastOrNull() + println("charChunked >> $charChunked") + chunked = charChunked?.toString()?.toInt() ?: 0 + println("chunked >> $chunked") + println("comp?.removeSuffix(charChunked!!.toString()) ${comp?.removeSuffix(charChunked!!.toString())}") + + comp = (comp?.substring(0,comp.length -1)) + println("comp $comp") + + comp = comp?.removePrefix(keyworkd.get(chunked))?.removePrefix(keyworkd2.get(chunked))?.reversed() + println("comp $comp") + comp = comp?.chunked(chunked){ + return@chunked it.toString().replace("=","") + }?.joinToString("") + println("comp $comp") + + + var decomp = CompressStringUtil.decompressString(comp) + println("decomp $decomp") + returnModelMap.put("D", decomp) + return returnModelMap + } + @ResponseBody @PostMapping("webhook") - suspend fun test(httpServletRequest: HttpServletRequest, @RequestBody update : kr.lunaticbum.back.lun.model.Result) : String { + suspend fun test(httpServletRequest: HttpServletRequest, @RequestBody update : kr.lunaticbum.back.lun.model.Result?, @RequestBody updates : kr.lunaticbum.back.lun.model.TelegramUpdate? ) : String { try { + println("test strat ${Gson().toJson(updates)}") println("test strat ${Gson().toJson(update)}") // println("test strat ${httpServletRequest.requestURI}") update?.message?.let { msg -> if(msg?.location != null && msg?.location?.latitude != 0.0 && msg?.location?.latitude != 0.0 ) { CoroutineScope(Dispatchers.IO).launch { try { - println("test strat ${msg.location}") - val lat = BigDecimal(msg?.location?.latitude!!).setScale(6, RoundingMode.HALF_UP) - val long = BigDecimal(msg?.location?.longitude!!).setScale(6, RoundingMode.HALF_UP) - WebClient.create().get() - .uri("http://api.weatherapi.com/v1/current.json?key=${globalEvv.weatherApiKey}&q=${lat},${long}&aqi=no") - .retrieve() - .bodyToMono(CurrentWeather::class.java) - .timeout(Duration.ofSeconds(30L)) - .block()?.let { sss -> - println("test strat ${sss}") - CoroutineScope(Dispatchers.IO).launch { - try { - val msg = TelegramSendMsg( - "${msg.from!!.id!!}", - sss.getSummaryInfo(lat.toString(), long.toString()) - ) - println("msg >>> ${Gson().toJson(msg)}") -// val fullUrl = -// "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage?chat_id=${msg.userId}&text=${msg.msg}" - val fullUrl = - "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage" - val result = WebClient.create(fullUrl) -// .get() - .post() - .contentType(MediaType.APPLICATION_JSON) - .body(BodyInserters.fromValue(Gson().toJson(msg))) - .retrieve() + var prefKey = Preferences.userNodeForPackage(Telegram::class.java).get("GAPI_KEY".plus("_").plus(msg.from!!.id.toString()), "") + if (prefKey != null && prefKey.length > 0) { + println("test strat ${msg.location}") + val lat = BigDecimal(msg?.location?.latitude!!).setScale(6, RoundingMode.HALF_UP) + val long = BigDecimal(msg?.location?.longitude!!).setScale(6, RoundingMode.HALF_UP) + WebClient.create().get() + .uri("http://api.weatherapi.com/v1/current.json?key=${globalEvv.weatherApiKey}&q=${lat},${long}&aqi=no") + .retrieve() + .bodyToMono(CurrentWeather::class.java) + .timeout(Duration.ofSeconds(30L)) + .block()?.let { sss -> + println("test strat ${sss}") + CoroutineScope(Dispatchers.IO).launch { + try { + val msg = TelegramSendMsg( + "${msg.from!!.id!!}", + sss.getSummaryInfo(lat.toString(), long.toString()) + ) + val fullUrl = + "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage" + val result = WebClient.create(fullUrl) + .post() + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(Gson().toJson(msg))) + .retrieve() - .bodyToMono(String::class.java).block() ?: "FAIL" - println("fullUrl ${fullUrl} : result $result") + .bodyToMono(String::class.java).block() ?: "FAIL" + println("fullUrl ${fullUrl} : result $result") - } catch (e: Exception) { - e.printStackTrace() + } catch (e: Exception) { + e.printStackTrace() + } } } + + val context = GeoApiContext.Builder() + .apiKey(prefKey) + .build() + var types = + arrayOf(PlaceType.RESTAURANT, PlaceType.CAFE, PlaceType.BAR, PlaceType.BAKERY) + types.forEach { type -> + PlacesApi.nearbySearchQuery(context, LatLng(lat.toDouble(), long.toDouble())) + .type(type).rankby(RankBy.DISTANCE).language("ko").await()?.let { respoce -> + respoce.results.filter { + return@filter it.rating > 4 && it.userRatingsTotal > 1 + }.sortedBy { it.userRatingsTotal }.forEach { + try { + val msg = TelegramSendMsg( + "${msg.from!!.id!!}", + "${type.name} :: " + it.summary(lat.toDouble(), long.toDouble()) + ) + println("msg >>> ${Gson().toJson(msg)}") + val fullUrl = + "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage" + val result = WebClient.create(fullUrl) + .post() + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(Gson().toJson(msg))) + .retrieve() + .bodyToMono(String::class.java).block() ?: "FAIL" + println("fullUrl ${fullUrl} : result $result") + } catch (e: Exception) { + e.printStackTrace() + } + } + } } - var restUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat}%2c${long}&radius=2000&type=restaurant&key=AIzaSyARLXyvmr_554tOy3UCh3naFlZQS3-qQQM&rankby=prominence" - WebClient.create().get() - .uri(restUrl) - .retrieve() - .bodyToMono(PlaceGoogle::class.java) - .timeout(Duration.ofSeconds(30L)) - .block()?.let { sss -> - println("restUrl >>> ${restUrl}") - try { - var topResult = arrayListOf() - sss.results.forEach { - try { - if (it.rating?.toDouble() ?: 0.0 >= 4.0) { - it.getDistane(lat.toDouble(),long.toDouble()) - println("${it.name} => ${Gson().toJson(it)}") - topResult.add(it) - } - } catch (e : Exception) { - e.printStackTrace() - } - } - topResult.forEach { - try { - val msg = TelegramSendMsg("${msg.from!!.id!!}", it.toString()) - println("msg >>> ${Gson().toJson(msg)}") - val fullUrl = "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage" - val result = WebClient.create(fullUrl) - .post() - .contentType(MediaType.APPLICATION_JSON) - .body(BodyInserters.fromValue(Gson().toJson(msg))) - .retrieve() - - .bodyToMono(String::class.java).block() ?: "FAIL" - println("fullUrl ${fullUrl} : result $result") - - } catch (e: Exception) { - e.printStackTrace() - } - } - } catch (e: Exception) { - e.printStackTrace() - } - } - -// "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${long}&radius=5000&type=cafe&key=AIzaSyARLXyvmr_554tOy3UCh3naFlZQS3-qQQM" + } + else { + sendSimpleMsg(globalEvv.telegramBotKey!!,msg.from!!.id.toString(),"서비스 키를 등록하셈.\n/setGaipKeys {key}") + } } - catch (e : Exception) { + catch(e : Exception) { e.printStackTrace() } } - } else if(msg.text?.startsWith("/") == true) { msg.text?.split(" ")?.let { cmds -> cmds[0].let { cmd -> when(cmd.trim()) { + "/reqGapiKeys" -> { + sendSimpleMsg(globalEvv.telegramBotKey!!,globalEvv.telegramMyId!!,"${msg.from!!.id.toString()}님이 서비스 키를 요첨항./setGaipKeys {key}") + } + "/setGaipKeys" -> { + Preferences.userNodeForPackage(Telegram::class.java).put("GAPI_KEY".plus("_").plus(msg.from!!.id.toString()), cmds[1]) + } "/get" ->{} "/jf" ->{ - CoroutineScope(Dispatchers.IO).launch { - logService.log("${cmd} Start ${cmds[1]}") - String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService) } - logService.log("${cmd} END ${cmds[1]}") - } - CoroutineScope(Dispatchers.IO).launch { - logService.log("on Cmd JF with SO") - logService.log("${cmd} Start ${cmds[1]}") - String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService)} - logService.log("${cmd} END ${cmds[1]}") - } +// CoroutineScope(Dispatchers.IO).launch { +// logService.log("${cmd} Start ${cmds[1]}") +// String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService) } +// logService.log("${cmd} END ${cmds[1]}") +// } +// CoroutineScope(Dispatchers.IO).launch { +// logService.log("on Cmd JF with SO") +// logService.log("${cmd} Start ${cmds[1]}") +// String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService)} +// logService.log("${cmd} END ${cmds[1]}") +// } } "/lama" -> { val req = BumlamaReq(msg.text!!.replace(cmd,"")) @@ -448,6 +509,20 @@ class Telegram { } + fun sendSimpleMsg(telegramBotKey : String , userId : String, msg :String) { + val fullUrl = "https://api.telegram.org/${telegramBotKey}/sendMessage" + var tlgSend = TelegramSendMsg(userId, msg) + WebClient + .create() + .post() + .uri(fullUrl) + .body(BodyInserters.fromValue(Gson().toJson(tlgSend))) + .retrieve().bodyToMono(String::class.java).timeout(Duration.ofMinutes(20L)) + .block()?.let { result -> + + } + } + @@ -493,69 +568,6 @@ 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() -// } -// } - -// 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") -// }) -// } fun sendMsg(target : String) { val client = WebClient.create() @@ -616,4 +628,8 @@ data class TelegramSendMsg( val userId: String, // null을 허용하지 않음 @SerializedName("text") val msg: String // null을 허용하지 않음 -) \ No newline at end of file +) + +fun PlacesSearchResult.summary(currentLat : Double,currentLng: Double) : String { + return "${name}\n총 리뷰수: ${userRatingsTotal}\n평점 : ${rating}\n거리 : \n${calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng)}km\n링크:\n https://www.google.com/maps/search/?api=1&query=${geometry!!.location!!.lat}%2C${geometry!!.location!!.lng}&query_place_id=${placeId}" +} \ No newline at end of file diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/model/PlaceGoogle.kt b/src/main/kotlin/kr/lunaticbum/back/lun/model/PlaceGoogle.kt index 6ee91a5..11da603 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/model/PlaceGoogle.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/model/PlaceGoogle.kt @@ -6,46 +6,55 @@ import kotlin.math.cos import kotlin.math.sin import kotlin.math.sqrt -class PlaceGoogle { - - var results : ArrayList = arrayListOf() -} -class Place { - var name : String = "" - var price_level : String? = null - var rating : String? = null - var reviews : ArrayList? = null - var user_ratings_total : String? = null - var geometry : PlaceGeometry? = null - var distance : Double = 0.0 - var place_id : String? = null - fun getDistane(currentLat : Double, currentLng : Double) : Double { - distance = calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng) - return distance - } - - override fun toString(): String = "상호 : ${name}\n 총 리뷰수: ${user_ratings_total}\n평점 : \n${rating}\n거리 : \n${distance}\n링크 열기: https://www.google.com/maps/search/?api=1&query=${geometry!!.location!!.lat}%2C${geometry!!.location!!.lng}&query_place_id=${place_id}" - -} -class PlaceGeometry { - var location : PlaceLocation? = null -} -class PlaceLocation { - var lat : Double = 0.0//37.3890078, - var lng : Double = 0.0//126.9510394 -} -class PlaceReview { - var author_name : String? = null - var rating : String? = null - var relative_time_description : String? = null - var time : String? = null - var author_url : String? = null - var language : String? = null - var original_language : String? = null - var profile_photo_url : String? = null - var text : String? = null - var translated : String? = null -} +// +//class PlaceGoogle { +// +// var results : ArrayList = arrayListOf() +//} +//class Place { +// var name : String? = "" +// +// var price_level : String? = null +// +// var rating : String? = null +// +//// var reviews : ArrayList? = null +// +// var user_ratings_total : String? = null +// +// var geometry : PlaceGeometry? = null +// +// var distance : Double? = 0.0 +// +// var place_id : String? = null +// +// fun getDistane(currentLat : Double, currentLng : Double) : Double { +// distance = calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng) +// return distance ?: 0.0 +// } +// +// override fun toString(): String = "상호 : ${name}\n 총 리뷰수: ${user_ratings_total}\n평점 : \n${rating}\n거리 : \n${distance}\n링크 열기: https://www.google.com/maps/search/?api=1&query=${geometry!!.location!!.lat}%2C${geometry!!.location!!.lng}&query_place_id=${place_id}" +// +//} +//class PlaceGeometry { +// var location : PlaceLocation? = null +//} +//class PlaceLocation { +// var lat : Double = 0.0//37.3890078, +// var lng : Double = 0.0//126.9510394 +//} +//class PlaceReview { +// var author_name : String? = null +// var rating : String? = null +// var relative_time_description : String? = null +// var time : String? = null +// var author_url : String? = null +// var language : String? = null +// var original_language : String? = null +// var profile_photo_url : String? = null +// var text : String? = null +// var translated : String? = null +//} const val EARTH_RADIUS = 6371.0 // 지구 반지름 (km) @@ -59,4 +68,86 @@ fun calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): D val c = 2 * atan2(sqrt(a), sqrt(1 - a)) return EARTH_RADIUS * c // km 단위 거리 반환 -} \ No newline at end of file +} + +// import com.fasterxml.jackson.databind.ObjectMapper; // version 2.11.1 +// import com.fasterxml.jackson.annotation.JsonProperty; // version 2.11.1 +/* ObjectMapper om = new ObjectMapper(); +Root root = om.readValue(myJsonString, Root.class); */ +class GPGeometry { + var location: GPLocation? = null + var viewport: GPViewport? = null +} + +class GPLocation { + var lat: Double = 0.0 + var lng: Double = 0.0 +} + +class GPNortheast { + var lat: Double = 0.0 + var lng: Double = 0.0 +} + +class GPOpeningHours { + var open_now: Boolean = false +} + +class GPPhoto { + var height: Int = 0 + var html_attributions: ArrayList? = null + var photo_reference: String? = null + var width: Int = 0 +} + +class GPPlusCode { + var compound_code: String? = null + var global_code: String? = null +} + +class GPResult { + var business_status: String? = null + var geometry: GPGeometry? = null + var icon: String? = null + var icon_background_color: String? = null + var icon_mask_base_uri: String? = null + var name: String? = null + var opening_hours: GPOpeningHours? = null + var photos: ArrayList? = null + var place_id: String? = null + var plus_code: GPPlusCode? = null + var price_level: Int = 0 + var rating: Double = 0.0 + var reference: String? = null + var scope: String? = null + var types: ArrayList? = null + var user_ratings_total: Int = 0 + var vicinity: String? = null + var permanently_closed: Boolean = false + var distance : Double = 0.0 + fun getDistane(currentLat : Double, currentLng : Double) : Double { + distance = calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng) + return distance ?: 0.0 + } + + override fun toString(): String = "상호 : ${name}\n 총 리뷰수: ${user_ratings_total}\n평점 : \n${rating}\n거리 : \n${distance}\n링크 열기: https://www.google.com/maps/search/?api=1&query=${geometry!!.location!!.lat}%2C${geometry!!.location!!.lng}&query_place_id=${place_id}" +} + +class GPlace { + var error_message : String? = null + var html_attributions: ArrayList? = null + var next_page_token: String? = null + var results: ArrayList? = null + var status: String? = null +} + +class GPSouthwest { + var lat: Double = 0.0 + var lng: Double = 0.0 +} + +class GPViewport { + var northeast: GPNortheast? = null + var southwest: GPSouthwest? = null +} + diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/model/TelegramUpdate.kt b/src/main/kotlin/kr/lunaticbum/back/lun/model/TelegramUpdate.kt index b984ad8..cbd5481 100644 --- a/src/main/kotlin/kr/lunaticbum/back/lun/model/TelegramUpdate.kt +++ b/src/main/kotlin/kr/lunaticbum/back/lun/model/TelegramUpdate.kt @@ -22,7 +22,7 @@ import reactor.core.publisher.Mono /* ObjectMapper om = new ObjectMapper(); Root root = om.readValue(myJsonString, Root.class); */ class Chat { - var id: Int = 0 + var id: Long = 0 var first_name: String? = null var last_name: String? = null var username: String? = null @@ -36,7 +36,7 @@ class Entity { } class From { - var id: Int = 0 + var id: Long = 0 var is_bot: Boolean = false var first_name: String? = null var last_name: String? = null diff --git a/src/main/kotlin/kr/lunaticbum/back/lun/utils/CompressStringUtil.kt b/src/main/kotlin/kr/lunaticbum/back/lun/utils/CompressStringUtil.kt new file mode 100644 index 0000000..7f8f773 --- /dev/null +++ b/src/main/kotlin/kr/lunaticbum/back/lun/utils/CompressStringUtil.kt @@ -0,0 +1,99 @@ +package bums.lunatic.launcher.utils + +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.io.UnsupportedEncodingException +import java.util.zip.DeflaterOutputStream +import java.util.zip.InflaterInputStream +import kotlin.math.floor + + +object CompressStringUtil { + val charsetName: String = "UTF-8" + + /** + * String 객체를 압축하여 String 으로 리턴한다. + * @param string + * @return + */ + @Synchronized + fun compressString(string: String): String? { + return byteToString(compress(string)) + } + + /** + * 압축된 스트링을 복귀시켜서 String 으로 리턴한다. + * @param compressed + * @return + */ + @Synchronized + fun decompressString(compressed: String?): String { + return decompress(hexToByteArray(compressed)) + } + + private fun byteToString(bytes: ByteArray?): String? { + val sb = StringBuilder() + try { + for (b in bytes!!) { + sb.append(String.format("%02X", b)) + } + } catch (e: Exception) { + e.printStackTrace() + return null + } + + return sb.toString() + } + + private fun compress(text: String): ByteArray? { + val baos = ByteArrayOutputStream() + try { + val out: OutputStream = DeflaterOutputStream(baos) + out.write(text.toByteArray(charset(charsetName))) + out.close() + } catch (e: UnsupportedEncodingException) { + e.printStackTrace() + return null + } catch (e: IOException) { + e.printStackTrace() + return null + } + return baos.toByteArray() + } + + + private fun decompress(bytes: ByteArray): String { + val `in`: InputStream = InflaterInputStream(ByteArrayInputStream(bytes)) + val baos = ByteArrayOutputStream() + try { + val buffer = ByteArray(8192) + var len: Int + while ((`in`.read(buffer).also { len = it }) > 0) baos.write(buffer, 0, len) + return String(baos.toByteArray(), charset(charsetName)) + } catch (e: IOException) { + e.printStackTrace() + throw AssertionError(e) + } + } + + /** + * 16진 문자열을 byte 배열로 변환한다. + */ + private fun hexToByteArray(hex: String?): ByteArray { + if (hex == null || hex.length % 2 != 0) { + return byteArrayOf() + } + + val bytes = ByteArray(hex.length / 2) + var i = 0 + while (i < hex.length) { + val value = hex.substring(i, i + 2).toInt(16).toByte() + bytes[floor((i / 2).toDouble()).toInt()] = value + i += 2 + } + return bytes + } +} \ No newline at end of file