Skip to content

Commit

Permalink
Version 1.9.10
Browse files Browse the repository at this point in the history
  • Loading branch information
Hexer10 committed Jul 14, 2021
1 parent 9d50d20 commit 7cb41f8
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 1.9.10
- Close #139: Implement Channel.subscribersCount.

## 1.9.9
- Fix issue #134 (Error when getting the hls manifest from a livestream)

Expand Down
5 changes: 4 additions & 1 deletion lib/src/channels/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ class Channel with EquatableMixin {
/// URL of the channel's logo image.
final String logoUrl;

/// The (approximate) channel subscriber's count.
final int? subscribersCount;

/// Initializes an instance of [Channel]
Channel(this.id, this.title, this.logoUrl);
Channel(this.id, this.title, this.logoUrl, this.subscribersCount);

@override
String toString() => 'Channel ($title)';
Expand Down
5 changes: 3 additions & 2 deletions lib/src/channels/channel_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class ChannelClient {
id = ChannelId.fromString(id);
var channelPage = await ChannelPage.get(_httpClient, id.value);

return Channel(id, channelPage.channelTitle, channelPage.channelLogoUrl);
return Channel(id, channelPage.channelTitle, channelPage.channelLogoUrl,
channelPage.subscribersCount);
}

/// Gets the metadata associated with the channel of the specified user.
Expand All @@ -42,7 +43,7 @@ class ChannelClient {
var channelPage =
await ChannelPage.getByUsername(_httpClient, username.value);
return Channel(ChannelId(channelPage.channelId), channelPage.channelTitle,
channelPage.channelLogoUrl);
channelPage.channelLogoUrl, channelPage.subscribersCount);
}

/// Gets the info found on a YouTube Channel About page.
Expand Down
63 changes: 63 additions & 0 deletions lib/src/reverse_engineering/responses/channel_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ class ChannelPage {
_root.querySelector('meta[property="og:image"]')?.attributes['content'] ??
'';

int? get subscribersCount => initialData.subscribersCount;

///
late final _InitialData initialData = _getInitialData();

_InitialData _getInitialData() {
final scriptText = _root
.querySelectorAll('script')
.map((e) => e.text)
.toList(growable: false);
return scriptText.extractGenericData(
(obj) => _InitialData(obj),
() => TransientFailureException(
'Failed to retrieve initial data from the channel about page, please report this to the project GitHub page.'));
}

///
ChannelPage(this._root);

Expand Down Expand Up @@ -68,3 +84,50 @@ class ChannelPage {
});
}
}

class _InitialData {
static final RegExp _subCountExp = RegExp(r'(\d+(?:\.\d+)?)(K|M|\s)');

// Json parsed map
final Map<String, dynamic> root;

_InitialData(this.root);

int? get subscribersCount {
final renderer = root.get('header')?.get('c4TabbedHeaderRenderer');
if (renderer?['subscriberCountText'] == null) {
return null;
}
final subText =
renderer?.get('subscriberCountText')?.getT<String>('simpleText');
if (subText == null) {
return null;
}
final match = _subCountExp.firstMatch(subText);
if (match == null) {
return null;
}
if (match.groupCount != 2) {
return null;
}

final count = double.tryParse(match.group(1) ?? '');
if (count == null) {
return null;
}

final multiplierText = match.group(2);
if (multiplierText == null) {
return null;
}

var multiplier = 1;
if (multiplierText == 'K') {
multiplier = 1000;
} else if (multiplierText == 'M') {
multiplier = 1000000;
}

return (count * multiplier).toInt();
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: youtube_explode_dart
description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
version: 1.9.9
version: 1.9.10

homepage: https://github.com/Hexer10/youtube_explode_dart

Expand Down
1 change: 1 addition & 0 deletions test/channel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ void main() {
expect(channel.title, 'Tyrrrz');
expect(channel.logoUrl, isNotEmpty);
expect(channel.logoUrl, isNot(equalsIgnoringWhitespace('')));
expect(channel.subscribersCount, greaterThanOrEqualTo(190));
});

group('Get metadata of any channel', () {
Expand Down

0 comments on commit 7cb41f8

Please sign in to comment.