<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Autofac.Features.Metadata;
using Bloom.Book;
using L10NSharp;
using Palaso.Extensions;

namespace Bloom.WebLibraryIntegration
{
	/// <summary>
	/// Currently pushes a book's metadata to Parse.com (a mongodb service) and files to Amazon S3.
	/// We are using both because Parse offers a more structured, query-able data organization
	/// that is useful for metadata, but does not allow large enough files for some of what we need.
	/// </summary>
	public class BookTransfer
	{
		private BloomParseClient _parseClient;
		private BloomS3Client _s3Client;

		public BookTransfer(BloomParseClient bloomParseClient, BloomS3Client bloomS3Client)
		{
			this._parseClient = bloomParseClient;
			this._s3Client = bloomS3Client;
		}


		public bool LogIn(string account, string password)
		{
			return _parseClient.LogIn(account, password);
		}

		public bool LoggedIn
		{
			get { return _parseClient.LoggedIn; }
		}

		public const string BookOrderExtension = ".BloomBookOrder";

		public string UploadBook(string bookFolder, Action<String> notifier = null)
		{
			var metaDataText = MetaDataText(bookFolder);
			var metadata = BookMetaData.FromString(metaDataText);
			// In case we somehow have a book with no ID, we must have one to upload it.
			if (string.IsNullOrEmpty(metadata.Id))
			{
				metadata.Id = Guid.NewGuid().ToString();
			}
			metadata.UploadedBy = _parseClient.Account;
			var s3BookId = S3BookId(metadata);
			metadata.DownloadSource = s3BookId;
			// Any updated ID at least needs to become a permanent part of the book.
			// The file uploaded must also contain the correct DownloadSource data, so that it can be used
			// as an 'order' to download the book.
			// It simplifies unit testing if the metadata file is also updated with the uploadedBy value.
			// Not sure if there is any other reason to do it (or not do it).
			// For example, do we want to send/receive who is the latest person to upload?
			metadata.WriteToFolder(bookFolder);
			// The metadata is also a book order...but we need it on the server with the desired file name,
			// because we can't rename on download. The extension must be the one Bloom knows about,
			// and we want the file name to indicate which book, so use the name of the book folder.
			var metadataPath = BookMetaData.MetaDataPath(bookFolder);
			var orderPath = Path.Combine(bookFolder, Path.GetFileName(bookFolder) + BookOrderExtension);
			File.Copy(metadataPath, orderPath, true);

			_s3Client.UploadBook(s3BookId, bookFolder, notifier);
			metadata.Thumbnail = _s3Client.ThumbnailUrl;
			metadata.BookOrder = _s3Client.BookOrderUrl;
			if (notifier != null)
				notifier(LocalizationManager.GetString("PublishWeb.UploadingBook","Uploading book record"));
			// Do this after uploading the books, since the ThumbnailUrl is generated in the course of the upload.
			_parseClient.SetBookRecord(metadata.Json);
			return s3BookId;
		}

		private static string MetaDataText(string bookFolder)
		{<commit_msg>Make sure uploaded metadata has SOME title<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Autofac.Features.Metadata;
using Bloom.Book;
using L10NSharp;
using Palaso.Extensions;

namespace Bloom.WebLibraryIntegration
{
	/// <summary>
	/// Currently pushes a book's metadata to Parse.com (a mongodb service) and files to Amazon S3.
	/// We are using both because Parse offers a more structured, query-able data organization
	/// that is useful for metadata, but does not allow large enough files for some of what we need.
	/// </summary>
	public class BookTransfer
	{
		private BloomParseClient _parseClient;
		private BloomS3Client _s3Client;

		public BookTransfer(BloomParseClient bloomParseClient, BloomS3Client bloomS3Client)
		{
			this._parseClient = bloomParseClient;
			this._s3Client = bloomS3Client;
		}


		public bool LogIn(string account, string password)
		{
			return _parseClient.LogIn(account, password);
		}

		public bool LoggedIn
		{
			get { return _parseClient.LoggedIn; }
		}

		public const string BookOrderExtension = ".BloomBookOrder";

		public string UploadBook(string bookFolder, Action<String> notifier = null)
		{
			var metaDataText = MetaDataText(bookFolder);
			var metadata = BookMetaData.FromString(metaDataText);
			// In case we somehow have a book with no ID, we must have one to upload it.
			if (string.IsNullOrEmpty(metadata.Id))
			{
				metadata.Id = Guid.NewGuid().ToString();
			}
			// And similarly it should have SOME title.
			if (string.IsNullOrEmpty(metadata.Title))
			{
				metadata.Title = Path.GetFileNameWithoutExtension(bookFolder);
			}
			metadata.UploadedBy = _parseClient.Account;
			var s3BookId = S3BookId(metadata);
			metadata.DownloadSource = s3BookId;
			// Any updated ID at least needs to become a permanent part of the book.
			// The file uploaded must also contain the correct DownloadSource data, so that it can be used
			// as an 'order' to download the book.
			// It simplifies unit testing if the metadata file is also updated with the uploadedBy value.
			// Not sure if there is any other reason to do it (or not do it).
			// For example, do we want to send/receive who is the latest person to upload?
			metadata.WriteToFolder(bookFolder);
			// The metadata is also a book order...but we need it on the server with the desired file name,
			// because we can't rename on download. The extension must be the one Bloom knows about,
			// and we want the file name to indicate which book, so use the name of the book folder.
			var metadataPath = BookMetaData.MetaDataPath(bookFolder);
			var orderPath = Path.Combine(bookFolder, Path.GetFileName(bookFolder) + BookOrderExtension);
			File.Copy(metadataPath, orderPath, true);

			_s3Client.UploadBook(s3BookId, bookFolder, notifier);
			metadata.Thumbnail = _s3Client.ThumbnailUrl;
			metadata.BookOrder = _s3Client.BookOrderUrl;
			if (notifier != null)
				notifier(LocalizationManager.GetString("PublishWeb.UploadingBook","Uploading book record"));
			// Do this after uploading the books, since the ThumbnailUrl is generated in the course of the upload.
			_parseClient.SetBookRecord(metadata.Json);
			return s3BookId;
		}

		private static string MetaDataText(string bookFolder)
		{
{'fraction_non_alphanumeric': 0.07903726708074534, 'fraction_numerical': 0.005279503105590062, 'mean_word_length': 3.9584295612009237, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1364664', 'n_tokens_mistral': 2048, 'n_tokens_neox': 1822, 'n_words': 679}