245 lines
9.1 KiB
Smalltalk
245 lines
9.1 KiB
Smalltalk
Extension { #name : #LeDatabase }
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> addPage2FromMarkdeep: markdeepDocTree withRemote: externalDocLocation [
|
|
| remoteMetadata divSnippets dataSnippets snippets page |
|
|
divSnippets := (markdeepDocTree xpath: '//div[@st-class]') asOrderedCollection
|
|
collect: [ :xmlElement | xmlElement postCopy ].
|
|
remoteMetadata := Markdeep new metadataFromXML: markdeepDocTree.
|
|
remoteMetadata at: 'origin' put: externalDocLocation.
|
|
dataSnippets := self sanitizeMarkdeepSnippets: divSnippets withMetadata: remoteMetadata.
|
|
snippets := dataSnippets collect: [ :each | each asLepiterSnippet ].
|
|
page := LePage new
|
|
title: (remoteMetadata at: 'title');
|
|
basicUid: (UUID fromString36: (remoteMetadata at: 'id'));
|
|
createTime: (LeTime new time: (remoteMetadata at: 'created') asDateAndTime);
|
|
editTime: (LeTime new time: (remoteMetadata at: 'modified') asDateAndTime);
|
|
latestEditTime: (LeTime new time: (remoteMetadata at: 'modified') asDateAndTime);
|
|
createEmail: (remoteMetadata at: 'creator');
|
|
editEmail: (remoteMetadata at: 'modifier').
|
|
^ { snippets . page }
|
|
"snippets do: [ :snippet |
|
|
(self hasBlockUID: snippet uid)
|
|
ifTrue: [ | existingPage |
|
|
existingPage := self pages
|
|
detect: [ :pageTemp | pageTemp includesSnippetUid: snippet uid ].
|
|
self importErrorForLocal: existingPage withRemote: externalDocLocation.
|
|
^ self ]
|
|
ifFalse: [ snippet database: self.
|
|
self registerSnippet: snippet ] ].
|
|
self addPage: page.
|
|
^ page"
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> addPageCopy: aLePage [
|
|
| pageTitle timestamp shortID page |
|
|
timestamp := DateAndTime now asString.
|
|
pageTitle := 'Copy of ', aLePage title.
|
|
page := aLePage duplicatePageWithNewName: pageTitle, timestamp.
|
|
shortID := '(id: ', (page uid asString copyFrom: 1 to: 8), ')'.
|
|
page title: (page title copyReplaceAll: timestamp with: shortID).
|
|
^ page
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> addPageFromMarkdeep: markdeepDocTree withRemote: externalDocLocation [
|
|
| remoteMetadata divSnippets dataSnippets snippets page |
|
|
divSnippets := (markdeepDocTree xpath: '//div[@st-class]') asOrderedCollection
|
|
collect: [ :xmlElement | xmlElement postCopy ].
|
|
remoteMetadata := Markdeep new metadataFromXML: markdeepDocTree.
|
|
remoteMetadata at: 'origin' put: externalDocLocation.
|
|
dataSnippets := self sanitizeMarkdeepSnippets: divSnippets withMetadata: remoteMetadata.
|
|
snippets := dataSnippets collect: [ :each | each asLepiterSnippet ].
|
|
page := LePage new
|
|
title: (remoteMetadata at: 'title');
|
|
basicUid: (UUID fromString36: (remoteMetadata at: 'id'));
|
|
createTime: (LeTime new time: (remoteMetadata at: 'created') asDateAndTime);
|
|
editTime: (LeTime new time: (remoteMetadata at: 'modified') asDateAndTime);
|
|
latestEditTime: (LeTime new time: (remoteMetadata at: 'modified') asDateAndTime);
|
|
createEmail: (remoteMetadata at: 'creator');
|
|
editEmail: (remoteMetadata at: 'modifier').
|
|
snippets do: [ :snippet | "| currentParent |"
|
|
page addSnippet: snippet.
|
|
"currentParent := page detectParentSnippetWithUid: (snippet metadata at: 'parent').
|
|
snippet parent: currentParent."
|
|
].
|
|
page children
|
|
do: [ :snippet |
|
|
(self hasBlockUID: snippet uid)
|
|
ifTrue: [ | existingPage |
|
|
existingPage := self pages
|
|
detect: [ :pageTemp | pageTemp includesSnippetUid: snippet uid ].
|
|
self importErrorForLocal: existingPage withRemote: externalDocLocation.
|
|
^ self ]
|
|
ifFalse: [ snippet database: self.
|
|
self registerSnippet: snippet ] ].
|
|
self addPage: page.
|
|
^ page
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> addPageFromMarkdeepUrl: aString [
|
|
| page |
|
|
page := self detectLocalPageForRemote: aString.
|
|
page
|
|
ifNotNil: [ :arg |
|
|
self importErrorForLocal: page withRemote: aString.
|
|
^ self ].
|
|
^ self addPage2FromMarkdeep: (self docTreeForLink: aString) withRemote: aString
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> detectLocalPageForRemote: markdeepDocUrl [
|
|
| markdeepHelper id remoteMetadata docTree |
|
|
markdeepHelper := Markdeep new.
|
|
docTree := self docTreeForLink: markdeepDocUrl.
|
|
remoteMetadata := markdeepHelper metadataFromXML: docTree.
|
|
id := remoteMetadata at: 'id' ifAbsent: [ nil ].
|
|
^ self pageWithID: id ifAbsent: [ ^ nil ].
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> docTreeForLink: aString [
|
|
^ (XMLHTMLParser on: aString asUrl retrieveContents) parseDocument
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> errorCardFor: error [
|
|
|
|
| keepButton overwriteButton backupButton errorMessageUI localPage errorKey |
|
|
errorKey := error keys first.
|
|
localPage := self pageWithID: errorKey.
|
|
keepButton := BrButton new
|
|
aptitude: BrGlamorousButtonWithIconAndLabelAptitude;
|
|
label: 'Keep existing local page';
|
|
icon: BrGlamorousVectorIcons cancel;
|
|
margin: (BlInsets left: 10);
|
|
action: [ :aButton |
|
|
aButton phlow spawnObject: localPage.
|
|
self errors removeKey: errorKey
|
|
].
|
|
overwriteButton := BrButton new
|
|
aptitude: BrGlamorousButtonWithIconAndLabelAptitude;
|
|
label: 'Overwrite with remote page';
|
|
icon: BrGlamorousVectorIcons edit;
|
|
action: [ :aButton |
|
|
self removePage: localPage.
|
|
aButton phlow spawnObject: (self addPageFromMarkdeepUrl: (error at: errorKey at: 'remote')).
|
|
self errors removeKey: errorKey
|
|
];
|
|
margin: (BlInsets left: 10).
|
|
backupButton := BrButton new
|
|
aptitude: BrGlamorousButtonWithIconAndLabelAptitude;
|
|
label: 'Backup local page';
|
|
icon: BrGlamorousVectorIcons changes;
|
|
action: [ :aButton | ];
|
|
margin: (BlInsets left: 10).
|
|
|
|
errorMessageUI := BrEditor new
|
|
aptitude: BrGlamorousRegularEditorAptitude new ;
|
|
text: (error at: errorKey at: 'message');
|
|
vFitContent.
|
|
^ { errorMessageUI. keepButton. overwriteButton. backupButton }
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> errors [
|
|
|
|
^ self optionAt: 'errors' ifAbsentPut: [ Dictionary new ]
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> gtViewErrorDetailsOn: aView [
|
|
<gtView>
|
|
^ aView explicit
|
|
title: 'Errors' translated;
|
|
priority: 5;
|
|
stencil: [ | container |
|
|
container := BlElement new
|
|
layout: BlFlowLayout new;
|
|
constraintsDo: [ :c |
|
|
c vertical fitContent.
|
|
c horizontal matchParent ];
|
|
padding: (BlInsets all: 10).
|
|
container
|
|
addChildren: (self errorCardFor: self errors)
|
|
].
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> importErrorForLocal: page withRemote: externalDocLocation [
|
|
|
|
| message id error |
|
|
id := page uidString.
|
|
message := String streamContents: [ :stream |
|
|
stream
|
|
nextPutAll: 'IMPORTATION ERROR: A page with
|
|
';
|
|
nextPut: Character lf;
|
|
nextPutAll: ' id: ' , id;
|
|
nextPut: Character lf;
|
|
nextPutAll: ' title: ' , page contentAsString;
|
|
nextPut: Character lf;
|
|
nextPut: Character lf;
|
|
nextPutAll: 'already exists in this database and includes overlapping contents';
|
|
nextPut: Character lf;
|
|
nextPutAll: 'with the page you are trying to import from:
|
|
';
|
|
nextPut: Character lf;
|
|
nextPutAll: externalDocLocation;
|
|
nextPut: Character lf;
|
|
nextPut: Character lf;
|
|
nextPutAll:
|
|
'Please choose one of the following options to addres the issue:
|
|
' ].
|
|
error := Dictionary new
|
|
at: 'remote' put: externalDocLocation;
|
|
at: 'message' put: message ;
|
|
yourself.
|
|
self errors at: id put: error
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> options [
|
|
|
|
^ options
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> previewSanitizedPageFromMarkdeep: markdeepDocTree withRemote: externalDocLocation [
|
|
| remoteMetadata divSnippets divSnippetsSanitized |
|
|
divSnippets := (markdeepDocTree xpath: '//div[@st-class]') asOrderedCollection
|
|
collect: [ :xmlElement | xmlElement postCopy ].
|
|
remoteMetadata := Markdeep new metadataFromXML: markdeepDocTree.
|
|
remoteMetadata at: 'origin' put: externalDocLocation.
|
|
divSnippetsSanitized := self sanitizeMarkdeepSnippets: divSnippets withMetadata: remoteMetadata.
|
|
^ { divSnippets . divSnippetsSanitized . remoteMetadata }
|
|
]
|
|
|
|
{ #category : #'*MiniDocs' }
|
|
LeDatabase >> sanitizeMarkdeepSnippets: divSnippets withMetadata: remoteMetadata [
|
|
^ divSnippets collectWithIndex: [:markdeepDiv :i | | snippetData creationTime modificationTime timestampWarning |
|
|
snippetData := markdeepDiv asSnippetDictionary.
|
|
creationTime := snippetData at: 'created'.
|
|
modificationTime := snippetData at: 'modified'.
|
|
timestampWarning := [:timestamp | 'Modified timestamps: ', timestamp ,' date and time was replaced instead of nil value. See "origin" metadata for more historical traceability information.'].
|
|
(creationTime = 'nil' and: [ modificationTime ~= 'nil' ])
|
|
ifTrue: [
|
|
snippetData redefineTimestampsBefore: modificationTime.
|
|
snippetData addErrata: (timestampWarning value: 'creation').
|
|
snippetData at: 'origin' put: (remoteMetadata at: 'origin').
|
|
].
|
|
(creationTime = 'nil' and: [ modificationTime = 'nil' ])
|
|
ifTrue: [ | timeDiff |
|
|
timeDiff := divSnippets size - i. "Suggesting that last snippets were modified after the first ones."
|
|
modificationTime := (remoteMetadata at: 'created') asDateAndTime - timeDiff seconds.
|
|
snippetData redefineTimestampsBefore: modificationTime.
|
|
snippetData addErrata: (timestampWarning value: 'creation').
|
|
snippetData addErrata: (timestampWarning value: 'modification').
|
|
snippetData at: 'origin' put: (remoteMetadata at: 'origin').
|
|
].
|
|
snippetData.
|
|
]
|
|
]
|