Skip to content

Commit

Permalink
Merge pull request #83 from Arquisoft/wikidata_sergiollende
Browse files Browse the repository at this point in the history
WikidataAPI improved and working
  • Loading branch information
UO289930 authored Mar 7, 2024
2 parents 12058e8 + 3ad11b0 commit 4f0499c
Show file tree
Hide file tree
Showing 12 changed files with 1,007 additions and 120 deletions.
408 changes: 407 additions & 1 deletion .gitignore

Large diffs are not rendered by default.

405 changes: 405 additions & 0 deletions wikidata_service/.gitignore

Large diffs are not rendered by default.

136 changes: 17 additions & 119 deletions wikidata_service/WikiDataTest/Controllers/WikiDataController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using WikiDataTest.Models;
using WikiDataTest.Services;

namespace WikiDataTest.Controllers
{
Expand All @@ -8,138 +10,34 @@ namespace WikiDataTest.Controllers
public class WikiDataController : ControllerBase
{
private readonly ILogger<WikiDataController> _logger;
private readonly QueryService _queryService;
private readonly WikiDataService _wikiDataService;
private readonly QuestionService _questionService;

public WikiDataController(ILogger<WikiDataController> logger)

public WikiDataController(ILogger<WikiDataController> logger,
QueryService queryService, WikiDataService wikiDataService, QuestionService questionService)
{
_logger = logger;
_queryService = queryService;
_wikiDataService = wikiDataService;
_questionService = questionService;
}

[HttpGet("GetQuestions")]
public async Task<IActionResult> GetQuestions()
{
string endpointUrl = "https://query.wikidata.org/sparql?query=";
string sparqlQuery = "SELECT ?capitalLabel ?countryLabel WHERE { ?capital wdt:P1376 ?country. ?capital wdt:P31 wd:Q5119. ?country wdt:P31 wd:Q3624078. SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\". }} LIMIT 400";
RootObject jsonQuestions = await _wikiDataService.GetQuestions(_queryService.GetCapitalsQuery());

var fullUrl = endpointUrl + sparqlQuery;
Question[] questions = _questionService.GenerateQuestionsCapitalsOf(jsonQuestions.results.bindings.ToArray<CapitalCountry>());

using (var client = new HttpClient())
foreach (var item in questions)
{
client.DefaultRequestHeaders.Add("User-Agent", "Sergiollende/1.0");
client.DefaultRequestHeaders.Add("Accept", "application/sparql-results+json");

HttpResponseMessage response = await client.GetAsync(fullUrl);

string responseBody = await response.Content.ReadAsStringAsync();

RootObject jsonResult = JsonConvert.DeserializeObject<RootObject>(responseBody);
foreach(CapitalCountry c in jsonResult.results.bindings)
{
Console.WriteLine(c.ToString());
}

Question[] questions = GenerateQuestionsCapitalsOf(jsonResult.results.bindings.ToArray<CapitalCountry>());

foreach (var item in questions)
{
Console.WriteLine(item.ToString());
}

return Ok(jsonResult);
Console.WriteLine(item.ToString());
}

}

private Question[] GenerateQuestionsCapitalsOf(CapitalCountry[] capitalCountries)
{
Question[] questions = new Question[10];

ISet<int> ids = new HashSet<int>();
Random r = new Random();

while (ids.Count < 10) {
ids.Add(r.Next(capitalCountries.Length));
}

int[] idsList = new int[10];
int i = 0;
foreach (int id in ids)
{
idsList[i++] = id;
}

for (int j = 0; j < idsList.Length; j++)
{
string text = "What is the capital of " + capitalCountries[idsList[j]].countryLabel.value;
string[] answers = new string[4];
answers[0] = capitalCountries[idsList[j]].capitalLabel.value;
int[] wrongIds = new int[3];
for (int w = 1; w < 4; w++)
{
int wrongId = r.Next(capitalCountries.Length);
while (idsList.Contains(wrongId) || wrongIds.Contains(wrongId) )
{
wrongId = r.Next(capitalCountries.Length);
}
answers[w] = capitalCountries[wrongId].capitalLabel.value;
}
int correctAnswer = 0;

questions[j] = new Question(text, answers, correctAnswer);
}

return questions;
}

return Ok(questions);
}
}

public class CapitalCountry
{
public Label capitalLabel { get; set; }
public Label countryLabel { get; set; }

public string ToString()
{
return countryLabel.value + ": " + capitalLabel.value;
}
}

public class Label
{
public string value { get; set; }
}


public class Results
{
public List<CapitalCountry> bindings { get; set; }
}

public class RootObject
{
public Results results { get; set; }
}

public class Question
{
public string text { get; set; }
public string[] answers;
public int correctAnswer;

public Question(string text, string[] answers, int correctAnswer)
{
this.text = text;
this.answers = answers;
this.correctAnswer = correctAnswer;
}

public string ToString()
{
string aux = "text: " + text;
aux += "\ncorrectAnswer: " + answers[0];
aux += "\nAnswer: " + answers[1];
aux += "\nAnswer: " + answers[2];
aux += "\nAnswer: " + answers[3];
return aux ;
}
}
}
14 changes: 14 additions & 0 deletions wikidata_service/WikiDataTest/Models/CapitalCountry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace WikiDataTest.Models
{

public class CapitalCountry
{
public Label capitalLabel { get; set; }
public Label countryLabel { get; set; }

public string ToString()
{
return countryLabel.value + ": " + capitalLabel.value;
}
}
}
8 changes: 8 additions & 0 deletions wikidata_service/WikiDataTest/Models/Label.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace WikiDataTest.Models
{
public class Label
{
public string value { get; set; }
}

}
26 changes: 26 additions & 0 deletions wikidata_service/WikiDataTest/Models/Question.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace WikiDataTest.Models
{
public class Question
{
public string text { get; set; }
public string[] answers { get; set; }
public int correctAnswer { get; set; }

public Question(string text, string[] answers, int correctAnswer)
{
this.text = text;
this.answers = answers;
this.correctAnswer = correctAnswer;
}

public string ToString()
{
string aux = "text: " + text;
aux += "\ncorrectAnswer: " + answers[0];
aux += "\nAnswer: " + answers[1];
aux += "\nAnswer: " + answers[2];
aux += "\nAnswer: " + answers[3];
return aux;
}
}
}
7 changes: 7 additions & 0 deletions wikidata_service/WikiDataTest/Models/Results.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace WikiDataTest.Models
{
public class Results
{
public List<CapitalCountry> bindings { get; set; }
}
}
7 changes: 7 additions & 0 deletions wikidata_service/WikiDataTest/Models/RootObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace WikiDataTest.Models
{
public class RootObject
{
public Results results { get; set; }
}
}
6 changes: 6 additions & 0 deletions wikidata_service/WikiDataTest/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using WikiDataTest.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
Expand All @@ -6,6 +8,10 @@
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton(new QueryService());
builder.Services.AddSingleton(new WikiDataService());
builder.Services.AddSingleton(new QuestionService());


var app = builder.Build();

Expand Down
10 changes: 10 additions & 0 deletions wikidata_service/WikiDataTest/Services/QueryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace WikiDataTest.Services
{
public class QueryService
{
public string GetCapitalsQuery()
{
return "SELECT ?capitalLabel ?countryLabel WHERE { ?capital wdt:P1376 ?country. ?capital wdt:P31 wd:Q5119. ?country wdt:P31 wd:Q3624078. SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\". }} LIMIT 400";
}
}
}
68 changes: 68 additions & 0 deletions wikidata_service/WikiDataTest/Services/QuestionService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using WikiDataTest.Controllers;
using WikiDataTest.Models;

namespace WikiDataTest.Services
{
public class QuestionService
{
/// <summary>
/// Generate the questions from the capital/countries passed as parameter
/// </summary>
/// <param name="capitalCountries"> all the countries obtained </param>
/// <param name="numberQuestions"> number of questions to generate </param>
/// <returns></returns>
public Question[] GenerateQuestionsCapitalsOf(CapitalCountry[] capitalCountries, int numberQuestions = 10)
{
Question[] questions = new Question[numberQuestions];

ISet<int> ids = new HashSet<int>();
Random r = new Random();

while (ids.Count < numberQuestions)
{
ids.Add(r.Next(capitalCountries.Length));
}

int[] idsList = new int[numberQuestions];
int i = 0;
foreach (int id in ids)
{
idsList[i++] = id;
}

// Generate questions
for (int j = 0; j < idsList.Length; j++)
{
// Generate the questions
string countryName = capitalCountries[idsList[j]].countryLabel.value;
string questionText = $"What is the capital of {countryName}?";
string[] answers = new string[4];

// Place of the correct answer
int correctAnswer = 0;

// Save the capital of the specific country on first place
answers[correctAnswer] = capitalCountries[idsList[j]].capitalLabel.value;

// Get 3 random wrong answers from all the capitals
int[] wrongIds = new int[3];
for (int w = 1; w < 4; w++)
{
int wrongId = r.Next(capitalCountries.Length);
while (idsList[j] == wrongId || wrongIds.Contains(wrongId))
{
wrongId = r.Next(capitalCountries.Length);
}
// Adding the id of the wrongAnswer to the array
wrongIds[w - 1] = wrongId;
answers[w] = capitalCountries[wrongId].capitalLabel.value;
}

questions[j] = new Question(questionText, answers, correctAnswer);
}

return questions;
}
}
}
32 changes: 32 additions & 0 deletions wikidata_service/WikiDataTest/Services/WikiDataService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Newtonsoft.Json;
using WikiDataTest.Controllers;
using WikiDataTest.Models;

namespace WikiDataTest.Services
{
public class WikiDataService
{
public WikiDataService() { }

public async Task<RootObject> GetQuestions(string sparqlQuery)
{
string endpointUrl = "https://query.wikidata.org/sparql?query=";

var fullUrl = endpointUrl + sparqlQuery;

using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("User-Agent", "Sergiollende/1.0");
client.DefaultRequestHeaders.Add("Accept", "application/sparql-results+json");

HttpResponseMessage response = await client.GetAsync(fullUrl);

string responseBody = await response.Content.ReadAsStringAsync();

RootObject jsonResult = JsonConvert.DeserializeObject<RootObject>(responseBody);

return jsonResult;
}
}
}
}

0 comments on commit 4f0499c

Please sign in to comment.