├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── SharpGrabber.sln
├── assets
├── SharpGrabberDesktop-ScreenShot-4.0-2.png
├── blackwidow-logo-text-sm.png
├── blackwidow-logo-text.png
├── blackwidow-logo-text.psd
├── blackwidow-logo.png
├── blackwidow-logo.psd
└── icon.png
├── blackwidow
├── README.md
├── repo
│ ├── feed.json
│ └── scripts
│ │ ├── pornhub.js
│ │ └── vimeo.js
└── schema
│ └── feed.json
├── src
├── SharpGrabber.Adult
│ ├── AdultGrabberBuilderExtensions.cs
│ ├── Internal
│ │ ├── JsonHelper.cs
│ │ └── StringHelper.cs
│ ├── PornHubGrabber.cs
│ ├── SharpGrabber.Adult.csproj
│ ├── XVideosGrabber.cs
│ └── XnxxGrabber.cs
├── SharpGrabber.BlackWidow
│ ├── BlackWidowConstants.cs
│ ├── BlackWidowInitializer.cs
│ ├── BlackWidowService.cs
│ ├── Builder
│ │ ├── BlackWidowBuilder.cs
│ │ ├── BlackWidowRepositoryConfigurator.cs
│ │ ├── BuilderExtensions.cs
│ │ ├── GrabberScriptInterpreterActivationContext.cs
│ │ ├── GrabberScriptInterpreterApiServiceActivationContext.cs
│ │ ├── GrabberScriptInterpreterServiceConfigurator.cs
│ │ ├── IBlackWidowBuilder.cs
│ │ ├── IBlackWidowRepositoryConfigurator.cs
│ │ └── IGrabberScriptInterpreterServiceConfigurator.cs
│ ├── Definitions
│ │ ├── GrabberScriptSource.cs
│ │ ├── GrabberScriptType.cs
│ │ ├── GrabberScriptTypeAttribute.cs
│ │ └── IGrabberScriptSource.cs
│ ├── Exceptions
│ │ ├── BlackWidowException.cs
│ │ ├── ScriptApiVersionMismatchException.cs
│ │ └── ScriptInterpretException.cs
│ ├── Host
│ │ ├── ConsoleLog.cs
│ │ ├── ConsoleLogLevel.cs
│ │ ├── IScriptHost.cs
│ │ └── ScriptHost.cs
│ ├── IBlackWidowGrabber.cs
│ ├── IBlackWidowService.cs
│ ├── Internal
│ │ ├── ConcurrentHashSet.cs
│ │ ├── EqualityUtils.cs
│ │ ├── HashCodeUtils.cs
│ │ ├── StringExtensions.cs
│ │ └── TypeExtensions.cs
│ ├── Interpreter
│ │ ├── Api
│ │ │ ├── DefaultInterpreterApiService.cs
│ │ │ ├── Delegates.cs
│ │ │ ├── IInterpreterApiService.cs
│ │ │ ├── ProcessedGrabScript.cs
│ │ │ └── v1
│ │ │ │ ├── ApiGrabRequest.cs
│ │ │ │ ├── ApiGrabResponse.cs
│ │ │ │ ├── ApiGrabberContext.cs
│ │ │ │ ├── ApiHostObject.cs
│ │ │ │ ├── ApiMimeContext.cs
│ │ │ │ ├── Delegates.cs
│ │ │ │ ├── Html
│ │ │ │ ├── ApiHtmlContext.cs
│ │ │ │ └── ApiHtmlElement.cs
│ │ │ │ └── Http
│ │ │ │ ├── ApiHttpClient.cs
│ │ │ │ ├── ApiHttpContext.cs
│ │ │ │ ├── ApiHttpRequest.cs
│ │ │ │ └── ApiHttpResponse.cs
│ │ ├── GrabberScriptInterpretOptions.cs
│ │ ├── GrabberScriptInterpreterService.cs
│ │ ├── IGrabberScriptInterpreter.cs
│ │ ├── IGrabberScriptInterpreterService.cs
│ │ └── JavaScript
│ │ │ ├── Conversion
│ │ │ ├── JintConvertExTypeConverter.cs
│ │ │ └── JintMultiTypeConverter.cs
│ │ │ ├── JintInterpreterServiceExtensions.cs
│ │ │ ├── JintJavaScriptHost.cs
│ │ │ └── JintJavaScriptInterpreter.cs
│ ├── Repository
│ │ ├── GitHub
│ │ │ └── GitHubGrabberRepository.cs
│ │ ├── GrabberRepositoryBase.cs
│ │ ├── GrabberRepositoryChangeDetector.cs
│ │ ├── GrabberRepositoryChangeEventHandler.cs
│ │ ├── GrabberRepositoryConfigurationExtensions.cs
│ │ ├── GrabberRepositoryFeed.cs
│ │ ├── GrabberRepositoryFeedDifference.cs
│ │ ├── GrabberRepositoryScript.cs
│ │ ├── IGrabberRepository.cs
│ │ ├── IGrabberRepositoryChangeDetector.cs
│ │ ├── IGrabberRepositoryFeed.cs
│ │ ├── IGrabberRepositoryScript.cs
│ │ ├── IGrabberRepositorySubscription.cs
│ │ ├── Local
│ │ │ └── PhysicalGrabberRepository.cs
│ │ ├── Memory
│ │ │ └── InMemoryRepository.cs
│ │ └── OfficialGrabberRepository.cs
│ ├── SharpGrabber.BlackWidow.csproj
│ ├── SharpGrabber.BlackWidow.csproj.DotSettings
│ └── TypeConversion
│ │ ├── ToBoolConverter.cs
│ │ └── TypeConverters.cs
├── SharpGrabber.Converter
│ ├── FFMpegHelper.cs
│ ├── IOContext.cs
│ ├── MediaConcatenator.cs
│ ├── MediaDecoder.cs
│ ├── MediaFrame.cs
│ ├── MediaHelper.cs
│ ├── MediaLibrary.cs
│ ├── MediaMerger.cs
│ ├── MediaMuxer.cs
│ ├── MediaPacket.cs
│ ├── MediaStreamSource.cs
│ ├── Reference.cs
│ ├── SharpGrabber.Converter.csproj
│ └── VideoFrameConverter.cs
├── SharpGrabber.Desktop
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Auth
│ │ └── InstagramAuthenticationHandlerInterface.cs
│ ├── Components
│ │ ├── LoadingSpinner.xaml
│ │ ├── LoadingSpinner.xaml.cs
│ │ ├── MediaResourceView.xaml
│ │ ├── MediaResourceView.xaml.cs
│ │ ├── StreamReferenceView.xaml
│ │ ├── StreamReferenceView.xaml.cs
│ │ ├── StreamResourceView.xaml
│ │ └── StreamResourceView.xaml.cs
│ ├── Constants.cs
│ ├── ConvertHelper.cs
│ ├── Downloading
│ │ ├── MediaDownloader.cs
│ │ └── StreamDownloader.cs
│ ├── IOHelper.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── Program.cs
│ ├── SharpGrabber.Desktop.csproj
│ ├── UI
│ │ ├── ButtonStyle.xaml
│ │ ├── Icons.xaml
│ │ ├── StringHelpers.cs
│ │ └── UIHelpers.cs
│ ├── Utils
│ │ └── ExceptionHelpers.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── GrabbedMediaViewModel.cs
│ │ ├── GrabbedStreamRefViewModel.cs
│ │ └── GrabbedStreamViewModel.cs
├── SharpGrabber.Hls
│ ├── AssemblyInitializer.cs
│ ├── Def
│ │ ├── HlsKey.cs
│ │ ├── HlsKeyMethod.cs
│ │ ├── HlsMediaSegment.cs
│ │ ├── HlsPlaylistType.cs
│ │ ├── HlsStreamInfo.cs
│ │ ├── PlaylistDocument.cs
│ │ ├── PlaylistDocumentLoadException.cs
│ │ ├── PlaylistTagValue.cs
│ │ ├── PlaylistToken.cs
│ │ ├── PlaylistTokenType.cs
│ │ └── PlaylistTokenizer.cs
│ ├── Grabbed
│ │ ├── GrabbedHlsStreamMetadata.cs
│ │ └── GrabbedHlsStreamReference.cs
│ ├── HlsGrabber.cs
│ ├── HlsGrabberBuilderExtensions.cs
│ ├── Internal
│ │ ├── HlsAes128Decryptor.cs
│ │ └── ListWrapper.cs
│ └── SharpGrabber.Hls.csproj
├── SharpGrabber.Instagram
│ ├── IInstagramAuthenticationInterface.cs
│ ├── InstagramAuthenticationHandler.cs
│ ├── InstagramAuthenticationHandlerExtensions.cs
│ ├── InstagramAuthenticationRequestState.cs
│ ├── InstagramGrabber.cs
│ ├── InstagramGrabberBuilderExtensions.cs
│ └── SharpGrabber.Instagram.csproj
├── SharpGrabber.Odysee
│ ├── OdyseeGrabber.cs
│ ├── OdyseeGrabberBuilderExtensions.cs
│ └── SharpGrabber.Odysee.csproj
├── SharpGrabber.Vimeo
│ ├── Internal
│ │ ├── VimeoConfiguration.cs
│ │ ├── VimeoFile.cs
│ │ ├── VimeoProgressive.cs
│ │ ├── VimeoRequest.cs
│ │ └── VimeoVideoInfo.cs
│ ├── SharpGrabber.Vimeo.csproj
│ ├── VimeoGrabber.cs
│ └── VimeoGrabberBuilderExtensions.cs
├── SharpGrabber.YouTube
│ ├── SharpGrabber.YouTube.csproj
│ ├── StringHelper.cs
│ ├── YouTubeAdaptiveStream.cs
│ ├── YouTubeGrabber.cs
│ ├── YouTubeGrabberBase.cs
│ ├── YouTubeGrabberBuilderExtensions.cs
│ ├── YouTubeImageType.cs
│ ├── YouTubeMetadata.cs
│ ├── YouTubeMuxedStream.cs
│ ├── YouTubePageInfo.cs
│ ├── YouTubePlayerResponse.cs
│ ├── YouTubeScript.cs
│ ├── YouTubeStreamInfo.cs
│ ├── YouTubeTagInfo.cs
│ ├── YouTubeUtils.cs
│ └── YouTubeWatchPageData.cs
└── SharpGrabber
│ ├── Auth
│ ├── FileAuthenticationStore.cs
│ ├── GrabberAuthenticationRequest.cs
│ ├── GrabberAuthenticationResult.cs
│ ├── GrabberAuthenticationService.cs
│ ├── GrabberBasicCredentials.cs
│ ├── IGrabberAuthenticationHandler.cs
│ ├── IGrabberAuthenticationService.cs
│ ├── IGrabberAuthenticationStore.cs
│ └── InMemoryAuthenticationStore.cs
│ ├── Builder
│ ├── GrabberAuthenticationServiceBuilder.cs
│ ├── GrabberBuilder.cs
│ ├── GrabberServicesBuilder.cs
│ ├── IGrabberAuthenticationServiceBuilder.cs
│ ├── IGrabberBuilder.cs
│ └── IGrabberServicesBuilder.cs
│ ├── Exceptions
│ ├── GrabAuthenticationException.cs
│ ├── GrabException.cs
│ ├── GrabParseException.cs
│ ├── SharpGrabberException.cs
│ └── UnsupportedGrabException.cs
│ ├── Extensions
│ ├── GrabResultExtensions.cs
│ └── GrabbedMediaExtensions.cs
│ ├── GrabOptions.cs
│ ├── GrabResult.cs
│ ├── Grabbed
│ ├── GrabbedComment.cs
│ ├── GrabbedComments.cs
│ ├── GrabbedHlsStream.cs
│ ├── GrabbedImage.cs
│ ├── GrabbedImageSize.cs
│ ├── GrabbedImageType.cs
│ ├── GrabbedInfo.cs
│ ├── GrabbedMedia.cs
│ ├── GrabbedTypeAttribute.cs
│ ├── MediaChannels.cs
│ ├── MediaFormat.cs
│ └── MediaSegment.cs
│ ├── GrabbedResourceBase.cs
│ ├── GrabbedTypeCollection.cs
│ ├── GrabberBase.cs
│ ├── GrabberServices.cs
│ ├── GrabberServicesAssemblyRegistry.cs
│ ├── IGrabResult.cs
│ ├── IGrabbed.cs
│ ├── IGrabbedResource.cs
│ ├── IGrabbedTypeCollection.cs
│ ├── IGrabber.cs
│ ├── IGrabberServices.cs
│ ├── IMultiGrabber.cs
│ ├── Internal
│ ├── ConcurrentHashSet.cs
│ ├── DefaultGlobalHttpProvider.cs
│ ├── DictionaryHelper.cs
│ ├── StringHelper.cs
│ └── WorkStatus.cs
│ ├── Mime
│ ├── DefaultMimeService.cs
│ ├── IMimeService.cs
│ ├── MimeInfo.cs
│ └── MimeType.cs
│ ├── MultiGrabber.cs
│ ├── MultiGrabberBase.cs
│ ├── RectSize.cs
│ ├── SharpGrabber.csproj
│ ├── State
│ ├── GrabberStateBag.cs
│ └── IGrabberStateBag.cs
│ ├── StreamWrappingDelegate.cs
│ └── Utils
│ ├── ResolutionUtils.cs
│ └── VideoResolutionDescriptor.cs
└── tests
├── DotNetTools.SharpGrabber.Tests
├── GrabTests.cs
├── MultiGrabberTests.cs
└── SharpGrabber.Tests.csproj
├── SharpGrabber.BlackWidow.Tests
├── Assets
│ ├── AssetsAccessor.cs
│ └── Html
│ │ └── SamplePage.html
├── BlackWidowServiceTests.cs
├── Interpreter
│ └── JavaScript
│ │ ├── JintGrabberTests.cs
│ │ ├── JintMultiTypeConverterTests.cs
│ │ └── JintUrlTests.cs
├── Repository
│ ├── ChangeDetectorTests.cs
│ ├── GetDifferencesTests.cs
│ ├── GitHubRepositoryTests.cs
│ └── LocalRepositoryTests.cs
└── SharpGrabber.BlackWidow.Tests.csproj
├── SharpGrabber.Tests
└── SharpGrabber.Tests
│ ├── Adult
│ └── PornHubTests.cs
│ ├── Odysee
│ └── OdyseeTests.cs
│ ├── SharpGrabber.Tests.csproj
│ └── YouTube
│ └── YouTubeTests.cs
└── assets
└── blackwidow
└── repo
├── emptyfeed.json
├── feed.json
└── scripts
└── youtube.js
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - name: Checkout source code
16 | uses: actions/checkout@v3
17 | - name: Setup .NET
18 | uses: actions/setup-dotnet@v2
19 | with:
20 | dotnet-version: 3.1.x
21 | - name: Restore dependencies
22 | run: dotnet restore
23 | - name: Build
24 | run: dotnet build --no-restore
25 | - name: Test
26 | run: dotnet test --no-build --verbosity normal
27 |
--------------------------------------------------------------------------------
/assets/SharpGrabberDesktop-ScreenShot-4.0-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/SharpGrabberDesktop-ScreenShot-4.0-2.png
--------------------------------------------------------------------------------
/assets/blackwidow-logo-text-sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/blackwidow-logo-text-sm.png
--------------------------------------------------------------------------------
/assets/blackwidow-logo-text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/blackwidow-logo-text.png
--------------------------------------------------------------------------------
/assets/blackwidow-logo-text.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/blackwidow-logo-text.psd
--------------------------------------------------------------------------------
/assets/blackwidow-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/blackwidow-logo.png
--------------------------------------------------------------------------------
/assets/blackwidow-logo.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/blackwidow-logo.psd
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnettools/SharpGrabber/96743e630a4ff37f39ed3f11cabb0b5c773d058a/assets/icon.png
--------------------------------------------------------------------------------
/blackwidow/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # BlackWidow
4 |
5 | BlackWidow is a .NET library based on SharpGrabber. Rather than relying on .NET assemblies, BlackWidow executes scripts written specifically for grabbing.
6 |
7 | ## Why use BlackWidow?
8 | BlackWidow gives you the following advantages over the traditional NuGet package approach:
9 |
10 | - **Always Up-to-date:** The scripts are always kept up-to-date at runtime; so the functionality of the host application won't break as the sources change - at least not for long!
11 | - **ECMAScript Support:** Supports JavaScript/ECMAScript out of the box.
12 | - **Easy Maintenance:** *JavaScript* is quick to code and welcomes many developers. This helps contributors to quickly write new grabbers or fix the existing ones.
13 | - **Secure**: The scripts are executed in a sandbox environment, and they only have access to what the BlackWidow API exposes to them.
14 | - **Highly Customizable:** Almost everything is open for extension or replacement. Make new script interpreters, custom grabber repositories, or roll out your own interpreter APIs
15 |
16 | ## How does it work?
17 |
18 | BlackWidow keeps a collection of scripts locally - called the local repository.
19 | Each script gets interpreted as an object implementing `IGrabber`.
20 | To keep the scripts up-to-date, a remote repository is constantly monitored as the single source of truth.
21 |
22 | **🗐 Installation / Documentation**
23 |
24 |
25 | <- Back to Home Page
26 |
--------------------------------------------------------------------------------
/blackwidow/repo/feed.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": [
3 | {
4 | "id": "vimeo.com",
5 | "name": "Vimeo",
6 | "version": "1.0",
7 | "type": "JavaScript",
8 | "apiVersion": 1,
9 | "supportedRegularExpressions": [ "^https?://(www\\.|player\\.)?vimeo\\.com/(video/)?([0-9]+)" ],
10 | "file": "scripts/vimeo.js"
11 | },
12 | {
13 | "id": "pornhub.com",
14 | "name": "PornHub",
15 | "version": "1.0",
16 | "type": "JavaScript",
17 | "apiVersion": 1,
18 | "supportedRegularExpressions": [ "^(https?:\\/\\/)?(www\\.)?pornhub\\.com\\/([^\\/]+)viewkey=(\\w+).*$" ],
19 | "file": "scripts/pornhub.js"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/src/SharpGrabber.Adult/AdultGrabberBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using DotNetTools.SharpGrabber.Adult;
2 |
3 | namespace DotNetTools.SharpGrabber
4 | {
5 | ///
6 | /// Provides extension methods for .
7 | ///
8 | public static class AdultGrabberBuilderExtensions
9 | {
10 | ///
11 | /// Includes the PornHub grabber.
12 | ///
13 | public static IGrabberBuilder AddPornHub(this IGrabberBuilder builder)
14 | => builder.Add();
15 |
16 | ///
17 | /// Includes the XNXX grabber.
18 | ///
19 | public static IGrabberBuilder AddXnxx(this IGrabberBuilder builder)
20 | => builder.Add();
21 |
22 | ///
23 | /// Includes the xvideos grabber.
24 | ///
25 | public static IGrabberBuilder AddXVideos(this IGrabberBuilder builder)
26 | => builder.Add();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/SharpGrabber.Adult/Internal/JsonHelper.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 |
3 | namespace DotNetTools.SharpGrabber.Adult.Internal
4 | {
5 | internal static class JsonHelper
6 | {
7 | ///
8 | /// Adopted from https://stackoverflow.com/a/51428508/492352 with minor modifications
9 | ///
10 | public static bool TryParseJson(string text, out T result)
11 | {
12 | bool success = true;
13 | var settings = new JsonSerializerSettings
14 | {
15 | Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; },
16 | MissingMemberHandling = MissingMemberHandling.Error
17 | };
18 | result = JsonConvert.DeserializeObject(text, settings);
19 | return success;
20 | }
21 |
22 | public static bool TryParseJson(string text, out object result)
23 | {
24 | bool success = true;
25 | var settings = new JsonSerializerSettings
26 | {
27 | Error = (sender, args) => { success = false; args.ErrorContext.Handled = true; },
28 | MissingMemberHandling = MissingMemberHandling.Error
29 | };
30 | result = JsonConvert.DeserializeObject(text, settings);
31 | return success;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/SharpGrabber.Adult/Internal/StringHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DotNetTools.SharpGrabber.Internal
4 | {
5 | internal static class StringHelper
6 | {
7 | public static int ForceParseInt(string s)
8 | {
9 | var num = 0;
10 | foreach (var ch in s)
11 | {
12 | if (!char.IsDigit(ch))
13 | continue;
14 | var digit = (int)char.GetNumericValue(ch);
15 | num = num * 10 + digit;
16 | }
17 | return num;
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/SharpGrabber.Adult/SharpGrabber.Adult.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | DotNetTools.SharpGrabber.Adult
6 | true
7 | Javid Shoaei
8 | github.com/dotnettools
9 | Adds support for grabbing information and media from top adult services.
10 | LICENSE
11 | https://github.com/dotnettools/SharpGrabber
12 | icon.png
13 |
14 | 9
15 | https://github.com/dotnettools/SharpGrabber
16 | adult,porn,video,download,grab,scrape,pornhub,xvideos,xnxx
17 | 1701;1702;1591
18 | 1.0.2
19 | AnyCPU;x64
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | True
30 |
31 |
32 |
33 | True
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/SharpGrabber.Adult/XVideosGrabber.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace DotNetTools.SharpGrabber.Adult
5 | {
6 | public class XVideosGrabber : XnxxGrabber
7 | {
8 | private static readonly Regex HostRegex = new(@"^(https?://)?(www\.)?xvideos.com/video([^/]+)/", RegexOptions.Compiled | RegexOptions.IgnoreCase);
9 |
10 | public XVideosGrabber(IGrabberServices services) : base(services)
11 | {
12 | }
13 |
14 | public override string StringId { get; } = "xvideos.com";
15 |
16 | public override string Name { get; } = "xvideos";
17 |
18 | public override bool Supports(Uri uri)
19 | {
20 | return GetVideoId(uri.ToString()) != null;
21 | }
22 |
23 | public static new string GetVideoId(string url)
24 | {
25 | var match = HostRegex.Match(url);
26 | if (match.Success)
27 | return match.Groups[3].Value;
28 | return null;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/BlackWidowConstants.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow
6 | {
7 | ///
8 | /// Defines BlackWidow-related constants.
9 | ///
10 | public static class BlackWidowConstants
11 | {
12 | public static class GitHub
13 | {
14 | public static class OfficialRepository
15 | {
16 | ///
17 | /// The offical repository name
18 | ///
19 | public const string RepositoryAddress = "dotnettools/SharpGrabber";
20 |
21 | ///
22 | /// Name of the main branch
23 | ///
24 | public const string MasterBranch = "master";
25 |
26 | ///
27 | /// Path to the directory that contains the feed file and the scripts
28 | ///
29 | public const string RootPath = "blackwidow/repo";
30 |
31 | ///
32 | /// Name of the feed JSON file
33 | ///
34 | public const string FeedFileName = "feed.json";
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/BlackWidowInitializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text;
5 |
6 | namespace DotNetTools.SharpGrabber.BlackWidow
7 | {
8 | internal static class BlackWidowInitializer
9 | {
10 | static BlackWidowInitializer()
11 | {
12 | EnsureLoaded(Hls.HlsGrabber.Initializer);
13 | }
14 |
15 | public static void Test()
16 | {
17 | // nothing should be done here,
18 | // the static constructor would run once.
19 | }
20 |
21 | private static void EnsureLoaded(params Type[] types)
22 | {
23 | foreach (var type in types)
24 | {
25 | // create a dummy instance just to ensure the type is loaded
26 | var o = Activator.CreateInstance(type);
27 | if (o is IDisposable disposable)
28 | disposable.Dispose();
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/BlackWidowRepositoryConfigurator.cs:
--------------------------------------------------------------------------------
1 | using DotNetTools.SharpGrabber.BlackWidow.Repository;
2 |
3 | namespace DotNetTools.SharpGrabber.BlackWidow
4 | {
5 | ///
6 | /// Builds BlackWidow repositories.
7 | ///
8 | internal class BlackWidowRepositoryConfigurator : IBlackWidowRepositoryConfigurator
9 | {
10 | public IGrabberRepository Repository { get; private set; }
11 |
12 | public IBlackWidowRepositoryConfigurator Use(IGrabberRepository repository)
13 | {
14 | Repository?.Dispose();
15 | Repository = repository;
16 | return this;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/BuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using DotNetTools.SharpGrabber.BlackWidow.Definitions;
2 | using DotNetTools.SharpGrabber.BlackWidow.Interpreter.Api;
3 | using DotNetTools.SharpGrabber.BlackWidow.Interpreter.JavaScript;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow
6 | {
7 | ///
8 | /// Defines extension methods for builder and configurator interfaces to work with built-in implementations.
9 | ///
10 | public static class BuilderExtensions
11 | {
12 | ///
13 | /// Registers Jint as the JavaScript interpreter.
14 | ///
15 | public static IGrabberScriptInterpreterServiceConfigurator AddJint(this IGrabberScriptInterpreterServiceConfigurator interpreterService)
16 | {
17 | return interpreterService.AddInterpreter(GrabberScriptType.JavaScript, context =>
18 | {
19 | return new JintJavaScriptInterpreter(context.ApiService, context.GrabberServices, context.ScriptHost);
20 | });
21 | }
22 |
23 | ///
24 | /// Configures to use the official API service.
25 | ///
26 | public static IGrabberScriptInterpreterServiceConfigurator SetDefaultApiService(this IGrabberScriptInterpreterServiceConfigurator interpreterService)
27 | {
28 | return interpreterService.SetApiService(context => new DefaultInterpreterApiService(context.GrabberServices, context.GrabbedTypes, context.TypeConverter));
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/GrabberScriptInterpreterActivationContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DotNetTools.SharpGrabber.BlackWidow.Host;
3 | using DotNetTools.SharpGrabber.BlackWidow.Interpreter.Api;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow
6 | {
7 | ///
8 | /// Provides references to services used when activating an interpreter.
9 | ///
10 | public class GrabberScriptInterpreterActivationContext
11 | {
12 | public GrabberScriptInterpreterActivationContext(IInterpreterApiService apiService, IGrabberServices grabberServices, IScriptHost scripHost)
13 | {
14 | ApiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
15 | GrabberServices = grabberServices ?? throw new ArgumentNullException(nameof(grabberServices));
16 | ScriptHost = scripHost ?? throw new ArgumentNullException(nameof(scripHost));
17 | }
18 |
19 | ///
20 | /// Gets the interpreter API service.
21 | ///
22 | public IInterpreterApiService ApiService { get; }
23 |
24 | ///
25 | /// Gets the grabber services.
26 | ///
27 | public IGrabberServices GrabberServices { get; }
28 |
29 | ///
30 | /// Gets the script host.
31 | ///
32 | public IScriptHost ScriptHost { get; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/GrabberScriptInterpreterApiServiceActivationContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DotNetTools.ConvertEx;
3 | using DotNetTools.SharpGrabber.BlackWidow.Host;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow
6 | {
7 | ///
8 | /// Provides references to services used when activating an interpreter API service.
9 | ///
10 | public class GrabberScriptInterpreterApiServiceActivationContext
11 | {
12 | public GrabberScriptInterpreterApiServiceActivationContext(IGrabberServices grabberServices, IScriptHost scriptHost,
13 | IGrabbedTypeCollection grabbedTypes, ITypeConverter typeConverter)
14 | {
15 | GrabberServices = grabberServices ?? throw new ArgumentNullException(nameof(grabberServices));
16 | ScriptHost = scriptHost ?? throw new ArgumentNullException(nameof(scriptHost));
17 | GrabbedTypes = grabbedTypes ?? throw new ArgumentNullException(nameof(grabbedTypes));
18 | TypeConverter = typeConverter ?? throw new ArgumentNullException(nameof(typeConverter));
19 | }
20 |
21 | ///
22 | /// Gets the grabber services.
23 | ///
24 | public IGrabberServices GrabberServices { get; }
25 |
26 | ///
27 | /// Gets the script host.
28 | ///
29 | public IScriptHost ScriptHost { get; }
30 |
31 | ///
32 | /// Gets the collection of grabbed types.
33 | ///
34 | public IGrabbedTypeCollection GrabbedTypes { get; }
35 |
36 | ///
37 | /// Gets the type converter.
38 | ///
39 | public ITypeConverter TypeConverter { get; }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/IBlackWidowBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using DotNetTools.SharpGrabber.BlackWidow.Host;
4 | using DotNetTools.SharpGrabber.BlackWidow.Interpreter;
5 | using DotNetTools.SharpGrabber.BlackWidow.Repository;
6 |
7 | namespace DotNetTools.SharpGrabber.BlackWidow
8 | {
9 | ///
10 | /// Builds a .
11 | ///
12 | public interface IBlackWidowBuilder
13 | {
14 | ///
15 | /// Configures the local repository.
16 | ///
17 | IBlackWidowBuilder ConfigureLocalRepository(Action configure);
18 |
19 | ///
20 | /// Configures the remote repository.
21 | ///
22 | IBlackWidowBuilder ConfigureRemoteRepository(Action configure);
23 |
24 | ///
25 | /// Sets the grabber services.
26 | ///
27 | IBlackWidowBuilder SetGrabberServices(IGrabberServices grabberServices);
28 |
29 | ///
30 | /// Sets the script host.
31 | ///
32 | IBlackWidowBuilder SetScriptHost(IScriptHost scriptHost);
33 |
34 | ///
35 | /// Sets the change detector.
36 | ///
37 | IBlackWidowBuilder SetChangeDetector(IGrabberRepositoryChangeDetector changeDetector);
38 |
39 | ///
40 | /// Sets to be used.
41 | ///
42 | IBlackWidowBuilder UseInterpreterService(IGrabberScriptInterpreterService interpreterService);
43 |
44 | ///
45 | /// Configures the interpreter service.
46 | ///
47 | IBlackWidowBuilder ConfigureInterpreterService(Action configure);
48 |
49 | ///
50 | /// Builds the service.
51 | ///
52 | /// Thrown in case of misconfiguration.
53 | Task BuildAsync();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Builder/IBlackWidowRepositoryConfigurator.cs:
--------------------------------------------------------------------------------
1 | using DotNetTools.SharpGrabber.BlackWidow.Repository;
2 |
3 | namespace DotNetTools.SharpGrabber.BlackWidow
4 | {
5 | ///
6 | /// Configures a repository on a builder.
7 | ///
8 | public interface IBlackWidowRepositoryConfigurator
9 | {
10 | ///
11 | /// Gets the configured repository.
12 | ///
13 | IGrabberRepository Repository { get; }
14 |
15 | ///
16 | /// Uses a repository instance.
17 | ///
18 | IBlackWidowRepositoryConfigurator Use(IGrabberRepository repository);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Definitions/GrabberScriptSource.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Threading.Tasks;
3 |
4 | namespace DotNetTools.SharpGrabber.BlackWidow.Definitions
5 | {
6 | ///
7 | /// Default implementation for
8 | ///
9 | public class GrabberScriptSource : IGrabberScriptSource
10 | {
11 | ///
12 | /// Refers to a static empty source.
13 | ///
14 | public static readonly GrabberScriptSource Empty = new(string.Empty);
15 |
16 | private readonly string _source;
17 |
18 | public GrabberScriptSource(string source)
19 | {
20 | _source = source;
21 | }
22 |
23 | ///
24 | /// Creates a by reading all the source code from a file.
25 | ///
26 | public static GrabberScriptSource FromFile(string fileName)
27 | {
28 | var src = File.ReadAllText(fileName);
29 | return new GrabberScriptSource(src);
30 | }
31 |
32 | public string GetSource()
33 | => _source;
34 |
35 | public Task GetSourceAsync()
36 | => Task.FromResult(_source);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Definitions/GrabberScriptType.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Reflection;
3 |
4 | namespace DotNetTools.SharpGrabber.BlackWidow.Definitions
5 | {
6 | ///
7 | /// Defines all possible script types.
8 | ///
9 | public enum GrabberScriptType
10 | {
11 | ///
12 | /// ECMAScript
13 | ///
14 | [GrabberScriptType(FileExtension = "js")]
15 | JavaScript = 1,
16 | }
17 |
18 | public static class GrabberScriptTypeExtensions
19 | {
20 | ///
21 | /// Gets the associated with the value.
22 | ///
23 | public static GrabberScriptTypeAttribute GetScriptTypeAttribute(this GrabberScriptType value, bool orDefault = true)
24 | {
25 | GrabberScriptTypeAttribute GetDefault()
26 | => orDefault ? GrabberScriptTypeAttribute.Default : null;
27 |
28 | var enumType = typeof(GrabberScriptType);
29 | var member = enumType.GetMember(value.ToString()).FirstOrDefault(m => m.DeclaringType == enumType);
30 | return member.GetCustomAttribute() ?? GetDefault();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Definitions/GrabberScriptTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DotNetTools.SharpGrabber.BlackWidow.Definitions
4 | {
5 | [AttributeUsage(AttributeTargets.Field)]
6 | public class GrabberScriptTypeAttribute : Attribute
7 | {
8 | ///
9 | /// Gets the default value.
10 | ///
11 | public static GrabberScriptTypeAttribute Default => new();
12 |
13 | ///
14 | /// Gets or sets the file extension associated with this script type.
15 | ///
16 | public string FileExtension { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Definitions/IGrabberScriptSource.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace DotNetTools.SharpGrabber.BlackWidow.Definitions
4 | {
5 | ///
6 | /// Provides access to the source of a grabber script.
7 | ///
8 | public interface IGrabberScriptSource
9 | {
10 | ///
11 | /// Gets the source code of the grabber script.
12 | ///
13 | string GetSource();
14 |
15 | ///
16 | /// Gets the source code of the grabber script.
17 | ///
18 | Task GetSourceAsync();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Exceptions/BlackWidowException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using System.Text;
5 |
6 | namespace DotNetTools.SharpGrabber.BlackWidow.Exceptions
7 | {
8 | public class BlackWidowException : Exception
9 | {
10 | public BlackWidowException()
11 | {
12 | }
13 |
14 | public BlackWidowException(string message) : base(message)
15 | {
16 | }
17 |
18 | public BlackWidowException(string message, Exception innerException) : base(message, innerException)
19 | {
20 | }
21 |
22 | protected BlackWidowException(SerializationInfo info, StreamingContext context) : base(info, context)
23 | {
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Exceptions/ScriptApiVersionMismatchException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using System.Text;
5 |
6 | namespace DotNetTools.SharpGrabber.BlackWidow.Exceptions
7 | {
8 | public class ScriptApiVersionMismatchException : BlackWidowException
9 | {
10 | public ScriptApiVersionMismatchException()
11 | {
12 | }
13 |
14 | public ScriptApiVersionMismatchException(string message) : base(message)
15 | {
16 | }
17 |
18 | public ScriptApiVersionMismatchException(string message, Exception innerException) : base(message, innerException)
19 | {
20 | }
21 |
22 | protected ScriptApiVersionMismatchException(SerializationInfo info, StreamingContext context) : base(info, context)
23 | {
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Exceptions/ScriptInterpretException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.Serialization;
4 | using System.Text;
5 |
6 | namespace DotNetTools.SharpGrabber.BlackWidow.Exceptions
7 | {
8 | public class ScriptInterpretException : BlackWidowException
9 | {
10 | public ScriptInterpretException() : this("Script interpret error.")
11 | {
12 | }
13 |
14 | public ScriptInterpretException(string message) : base(message)
15 | {
16 | }
17 |
18 | public ScriptInterpretException(string message, Exception innerException) : base(message, innerException)
19 | {
20 | }
21 |
22 | protected ScriptInterpretException(SerializationInfo info, StreamingContext context) : base(info, context)
23 | {
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Host/ConsoleLog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow.Host
6 | {
7 | ///
8 | /// Describes a log entry.
9 | ///
10 | public class ConsoleLog
11 | {
12 | public ConsoleLog(ConsoleLogLevel level, params object[] objects)
13 | {
14 | Level = level;
15 | Objects = objects;
16 | }
17 |
18 | ///
19 | /// Gets the level.
20 | ///
21 | public ConsoleLogLevel Level { get; }
22 |
23 | ///
24 | /// Gets the logged objects.
25 | ///
26 | public object[] Objects { get; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Host/ConsoleLogLevel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow.Host
6 | {
7 | public enum ConsoleLogLevel
8 | {
9 | Log,
10 | Debug,
11 | Error,
12 | Info,
13 | Warning,
14 | Trace
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Host/IScriptHost.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow.Host
6 | {
7 | ///
8 | /// Defines handlers for various operations on the script host.
9 | ///
10 | public interface IScriptHost
11 | {
12 | void Alert(object input);
13 |
14 | void Log(ConsoleLog log);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/SharpGrabber.BlackWidow/Host/ScriptHost.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace DotNetTools.SharpGrabber.BlackWidow.Host
6 | {
7 | ///
8 | /// Implements with events.
9 | ///
10 | public class ScriptHost : IScriptHost
11 | {
12 | public ScriptHost()
13 | {
14 | }
15 |
16 | public event Action