Compare commits

..

No commits in common. "master" and "Windows" have entirely different histories.

17 changed files with 1140 additions and 1188 deletions

View File

@ -16,27 +16,42 @@ BaselineOfBrea >> baseline: spec [
for: #common for: #common
do: [ do: [
"Dependencies" "Dependencies"
self miniDocs: spec. self grafoscopioUtils: spec.
spec spec
baseline: 'TaskIt' with: [ spec repository: 'github://pharo-contributions/taskit:v1.0' ] baseline: 'NeoJSON' with: [ spec repository: 'github://svenvc/NeoJSON/repository' ];
"[ spec repository: 'github://noha/taskit:add-all-future' ]" baseline: 'Mustache' with: [ spec repository: 'github://noha/mustache/repository' ];
"Disabling Noha's Fork to make Brea installable.". baseline: 'TaskIt' with: [ spec repository: 'github://noha/taskit:add-all-future' ].
"Packages" "Packages"
spec package: 'Brea' with: [ spec requires: #('MiniDocs' 'TaskIt') ]. spec package: 'Brea' with: [ spec requires: #('NeoJSON' 'Mustache' 'TaskIt' 'Grafoscopio-Utils') ].
] ]
] ]
{ #category : #baselines } { #category : #baselines }
BaselineOfBrea >> miniDocs: spec [ BaselineOfBrea >> grafoscopioUtils: spec [
| repo | "I load the configuration of this package using a external Gitea repository."
repo := ExoRepo new "While more Git independient providers are implemented in Monticello, I will use Iceberg
repository: 'https://code.tupale.co/Offray/MiniDocs'. to download the repository and load it from a local directory"
repo
onConflict: [ :ex | ex useLoaded ]; | location localRepo |
onUpgrade: [ :ex | ex useLoaded ]; "Dependencies"
onDowngrade: [ :ex | ex useLoaded ];
onWarningLog; "Local and remote repo definition"
location := FileLocator localDirectory / 'iceberg' / 'Offray' / 'GrafoscopioUtils'.
location exists ifFalse: [
(IceRepositoryCreator new
location: location;
remote: (IceGitRemote url: 'https://code.tupale.co/Offray/GrafoscopioUtils.git');
createRepository)
register
].
"Package loading"
localRepo := 'gitlocal://', location fullName.
Metacello new
repository: localRepo;
baseline: 'GrafoscopioUtils';
load. load.
spec baseline: 'MiniDocs' with: [ spec repository: 'gitlocal://', repo local fullName ] spec baseline: 'GrafoscopioUtils' with: [ spec repository: localRepo ].
spec package: 'Grafoscopio-Utils' with: [ spec repository: localRepo ].
] ]

View File

@ -113,7 +113,6 @@ BreaPageTest >> setUp [
super setUp. super setUp.
self createMarkdownFile. self createMarkdownFile.
self createHTMLTemplateFile. self createHTMLTemplateFile.
self createJSONFile
] ]
{ #category : #tests } { #category : #tests }

View File

@ -2,16 +2,16 @@
A BreaQueryTest is a test class for testing the behavior of BreaQuery A BreaQueryTest is a test class for testing the behavior of BreaQuery
" "
Class { Class {
#name : #BreaOperatorTest, #name : #BreaQueryTest,
#superclass : #TestCase, #superclass : #TestCase,
#category : #'Brea-Tests' #category : #'Brea-Tests'
} }
{ #category : #tests } { #category : #tests }
BreaOperatorTest >> testSTONSerialization [ BreaQueryTest >> testSTONSerialization [
| original store deserialized | | original store deserialized |
original := BreaOperator new original := BreaQuery new
name: 'plus'; name: 'plus';
inputs: {'a' -> 3. 'b' -> 4} asDictionary; inputs: {'a' -> 3. 'b' -> 4} asDictionary;
codeBlock: [ :x :y | x + y ]. codeBlock: [ :x :y | x + y ].

View File

@ -0,0 +1,51 @@
"
I model an Airtable (https://airtable.com/) database (or Base as they call it).
"
Class {
#name : #Airtable,
#superclass : #Object,
#instVars : [
'id',
'apiKey'
],
#category : #Brea
}
{ #category : #accessing }
Airtable >> apiKey [
^ apiKey
]
{ #category : #accessing }
Airtable >> apiKey: aString [
apiKey := aString
]
{ #category : #accessing }
Airtable >> id [
^ id
]
{ #category : #accessing }
Airtable >> id: aString [
id := aString
]
{ #category : #'as yet unclassified' }
Airtable >> rawRecords [
(self id isNil or: [ self apiKey isNil ]) ifTrue: [ ^ self ].
^ ZnClient new
url: (self id);
headerAt: 'Authorization' put: 'Bearer ', (self apiKey);
get.
]
{ #category : #'as yet unclassified' }
Airtable >> records [
^ ((NeoJSONReader fromString: (self rawRecords)) at: 'records')
select: [ :each | (each at: 'fields') isNotEmpty ]
]

View File

@ -1,104 +0,0 @@
Class {
#name : #BreaApp,
#superclass : #Object,
#instVars : [
'name',
'folder',
'host',
'componets'
],
#category : #Brea
}
{ #category : #accessing }
BreaApp >> add: anObject [
anObject class = String ifFalse: [ ].
self body
nextPutAll: (Pandoc htmlStringToMarkdown: anObject); cr.
]
{ #category : #accessing }
BreaApp >> appName [
^ self name asCamelCase
]
{ #category : #accessing }
BreaApp >> at: key put: anObject [
self components at: key put: anObject.
]
{ #category : #accessing }
BreaApp >> components [
^ componets ifNil: [ componets := OrderedDictionary new]
]
{ #category : #accessing }
BreaApp >> componentsWebView [
| response |
response := '' writeStream.
self components ifEmpty: [ ^ response contents ].
self components valuesDo: [ :component |
response
nextPutAll: component webView; cr
].
^ response contents
]
{ #category : #accessing }
BreaApp >> defaultView [
^ '<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark" />
<link rel="stylesheet" href="css/pico.min.css">
<title>', self name, '</title>
</head>
<body>
<main class="container">
', self componentsWebView,'
</main>
</body>
</html>'
]
{ #category : #accessing }
BreaApp >> folder [
^ folder
]
{ #category : #accessing }
BreaApp >> folder: aFileDirectory [
folder := aFileDirectory
]
{ #category : #accessing }
BreaApp >> name [
^ name
]
{ #category : #accessing }
BreaApp >> name: aString [
name := aString
]
{ #category : #accessing }
BreaApp >> parentFolder: anObject [
self folder: anObject / self name asCamelCase
]
{ #category : #accessing }
BreaApp >> preview [
| defaultRoute |
defaultRoute := 'http://localhost:',self webHost server port asString, '/', self appName.
self webHost
GET: self appName -> [ self defaultView ].
GoogleChrome openWindowOn: defaultRoute
]
{ #category : #accessing }
BreaApp >> webHost [
^ host ifNil: [ host := Teapot allInstances detect: [ :each | each server isRunning ] ifNone: [ host := Teapot on. host server start ]]
]

View File

@ -24,17 +24,14 @@ Class {
{ #category : #operation } { #category : #operation }
BreaPage >> bodyContentsAsHTML [ BreaPage >> bodyContentsAsHTML [
| sourcePage commandParameters | | sourcePage |
self contentsFile ifNil: [ ^ self ]. self contentsFile ifNil: [ ^ self ].
sourcePage := self file file.
Smalltalk os isWindows ifTrue: [ Smalltalk os isWindows ifTrue: [
^ Pandoc markdownToHtml: sourcePage ^ Pandoc markdownToHtml: self file file
]. ].
commandParameters := ' -f markdown+startnum+task_lists -t html '. sourcePage := FileLocator temp / 'wikiPage.md'.
^ GtSubprocessWithInMemoryOutput new MarkupFile exportAsFileOn: sourcePage containing: self contents.
shellCommand: 'pandoc', commandParameters, sourcePage fullName; ^ Pandoc markdownToHtml: sourcePage
runAndWait;
stdout.
] ]
{ #category : #accessing } { #category : #accessing }
@ -66,7 +63,7 @@ BreaPage >> contents [
result nextPutAll: (Markdown fromFile: markdownTempFile) contents. result nextPutAll: (Markdown fromFile: markdownTempFile) contents.
] ]
]. ].
^ result contents withInternetLineEndings. ^ result contents.
] ]
{ #category : #operation } { #category : #operation }
@ -86,7 +83,7 @@ BreaPage >> exportAsHTML [
self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ]. self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ].
self bodyTag ifNotNil: [ self bodyTag ifNotNil: [
actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ].
allActions := TKTFuture fromCollectionOfFutures: actionsArray. allActions := TKTFuture all: actionsArray.
semaphore := Semaphore new. semaphore := Semaphore new.
allActions onSuccessDo: [ :values | allActions onSuccessDo: [ :values |
result := values last. result := values last.
@ -139,7 +136,17 @@ BreaPage >> metadata: aDictionary [
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaPage >> populateBodyAs: key [ BreaPage >> populateBodyAs: key [
self templateData at: key put: self bodyContentsAsHTML. | allActions result semaphore |
allActions := TKTFuture all: {
[ self bodyContentsAsHTML ] future.
}.
semaphore := Semaphore new.
allActions onSuccessDo: [ :values |
result := values last.
semaphore signal ].
semaphore wait.
self templateData at: key put: result contents.
^ self. ^ self.
] ]
@ -157,7 +164,7 @@ BreaPage >> populateMetadata [
ifNil: [ metadataTemp := self contentsFile metadata]. ifNil: [ metadataTemp := self contentsFile metadata].
metadataTemp keysAndValuesDo: [ :key :value | metadataTemp keysAndValuesDo: [ :key :value |
self templateData at: key put: value ]. self templateData at: key put: value ].
^ self templateData ^ templateData
] ]
{ #category : #operation } { #category : #operation }

View File

@ -20,7 +20,7 @@ Internal Representation and Key Implementation Points.
Implementation Points Implementation Points
" "
Class { Class {
#name : #BreaOperator, #name : #BreaQuery,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'name', 'name',
@ -32,12 +32,12 @@ Class {
} }
{ #category : #converting } { #category : #converting }
BreaOperator >> asSton [ BreaQuery >> asSton [
^ STON toStringPretty: self ^ STON toStringPretty: self
] ]
{ #category : #converting } { #category : #converting }
BreaOperator >> cleanInputs [ BreaQuery >> cleanInputs [
self cleanedInputs ifNil: [ ^ self ]. self cleanedInputs ifNil: [ ^ self ].
self cleanedInputs ifTrue: [ self cleanedInputs ifTrue: [
self inputs keysAndValuesDo: [ :k :v | | currentValue | self inputs keysAndValuesDo: [ :k :v | | currentValue |
@ -48,48 +48,48 @@ BreaOperator >> cleanInputs [
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> cleanedInputs [ BreaQuery >> cleanedInputs [
^ cleanedInputs ^ cleanedInputs
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> cleanedInputs: aBoolean [ BreaQuery >> cleanedInputs: aBoolean [
"I tell if the inputs should be cleaned when the query is serialized as STON, for "I tell if the inputs should be cleaned when the query is serialized as STON, for
example when they contain sensible information, like API keys or passwords" example when they contain sensible information, like API keys or passwords"
cleanedInputs := aBoolean cleanedInputs := aBoolean
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> codeBlock [ BreaQuery >> codeBlock [
^ codeBlock ^ codeBlock
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> codeBlock: anObject [ BreaQuery >> codeBlock: anObject [
codeBlock := anObject codeBlock := anObject
] ]
{ #category : #execution } { #category : #execution }
BreaOperator >> execute [ BreaQuery >> execute [
^ self codeBlock valueWithArguments: self inputs values. ^ self codeBlock valueWithArguments: self inputs values.
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> inputs [ BreaQuery >> inputs [
^ inputs ^ inputs
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> inputs: anOrderedDictionary [ BreaQuery >> inputs: anOrderedDictionary [
inputs := anOrderedDictionary inputs := anOrderedDictionary
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> name [ BreaQuery >> name [
^ name ^ name
] ]
{ #category : #accessing } { #category : #accessing }
BreaOperator >> name: anObject [ BreaQuery >> name: anObject [
name := anObject name := anObject
] ]

View File

@ -32,7 +32,8 @@ Class {
'url', 'url',
'preview', 'preview',
'license', 'license',
'operators' 'queries',
'customizations'
], ],
#category : #Brea #category : #Brea
} }
@ -102,8 +103,8 @@ BreaTheme class >> downloadLinks [
] ]
{ #category : #operation } { #category : #operation }
BreaTheme >> addOperator: aBreaQuery [ BreaTheme >> addQuery: aBreaQuery [
self operators add: aBreaQuery cleanInputs self queries add: aBreaQuery cleanInputs
] ]
{ #category : #operation } { #category : #operation }
@ -143,13 +144,8 @@ BreaTheme >> folder: anObject [
BreaTheme >> installInto: aFolder [ BreaTheme >> installInto: aFolder [
| zippedFile | | zippedFile |
self url ifNil: [ ^ self ]. self url ifNil: [ ^ self ].
zippedFile := FileLocator temp / 'download'. zippedFile := self downloadInto: FileLocator temp.
zippedFile ensureDelete.
ZnClient new
url: self url;
downloadTo: FileLocator temp.
(ZipArchive new readFrom: zippedFile) extractAllTo: aFolder. (ZipArchive new readFrom: zippedFile) extractAllTo: aFolder.
self folder: aFolder.
^ aFolder ^ aFolder
] ]
@ -188,16 +184,6 @@ BreaTheme >> name: anObject [
name := anObject name := anObject
] ]
{ #category : #accessing }
BreaTheme >> operators [
^ operators ifNil: [ operators := OrderedCollection new ]
]
{ #category : #accessing }
BreaTheme >> operators: cleanedBreaQueriesCollection [
operators := cleanedBreaQueriesCollection
]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> preview [ BreaTheme >> preview [
^ preview ^ preview
@ -218,6 +204,16 @@ BreaTheme >> provider: anObject [
provider := anObject provider := anObject
] ]
{ #category : #accessing }
BreaTheme >> queries [
^ queries ifNil: [ queries := OrderedCollection new ]
]
{ #category : #accessing }
BreaTheme >> queries: cleanedBreaQueriesCollection [
queries := cleanedBreaQueriesCollection
]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> url [ BreaTheme >> url [
^ url ifNil: [ url := self class downloadLinks at: self name. ] ^ url ifNil: [ url := self class downloadLinks at: self name. ]

View File

@ -1,6 +0,0 @@
Extension { #name : #String }
{ #category : #'*Brea' }
String >> webView [
^ (Pandoc htmlStringToMarkdown: self) accentedCharactersCorrection
]

View File

@ -1,6 +0,0 @@
Extension { #name : #Teapot }
{ #category : #'*Brea' }
Teapot >> dynamicRoutes [
^ dynamicRouter routes
]