Skip to content

Commit

Permalink
Added user experience
Browse files Browse the repository at this point in the history
  • Loading branch information
PoinP committed Oct 4, 2020
1 parent 162c2bf commit 4af3de9
Show file tree
Hide file tree
Showing 18 changed files with 579 additions and 97 deletions.
Binary file modified .vs/LightShotScraper/DesignTimeBuild/.dtbcache.v2
Binary file not shown.
Binary file modified .vs/LightShotScraper/v16/.suo
Binary file not shown.
78 changes: 78 additions & 0 deletions LightShot Scraper/Core/HtmlParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,78 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace LightShotScraper.Core
{
class HtmlParser : WebClientService
{
bool isUserAgentChanged;

public HtmlParser() : base()
{
isUserAgentChanged = false;
}

public Uri GetImageUrl(Uri uri)
{
var htmlData = _webClient.DownloadString(uri);

if (!isUserAgentChanged)
{
_webClient.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36");
isUserAgentChanged = true;
}

return ParseImageUrl(htmlData);
}

public Uri GetImageUrl(string url)
{
if(!Uri.IsWellFormedUriString(url, UriKind.Absolute))
{
throw new UriFormatException("Url was not formatted correctly!");
}

Uri.TryCreate(url, UriKind.Absolute, out var uri);

return GetImageUrl(uri);
}

public async Task<Uri> GetImageUrlAsync(Uri uri)
{
var htmlData = await _webClient.DownloadStringTaskAsync(uri);

return ParseImageUrl(htmlData);
}

public async Task<List<Uri>> GetImagesUrlsAsync(List<Uri> uris)
{
List<Task<Uri>> tasks = new List<Task<Uri>>();

foreach(var uri in uris)
{
tasks.Add(GetImageUrlAsync(uri));
}

var parsedUris = await Task.WhenAll(tasks);

return parsedUris.ToList();
}

private Uri ParseImageUrl(string url)
{
var imageUrl = url
.GetStringBetween("image_url=", @">")
.Replace('"', ' ')
.Trim();

if (!Uri.TryCreate(imageUrl, UriKind.Absolute, out var imageUri))
{
throw new UriFormatException("ImageUrl was not formatted correctly!");
}

return imageUri;
}
}
}
90 changes: 90 additions & 0 deletions LightShot Scraper/Core/ImageDownloader.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,90 @@
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;

using LightShotScraper.Utility;

namespace LightShotScraper.Core
{
class ImageDownloader : WebClientService
{
private string _path;
private LightshotImage _image;

public ImageDownloader(string path = "") : base()
{
_path = path;
}

public LightshotImage DownloadImage(Uri uri)
{
_image = new LightshotImage(uri);

if (IsImageValid())
{
return SaveImage();
}
return null;
}

public List<LightshotImage> DownloadImagesAsync(List<Uri> uris, ProgressBar progress)
{
var images = new List<LightshotImage>();
int count = 0;

foreach (var uri in uris)
{
count ;
_image = new LightshotImage(uri);

if (IsImageValid() && !DoesImageExist())
{
images.Add(DownloadImage(uri));
progress.Report((count * 100) / uris.Count, _image);
continue;
}

string message = !IsImageValid() ?
$"\rImage {_image.Name} does not exist on the site! " :
$"\rImage {_image.Name} already exists in the selected directory! ";

Console.WriteLine(message);
progress.DrawCurrentProgressBar();
}

return images;
}
private string GetFilePath()
{
return $@"{_path}\{_image.Name}.{_image.Format}";
}

private LightshotImage SaveImage()
{
var imagePath = GetFilePath();

using var stream = _webClient.OpenRead(_image.Uri.AbsoluteUri);
var imageSize = Convert.ToInt64(_webClient.ResponseHeaders["Content-Length"]);
_image.SetFileSize(imageSize);
Bitmap bitmap = new Bitmap(stream);

if (bitmap != null)
{
bitmap.Save(imagePath, _image.Format);
}

return _image;
}

private bool IsImageValid()
{
return !_image.Uri.AbsoluteUri.Contains("st.prntscr.com/2020/08/01/0537/img/0_173a7b_211be8ff.png");
}

private bool DoesImageExist()
{
return File.Exists(GetFilePath());
}
}
}
96 changes: 96 additions & 0 deletions LightShot Scraper/Core/LightshotImage.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,96 @@
using System;
using System.Drawing.Imaging;

using LightShotScraper.Core;

namespace LightShotScraper
{
public class LightshotImage
{
public string Url { get; private set; }
public Uri Uri { get; private set; }
public string Name { get; private set; }
public string Size { get; private set; }
public ImageFormat Format { get; private set; }


public LightshotImage(string url)
{
HtmlParser parser = new HtmlParser();
Uri.TryCreate(url, UriKind.Absolute, out var uri);
Uri = parser.GetImageUrl(uri);
Url = Uri.AbsoluteUri;
Name = url.Split("sc/")[1];
Format = GetImageFormatFromUrl();
}

public LightshotImage(Uri uri)
{
HtmlParser parser = new HtmlParser();
Uri = parser.GetImageUrl(uri.AbsoluteUri);
Url = Uri.AbsoluteUri;
Name = uri.AbsoluteUri.Split("sc/")[1];
Format = GetImageFormatFromUrl();
}

public void SetFileSize(long bytes)
{
Unit unit = Unit.B;
double size = 0;

if (bytes < 1024)
{
unit = Unit.B;
Size = $"{bytes} {unit}";
return;
}
if (bytes > 1024 && bytes < Math.Pow(1024, 2))
{
unit = Unit.KB;
size = bytes / 1024;
}
else if (bytes > Math.Pow(1024, 2) && bytes < Math.Pow(1024, 3))
{
unit = Unit.MB;
size = bytes / Math.Pow(1024, 2);
}
else if (bytes > Math.Pow(1024, 3) && bytes < Math.Pow(1024, 4))
{
unit = Unit.GB;
size = bytes / Math.Pow(1024, 3);
}
else if (bytes > Math.Pow(1024, 4))
{
unit = Unit.TB;
size = bytes / Math.Pow(1024, 4);
}

Size = $"{Math.Round(size, 2)} {unit}";
}

private ImageFormat GetImageFormatFromUrl()
{
int dotFormatIndex = Url.LastIndexOf('.');

string imageFormatString = Url.Substring(dotFormatIndex 1).FirstCharToUpper();

return SeekFormat(imageFormatString);
}

private ImageFormat SeekFormat(string formatString) =>
formatString switch
{
"Bmp" => ImageFormat.Bmp,
"Emf" => ImageFormat.Emf,
"Exif" => ImageFormat.Exif,
"Gif" => ImageFormat.Gif,
"Icon" => ImageFormat.Icon,
"Jpeg" => ImageFormat.Jpeg,
"Jpg" => ImageFormat.Jpeg,
"Png" => ImageFormat.Png,
"Tiff" => ImageFormat.Tiff,
"Wmf" => ImageFormat.Wmf,
_ => throw new ArgumentException("No such format exists!")
};
}
}
19 changes: 19 additions & 0 deletions LightShot Scraper/Core/WebClientService.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,19 @@
using System.Net;

namespace LightShotScraper.Core
{
abstract class WebClientService
{
protected WebClient _webClient;
private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0";

protected WebClientService()
{
_webClient = new WebClient();
_webClient.Headers.Add("authority", "prnt.sc");
_webClient.Headers.Add("cache-control", "max-age=0");
_webClient.Headers.Add("upgrade-insecure-requests", "1");
_webClient.Headers.Add("user-agent", UserAgent);
}
}
}
8 changes: 8 additions & 0 deletions LightShot Scraper/Enum/Unit.cs
Original file line number Diff line number Diff line change
@@ -0,0 1,8 @@
 enum Unit
{
B,
KB,
MB,
GB,
TB
}
4 changes: 1 addition & 3 deletions LightShot Scraper/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 1,4 @@

using System.Diagnostics;
using System.Linq;
using System.Linq;

namespace System
{
Expand Down
Loading

0 comments on commit 4af3de9

Please sign in to comment.