@@ -1,8 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="18"
android-versionName="0.1.8"
<widget android-versionCode="110"
android-versionName="0.1.10"
id="io.cozy.files-client"
version="0.1.8"
version="0.1.10"
xmlns="http://www.w3.org/ns/widgets"
xmlns:cdv="http://cordova.apache.org/ns/1.0">

@@ -41,11 +41,12 @@ module.exports =

@replicator.init (err, config) =>
if err
log.error err.message, err.stack
log.error err
return alert err.message or err

@notificationManager = new Notifications()
@serviceManager = new ServiceManager()
# Monkey patch for browser debugging
unless window.isBrowserDebugging
@notificationManager = new Notifications()
@serviceManager = new ServiceManager()

$('body').empty().append @layout.render().$el
Backbone.history.start()
@@ -73,7 +74,7 @@ module.exports =
app.backFromOpen = false
app.replicator.startRealtime()
else
app.replicator.backup {}, (err) -> log.error err.message if err
app.replicator.backup {}, (err) -> log.error err if err
, false
document.addEventListener "pause", =>
log.info "PAUSE EVENT"
@@ -89,11 +90,11 @@ module.exports =
DeviceStatus = require './lib/device_status'
DeviceStatus.update()
backup = () ->
app.replicator.backup {}, (err) -> log.error err.message if err
app.replicator.backup {}, (err) -> log.error err if err
window.removeEventListener 'realtime:onChange', backup, false
window.addEventListener 'realtime:onChange', backup, false
, false

@router.navigate 'folder/', trigger: true
@router.once 'collectionfetched', =>
app.replicator.backup {}, (err) -> log.error err.message if err
app.replicator.backup {}, (err) -> log.error err if err
@@ -148,14 +148,14 @@ module.exports = class FileAndFolderCollection extends Backbone.Collection
FileAndFolderCollection.cache[path] = items unless err
app.replicator.folderInFileSystem path, (err, incache) ->
return cb new Error('cancelled') if @cancelled
log.error err.message if err
log.error err if err
folder.set 'incache', incache

setImmediate cb # don't freeze UI

, (err) =>
return if @cancelled
log.error err.message if err
log.error err if err

# memcache the parent
path = (@path or '').split('/')[0..-2].join('/')
@@ -1,10 +1,13 @@

callbacks = []
initialized = false
readyForSync = null
readyForSyncMsg = ""
battery = null

log = require('/lib/persistent_log')
prefix: "device status"
date: true

callbackWaiting = (err, ready, msg) ->
readyForSync = ready
readyForSyncMsg = msg
@@ -15,11 +18,14 @@ module.exports.update = update = ->
return unless battery?

unless (battery.level > 20 or battery.isPlugged)
log.info "NOT ready on battery low."
return callbackWaiting null, false, 'no battery'
if app.replicator.config.get('syncOnWifi') and
(not (navigator.connection.type is Connection.WIFI))
return callbackWaiting null, false, 'no wifi'
(not (navigator.connection.type is Connection.WIFI))
log.info "NOT ready on no wifi."
return callbackWaiting null, false, 'no wifi'

log.info "ready to sync."
callbackWaiting null, true

module.exports.checkReadyForSync = (force, callback) ->
@@ -30,7 +30,12 @@ class Logger


stringify: (text) ->
if text instanceof Object
if text instanceof Error
err = text
text = err.message
if err.stack?
text += "\n" + err.stack
else if text instanceof Object
text = JSON.stringify text
return text

@@ -60,7 +60,7 @@ module.exports = class Replicator extends Backbone.Model
# pings the cozy to check the credentials without creating a device
checkCredentials: (config, callback) ->
request.post
uri: "https://#{config.cozyURL}/login"
uri: "#{@config.getScheme()}://#{config.cozyURL}/login"
json:
username: 'owner'
password: config.password
@@ -80,7 +80,7 @@ module.exports = class Replicator extends Backbone.Model
# Register the device in cozy.
registerRemote: (config, callback) ->
request.post
uri: "https://#{config.cozyURL}/device/",
uri: "#{@config.getScheme()}://#{config.cozyURL}/device/",
auth:
username: 'owner'
password: config.password
@@ -104,7 +104,7 @@ module.exports = class Replicator extends Backbone.Model
username: config.deviceName
password: body.password
fullRemoteURL:
"https://#{config.deviceName}:#{body.password}" +
"#{@config.getScheme()}://#{config.deviceName}:#{body.password}" +
"@#{config.cozyURL}/cozy"

@config.save config, callback
@@ -51,15 +51,15 @@ module.exports =
(cb) =>
@syncPictures force, (err) ->
if err
log.error "in syncPictures: ", err.message
log.error "in syncPictures: ", err
errors.push err
cb()
(cb) =>
status = DeviceStatus.getStatus()
if status.readyForSync
@syncCache (err) ->
if err
log.error "in syncCache", err.message
log.error "in syncCache", err
errors.push err
cb()
else
@@ -70,7 +70,7 @@ module.exports =
if status.readyForSync
@syncContacts (err) ->
if err
log.error "in syncContacts", err.message
log.error "in syncContacts", err
errors.push err
cb()
else
@@ -1,6 +1,6 @@
basic = require '../lib/basic'

APP_VERSION = "0.1.9"
APP_VERSION = "0.1.10"

module.exports = class ReplicatorConfig extends Backbone.Model
constructor: (@replicator) ->
@@ -37,10 +37,18 @@ module.exports = class ReplicatorConfig extends Backbone.Model
@remote = @createRemotePouchInstance()
callback? null, this

getScheme: () ->
# Monkey patch for browser debugging
if window.isBrowserDebugging
return 'http'
else
return 'https'


makeUrl: (path) ->
json: true
auth: @get 'auth'
url: 'https://' + @get('cozyURL') + '/cozy' + path
url: "#{@getScheme()}://" + @get('cozyURL') + '/cozy' + path

makeFilterName: -> @get('deviceId') + '/filter'

@@ -56,6 +56,7 @@ module.exports =

# Update contact in pouchDB with specified contact from phone.
# @param phoneContact cordova contact format.
# @param retry retry lighter update after a failed one.
_updateInPouch: (phoneContact, callback) ->
async.parallel
fromPouch: (cb) =>
@@ -66,7 +67,7 @@ module.exports =
, (err, res) =>
return callback err if err

# _.extend : Keeps no android compliant data of the 'cozy'-contact
# _.extend : Keeps not android compliant data of the 'cozy'-contact
contact = _.extend res.fromPouch, res.fromPhone

if contact._attachments?.picture?
@@ -78,14 +79,18 @@ module.exports =
picture.revpos = oldPicture.revpos
else
picture.revpos = 1 + parseInt contact._rev.split('-')[0]

@db.put contact, contact._id, contact._rev, (err, idNrev) =>
if err
if err.status is 409 # conflict, bad _rev
log.error "UpdateInPouch, immediate conflict with \
#{contact._id}.", err
# no error, no undirty, will try again next step.
return callback null
else if err.message is "Some query argument is invalid"
log.error "While retrying update contact in pouch"
, err
# Continue with next one.
return callback null
else
return callback err

@@ -94,6 +99,7 @@ module.exports =

# Create a new contact in app's pouchDB from newly created phone contact.
# @param phoneContact cordova contact format.
# @param retry retry lighter update after a failed one.
_createInPouch: (phoneContact, callback) ->
Contact.cordova2Cozy phoneContact, (err, fromPhone) =>
contact = _.extend
@@ -105,7 +111,15 @@ module.exports =
contact._attachments.picture.revpos = 1

@db.post contact, (err, idNrev) =>
return callback err if err
if err
if err.message is "Some query argument is invalid"
log.error "While retrying create contact in pouch"
, err
# Continue with next one.
return callback null
else
return callback err

@_undirty phoneContact, idNrev, callback


@@ -41,7 +41,7 @@ module.exports = Service =
@replicator = new Replicator()
@replicator.init (err, config) =>
if err
log.error err.message, err.stack
log.error err
return window.service.workDone()

if config.remote
@@ -57,7 +57,7 @@ module.exports = Service =


delayedQuit = (err) ->
log.error err.message if err
log.error err if err
# give some time to finish and close things.
setTimeout ->
# call this javabinding directly on object to avoid
@@ -81,7 +81,7 @@ document.addEventListener 'deviceready', ->
Service.initialize()

catch error
log.error 'EXCEPTION SERVICE INITIALIZATION : ', err.message
log.error 'EXCEPTION SERVICE INITIALIZATION : ', err

finally
# "Watchdog" : in all cases, kill service after 10'
@@ -43,6 +43,12 @@ module.exports = class ConfigView extends BaseView

# only happens after the first config (post install)
configDone: ->
log.info 'starting first replication'
app.replicator.initialReplication (err) ->
if err
log.error err
alert t err.message

app.router.navigate 'first-sync', trigger: true


@@ -53,7 +59,9 @@ module.exports = class ConfigView extends BaseView
app.replicator.set 'inSync', true # run the spinner
app.replicator.set 'backup_step', 'destroying database'
app.replicator.destroyDB (err) =>
return alert err.message if err
if err
log.error err
return alert err.message
$('#redbtn').text t 'done'
window.location.reload(true);

@@ -63,7 +71,10 @@ module.exports = class ConfigView extends BaseView
#@TODO delete device on remote ?
app.router.navigate 'first-sync', trigger: true
app.replicator.resetSynchro (err) =>
return alert err.message if err
if err
log.error err
return alert err.message


sendlogBtn: ->
query =
@@ -39,15 +39,12 @@ module.exports = class DeviceNamePickerView extends BaseView
$('#btn-save').text t 'registering...'
app.replicator.registerRemote config, (err) =>
if err?
log.error err
@displayError t err.message
else
delete app.loginConfig
app.isFirstRun = true

log.info 'starting first replication'
app.replicator.initialReplication (err) ->
alert t err.message if err

app.router.navigate 'config', trigger: true

onCompleteDefaultValue: ->
@@ -64,7 +64,10 @@ module.exports = class FolderLineView extends BaseView
callback = callback or ->
return (err, url) =>
@hideProgress()
return alert t(err.message) if err

if err
log.error err
return alert t(err.message)
@model.set incache: true
@model.set version: app.replicator.fileVersion @model.attributes
callback(err, url)
@@ -91,8 +94,8 @@ module.exports = class FolderLineView extends BaseView
(err) ->
if 0 is err?.indexOf 'No Activity found'
err = t 'no activity found'
alert err
log.error err.message
alert err.message
log.error err

addToCache: =>
return true if @downloading
@@ -26,8 +26,8 @@ module.exports = class Menu extends BaseView
sync: ->
return if app.replicator.get 'inSync'
app.replicator.sync {}, (err) ->
log.error err.message, err.stack if err
if err
log.error err
alert t if err.message? then err.message else "no connection"
app.layout.currentView?.collection?.fetch()

@@ -43,7 +43,7 @@ module.exports = class Menu extends BaseView
else
app.replicator.backup { force: false }, (err) =>
if err
log.error err.message, err.stack
log.error err
alert t err.message
return

@@ -43,7 +43,7 @@ module.exports = class Notifications
markAsShown: (notification) =>
app.replicator.db.remove notification, (err) ->
if err
log.error "Error while removing notification.", err.message
log.error "Error while removing notification.", err

showNotification: (notification) =>
# generate id : android require an 'int' id, we generate it from the