2017-06-01 12:12:11 +00:00
|
|
|
"
|
|
|
|
I model a fossil repository. For details about fossil see:
|
|
|
|
|
|
|
|
http://fossil-scm.org/
|
2017-06-09 07:42:57 +00:00
|
|
|
|
|
|
|
The protocols are named following Smalltalk conventions, but
|
|
|
|
also after the Fossil JSON API documentation at [1]
|
|
|
|
|
|
|
|
[1] https://docs.google.com/document/d/1fXViveNhDbiXgCuE7QDXQOKeFzf2qNUkBEgiUvoqFN4/view
|
2017-06-01 12:12:11 +00:00
|
|
|
"
|
|
|
|
Class {
|
|
|
|
#name : #FossilRepo,
|
|
|
|
#superclass : #Object,
|
|
|
|
#instVars : [
|
2017-06-06 10:27:57 +00:00
|
|
|
'local',
|
|
|
|
'remote'
|
2017-06-01 12:12:11 +00:00
|
|
|
],
|
|
|
|
#category : #Fossil
|
|
|
|
}
|
|
|
|
|
2017-06-09 07:42:57 +00:00
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> authTokenFor: anUserName withPassword: passwordString [
|
|
|
|
^ ((self loginAs: anUserName withPassword: passwordString) at: 'payload') at: 'authToken'
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> capabilities [
|
|
|
|
| payload name permissions |
|
|
|
|
payload := self rawCapabilities at: 'payload'.
|
|
|
|
name := payload at: 'name'.
|
|
|
|
permissions := ((payload at: 'permissionFlags') select: [ :item | item value ]) keys.
|
|
|
|
^ Dictionary new
|
|
|
|
at: 'name' put: name;
|
|
|
|
at: 'permissions' put: permissions;
|
|
|
|
yourself.
|
|
|
|
]
|
|
|
|
|
2017-06-01 12:12:11 +00:00
|
|
|
{ #category : #querying }
|
|
|
|
FossilRepo >> checkinsFor: relativeFilePath [
|
|
|
|
"I get all histotical checkins information for a full file name, wich includes relative path
|
2017-07-06 21:28:17 +00:00
|
|
|
in the repository (i.e: 'Doc/Es/Tutoriales/tutorial.ston' or 'index.html')"
|
|
|
|
| payload |
|
|
|
|
payload := (self jsonDataFor: relativeFilePath) at: 'payload' ifAbsent: [
|
|
|
|
self inform:
|
2017-06-01 12:12:11 +00:00
|
|
|
'WARNING! Key not found, verify the file name you are looking in this repository'.
|
2017-07-06 21:28:17 +00:00
|
|
|
^ self ].
|
|
|
|
^ payload at: 'checkins'
|
2017-06-01 12:12:11 +00:00
|
|
|
]
|
|
|
|
|
2017-10-11 11:36:57 +00:00
|
|
|
{ #category : #querying }
|
|
|
|
FossilRepo >> commitsByDate [
|
|
|
|
"I present the sum of all commit organized by date."
|
|
|
|
| result |
|
|
|
|
result := Dictionary new.
|
|
|
|
self timeline do: [ :commit | | key |
|
|
|
|
key := (DateAndTime fromUnixTime: (commit at: 'timestamp' )) asDate.
|
|
|
|
result at: key
|
|
|
|
ifPresent: [ result at: key put: (result at: key) + 1 ]
|
|
|
|
ifAbsent: [ result at: key put: 1 ] ].
|
|
|
|
^ result
|
|
|
|
]
|
|
|
|
|
2017-10-12 15:24:47 +00:00
|
|
|
{ #category : #'data visualization' }
|
|
|
|
FossilRepo >> commitsCalendarFrom: startYear to: endYear colored: colorsPalette [
|
|
|
|
"I"
|
|
|
|
|
|
|
|
| b colors dictionary valuedColors |
|
|
|
|
dictionary := self commitsByDate.
|
|
|
|
colors := RTColorPalette sequential colors: 9 scheme: 'Blues'.
|
|
|
|
valuedColors := self commitsByDate collect: [ :v | colors at: v // 2 + 1 ].
|
|
|
|
b := RTCalendarBuilder new.
|
|
|
|
b dateShape rectangle
|
|
|
|
size: 15;
|
|
|
|
color: Color white;
|
|
|
|
borderColor: Color lightGray.
|
|
|
|
b monthShape shape: (b monthShapePath: 15.0).
|
|
|
|
b yearShape
|
|
|
|
composite: [ :comp |
|
|
|
|
comp
|
|
|
|
add:
|
|
|
|
(RTLabel new
|
|
|
|
text: [ :d | d year ];
|
|
|
|
height: 20).
|
|
|
|
comp add: (RTBox new color: Color transparent) ].
|
|
|
|
b dates: ((Year year: startYear) to: (Year year: endYear)).
|
|
|
|
b dateLayout gapSize: 0.
|
|
|
|
b monthLayout month.
|
|
|
|
b yearLayout horizontalLine.
|
|
|
|
b dateShape
|
|
|
|
if: [ :d | dictionary includesKey: d ]
|
|
|
|
color: [ :d | valuedColors at: d ].
|
|
|
|
b dateInteraction popup.
|
|
|
|
b build.
|
|
|
|
(b view elements select: [ :e | e model isKindOf: Month ]) pushFront.
|
|
|
|
^ b view
|
|
|
|
]
|
|
|
|
|
2017-06-06 10:27:57 +00:00
|
|
|
{ #category : #wiki }
|
2017-06-09 07:42:57 +00:00
|
|
|
FossilRepo >> createPage: pageName [
|
|
|
|
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'create/', pageName)
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #wiki }
|
|
|
|
FossilRepo >> fetchPage: pageName [
|
|
|
|
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'get/', pageName)
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #utility }
|
2017-06-06 10:27:57 +00:00
|
|
|
FossilRepo >> jsonDataFor: anUrlSegment [
|
2017-07-06 21:28:17 +00:00
|
|
|
|
|
|
|
^ NeoJSONReader fromString: (self jsonStringFor: anUrlSegment)
|
2017-06-09 07:42:57 +00:00
|
|
|
]
|
|
|
|
|
2017-06-01 12:12:11 +00:00
|
|
|
{ #category : #querying }
|
|
|
|
FossilRepo >> jsonStringFor: aFileName [
|
2017-07-06 21:28:17 +00:00
|
|
|
| baseUrl queryForJSONData |
|
2017-11-28 21:24:55 +00:00
|
|
|
baseUrl := self remote.
|
|
|
|
baseUrl addPathSegments: #('json' 'finfo').
|
2017-07-06 21:28:17 +00:00
|
|
|
queryForJSONData := baseUrl queryAt: 'name' put: aFileName.
|
2017-06-01 12:12:11 +00:00
|
|
|
^ (ZnEasy get: queryForJSONData) contents.
|
|
|
|
]
|
|
|
|
|
2017-06-09 07:42:57 +00:00
|
|
|
{ #category : #wiki }
|
|
|
|
FossilRepo >> jsonWikiDataFor: anUrlSegment [
|
|
|
|
^ ZnClient new
|
|
|
|
get: (self wikiRoot addPathSegment: anUrlSegment);
|
|
|
|
contents.
|
|
|
|
]
|
|
|
|
|
2017-06-01 12:12:11 +00:00
|
|
|
{ #category : #querying }
|
|
|
|
FossilRepo >> lastHashNumberFor: aFileName [
|
|
|
|
"I'm useful to see if local versions of files are updated to the last versions of the
|
|
|
|
online repository"
|
|
|
|
^ (self checkinsFor: aFileName) first at: 'uuid'
|
|
|
|
]
|
|
|
|
|
2017-06-01 15:57:15 +00:00
|
|
|
{ #category : #accessing }
|
|
|
|
FossilRepo >> local [
|
|
|
|
^ local
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #accessing }
|
|
|
|
FossilRepo >> local: aLocalFilePath [
|
|
|
|
local := aLocalFilePath
|
|
|
|
]
|
|
|
|
|
2017-06-09 07:42:57 +00:00
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> loginAs: anUserName withPassword: password [
|
|
|
|
| jsonData |
|
|
|
|
jsonData := ZnClient new
|
|
|
|
url: (self loginUrlWithName: anUserName andPassword: password);
|
|
|
|
get;
|
|
|
|
contents.
|
|
|
|
^ NeoJSONReader fromString: jsonData
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> loginUrlWithName: aUser andPassword: passwd [
|
|
|
|
^ self jsonRoot
|
|
|
|
addPathSegment: 'login';
|
|
|
|
queryAt: 'name' put: aUser;
|
|
|
|
queryAt: 'password' put: passwd.
|
|
|
|
]
|
|
|
|
|
2017-06-06 10:27:57 +00:00
|
|
|
{ #category : #wiki }
|
|
|
|
FossilRepo >> pageList [
|
2017-06-09 07:42:57 +00:00
|
|
|
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'list')
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> rawCapabilities [
|
|
|
|
^ NeoJSONReader fromString: (self jsonDataFor: 'cap')
|
2017-06-06 10:27:57 +00:00
|
|
|
]
|
|
|
|
|
2017-06-01 12:12:11 +00:00
|
|
|
{ #category : #accessing }
|
2017-06-06 10:27:57 +00:00
|
|
|
FossilRepo >> remote [
|
|
|
|
^ remote
|
2017-06-01 12:12:11 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #accessing }
|
2017-06-06 10:27:57 +00:00
|
|
|
FossilRepo >> remote: anUrlString [
|
|
|
|
remote := anUrlString asUrl
|
|
|
|
]
|
|
|
|
|
2017-10-11 11:36:57 +00:00
|
|
|
{ #category : #accessing }
|
|
|
|
FossilRepo >> timeline [
|
|
|
|
"I return all information of all commits in a repository timeline."
|
|
|
|
| baseUrl queryForJSONData |
|
|
|
|
baseUrl := self remote addPathSegments: #('json' 'timeline' 'checkin').
|
|
|
|
queryForJSONData := baseUrl queryAt: 'limit' put: 0.
|
|
|
|
^ ((NeoJSONReader fromString: (queryForJSONData asUrl retrieveContents))
|
|
|
|
at: 'payload') at: 'timeline'
|
|
|
|
]
|
|
|
|
|
2017-06-09 07:42:57 +00:00
|
|
|
{ #category : #authentication }
|
|
|
|
FossilRepo >> whoAmI [
|
|
|
|
^ NeoJSONReader fromString: (self jsonDataFor: 'whoami')
|
|
|
|
]
|
|
|
|
|
2017-06-06 10:27:57 +00:00
|
|
|
{ #category : #wiki }
|
|
|
|
FossilRepo >> wikiRoot [
|
|
|
|
^ self jsonRoot addPathSegment: 'wiki'
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #wiki }
|
|
|
|
FossilRepo >> wikiTimeline [
|
2017-06-09 07:42:57 +00:00
|
|
|
^ NeoJSONReader fromString: (self jsonWikiDataFor: 'timeline')
|
2017-06-01 12:12:11 +00:00
|
|
|
]
|