David Li commited on
Commit
02ec2cc
1 Parent(s): 46951bb

fix: update dart off server

Browse files
bin/dart_off_server.dart CHANGED
@@ -1,4 +1,4 @@
1
- import 'package:dart_off_server/core.dart' as openfood;
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
- openfood.mkConfiguration();
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 openfood.search(query).then((value) {
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
- http:
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