Skip to content

Commit

Permalink
Merge pull request #114 from nono/refactoring_bis
Browse files Browse the repository at this point in the history
Big refactoring for readonly mode
  • Loading branch information
Frank Rousseau committed Nov 2, 2015
2 parents 997d139 + 666a561 commit 0775244
Show file tree
Hide file tree
Showing 74 changed files with 4,956 additions and 3,062 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/backend/*.js
/backend/**/*.js
/bin/cli.js
/build
/cache
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
sudo: false
language: node_js
matrix:
fast_finish: true
allow_failures:
- node_js: 0.12
- node_js: 4
node_js:
- 0.10
Expand Down
48 changes: 35 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ The Cozy desktop app allows to sync the files stored in your Cozy with your lapt
and/or your desktop. It replicates your files on your hard drive and apply
changes you made on them on other synced devices and on your online Cozy.


## CLI Install

The cozy-desktop requires node.js and build tools to run
The cozy-desktop requires node.js (at least version 0.10) and build tools.
For example, you can install them on debian with:

sudo apt-get install nodejs-legacy build-essential

Then you can install it via NPM:
Then you can install cozy-desktop via NPM:

sudo npm install cozy-desktop -g

## CLI Running

```bash
# Configure it with your remote Cozy
cozy-desktop add-remote-cozy http://url.of.my.cozy devicename /sync/directory
### CLI Running

# Then start synchronization daemon:
cozy-desktop sync
```
Configure it with your remote Cozy

cozy-desktop add-remote-cozy http://url.of.my.cozy devicename /sync/directory

Then start synchronization daemon:

cozy-desktop sync

Other commands can be listed with

Expand Down Expand Up @@ -86,9 +89,15 @@ To hack the synchronization backend, you can just edit the files under the
[![Build
Status](https://travis-ci.org/cozy-labs/cozy-desktop.png?branch=master)](https://travis-ci.org/cozy-labs/cozy-desktop)

Tests require that you have the Cozy dev VM up (it means a data-system and a
proxy up and running) and that the files application is accessible on the 9121
port. It's also expected that a user is registered.
There are several levels of tests in cozy-desktop:

- unit tests, for testing a class in isolation, method per method
- functional tests, for testing a behaviour that requires the collaboration of
several classes, but still in a mock environment
- integration tests, to test the communication between cozy-desktop and a
remote cozy stack (proxy, data-system, files, etc.)

Unit and functional tests are easy to launch:

```
# Make sure to have dev dependencies installed
Expand All @@ -99,9 +108,22 @@ node_modules/.bin/gulp test
# To run a specific set of tests (here testing local_watcher with DEBUG activated)
npm install -g mocha
DEBUG=true DEFAULT_DIR=tests mocha --compilers coffee:coffee-script/register tests/local_watcher.coffee
DEBUG=true DEFAULT_DIR=tmp mocha --compilers coffee:coffee-script/register tests/unit/pouch.coffee
# Or, if you want pouchdb to be really verbose
DEBUG=pouchdb:api DEFAULT_DIR=tmp mocha --compilers coffee:coffee-script/register tests/unit/pouch.coffee
```

Integration tests require that you have the Cozy dev VM up (it means a
data-system and a proxy up and running) and that the files application is
accessible on the 9121 port. It's also expected that a user is registered with
`cozytest` as password.

```
DEFAULT_DIR=tmp mocha --compilers coffee:coffee-script/register tests/integration/*.coffee
```


## What is Cozy?

![Cozy Logo](https://raw.github.com/cozy/cozy-setup/gh-pages/assets/images/happycloud.png)
Expand Down
101 changes: 42 additions & 59 deletions backend/app.coffee
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
fs = require 'fs-extra'
EventEmitter = require('events').EventEmitter
path = require 'path-extra'
async = require 'async'
log = require('printit')
prefix: 'Cozy Desktop '

filesystem = require '../backend/filesystem'
pouch = require '../backend/db'
device = require '../backend/device'
localEventWatcher = require '../backend/local_event_watcher'
remoteEventWatcher = require '../backend/remote_event_watcher'
Config = require './config'
Devices = require './devices'
Pouch = require './pouch'
Merge = require './merge'
Local = require './local'
Remote = require './remote'
Sync = require './sync'


# App is the entry point for the CLI and GUI.
# They both can do actions and be notified by events via an App instance.
#
# basePath is the directory where the config and pouch are saved
class App

# basePath is the directory where the config and pouch are saved
constructor: (basePath) ->
@lang = 'fr'
@basePath = basePath or path.homedir()
@config = require './config'
# TODO @config.init @basePath
@config = new Config @basePath
@events = new EventEmitter
@pouch = new Pouch @config

# This method is here to be surcharged by the UI
# to ask its password to the user
#
# callback is a function that takes two parameters: error and password
askPassword: (callback) ->
callback 'Not implemented', null
callback new Error('Not implemented'), null


# Register current device to remote Cozy and then save related informations
Expand All @@ -37,46 +40,40 @@ class App
addRemote: (url, deviceName, syncPath) =>
async.waterfall [
@askPassword,

(password, next) ->
options =
url: url
deviceName: deviceName
password: password
device.registerDevice options, next

Devices.registerDevice options, next
], (err, credentials) =>
if err
log.error err
log.error 'An error occured while registering your device.'
else
options =
path: path.resolve syncPath
url: url
deviceName: deviceName
path: path.resolve syncPath
deviceId: credentials.id
devicePassword: credentials.password
password: credentials.password
@config.addRemoteCozy options
log.info 'The remote Cozy has properly been configured ' +
'to work with current device.'


# Unregister current device from remote Cozy and then remove remote from
# the config file
# TODO also remove the pouch database
removeRemote: (deviceName) =>
remoteConfig = @config.getConfig()
deviceName = deviceName or @config.getDeviceName()

device = @config.getDevice deviceName
async.waterfall [
@askPassword,

(password, next) ->
options =
url: remoteConfig.url
deviceId: remoteConfig.deviceId
url: device.url
deviceId: device.deviceId
password: password
device.unregisterDevice options, saveConfig

Devices.unregisterDevice options, next
], (err) =>
if err
log.error err
Expand All @@ -88,60 +85,46 @@ class App

# Start database sync process and setup file change watcher
sync: (mode) =>
syncToCozy = true
switch mode
when 'readonly' then syncToCozy = false
else
log.error "Unknown mode for sync: #{mode}"
return

config = @config.getConfig()

if config.deviceName? and config.url? and config.path?
fs.ensureDir config.path, ->
pouch.addAllFilters ->
remoteEventWatcher.init syncToCozy, ->
log.info "Init done"
remoteEventWatcher.start ->
if syncToDesktop
localEventWatcher.start()
@merge = new Merge @pouch
@local = new Local @config, @merge, @pouch, @events
@remote = new Remote @config, @merge, @pouch, @events
@sync = new Sync @pouch, @local, @remote, @events
device = @config.getDevice()
if device.deviceName? and device.url? and device.path?
log.info 'Run first synchronisation...'
@sync.start mode, (err) ->
if err
log.error err
log.error err.stack if err.stack
process.exit 1 # TODO don't exit for GUI
else
log.error 'No configuration found, please run add-remote-cozy' +
'command before running a synchronization.'


# Recreate the local pouch database
resetDatabase: (callback) ->
resetDatabase: (callback) =>
log.info "Recreates the local database..."
pouch.resetDatabase ->
@pouch.resetDatabase ->
log.info "Database recreated"
callback?()


# Return the whole content of the database
allDocs: (callback) ->
pouch.db.allDocs include_docs: true, (err, results) ->
log.info err if err
callback err, results
allDocs: (callback) =>
@pouch.db.allDocs include_docs: true, callback


# Return all docs for a given query
query: (query, callback) ->
log.info "Query: #{query}"
pouch.db.query query, (err, results) ->
log.error err if err
callback err, results
query: (query, callback) =>
@pouch.db.query query, include_docs: true, callback


# Get useful information about the disk space
# (total, used and left) on the remote Cozy
getDiskSpace: (callback) =>
remoteConfig = @config.getConfig()
options =
url: remoteConfig.url
user: remoteConfig.deviceName
password: remoteConfig.devicePassword
device.getDiskSpace options, callback
device = @config.getDevice
Devices.getDiskSpace device, callback


module.exports = App
Loading

0 comments on commit 0775244

Please sign in to comment.