<commit_before>WORK ON PROGRESS, but it works.

Ruby on Rails plugin (gem) for managing repositories (files/folders/permissions). 

# RepositoryManager

This project is based on the need for a repository manager system for [Collaide](https://github.com/facenord-sud/collaide). A system for easily create/delete files and folders in a repository. For share these repositories easily with other object with a flexible and complete authorisations management. 

Instead of creating my core repository manager system heavily
dependent on our development, I'm trying to implement a generic and potent repository gem.

After looking for a good gem to use I noticed the lack of repository gems
and flexibility in them. RepositoryManager tries to be the more flexible possible.
Each instance (users, groups, etc..) can have it own repositories (with files and folders). It can manage them easily (edit, remove, add, etc) and share them with other instance.

This gem is my informatics project for the Master in [University of Lausanne (CH)](http://www.unil.ch/index.html). 

## Installation


Add to your Gemfile:

```ruby
gem 'repository-manager'
```

Then run:

```sh
$ bundle update
```

Run install script:

```sh
$ rails g repository_manager:install
```

And don't forget to migrate your database:

```sh
$ rake db:migrate
```

## Preparing your models

You can choose wich model can have repository. 

In your model:

```ruby
class User < ActiveRecord::Base
  has_repository
end
```

You are not limited to the User model. You can use RepositoryManager in any other model and use it in serveral different models. If you have Groups and Houses in your application and you want to exchange repositories as if they were the same, just add `has_repository` to each one and you will be able to share files/folders groups-groups, groups-users, users-groups and users-users. Of course, you can extend it for as many classes as you need.

Example:

```ruby
class User < ActiveRecord::Base
  has_repository
end
```

```ruby
class Group < ActiveRecord::Base
  has_repository
end
```

## How to use RepositoryManager

### How can I create/delete a repository (file or folder)

You just have to call the method `createFile`, `createFolder`, or `deleteRepository`.

```ruby
# user1 wants to create a folder in his repository

# Create a root folder on the user1 repository (you can have how many roots as you want)
sourceFolder = createFolder('Root folder')

# user1 own repository :
#   'Root folder'

# sourceFolder is the directory in wich user1 wants to create the folder 'The new folder'
name = 'The new folder'
theFolder = user1.createFolder(name, sourceFolder)

# user1 own repository :
#   'Root folder'
#     'The new folder'

# Now we want to add a file into theFolder 
# Note : user1 needs the ':can_create => true' permission in the folder : theFolder
user1.createFile(params[:file], theFolder)
# OR
#user1.createFile(File.open('somewhere'), theFolder)

# user1 own repository :
#   'Root folder'
#     'The new folder'
#        'file'

file2 = user1.createFile(params[:file2])

# user1 own repository :
#   'Root folder'
#     'The new folder'
#        'file'
#   'file2'

# Delete a repository
# Note : user1 needs the ':can_delete => true' permission in the folder : theFolder
user1.deleteRepository(theFolder)

# user1 own repository :
#   'Root folder'
#   'file2'

user1.deleteRepository(file2)

# user1 own repository :
#   'Root folder'

```

### How can I share a repository (file/folder)

Now, user1 want to share his folder 'The new folder' with a Group object et another User object.

```ruby
# user1 wants to share theFolder with group1 and user2

items = []
# You can add other instance (who has_repository) in this array to share with more than one instance
item << group1
items << user2

# Default shares permisions are : {can_add: false, can_remove: false} 
share_permissions = {can_add: true, can_remove: true}
# Default reposiroty permissions are: {can_read: false, can_create: false, can_update:false, can_delete:false, can_share: false}
repo_permissions = {can_read: true, can_create: true, can_update:true, can_delete:true, can_share: true}

share = user1.share(theFolder, items, repo_permissions, share_permissions)
```

`share_permissions` specifies if the item who receive the share can add or remove items in this share.

`repo_permissions` specifies what kind of permission do you give at this share. If all the params are false (as_default), the share is useless, because the items have no more permissions in the repository selectionned. 

See the chapter Authorisations for more details.

### How can I see my repository

There is two king of repository: 
- Your own repositories
- The repositories shared with you.

```ruby
# user1 want to get his own repository
user1.repositories.all # => You get the repository that user1 has created

# user2 want to get his shared repository
user2.shares_repositories.all
```

A repository can be:
- A file
- A folder

```ruby
# We want to know if the object repository is a file or a folder:
if repository.type == 'Folder'
  repository.name #=> Returns the name of the folder ('New folder').
elsif repository.type == 'AppFile'
  repository.name #=> Returns the name of the file ('file.png').
  # Here is the file
  repository.file.url # => '/url/to/file.png'
  repository.file.current_path # => 'path/to/file.png'
  repository.file.identifier # => 'file.png'
```


### How can I manage a share


If it has the authorisation, an object can add items to a share.

```ruby
# user1 want to add items to his share (the actions are done only if user1 has the ':can_add' permission)
user1.can_add_to_share(share) # => true

share_permissions = {can_add: true, can_remove: false}
# Add items
items = []
items << user3
items << group2
...<commit_msg>add file field in repositories<commit_after>WORK ON PROGRESS, but it works.

Ruby on Rails plugin (gem) for managing repositories (files/folders/permissions). 

# RepositoryManager

This project is based on the need for a repository manager system for [Collaide](https://github.com/facenord-sud/collaide). A system for easily create/delete files and folders in a repository. For share these repositories easily with other object with a flexible and complete authorisations management. 

Instead of creating my core repository manager system heavily
dependent on our development, I'm trying to implement a generic and potent repository gem.

After looking for a good gem to use I noticed the lack of repository gems
and flexibility in them. RepositoryManager tries to be the more flexible possible.
Each instance (users, groups, etc..) can have it own repositories (with files and folders). It can manage them easily (edit, remove, add, etc) and share them with other instance.

This gem is my informatics project for the Master in [University of Lausanne (CH)](http://www.unil.ch/index.html). 

## Installation


Add to your Gemfile:

```ruby
gem 'repository-manager'
```

Then run:

```sh
$ bundle update
```

Run install script:

```sh
$ rails g repository_manager:install
```

And don't forget to migrate your database:

```sh
$ rake db:migrate
```

## Preparing your models

You can choose wich model can have repository. 

In your model:

```ruby
class User < ActiveRecord::Base
  has_repository
end
```

You are not limited to the User model. You can use RepositoryManager in any other model and use it in serveral different models. If you have Groups and Houses in your application and you want to exchange repositories as if they were the same, just add `has_repository` to each one and you will be able to share files/folders groups-groups, groups-users, users-groups and users-users. Of course, you can extend it for as many classes as you need.

Example:

```ruby
class User < ActiveRecord::Base
  has_repository
end
```

```ruby
class Group < ActiveRecord::Base
  has_repository
end
```

## How to use RepositoryManager

### How can I create/delete a repository (file or folder)

You just have to call the method `createFile`, `createFolder`, or `deleteRepository`.

```ruby
# user1 wants to create a folder in his repository

# Create a root folder on the user1 repository (you can have how many roots as you want)
sourceFolder = createFolder('Root folder')

# user1 own repository :
#   'Root folder'

# sourceFolder is the directory in wich user1 wants to create the folder 'The new folder'
name = 'The new folder'
theFolder = user1.createFolder(name, sourceFolder)

# user1 own repository :
#   'Root folder'
#     'The new folder'

# Now we want to add a file into theFolder 
# Note : user1 needs the ':can_create => true' permission in the folder : theFolder
user1.createFile(params[:file], theFolder)
# OR
#user1.createFile(File.open('somewhere'), theFolder)

# user1 own repository :
#   'Root folder'
#     'The new folder'
#        'file'

file2 = user1.createFile(params[:file2])

# user1 own repository :
#   'Root folder'
#     'The new folder'
#        'file'
#   'file2'

# Delete a repository
# Note : user1 needs the ':can_delete => true' permission in the folder : theFolder
user1.deleteRepository(theFolder)

# user1 own repository :
#   'Root folder'
#   'file2'

user1.deleteRepository(file2)

# user1 own repository :
#   'Root folder'

```

### How can I share a repository (file/folder)

Now, user1 want to share his folder 'The new folder' with a Group object et another User object.

```ruby
# user1 wants to share theFolder with group1 and user2

items = []
# You can add other instance (who has_repository) in this array to share with more than one instance
item << group1
items << user2

# Default shares permisions are : {can_add: false, can_remove: false} 
share_permissions = {can_add: true, can_remove: true}
# Default reposiroty permissions are: {can_read: false, can_create: false, can_update:false, can_delete:false, can_share: false}
repo_permissions = {can_read: true, can_create: true, can_update:true, can_delete:true, can_share: true}

share = user1.share(theFolder, items, repo_permissions, share_permissions)
```

`share_permissions` specifies if the item who receive the share can add or remove items in this share.

`repo_permissions` specifies what kind of permission do you give at this share. If all the params are false (as_default), the share is useless, because the items have no more permissions in the repository selectionned. 

See the chapter Authorisations for more details.

### How can I see my repository

There is two king of repository: 
- Your own repositories
- The repositories shared with you.

```ruby
# user1 want to get his own repository
user1.repositories.all # => You get the repository that user1 has created

# user2 want to get his shared repository
user2.shares_repositories.all
```

A repository can be:
- A file
- A folder

```ruby
# We want to know if the object repository is a file or a folder:
if repository.type == 'Folder'
  repository.name #=> Returns the name of the folder ('New folder').
elsif repository.type == 'AppFile'
  repository.name #=> Returns the name of the file ('file.png').
  # Here is the file
  repository.file.url # => '/url/to/file.png'
  repository.file.current_path # => 'path/to/file.png'
  repository.file.identifier # => 'file.png'
end
```


### How can I manage a share


If it has the authorisation, an object can add items to a share.

```ruby
# user1 want to add items to his share (the actions are done only if user1 has the ':can_add' permission)
user1.can_add_to_share(share) # => true

share_permissions = {can_add: true, can_remove: false}
# Add items
items = []
items << user3
items << group2
...
{'fraction_non_alphanumeric': 0.08663515255694026, 'fraction_numerical': 0.0067039106145251395, 'mean_word_length': 4.337614678899082, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7402598', 'n_tokens_mistral': 3453, 'n_tokens_neox': 3294, 'n_words': 1521}