mirror of
				https://github.com/arcan1s/ffxivbis.git
				synced 2025-10-30 21:23:41 +00:00 
			
		
		
		
	another iteration with parsing xivapi
This commit is contained in:
		| @ -58,15 +58,27 @@ class Ariyala extends Actor with StrictLogging { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   private def getIsTome(itemIds: Seq[Long]): Future[Map[Long, Boolean]] = { |   private def getIsTome(itemIds: Seq[Long]): Future[Map[Long, Boolean]] = { | ||||||
|     val uri = Uri(xivapiUrl) |     val uriForItems = Uri(xivapiUrl) | ||||||
|       .withPath(Uri.Path / "item") |       .withPath(Uri.Path / "item") | ||||||
|       .withQuery(Uri.Query(Map( |       .withQuery(Uri.Query(Map( | ||||||
|         "columns" -> Seq("ID", "Lot").mkString(","), |         "columns" -> Seq("ID", "GameContentLinks").mkString(","), | ||||||
|         "ids" -> itemIds.mkString(","), |         "ids" -> itemIds.mkString(","), | ||||||
|         "private_key" -> xivapiKey.getOrElse("") |         "private_key" -> xivapiKey.getOrElse("") | ||||||
|       ))) |       ))) | ||||||
|  |  | ||||||
|     sendRequest(uri, Ariyala.parseXivapiJson) |     sendRequest(uriForItems, Ariyala.parseXivapiJsonToShop).flatMap { shops => | ||||||
|  |       val shopIds = shops.values.map(_._2).toSet | ||||||
|  |       val columns = shops.values.map(pair => s"ItemCost${pair._1}").toSet.toSeq | ||||||
|  |       val uriForShops = Uri(xivapiUrl) | ||||||
|  |         .withPath(Uri.Path / "specialshop") | ||||||
|  |         .withQuery(Uri.Query(Map( | ||||||
|  |           "columns" -> (columns :+ "ID").mkString(","), | ||||||
|  |           "ids" -> shopIds.mkString(","), | ||||||
|  |           "private_key" -> xivapiKey.getOrElse("") | ||||||
|  |         ))) | ||||||
|  |  | ||||||
|  |       sendRequest(uriForShops, Ariyala.parseXivapiJsonToTome(shops)) | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private def sendRequest[T](uri: Uri, parser: JsObject => Future[T]): Future[T] = |   private def sendRequest[T](uri: Uri, parser: JsObject => Future[T]): Future[T] = | ||||||
| @ -118,18 +130,56 @@ object Ariyala { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   private def parseXivapiJson(js: JsObject) |   private def parseXivapiJsonToShop(js: JsObject) | ||||||
|                              (implicit executionContext: ExecutionContext): Future[Map[Long, Boolean]] = |                                    (implicit executionContext: ExecutionContext): Future[Map[Long, (String, Long)]] = { | ||||||
|  |     def extractTraderId(js: JsObject) = | ||||||
|  |       js.fields("SpecialShop").asJsObject | ||||||
|  |         .fields.collectFirst { | ||||||
|  |         case (shopName, JsArray(array)) if shopName.startsWith("ItemReceive") => | ||||||
|  |           val shopId = array.head match { | ||||||
|  |             case JsNumber(id) => id.toLong | ||||||
|  |             case other => throw deserializationError(s"Could not parse $other") | ||||||
|  |           } | ||||||
|  |           (shopName.replace("ItemReceive", ""), shopId) | ||||||
|  |       }.getOrElse(throw deserializationError(s"Could not parse $js")) | ||||||
|  |  | ||||||
|     Future { |     Future { | ||||||
|       js.fields("Results") match { |       js.fields("Results") match { | ||||||
|         case array: JsArray => |         case array: JsArray => | ||||||
|           array.elements.map(_.asJsObject.getFields("ID", "Lot") match { |           array.elements.map(_.asJsObject.getFields("ID", "GameContentLinks") match { | ||||||
|             case Seq(JsNumber(id), JsNumber(isTome)) => id.toLong -> (isTome == 0) |             case Seq(JsNumber(id), shop) => id.toLong -> extractTraderId(shop.asJsObject) | ||||||
|             case other => throw deserializationError(s"Could not parse $other") |             case other => throw deserializationError(s"Could not parse $other") | ||||||
|           }).toMap |           }).toMap | ||||||
|         case other => throw deserializationError(s"Could not parse $other") |         case other => throw deserializationError(s"Could not parse $other") | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   private def parseXivapiJsonToTome(shops: Map[Long, (String, Long)])(js: JsObject) | ||||||
|  |                                    (implicit executionContext: ExecutionContext): Future[Map[Long, Boolean]] = | ||||||
|  |     Future { | ||||||
|  |       val shopMap = js.fields("Results") match { | ||||||
|  |         case array: JsArray => | ||||||
|  |           array.elements.map { shop => | ||||||
|  |             shop.asJsObject.fields("ID") match { | ||||||
|  |               case JsNumber(id) => id.toLong -> shop.asJsObject | ||||||
|  |               case other => throw deserializationError(s"Could not parse $other") | ||||||
|  |             } | ||||||
|  |           }.toMap | ||||||
|  |         case other => throw deserializationError(s"Could not parse $other") | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       shops.map { case (itemId, (index, shopId)) => | ||||||
|  |         val isTome = Try(shopMap(shopId).fields(s"ItemCost$index").asJsObject).toOption.getOrElse(throw new Exception(s"${shopMap(shopId).fields(s"ItemCost$index")}, $index")) | ||||||
|  |           .getFields("IsUnique", "StackSize") match { | ||||||
|  |           case Seq(JsNumber(isUnique), JsNumber(stackSize)) => | ||||||
|  |             // either upgraded gear or tomes found | ||||||
|  |             isUnique == 1 || stackSize.toLong == 2000 | ||||||
|  |           case other => throw deserializationError(s"Could not parse $other") | ||||||
|  |         } | ||||||
|  |         itemId -> isTome | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|   private def remapKey(key: String): Option[String] = key match { |   private def remapKey(key: String): Option[String] = key match { | ||||||
|     case "mainhand" => Some("weapon") |     case "mainhand" => Some("weapon") | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user