Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {

allprojects {
group = 'ru.funpay4j'
version = '1.0.6'
version = '1.0.7'

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.panic08.funpay4j.exceptions.order;

/**
* Base class for exception related to the fact that the order is not found
*
* @author panic08
* @since 1.0.7
*/
public class OrderNotFoundException extends RuntimeException {

/**
* Initializes a new OrderNotFoundException exception
*
* @param message exception message
*/
public OrderNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.panic08.funpay4j.objects.order;

import java.util.List;
import java.util.Map;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

import com.panic08.funpay4j.objects.user.ParsedPreviewUser;

/**
* This object represents the parsed FunPay order
*
* @author panic08
* @since 1.0.7
*/
@Data
@AllArgsConstructor
@Builder
public class ParsedOrder {

private String id;

private List<String> statuses;

private String shortDescription;

private String detailedDescription;

private Map<String, String> params;

private double price;

private ParsedPreviewUser other;
}
14 changes: 14 additions & 0 deletions client/src/main/java/com/panic08/funpay4j/parser/FunPayParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
import com.panic08.funpay4j.exceptions.InvalidGoldenKeyException;
import com.panic08.funpay4j.exceptions.lot.LotNotFoundException;
import com.panic08.funpay4j.exceptions.offer.OfferNotFoundException;
import com.panic08.funpay4j.exceptions.order.OrderNotFoundException;
import com.panic08.funpay4j.exceptions.user.UserNotFoundException;
import com.panic08.funpay4j.objects.CsrfTokenAndPHPSESSID;
import com.panic08.funpay4j.objects.game.ParsedPromoGame;
import com.panic08.funpay4j.objects.lot.ParsedLot;
import com.panic08.funpay4j.objects.offer.ParsedOffer;
import com.panic08.funpay4j.objects.order.ParsedOrder;
import com.panic08.funpay4j.objects.transaction.ParsedTransaction;
import com.panic08.funpay4j.objects.transaction.ParsedTransactionType;
import com.panic08.funpay4j.objects.user.ParsedSellerReview;
Expand Down Expand Up @@ -173,6 +175,18 @@ List<ParsedTransaction> parseTransactions(
List<ParsedTransaction> parseTransactions(String goldenKey, long userId, int pages)
throws FunPayApiException, UserNotFoundException, InvalidGoldenKeyException;

/**
* Parse order authorized
*
* @param goldenKey golden key which will be used to authorize the user
* @param orderId order id by which order will be parsed
* @return order
* @throws FunPayApiException if the other api-related exception
* @throws OrderNotFoundException if the order with id does not found
*/
ParsedOrder parseOrder(String goldenKey, String orderId)
throws FunPayApiException, OrderNotFoundException;

/**
* Parse csrf-token and PHPSESSID
*
Expand Down
150 changes: 120 additions & 30 deletions client/src/main/java/com/panic08/funpay4j/parser/JsoupFunPayParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.panic08.funpay4j.exceptions.InvalidGoldenKeyException;
import com.panic08.funpay4j.exceptions.lot.LotNotFoundException;
import com.panic08.funpay4j.exceptions.offer.OfferNotFoundException;
import com.panic08.funpay4j.exceptions.order.OrderNotFoundException;
import com.panic08.funpay4j.exceptions.user.UserNotFoundException;
import com.panic08.funpay4j.objects.CsrfTokenAndPHPSESSID;
import com.panic08.funpay4j.objects.game.ParsedPromoGame;
Expand All @@ -48,14 +49,11 @@
import com.panic08.funpay4j.objects.lot.ParsedLotCounter;
import com.panic08.funpay4j.objects.offer.ParsedOffer;
import com.panic08.funpay4j.objects.offer.ParsedPreviewOffer;
import com.panic08.funpay4j.objects.order.ParsedOrder;
import com.panic08.funpay4j.objects.transaction.ParsedTransaction;
import com.panic08.funpay4j.objects.transaction.ParsedTransactionStatus;
import com.panic08.funpay4j.objects.transaction.ParsedTransactionType;
import com.panic08.funpay4j.objects.user.ParsedAdvancedSellerReview;
import com.panic08.funpay4j.objects.user.ParsedPreviewSeller;
import com.panic08.funpay4j.objects.user.ParsedSeller;
import com.panic08.funpay4j.objects.user.ParsedSellerReview;
import com.panic08.funpay4j.objects.user.ParsedUser;
import com.panic08.funpay4j.objects.user.*;

/**
* This implementation of FunPayParser uses Jsoup to parse
Expand Down Expand Up @@ -389,34 +387,14 @@ public ParsedOffer parseOffer(long offerId) throws FunPayApiException, OfferNotF
parameters.put(key, value);
}

Element previewSellerUsernameElement =
funPayDocument.getElementsByClass("media-user-name").first().selectFirst("a");
Element previewSellerImgElement =
funPayDocument.getElementsByClass("media-user").first().selectFirst("img");
Element previewSellerReviewCountElement =
funPayDocument.getElementsByClass("text-mini text-light mb5").first();

String previewSellerUsernameElementHrefAttributeValue =
previewSellerUsernameElement.attr("href");

long previewSellerUserId =
Long.parseLong(
previewSellerUsernameElementHrefAttributeValue.substring(
25,
previewSellerUsernameElementHrefAttributeValue.length() - 1));
String previewSellerUsername = previewSellerUsernameElement.text();
String previewSellerAvatarPhotoLink = previewSellerImgElement.attr("src");

// if the previewUser has a regular photo
if (previewSellerAvatarPhotoLink.equals("/img/layout/avatar.png"))
previewSellerAvatarPhotoLink = null;

// Select rating from string like "219 reviews over 2 years"
int previewSellerReviewCount =
Integer.parseInt(
previewSellerReviewCountElement.text().replaceAll("\\D.*", ""));
boolean isPreviewSellerOnline =
funPayDocument.getElementsByClass("media media-user online").first() != null;
ParsedPreviewUser parsedPreviewUser = extractPreviewUserFromProductPage(funPayDocument);

return ParsedOffer.builder()
.id(offerId)
Expand All @@ -428,11 +406,11 @@ public ParsedOffer parseOffer(long offerId) throws FunPayApiException, OfferNotF
.parameters(parameters)
.seller(
ParsedPreviewSeller.builder()
.userId(previewSellerUserId)
.username(previewSellerUsername)
.avatarPhotoLink(previewSellerAvatarPhotoLink)
.userId(parsedPreviewUser.getUserId())
.avatarPhotoLink(parsedPreviewUser.getAvatarPhotoLink())
.username(parsedPreviewUser.getUsername())
.isOnline(parsedPreviewUser.isOnline())
.reviewCount(previewSellerReviewCount)
.isOnline(isPreviewSellerOnline)
.build())
.build();
} catch (IOException e) {
Expand Down Expand Up @@ -497,6 +475,86 @@ public List<ParsedTransaction> parseTransactions(String goldenKey, long userId,
return parseTransactionsInternal(goldenKey, userId, null, pages);
}

/** {@inheritDoc} */
@Override
public ParsedOrder parseOrder(String goldenKey, String orderId)
throws FunPayApiException, OrderNotFoundException {
try (Response funPayHtmlResponse =
httpClient
.newCall(
new Request.Builder()
.get()
.addHeader("Cookie", "golden_key=" + goldenKey)
.url(baseURL + "/orders/" + orderId + "/")
.build())
.execute()) {
String funPayHtmlPageBody = funPayHtmlResponse.body().string();

Document funPayDocument = Jsoup.parse(funPayHtmlPageBody);

if (isNonExistentFunPayPage(funPayDocument)) {
throw new OrderNotFoundException(
"Order with orderId " + orderId + " does not found");
}

List<String> statuses = new ArrayList<>();

List<Element> pageContentChildren =
funPayDocument.getElementsByClass("page-content").first().children();

Element pageHeader = pageContentChildren.get(0);
for (Element statusElement : pageHeader.children()) {
statuses.add(statusElement.text());
}

Element paramList = pageContentChildren.get(1);

Map<String, String> params = new HashMap<>();

for (Element col : paramList.getElementsByClass("row").first().children()) {
List<Element> paramItemChildren =
col.getElementsByClass("param-item").first().children();
params.put(paramItemChildren.get(0).text(), paramItemChildren.get(1).text());
}

List<Element> paramRows = paramList.getElementsByClass("row");

Double price = null;

for (Element paramRow : paramRows) {
for (Element paramCol : paramRow.children()) {
List<Element> paramItemChildren =
paramCol.getElementsByClass("param-item").first().children();
if (paramItemChildren.get(0).text().equals("Сумма")) {
price =
Double.parseDouble(
paramItemChildren.get(1).children().get(0).text());
} else {
params.put(
paramItemChildren.get(0).text(), paramItemChildren.get(1).text());
}
}
}

List<Element> paramListChildren = paramList.children();

String shortDescription = paramListChildren.get(1).children().get(1).text();
String detailedDescription = paramListChildren.get(2).children().get(1).text();

return ParsedOrder.builder()
.id(orderId)
.statuses(statuses)
.params(params)
.shortDescription(shortDescription)
.detailedDescription(detailedDescription)
.price(price)
.other(extractPreviewUserFromProductPage(funPayDocument))
.build();
} catch (IOException e) {
throw new FunPayApiException(e.getLocalizedMessage());
}
}

/** {@inheritDoc} */
@Override
public CsrfTokenAndPHPSESSID parseCsrfTokenAndPHPSESSID(@NonNull String goldenKey)
Expand Down Expand Up @@ -923,6 +981,38 @@ private List<ParsedSellerReview> parseSellerReviewsInternal(
return currentSellerReviews;
}

private ParsedPreviewUser extractPreviewUserFromProductPage(Document funPayDocument) {
System.out.println();
Element previewSellerUsernameElement =
funPayDocument.getElementsByClass("media-user-name").first().selectFirst("a");
Element previewSellerImgElement =
funPayDocument.getElementsByClass("media-user").first().selectFirst("img");
Element previewSellerReviewCountElement =
funPayDocument.getElementsByClass("text-mini text-light mb5").first();

String previewSellerUsernameElementHrefAttributeValue =
previewSellerUsernameElement.attr("href");

long previewSellerUserId =
Long.parseLong(
previewSellerUsernameElementHrefAttributeValue.substring(
25, previewSellerUsernameElementHrefAttributeValue.length() - 1));
String previewSellerUsername = previewSellerUsernameElement.text();
String previewSellerAvatarPhotoLink = previewSellerImgElement.attr("src");

// if the previewUser has a regular photo
if (previewSellerAvatarPhotoLink.equals("/img/layout/avatar.png"))
previewSellerAvatarPhotoLink = null;
boolean isPreviewSellerOnline =
funPayDocument.getElementsByClass("media media-user online").first() != null;
return ParsedPreviewUser.builder()
.userId(previewSellerUserId)
.username(previewSellerUsername)
.avatarPhotoLink(previewSellerAvatarPhotoLink)
.isOnline(isPreviewSellerOnline)
.build();
}

private void extractReviewsFromReviewsHtml(
Document reviewsHtml, List<ParsedSellerReview> currentSellerReviews) {
List<Element> reviewContainerElements = reviewsHtml.getElementsByClass("review-container");
Expand Down
Loading