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