Exemplo n.º 1
0
        public IEnumerable<string> PopulatePages(Doujin doujin)
        {
            if (!int.TryParse(doujin.SourceId, out var intId))
                yield break;

            var data = _serializer.Deserialize<InternalDoujinData>(doujin.Data);

            if (data.ImageNames == null || data.Extensions == null)
                yield break;

            for (var i = 0; i < data.ImageNames.Length; i++)
            {
                var    name = data.ImageNames[i];
                string extension;

                switch (data.Extensions[i])
                {
                    case '.':
                        extension = "";
                        break;
                    case 'p':
                        extension = ".png";
                        break;
                    case 'J':
                        extension = ".jpeg";
                        break;
                    case 'g':
                        extension = ".gif";
                        break;
                    default:
                        extension = ".jpg";
                        break;
                }

                yield return Hitomi.Image(intId, name + extension);
            }
        }
Exemplo n.º 2
0
        public async Task<DoujinInfo> GetAsync(string id,
                                               CancellationToken cancellationToken = default)
        {
            if (!int.TryParse(id, out var intId))
                return null;

            HtmlNode root;

            // load html page
            using (var response = await _http.SendAsync(
                new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(Hitomi.Gallery(intId))
                },
                cancellationToken))
            {
                if (!response.IsSuccessStatusCode)
                    return null;

                using (var reader = new StringReader(await response.Content.ReadAsStringAsync()))
                {
                    var doc = new HtmlDocument();
                    doc.Load(reader);

                    root = doc.DocumentNode;
                }
            }

            // filter out anime
            var type = Sanitize(root.SelectSingleNode(Hitomi.XPath.Type));

            if (type != null && type.Equals("anime", StringComparison.OrdinalIgnoreCase))
            {
                _logger.LogInformation($"Skipping '{id}' because it is of type 'anime'.");
                return null;
            }

            var prettyName = Sanitize(root.SelectSingleNode(Hitomi.XPath.Name));

            // replace stuff in brackets with nothing
            prettyName = _bracketsRegex.Replace(prettyName, "");

            var originalName = prettyName;

            // parse names with two parts
            var pipeIndex = prettyName.IndexOf('|');

            if (pipeIndex != -1)
            {
                prettyName   = prettyName.Substring(0, pipeIndex).Trim();
                originalName = originalName.Substring(pipeIndex + 1).Trim();
            }

            // parse language
            var languageHref = root.SelectSingleNode(Hitomi.XPath.Language)?.Attributes["href"]?.Value;

            var language = languageHref == null
                ? null
                : _languageHrefRegex.Match(languageHref).Groups["language"].Value;

            var doujin = new DoujinInfo
            {
                PrettyName   = prettyName,
                OriginalName = originalName,

                UploadTime = DateTime.Parse(Sanitize(root.SelectSingleNode(Hitomi.XPath.Date))).ToUniversalTime(),

                Source   = this,
                SourceId = id,

                Artist     = Sanitize(root.SelectSingleNode(Hitomi.XPath.Artists))?.ToLowerInvariant(),
                Group      = Sanitize(root.SelectSingleNode(Hitomi.XPath.Groups))?.ToLowerInvariant(),
                Language   = language?.ToLowerInvariant(),
                Parody     = ConvertSeries(Sanitize(root.SelectSingleNode(Hitomi.XPath.Series)))?.ToLowerInvariant(),
                Characters = root.SelectNodes(Hitomi.XPath.Characters)?.Select(n => Sanitize(n)?.ToLowerInvariant()),
                Tags = root.SelectNodes(Hitomi.XPath.Tags)
                          ?.Select(n => ConvertTag(Sanitize(n)?.ToLowerInvariant()))
            };

            // parse images
            using (var response = await _http.SendAsync(
                new HttpRequestMessage
                {
                    Method     = HttpMethod.Get,
                    RequestUri = new Uri(Hitomi.GalleryInfo(intId))
                },
                cancellationToken))
            {
                if (!response.IsSuccessStatusCode)
                    return null;

                using (var textReader = new StringReader(await response.Content.ReadAsStringAsync()))
                using (var jsonReader = new JsonTextReader(textReader))
                {
                    // discard javascript bit and start at json
                    while ((char) textReader.Peek() != '[')
                        textReader.Read();

                    var images = _serializer.Deserialize<ImageInfo[]>(jsonReader);

                    var extensionsCombined =
                        new string(images.Select(i =>
                                          {
                                              var ext = Path.GetExtension(i.Name);

                                              switch (ext)
                                              {
                                                  case "":      return '.';
                                                  case ".jpg":  return 'j';
                                                  case ".jpeg": return 'J';
                                                  case ".png":  return 'p';
                                                  case ".gif":  return 'g';
                                                  default:

                                                      throw new NotSupportedException(
                                                          $"Unknown image format '{ext}'.");
                                              }
                                          })
                                         .ToArray());

                    doujin.PageCount = images.Length;

                    doujin.Data = _serializer.Serialize(new InternalDoujinData
                    {
                        ImageNames = images.Select(i => Path.GetFileNameWithoutExtension(i.Name)).ToArray(),
                        Extensions = extensionsCombined
                    });
                }
            }

            return doujin;
        }