diff --git a/.DS_Store b/.DS_Store index e2fb3cb..caf0f17 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/app/__init__.py b/app/__init__.py index fa1b60b..de56f98 100755 --- a/app/__init__.py +++ b/app/__init__.py @@ -36,4 +36,3 @@ socketio = SocketIO(app) app.config.from_object(__name__) from app import views - diff --git a/app/cover.py b/app/cover.py index 1b0e04f..ef1bccc 100755 --- a/app/cover.py +++ b/app/cover.py @@ -40,7 +40,7 @@ def get_cover(file_path, filename): big_filename = "app/uploads/cover/"+page["filename"] + "_cover.png" small_filename = "app/uploads/cover/"+page["filename"] + "cover_small" + ".png" - img = pdf_page_to_png(src_pdf, pagenum = page["pagenum"], resolution = 300) + img = pdf_page_to_png(src_pdf, pagenum = page["pagenum"], resolution = 200) img.save(filename = big_filename) # Ensmallen diff --git a/app/extractText.py b/app/extractText.py new file mode 100644 index 0000000..e3e435f --- /dev/null +++ b/app/extractText.py @@ -0,0 +1,23 @@ +import PyPDF2 + + +def get_text(file_path, filename): + read_pdf =file_path + + with open(read_pdf,'rb') as pdf_file, open("app/uploads/"+filename+'.txt', 'w') as text_file: + read_pdf = PyPDF2.PdfFileReader(pdf_file) + number_of_pages = read_pdf.getNumPages() + for page_number in range(number_of_pages): # use xrange in Py2 + page = read_pdf.getPage(page_number) + page_content = page.extractText() + text_file.write(page_content) + + + +def extract_text(file_path, filename): + try: + get_text(file_path, filename) + except: + with open(filename+'.txt', 'w') as text_file: + page_content = "" + text_file.write(page_content) diff --git a/app/models.py b/app/models.py index 11d403a..68b7a23 100755 --- a/app/models.py +++ b/app/models.py @@ -15,6 +15,11 @@ stacks = db.Table('books_stacks', db.Column('stack_id', db.Integer, db.ForeignKey('stacks.id'), primary_key=True) ) +instances = db.Table('books_instances', + db.Column('book_id', db.Integer, db.ForeignKey('books.id'), primary_key=True), + db.Column('instance_id', db.Integer, db.ForeignKey('instances.id'), primary_key=True) +) + class Book(db.Model): __tablename__ = 'books' @@ -26,10 +31,14 @@ class Book(db.Model): category = db.Column(db.String(255)) year_published = db.Column(db.Numeric(4,0)) description = db.Column(db.String(2500)) + html = db.Column(db.String(255)) + downloads = db.Column(db.Numeric(100,0)) authors = db.relationship('Author', secondary=authors,cascade="delete", lazy='subquery', backref=db.backref('books', lazy=True),passive_deletes=True) stacks = db.relationship('Stack', secondary=stacks, lazy='subquery', backref=db.backref('books', lazy=True)) + instances = db.relationship('Instance', secondary=instances, lazy='subquery', + backref=db.backref('books', lazy=True)) scapeX = db.Column(db.Numeric(10,2)) scapeY = db.Column(db.Numeric(10,2)) message = db.Column(db.String(1000)) @@ -47,6 +56,7 @@ class Book(db.Model): self.fileformat = fileformat self.category = category self.year_published = year_published + self.download = None self.scapeX = 0 self.scapeY = 0 self.message = message @@ -73,6 +83,19 @@ class Author(db.Model): def __init__(self, author_name): self.author_name = author_name +class Instance(db.Model): + __tablename__ = 'instances' + + id = db.Column(db.Integer(), primary_key=True) + name = db.Column(db.String(50)) + ip = db.Column(db.String(50)) + action = db.Column(db.String(50)) + + def __init__(self, ip, action): + self.name = ip + self.ip = ip + self.action = action + class UserIns(db.Model): __tablename__ = 'userins' diff --git a/app/static/css/style.css b/app/static/css/style.css index e862ae3..6ae5dd1 100755 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -199,6 +199,7 @@ font-size: 12px; .ui-tabs-vertical { width: 100em; border-top: 0;} <<<<<<< HEAD +<<<<<<< HEAD .ui-tabs-vertical .ui-tabs-nav { padding: .2em .2em .2em .2em; float: left; width: 15em; } .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 0 !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; } ======= @@ -206,6 +207,11 @@ font-size: 12px; .ui-tabs-vertical .ui-tabs-nav { padding: .2em .2em .2em .2em; float: left; width: 15em; -webkit-appearance: none;} .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 0 !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; list-style-type: none; } >>>>>>> stack_stuff +======= +.ui-tabs-vertical a { text-decoration: none; color: black;} +.ui-tabs-vertical .ui-tabs-nav { padding: .2em .2em .2em .2em; float: left; width: 15em; -webkit-appearance: none;} +.ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 0 !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; list-style-type: none; } +>>>>>>> master .ui-tabs-vertical .ui-tabs-nav li a { display:block; } .ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { padding-bottom: 0; padding-right: .1em; border-right-width: 0; background-color: yellow !important; list-style-type: none;} .ui-tabs-vertical .ui-tabs-panel { padding: 1em; float: left; width: 50em; font-size: 12px; list-style-type: none;} diff --git a/app/templates/base.html b/app/templates/base.html index 9af5ed1..f407b49 100755 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -14,7 +14,6 @@ - {% block css %} {% endblock%} @@ -62,7 +61,7 @@ console.log(time) return ('0'+time.getDate()).slice(-2) + '.' + ('0'+(time.getMonth()+1)).slice(-2) + '.' + time.getFullYear() +" " + ('0'+time.getHours()).slice(-2)+":"+ ('0'+time.getMinutes()).slice(-2); } //change addr when ONLINE::::::-> -var socket = io.connect('http://localhost:5000'); +var socket = io.connect('{{server}}'); var app = new Vue({ el: "#app", delimiters: ['[[', ']]'], @@ -112,6 +111,11 @@ socket.on('channel-' + app.channel, function(msg) { scrollTop: $('.messages')[0].scrollHeight }); }); + + +document.getElementById("file_import_csv").onchange = function() { + document.getElementById("form_import_csv").submit(); +}; diff --git a/app/templates/header.html b/app/templates/header.html index 5fc33bf..0d8b33d 100755 --- a/app/templates/header.html +++ b/app/templates/header.html @@ -6,6 +6,7 @@
  • Add Book
  • Add Stack
  • About
  • +
  • Instances
  • diff --git a/app/templates/home.html b/app/templates/home.html index 3084287..089c2ba 100755 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -4,6 +4,8 @@

    XPPL

    This is the awesome library of Experimental Publishing.
    +On instance: {{server}} / From: {{client}} +
    This might only be one interface to this library:

    @@ -12,6 +14,14 @@ This might only be one interface to this library: List


    + +
    + +
    +
    + + +
    diff --git a/app/templates/import_csv.html b/app/templates/import_csv.html new file mode 100644 index 0000000..1308f1d --- /dev/null +++ b/app/templates/import_csv.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block main %} +

    Imported CSV

    +

    {{numberadded}} books added!

    + +{% endblock %} diff --git a/app/templates/scape.html b/app/templates/scape.html index 7e222f3..3adea7a 100644 --- a/app/templates/scape.html +++ b/app/templates/scape.html @@ -3,27 +3,100 @@ - - + +
    + +
    +
    +
    -
    +
    {% for book in books|sort(attribute='title', reverse = False) %} -
    +
    -

    {{ book.title }}

    +

    {{ book.title }}

    + + {% set got = {} %} + {% set all = 1 %} + {% for instance in book.instances %} + + {% if instance.name in got %} + {% set x=got.__setitem__(instance.name, got[instance.name]+1) %} + {% else %} + {% set x=got.__setitem__(instance.name, 1) %} + {% endif %} + {% set all = loop.index %} + {% endfor %} + + {% for instance, value in got.items() %} + {% set result = value/(book.instances|length) %} + + + {% endfor %}
    + + {% endfor %}
    @@ -81,7 +154,29 @@ diff --git a/app/templates/show_book_detail.html b/app/templates/show_book_detail.html index d2e3f0d..b27dad3 100755 --- a/app/templates/show_book_detail.html +++ b/app/templates/show_book_detail.html @@ -35,11 +35,11 @@

    – Remove from stack{% endfor %} - + - Notes from uploader + Notes from uploader @@ -66,6 +66,7 @@ +<<<<<<< HEAD <<<<<<< HEAD download {{ book.fileformat }} @@ -92,18 +93,52 @@ {% else %} {% endif %} >>>>>>> stack_stuff +======= + download {{ book.fileformat }} +
    +
    +

    Instances:

    + {% set got = {} %} + {% set all = 1 %} + {% for instance in book.instances %} + + {% if instance.name in got %} + {% set x=got.__setitem__(instance.name, got[instance.name]+1) %} + {% else %} + {% set x=got.__setitem__(instance.name, 1) %} + {% endif %} + {% set all = loop.index %} + {% endfor %} + + {% for instance, value in got.items() %} + {% set result = value/(book.instances|length) %} + {{ instance }}: {{ (result*100)|round|int }}%
    + {% endfor %} +
    + + + {% if book.file %} + + + {% else %} + {% endif %} +>>>>>>> master


    -{% if previousbook %} +{% if previousbook %} < see the previous book added to XPPL:  {{ previousbook.title |truncate(40,True,'...') }} {% endif %} -{% if nextbook %} +{% if nextbook %} see the next book added to XPPL:  {{ nextbook.title|truncate(40,True,'...')}} > {% endif %}
    {% endblock %} - - diff --git a/app/templates/show_instances.html b/app/templates/show_instances.html new file mode 100644 index 0000000..41b3fa9 --- /dev/null +++ b/app/templates/show_instances.html @@ -0,0 +1,37 @@ +{% extends 'base.html' %} + +{% block main %} +
    +

    Instances

    +

    All instances, that are using this library

    + + + + + +
      +{% for instance in instances %} + +
    • {{ instance.name }} / {{ instance.ip }}
    • +
      +
      + + + + {% endfor %} +
    + + + + +{% endblock %} diff --git a/app/views.py b/app/views.py index b84e2b6..5cbc8bd 100755 --- a/app/views.py +++ b/app/views.py @@ -13,16 +13,23 @@ import os from sqlalchemy.sql.expression import func, select from sqlalchemy.sql import except_ from app.forms import UploadForm, EditForm, SearchForm, ChatForm, StackForm, AddtoStackForm, EditStackForm -from app.models import Book, BookSchema, Author, AuthorSchema, Stack, StackSchema, UserIns, Chat, ChatSchema, Potential +from app.models import Book, BookSchema, Author, AuthorSchema, Stack, StackSchema, UserIns, Chat, ChatSchema, Instance, Potential from app.cover import get_cover +<<<<<<< HEAD from app.getannot import get_annotations from urllib.parse import quote as urlquote +======= +from app.extractText import extract_text +>>>>>>> master from os import environ from flask_socketio import SocketIO, emit from weasyprint import HTML import datetime import time -import autocomplete +from csv import DictWriter, DictReader +import io +from sqlalchemy.inspection import inspect +#import autocomplete import sys from werkzeug.utils import secure_filename @@ -57,8 +64,14 @@ def home(): # msg = Chat(message) # db.session.add(msg) # db.session.commit() + #client = request.remote_addr + server = request.host + if request.environ.get('HTTP_X_FORWARDED_FOR') is None: + client =request.environ['REMOTE_ADDR'] + else: + client = request.environ['HTTP_X_FORWARDED_FOR'] - return render_template('home.html',domain=DOMAIN,chat=chat_messages, channel = 1, username=username) + return render_template('home.html',domain=DOMAIN,chat=chat_messages, channel = 1, username=username, client=client, server=server) @app.route('/hello/') def hello(name): @@ -71,6 +84,13 @@ def about(): @app.route('/uploads/') def uploaded_file(filename): + book = Book.query.filter_by(file=filename).first() + i = Instance(request.host, "download") + existing_ip = db.session.query(Instance).filter_by(ip=request.host).first() + if existing_ip: + i.name = existing_ip.name + book.instances.append(i) + db.session.commit() return send_from_directory(app.config['UPLOAD_FOLDER'], filename) @@ -101,7 +121,19 @@ def scape(): book.scapeY = data['y'] db.session.commit() books = db.session.query(Book).all() # or you could have used User.query.all() - return render_template('scape.html', books=books) + all_instances = db.session.query(Instance).all() + instances = [] + for instance in all_instances: + exists = False + for existing_inst in instances: + if existing_inst.name == instance.name: + exists = True + break + else: + exists = False + if not exists: + instances.append(instance) + return render_template('scape.html', books=books, instances=instances) @app.route('/books_grid') @@ -112,6 +144,7 @@ def show_books_grid(): @app.route('/books/') def show_book_by_id(id): book = Book.query.get(id) + all_instances = db.session.query(Instance).all() previousbook = Book.query.filter_by(id=id - 1).first() nextbook = Book.query.filter_by(id=id + 1).first() allbooks = db.session.query(Book).all() @@ -132,7 +165,7 @@ def show_book_by_id(id): if not book: return render_template('red_link.html', id=id) else: - return render_template('show_book_detail.html', book=book, previousbook = previousbook, nextbook = nextbook) + return render_template('show_book_detail.html', book=book, previousbook = previousbook, nextbook = nextbook, all_instances=all_instances) @app.route('/books//delete', methods=['POST', 'GET']) @@ -176,6 +209,11 @@ def edit_book_by_id(id): a = Author(author_name=author_name) db.session.add(a) book.authors.append(a) + i = Instance(request.host, "edit") + existing_ip = db.session.query(Instance).filter_by(ip=request.host).first() + if existing_ip: + i.name = existing_ip.name + book.instances.append(i) # editing / uploading new file if user_form.file.data: @@ -255,7 +293,13 @@ def add_book(): fullpath = os.path.join(app.config['UPLOAD_FOLDER'], filename) name, file_extension = os.path.splitext(filename) file.save(fullpath) - cover = get_cover(fullpath, name) + try: + cover = get_cover(fullpath, name) + except: + cover = '' + + extract_text(fullpath, name) + else: flash('allowed file formats: %s' % ALLOWED_EXTENSIONS) #if upload without file -> wishform, with potential PDF @@ -285,6 +329,11 @@ def add_book(): a = Author(author_name=author_name) db.session.add(a) book.authors.append(a) + i = Instance(request.host, "add") + existing_ip = db.session.query(Instance).filter_by(ip=request.host).first() + if existing_ip: + i.name = existing_ip.name + book.instances.append(i) db.session.commit() flash("%s added to the library" % (title)) @@ -378,10 +427,40 @@ def edit_stack_by_id(id): stack.stack_name = stack_name stack.stack_description = stack_description db.session.commit() - return redirect(url_for('show_stack_by_id', id=id)) return render_template('edit_stack_detail.html', stack=stack, form=form) +@app.route('/instances', methods=['POST', 'GET']) +def show_instances(): + all_instances = db.session.query(Instance).all() + instances = [] + for instance in all_instances: + exists = False + for existing_inst in instances: + if existing_inst.name == instance.name: + exists = True + break + else: + exists = False + if not exists: + instances.append(instance) + + if request.method == 'POST': + for item in request.form.items(): + for i, itm in enumerate(item): + if i == 0: + oldname = itm + if i == 1: + name = itm + + all_instances = db.session.query(Instance).filter_by(name=oldname).all() + for instance in all_instances: + instance.name = name + print(oldname) + print(name) + db.session.commit() + return render_template('show_instances.html', instances=instances) + @app.route('/stacks//remove/', methods=['POST', 'GET']) def remove_from_stack(bookid, stackid): book = Book.query.get(bookid) @@ -392,18 +471,21 @@ def remove_from_stack(bookid, stackid): db.session.commit() return render_template('show_book_detail.html', book=book) - ## search view = ['1'] @app.route('/books', methods= ['POST','GET']) def show_books(): +<<<<<<< HEAD <<<<<<< HEAD autocomplete.load() #Train markov model once, for autocomplete in search books = db.session.query(Book).all() ======= books = db.session.query(Book).order_by(Book.title) >>>>>>> stack_stuff +======= + books = db.session.query(Book).order_by(Book.title) +>>>>>>> master search = SearchForm(request.form) view.append('1') viewby = '1' @@ -514,6 +596,7 @@ def search_results(searchtype, query, viewby): if viewby == '2': return render_template('results_grid.html', form=search, books=results, books_all=books_all, searchtype=search.select.data, query=query, count = count, whole = whole, percentage = percentage) +<<<<<<< HEAD <<<<<<< HEAD ## Search - autocomplete autocomplete_suggestions = [] @@ -541,6 +624,8 @@ def test1(): ## STACKS! ======= +======= +>>>>>>> master else: return render_template('results.html', form=search, books=results, books_all=books_all, searchtype=search.select.data, query=query, count = count, whole = whole, percentage = percentage) @@ -562,11 +647,21 @@ def test1(): # autocomplete_suggestions.clear() # for suggestion, score in autocomplete_output: # autocomplete_suggestions.append(suggestion) +# +# session['autocomplete_suggestions'] = str(autocomplete_suggestions) +# +# print(session['autocomplete_suggestions']) +# +# return Response(json.dumps(session['autocomplete_suggestions']), mimetype='application/json') +<<<<<<< HEAD # print(autocomplete_suggestions) # return Response(json.dumps(autocomplete_suggestions), mimetype='application/json') >>>>>>> stack_stuff +======= +## STACKS! +>>>>>>> master @app.route('/add_to_stack/', methods=['GET', 'POST']) def add_to_stack(id): @@ -583,23 +678,97 @@ def add_to_stack(id): db.session.commit() return render_template('show_stack_detail.html', stack=stack) -from csv import DictWriter -import io @app.route('/export/csv', methods=['GET']) -def export_csv (): +def export_csv(): output = io.StringIO() - fieldnames = ['title', 'authors'] - csv = DictWriter(output,fieldnames) + #fieldnames = ['title', 'authors', 'file', 'fileformat', 'category', 'year_published', 'description' ] + fields = Book.__mapper__.columns + fieldnames = [] + for columns in fields: + fieldnames.append(columns.name) + i = inspect(Book) + referred_classes = [r.mapper.class_ for r in i.relationships] + referred_classes_tablenames = [r.mapper.class_.__tablename__ for r in i.relationships] + print(fieldnames+referred_classes_tablenames) + csv = DictWriter(output,fieldnames+referred_classes_tablenames) csv.writeheader() - # for i in range(10): - # csv.writerow({'ID': i, 'fruit': "Tomato"}) for book in Book.query.order_by("title"): - authors = ", ".join([x.author_name for x in book.authors]) - csv.writerow({"title": book.title, "authors": authors}) - resp = Response(output.getvalue(), mimetype="text/plain") - # resp.headers["Content-Disposition"] = "attachment;filename=export.csv" + row = {} + for col in fieldnames: + print(getattr(book, col)) + row[col] = getattr(book, col) + for col in referred_classes: + subattr = [] + for subcol in getattr(book, col.__tablename__): + for metacol in subcol.__mapper__.columns: + query = metacol.name + if query != "id": + this = getattr(subcol, query) + subattr.append(this) + row[col.__tablename__] = " | ".join(subattr) + csv.writerow(row) + #print(row) + resp = Response(output.getvalue(), mimetype="text/csv") + resp.headers["Content-Disposition"] = "attachment;filename=export.csv" return resp + +import codecs +@app.route('/import/csv', methods= ['POST','GET']) +def import_csv(): + if request.method == 'POST': + if 'file' not in request.files: + flash('No file part') + return redirect(request.url) + else: + file = request.files['file'] + for row in DictReader(codecs.iterdecode(file, 'utf-8')): + numberadded = 0; + book = Book.query.filter_by(title=row['title']).first() + if book: + print("allreadyexists") + else: + cover = '' + if row['file']: + fullpath = os.path.join(app.config['UPLOAD_FOLDER'], row['file']) + name, file_extension = os.path.splitext(row['file']) + print ('get_cover', fullpath, name) + cover = get_cover(fullpath, name) + + if row['year_published']: + year_published = int(row['year_published']) + else: + year_published = None; + book = Book(row['title'], row['file'], cover, row['fileformat'], row['category'],year_published, None, None, None, None, None, None) + book.scapeX = float(row['scapeX']) + book.scapeY = float(row['scapeY']) + + db.session.add(book) + numberadded = numberadded+1 + authors = row['authors'].split('|') + authors = [x.strip() for x in authors] + for author in authors: + if author: + a = db.session.query(Author).filter_by(author_name=author).first() + if a == None: + a = Author(author_name=author) + db.session.add(a) + book.authors.append(a) + db.session.commit() + return render_template('import_csv.html', numberadded=numberadded) + + +@app.route('/empty_catalogue487352698237465', methods= ['POST','GET']) +def empty_catalogue(): + meta = db.metadata + for table in reversed(meta.sorted_tables): + if str(table) == "books" or str(table) == "authors" or str(table) == "books_authors": + print('Clear table %s' % table) + db.session.execute(table.delete()) + db.create_all() + db.session.commit() + return "ALL CLEARED" + ### # The API ### @@ -673,10 +842,14 @@ def page_not_found(error): """Custom 404 page.""" return render_template('404.html'), 404 + +### SOCKET for the chat + @socketio.on('new_message') def new_message(message): - # Send message to alls users - print("new message") + # Send message to all users + # print("new message") + # channel is always 1 now, but might be interesting for further development emit('channel-' + str(message['channel']), { 'username': message['username'], 'text': message['text'], @@ -688,6 +861,7 @@ def new_message(message): my_new_chat = Chat( message=message['text'] ) + db.session.add(my_new_chat) try: db.session.commit() diff --git a/init_db.sh b/init_db.sh index 7302c05..c90baea 100644 --- a/init_db.sh +++ b/init_db.sh @@ -4,4 +4,4 @@ mkdir -p app/uploads/cover chmod 777 app/uploads/ chmod 777 app/uploads/cover python3 init.py -python3 import_csv.py xpublibrary.csv +#python3 import_csv.py xpublibrary.csv diff --git a/requirements.txt b/requirements.txt index 4af1a1c..542394a 100755 --- a/requirements.txt +++ b/requirements.txt @@ -16,6 +16,12 @@ WTForms==2.1 flask-marshmallow==0.9.0 Wand==0.4.4 PyPDF2==1.26.0 +<<<<<<< HEAD +flask-socketio==2.9.2 +flask-whooshalchemyplus==0.7.5 +python-dotenv==0.7.1 +======= autocomplete==0.0.104 +>>>>>>> 30d8bade54d8646ad4a5e314022d62e2dbf81755 diff --git a/run.py b/run.py index 530a462..4f85843 100755 --- a/run.py +++ b/run.py @@ -1,9 +1,13 @@ #! /usr/bin/env python from app import app, socketio <<<<<<< HEAD +<<<<<<< HEAD # socketio.run(app) app.run(debug=True,host="0.0.0.0",port=8080) ======= socketio.run(app, port=8080) +======= +socketio.run(app,host="0.0.0.0", port=8080) +>>>>>>> master #app.run(debug=True,host="0.0.0.0",port=8080) >>>>>>> stack_stuff diff --git a/whoosh/Book/MAIN_071mbyqoitijmyv4.seg b/whoosh/Book/MAIN_071mbyqoitijmyv4.seg new file mode 100644 index 0000000..93716a0 Binary files /dev/null and b/whoosh/Book/MAIN_071mbyqoitijmyv4.seg differ diff --git a/whoosh/Book/MAIN_2a7vygakwdvdefoe.seg b/whoosh/Book/MAIN_2a7vygakwdvdefoe.seg new file mode 100644 index 0000000..b928bfb Binary files /dev/null and b/whoosh/Book/MAIN_2a7vygakwdvdefoe.seg differ diff --git a/whoosh/Book/MAIN_5id3ip2mvmsu2mbl.seg b/whoosh/Book/MAIN_5id3ip2mvmsu2mbl.seg new file mode 100644 index 0000000..99e6446 Binary files /dev/null and b/whoosh/Book/MAIN_5id3ip2mvmsu2mbl.seg differ diff --git a/whoosh/Book/MAIN_6bsjkp9xdes7zrrx.seg b/whoosh/Book/MAIN_6bsjkp9xdes7zrrx.seg new file mode 100644 index 0000000..6764b53 Binary files /dev/null and b/whoosh/Book/MAIN_6bsjkp9xdes7zrrx.seg differ diff --git a/whoosh/Book/MAIN_es8t5xyup7nfqm7j.seg b/whoosh/Book/MAIN_es8t5xyup7nfqm7j.seg new file mode 100644 index 0000000..30a931a Binary files /dev/null and b/whoosh/Book/MAIN_es8t5xyup7nfqm7j.seg differ diff --git a/whoosh/Book/MAIN_hljrpqpa46dk3vgc.seg b/whoosh/Book/MAIN_hljrpqpa46dk3vgc.seg new file mode 100644 index 0000000..ee33184 Binary files /dev/null and b/whoosh/Book/MAIN_hljrpqpa46dk3vgc.seg differ diff --git a/whoosh/Book/MAIN_q0ohjvxyt5ufv1vl.seg b/whoosh/Book/MAIN_q0ohjvxyt5ufv1vl.seg new file mode 100644 index 0000000..386444d Binary files /dev/null and b/whoosh/Book/MAIN_q0ohjvxyt5ufv1vl.seg differ diff --git a/whoosh/Book/_MAIN_293.toc b/whoosh/Book/_MAIN_293.toc new file mode 100644 index 0000000..85f8b84 Binary files /dev/null and b/whoosh/Book/_MAIN_293.toc differ