This commit is contained in:
lunaticbum 2025-02-27 17:08:15 +09:00
parent deb4a8e262
commit 7c4d5cde69
6 changed files with 422 additions and 206 deletions

View File

@ -53,6 +53,11 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-security") implementation("org.springframework.boot:spring-boot-starter-security")
compileOnly("org.projectlombok:lombok") 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-api:0.11.5")
implementation("io.jsonwebtoken:jjwt-impl:0.11.5") implementation("io.jsonwebtoken:jjwt-impl:0.11.5")
implementation("io.jsonwebtoken:jjwt-jackson:0.11.5") implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")

View File

@ -4,6 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication import org.springframework.boot.runApplication
import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.web.reactive.function.client.WebClient 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 // 추가 @EnableScheduling // 추가
@ -20,6 +24,8 @@ class LunApplication {
} }
} }
@ -30,4 +36,3 @@ fun main(args: Array<String>) {
} }
runApplication<LunApplication>(*args) runApplication<LunApplication>(*args)
} }

View File

@ -1,12 +1,18 @@
package kr.lunaticbum.back.lun.controllers package kr.lunaticbum.back.lun.controllers
import bums.lunatic.launcher.utils.CompressStringUtil
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.annotations.SerializedName 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 jakarta.servlet.http.HttpServletRequest
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kr.lunaticbum.back.lun.configs.GlobalEnvironment import kr.lunaticbum.back.lun.configs.GlobalEnvironment
import kr.lunaticbum.back.lun.model.* import kr.lunaticbum.back.lun.model.*
@ -14,22 +20,18 @@ import kr.lunaticbum.back.lun.utils.LogService
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.scheduling.annotation.Scheduled import org.springframework.scheduling.annotation.Scheduled
import org.springframework.ui.ModelMap
import org.springframework.web.bind.annotation.* 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.BodyInserters
import org.springframework.web.reactive.function.client.WebClient import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.bodyToMono
import java.math.BigDecimal import java.math.BigDecimal
import java.math.RoundingMode import java.math.RoundingMode
import java.net.URLEncoder
import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.Duration import java.time.Duration
import java.util.* import java.util.*
import kotlin.collections.ArrayList import java.util.prefs.Preferences
@RestController @RestController
@ -56,120 +58,179 @@ class Telegram {
@Autowired @Autowired
lateinit var rssDataService: RssDataService 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 @ResponseBody
@PostMapping("webhook") @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 { try {
println("test strat ${Gson().toJson(updates)}")
println("test strat ${Gson().toJson(update)}") println("test strat ${Gson().toJson(update)}")
// println("test strat ${httpServletRequest.requestURI}") // println("test strat ${httpServletRequest.requestURI}")
update?.message?.let { msg -> update?.message?.let { msg ->
if(msg?.location != null && msg?.location?.latitude != 0.0 && msg?.location?.latitude != 0.0 ) { if(msg?.location != null && msg?.location?.latitude != 0.0 && msg?.location?.latitude != 0.0 ) {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
try { try {
println("test strat ${msg.location}") var prefKey = Preferences.userNodeForPackage(Telegram::class.java).get("GAPI_KEY".plus("_").plus(msg.from!!.id.toString()), "")
val lat = BigDecimal(msg?.location?.latitude!!).setScale(6, RoundingMode.HALF_UP) if (prefKey != null && prefKey.length > 0) {
val long = BigDecimal(msg?.location?.longitude!!).setScale(6, RoundingMode.HALF_UP) println("test strat ${msg.location}")
WebClient.create().get() val lat = BigDecimal(msg?.location?.latitude!!).setScale(6, RoundingMode.HALF_UP)
.uri("http://api.weatherapi.com/v1/current.json?key=${globalEvv.weatherApiKey}&q=${lat},${long}&aqi=no") val long = BigDecimal(msg?.location?.longitude!!).setScale(6, RoundingMode.HALF_UP)
.retrieve() WebClient.create().get()
.bodyToMono(CurrentWeather::class.java) .uri("http://api.weatherapi.com/v1/current.json?key=${globalEvv.weatherApiKey}&q=${lat},${long}&aqi=no")
.timeout(Duration.ofSeconds(30L)) .retrieve()
.block()?.let { sss -> .bodyToMono(CurrentWeather::class.java)
println("test strat ${sss}") .timeout(Duration.ofSeconds(30L))
CoroutineScope(Dispatchers.IO).launch { .block()?.let { sss ->
try { println("test strat ${sss}")
val msg = TelegramSendMsg( CoroutineScope(Dispatchers.IO).launch {
"${msg.from!!.id!!}", try {
sss.getSummaryInfo(lat.toString(), long.toString()) val msg = TelegramSendMsg(
) "${msg.from!!.id!!}",
println("msg >>> ${Gson().toJson(msg)}") sss.getSummaryInfo(lat.toString(), long.toString())
// val fullUrl = )
// "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage?chat_id=${msg.userId}&text=${msg.msg}" val fullUrl =
val fullUrl = "https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage"
"https://api.telegram.org/${globalEvv.telegramBotKey}/sendMessage" val result = WebClient.create(fullUrl)
val result = WebClient.create(fullUrl) .post()
// .get() .contentType(MediaType.APPLICATION_JSON)
.post() .body(BodyInserters.fromValue(Gson().toJson(msg)))
.contentType(MediaType.APPLICATION_JSON) .retrieve()
.body(BodyInserters.fromValue(Gson().toJson(msg)))
.retrieve()
.bodyToMono(String::class.java).block() ?: "FAIL" .bodyToMono(String::class.java).block() ?: "FAIL"
println("fullUrl ${fullUrl} : result $result") println("fullUrl ${fullUrl} : result $result")
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() 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() else {
.uri(restUrl) sendSimpleMsg(globalEvv.telegramBotKey!!,msg.from!!.id.toString(),"서비스 키를 등록하셈.\n/setGaipKeys {key}")
.retrieve() }
.bodyToMono(PlaceGoogle::class.java)
.timeout(Duration.ofSeconds(30L))
.block()?.let { sss ->
println("restUrl >>> ${restUrl}")
try {
var topResult = arrayListOf<Place>()
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"
} }
catch (e : Exception) { catch(e : Exception) {
e.printStackTrace() e.printStackTrace()
} }
} }
} else if(msg.text?.startsWith("/") == true) { } else if(msg.text?.startsWith("/") == true) {
msg.text?.split(" ")?.let { cmds -> msg.text?.split(" ")?.let { cmds ->
cmds[0].let { cmd -> cmds[0].let { cmd ->
when(cmd.trim()) { 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" ->{} "/get" ->{}
"/jf" ->{ "/jf" ->{
CoroutineScope(Dispatchers.IO).launch { // CoroutineScope(Dispatchers.IO).launch {
logService.log("${cmd} Start ${cmds[1]}") // logService.log("${cmd} Start ${cmds[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService) } // String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9qYXZtb3N0LnRvL3NlYXJjaC9tb3ZpZS8lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService) }
logService.log("${cmd} END ${cmds[1]}") // logService.log("${cmd} END ${cmds[1]}")
} // }
CoroutineScope(Dispatchers.IO).launch { // CoroutineScope(Dispatchers.IO).launch {
logService.log("on Cmd JF with SO") // logService.log("on Cmd JF with SO")
logService.log("${cmd} Start ${cmds[1]}") // logService.log("${cmd} Start ${cmds[1]}")
String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService)} // String.format(String(Base64.getMimeDecoder().decode("aHR0cHM6Ly9rcjcwLnNvZ2lybC5zby8/cz0lcw==".toByteArray())),cmds[1]).getJ().let { doc -> FeedParseManager.parse(doc,rssDataService)}
logService.log("${cmd} END ${cmds[1]}") // logService.log("${cmd} END ${cmds[1]}")
} // }
} }
"/lama" -> { "/lama" -> {
val req = BumlamaReq(msg.text!!.replace(cmd,"")) 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) { fun sendMsg(target : String) {
val client = WebClient.create() val client = WebClient.create()
@ -617,3 +629,7 @@ data class TelegramSendMsg(
@SerializedName("text") @SerializedName("text")
val msg: String // null을 허용하지 않음 val msg: String // null을 허용하지 않음
) )
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}"
}

View File

@ -6,46 +6,55 @@ import kotlin.math.cos
import kotlin.math.sin import kotlin.math.sin
import kotlin.math.sqrt import kotlin.math.sqrt
class PlaceGoogle { //
//class PlaceGoogle {
var results : ArrayList<Place> = arrayListOf() //
} // var results : ArrayList<Place> = arrayListOf()
class Place { //}
var name : String = "" //class Place {
var price_level : String? = null // var name : String? = ""
var rating : String? = null //
var reviews : ArrayList<PlaceReview>? = null // var price_level : String? = null
var user_ratings_total : String? = null //
var geometry : PlaceGeometry? = null // var rating : String? = null
var distance : Double = 0.0 //
var place_id : String? = null //// var reviews : ArrayList<PlaceReview>? = null
fun getDistane(currentLat : Double, currentLng : Double) : Double { //
distance = calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng) // var user_ratings_total : String? = null
return distance //
} // var geometry : PlaceGeometry? = null
//
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}" // var distance : Double? = 0.0
//
} // var place_id : String? = null
class PlaceGeometry { //
var location : PlaceLocation? = null // fun getDistane(currentLat : Double, currentLng : Double) : Double {
} // distance = calculateDistance(currentLat, currentLng, geometry!!.location!!.lat, geometry!!.location!!.lng)
class PlaceLocation { // return distance ?: 0.0
var lat : Double = 0.0//37.3890078, // }
var lng : Double = 0.0//126.9510394 //
} // 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 PlaceReview { //
var author_name : String? = null //}
var rating : String? = null //class PlaceGeometry {
var relative_time_description : String? = null // var location : PlaceLocation? = null
var time : String? = null //}
var author_url : String? = null //class PlaceLocation {
var language : String? = null // var lat : Double = 0.0//37.3890078,
var original_language : String? = null // var lng : Double = 0.0//126.9510394
var profile_photo_url : String? = null //}
var text : String? = null //class PlaceReview {
var translated : String? = null // 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) const val EARTH_RADIUS = 6371.0 // 지구 반지름 (km)
@ -60,3 +69,85 @@ fun calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): D
return EARTH_RADIUS * c // km 단위 거리 반환 return EARTH_RADIUS * c // km 단위 거리 반환
} }
// 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<String>? = 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<GPPhoto>? = 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<String>? = 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<Any>? = null
var next_page_token: String? = null
var results: ArrayList<GPResult>? = 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
}

View File

@ -22,7 +22,7 @@ import reactor.core.publisher.Mono
/* ObjectMapper om = new ObjectMapper(); /* ObjectMapper om = new ObjectMapper();
Root root = om.readValue(myJsonString, Root.class); */ Root root = om.readValue(myJsonString, Root.class); */
class Chat { class Chat {
var id: Int = 0 var id: Long = 0
var first_name: String? = null var first_name: String? = null
var last_name: String? = null var last_name: String? = null
var username: String? = null var username: String? = null
@ -36,7 +36,7 @@ class Entity {
} }
class From { class From {
var id: Int = 0 var id: Long = 0
var is_bot: Boolean = false var is_bot: Boolean = false
var first_name: String? = null var first_name: String? = null
var last_name: String? = null var last_name: String? = null

View File

@ -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
}
}