Spaces:
Build error
Build error
David Li
commited on
Commit
·
02ec2cc
1
Parent(s):
46951bb
fix: update dart off server
Browse files- bin/dart_off_server.dart +7 -3
- lib/core.dart +51 -0
- lib/types.dart +28 -0
- pubspec.lock +22 -1
- pubspec.yaml +2 -0
- test/core_test.dart +17 -0
- test/sample.html +0 -0
bin/dart_off_server.dart
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
import 'package:dart_off_server/core.dart' as
|
2 |
import 'package:alfred/alfred.dart';
|
3 |
import 'dart:io';
|
4 |
import 'package:openfoodfacts/openfoodfacts.dart';
|
@@ -11,7 +11,7 @@ void main(List<String> arguments) async {
|
|
11 |
} else {
|
12 |
port = int.tryParse(arguments.first) ?? 6565;
|
13 |
}
|
14 |
-
|
15 |
final app = Alfred();
|
16 |
|
17 |
// print line
|
@@ -42,12 +42,16 @@ void main(List<String> arguments) async {
|
|
42 |
|
43 |
app.get('/food/search', (req, res) {
|
44 |
final query = req.uri.queryParameters;
|
45 |
-
return
|
46 |
res.json(value);
|
47 |
}).catchError((error) {
|
48 |
res.json(error);
|
49 |
});
|
50 |
});
|
51 |
|
|
|
|
|
|
|
|
|
52 |
await app.listen(port); //Listening on port 6565
|
53 |
}
|
|
|
1 |
+
import 'package:dart_off_server/core.dart' as core;
|
2 |
import 'package:alfred/alfred.dart';
|
3 |
import 'dart:io';
|
4 |
import 'package:openfoodfacts/openfoodfacts.dart';
|
|
|
11 |
} else {
|
12 |
port = int.tryParse(arguments.first) ?? 6565;
|
13 |
}
|
14 |
+
core.mkConfiguration();
|
15 |
final app = Alfred();
|
16 |
|
17 |
// print line
|
|
|
42 |
|
43 |
app.get('/food/search', (req, res) {
|
44 |
final query = req.uri.queryParameters;
|
45 |
+
return core.search(query).then((value) {
|
46 |
res.json(value);
|
47 |
}).catchError((error) {
|
48 |
res.json(error);
|
49 |
});
|
50 |
});
|
51 |
|
52 |
+
app.get('/steam', (req, res) {
|
53 |
+
return core.findTopSteamSellers();
|
54 |
+
});
|
55 |
+
|
56 |
await app.listen(port); //Listening on port 6565
|
57 |
}
|
lib/core.dart
CHANGED
@@ -1,4 +1,9 @@
|
|
1 |
import 'package:openfoodfacts/openfoodfacts.dart';
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
Future<SearchResult> search(Map<String, String> query) {
|
4 |
var parametersList = <Parameter>[];
|
@@ -98,3 +103,49 @@ void mkConfiguration() {
|
|
98 |
|
99 |
OpenFoodAPIConfiguration.globalCountry = OpenFoodFactsCountry.CANADA;
|
100 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import 'package:openfoodfacts/openfoodfacts.dart';
|
2 |
+
import 'package:http/http.dart' as http;
|
3 |
+
// ignore_for_file: constant_identifier_names
|
4 |
+
import 'package:beautiful_soup_dart/beautiful_soup.dart';
|
5 |
+
import './types.dart';
|
6 |
+
|
7 |
|
8 |
Future<SearchResult> search(Map<String, String> query) {
|
9 |
var parametersList = <Parameter>[];
|
|
|
103 |
|
104 |
OpenFoodAPIConfiguration.globalCountry = OpenFoodFactsCountry.CANADA;
|
105 |
}
|
106 |
+
|
107 |
+
|
108 |
+
// function that scans for top steam charts
|
109 |
+
|
110 |
+
Future<List<SteamTopSeller>> findTopSteamSellers() async {
|
111 |
+
var url = Uri.https('store.steampowered.com', 'search/?filter=topsellers');
|
112 |
+
var html = await http.get(url);
|
113 |
+
return parseSteamTopSellers(html.body);
|
114 |
+
}
|
115 |
+
|
116 |
+
List<SteamTopSeller> parseSteamTopSellers(String rawHTML ) {
|
117 |
+
BeautifulSoup soup = BeautifulSoup(rawHTML);
|
118 |
+
var searchResultsDiv = soup.find('div', attrs: {'id': 'search_resultsRows'});
|
119 |
+
if (searchResultsDiv == null) {
|
120 |
+
return <SteamTopSeller>[];
|
121 |
+
}
|
122 |
+
var topSellers = searchResultsDiv.findAll('a');
|
123 |
+
|
124 |
+
if (topSellers.isEmpty) {
|
125 |
+
return <SteamTopSeller>[];
|
126 |
+
}
|
127 |
+
var topSellersList = <SteamTopSeller>[];
|
128 |
+
for (var topSeller in topSellers) {
|
129 |
+
var imageDiv = topSeller.find('img');
|
130 |
+
String? imageSrc = '';
|
131 |
+
if (imageDiv != null) {
|
132 |
+
imageSrc = imageDiv.attributes['src'];
|
133 |
+
}
|
134 |
+
var title = topSeller.find('span', attrs: {'class': 'title'})?.text;
|
135 |
+
var publishDate = topSeller.find('div', attrs: {'class': 'col search_released responsive_secondrow'})?.text;
|
136 |
+
// var publishDate = topSeller.find('div', attrs: {'class': 'tab_item_top_tags'}).text;
|
137 |
+
// get data-price-final
|
138 |
+
var price = topSeller.find('div', attrs: {'class': 'search_price_discount_combined'})?.attributes['data-price-final'];
|
139 |
+
var discountDiv = topSeller.find('div', attrs: {'class': 'search_discount'});
|
140 |
+
String discount = "";
|
141 |
+
if (discountDiv != null) {
|
142 |
+
var discountSpan = discountDiv.find("span");
|
143 |
+
if (discountSpan != null) {
|
144 |
+
discount = discountSpan.text;
|
145 |
+
}
|
146 |
+
}
|
147 |
+
topSellersList.add(SteamTopSeller(imageSrc, title, price, publishDate, discount));
|
148 |
+
}
|
149 |
+
|
150 |
+
return topSellersList;
|
151 |
+
}
|
lib/types.dart
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class SteamTopSeller {
|
2 |
+
String? imageSrc;
|
3 |
+
String? title;
|
4 |
+
String? price;
|
5 |
+
String? publishDate;
|
6 |
+
String? discount;
|
7 |
+
|
8 |
+
|
9 |
+
SteamTopSeller(this.imageSrc, this.title, this.price, this.publishDate, this.discount);
|
10 |
+
|
11 |
+
fromJson(Map<String, dynamic> json) {
|
12 |
+
this.imageSrc = json['imageSrc'];
|
13 |
+
this.title = json['title'];
|
14 |
+
this.price = json['price'];
|
15 |
+
this.publishDate = json['publishDate'];
|
16 |
+
this.discount = json['discount'];
|
17 |
+
}
|
18 |
+
|
19 |
+
Map<String, dynamic> toJson() {
|
20 |
+
return {
|
21 |
+
'imageSrc': this.imageSrc,
|
22 |
+
'title': this.title,
|
23 |
+
'price': this.price,
|
24 |
+
'publishDate': this.publishDate,
|
25 |
+
'discount': this.discount,
|
26 |
+
};
|
27 |
+
}
|
28 |
+
}
|
pubspec.lock
CHANGED
@@ -36,6 +36,13 @@ packages:
|
|
36 |
url: "https://pub.dartlang.org"
|
37 |
source: hosted
|
38 |
version: "2.9.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
boolean_selector:
|
40 |
dependency: transitive
|
41 |
description:
|
@@ -71,6 +78,13 @@ packages:
|
|
71 |
url: "https://pub.dartlang.org"
|
72 |
source: hosted
|
73 |
version: "3.0.2"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
file:
|
75 |
dependency: transitive
|
76 |
description:
|
@@ -92,8 +106,15 @@ packages:
|
|
92 |
url: "https://pub.dartlang.org"
|
93 |
source: hosted
|
94 |
version: "2.1.1"
|
95 |
-
|
96 |
dependency: transitive
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
description:
|
98 |
name: http
|
99 |
url: "https://pub.dartlang.org"
|
|
|
36 |
url: "https://pub.dartlang.org"
|
37 |
source: hosted
|
38 |
version: "2.9.0"
|
39 |
+
beautiful_soup_dart:
|
40 |
+
dependency: "direct main"
|
41 |
+
description:
|
42 |
+
name: beautiful_soup_dart
|
43 |
+
url: "https://pub.dartlang.org"
|
44 |
+
source: hosted
|
45 |
+
version: "0.3.0"
|
46 |
boolean_selector:
|
47 |
dependency: transitive
|
48 |
description:
|
|
|
78 |
url: "https://pub.dartlang.org"
|
79 |
source: hosted
|
80 |
version: "3.0.2"
|
81 |
+
csslib:
|
82 |
+
dependency: transitive
|
83 |
+
description:
|
84 |
+
name: csslib
|
85 |
+
url: "https://pub.dartlang.org"
|
86 |
+
source: hosted
|
87 |
+
version: "0.17.2"
|
88 |
file:
|
89 |
dependency: transitive
|
90 |
description:
|
|
|
106 |
url: "https://pub.dartlang.org"
|
107 |
source: hosted
|
108 |
version: "2.1.1"
|
109 |
+
html:
|
110 |
dependency: transitive
|
111 |
+
description:
|
112 |
+
name: html
|
113 |
+
url: "https://pub.dartlang.org"
|
114 |
+
source: hosted
|
115 |
+
version: "0.15.1"
|
116 |
+
http:
|
117 |
+
dependency: "direct main"
|
118 |
description:
|
119 |
name: http
|
120 |
url: "https://pub.dartlang.org"
|
pubspec.yaml
CHANGED
@@ -8,6 +8,8 @@ environment:
|
|
8 |
|
9 |
dependencies:
|
10 |
alfred: ^1.0.0+1
|
|
|
|
|
11 |
openfoodfacts: ^2.2.1
|
12 |
|
13 |
dev_dependencies:
|
|
|
8 |
|
9 |
dependencies:
|
10 |
alfred: ^1.0.0+1
|
11 |
+
beautiful_soup_dart: ^0.3.0
|
12 |
+
http: ^0.13.5
|
13 |
openfoodfacts: ^2.2.1
|
14 |
|
15 |
dev_dependencies:
|
test/core_test.dart
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// load sample.html and run findTopSteamSellers, expect list of top steam sellers
|
2 |
+
import 'dart:io';
|
3 |
+
import 'package:test/test.dart';
|
4 |
+
import "package:dart_off_server/core.dart" as core;
|
5 |
+
import "package:path/path.dart" as p;
|
6 |
+
|
7 |
+
void main() {
|
8 |
+
test('calculate', () {
|
9 |
+
var rawHTMLPath = p.join(p.current, 'test', 'sample.html');
|
10 |
+
// load rawHTML from rawHTMLPath
|
11 |
+
File file = File(rawHTMLPath);
|
12 |
+
var rawHTML = file.readAsStringSync();
|
13 |
+
var steamSellers = core.parseSteamTopSellers(rawHTML);
|
14 |
+
// greater than 5
|
15 |
+
expect(steamSellers.length, greaterThan(5));
|
16 |
+
});
|
17 |
+
}
|
test/sample.html
ADDED
The diff for this file is too large to render.
See raw diff
|
|