Add project files.
parent
eaeebaf057
commit
5da1787234
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ViraScraper.Repositories;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
using ViraScraper.Services.Contracts;
|
||||
|
||||
namespace ViraScraper.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ScraperController : ControllerBase
|
||||
{
|
||||
private readonly IServiceWrapper _serviceWrapper;
|
||||
|
||||
public ScraperController(IServiceWrapper serviceWrapper)
|
||||
{
|
||||
_serviceWrapper = serviceWrapper;
|
||||
}
|
||||
[HttpGet()]
|
||||
public async Task<IActionResult> GetScrape()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _serviceWrapper.HashtagService.GetHshtags("باران"));
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
}
|
||||
/*[HttpGet]
|
||||
public async Task<IActionResult> GetScrape(string hashtag)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(await _serviceWrapper.HashtagService.GetHshtags(hashtag));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Migrations
|
||||
{
|
||||
[DbContext(typeof(ScrapDbContext))]
|
||||
[Migration("20191212061434_Init")]
|
||||
partial class Init
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.1.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Hashtag", b =>
|
||||
{
|
||||
b.Property<int>("HashtagId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("HashtagType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Tag")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("HashtagId");
|
||||
|
||||
b.ToTable("Hashtags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Synonyms", b =>
|
||||
{
|
||||
b.Property<int>("SynonymsId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("HashtagAId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("HashtagBId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("SynonymsId");
|
||||
|
||||
b.HasIndex("HashtagAId");
|
||||
|
||||
b.HasIndex("HashtagBId");
|
||||
|
||||
b.ToTable("Synonymses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Synonyms", b =>
|
||||
{
|
||||
b.HasOne("ViraScraper.Models.Hashtag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("HashtagAId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ViraScraper.Models.Hashtag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("HashtagBId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace ViraScraper.Migrations
|
||||
{
|
||||
public partial class Init : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Hashtags",
|
||||
columns: table => new
|
||||
{
|
||||
HashtagId = table.Column<int>(nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Tag = table.Column<string>(nullable: true),
|
||||
CreationDate = table.Column<DateTime>(nullable: false),
|
||||
HashtagType = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Hashtags", x => x.HashtagId);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Synonymses",
|
||||
columns: table => new
|
||||
{
|
||||
SynonymsId = table.Column<int>(nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
HashtagAId = table.Column<int>(nullable: false),
|
||||
HashtagBId = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Synonymses", x => x.SynonymsId);
|
||||
table.ForeignKey(
|
||||
name: "FK_Synonymses_Hashtags_HashtagAId",
|
||||
column: x => x.HashtagAId,
|
||||
principalTable: "Hashtags",
|
||||
principalColumn: "HashtagId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_Synonymses_Hashtags_HashtagBId",
|
||||
column: x => x.HashtagBId,
|
||||
principalTable: "Hashtags",
|
||||
principalColumn: "HashtagId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Synonymses_HashtagAId",
|
||||
table: "Synonymses",
|
||||
column: "HashtagAId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Synonymses_HashtagBId",
|
||||
table: "Synonymses",
|
||||
column: "HashtagBId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Synonymses");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Hashtags");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Migrations
|
||||
{
|
||||
[DbContext(typeof(ScrapDbContext))]
|
||||
partial class ScrapDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "3.1.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128)
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Hashtag", b =>
|
||||
{
|
||||
b.Property<int>("HashtagId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("datetime2");
|
||||
|
||||
b.Property<int>("HashtagType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Tag")
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.HasKey("HashtagId");
|
||||
|
||||
b.ToTable("Hashtags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Synonyms", b =>
|
||||
{
|
||||
b.Property<int>("SynonymsId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
|
||||
|
||||
b.Property<int>("HashtagAId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("HashtagBId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("SynonymsId");
|
||||
|
||||
b.HasIndex("HashtagAId");
|
||||
|
||||
b.HasIndex("HashtagBId");
|
||||
|
||||
b.ToTable("Synonymses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ViraScraper.Models.Synonyms", b =>
|
||||
{
|
||||
b.HasOne("ViraScraper.Models.Hashtag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("HashtagAId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("ViraScraper.Models.Hashtag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("HashtagBId")
|
||||
.OnDelete(DeleteBehavior.Restrict)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViraScraper.Models
|
||||
{
|
||||
public enum HashtagType
|
||||
{
|
||||
Instagram,
|
||||
Twitter,
|
||||
Facebook
|
||||
|
||||
}
|
||||
public class Hashtag
|
||||
{
|
||||
public int HashtagId { get; set; }
|
||||
public string Tag { get; set; }
|
||||
public DateTime CreationDate { get; set; }
|
||||
public HashtagType HashtagType { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public virtual IEnumerable<Synonyms> Synonymses { get; set; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var hsb = obj as Hashtag;
|
||||
if (hsb.Tag == Tag)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ViraScraper.Models
|
||||
{
|
||||
public class ScrapDbContext : DbContext
|
||||
{
|
||||
public DbSet<Hashtag> Hashtags { get; set; }
|
||||
public DbSet<Synonyms> Synonymses { get; set; }
|
||||
|
||||
public ScrapDbContext(DbContextOptions<ScrapDbContext> options) : base(options) { }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<Synonyms>()
|
||||
.HasOne<Hashtag>()
|
||||
.WithMany()
|
||||
.HasForeignKey(s=>s.HashtagAId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
modelBuilder.Entity<Synonyms>()
|
||||
.HasOne<Hashtag>()
|
||||
.WithMany()
|
||||
.HasForeignKey(s => s.HashtagBId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViraScraper.Models
|
||||
{
|
||||
public class Synonyms
|
||||
{
|
||||
[Key]
|
||||
public int SynonymsId { get; set; }
|
||||
public int HashtagAId { get; set; }
|
||||
public int HashtagBId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public Hashtag HashtagA { get; set; }
|
||||
[NotMapped]
|
||||
public Hashtag HashtagB { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ViraScraper
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:50934",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"ViraScraper": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Repositories.Contracts
|
||||
{
|
||||
public interface IHashtagRepository : IRepositoryBase<Hashtag>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViraScraper.Repositories
|
||||
{
|
||||
public interface IRepositoryBase<T>
|
||||
{
|
||||
IQueryable<T> GetAll();
|
||||
IQueryable<T> GetAll(Expression<Func<T, bool>> expression);
|
||||
void Insert(T entity);
|
||||
void InsertS(T entity);
|
||||
void InsertRang(IEnumerable<T> entitys);
|
||||
void InsertSRang(IEnumerable<T> entitys);
|
||||
void Update(T entity);
|
||||
void Remove(T entity);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViraScraper.Repositories.Contracts
|
||||
{
|
||||
public interface IRepositoryWrapper
|
||||
{
|
||||
IHashtagRepository Hashtag { get; }
|
||||
ISynonymsRepository Synonyms { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Repositories.Contracts
|
||||
{
|
||||
public interface ISynonymsRepository : IRepositoryBase<Synonyms>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
|
||||
namespace ViraScraper.Repositories
|
||||
{
|
||||
public class HashtagRepository : RepositoryBase<Hashtag>,IHashtagRepository
|
||||
{
|
||||
public HashtagRepository(ScrapDbContext context) : base(context) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Repositories
|
||||
{
|
||||
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
|
||||
{
|
||||
protected readonly ScrapDbContext _context;
|
||||
|
||||
public RepositoryBase(ScrapDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
public IQueryable<T> GetAll()
|
||||
{
|
||||
return _context.Set<T>().AsNoTracking();
|
||||
}
|
||||
|
||||
public IQueryable<T> GetAll(Expression<Func<T, bool>> expression)
|
||||
{
|
||||
return _context.Set<T>().Where(expression).AsNoTracking();
|
||||
}
|
||||
|
||||
public async void Insert(T entity)
|
||||
{
|
||||
await _context.AddAsync(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async void InsertRang(IEnumerable<T> entitys)
|
||||
{
|
||||
await _context.AddRangeAsync(entitys);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async void InsertS(T entity)
|
||||
{
|
||||
var ent = _context.Entry(entity);
|
||||
if (ent == null)
|
||||
{
|
||||
await _context.AddAsync(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async void InsertSRang(IEnumerable<T> entitys)
|
||||
{
|
||||
foreach (var entity in entitys)
|
||||
{
|
||||
var ent = _context.Set<T>().AsNoTracking().FirstOrDefault(e => e.Equals(entity));
|
||||
if (ent == null)
|
||||
{
|
||||
await _context.AddAsync(entity);
|
||||
}
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async void Remove(T entity)
|
||||
{
|
||||
var ent = _context.Entry(entity);
|
||||
ent.State = EntityState.Detached;
|
||||
ent.State = EntityState.Deleted;
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async void Update(T entity)
|
||||
{
|
||||
var ent = _context.Entry(entity);
|
||||
ent.State = EntityState.Detached;
|
||||
ent.State = EntityState.Modified;
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
|
||||
namespace ViraScraper.Repositories
|
||||
{
|
||||
public class RepositoryWrapper : IRepositoryWrapper
|
||||
{
|
||||
protected readonly ScrapDbContext _context;
|
||||
private IHashtagRepository hashtag;
|
||||
private ISynonymsRepository synonyms;
|
||||
public RepositoryWrapper(ScrapDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
public IHashtagRepository Hashtag
|
||||
{
|
||||
get
|
||||
{
|
||||
if(hashtag==null)
|
||||
hashtag = new HashtagRepository(_context);
|
||||
return hashtag;
|
||||
}
|
||||
}
|
||||
|
||||
public ISynonymsRepository Synonyms
|
||||
{
|
||||
get
|
||||
{
|
||||
if (synonyms == null)
|
||||
synonyms = new SynonymsRepository(_context);
|
||||
return synonyms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
|
||||
namespace ViraScraper.Repositories
|
||||
{
|
||||
public class SynonymsRepository : RepositoryBase<Synonyms> , ISynonymsRepository
|
||||
{
|
||||
public SynonymsRepository(ScrapDbContext context) : base(context) { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Models;
|
||||
|
||||
namespace ViraScraper.Services.Contracts
|
||||
{
|
||||
public interface IHashtagService
|
||||
{
|
||||
Task<IEnumerable<Hashtag>> GetHshtags(string hashtag);
|
||||
IEnumerable<Hashtag> GetHshtags(string hashtag,HashtagType type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ViraScraper.Services.Contracts
|
||||
{
|
||||
public interface IServiceWrapper
|
||||
{
|
||||
IHashtagService HashtagService { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using HtmlAgilityPack;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using ViraScraper.Models;
|
||||
using ViraScraper.Models.JsonModels;
|
||||
using ViraScraper.Repositories;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
using ViraScraper.Services.Contracts;
|
||||
using Hashtag = ViraScraper.Models.Hashtag;
|
||||
|
||||
namespace ViraScraper.Services
|
||||
{
|
||||
public class HashtagService : IHashtagService
|
||||
{
|
||||
private readonly IRepositoryWrapper _repository;
|
||||
|
||||
public HashtagService(IRepositoryWrapper repository)
|
||||
{
|
||||
_repository = repository;
|
||||
}
|
||||
public async Task<IEnumerable<Hashtag>> GetHshtags(string hashtag)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Hashtag> returnedList = new List<Hashtag>();
|
||||
var hashtagList = _repository.Hashtag.GetAll(h => h.Tag.Contains(hashtag)).ToList();
|
||||
return hashtagList;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Task.Run(() => UpdateInstagramHashtag(hashtag));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Hashtag> GetHshtags(string hashtag, HashtagType type)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private void UpdateInstagramHashtag(string hash)
|
||||
{
|
||||
string uri = $"https://www.instagram.com/explore/tags/{hash}/";
|
||||
HttpClient client = new HttpClient();
|
||||
var html = client.GetStringAsync(uri).Result;
|
||||
var htmlDocument = new HtmlDocument();
|
||||
htmlDocument.LoadHtml(html);
|
||||
string postList = htmlDocument.DocumentNode.Descendants("script").Where(n => n.InnerHtml.Contains("window._sharedData")).ToList().FirstOrDefault()?.InnerHtml;
|
||||
postList = postList.Substring(20, postList.Length - 21);
|
||||
List<string> hashtagList = new List<string>();
|
||||
Dictionary<string, int> synonymses = new Dictionary<string, int>();
|
||||
var root = JsonConvert.DeserializeObject<InstaExplorerRoot>(postList);
|
||||
foreach (var tagPage in root.entry_data.TagPage)
|
||||
{
|
||||
foreach (var edge in tagPage.graphql.hashtag.edge_hashtag_to_top_posts.edges)
|
||||
{
|
||||
foreach (var edgeC in edge.node.edge_media_to_caption.edges)
|
||||
{
|
||||
var hashtags = edgeC.node.text.Split('#');
|
||||
hashtags[0] = " ";
|
||||
hashtags[hashtags.Length - 1] = " ";
|
||||
foreach (var hashtag in hashtags)
|
||||
{
|
||||
foreach (var str in hashtag.Split(' '))
|
||||
{
|
||||
hashtagList.AddRange(hashtag.Split('\n').Where(s => s.Contains(hash)));
|
||||
if (synonymses.ContainsKey(str))
|
||||
{
|
||||
int v = synonymses.GetValueOrDefault(str) + 1;
|
||||
synonymses.Remove(str);
|
||||
synonymses.Add(str, v);
|
||||
}
|
||||
else
|
||||
synonymses.Add(str, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var hashtagToMedium in tagPage.graphql.hashtag.edge_hashtag_to_media.edges)
|
||||
{
|
||||
foreach (var edgeC in hashtagToMedium.node.edge_media_to_caption.edges)
|
||||
{
|
||||
var hashtags = edgeC.node.text.Split('#');
|
||||
hashtags[0] = " ";
|
||||
hashtags[hashtags.Length - 1] = " ";
|
||||
foreach (var hashtag in hashtags)
|
||||
{
|
||||
foreach (var str in hashtag.Split(' '))
|
||||
{
|
||||
hashtagList.AddRange(hashtag.Split('\n').Where(s => s.Contains(hash)));
|
||||
if (synonymses.ContainsKey(str))
|
||||
{
|
||||
int v = synonymses.GetValueOrDefault(str) + 1;
|
||||
synonymses.Remove(str);
|
||||
synonymses.Add(str, v);
|
||||
}
|
||||
else
|
||||
synonymses.Add(str, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hashtagList = hashtagList.Distinct().ToList();
|
||||
hashtagList.Sort((s1, s2) => { return s2.Length.CompareTo(s1.Length); });
|
||||
hashtagList.RemoveRange(0, hashtagList.Where(s => s.Length > 30).Count());
|
||||
hashtagList.ForEach(s =>
|
||||
{
|
||||
s = Regex.Replace(s, @"\t|\n|\r", "");
|
||||
s = Regex.Replace(s, @"\s+", "");
|
||||
});
|
||||
hashtagList = hashtagList.Distinct().ToList();
|
||||
List<Hashtag> hashList = new List<Hashtag>();
|
||||
hashtagList.ForEach(h =>
|
||||
{
|
||||
hashList.Add(new Hashtag
|
||||
{
|
||||
Tag = h,
|
||||
HashtagType = HashtagType.Instagram,
|
||||
CreationDate = DateTime.Now
|
||||
});
|
||||
});
|
||||
_repository.Hashtag.InsertSRang(hashList);
|
||||
|
||||
UpdateInstagramSynonyms(hash,synonymses);
|
||||
|
||||
}
|
||||
|
||||
private void UpdateInstagramSynonyms(string hash, Dictionary<string,int> synonymses)
|
||||
{
|
||||
|
||||
|
||||
var synonymsesList = synonymses.ToList();
|
||||
synonymsesList.Sort((paira,pairb)=>pairb.Value.CompareTo(paira.Value));
|
||||
synonymsesList.RemoveAll(s => s.Key == "");
|
||||
synonymsesList.RemoveAll(s => s.Key.Contains(hash));
|
||||
synonymsesList.RemoveAll(s => s.Key == " ");
|
||||
synonymsesList.RemoveAll(s => s.Key.Length<4);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
using ViraScraper.Services.Contracts;
|
||||
|
||||
namespace ViraScraper.Services
|
||||
{
|
||||
public class ServiceWrapper : IServiceWrapper
|
||||
{
|
||||
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||
|
||||
public ServiceWrapper(IRepositoryWrapper repository)
|
||||
{
|
||||
_repositoryWrapper = repository;
|
||||
}
|
||||
|
||||
private IHashtagService _hashtagService;
|
||||
public IHashtagService HashtagService
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hashtagService == null)
|
||||
_hashtagService = new HashtagService(_repositoryWrapper);
|
||||
return _hashtagService;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using ViraScraper.Models;
|
||||
using ViraScraper.Repositories;
|
||||
using ViraScraper.Repositories.Contracts;
|
||||
using ViraScraper.Services;
|
||||
using ViraScraper.Services.Contracts;
|
||||
|
||||
namespace ViraScraper
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddDbContext<ScrapDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer(Configuration.GetConnectionString("LocalConnection"));
|
||||
}, ServiceLifetime.Singleton);
|
||||
services.AddControllers();
|
||||
services.AddTransient<IRepositoryWrapper, RepositoryWrapper>();
|
||||
services.AddTransient<IServiceWrapper, ServiceWrapper>();
|
||||
|
||||
|
||||
|
||||
#region Swagger
|
||||
|
||||
services.AddSwaggerGen(swagger =>
|
||||
{
|
||||
swagger.SwaggerDoc("v1", new OpenApiInfo { Title = "EShop Api", Version = "v1" });
|
||||
});
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "EShop Api Swagger"); });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.17" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0-rc4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29519.181
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ViraScraper", "ViraScraper.csproj", "{04D98376-DD9D-4A2A-805A-78C048D4B178}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{04D98376-DD9D-4A2A-805A-78C048D4B178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{04D98376-DD9D-4A2A-805A-78C048D4B178}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{04D98376-DD9D-4A2A-805A-78C048D4B178}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{04D98376-DD9D-4A2A-805A-78C048D4B178}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4F73DBD3-7BF6-4627-A6E3-7B6B9B753740}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace ViraScraper
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"ConnectionStrings": {
|
||||
"LocalConnection": "Server=.;Database=ViraScraper;Trusted_Connection=true;MultipleActiveResultSets=true",
|
||||
"ServerConnection": "Data Source=localhost;Initial Catalog=hashshar_test01;Integrated Security=False;User ID=sa;Password=0099;Connect Timeout=15;Encrypt=False;Packet Size=4096"
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
Loading…
Reference in New Issue