From ba03def62c95b98f7295981b3e4463ad7f18aee8 Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Thu, 19 Nov 2020 19:05:28 -0500 Subject: [PATCH 1/5] Code cleaning. Improving html export. --- repository/Brea/BreaDataSource.class.st | 31 -- repository/Brea/BreaMember.class.st | 489 ---------------------- repository/Brea/BreaMemberTest.class.st | 8 - repository/Brea/BreaOrganization.class.st | 32 -- repository/Brea/BreaPage.class.st | 12 +- repository/Brea/BreaTemplate.class.st | 89 ---- repository/Brea/BreaWebPresence.class.st | 54 --- repository/Brea/BreaWebsite.class.st | 292 ------------- 8 files changed, 8 insertions(+), 999 deletions(-) delete mode 100644 repository/Brea/BreaDataSource.class.st delete mode 100644 repository/Brea/BreaMember.class.st delete mode 100644 repository/Brea/BreaMemberTest.class.st delete mode 100644 repository/Brea/BreaOrganization.class.st delete mode 100644 repository/Brea/BreaTemplate.class.st delete mode 100644 repository/Brea/BreaWebPresence.class.st delete mode 100644 repository/Brea/BreaWebsite.class.st diff --git a/repository/Brea/BreaDataSource.class.st b/repository/Brea/BreaDataSource.class.st deleted file mode 100644 index 1de0c35..0000000 --- a/repository/Brea/BreaDataSource.class.st +++ /dev/null @@ -1,31 +0,0 @@ -Class { - #name : #BreaDataSource, - #superclass : #Object, - #instVars : [ - 'source', - 'queries' - ], - #category : #Brea -} - -{ #category : #accessing } -BreaDataSource >> queries [ - ^ queries -] - -{ #category : #accessing } -BreaDataSource >> queries: anObject [ - queries := anObject -] - -{ #category : #accessing } -BreaDataSource >> source [ - ^ source -] - -{ #category : #accessing } -BreaDataSource >> source: aDictionary [ - "Key, value pair in aDictionary contain a short name and a url pointing to a local or a remote - resource. If is local a FileLocator should be provided." - source := aDictionary -] diff --git a/repository/Brea/BreaMember.class.st b/repository/Brea/BreaMember.class.st deleted file mode 100644 index 07e8c98..0000000 --- a/repository/Brea/BreaMember.class.st +++ /dev/null @@ -1,489 +0,0 @@ -" -I model a member of a Brea site, usually a human. -" -Class { - #name : #BreaMember, - #superclass : #Object, - #instVars : [ - 'givenName', - 'familyName', - 'picture', - 'country', - 'tags', - 'email', - 'password', - 'webPresence', - 'organizations' - ], - #category : #Brea -} - -{ #category : #converting } -BreaMember >> asStonModified [ - "asSton is generated a core dumped now. This renaming is trying to solve that. Maybe - in the offical release it will be solved" - ^ STON toStringPretty: self -] - -{ #category : #accessing } -BreaMember >> country [ - ^ country -] - -{ #category : #accessing } -BreaMember >> country: anObject [ - country := anObject -] - -{ #category : #public } -BreaMember >> countryTemplate [ - ^ '{{#country}} - - Country - {{.}} - - {{/country}}' asMustacheTemplate value: self -] - -{ #category : #helpers } -BreaMember >> createTestUser [ - ^ self class new - givenName: 'Test'; - familyName: 'User'; - country: 'Neverland'; - memberOf: 'HackBo' withWebsite: 'http://hackbo.co/'; - memberOf: 'mutabiT' withWebsite: 'http://mutabit.com/'; - website: 'http://test.user'; - twitter: '@offrayLC'; - email: 'iam@test.user'; - tags: 'just, a lot, of words, separated, by commas'. -] - -{ #category : #accessing } -BreaMember >> email [ - ^ email -] - -{ #category : #accessing } -BreaMember >> email: anEmailAddress [ - email := (SHA1 new hashMessage: anEmailAddress) hex -] - -{ #category : #accessing } -BreaMember >> facebook [ - ^ self webPresence facebook. -] - -{ #category : #accessing } -BreaMember >> facebook: aProfileName [ - aProfileName = '' - ifTrue: [ self webPresence facebook: nil ] - ifFalse: [ self webPresence facebook: aProfileName ] -] - -{ #category : #public } -BreaMember >> facebookTemplate [ - ^ '{{#facebook}} - - - Facebook - - - {{.}} - - {{/facebook}}' asMustacheTemplate value: self -] - -{ #category : #accessing } -BreaMember >> familyName [ - ^ familyName -] - -{ #category : #accessing } -BreaMember >> familyName: anObject [ - familyName := anObject -] - -{ #category : #helpers } -BreaMember >> fullName [ - ^ self givenName asLowercase, '-', self familyName asLowercase -] - -{ #category : #accessing } -BreaMember >> getGenericProfilePicture [ - "Other considered avatars where: - 'https://upload.wikimedia.org/wikipedia/commons/1/1e/Default-avatar.jpg'" - self picture: 'https://www.jamf.com/jamf-nation/img/default-avatars/generic-user.png'. - ^ picture -] - -{ #category : #accessing } -BreaMember >> givenName [ - ^ givenName -] - -{ #category : #accessing } -BreaMember >> givenName: anObject [ - givenName := anObject -] - -{ #category : #public } -BreaMember >> head [ - ^ '', self headMeta, self headTitle, self headStyles,'' -] - -{ #category : #utility } -BreaMember >> headMeta [ - ^ ' - - - ' -] - -{ #category : #utility } -BreaMember >> headStyles [ - ^ ' - - - - - - ' -] - -{ #category : #utility } -BreaMember >> headTitle [ - ^ self headTitled: 'GIG: Network' -] - -{ #category : #utility } -BreaMember >> headTitled: aString [ - ^ '', aString ,'' -] - -{ #category : #public } -BreaMember >> html [ - "I show the member profile as HTML" - ^ self head, self htmlOutput -] - -{ #category : #public } -BreaMember >> htmlInput [ - "I capture data in a HTML Form and use it to create a new BreaMember" - ^ ' - - - - - - - - Add Member | GIG Network - - - - - - -
-
- -
-
-
-
-
-

Add new member

-
-
-

- Fill out the form. - The fields preceded by [*] are obligatory. -

-
-
- - - Letters and spaces only -
-
- - - Letters and spaces only -

-
- - -
-
- - - Letters and spaces only -

-
- - - Letters and spaces only -

-
- - -
-
- - -

-
- - -
-
- - -

-
- - -
-

- -

-
-
-
-
- -
-
- - - -' -] - -{ #category : #public } -BreaMember >> htmlOutput [ - - ^ self htmlOutputTemplate asMustacheTemplate value: self -] - -{ #category : #public } -BreaMember >> htmlOutputTemplate [ - "I show the member profile as HTML" - ^ '
-
-
-

{{givenName}} {{familyName}}

-
-
- -
-
- - - - - - ', - self countryTemplate, - self organizationsTemplate, - self websiteTemplate, - self twitterTemplate, - self facebookTemplate, - self tagsTemplate, - ' - -
Name{{givenName}} {{familyName}}
-
-
- Read more -
-
-
- ' -] - -{ #category : #accessing } -BreaMember >> instagram [ - ^ self webPresence instagram. -] - -{ #category : #accessing } -BreaMember >> instagram: aProfileName [ - self webPresence instagram: aProfileName -] - -{ #category : #accessing } -BreaMember >> memberOf: anOrgName [ - self organizations add: - (BreaOrganization new name: anOrgName) -] - -{ #category : #accessing } -BreaMember >> memberOf: anOrgName withWebsite: aUrl [ - self organizations add: - (BreaOrganization new - name: anOrgName; - website: aUrl) -] - -{ #category : #accessing } -BreaMember >> organizations [ - ^ organizations ifNil: [ organizations := OrderedCollection new ] -] - -{ #category : #accessing } -BreaMember >> organizations: anOrgListOrName [ - anOrgListOrName splitOn: ',' do: [ :each | self memberOf: each ] -] - -{ #category : #public } -BreaMember >> organizationsTemplate [ - ^ ' - - Organization(s) - - {{#organizations}} - {{name}} - {{/organizations}} - - ' asMustacheTemplate value: self -] - -{ #category : #accessing } -BreaMember >> password [ - ^ password -] - -{ #category : #accessing } -BreaMember >> password: anObject [ - password := anObject -] - -{ #category : #accessing } -BreaMember >> picture [ - ^ picture ifNil: [ ^ self getGenericProfilePicture ] -] - -{ #category : #accessing } -BreaMember >> picture: anImageFilePath [ - picture := anImageFilePath -] - -{ #category : #helpers } -BreaMember >> renderTestUserAsHtml [ - ^ self class new createTestUser html -] - -{ #category : #'server handling' } -BreaMember >> storeInto: aFileDirectory [ - | folder file | - folder := (aFileDirectory asFileReference / self fullName) ensureCreateDirectory. - file := (folder / 'info.ston') ensureCreateFile. - file writeStreamDo: [:stream | - (STON writer on: stream) - newLine: String crlf; - prettyPrint: true; - nextPut: self] -] - -{ #category : #accessing } -BreaMember >> tags [ - ^ tags -] - -{ #category : #accessing } -BreaMember >> tags: anObject [ - tags := anObject -] - -{ #category : #public } -BreaMember >> tagsTemplate [ - ^ '{{#tags}} - - - Tags
- {{.}} - - - {{/tags}}' asMustacheTemplate value: self -] - -{ #category : #accessing } -BreaMember >> twitter [ - ^ self webPresence twitter. -] - -{ #category : #accessing } -BreaMember >> twitter: aProfileName [ - aProfileName = '' - ifTrue: [ self webPresence twitter: nil ] - ifFalse: [ self webPresence twitter: aProfileName ] -] - -{ #category : #public } -BreaMember >> twitterTemplate [ - ^ '{{#twitter}} - - - Twitter - - - {{.}} - - {{/twitter}}' asMustacheTemplate value: self -] - -{ #category : #accessing } -BreaMember >> webPresence [ - ^ webPresence ifNil: [ webPresence := BreaWebPresence new ] -] - -{ #category : #accessing } -BreaMember >> webPresence: anObject [ - webPresence := anObject -] - -{ #category : #accessing } -BreaMember >> website [ - ^ self webPresence website. -] - -{ #category : #accessing } -BreaMember >> website: anUrl [ - self webPresence website: anUrl -] - -{ #category : #public } -BreaMember >> websiteTemplate [ - ^ '{{#website}} - - Website - - {{.}} - - {{/website}}' asMustacheTemplate value: self -] diff --git a/repository/Brea/BreaMemberTest.class.st b/repository/Brea/BreaMemberTest.class.st deleted file mode 100644 index 162a3c5..0000000 --- a/repository/Brea/BreaMemberTest.class.st +++ /dev/null @@ -1,8 +0,0 @@ -" -A BreaMemberTest is a test class for testing the behavior of BreaMember -" -Class { - #name : #BreaMemberTest, - #superclass : #TestCase, - #category : #'Brea-Tests' -} diff --git a/repository/Brea/BreaOrganization.class.st b/repository/Brea/BreaOrganization.class.st deleted file mode 100644 index 7142be6..0000000 --- a/repository/Brea/BreaOrganization.class.st +++ /dev/null @@ -1,32 +0,0 @@ -" -I store the places a BreaMember is affiliated to. -" -Class { - #name : #BreaOrganization, - #superclass : #Object, - #instVars : [ - 'name', - 'website' - ], - #category : #Brea -} - -{ #category : #accessing } -BreaOrganization >> name [ - ^ name -] - -{ #category : #accessing } -BreaOrganization >> name: anObject [ - name := anObject -] - -{ #category : #accessing } -BreaOrganization >> website [ - ^ website -] - -{ #category : #accessing } -BreaOrganization >> website: anObject [ - website := anObject -] diff --git a/repository/Brea/BreaPage.class.st b/repository/Brea/BreaPage.class.st index 9591c77..a1ab14e 100644 --- a/repository/Brea/BreaPage.class.st +++ b/repository/Brea/BreaPage.class.st @@ -76,10 +76,13 @@ BreaPage >> exportAsHTML [ | htmlContents allActions actionsArray semaphore result | self shortName ifNil: [ ^ self ]. self template ifNil: [ ^ self ]. - actionsArray := { [ self populateMetadata ] future. [ self split ] future. }. - self bodyTag ifNotNil: [ actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. + actionsArray := { [ self populateMetadata ] future. }. + self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ [ self split ] future ] ]. + self bodyTag ifNotNil: [ + actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. allActions := TKTFuture all: actionsArray. semaphore := Semaphore new. + "self halt." allActions onSuccessDo: [ :values | result := values last. semaphore signal. @@ -119,7 +122,7 @@ BreaPage >> htmlContents [ { #category : #accessing } BreaPage >> metadata [ - ^ metadata + ^ metadata ifNil: [ self contentsFile metadata ] ] { #category : #accessing } @@ -132,7 +135,7 @@ BreaPage >> metadata: aDictionary [ { #category : #'as yet unclassified' } BreaPage >> populateBodyAs: key [ | allActions result semaphore | - "(self file isMarkdown and: [ self bodyTag isNil ]) ifTrue: [ ^ self ]". + allActions := TKTFuture all: { [ self bodyContentsAsHTML ] future. }. @@ -176,6 +179,7 @@ BreaPage >> shortName: aString [ { #category : #'as yet unclassified' } BreaPage >> split [ + self splitters ifEmpty: [ ^ self ]. self splitters keysAndValuesDo: [ :key :value | self split: key with: value ]. ] diff --git a/repository/Brea/BreaTemplate.class.st b/repository/Brea/BreaTemplate.class.st deleted file mode 100644 index f23e4f9..0000000 --- a/repository/Brea/BreaTemplate.class.st +++ /dev/null @@ -1,89 +0,0 @@ -" -I define a [Mustache][1] template and how it is used to create -derivate output files combining it with particular data sources. - -[1]: https://mustache.github.io/ -" -Class { - #name : #BreaTemplate, - #superclass : #Object, - #instVars : [ - 'template', - 'data', - 'location', - 'queries', - 'outputs' - ], - #category : #Brea -} - -{ #category : #adding } -BreaTemplate >> addDataSourceNamed: name with: source [ - self - data at: name put: source. - self data. -] - -{ #category : #accessing } -BreaTemplate >> data [ - ^ data ifNil: [ data := Dictionary new ] -] - -{ #category : #accessing } -BreaTemplate >> data: aDictionary [ - "Each item in the dictionary is a unique alias (as key) and a data location (as value), - usually on the web. - Alias and locations are used later to define data queries to feed into templates." - data := aDictionary -] - -{ #category : #accessing } -BreaTemplate >> location [ - ^ location -] - -{ #category : #accessing } -BreaTemplate >> location: aFolderPath [ - "This is the place where a template and its derivate files are located. - A shared location is an easy approach to start with and creates more explicit - relation between derived files and templates. - Eventually some re-mapping or re-routing could be used so templates and their outputs - could be further apart." - location := aFolderPath -] - -{ #category : #accessing } -BreaTemplate >> outputs [ - ^ outputs -] - -{ #category : #accessing } -BreaTemplate >> outputs: fileNamesList [ - "fileNamesList contain the files which are derived from the template." - outputs := fileNamesList -] - -{ #category : #accessing } -BreaTemplate >> queries [ - ^ queries ifNil: [ queries := Dictionary new ] -] - -{ #category : #accessing } -BreaTemplate >> queries: aDictionary [ - "aDictionary contains the alias for the query as key and a block that will be executed - on a particular data source, as value." - queries := aDictionary -] - -{ #category : #accessing } -BreaTemplate >> template [ - ^ template -] - -{ #category : #accessing } -BreaTemplate >> template: aFileName [ - "I provide the name of the mustache base template. - The file can have any name, but by convention they end in '.mus.html' 'mus.md' and - so on." - template := aFileName -] diff --git a/repository/Brea/BreaWebPresence.class.st b/repository/Brea/BreaWebPresence.class.st deleted file mode 100644 index 815a62c..0000000 --- a/repository/Brea/BreaWebPresence.class.st +++ /dev/null @@ -1,54 +0,0 @@ -" -I store the common forms of web presence a BreaMember can have online. -" -Class { - #name : #BreaWebPresence, - #superclass : #Object, - #instVars : [ - 'website', - 'twitter', - 'facebook', - 'instagram' - ], - #category : #Brea -} - -{ #category : #accessing } -BreaWebPresence >> facebook [ - ^ facebook -] - -{ #category : #accessing } -BreaWebPresence >> facebook: anObject [ - facebook := anObject -] - -{ #category : #accessing } -BreaWebPresence >> instagram [ - ^ instagram -] - -{ #category : #accessing } -BreaWebPresence >> instagram: anObject [ - instagram := anObject -] - -{ #category : #accessing } -BreaWebPresence >> twitter [ - ^ twitter -] - -{ #category : #accessing } -BreaWebPresence >> twitter: anObject [ - twitter := anObject -] - -{ #category : #accessing } -BreaWebPresence >> website [ - ^ website -] - -{ #category : #accessing } -BreaWebPresence >> website: anObject [ - website := anObject -] diff --git a/repository/Brea/BreaWebsite.class.st b/repository/Brea/BreaWebsite.class.st deleted file mode 100644 index fa187c2..0000000 --- a/repository/Brea/BreaWebsite.class.st +++ /dev/null @@ -1,292 +0,0 @@ -" -I model the fossil repository where public data is stored for the -building of this web site. -" -Class { - #name : #BreaWebsite, - #superclass : #Object, - #instVars : [ - 'fossilRepo', - 'server', - 'template', - 'title' - ], - #category : #Brea -} - -{ #category : #utility } -BreaWebsite class >> availableTemplates [ - self templates keys. -] - -{ #category : #utility } -BreaWebsite class >> demoFolder [ - ^ FileLocator temp asFileReference / 'BreaDemo'. -] - -{ #category : #example } -BreaWebsite class >> example [ - "I run an example mockup of a website using Brea. - After runing me, go to: - - http://localhost:8080/demo - - http://localhost:8080/members/test - - http://localhost:8080/members/add " - self new - local: FileLocator temp asFileReference / 'BreaDemo'; - template: 'portafolio'; - downloadTemplate; - modifyTemplate; - start -] - -{ #category : #example } -BreaWebsite class >> exampleDashboard [ - "I run an example mockup of a website using Brea. - After runing me, go to: http://localhost:8080/demo " - self new - local: FileLocator temp asFileReference / 'BreaDemo'; - template: 'dashboard'; - downloadTemplate; - modifyTemplate; - start -] - -{ #category : #'server handling' } -BreaWebsite class >> stopAll [ - "I stop the server" - Teapot stopAll -] - -{ #category : #utility } -BreaWebsite class >> templates [ - "I provide the supported MDL templates taken from: https://getmdl.io/templates/" - ^ Dictionary new - at: 'portafolio' put: 'https://code.getmdl.io/1.3.0/mdl-template-portfolio.zip'; - at: 'dashboard' put: 'https://code.getmdl.io/1.3.0/mdl-template-dashboard.zip'; - yourself. -] - -{ #category : #utility } -BreaWebsite >> defaultTemplate [ - self template - ifNil: [ - self template: 'portafolio' ]. - ^ self template. -] - -{ #category : #utility } -BreaWebsite >> downloadDefaultTemplate [ - self downloadTemplateNamed: self defaultTemplate Into: self local. -] - -{ #category : #utility } -BreaWebsite >> downloadDefaultTemplateInto: aDirectory [ - | remoteUrl templatesFile | - aDirectory ensureDeleteAll. - aDirectory ensureCreateDirectory. - remoteUrl := self class templates at: self template. - GrafoscopioUtils - downloadingFrom: remoteUrl - withMessage: 'Downloading templates' - into: FileLocator temp asFileReference. - templatesFile := FileLocator temp asFileReference / (remoteUrl splitOn: '/') last. - ZipArchive new - readFrom: templatesFile; - extractAllTo: aDirectory -] - -{ #category : #utility } -BreaWebsite >> downloadTemplate [ - self downloadTemplateNamed: self template Into: self local. -] - -{ #category : #utility } -BreaWebsite >> downloadTemplateNamed: aName Into: aDirectory [ - "aName: String aDirectory: aFileLocation" - | remoteUrl templatesFile localDirectory | - localDirectory := aDirectory asFileReference. - localDirectory ensureDeleteAll. - localDirectory ensureCreateDirectory. - remoteUrl := self class templates at: aName. - GrafoscopioUtils - downloadingFrom: remoteUrl - withMessage: 'Downloading templates' - into: FileLocator temp asFileReference. - templatesFile := FileLocator temp asFileReference / (remoteUrl splitOn: '/') last. - ZipArchive new - readFrom: templatesFile; - extractAllTo: localDirectory -] - -{ #category : #accessing } -BreaWebsite >> fossilRepo [ - ^ fossilRepo ifNil: [ fossilRepo := FossilRepo new ] -] - -{ #category : #accessing } -BreaWebsite >> fossilRepo: aFossilRepo [ - fossilRepo := aFossilRepo -] - -{ #category : #utility } -BreaWebsite >> local [ - ^ self fossilRepo local -] - -{ #category : #'server handling' } -BreaWebsite >> local: aFilePath [ - "I define the local storage of the Fossil repository. - For the moment aFilePath must be an absolute " - | localSite | - aFilePath asFileReference exists - ifFalse: [ - localSite := (FileLocator temp / 'breaSite') ensureCreateDirectory. - self fossilRepo local: localSite fullName ] - ifTrue: [ self fossilRepo local: aFilePath ]. -] - -{ #category : #'server handling' } -BreaWebsite >> local: aFilePath remote: anUrl [ - "I define the local and remote storages of the Fossil repository" - self remote: anUrl. - self local: aFilePath -] - -{ #category : #utility } -BreaWebsite >> modifyDashboardTemplate [ - "I replace default templates with versioned files, that contains Mustache tags used - for examples." - "This part should be factorized and integrated into a single method tha modifies any - template, instead of repeated the code of modifyPortafolioTemplate." - | remoteRepoUrl files | - remoteRepoUrl := 'http://mutabit.com/repos.fossil/brea/templates/portaforlio'. - files := #('index.html' 'styles.css'). - "files do: [ :file | - GrafoscopioUtils - downloadingFrom: remoteRepoUrl, 'doc/tip/', file - withMessage: 'Replacing ', file - into: self local ]" -] - -{ #category : #utility } -BreaWebsite >> modifyPortafolioTemplate [ - "I replace default templates with versioned files, that contains Mustache tags used - for examples." - | remoteRepoUrl files | - remoteRepoUrl := 'http://mutabit.com/repos.fossil/gig/'. - files := #('index.html' 'styles.css'). - files do: [ :file | - GrafoscopioUtils - downloadingFrom: remoteRepoUrl, 'doc/tip/', file - withMessage: 'Replacing ', file - into: self local ] -] - -{ #category : #utility } -BreaWebsite >> modifyTemplate [ - "I replace default templates with versioned files, that contains Mustache tags used - for examples." - self template = 'portafolio' ifTrue: [ self modifyPortafolioTemplate ]. - self template = 'dashboard' ifTrue: [ self modifyDashboardTemplate ] -] - -{ #category : #'input processing' } -BreaWebsite >> processNewMember: request [ - | member badRequest | - badRequest := [ ^ ZnResponse badRequest: request ]. - (request hasEntity - and: [ request contentType matches: ZnMimeType applicationFormUrlEncoded ]) - ifFalse: [ badRequest ]. - member := BreaMember new - givenName: (request at: #givenName); - familyName: (request at: #familyName); - email: (request at: #email); - country: (request at: #country); - organizations: (request at: #organizations); - picture: (request at: #picture); - website: (request at: #website); - twitter: (request at: #twitter); - facebook: (request at: #facebook); - tags: (request at: #tags). - self store: member. - ^ 'New member stored!' -] - -{ #category : #'server handling' } -BreaWebsite >> remote: anUrl [ - "I define the remote storage of the Fossil repository" - self remote: anUrl. -] - -{ #category : #'server handling' } -BreaWebsite >> routes [ - "I define how the website behaves accordingly to particular routes." - self server - serveStatic: 'demo' from: (self local); - GET: 'members/test' -> [ :req | BreaMember new renderTestUserAsHtml ]; - GET: 'members/add' -> [ :req | BreaMember new htmlInput ]; - POST: 'members/summit' -> [ :req | self processNewMember: req ] -] - -{ #category : #accessing } -BreaWebsite >> server [ - ^ server ifNil: [ self setup ] -] - -{ #category : #accessing } -BreaWebsite >> server: anObject [ - server := anObject -] - -{ #category : #accessing } -BreaWebsite >> setup [ - ^ server := Teapot - configure: - {(#port -> 8080). - (#debugMode -> true)} -] - -{ #category : #'server handling' } -BreaWebsite >> start [ - "I define the config and start the server" - self routes. - self server start -] - -{ #category : #'server handling' } -BreaWebsite >> storageFor: anObject [ - "I define the places where local storage is done for several types of objects" - anObject class = BreaMember - ifTrue: [ ^ self local asFileReference / 'members' ]. - ^ self -] - -{ #category : #'server handling' } -BreaWebsite >> store: anObject [ - "I store different kind of objects in the website repository. - For the moment I will only store BreaMembers, but as long as new - objects will emerge, I will specialize other ways of storage." - anObject storeInto: (self storageFor: anObject) -] - -{ #category : #accessing } -BreaWebsite >> template [ - ^ template -] - -{ #category : #accessing } -BreaWebsite >> template: aTemplateName [ - "I define the default template to be used for the Brea website. - Available options are at self class templates." - template := aTemplateName -] - -{ #category : #accessing } -BreaWebsite >> title [ - ^ title -] - -{ #category : #accessing } -BreaWebsite >> title: anObject [ - title := anObject -] From ffeeff423bbaa607f600fc5eca1c854acd6f11bf Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Sat, 21 Nov 2020 13:34:20 -0500 Subject: [PATCH 2/5] Adding tests package. --- repository/Brea-Tests/BreaPageTest.class.st | 188 ++++++++++++++++++++ repository/Brea-Tests/package.st | 1 + repository/Brea/BreaFile.class.st | 2 +- repository/Brea/BreaPage.class.st | 6 + 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 repository/Brea-Tests/BreaPageTest.class.st create mode 100644 repository/Brea-Tests/package.st diff --git a/repository/Brea-Tests/BreaPageTest.class.st b/repository/Brea-Tests/BreaPageTest.class.st new file mode 100644 index 0000000..1d1d175 --- /dev/null +++ b/repository/Brea-Tests/BreaPageTest.class.st @@ -0,0 +1,188 @@ +" +A BreaPageTest is a test class for testing the behavior of BreaPage +" +Class { + #name : #BreaPageTest, + #superclass : #TestCase, + #category : #'Brea-Tests' +} + +{ #category : #initialization } +BreaPageTest >> createHTMLTemplateFile [ + | testFile contents | + testFile := FileLocator temp / 'template.mus.html'. + testFile ensureCreateFile. + contents := +' + + + + + {{title}} + + +

{{title}}

+

+ {{#show}} You should see me. {{/show}} +

+

+ {{#unhide}} You should not see me. {{/unhide}} +

+ {{ contents }} + +'. + + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #initialization } +BreaPageTest >> createJSONFile [ + | testFile contents | + testFile := self jsonTestFile. + testFile ensureCreateFile. + contents := '{ "title": "This is a test", "show": true, "unhide": false }'. + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #initialization } +BreaPageTest >> createMarkdownFile [ + | testFile contents | + testFile := self markdownTestFile. + testFile ensureCreateFile. + contents := +'--- +title: This is a test +show: true +unhide: false + +--- + +# Level one header + +And paragraph contents with _emphasis_ and **strong emphasis**.'. + + MarkupFile exportAsFileOn: testFile containing: contents. + +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> htmlBodyContents [ + ^ '

Level one header

+

And paragraph contents with emphasis and strong emphasis.

+' +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> htmlOutput [ + ^ ' + + + + + This is a test + + +

This is a test

+

+ You should see me. +

+

+

', + self htmlBodyContents, +' +' +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> jsonTestFile [ + ^ FileLocator temp / 'test1.json'. +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> markdownTestFile [ + ^ FileLocator temp / 'test.md'. +] + +{ #category : #'as yet unclassified' } +BreaPageTest >> setUp [ + "I create disposable simple files for testing purposes." + super setUp. + self createMarkdownFile. + self createHTMLTemplateFile. +] + +{ #category : #tests } +BreaPageTest >> testJSONMetadataExtraction [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test1'; + folder: FileLocator temp. + self assert: page metadata equals: testMetadata +] + +{ #category : #tests } +BreaPageTest >> testJSONPopulateMetadata [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test1'; + folder: FileLocator temp. + page templateData at: 'extra' put: 'value'. + self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) +] + +{ #category : #tests } +BreaPageTest >> testMarkdownContentExtraction [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + self assert: page contents equals: self markdownTestFile contents. +] + +{ #category : #tests } +BreaPageTest >> testMarkdownMetadataExtraction [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + self assert: page metadata equals: testMetadata +] + +{ #category : #tests } +BreaPageTest >> testMarkdownPopulateBody [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp; + bodyTag: 'contents'. + page populateTaggedBody. + self assert: (page templateData at: 'contents') equals: self htmlBodyContents. +] + +{ #category : #tests } +BreaPageTest >> testMarkdownPopulateMetadata [ + + | page testMetadata | + testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary. + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp. + page templateData at: 'extra' put: 'value'. + self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself) +] diff --git a/repository/Brea-Tests/package.st b/repository/Brea-Tests/package.st new file mode 100644 index 0000000..3af073a --- /dev/null +++ b/repository/Brea-Tests/package.st @@ -0,0 +1 @@ +Package { #name : #'Brea-Tests' } diff --git a/repository/Brea/BreaFile.class.st b/repository/Brea/BreaFile.class.st index cdbf0cd..b2c8616 100644 --- a/repository/Brea/BreaFile.class.st +++ b/repository/Brea/BreaFile.class.st @@ -57,7 +57,7 @@ BreaFile >> folder: anObject [ BreaFile >> metadata [ self name ifNil: [ ^ nil ]. (self name endsWith: '.md') ifTrue: [ ^ self contents metadata ]. - (self name endsWith: '.json') ifTrue: [ ^ self contents ]. + (self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ]. ] { #category : #accessing } diff --git a/repository/Brea/BreaPage.class.st b/repository/Brea/BreaPage.class.st index a1ab14e..0485c27 100644 --- a/repository/Brea/BreaPage.class.st +++ b/repository/Brea/BreaPage.class.st @@ -165,6 +165,12 @@ BreaPage >> populateMetadata [ ^ templateData ] +{ #category : #operation } +BreaPage >> populateTaggedBody [ + self bodyTag ifNil: [ ^ self ]. + ^ self populateBodyAs: self bodyTag. +] + { #category : #accessing } BreaPage >> shortName [ ^ shortName From 72098ee5b9758a931155803cb9fb276b7b551188 Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Sat, 21 Nov 2020 14:15:38 -0500 Subject: [PATCH 3/5] Updated test. Need to improve on Internet line endings. --- repository/Brea-Tests/BreaPageTest.class.st | 25 ++++++++++++++++----- repository/Brea/BreaPage.class.st | 1 - 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/repository/Brea-Tests/BreaPageTest.class.st b/repository/Brea-Tests/BreaPageTest.class.st index 1d1d175..a6a5485 100644 --- a/repository/Brea-Tests/BreaPageTest.class.st +++ b/repository/Brea-Tests/BreaPageTest.class.st @@ -28,7 +28,7 @@ BreaPageTest >> createHTMLTemplateFile [

{{#unhide}} You should not see me. {{/unhide}}

- {{ contents }} + {{{ contents }}} '. @@ -86,12 +86,14 @@ BreaPageTest >> htmlOutput [

This is a test

- You should see me. + You should see me.

-

', - self htmlBodyContents, -' + +

+ ', self htmlBodyContents, +' + ' ] @@ -149,6 +151,19 @@ BreaPageTest >> testMarkdownContentExtraction [ self assert: page contents equals: self markdownTestFile contents. ] +{ #category : #tests } +BreaPageTest >> testMarkdownHTMLExport [ + + | page | + page := BreaPage new. + page + shortName: 'test'; + folder: FileLocator temp; + template: 'template.mus.html'; + bodyTag: 'contents'. + self assert: (page exportAsHTML contents) equals: self htmlOutput. +] + { #category : #tests } BreaPageTest >> testMarkdownMetadataExtraction [ diff --git a/repository/Brea/BreaPage.class.st b/repository/Brea/BreaPage.class.st index 0485c27..ea3845d 100644 --- a/repository/Brea/BreaPage.class.st +++ b/repository/Brea/BreaPage.class.st @@ -82,7 +82,6 @@ BreaPage >> exportAsHTML [ actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. allActions := TKTFuture all: actionsArray. semaphore := Semaphore new. - "self halt." allActions onSuccessDo: [ :values | result := values last. semaphore signal. From 3cb08d4d2cc6e4f1e730f5539e7ee17076fbe96b Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Sat, 21 Nov 2020 17:08:59 -0500 Subject: [PATCH 4/5] Fixing typo with wrong number of parenthesis. --- repository/Brea/BreaPage.class.st | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repository/Brea/BreaPage.class.st b/repository/Brea/BreaPage.class.st index ea3845d..94a47ab 100644 --- a/repository/Brea/BreaPage.class.st +++ b/repository/Brea/BreaPage.class.st @@ -77,7 +77,7 @@ BreaPage >> exportAsHTML [ self shortName ifNil: [ ^ self ]. self template ifNil: [ ^ self ]. actionsArray := { [ self populateMetadata ] future. }. - self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ [ self split ] future ] ]. + self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ]. self bodyTag ifNotNil: [ actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. allActions := TKTFuture all: actionsArray. From 9f0f06d2855ba6e96fe5ff1097acdb4d4a7d7c40 Mon Sep 17 00:00:00 2001 From: Offray Luna Date: Sat, 5 Dec 2020 21:16:14 -0500 Subject: [PATCH 5/5] Support for Airtable data sources, publishing tests and now BreaQueries are part of the BreaThemes. --- repository/Brea-Tests/BreaQueryTest.class.st | 21 +++++ repository/Brea/Airtable.class.st | 51 +++++++++++ repository/Brea/BlockClosure.extension.st | 20 +++++ repository/Brea/BreaQuery.class.st | 95 ++++++++++++++++++++ repository/Brea/BreaTheme.class.st | 25 +++++- 5 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 repository/Brea-Tests/BreaQueryTest.class.st create mode 100644 repository/Brea/Airtable.class.st create mode 100644 repository/Brea/BlockClosure.extension.st create mode 100644 repository/Brea/BreaQuery.class.st diff --git a/repository/Brea-Tests/BreaQueryTest.class.st b/repository/Brea-Tests/BreaQueryTest.class.st new file mode 100644 index 0000000..1917fb2 --- /dev/null +++ b/repository/Brea-Tests/BreaQueryTest.class.st @@ -0,0 +1,21 @@ +" +A BreaQueryTest is a test class for testing the behavior of BreaQuery +" +Class { + #name : #BreaQueryTest, + #superclass : #TestCase, + #category : #'Brea-Tests' +} + +{ #category : #tests } +BreaQueryTest >> testSTONSerialization [ + + | original store deserialized | + original := BreaQuery new + name: 'plus'; + inputs: {'a' -> 3. 'b' -> 4} asDictionary; + codeBlock: [ :x :y | x + y ]. + store := STON toString: original. + deserialized := (STONReader on: store readStream) next. + self assert: original execute equals: deserialized execute +] diff --git a/repository/Brea/Airtable.class.st b/repository/Brea/Airtable.class.st new file mode 100644 index 0000000..c3f8896 --- /dev/null +++ b/repository/Brea/Airtable.class.st @@ -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 ] + +] diff --git a/repository/Brea/BlockClosure.extension.st b/repository/Brea/BlockClosure.extension.st new file mode 100644 index 0000000..ce06ce6 --- /dev/null +++ b/repository/Brea/BlockClosure.extension.st @@ -0,0 +1,20 @@ +Extension { #name : #BlockClosure } + +{ #category : #'*Brea' } +BlockClosure class >> fromSton: stonReader [ + ^ self compilerClass new + source: stonReader parseListSingleton; + evaluate +] + +{ #category : #'*Brea' } +BlockClosure >> stonContainSubObjects [ + ^ false +] + +{ #category : #'*Brea' } +BlockClosure >> stonOn: stonWriter [ + self isClean + ifTrue: [ stonWriter writeObject: self listSingleton: self printString ] + ifFalse: [ stonWriter error: 'Only clean block can be serialized' ] +] diff --git a/repository/Brea/BreaQuery.class.st b/repository/Brea/BreaQuery.class.st new file mode 100644 index 0000000..789f0d5 --- /dev/null +++ b/repository/Brea/BreaQuery.class.st @@ -0,0 +1,95 @@ +" +I represent a operation that can be done on data inputs to produce and output by executing +a code block. + +I can be used by BreaThemes to produce outpus reflected in a particular set of theme pages. + + +- (for bonus points) how to create instances. + + One simple example is simply gorgeous. + +Internal Representation and Key Implementation Points. + + Instance Variables + codeBlock: + inputs: + name: + + + Implementation Points +" +Class { + #name : #BreaQuery, + #superclass : #Object, + #instVars : [ + 'name', + 'inputs', + 'codeBlock', + 'cleanedInputs' + ], + #category : #Brea +} + +{ #category : #converting } +BreaQuery >> asSton [ + ^ STON toStringPretty: self +] + +{ #category : #converting } +BreaQuery >> cleanInputs [ + self cleanedInputs ifNil: [ ^ self ]. + self cleanedInputs ifTrue: [ + self inputs keysAndValuesDo: [ :k :v | | currentValue | + currentValue := self inputs at: k. + self inputs at: k put: currentValue class new + ] + ]. +] + +{ #category : #accessing } +BreaQuery >> cleanedInputs [ + ^ cleanedInputs +] + +{ #category : #accessing } +BreaQuery >> cleanedInputs: aBoolean [ + "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" + cleanedInputs := aBoolean +] + +{ #category : #accessing } +BreaQuery >> codeBlock [ + ^ codeBlock +] + +{ #category : #accessing } +BreaQuery >> codeBlock: anObject [ + codeBlock := anObject +] + +{ #category : #execution } +BreaQuery >> execute [ + ^ self codeBlock valueWithArguments: self inputs values. +] + +{ #category : #accessing } +BreaQuery >> inputs [ + ^ inputs +] + +{ #category : #accessing } +BreaQuery >> inputs: anOrderedDictionary [ + inputs := anOrderedDictionary +] + +{ #category : #accessing } +BreaQuery >> name [ + ^ name +] + +{ #category : #accessing } +BreaQuery >> name: anObject [ + name := anObject +] diff --git a/repository/Brea/BreaTheme.class.st b/repository/Brea/BreaTheme.class.st index 8dc2f20..bc020b0 100644 --- a/repository/Brea/BreaTheme.class.st +++ b/repository/Brea/BreaTheme.class.st @@ -27,11 +27,12 @@ Class { #superclass : #Object, #instVars : [ 'name', + 'folder', 'provider', 'url', 'preview', 'license', - 'folder', + 'queries', 'customizations' ], #category : #Brea @@ -101,6 +102,16 @@ BreaTheme class >> downloadLinks [ ^ result ] +{ #category : #operation } +BreaTheme >> addQuery: aBreaQuery [ + self queries add: aBreaQuery cleanInputs +] + +{ #category : #operation } +BreaTheme >> asSton [ + ^ STON toStringPretty: self +] + { #category : #utilities } BreaTheme >> dashedName [ ^ self name asDashedLowercase @@ -148,7 +159,7 @@ BreaTheme >> license: anObject [ license := anObject ] -{ #category : #'as yet unclassified' } +{ #category : #operation } BreaTheme >> loadConfiguration [ | config | config := self folder / 'brea.yaml'. @@ -193,6 +204,16 @@ BreaTheme >> provider: anObject [ provider := anObject ] +{ #category : #accessing } +BreaTheme >> queries [ + ^ queries ifNil: [ queries := OrderedCollection new ] +] + +{ #category : #accessing } +BreaTheme >> queries: cleanedBreaQueriesCollection [ + queries := cleanedBreaQueriesCollection +] + { #category : #accessing } BreaTheme >> url [ ^ url ifNil: [ url := self class downloadLinks at: self name. ]