Skip to content

Commit

Permalink
v0.2 Closed Beta Release (#169)
Browse files Browse the repository at this point in the history
* fix subtle popover issue
* add name of link tatget
* add text rollovers
* fix thumbnail generation problem
* disable hide logic while rendering in write mode
* improve error handling for image info uris
* allow documents to be parents of documents
* force ssl
* force image links to https
* support n sequences
* retry on CORS
* increase max canvases
  • Loading branch information
NickLaiacona authored Mar 7, 2019
1 parent dbe5569 commit a3b5000
Show file tree
Hide file tree
Showing 17 changed files with 376 additions and 105 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@

.byebug_history
.vscode
convert/node_modules
convert/node_modules

latest.dump
24 changes: 24 additions & 0 deletions app/controllers/document_folders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ class DocumentFoldersController < ApplicationController
before_action only: [:create] do
@project = Project.find(params[:project_id])
end
before_action only: [:add_tree] do
p = document_folder_add_tree_params
if p[:parent_type] == 'Project'
@project = Project.find(p[:parent_id])
else
@document_folder = DocumentFolder.find(p[:parent_id])
@project = @document_folder.project
end
validate_user_write(@project)
end
before_action only: [:show] do
validate_user_read(@project)
end
Expand Down Expand Up @@ -31,6 +41,16 @@ def create
end
end

# POST /document_folders/1/add_tree
def add_tree
p = document_folder_add_tree_params
if p[:parent_type] == 'Project'
@project.add_subtree(p[:tree].as_json)
else
@document_folder.add_subtree(p[:tree].as_json)
end
end

# PATCH/PUT /document_folders/1
def update
if params[:parent_type] == 'DocumentFolder' && (@document_folder.id == params[:parent_id] || @document_folder.descendant_folder_ids.include?(params[:parent_id]))
Expand Down Expand Up @@ -68,6 +88,10 @@ def document_folder_move_params
params.require(:document_folder).permit(:destination_id, :position)
end

def document_folder_add_tree_params
params.require(:document_folder).permit(:parent_id, :parent_type, :tree => {})
end

# Only allow a trusted parameter "white list" through.
def document_folder_params
params.require(:document_folder).permit(:project_id, :title, :parent_id, :parent_type )
Expand Down
8 changes: 2 additions & 6 deletions app/controllers/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,7 @@ def add_images

# POST /documents/1/set_thumbnail
def set_thumbnail
processed = ImageProcessing::MiniMagick.source(open(params['image_url']))
.resize_to_fill(80, 80)
.convert('png')
.call
@document.thumbnail.attach(io: processed, filename: "thumbnail-for-document-#{@document.id}.png")
@document.add_thumbnail( params['image_url'] )
render json: @document
end

Expand All @@ -98,7 +94,7 @@ def set_document

# Only allow a trusted parameter "white list" through.
def new_document_params
params.require(:document).permit(:project_id, :title, :document_kind, :images => [], :content => {})
params.require(:document).permit(:project_id, :title, :parent_id, :parent_type, :document_kind, :images => [], :content => {})
end

def document_move_params
Expand Down
69 changes: 66 additions & 3 deletions app/models/concerns/tree_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,60 @@ def remove_from_tree
}
end
end

def add_subtree( tree )
project_id = self.document_kind == 'Project' ? self.id : self.project_id
parent_type = self.document_kind == 'Project' ? 'Project' : 'DocumentFolder'
root_folder = self.add_child_folder( project_id, self.id, parent_type, tree['name'] )
# note this isn't recursive, parses manifest and 1..n sequences
tree['children'].each { |child|
if child['children']
child_folder = self.add_child_folder( project_id, root_folder.id, 'DocumentFolder', child['name'] )
child['children'].each { |grandchild|
self.add_child_document( project_id, child_folder.id, 'DocumentFolder', grandchild )
}
else
# if there's only one sequence, we don't create a sub folder
self.add_child_document( project_id, root_folder.id, 'DocumentFolder', child )
end
}
end

def add_child_folder( project_id, parent_id, parent_type, name )
document_folder = DocumentFolder.new({
project_id: project_id,
title: name,
parent_id: parent_id,
parent_type: parent_type
})
document_folder.save!
document_folder.move_to( :end, parent_id, parent_type )
document_folder
end

def add_child_document( project_id, parent_id, parent_type, document_json )
image_url = document_json['image_info_uri']
document = Document.new({
project_id: project_id,
parent_id: parent_id,
parent_type: parent_type,
title: document_json['name'],
document_kind: 'canvas',
content: {
tileSources: [ image_url ]
}
})
document.save!
begin
document.add_thumbnail( image_url + '/full/!160,160/0/default.png')
rescue => exception
logger.error "Unable to generate thumb: #{exception}"
end
document.move_to( :end, parent_id, parent_type )
document
end

def contents_children
return nil if self.is_leaf?
(self.documents + self.document_folders).sort_by(&:position)
end

Expand All @@ -49,8 +100,20 @@ def same_as(node_a, node_b)
node_a.id == node_b.id && node_a.class.to_s == node_b.class.to_s
end

def move_to( target_position, destination_id=nil )
destination = destination_id.nil? ? self.project : DocumentFolder.find(destination_id)
def get_tree_node_record( record_id, record_type )
if record_type == "Project"
return Project.find(record_id)
elsif record_type == "DocumentFolder"
return DocumentFolder.find(record_id)
elsif record_type == "Document"
return Document.find(record_id)
end
end

def move_to( target_position, destination_id=nil, destination_type='DocumentFolder' )
destination = destination_id.nil? ?
self.get_tree_node_record(self.parent_id, self.parent_type) :
self.get_tree_node_record(destination_id, destination_type)

if same_as(self.parent, destination)
siblings = (destination.documents + destination.document_folders ).sort_by(&:position)
Expand Down
14 changes: 10 additions & 4 deletions app/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class Document < Linkable
belongs_to :parent, polymorphic: true, optional: true
has_many :highlights, dependent: :delete_all
has_many_attached :images
has_many :documents, as: :parent, dependent: :destroy
has_many :document_folders, as: :parent, dependent: :destroy

include PgSearch
include TreeNode
Expand Down Expand Up @@ -57,10 +59,6 @@ def adjust_lock( user, state )
return false
end
end

def is_leaf?
true
end

def document_id
self.id
Expand All @@ -82,6 +80,14 @@ def color
nil
end

def add_thumbnail( image_url )
processed = ImageProcessing::MiniMagick.source(open(image_url))
.resize_to_fill(80, 80)
.convert('png')
.call
self.thumbnail.attach(io: processed, filename: "thumbnail-for-document-#{self.id}.png")
end

def highlight_map
Hash[self.highlights.collect { |highlight| [highlight.uid, highlight]}]
end
Expand Down
6 changes: 1 addition & 5 deletions app/models/document_folder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ class DocumentFolder < ApplicationRecord

after_create :add_to_tree
before_destroy :remove_from_tree

def is_leaf?
false
end


def document_id
nil
end
Expand Down
8 changes: 4 additions & 4 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ def can_read
self.users.merge(UserProjectPermission.read)
end

def is_leaf?
false
end

def can_write
self.users.merge(UserProjectPermission.write)
end
Expand All @@ -26,6 +22,10 @@ def can_admin
self.users.merge(UserProjectPermission.admin)
end

def document_kind
"Project"
end

# one time migration function for 20190124154624_add_document_position
def self.migrate_to_position_all!
Project.all.each { |project|
Expand Down
54 changes: 13 additions & 41 deletions client/src/AddImageLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { setAddTileSourceMode, setImageUrl, IIIF_TILE_SOURCE_TYPE, IMAGE_URL_SOU
import { replaceDocument, updateDocument, setDocumentThumbnail } from './modules/documentGrid';

const tileSourceTypeLabels = {};
tileSourceTypeLabels[IIIF_TILE_SOURCE_TYPE] = {select: 'IIIF', textField: 'Link to IIIF Image'};
tileSourceTypeLabels[IIIF_TILE_SOURCE_TYPE] = {select: 'IIIF', textField: 'Link to IIIF Image Information URI'};
tileSourceTypeLabels[IMAGE_URL_SOURCE_TYPE] = {select: 'Image URL', textField: 'Link to Web Image'};
tileSourceTypeLabels[UPLOAD_SOURCE_TYPE] = {select: 'Upload image', textField: 'Choose files'};

Expand Down Expand Up @@ -71,65 +71,36 @@ class AddImageLayer extends Component {
break;

case IIIF_TILE_SOURCE_TYPE:
newTileSources.push(this.state.newTileSourceValue);
if (shouldSetThumbnail) {
const baseUrl = this.state.newTileSourceValue.split('info.json')[0];
imageUrlForThumbnail = baseUrl + 'full/!160,160/0/default.png';
imageUrlForThumbnail = this.state.newTileSourceValue + '/full/!160,160/0/default.png';
}
break;

default:
newTileSources.push(this.state.newTileSourceValue);
}

newContent.tileSources = existingTileSources.concat(newTileSources);
this.props.updateDocument(this.props.document_id, {
content: newContent
});
if (this.props.osdViewer) {
this.props.osdViewer.open(newContent.tileSources);
}
this.setState( { ...this.state, newTileSourceValue: null } );
this.props.setAddTileSourceMode(this.props.document_id, null);

if (shouldSetThumbnail && imageUrlForThumbnail)
if (shouldSetThumbnail && imageUrlForThumbnail) {
this.props.setDocumentThumbnail(this.props.document_id, imageUrlForThumbnail);
this.props.setImageUrl(this.props.editorKey, imageUrlForThumbnail)
}

parseIIIFManifest(manifestJSON) {

const manifest = JSON.parse(manifestJSON);

if( manifest === null ) {
return [];
}

// IIIF presentation 2.0
// manifest["sequences"][n]["canvases"][n]["images"][n]["resource"]["service"]["@id"]

let images = [];

let sequence = manifest.sequences[0];
if( sequence !== null && sequence.canvases !== null ) {
sequence.canvases.forEach( (canvas) => {
let image = canvas.images[0]
newContent.tileSources = existingTileSources.concat(newTileSources);
this.props.updateDocument(this.props.document_id, {
content: newContent
});

if( image !== null &&
image.resource !== null &&
image.resource.service !== null ) {
images.push({
name: canvas.label,
xml_id: image.resource.service["@id"],
tile_source: image.resource.service["@id"]
});
}
});
if( addTileSourceMode === UPLOAD_SOURCE_TYPE ) {
this.props.openTileSource(newContent.tileSources[0])
} else {
this.props.openTileSource(this.state.newTileSourceValue)
}

return images;
}


renderUploadButton(buttonStyle,iconStyle) {
const { document_id, replaceDocument } = this.props;
return (
Expand All @@ -138,6 +109,7 @@ class AddImageLayer extends Component {
path: `/documents/${document_id}/add_images`,
model: 'Document',
attribute: 'images',
protocol: 'https',
method: 'PUT'
}}
multiple={true}
Expand Down
Loading

0 comments on commit a3b5000

Please sign in to comment.