Luca3317 / OpenLibrary.NET

C# library for OpenLibrary by the InternetArchive
MIT License
15 stars 3 forks source link

adding works/editions to a list #5

Closed bradyguyc closed 6 months ago

bradyguyc commented 6 months ago

would you be able to provide an example of how to add works/editions to a list?

Luca3317 commented 6 months ago

It doesnt appear to be implemented into the OpenLibrary API as of now: https://openlibrary.org/dev/docs/api/lists#update-list

bradyguyc commented 6 months ago

I figured it out. The following link as a vague example. I copied in my code that syncs a list of series with list in my account on open library.org well it's the start. Right now it just creates the list.

The API take a thrird parameter that is just a list of strings that are openlibrary key's to the edition of the book to put in the list.

I don't think there is anything you need to do to the library, looks like it just works :)

https://openlibrary.org/dev/docs/api/lists#update-list

` public async Task SyncSeriesWithList(ObservableCollection seriesCollection) {

      try
      {
          if (!OLclient.LoggedIn)
          {
              await ReadSecureValues();
              await LoginWithUserName(OLUserName, OLPassword);
              if (!OLclient.LoggedIn)
              {
                  throw new Exception("Unable to log in to OpenLibrary");
              }
          }
          OLListData[] userList = await OLclient.List.GetUserListsAsync(OLclient.Username);
          foreach (Series s in seriesCollection)
          {
              var seriesInUserList = userList.FirstOrDefault(list => list.Name == s.Name);
              if (seriesInUserList == null)
              {

                  List<String> booksForList = new List<string>();
                  // Create a new list with the series name and description
                  foreach (var book in s.Books)
                  {
                      if (!string.IsNullOrEmpty(book.OLKey))
                      {
                          booksForList.Add(book.OLKey);
                      }
                  }
                  await OLclient.CreateListAsync(s.Name, s.Description, booksForList);

                  // Inside the SyncSeriesWithList method, after creating a new list

              }
          }

      }
      catch (Exception ex)
      {
          throw new Exception(ex.Message, ex);
      }
  }`
Luca3317 commented 6 months ago

I also just played around with it a bit and turns out you can modify existing lists pretty easily as well; will add wrappers for that next chance i get.

If you need a quick working solution for now:

var handler = new HttpClientHandler
{
    AllowAutoRedirect = true,
    UseCookies = true
};
HttpClient client = new HttpClient(handler);
Uri posturi = new Uri("http://openlibrary.org/people/*YourUserNameHere*/lists/*TheListIDHere*/seeds.json");

var requestData = new
{
    add = new[]
    {
        // Books you want to add
        new { key = "/books/OL25083437M" },
        new { key = "/books/OL24375501M" }
    }
};

var jsonContent = new StringContent(
    System.Text.Json.JsonSerializer.Serialize(requestData),
    System.Text.Encoding.UTF8,
    "application/json"
);
var response = await client.PostAsync(posturi, jsonContent);

To remove just replace "add" with "remove" in the request data.

Edit: Forgot to mention that you of course first have to login. I just copied this code from OpenLibraryClient.

async Task LoginAsync(string email, string password)
{
    KeyValuePair<string, string>[] nameValueCollection = new KeyValuePair<string, string>[2]
    {
            new KeyValuePair<string, string>("username", email),
            new KeyValuePair<string, string>("password", password)
    };
    Uri requestUri = new Uri(OpenLibraryUtility.BaseUri, "account/login");
    FormUrlEncodedContent content = new FormUrlEncodedContent(nameValueCollection);
    await client.PostAsync(requestUri, content);
    try
    {
        Cookie sessionCookie = handler.CookieContainer.GetCookies(OpenLibraryUtility.BaseUri).Single((Cookie cookie) => cookie.Name == "session");
    }
    catch
    {
        throw new HttpRequestException("Failed to authenticate; did you correctly input your email and password?");
    }
}

string ExtractUsernameFromSessionCookie(Cookie sessionCookie)
{
    return Regex.Match(sessionCookie.Value, "(?<=/people/).*?(?=%)").Value;
}
Luca3317 commented 6 months ago

Can you let me know if this worked for you so that I can close the issue?

Luca3317 commented 6 months ago

Added list editing to the new version of the nuget package, so ill close this