Skip to content
This repository was archived by the owner on Feb 4, 2024. It is now read-only.

Commit 7a4de84

Browse files
committed
⚡ Speed up the workflow
1 parent 53a1c91 commit 7a4de84

21 files changed

Lines changed: 161 additions & 842 deletions

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
APP_VERSION=0.0.1
1+
APP_VERSION=0.0.2
22
GITHUB_REPOSITORY_URL=https://github.com/techouse/alfred-stackexchange
3-
STACK_EXCHANGE_API_BASE_URL=https://api.stackexchange.com/2.3/
3+
STACK_EXCHANGE_API_VERSION=2.3
44
STACK_EXCHANGE_API_KEY=
55
STACK_EXCHANGE_CLIENT_ID=

bin/main.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import 'dart:io' show exitCode, stdout;
44

55
import 'package:alfred_workflow/alfred_workflow.dart';
66
import 'package:args/args.dart';
7-
import 'package:chopper/chopper.dart';
87
import 'package:cli_script/cli_script.dart';
98
import 'package:collection/collection.dart';
109
import 'package:html_unescape/html_unescape.dart';
10+
import 'package:http/http.dart' as http show ClientException;
1111
import 'package:stash/stash_api.dart';
1212

13-
import 'src/api/api.dart';
1413
import 'src/env/env.dart';
1514
import 'src/extensions/string_helpers.dart';
1615
import 'src/models/item_list.dart';
1716
import 'src/models/question.dart';
17+
import 'src/api/stack_exchange_service.dart';
1818

1919
part 'main_helpers.dart';
2020

bin/main_helpers.dart

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore_for_file: long-method
2+
13
part of 'main.dart';
24

35
final HtmlUnescape _unescape = HtmlUnescape();
@@ -18,7 +20,7 @@ final AlfredUpdater _updater = AlfredUpdater(
1820
updateInterval: Duration(days: 1),
1921
);
2022

21-
final Api _api = Api();
23+
// final Api _api = Api();
2224

2325
const updateItem = AlfredItem(
2426
title: 'Auto-Update available!',
@@ -43,19 +45,20 @@ Future<void> _performSearch({
4345
required String query,
4446
Set<String>? tags,
4547
}) async {
46-
final Response<ItemList<Question>> response = await _api.service.search(
47-
siteId: 'stackoverflow',
48-
query: query,
49-
tagged: tags,
50-
page: 1,
51-
pageSize: 20,
52-
);
48+
try {
49+
final ItemList<Question> questions = await StackExchangeService.search(
50+
siteId: 'stackoverflow',
51+
query: query,
52+
tagged: tags,
53+
page: 1,
54+
pageSize: 20,
55+
);
5356

54-
if (response.isSuccessful && (response.body?.isNotEmpty ?? false)) {
55-
_workflow.addItems(
56-
response.body!
57-
.map(
58-
(Question question) => AlfredItem(
57+
if (questions.isNotEmpty) {
58+
_workflow.addItems(
59+
<AlfredItem>[
60+
for (final Question question in questions)
61+
AlfredItem(
5962
uid: question.id.toString(),
6063
title: _unescape.convert(question.title),
6164
subtitle: _unescape.convert(question.tags.join(', ')),
@@ -71,23 +74,30 @@ Future<void> _performSearch({
7174
icon: AlfredItemIcon(path: 'icon.png'),
7275
valid: true,
7376
),
74-
)
75-
.toList(),
76-
);
77-
} else {
78-
final Uri url = Uri.https('www.google.com', '/search', {'q': query});
77+
],
78+
);
79+
} else {
80+
final Uri url = Uri.https('www.google.com', '/search', {'q': query});
7981

82+
_workflow.addItem(
83+
AlfredItem(
84+
title: 'No matching questions found',
85+
subtitle: 'Shall I try and search Google?',
86+
arg: url.toString(),
87+
text: AlfredItemText(copy: url.toString()),
88+
quickLookUrl: url.toString(),
89+
icon: AlfredItemIcon(path: 'google.png'),
90+
valid: true,
91+
),
92+
);
93+
}
94+
} on http.ClientException catch (error) {
8095
_workflow.addItem(
8196
AlfredItem(
82-
title: 'No matching questions found',
83-
subtitle: 'Shall I try and search Google?',
84-
arg: url.toString(),
85-
text: AlfredItemText(
86-
copy: url.toString(),
87-
),
88-
quickLookUrl: url.toString(),
89-
icon: AlfredItemIcon(path: 'google.png'),
90-
valid: true,
97+
title: 'StackExchange API Error',
98+
subtitle: error.message,
99+
text: AlfredItemText(copy: error.message),
100+
valid: false,
91101
),
92102
);
93103
}

bin/src/api/api.dart

Lines changed: 0 additions & 65 deletions
This file was deleted.

bin/src/api/credentials_interceptor.dart

Lines changed: 0 additions & 17 deletions
This file was deleted.

bin/src/api/json_serializable_converter.dart

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// ignore_for_file: long-parameter-list
2+
3+
import 'dart:convert' show jsonDecode;
4+
import 'package:http/http.dart' as http show get, ClientException, Response;
5+
6+
import 'order.dart';
7+
import 'sort.dart';
8+
import '../env/env.dart';
9+
import '../extensions/unix_date_time_extension.dart';
10+
import '../models/item_list.dart';
11+
import '../models/question.dart';
12+
13+
class StackExchangeService {
14+
/// Read more https://api.stackexchange.com/docs/advanced-search
15+
static Future<ItemList<Question>> search({
16+
required String siteId,
17+
required String query,
18+
bool? accepted,
19+
int? answers,
20+
String? body,
21+
bool? closed,
22+
bool? migrated,
23+
bool? notice,
24+
Set<String>? notTagged,
25+
Set<String>? tagged,
26+
String? title,
27+
int? ownerId,
28+
Uri? url,
29+
int? views,
30+
bool? wiki,
31+
DateTime? fromDate,
32+
DateTime? toDate,
33+
int page = 1,
34+
int pageSize = 100,
35+
Sort sort = Sort.relevance,
36+
Order order = Order.desc,
37+
}) =>
38+
_search(
39+
{
40+
'site': siteId,
41+
'q': query,
42+
'accepted': accepted,
43+
'answers': answers,
44+
'body': body,
45+
'closed': closed,
46+
'migrated': migrated,
47+
'notice': notice,
48+
'nottagged': notTagged?.join(';'),
49+
'tagged': tagged?.join(';'),
50+
'title': title,
51+
'user': ownerId,
52+
'url': url,
53+
'views': views,
54+
'wiki': wiki,
55+
'fromdate': fromDate?.secondsSinceEpoch,
56+
'todate': toDate?.secondsSinceEpoch,
57+
'page': page,
58+
'pagesize': pageSize,
59+
'sort': sort,
60+
'order': order,
61+
}..removeWhere((String key, dynamic value) => value == null),
62+
);
63+
64+
static Future<ItemList<Question>> _search(Map<String, dynamic> params) async {
65+
final Uri url = Uri.https(
66+
'api.stackexchange.com',
67+
'${Env.stackExchangeApiVersion}/search/advanced',
68+
{
69+
...params,
70+
'key': Env.stackExchangeApiKey,
71+
'client_id': Env.stackExchangeClientId,
72+
}.map(
73+
(String key, dynamic value) => MapEntry(
74+
key,
75+
value?.toString(),
76+
),
77+
),
78+
);
79+
80+
final http.Response response = await http.get(url);
81+
82+
if (response.statusCode >= 200 && response.statusCode < 300) {
83+
if (response.body.isNotEmpty) {
84+
final Map<String, dynamic> json = jsonDecode(response.body);
85+
86+
return json.containsKey('items') && json['items'] is Iterable
87+
? ItemList<Question>(
88+
<Question>[
89+
for (final item in json['items'] as List)
90+
Question.fromJson(item as Map<String, dynamic>),
91+
],
92+
hasMore: json['has_more'] as bool? ?? false,
93+
quotaMax: json['quota_max'] as int? ?? 0,
94+
quotaRemaining: json['quota_remaining'] as int? ?? 0,
95+
)
96+
: ItemList<Question>.empty();
97+
}
98+
99+
return ItemList<Question>.empty();
100+
} else {
101+
if (response.body.isNotEmpty) {
102+
final Map<String, dynamic> json = jsonDecode(response.body);
103+
throw http.ClientException(
104+
json['error_message'] ?? 'Failed to load data',
105+
url,
106+
);
107+
}
108+
109+
throw http.ClientException('Failed to load data', url);
110+
}
111+
}
112+
}

bin/src/env/env.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ abstract class Env {
1010
@EnviedField(varName: 'GITHUB_REPOSITORY_URL')
1111
static const String githubRepositoryUrl = _Env.githubRepositoryUrl;
1212

13-
@EnviedField(varName: 'STACK_EXCHANGE_API_BASE_URL')
14-
static const String stackExchangeBaseUrl = _Env.stackExchangeBaseUrl;
13+
@EnviedField(varName: 'STACK_EXCHANGE_API_VERSION')
14+
static const String stackExchangeApiVersion = _Env.stackExchangeApiVersion;
1515

1616
@EnviedField(varName: 'STACK_EXCHANGE_API_KEY', obfuscate: true)
1717
static final String stackExchangeApiKey = _Env.stackExchangeApiKey;

0 commit comments

Comments
 (0)