diff --git a/admin/sync/exercices.go b/admin/sync/exercices.go index 7d5069d3..28383804 100644 --- a/admin/sync/exercices.go +++ b/admin/sync/exercices.go @@ -9,6 +9,7 @@ import ( "srs.epita.fr/fic-server/libfic" ) +// getExercices returns all exercice directories existing in a given theme, considering the given Importer. func getExercices(i Importer, theme fic.Theme) ([]string, error) { var exercices []string @@ -25,6 +26,7 @@ func getExercices(i Importer, theme fic.Theme) ([]string, error) { return exercices, nil } +// findResolutionMovie searchs a resolution movie across a given exercice path. func findResolutionMovie(i Importer, exPath string) (videoURI string, err error) { var files []string @@ -42,6 +44,7 @@ func findResolutionMovie(i Importer, exPath string) (videoURI string, err error) return } +// SyncExercices imports new or updates existing exercices, in a given theme. func SyncExercices(i Importer, theme fic.Theme) []string { var errs []string @@ -162,6 +165,7 @@ func SyncExercices(i Importer, theme fic.Theme) []string { return errs } +// ApiListRemoteExercices is an accessor letting foreign packages to access remote exercices list. func ApiListRemoteExercices(theme fic.Theme, _ []byte) (interface{}, error) { return getExercices(GlobalImporter, theme) } diff --git a/admin/sync/file.go b/admin/sync/file.go index 3afac7cb..4b6195d3 100644 --- a/admin/sync/file.go +++ b/admin/sync/file.go @@ -24,15 +24,22 @@ type Importer interface { exists(filename string) bool // toURL gets the full path/URL to the given file, the Importer will look internaly (used for debuging purpose). toURL(filename string) string - // importFile imports the file at the given URI + // importFile imports the file at the given URI, inside the global FILES/ directory. + // Then calls back the next function, with the downloaded location and the original URI. + // Callback return is forwarded. importFile(URI string, next func(string, string) (interface{}, error)) (interface{}, error) + // getFile write to the given buffer, the file at the given location. getFile(filename string, writer *bufio.Writer) error + // listDir returns a list of the files and subdirectories contained inside the directory at the given location. listDir(filename string) ([]string, error) + // stat returns many information about the given file: such as last modification date, size, ... stat(filename string) (os.FileInfo, error) } +// GlobalImporter stores the main importer instance to use for global imports. var GlobalImporter Importer +// getFile helps to manage huge file transfert by concatenating splitted (with split(1)) files. func getFile(i Importer, URI string, writer *bufio.Writer) error { // Import file if it exists if i.exists(URI) { @@ -67,7 +74,7 @@ func getFile(i Importer, URI string, writer *bufio.Writer) error { return errors.New(fmt.Sprintf("%q: no such file or directory", URI)) } -// getFileContent +// getFileContent retrieves the content of the given text file. func getFileContent(i Importer, URI string) (string, error) { cnt := bytes.Buffer{} diff --git a/admin/sync/full.go b/admin/sync/full.go index b8d4c348..19b3ae76 100644 --- a/admin/sync/full.go +++ b/admin/sync/full.go @@ -13,8 +13,10 @@ import ( "srs.epita.fr/fic-server/settings" ) +// oneDeepSync ensure there is no more than one running deep sync. var oneDeepSync sync.Mutex +// SyncDeep performs a recursive synchronisation: from themes to challenge items. func SyncDeep(i Importer) (errs map[string][]string) { oneDeepSync.Lock() defer oneDeepSync.Unlock() diff --git a/admin/sync/importer_cloud.go b/admin/sync/importer_cloud.go index 07b8406f..70811e6d 100644 --- a/admin/sync/importer_cloud.go +++ b/admin/sync/importer_cloud.go @@ -12,12 +12,20 @@ import ( "github.com/studio-b12/gowebdav" ) +// CloudImporter implements an Importer, where files to imports are located +// remotely, under a WebDAV server (such as sabre/dav, owncloud, ...). type CloudImporter struct { + // baseDAV is the URL (most probably http or https one) to the root directory. + // It should contains all themes, in separated directories. baseDAV url.URL + // username is the username used to perform authentication through BasicAuth. username string + // password is the password used to perform authentication through BasicAuth. password string } +// NewCloudImporter registers a new object CloudImporter, as the URL conversion +// can returns errors. func NewCloudImporter(baseDAV string, username string, password string) (*CloudImporter, error) { if r, err := url.Parse(baseDAV); err != nil { return nil, err diff --git a/admin/sync/importer_localfs.go b/admin/sync/importer_localfs.go index fe8c6530..6fe32cfa 100644 --- a/admin/sync/importer_localfs.go +++ b/admin/sync/importer_localfs.go @@ -7,8 +7,13 @@ import ( "path" ) +// LocalImporter implements an Importer, where files to imports are located +// inside a local directory from your filesystem. type LocalImporter struct { + // Base is the root directory used by the LocalImporter. It should contains all themes. Base string + // Symlink changes the normal file copy/concatenate behaviour to symlink/concatenate. + // If enable, your base directory must be accessible by the frontend processus as it will follow the symlink. Symlink bool } diff --git a/admin/sync/themes.go b/admin/sync/themes.go index 7126c2cf..063fd1de 100644 --- a/admin/sync/themes.go +++ b/admin/sync/themes.go @@ -9,6 +9,7 @@ import ( "github.com/julienschmidt/httprouter" ) +// getThemes returns all theme directories in the base directory. func getThemes(i Importer) ([]string, error) { var themes []string @@ -25,6 +26,7 @@ func getThemes(i Importer) ([]string, error) { return themes, nil } +// getAuthors parses the AUTHORS file. func getAuthors(i Importer, tname string) ([]string, error) { if authors, err := getFileContent(i, path.Join(tname, "AUTHORS.txt")); err != nil { return nil, err @@ -33,6 +35,7 @@ func getAuthors(i Importer, tname string) ([]string, error) { } } +// SyncThemes imports new or updates existing themes. func SyncThemes(i Importer) []string { var errs []string @@ -73,10 +76,12 @@ func SyncThemes(i Importer) []string { return errs } +// ApiListRemoteThemes is an accessor letting foreign packages to access remote themes list. func ApiListRemoteThemes(_ httprouter.Params, _ []byte) (interface{}, error) { return getThemes(GlobalImporter) } +// ApiListRemoteTheme is an accessor letting foreign packages to access remote main theme attributes. func ApiGetRemoteTheme(ps httprouter.Params, _ []byte) (interface{}, error) { return getAuthors(GlobalImporter, ps.ByName("thid")) } diff --git a/libfic/member.go b/libfic/member.go index 66921f19..f517af0a 100644 --- a/libfic/member.go +++ b/libfic/member.go @@ -34,6 +34,7 @@ func (t Team) GetMembers() ([]Member, error) { } } +// AddMember creates and fills a new struct Member and registers it into the database. func (t Team) AddMember(firstname string, lastname string, nickname string, company string) (Member, error) { if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.Id, firstname, lastname, nickname, company); err != nil { return Member{}, err @@ -44,6 +45,7 @@ func (t Team) AddMember(firstname string, lastname string, nickname string, comp } } +// GainMember associates (or registers, it if it doesn't exists yet) a member to the team. func (t Team) GainMember(m Member) error { if m.Id == 0 { if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.Id, m.Firstname, m.Lastname, m.Nickname, m.Company); err != nil { @@ -62,6 +64,7 @@ func (t Team) GainMember(m Member) error { } } +// Update applies modifications back to the database. func (m Member) Update() (int64, error) { if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.Id); err != nil { return 0, err @@ -72,6 +75,7 @@ func (m Member) Update() (int64, error) { } } +// Delete the member from the database. func (m Member) Delete() (int64, error) { if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.Id); err != nil { return 0, err @@ -82,6 +86,7 @@ func (m Member) Delete() (int64, error) { } } +// ClearMembers deletes members in the team. func (t Team) ClearMembers() (int64, error) { if res, err := DBExec("DELETE FROM team_members WHERE id_team = ?", t.Id); err != nil { return 0, err