<commit_before>"""
    Eventually the creation of new indicators should be part of a UI. This is a temporary solution.
"""

def _make_qid(question_id, version):
    return {
        'question_id': question_id,
        'version': version,
    }

CHILD_VISIT_QUESTION_IDS = {
    'immediate_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.immediate_danger_sign', 1),
        'mvp-potou': _make_qid('patient_available.immediate_danger_sign', 1),
    },
    'emergency_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.emergency_danger_sign', 1),
        'mvp-potou': _make_qid('patient_available.emergency_danger_sign', 1),
    },
    'visit_hospital': {
        'mvp-sauri': _make_qid('visit_hospital', 1),
        'mvp-potou': _make_qid('visit_hospital', 1),
    },
    'rdt_result': {
        'mvp-sauri': _make_qid('patient_available.referral_follow_on.rdt_result', 1),
        'mvp-potou': _make_qid('patient_available.referral_follow_on.rdt_result', 1),
    },
    'fever_medication': {
        'mvp-sauri': _make_qid('patient_available.fever_medication', 1),
        'mvp-potou': _make_qid('patient_available.medication_type', 1),
    },
    'diarrhea_medication': {
        'mvp-sauri': _make_qid('patient_available.diarrhea_medication', 1),
        'mvp-potou': _make_qid('patient_available.medication_type', 1),
    },
    'referral_type': {
        'mvp-sauri': _make_qid('patient_available.referral_type', 1),
        'mvp-potou': _make_qid('patient_available.referral_type', 1),
    },
    'muac': {
        'mvp-sauri': _make_qid('patient_available.muac', 1),
        'mvp-potou': _make_qid('patient_available.muac', 1),
    },
    'exclusive_breastfeeding': {
        'mvp-sauri': _make_qid('group_counseling.exclusive_breastfeeding', 1),
        'mvp-potou': _make_qid('group_counseling.exclusive_breastfeeding', 1),
    },
}

PREGNANCY_VISIT_QUESTION_IDS = {
    'immediate_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.immediate_danger_sign', 1),
        'mvp-potou': _make_qid('immediate_danger_sign', 1),
    },
    'emergency_danger_sign': {
        'mvp-sauri': _make_qid('emergency_danger_sign', 1),
        'mvp-potou': _make_qid('emergency_danger_sign', 1),
    },
    'prev_num_anc': {
        'mvp-sauri': _make_qid('group_counseling.prev_num_anc', 1),
        'mvp-potou': _make_qid('prev_num_anc', 1),
    },
    'num_anc': {
        'mvp-sauri': _make_qid('group_counseling.num_anc', 1),
        'mvp-potou': _make_qid('group_counseling.num_anc', 1),
    },
    'last_anc_date': {
        'mvp-sauri': _make_qid('group_counseling.last_anc_date', 1),
    },
    'last_anc_weeks': {
        'mvp-potou': _make_qid('group_counseling.last_anc_weeks', 1),
    },
    'referral_type': {
        'mvp-sauri': _make_qid('group_referral_dangersign.referral_type', 1),
        'mvp-potou': _make_qid('group_referral_dangersign.referral_type', 1),
    },
}

HOUSEHOLD_VISIT_QUESTION_IDS = {
    'num_using_fp': {
        'mvp-sauri': _make_qid('num_using_fp', 1),
        'mvp-potou': _make_qid('num_using_fp', 1),
    },
    'num_ec': {
        'mvp-sauri': _make_qid('num_ec', 1),
        'mvp-potou': _make_qid('num_ec', 1),
    },
}

CHILD_CLOSE_FORM_QUESTION_IDS = {
    'close_reason': {
        'mvp-sauri': _make_qid('reason', 2),
        'mvp-potou': _make_qid('reason', 2),
    },
    'date_of_death': {
        'mvp-sauri': _make_qid('date_of_death', 2),
        'mvp-potou': _make_qid('date_of_death', 2),
    },
}

PREGNANCY_CLOSE_FORM_QUESTION_IDS = dict(
    close_reason={
        'mvp-sauri': _make_qid('close_reason', 2),
        'mvp-potou': _make_qid('close_reason', 2),
    },
    termination_reason={
        'mvp-sauri': _make_qid('termination_reason', 1),
        'mvp-potou': _make_qid('termination_reason', 1),
    },
    pregnancy_termination={
        'mvp-sauri': _make_qid('date_of_termination', 1),
        'mvp-potou': _make_qid('date_of_termination', 1),
        }
)
<commit_msg>changed question IDs after a back and forth with nick<commit_after>"""
    Eventually the creation of new indicators should be part of a UI. This is a temporary solution.
"""

def _make_qid(question_id, version):
    return {
        'question_id': question_id,
        'version': version,
    }

CHILD_VISIT_QUESTION_IDS = {
    'immediate_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.immediate_danger_sign', 1),
        'mvp-potou': _make_qid('patient_available.immediate_danger_sign', 1),
    },
    'emergency_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.emergency_danger_sign', 1),
        'mvp-potou': _make_qid('patient_available.emergency_danger_sign', 1),
    },
    'visit_hospital': {
        'mvp-sauri': _make_qid('visit_hospital', 1),
        'mvp-potou': _make_qid('visit_hospital', 1),
    },
    'rdt_result': {
        'mvp-sauri': _make_qid('patient_available.referral_follow_on.rdt_result', 1),
        'mvp-potou': _make_qid('patient_available.referral_follow_on.rdt_result', 1),
    },
    'fever_medication': {
        'mvp-sauri': _make_qid('patient_available.fever_medication', 1),
        'mvp-potou': _make_qid('patient_available.medication_type', 1),
    },
    'diarrhea_medication': {
        'mvp-sauri': _make_qid('patient_available.diarrhea_medication', 1),
        'mvp-potou': _make_qid('patient_available.medication_type', 1),
    },
    'referral_type': {
        'mvp-sauri': _make_qid('patient_available.referral_type', 1),
        'mvp-potou': _make_qid('patient_available.referral_type', 1),
    },
    'muac': {
        'mvp-sauri': _make_qid('patient_available.muac', 1),
        'mvp-potou': _make_qid('patient_available.muac', 1),
    },
    'exclusive_breastfeeding': {
        'mvp-sauri': _make_qid('group_counseling.exclusive_breastfeeding', 1),
        'mvp-potou': _make_qid('group_counseling.exclusive_breastfeeding', 1),
    },
}

PREGNANCY_VISIT_QUESTION_IDS = {
    'immediate_danger_sign': {
        'mvp-sauri': _make_qid('patient_available.immediate_danger_sign', 1),
        'mvp-potou': _make_qid('immediate_danger_sign', 1),
    },
    'emergency_danger_sign': {
        'mvp-sauri': _make_qid('emergency_danger_sign', 1),
        'mvp-potou': _make_qid('emergency_danger_sign', 1),
    },
    'prev_num_anc': {
        'mvp-sauri': _make_qid('prev_num_anc', 2),
        'mvp-potou': _make_qid('prev_cur_num_anc', 2),
    },
    'num_anc': {
        'mvp-sauri': _make_qid('group_counseling.num_anc', 1),
        'mvp-potou': _make_qid('group_referral_dangersign.num_anc', 2),
    },
    'last_anc_date': {
        'mvp-sauri': _make_qid('group_counseling.last_anc_date', 1),
    },
    'last_anc_weeks': {
        'mvp-potou': _make_qid('group_referral_dangersign.last_anc_weeks', 2),
    },
    'referral_type': {
        'mvp-sauri': _make_qid('group_referral_dangersign.referral_type', 1),
        'mvp-potou': _make_qid('group_referral_dangersign.referral_type', 1),
    },
}

HOUSEHOLD_VISIT_QUESTION_IDS = {
    'num_using_fp': {
        'mvp-sauri': _make_qid('num_using_fp', 1),
        'mvp-potou': _make_qid('num_using_fp', 1),
    },
    'num_ec': {
        'mvp-sauri': _make_qid('num_ec', 1),
        'mvp-potou': _make_qid('num_ec', 1),
    },
}

CHILD_CLOSE_FORM_QUESTION_IDS = {
    'close_reason': {
        'mvp-sauri': _make_qid('reason', 2),
        'mvp-potou': _make_qid('reason', 2),
    },
    'date_of_death': {
        'mvp-sauri': _make_qid('date_of_death', 2),
        'mvp-potou': _make_qid('date_of_death', 2),
    },
}

PREGNANCY_CLOSE_FORM_QUESTION_IDS = dict(
    close_reason={
        'mvp-sauri': _make_qid('close_reason', 2),
        'mvp-potou': _make_qid('close_reason', 2),
    },
    termination_reason={
        'mvp-sauri': _make_qid('termination_reason', 1),
        'mvp-potou': _make_qid('termination_reason', 1),
    },
    pregnancy_termination={
        'mvp-sauri': _make_qid('date_of_termination', 1),
        'mvp-potou': _make_qid('date_of_termination', 1),
        }
)
<|endoftext|>


<commit_before>#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4

import sys
import os
import subprocess
import time

def try_compile(source):
    """ Accepts source file name, tries to figure out what it is and compile
    it. Returns the executable command for running the compiled (or not
    compiled) program and potentially a filename to cleanup
    """
    sourcepath = source.split('/')
    (basename, extension) = sourcepath[-1].rpartition(".")[::2]

    comp = None
    output = None
    executable = source

    if extension == "cpp":
        comp = "g++ -o %s %s" % (basename, source)
        executable = "./%s" % basename
        output = basename

    elif extension == "c":
        comp = "gcc -o %s %s" % (basename, source)
        executable = "./%s" % basename
        output = basename

    elif extension == "java":
        comp = "cp %s . ; javac %s.java" % (source, basename)
        executable = "java %s" % basename
        output = "%s.class" % basename

    elif extension == "frink":
        executable = "/home/ubuntu/cnc_2012/grader/frink %s" % source

    else:
        # assume interpreted
        comp = "chmod u+x %s" % source
        if len(sourcepath) < 2:
            executable = "./%s" % source

    # if we have a compile command, run it
    if comp:
        comp_cmd = subprocess.Popen(comp, shell=True, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        # TODO: timeout rather than wait forever
        if comp_cmd.wait():
            print "Compilation failed"
            (out, err) = comp_cmd.communicate()
            print out
            print err
            sys.exit(1)

    return executable, output

def main(source, input_file, output_file=None):
    # TODO: take submissions with a makefile
    # TODO: take submissions as a tarball
    # TODO: run tests in a chroot

    executable, output = try_compile(source)

    executable = "%s < %s" % (executable, input_file)

#    if output_file:
#        executable = "%s | diff -Bb - %s" % (executable, output_file)

    # Run the test program
    exec_cmd = subprocess.Popen(executable, shell=True, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
    # 60-second time limit
    ret = exec_cmd.poll()
    i = 0
    while i < 60 and ret == None:
        i += 1
        ret = exec_cmd.poll()
        time.sleep(1)

    result = 0

    if ret == None:
        # timeout. kill process and fail
        exec_cmd.kill()
        print "Execution timed out"
        result = 2
    elif ret:
        # program execution failed
        print "Program execution failed with return code %d"%ret
        result = 2
    else:
        if output_file:
            (out, err) = exec_cmd.communicate()
            diff_cmd = subprocess.Popen("diff -Bb - %s"%output_file,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                    stdin=subprocess.PIPE, shell=True)
            (diff_out, diff_err) = diff_cmd.communicate(out)
            ret = diff_cmd.wait()
            if ret:
                print "%s failed test"%source
                result = 2
            else:
                print "%s passed"%source
        else:
            print "%s passed"%source

#    # TODO: timeout rather than wait forever
#    if exec_cmd.wait():
#        print "Execution failed"
#        (out, err) = exec_cmd.communicate()
#        #print out
#        #print err
#        if output:
#            os.remove(output)
#        sys.exit(2)
#
#    print "%s passed" % source
    if output:
        os.remove(output)

    sys.exit(result)

if __name__ == '__main__':
    if len(sys.argv) < 3 or len(sys.argv) > 4:
        print "Usage: grade.py <source> <input> [output]"

    main(*sys.argv[1:])
<commit_msg>Try harder to kill timed-out processes.<commit_after>#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4

import sys
import os
import subprocess
import time

def try_compile(source):
    """ Accepts source file name, tries to figure out what it is and compile
    it. Returns the executable command for running the compiled (or not
    compiled) program and potentially a filename to cleanup
    """
    sourcepath = source.split('/')
    (basename, extension) = sourcepath[-1].rpartition(".")[::2]

    comp = None
    output = None
    executable = source

    if extension == "cpp":
        comp = "g++ -o %s %s" % (basename, source)
        executable = "./%s" % basename
        output = basename

    elif extension == "c":
        comp = "gcc -o %s %s" % (basename, source)
        executable = "./%s" % basename
        output = basename

    elif extension == "java":
        comp = "cp %s . ; javac %s.java" % (source, basename)
        executable = "java %s" % basename
        output = "%s.class" % basename

    elif extension == "frink":
        executable = "/home/ubuntu/cnc_2012/grader/frink %s" % source

    else:
        # assume interpreted
        comp = "chmod u+x %s" % source
        if len(sourcepath) < 2:
            executable = "./%s" % source

    # if we have a compile command, run it
    if comp:
        comp_cmd = subprocess.Popen(comp, shell=True, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
        # TODO: timeout rather than wait forever
        if comp_cmd.wait():
            print "Compilation failed"
            (out, err) = comp_cmd.communicate()
            print out
            print err
            sys.exit(1)

    return executable, output

def main(source, input_file, output_file=None):
    # TODO: take submissions with a makefile
    # TODO: take submissions as a tarball
    # TODO: run tests in a chroot

    executable, output = try_compile(source)

    executable = "%s < %s" % (executable, input_file)

#    if output_file:
#        executable = "%s | diff -Bb - %s" % (executable, output_file)

    # Run the test program
    exec_cmd = subprocess.Popen(executable, shell=True, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
    # 60-second time limit
    ret = exec_cmd.poll()
    i = 0
    while i < 60 and ret == None:
        i += 1
        ret = exec_cmd.poll()
        time.sleep(1)

    result = 0

    if ret == None:
        # timeout. kill process and fail
        exec_cmd.kill()
        print "Execution timed out"
        ret = exec_cmd.poll()
        while ret == None:
           exec_cmd.send_signal(9)
           time.sleep(1)
           ret = exec_cmd.poll()
        result = 2
    elif ret:
        # program execution failed
        print "Program execution failed with return code %d"%ret
        result = 2
    else:
        if output_file:
            (out, err) = exec_cmd.communicate()
            diff_cmd = subprocess.Popen("diff -Bb - %s"%output_file,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                    stdin=subprocess.PIPE, shell=True)
            (diff_out, diff_err) = diff_cmd.communicate(out)
            ret = diff_cmd.wait()
            if ret:
                print "%s failed test"%source
                result = 2
            else:
                print "%s passed"%source
        else:
            print "%s passed"%source

    if output:
        os.remove(output)

    sys.exit(result)

if __name__ == '__main__':
    if len(sys.argv) < 3 or len(sys.argv) > 4:
        print "Usage: grade.py <source> <input> [output]"

    main(*sys.argv[1:])
<|endoftext|>


<commit_before>from nanopore.metaAnalyses.abstractUnmappedAnalysis import AbstractUnmappedMetaAnalysis
import os, sys
from jobTree.src.bioio import system
from itertools import product

class UnmappedKmerAnalysis(AbstractUnmappedMetaAnalysis):
    """Calculates kmer statistics for all reads (in all samples) not mapped by any mapper
    """

    def countKmers(self, seq):
        kmers = Counter()
        for i in xrange(kmerSize, len(seq)):
            if "N" not in seq[ i - kmerSize : i ]:
                kmers[ seq[ i - kmerSize : i ] ] += 1
        return kmers

    def run(self, kmer_size=5):
        for readType in self.readTypes:
            mappedKmers, unmappedKmers = Counter(), Counter()
            for read in self.reads:
                if read.readType == readType and read.is_mapped:
                    mappedKmers += countKmers(read.seq)
                elif read.readType == readType
                    unmappedKmers += countKmers(read.seq)

            mappedSize, unmappedSize = sum(mappedKmers.values()), sum(unmappedKmers.values())
            outf = open(os.path.join(self.getLocalTempDir(), "kmer_counts.txt"), "w")
            outf.write("kmer\trefCount\trefFraction\treadCount\treadFraction\tfoldChange\n")
            for kmer in itertools.product("ATGC",repeat=5):
                kmer = "".join(kmer)
                refFraction, readFraction = 1.0 * refKmers[kmer] / refSize, 1.0 * readKmers[kmer] / readSize
                foldChange = -log(readFraction / refFraction)
                outf.write("\t".join(map(str,[kmer, refKmers[kmer], refFraction, readKmers[kmer], readFraction, foldChange]))+"\n")
            outf.close()

        system("Rscript nanopore/analyses/kmer_analysis.R {} {}".format(os.path.join(self.getLocalTempDir(), "kmer_counts.txt"), os.path.join(self.outputDir, readType + "kmer_counts.txt")))
<commit_msg>typo again<commit_after>from nanopore.metaAnalyses.abstractUnmappedAnalysis import AbstractUnmappedMetaAnalysis
import os, sys
from jobTree.src.bioio import system
from itertools import product

class UnmappedKmerAnalysis(AbstractUnmappedMetaAnalysis):
    """Calculates kmer statistics for all reads (in all samples) not mapped by any mapper
    """

    def countKmers(self, seq):
        kmers = Counter()
        for i in xrange(kmerSize, len(seq)):
            if "N" not in seq[ i - kmerSize : i ]:
                kmers[ seq[ i - kmerSize : i ] ] += 1
        return kmers

    def run(self, kmer_size=5):
        for readType in self.readTypes:
            mappedKmers, unmappedKmers = Counter(), Counter()
            for read in self.reads:
                if read.readType == readType and read.is_mapped:
                    mappedKmers += countKmers(read.seq)
                elif read.readType == readType:
                    unmappedKmers += countKmers(read.seq)

            mappedSize, unmappedSize = sum(mappedKmers.values()), sum(unmappedKmers.values())
            outf = open(os.path.join(self.getLocalTempDir(), "kmer_counts.txt"), "w")
            outf.write("kmer\trefCount\trefFraction\treadCount\treadFraction\tfoldChange\n")
            for kmer in itertools.product("ATGC",repeat=5):
                kmer = "".join(kmer)
                refFraction, readFraction = 1.0 * refKmers[kmer] / refSize, 1.0 * readKmers[kmer] / readSize
                foldChange = -log(readFraction / refFraction)
                outf.write("\t".join(map(str,[kmer, refKmers[kmer], refFraction, readKmers[kmer], readFraction, foldChange]))+"\n")
            outf.close()

        system("Rscript nanopore/analyses/kmer_analysis.R {} {}".format(os.path.join(self.getLocalTempDir(), "kmer_counts.txt"), os.path.join(self.outputDir, readType + "kmer_counts.txt")))
<|endoftext|>


<commit_before>from django.core.urlresolvers import reverse

from rest_framework import test

from nodeconductor.backup import models, backup_registry
from nodeconductor.backup.tests import factories
from nodeconductor.structure.tests import factories as structure_factories

def _backup_url(backup, action=None):
    url = 'http://testserver' + reverse('backup-detail', args=(str(backup.uuid), ))
    return url if action is None else url + action + '/'

def _backup_list_url():
    return 'http://testserver' + reverse('backup-list')

def _backup_schedule_url(schedule, action=None):
    url = 'http://testserver' + reverse('backupschedule-detail', args=(str(schedule.uuid), ))
    return url if action is None else url + action + '/'

def _backup_schedule_list_url():
    return 'http://testserver' + reverse('backupschedule-list')

class BackupUsageTest(test.APISimpleTestCase):

    def setUp(self):
        # only for test lets make backupshedule backupable
        backup_registry.BACKUP_REGISTRY = {'Schedule': 'backup_backupschedule'}
        self.user = structure_factories.UserFactory.create(is_staff=True, is_superuser=True)
        self.client.force_authenticate(user=self.user)

    def test_backup_manually_create(self):
        # success:
        backupable = factories.BackupScheduleFactory()
        backup_data = {
            'backup_source': _backup_schedule_url(backupable),
        }
        url = _backup_list_url()
        response = self.client.post(url, data=backup_data)
        self.assertEqual(response.status_code, 201)
        backup = models.Backup.objects.get(object_id=backupable.id)
        self.assertEqual(backup.state, models.Backup.States.BACKING_UP)
        # fail:
        backup_data = {
            'backup_source': 'some_random_url',
        }
        url = _backup_list_url()
        response = self.client.post(url, data=backup_data)
        self.assertEqual(response.status_code, 400)
        self.assertIn('backup_source', response.content)

    def test_backup_restore(self):
        backup = factories.BackupFactory()
        url = _backup_url(backup, action='restore')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(models.Backup.objects.get(pk=backup.pk).state, models.Backup.States.RESTORING)

    def test_backup_delete(self):
        backup = factories.BackupFactory()
        url = _backup_url(backup, action='delete')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(models.Backup.objects.get(pk=backup.pk).state, models.Backup.States.DELETING)

class BackupScheduleUsageTest(test.APISimpleTestCase):

    def setUp(self):
        # only for test lets make backupshedule backupable
        backup_registry.BACKUP_REGISTRY = {'Schedule': 'backup_backupschedule'}
        self.user = structure_factories.UserFactory.create(is_staff=True, is_superuser=True)
        self.client.force_authenticate(user=self.user)

    def test_backup_schedule_creation(self):
        backupable = factories.BackupScheduleFactory()
        backup_schedule_data = {
            'retention_time': 3,
            'backup_source': _backup_schedule_url(backupable),
            'schedule': '*/5 * * * *',
            'maximal_number_of_backups': 3,
        }
        response = self.client.post(_backup_schedule_list_url(), backup_schedule_data)
        self.assertEqual(response.status_code, 201)
        backup_schedule = models.BackupSchedule.objects.get(object_id=backupable.id)
        self.assertEqual(backup_schedule.retention_time, backup_schedule_data['retention_time'])
        self.assertEqual(backup_schedule.maximal_number_of_backups, backup_schedule_data['maximal_number_of_backups'])
        self.assertEqual(backup_schedule.schedule, backup_schedule_data['schedule'])

    def test_schedule_activation_and_deactivation(self):
        schedule = factories.BackupScheduleFactory(is_active=False)
        # activate
        response = self.client.post(_backup_schedule_url(schedule, action='activate'))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(models.BackupSchedule.objects.get(pk=schedule.pk).is_active)
        # deactivate
        response = self.client.post(_backup_schedule_url(schedule, action='deactivate'))
        self.assertEqual(response.status_code, 200)
        self.assertFalse(models.BackupSchedule.objects.get(pk=schedule.pk).is_active)
<commit_msg>test_backup_schedule_creation erros cases added<commit_after>from django.core.urlresolvers import reverse

from rest_framework import test

from nodeconductor.backup import models, backup_registry
from nodeconductor.backup.tests import factories
from nodeconductor.structure.tests import factories as structure_factories

def _backup_url(backup, action=None):
    url = 'http://testserver' + reverse('backup-detail', args=(str(backup.uuid), ))
    return url if action is None else url + action + '/'

def _backup_list_url():
    return 'http://testserver' + reverse('backup-list')

def _backup_schedule_url(schedule, action=None):
    url = 'http://testserver' + reverse('backupschedule-detail', args=(str(schedule.uuid), ))
    return url if action is None else url + action + '/'

def _backup_schedule_list_url():
    return 'http://testserver' + reverse('backupschedule-list')

class BackupUsageTest(test.APISimpleTestCase):

    def setUp(self):
        # only for test lets make backupshedule backupable
        backup_registry.BACKUP_REGISTRY = {'Schedule': 'backup_backupschedule'}
        self.user = structure_factories.UserFactory.create(is_staff=True, is_superuser=True)
        self.client.force_authenticate(user=self.user)

    def test_backup_manually_create(self):
        # success:
        backupable = factories.BackupScheduleFactory()
        backup_data = {
            'backup_source': _backup_schedule_url(backupable),
        }
        url = _backup_list_url()
        response = self.client.post(url, data=backup_data)
        self.assertEqual(response.status_code, 201)
        backup = models.Backup.objects.get(object_id=backupable.id)
        self.assertEqual(backup.state, models.Backup.States.BACKING_UP)
        # fail:
        backup_data = {
            'backup_source': 'some_random_url',
        }
        url = _backup_list_url()
        response = self.client.post(url, data=backup_data)
        self.assertEqual(response.status_code, 400)
        self.assertIn('backup_source', response.content)

    def test_backup_restore(self):
        backup = factories.BackupFactory()
        url = _backup_url(backup, action='restore')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(models.Backup.objects.get(pk=backup.pk).state, models.Backup.States.RESTORING)

    def test_backup_delete(self):
        backup = factories.BackupFactory()
        url = _backup_url(backup, action='delete')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(models.Backup.objects.get(pk=backup.pk).state, models.Backup.States.DELETING)

class BackupScheduleUsageTest(test.APISimpleTestCase):

    def setUp(self):
        # only for test lets make backupshedule backupable
        backup_registry.BACKUP_REGISTRY = {'Schedule': 'backup_backupschedule'}
        self.user = structure_factories.UserFactory.create(is_staff=True, is_superuser=True)
        self.client.force_authenticate(user=self.user)

    def test_backup_schedule_creation(self):
        backupable = factories.BackupScheduleFactory()
        backup_schedule_data = {
            'retention_time': 3,
            'backup_source': _backup_schedule_url(backupable),
            'schedule': '*/5 * * * *',
            'maximal_number_of_backups': 3,
        }
        response = self.client.post(_backup_schedule_list_url(), backup_schedule_data)
        self.assertEqual(response.status_code, 201)
        backup_schedule = models.BackupSchedule.objects.get(object_id=backupable.id)
        self.assertEqual(backup_schedule.retention_time, backup_schedule_data['retention_time'])
        self.assertEqual(backup_schedule.maximal_number_of_backups, backup_schedule_data['maximal_number_of_backups'])
        self.assertEqual(backup_schedule.schedule, backup_schedule_data['schedule'])
        # wrong schedule:
        backup_schedule_data['schedule'] = 'wrong schedule'
        response = self.client.post(_backup_schedule_list_url(), backup_schedule_data)
        self.assertEqual(response.status_code, 400)
        self.assertIn('schedule', response.content)
        # wrong backup source:
        backup_schedule_data['schedule'] = '*/5 * * * *'
        backup = factories.BackupFactory()
        unbackupable_url = 'http://testserver' + reverse('backup-detail', args=(backup.uuid, ))
        backup_schedule_data['backup_source'] = unbackupable_url
        response = self.client.post(_backup_schedule_list_url(), backup_schedule_data)
        self.assertEqual(response.status_code, 400)
        self.assertIn('backup_source', response.content)

    def test_schedule_activation_and_deactivation(self):
        schedule = factories.BackupScheduleFactory(is_active=False)
        # activate
        response = self.client.post(_backup_schedule_url(schedule, action='activate'))
        self.assertEqual(response.status_code, 200)
        self.assertTrue(models.BackupSchedule.objects.get(pk=schedule.pk).is_active)
        # deactivate
        response = self.client.post(_backup_schedule_url(schedule, action='deactivate'))
        self.assertEqual(response.status_code, 200)
        self.assertFalse(models.BackupSchedule.objects.get(pk=schedule.pk).is_active)
<|endoftext|>


<commit_before>"""
Test LocalClient with native FS operations and specific OS ones.
See win_local_client.py and mac_local_client.py for more informations.
"""
from time import sleep

import hashlib
import os
from unittest import skipIf

from nxdrive.client import LocalClient, NotFound
from nxdrive.osi import AbstractOSIntegration
from tests.common import EMPTY_DIGEST, SOME_TEXT_CONTENT, SOME_TEXT_DIGEST
from tests.common_unit_test import UnitTestCase

try:
    from exceptions import WindowsError
except ImportError:
    WindowsError = IOError

class StubLocalClient(object):
    """ All tests goes here. If you need to implement a special behavior for
        one OS, override the test method in the class TestLocalClientSimulation.
        Check TestLocalClientSimulation.test_complex_filenames() for a real
        world example.
    """

    def test_make_documents(self):
        doc_1 = self.local_client_1.make_file('/', 'Document 1.txt')
        self.assertTrue(self.local_client_1.exists(doc_1))
        self.assertEqual(self.local_client_1.get_content(doc_1), b'')
        doc_1_info = self.local_client_1.get_info(doc_1)
        self.assertEqual(doc_1_info.name, 'Document 1.txt')
        self.assertEqual(doc_1_info.path, doc_1)
        self.assertEqual(doc_1_info.get_digest(), EMPTY_DIGEST)
        self.assertEqual(doc_1_info.folderish, False)

        doc_2 = self.local_client_1.make_file('/', 'Document 2.txt',
                                              content=SOME_TEXT_CONTENT)
        self.assertTrue(self.local_client_1.exists(doc_2))
        self.assertEqual(self.local_client_1.get_content(doc_2),
                         SOME_TEXT_CONTENT)
        doc_2_info = self.local_client_1.get_info(doc_2)
        self.assertEqual(doc_2_info.name, 'Document 2.txt')
        self.assertEqual(doc_2_info.path, doc_2)
        self.assertEqual(doc_2_info.get_digest(), SOME_TEXT_DIGEST)
        self.assertEqual(doc_2_info.folderish, False)

        self.local_client_1.delete(doc_2)
        self.assertTrue(self.local_client_1.exists(doc_1))
        self.assertFalse(self.local_client_1.exists(doc_2))

        folder_1 = self.local_client_1.make_folder('/', 'A new folder')
        self.assertTrue(self.local_client_1.exists(folder_1))
        folder_1_info = self.local_client_1.get_info(folder_1)
        self.assertEqual(folder_1_info.name, 'A new folder')
        self.assertEqual(folder_1_info.path, folder_1)
        self.assertEqual(folder_1_info.get_digest(), None)
        self.assertEqual(folder_1_info.folderish, True)

        doc_3 = self.local_client_1.make_file(folder_1, 'Document 3.txt',
                                              content=SOME_TEXT_CONTENT)
        self.local_client_1.delete(folder_1)
        self.assertFalse(self.local_client_1.exists(folder_1))
        self.assertFalse(self.local_client_1.exists(doc_3))

    def test_get_info_invalid_date(self):
        doc_1 = self.local_client_1.make_file('/', 'Document 1.txt')
        os.utime(self.local_client_1._abspath(
                os.path.join('/', 'Document 1.txt')), (0, 999999999999999))
        doc_1_info = self.local_client_1.get_info(doc_1)
        self.assertEqual(doc_1_info.name, 'Document 1.txt')
        self.assertEqual(doc_1_info.path, doc_1)
        self.assertEqual(doc_1_info.get_digest(), EMPTY_DIGEST)
        self.assertEqual(doc_1_info.folderish, False)

    def test_complex_filenames(self):
        # create another folder with the same title
        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_1 = self.local_client_1.make_folder('/', title_with_accents)
        folder_1_info = self.local_client_1.get_info(folder_1)
        self.assertEqual(folder_1_info.name, title_with_accents)

        # create another folder with the same title
        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_2 = self.local_client_1.make_folder('/', title_with_accents)
        folder_2_info = self.local_client_1.get_info(folder_2)
        self.assertEqual(folder_2_info.name, title_with_accents + u"__1")
        self.assertNotEqual(folder_1, folder_2)

        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_3 = self.local_client_1.make_folder('/', title_with_accents)
        folder_3_info = self.local_client_1.get_info(folder_3)
        self.assertEqual(folder_3_info.name, title_with_accents + u"__2")
        self.assertNotEqual(folder_1, folder_3)

        # Create a long file name with weird chars
        long_filename = u"\xe9" * 50 + u"%$#!()[]{}+_-=';&^" + u".doc"
        file_1 = self.local_client_1.make_file(folder_1, long_filename)
        file_1 = self.local_client_1.get_info(file_1)
        self.assertEqual(file_1.name, long_filename)
        self.assertEqual(file_1.path, folder_1_info.path + u"/" + long_filename)

        # Create a file with invalid chars
        invalid_filename = u"a/b\\c*d:e<f>g?h\"i|j.doc"
        escaped_filename = u"a-b-c-d-e-f-g-h-i-j.doc"
        file_2 = self.local_client_1.make_file(folder_1, invalid_filename)
        file_2 = self.local_client_1.get_info(file_2)
        self.assertEqual(file_2.name, escaped_filename)
        self.assertEqual(
                file_2.path, folder_1_info.path + u'/' + escaped_filename)

    def test_missing_file(self):
        with self.assertRaises(NotFound):
            self.local_client_1.get_info('/Something Missing')

    def test_get_children_info(self):
        folder_1 = self.local_client_1.make_folder('/', 'Folder 1')
        folder_2 = self.local_client_1.make_folder('/', 'Folder 2')
        file_1 = self.local_client_1.make_file('/', 'File 1.txt',
                                               content=b'foo\n')

        # not a direct child of '/'
        self.local_client_1.make_file(folder_1, 'File 2.txt', content=b'bar\n')

        # ignored files
        data = b'baz\n'
        self.local_client_1.make_file('/', '.File 2.txt', content=data)
        self.local_client_1.make_file('/', '~$File 2.txt', content=data)
        self.local_client_1.make_file('/', 'File 2.txt~', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.swp', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.lock', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.LOCK', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.part', content=data)
        self.local_client_1.make_file('/', '.File 2.txt.nxpart', content=data)

        workspace_children = self.local_client_1.get_children_info('/')
        self.assertEqual(len(workspace_children), 3)
        self.assertEqual(workspace_children[0].path, file_1)
        self.assertEqual(workspace_children[1].path, folder_1)
        self.assertEqual(workspace_children[2].path, folder_2)

    def test_deep_folders(self):
        # Check that local client can workaround the default >indows
        # MAX_PATH limit
        folder = '/'
        for _i in range(30):
            folder = self.local_client_1.make_folder(folder, '0123456789')

        # Last Level
        last_level_folder_info = self.local_client_1.get_info(folder)
        self.assertEqual(last_level_folder_info.path, '/0123456789' * 30)

        # Create a nested file
        deep_file = self.local_client_1.make_file(folder, 'File.txt',
                                                  content=b'Some Content.')

        # Check the consistency of  get_children_info and get_info
        deep_file_info = self.local_client_1.get_info(deep_file)
        deep_children = self.local_client_1.get_children_info(folder)
        self.assertEqual(len(deep_children), 1)
        deep_child_info = deep_children[0]
        self.assertEqual(deep_file_info.name, deep_child_info.name)
        self.assertEqual(deep_file_info.path, deep_child_info.path)
        self.assertEqual(deep_file_info.get_digest(),
                         deep_child_info.get_digest())

        # Update the file content
        self.local_client_1.update_content(deep_file, b'New Content.')
        self.assertEqual(self.local_client_1.get_content(deep_file),
                         b'New Content.')

        # Delete the folder
        self.local_client_1.delete(folder)
        self.assertFalse(self.local_client_1.exists(folder))
        self.assertFalse(self.local_client_1.exists(deep_file))

        # Delete the root folder and descendants
        self.local_client_1.delete('/0123456789')
        self.assertFalse(self.local_client_1.exists('/0123456789'))

    def test_get_new_file(self):
        path, os_path, name = self.local_client_1.get_new_file('/',
                                                               'Document 1.txt')
        self.assertEqual(path, '/Document 1.txt')
        self.assertTrue(os_path.endswith(os.path.join(self.workspace_title,
                                                      'Document 1.txt')))
        self.assertEqual(name, 'Document 1.txt')
        self.assertFalse(self.local_client_1.exists(path))
        self.assertFalse(os.path.exists(os_path))

    def test_xattr(self):
        ref = self.local_client_1.make_file('/', 'File 2.txt', content=b'baz\n')
        path = self.local_client_1._abspath(ref)
        mtime = int(os.path.getmtime(path))
        sleep(1)
        self.local_client_1.set_remote_id(ref, 'TEST')
        self.assertTrue(mtime == int(os.path.getmtime(path)))
        sleep(1)
        self.local_client_1.remove_remote_id(ref)
        self.assertTrue(mtime == int(os.path.getmtime(path)))

    def test_get_path(self):
        abs_path = os.path.join(self.local_nxdrive_folder_1,
                                self.workspace_title,
                                'Test doc.txt')
        self.assertEqual(self.local_client_1.get_path(abs_path),
                         '/Test doc.txt')

    def test_is_equal_digests(self):
        content = b'joe'
        local_path = self.local_client_1.make_file('/', 'File.txt',
                                                   content=content)
        local_digest = hashlib.md5(content).hexdigest()
        # Equal digests
        self.assertTrue(self.local_client_1.is_equal_digests(local_digest,
                                                             local_digest,
                                                             local_path))

        # Different digests with same digest algorithm
        other_content = b'jack'
        remote_digest = hashlib.md5(other_content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertFalse(self.local_client_1.is_equal_digests(local_digest,
                                                              remote_digest,
                                                              local_path))

        # Different digests with different digest algorithms but same content
        remote_digest = hashlib.sha1(content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertTrue(self.local_client_1.is_equal_digests(local_digest,
                                                             remote_digest,
                                                             local_path))

        # Different digests with different digest algorithms and different
        # content
        remote_digest = hashlib.sha1(other_content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertFalse(self.local_client_1.is_equal_digests(local_digest,
                                                              remote_digest,
                                                              local_path))

class TestLocalClientNative(StubLocalClient, UnitTestCase):
    """ Test LocalClient using native python commands to make FS operations.
        This will simulate Drive actions.
    """

    def setUp(self):
        super(TestLocalClientNative, self).setUp()
        self.engine_1.start()
        self.wait_sync()

    def get_local_client(self, path):
        return LocalClient(path)

@skipIf(AbstractOSIntegration.is_linux(),
        'GNU/Linux uses native LocalClient.')
class TestLocalClientSimulation(StubLocalClient, UnitTestCase):
    """ Test LocalClient using OS specific commands to make FS operations.
        This will simulate user actions on:
            - Explorer (Windows)
            - File Manager (macOS)
    """

    def setUp(self):
        super(TestLocalClientSimulation, self).setUp()
        self.engine_1.start()
        self.wait_sync()

    def test_complex_filenames(self):
        """ It should fail on Windows:
            Explorer cannot find the directory as the path is way to long.
        """

        if AbstractOSIntegration.is_windows():
            # IOError: [Errno 2] No such file or directory
            with self.assertRaises(IOError):
                super(TestLocalClientSimulation, self).test_complex_filenames()
        else:
            super(TestLocalClientSimulation, self).test_complex_filenames()

    def test_deep_folders(self):
        """ It should fail on Windows:
            Explorer cannot deal with very long paths.
        """

        if AbstractOSIntegration.is_windows():
            # WindowsError: [Error 206] The filename or extension is too long
            with self.assertRaises(WindowsError):
                super(TestLocalClientSimulation, self).test_deep_folders()
        else:
            super(TestLocalClientSimulation, self).test_deep_folders()
<commit_msg>NXDRIVE-742: Fix test_complex_filenames Windows simulation<commit_after>"""
Test LocalClient with native FS operations and specific OS ones.
See win_local_client.py and mac_local_client.py for more informations.

See NXDRIVE-742.
"""
from time import sleep

import hashlib
import os
from unittest import skipIf

from nxdrive.client import LocalClient, NotFound
from nxdrive.osi import AbstractOSIntegration
from tests.common import EMPTY_DIGEST, SOME_TEXT_CONTENT, SOME_TEXT_DIGEST
from tests.common_unit_test import UnitTestCase

try:
    from exceptions import WindowsError
except ImportError:
    WindowsError = IOError

class StubLocalClient(object):
    """
    All tests goes here. If you need to implement a special behavior for
    one OS, override the test method in the class TestLocalClientSimulation.
    Check TestLocalClientSimulation.test_complex_filenames() for a real
    world example.
    """

    def test_make_documents(self):
        doc_1 = self.local_client_1.make_file('/', 'Document 1.txt')
        self.assertTrue(self.local_client_1.exists(doc_1))
        self.assertEqual(self.local_client_1.get_content(doc_1), b'')
        doc_1_info = self.local_client_1.get_info(doc_1)
        self.assertEqual(doc_1_info.name, 'Document 1.txt')
        self.assertEqual(doc_1_info.path, doc_1)
        self.assertEqual(doc_1_info.get_digest(), EMPTY_DIGEST)
        self.assertEqual(doc_1_info.folderish, False)

        doc_2 = self.local_client_1.make_file('/', 'Document 2.txt',
                                              content=SOME_TEXT_CONTENT)
        self.assertTrue(self.local_client_1.exists(doc_2))
        self.assertEqual(self.local_client_1.get_content(doc_2),
                         SOME_TEXT_CONTENT)
        doc_2_info = self.local_client_1.get_info(doc_2)
        self.assertEqual(doc_2_info.name, 'Document 2.txt')
        self.assertEqual(doc_2_info.path, doc_2)
        self.assertEqual(doc_2_info.get_digest(), SOME_TEXT_DIGEST)
        self.assertEqual(doc_2_info.folderish, False)

        self.local_client_1.delete(doc_2)
        self.assertTrue(self.local_client_1.exists(doc_1))
        self.assertFalse(self.local_client_1.exists(doc_2))

        folder_1 = self.local_client_1.make_folder('/', 'A new folder')
        self.assertTrue(self.local_client_1.exists(folder_1))
        folder_1_info = self.local_client_1.get_info(folder_1)
        self.assertEqual(folder_1_info.name, 'A new folder')
        self.assertEqual(folder_1_info.path, folder_1)
        self.assertEqual(folder_1_info.get_digest(), None)
        self.assertEqual(folder_1_info.folderish, True)

        doc_3 = self.local_client_1.make_file(folder_1, 'Document 3.txt',
                                              content=SOME_TEXT_CONTENT)
        self.local_client_1.delete(folder_1)
        self.assertFalse(self.local_client_1.exists(folder_1))
        self.assertFalse(self.local_client_1.exists(doc_3))

    def test_get_info_invalid_date(self):
        doc_1 = self.local_client_1.make_file('/', 'Document 1.txt')
        os.utime(self.local_client_1._abspath(
                os.path.join('/', 'Document 1.txt')), (0, 999999999999999))
        doc_1_info = self.local_client_1.get_info(doc_1)
        self.assertEqual(doc_1_info.name, 'Document 1.txt')
        self.assertEqual(doc_1_info.path, doc_1)
        self.assertEqual(doc_1_info.get_digest(), EMPTY_DIGEST)
        self.assertEqual(doc_1_info.folderish, False)

    def test_complex_filenames(self):
        # create another folder with the same title
        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_1 = self.local_client_1.make_folder('/', title_with_accents)
        folder_1_info = self.local_client_1.get_info(folder_1)
        self.assertEqual(folder_1_info.name, title_with_accents)

        # create another folder with the same title
        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_2 = self.local_client_1.make_folder('/', title_with_accents)
        folder_2_info = self.local_client_1.get_info(folder_2)
        self.assertEqual(folder_2_info.name, title_with_accents + u"__1")
        self.assertNotEqual(folder_1, folder_2)

        title_with_accents = u"\xc7a c'est l'\xe9t\xe9 !"
        folder_3 = self.local_client_1.make_folder('/', title_with_accents)
        folder_3_info = self.local_client_1.get_info(folder_3)
        self.assertEqual(folder_3_info.name, title_with_accents + u"__2")
        self.assertNotEqual(folder_1, folder_3)

        # Create a long file name with weird chars
        long_filename = u"\xe9" * 50 + u"%$#!()[]{}+_-=';&^" + u".doc"
        file_1 = self.local_client_1.make_file(folder_1, long_filename)
        file_1 = self.local_client_1.get_info(file_1)
        self.assertEqual(file_1.name, long_filename)
        self.assertEqual(file_1.path, folder_1_info.path + u"/" + long_filename)

        # Create a file with invalid chars
        invalid_filename = u"a/b\\c*d:e<f>g?h\"i|j.doc"
        escaped_filename = u"a-b-c-d-e-f-g-h-i-j.doc"
        file_2 = self.local_client_1.make_file(folder_1, invalid_filename)
        file_2 = self.local_client_1.get_info(file_2)
        self.assertEqual(file_2.name, escaped_filename)
        self.assertEqual(
                file_2.path, folder_1_info.path + u'/' + escaped_filename)

    def test_missing_file(self):
        with self.assertRaises(NotFound):
            self.local_client_1.get_info('/Something Missing')

    def test_get_children_info(self):
        folder_1 = self.local_client_1.make_folder('/', 'Folder 1')
        folder_2 = self.local_client_1.make_folder('/', 'Folder 2')
        file_1 = self.local_client_1.make_file('/', 'File 1.txt',
                                               content=b'foo\n')

        # not a direct child of '/'
        self.local_client_1.make_file(folder_1, 'File 2.txt', content=b'bar\n')

        # ignored files
        data = b'baz\n'
        self.local_client_1.make_file('/', '.File 2.txt', content=data)
        self.local_client_1.make_file('/', '~$File 2.txt', content=data)
        self.local_client_1.make_file('/', 'File 2.txt~', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.swp', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.lock', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.LOCK', content=data)
        self.local_client_1.make_file('/', 'File 2.txt.part', content=data)
        self.local_client_1.make_file('/', '.File 2.txt.nxpart', content=data)

        workspace_children = self.local_client_1.get_children_info('/')
        self.assertEqual(len(workspace_children), 3)
        self.assertEqual(workspace_children[0].path, file_1)
        self.assertEqual(workspace_children[1].path, folder_1)
        self.assertEqual(workspace_children[2].path, folder_2)

    def test_deep_folders(self):
        # Check that local client can workaround the default >indows
        # MAX_PATH limit
        folder = '/'
        for _i in range(30):
            folder = self.local_client_1.make_folder(folder, '0123456789')

        # Last Level
        last_level_folder_info = self.local_client_1.get_info(folder)
        self.assertEqual(last_level_folder_info.path, '/0123456789' * 30)

        # Create a nested file
        deep_file = self.local_client_1.make_file(folder, 'File.txt',
                                                  content=b'Some Content.')

        # Check the consistency of  get_children_info and get_info
        deep_file_info = self.local_client_1.get_info(deep_file)
        deep_children = self.local_client_1.get_children_info(folder)
        self.assertEqual(len(deep_children), 1)
        deep_child_info = deep_children[0]
        self.assertEqual(deep_file_info.name, deep_child_info.name)
        self.assertEqual(deep_file_info.path, deep_child_info.path)
        self.assertEqual(deep_file_info.get_digest(),
                         deep_child_info.get_digest())

        # Update the file content
        self.local_client_1.update_content(deep_file, b'New Content.')
        self.assertEqual(self.local_client_1.get_content(deep_file),
                         b'New Content.')

        # Delete the folder
        self.local_client_1.delete(folder)
        self.assertFalse(self.local_client_1.exists(folder))
        self.assertFalse(self.local_client_1.exists(deep_file))

        # Delete the root folder and descendants
        self.local_client_1.delete('/0123456789')
        self.assertFalse(self.local_client_1.exists('/0123456789'))

    def test_get_new_file(self):
        path, os_path, name = self.local_client_1.get_new_file('/',
                                                               'Document 1.txt')
        self.assertEqual(path, '/Document 1.txt')
        self.assertTrue(os_path.endswith(os.path.join(self.workspace_title,
                                                      'Document 1.txt')))
        self.assertEqual(name, 'Document 1.txt')
        self.assertFalse(self.local_client_1.exists(path))
        self.assertFalse(os.path.exists(os_path))

    def test_xattr(self):
        ref = self.local_client_1.make_file('/', 'File 2.txt', content=b'baz\n')
        path = self.local_client_1._abspath(ref)
        mtime = int(os.path.getmtime(path))
        sleep(1)
        self.local_client_1.set_remote_id(ref, 'TEST')
        self.assertTrue(mtime == int(os.path.getmtime(path)))
        sleep(1)
        self.local_client_1.remove_remote_id(ref)
        self.assertTrue(mtime == int(os.path.getmtime(path)))

    def test_get_path(self):
        abs_path = os.path.join(self.local_nxdrive_folder_1,
                                self.workspace_title,
                                'Test doc.txt')
        self.assertEqual(self.local_client_1.get_path(abs_path),
                         '/Test doc.txt')

    def test_is_equal_digests(self):
        content = b'joe'
        local_path = self.local_client_1.make_file('/', 'File.txt',
                                                   content=content)
        local_digest = hashlib.md5(content).hexdigest()
        # Equal digests
        self.assertTrue(self.local_client_1.is_equal_digests(local_digest,
                                                             local_digest,
                                                             local_path))

        # Different digests with same digest algorithm
        other_content = b'jack'
        remote_digest = hashlib.md5(other_content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertFalse(self.local_client_1.is_equal_digests(local_digest,
                                                              remote_digest,
                                                              local_path))

        # Different digests with different digest algorithms but same content
        remote_digest = hashlib.sha1(content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertTrue(self.local_client_1.is_equal_digests(local_digest,
                                                             remote_digest,
                                                             local_path))

        # Different digests with different digest algorithms and different
        # content
        remote_digest = hashlib.sha1(other_content).hexdigest()
        self.assertNotEqual(local_digest, remote_digest)
        self.assertFalse(self.local_client_1.is_equal_digests(local_digest,
                                                              remote_digest,
                                                              local_path))

class TestLocalClientNative(StubLocalClient, UnitTestCase):
    """
    Test LocalClient using native python commands to make FS operations.
    This will simulate Drive actions.
    """

    def setUp(self):
        super(TestLocalClientNative, self).setUp()
        self.engine_1.start()
        self.wait_sync()

    def get_local_client(self, path):
        return LocalClient(path)

@skipIf(AbstractOSIntegration.is_linux(),
        'GNU/Linux uses native LocalClient.')
class TestLocalClientSimulation(StubLocalClient, UnitTestCase):
    """
    Test LocalClient using OS specific commands to make FS operations.
    This will simulate user actions on:
        - Explorer (Windows)
        - File Manager (macOS)
    """

    def setUp(self):
        super(TestLocalClientSimulation, self).setUp()
        self.engine_1.start()
        self.wait_sync()

    def test_complex_filenames(self):
        """
        It should fail on Windows:
        Explorer cannot find the directory as the path is way to long.
        """

        if AbstractOSIntegration.is_windows():
            try:
                # IOError: [Errno 2] No such file or directory
                with self.assertRaises(IOError):
                    super(TestLocalClientSimulation,
                          self).test_complex_filenames()
            except AssertionError:
                # Sometimes it does not raise the expected assertion ...
                # TODO: More tests to know why.
                pass
        else:
            super(TestLocalClientSimulation, self).test_complex_filenames()

    def test_deep_folders(self):
        """
        It should fail on Windows:
        Explorer cannot deal with very long paths.
        """

        if AbstractOSIntegration.is_windows():
            # WindowsError: [Error 206] The filename or extension is too long
            with self.assertRaises(WindowsError):
                super(TestLocalClientSimulation, self).test_deep_folders()
        else:
            super(TestLocalClientSimulation, self).test_deep_folders()
<|endoftext|>


<commit_before>import logsupport
import config
import json
from logsupport import ConsoleWarning

WeathProvs = {}

TermShortener = {}

GenericShortener = {
	'moderate': 'mdrt',
	'patchy': 'pchy',
	'chance': 'chc',
	'freezing': 'frzing',
	'light': 'lt',
	'heavy': 'hvy',
	'shower': 'shwr',
	'drizzle': 'drzl',
	'rain': 'rn',
	'snow': 'snw'
}

def TryShorten(term):
	global TermShortener
	newterm = term
	if term in TermShortener:
		return TermShortener[term]
	elif len(term) > 12 and term[0:4] != 'http':
		phrase = term.split(' ')
		chg = False
		for i, word in enumerate(list(phrase)):
			if word.lower() in GenericShortener:
				chg = True
				phrase[i] = GenericShortener[word.lower()]
				if word[0].isupper(): phrase[i] = phrase[i].capitalize()
		if chg:
			newterm = ' '.join(phrase)
			if len(newterm) > 12:
				logsupport.Logs.Log("Long term: ", term, ' generically shortened to: ', newterm,
									severity=ConsoleWarning)
			else:
				logsupport.Logs.Log("Long term: ", term, ' generically shortened to: ', newterm)
		else:
			logsupport.Logs.Log("Long term: " + term, severity=ConsoleWarning)
		TermShortener[term] = newterm  # only report once
		with open(config.homedir + '/Console/termshortenlist.new', 'w') as f:
			json.dump(TermShortener, f, indent=4, separators=(',', ": "))
	return newterm

# noinspection PyBroadException
def SetUpTermShortener():
	global TermShortener
	try:
		with open(config.homedir + '/Console/termshortenlist', 'r') as f:
		# noinspection PyBroadException
			TermShortener = json.load(f)
	except:
		TermShortener = {}
<commit_msg>Reduce reporting of weather string shortening<commit_after>import logsupport
import config
import json
from logsupport import ConsoleWarning, ConsoleDetail

WeathProvs = {}

TermShortener = {}

GenericShortener = {
	'moderate': 'mdrt',
	'patchy': 'pchy',
	'chance': 'chc',
	'freezing': 'frzing',
	'light': 'lt',
	'heavy': 'hvy',
	'shower': 'shwr',
	'showers': 'shwrs',
	'drizzle': 'drzl',
	'rain': 'rn',
	'snow': 'snw',
	'or': '/'
}

def TryShorten(term):
	global TermShortener
	newterm = term
	if term in TermShortener:
		return TermShortener[term]
	elif len(term) > 12 and term[0:4] != 'http':
		phrase = term.split(' ')
		chg = False
		for i, word in enumerate(list(phrase)):
			if word.lower() in GenericShortener:
				chg = True
				phrase[i] = GenericShortener[word.lower()]
				if word[0].isupper(): phrase[i] = phrase[i].capitalize()
		if chg:
			newterm = ' '.join(phrase).replace(' / ','/')
			if len(newterm) > 12:
				logsupport.Logs.Log("Long term: ", term, ' generically shortened to: ', newterm,
									severity=ConsoleWarning)
			else:
				logsupport.Logs.Log("Long term: ", term, ' generically shortened to: ', newterm,
									severity=ConsoleDetail)
		else:
			logsupport.Logs.Log("Long term: " + term, severity=ConsoleWarning)
		TermShortener[term] = newterm  # only report once
		with open(config.homedir + '/Console/termshortenlist.new', 'w') as f:
			json.dump(TermShortener, f, indent=4, separators=(',', ": "))
	return newterm

# noinspection PyBroadException
def SetUpTermShortener():
	global TermShortener
	try:
		with open(config.homedir + '/Console/termshortenlist', 'r') as f:
		# noinspection PyBroadException
			TermShortener = json.load(f)
	except:
		TermShortener = {}
<|endoftext|>


<commit_before>from collections import Counter

from string_algorithms.rmq import RMQ
from string_algorithms.tree import OrderedTreeNode, Tree
from string_algorithms.utils import inverse_index, inverse_index_array

def naive_suffix_array(s):
    return tuple(x[1] for x in sorted((s[i:], i) for i in range(len(s))))

def suffix_array(s):
    """
    Induced sorting implementation of linear time suffix array construction
    :param s:string
    :return: tuple
    """
    if not s:
        return tuple()

    # compute type
    t = [1] * len(s)
    for i in range(len(s) - 2, -1, -1):
        if s[i] < s[i + 1]:
            t[i] = 0
        elif s[i] > s[i + 1]:
            t[i] = 1
        else:
            t[i] = t[i + 1]

    # compute bucket sizes:
    freq = Counter(s)
    alphabet = tuple(sorted(freq.keys()))
    inverse_alphabet = inverse_index(alphabet)
    buckets = []
    sum = 0
    for sa in alphabet:
        buckets.append((sum, sum + freq[sa]))
        sum += freq[sa]

    def is_lms(i):
        if i == 0:
            return False
        return t[i] == 0 and t[i - 1] == 1

    def is_equal(i, j):
        if s[i] != s[j]:
            return False
        i += 1
        j += 1
        while i < len(s) - 1 and j < len(s) - 1 and s[i] == s[j] and not is_lms(i) and not is_lms(j):
            i += 1
            j += 1
        return s[i] == s[j]

    def place_lms(lms, a):
        counters = [e for _, e in buckets]
        for p in reversed(lms):
            a[counters[inverse_alphabet[s[p]]] - 1] = p
            counters[inverse_alphabet[s[p]]] -= 1

    def place_l_positions(a):
        counters = [b for b, _ in buckets]
        a[counters[inverse_alphabet[s[-1]]]] = len(s) - 1
        counters[inverse_alphabet[s[-1]]] += 1
        for i in a:
            if i is None or i <= 0:
                continue
            p = i - 1
            if t[p] == 1:
                a[counters[inverse_alphabet[s[p]]]] = p
                counters[inverse_alphabet[s[p]]] += 1

    def place_s_positions(a):
        counters = [e for _, e in buckets]
        for i in reversed(a):
            if i is None or i <= 0:
                continue
            p = i - 1
            if t[p] == 0:
                a[counters[inverse_alphabet[s[p]]] - 1] = p
                counters[inverse_alphabet[s[p]]] -= 1

    # phase 1: sort LMS positions
    sa = [None] * len(s)
    lms = [i for i in range(1, len(s)) if is_lms(i)]
    # (1.1 - 1.3)
    place_lms(lms, sa)
    place_l_positions(sa)
    place_s_positions(sa)
    # (1.4)
    j = 0
    prev = None
    ln = dict()
    for i in filter(is_lms, sa):
        if prev is None:
            ln[i] = j
            prev = i
        else:
            if not is_equal(i, prev):
                j += 1
            ln[i] = j
            prev = i
    # (1.5 - 1.8)
    ss = [ln[i] for i in lms]
    if j < len(s) - 1:
        ss = suffix_array(ss)
    sorted_lms = [lms[ss[i]] for i in range(len(lms))]

    # phase 2: build suffix array
    sa = [None] * len(s)
    place_lms(sorted_lms, sa)
    place_l_positions(sa)
    place_s_positions(sa)
    return tuple(sa)

def lcp_array(s, sa):
    assert (len(s) == len(sa))
    isa = inverse_index_array(sa)
    lcp = [0] * len(s)
    l = 0
    for i in range(len(s)):
        j = isa[i]
        if j:
            k = sa[j - 1]
            while k + l < len(s) and i + l < len(s) and s[k + l] == s[i + l]:
                l += 1
            lcp[j] = l
            if l:
                l -= 1
    return tuple(lcp)

class LCPTreeNode(OrderedTreeNode):
    def __init__(self, lcp, lb, rb=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.lcp = lcp
        self.lb = lb
        self.rb = rb

def bottom_up_lcp_interval_tree_traverse(lcp, action=None, keep_tree=False, node_class=LCPTreeNode):
    last_interval = None
    stack = list()
    stack.append(node_class(0, 0))
    for k in range(1, len(lcp) + 1):
        l = k - 1
        # close all interval on stack that ended at position k - 1
        while len(stack) and (k == len(lcp) or lcp[k] < stack[-1].lcp):
            stack[-1].rb = k
            last_interval = stack.pop()
            if action:
                action(last_interval)
            if not keep_tree:  # children are no more needed, so free the memory
                last_interval.children.clear()
            l = last_interval.lb
            if len(stack) and (k == len(lcp) or lcp[k] <= stack[-1].lcp):
                stack[-1].children.append(last_interval)
                last_interval = None
        if len(stack) and (k == len(lcp) or lcp[k] > stack[-1].lcp):  # open new interval
            stack.append(node_class(lcp[k], l))
            if last_interval is not None:
                stack[-1].children.append(last_interval)
                last_interval = None
    return last_interval  # return root node

class LCPConceptualIntervalTree(Tree):
    """Conceptual LCPIntervalTree"""
    def __init__(self, lcp, node_class=LCPTreeNode, include_singletons=False, **kwargs):
        super().__init__(root=node_class(0, 0, len(lcp)), node_class=node_class, **kwargs)
        self.lcp = lcp
        self.rmq = RMQ(lcp)
        self.include_singletons = include_singletons

    def get_children(self, node, sort=False):
        i, j = node.lb, node.rb
        children = []
        if i == j - 1:
            return children
        k = i
        l = self.rmq.query(i + 1, j)
        while k < j:
            m = self.rmq.query_pos(k + 1, j)
            if m is None or self.rmq.array[m] != l:
                m = j
            if k < m - 1 or self.include_singletons:
                children.append(self.node_class(self.rmq.query(k + 1, m), k, m))
            k = m
        return children
<commit_msg>lcp node to string<commit_after>from collections import Counter

from string_algorithms.rmq import RMQ
from string_algorithms.tree import OrderedTreeNode, Tree
from string_algorithms.utils import inverse_index, inverse_index_array

def naive_suffix_array(s):
    return tuple(x[1] for x in sorted((s[i:], i) for i in range(len(s))))

def suffix_array(s):
    """
    Induced sorting implementation of linear time suffix array construction
    :param s:string
    :return: tuple
    """
    if not s:
        return tuple()

    # compute type
    t = [1] * len(s)
    for i in range(len(s) - 2, -1, -1):
        if s[i] < s[i + 1]:
            t[i] = 0
        elif s[i] > s[i + 1]:
            t[i] = 1
        else:
            t[i] = t[i + 1]

    # compute bucket sizes:
    freq = Counter(s)
    alphabet = tuple(sorted(freq.keys()))
    inverse_alphabet = inverse_index(alphabet)
    buckets = []
    sum = 0
    for sa in alphabet:
        buckets.append((sum, sum + freq[sa]))
        sum += freq[sa]

    def is_lms(i):
        if i == 0:
            return False
        return t[i] == 0 and t[i - 1] == 1

    def is_equal(i, j):
        if s[i] != s[j]:
            return False
        i += 1
        j += 1
        while i < len(s) - 1 and j < len(s) - 1 and s[i] == s[j] and not is_lms(i) and not is_lms(j):
            i += 1
            j += 1
        return s[i] == s[j]

    def place_lms(lms, a):
        counters = [e for _, e in buckets]
        for p in reversed(lms):
            a[counters[inverse_alphabet[s[p]]] - 1] = p
            counters[inverse_alphabet[s[p]]] -= 1

    def place_l_positions(a):
        counters = [b for b, _ in buckets]
        a[counters[inverse_alphabet[s[-1]]]] = len(s) - 1
        counters[inverse_alphabet[s[-1]]] += 1
        for i in a:
            if i is None or i <= 0:
                continue
            p = i - 1
            if t[p] == 1:
                a[counters[inverse_alphabet[s[p]]]] = p
                counters[inverse_alphabet[s[p]]] += 1

    def place_s_positions(a):
        counters = [e for _, e in buckets]
        for i in reversed(a):
            if i is None or i <= 0:
                continue
            p = i - 1
            if t[p] == 0:
                a[counters[inverse_alphabet[s[p]]] - 1] = p
                counters[inverse_alphabet[s[p]]] -= 1

    # phase 1: sort LMS positions
    sa = [None] * len(s)
    lms = [i for i in range(1, len(s)) if is_lms(i)]
    # (1.1 - 1.3)
    place_lms(lms, sa)
    place_l_positions(sa)
    place_s_positions(sa)
    # (1.4)
    j = 0
    prev = None
    ln = dict()
    for i in filter(is_lms, sa):
        if prev is None:
            ln[i] = j
            prev = i
        else:
            if not is_equal(i, prev):
                j += 1
            ln[i] = j
            prev = i
    # (1.5 - 1.8)
    ss = [ln[i] for i in lms]
    if j < len(s) - 1:
        ss = suffix_array(ss)
    sorted_lms = [lms[ss[i]] for i in range(len(lms))]

    # phase 2: build suffix array
    sa = [None] * len(s)
    place_lms(sorted_lms, sa)
    place_l_positions(sa)
    place_s_positions(sa)
    return tuple(sa)

def lcp_array(s, sa):
    assert (len(s) == len(sa))
    isa = inverse_index_array(sa)
    lcp = [0] * len(s)
    l = 0
    for i in range(len(s)):
        j = isa[i]
        if j:
            k = sa[j - 1]
            while k + l < len(s) and i + l < len(s) and s[k + l] == s[i + l]:
                l += 1
            lcp[j] = l
            if l:
                l -= 1
    return tuple(lcp)

class LCPTreeNode(OrderedTreeNode):
    def __init__(self, lcp, lb, rb=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.lcp = lcp
        self.lb = lb
        self.rb = rb

    def __str__(self):
        return '{}-({},{})'.format(self.lcp, self.lb, self.rb)

def bottom_up_lcp_interval_tree_traverse(lcp, action=None, keep_tree=False, node_class=LCPTreeNode):
    last_interval = None
    stack = list()
    stack.append(node_class(0, 0))
    for k in range(1, len(lcp) + 1):
        l = k - 1
        # close all interval on stack that ended at position k - 1
        while len(stack) and (k == len(lcp) or lcp[k] < stack[-1].lcp):
            stack[-1].rb = k
            last_interval = stack.pop()
            if action:
                action(last_interval)
            if not keep_tree:  # children are no more needed, so free the memory
                last_interval.children.clear()
            l = last_interval.lb
            if len(stack) and (k == len(lcp) or lcp[k] <= stack[-1].lcp):
                stack[-1].children.append(last_interval)
                last_interval = None
        if len(stack) and (k == len(lcp) or lcp[k] > stack[-1].lcp):  # open new interval
            stack.append(node_class(lcp[k], l))
            if last_interval is not None:
                stack[-1].children.append(last_interval)
                last_interval = None
    return last_interval  # return root node

class LCPConceptualIntervalTree(Tree):
    """Conceptual LCPIntervalTree"""
    def __init__(self, lcp, node_class=LCPTreeNode, include_singletons=False, **kwargs):
        super().__init__(root=node_class(0, 0, len(lcp)), node_class=node_class, **kwargs)
        self.lcp = lcp
        self.rmq = RMQ(lcp)
        self.include_singletons = include_singletons

    def get_children(self, node, sort=False):
        i, j = node.lb, node.rb
        children = []
        if i == j - 1:
            return children
        k = i
        l = self.rmq.query(i + 1, j)
        while k < j:
            m = self.rmq.query_pos(k + 1, j)
            if m is None or self.rmq.array[m] != l:
                m = j
            if k < m - 1 or self.include_singletons:
                children.append(self.node_class(self.rmq.query(k + 1, m), k, m))
            k = m
        return children
<|endoftext|>


<commit_before>"""Shell side object which manages request to start activity"""
# Copyright (C) 2006-2007 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import logging

import dbus
import gobject
import gtk

from sugar.presence import presenceservice
from sugar.activity.activityhandle import ActivityHandle
from sugar import util

import os

_SHELL_SERVICE = "org.laptop.Shell"
_SHELL_PATH = "/org/laptop/Shell"
_SHELL_IFACE = "org.laptop.Shell"

_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"

_RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
_RAINBOW_ACTIVITY_FACTORY_PATH = "/"
_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"

def create_activity_id():
    """Generate a new, unique ID for this activity"""
    pservice = presenceservice.get_instance()

    # create a new unique activity ID
    i = 0
    act_id = None
    while i < 10:
        act_id = util.unique_id()
        i += 1

        # check through network activities
        found = False
        activities = pservice.get_activities()
        for act in activities:
            if act_id == act.props.id:
                found = True
                break
        if not found:
            return act_id
    raise RuntimeError("Cannot generate unique activity id.")

class ActivityCreationHandler(gobject.GObject):
    """Sugar-side activity creation interface

    This object uses a dbus method on the ActivityFactory
    service to create the new activity.  It generates
    GObject events in response to the success/failure of
    activity startup using callbacks to the service's
    create call.
    """

    def __init__(self, service_name, activity_handle):
        """Initialise the handler

        service_name -- the service name of the bundle factory
        activity_handle -- stores the values which are to
            be passed to the service to uniquely identify
            the activity to be created and the sharing
            service that may or may not be connected with it

            sugar.activity.activityhandle.ActivityHandle instance

        calls the "create" method on the service for this
        particular activity type and registers the
        _reply_handler and _error_handler methods on that
        call's results.

        The specific service which creates new instances of this
        particular type of activity is created during the activity
        registration process in shell bundle registry which creates
        service definition files for each registered bundle type.

        If the file '/etc/olpc-security' exists, then activity launching
        will be delegated to the prototype 'Rainbow' security service.
        """
        gobject.GObject.__init__(self)
        self._service_name = service_name
        self._activity_handle = activity_handle

        bus = dbus.SessionBus()

        bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
        self._shell = dbus.Interface(bus_object, _SHELL_IFACE)

        object_path = '/' + service_name.replace('.', '/')
        proxy_obj = bus.get_object(service_name, object_path,
                                   follow_name_owner_changes=True)
        self._factory = dbus.Interface(proxy_obj, _ACTIVITY_FACTORY_INTERFACE)

        if self.get_activity_id() != None:
            self._shell.ActivateActivity(self.get_activity_id(),
                        reply_handler=self._activate_reply_handler,
                        error_handler=self._activate_error_handler)
        else:
            self._launch_activity()

    def _launch_activity(self):
        self._shell.NotifyLaunch(
                    self._service_name, self.get_activity_id(),
                    reply_handler=self._no_reply_handler,
                    error_handler=self._notify_launch_error_handler)

        if not os.path.exists('/etc/olpc-security'):
            self._factory.create(self._activity_handle.get_dict(),
                                 timeout=120 * 1000,
                                 reply_handler=self._no_reply_handler,
                                 error_handler=self._create_error_handler)
        else:
            system_bus = dbus.SystemBus()
            factory = system_bus.get_object(_RAINBOW_SERVICE_NAME,
                                            _RAINBOW_ACTIVITY_FACTORY_PATH)
            factory.CreateActivity(
                    self._service_name,
                    self._activity_handle.get_dict(),
                    timeout=120 * 1000,
                    reply_handler=self._create_reply_handler,
                    error_handler=self._create_error_handler,
                    dbus_interface=_RAINBOW_ACTIVITY_FACTORY_INTERFACE)

    def get_activity_id(self):
        """Retrieve the unique identity for this activity"""
        return self._activity_handle.activity_id

    def _no_reply_handler(self, *args):
        pass

    def _notify_launch_failure_error_handler(self, err):
        logging.debug('Notify launch failure failed %s' % err)

    def _notify_launch_error_handler(self, err):
        logging.debug('Notify launch failed %s' % err)

    def _activate_reply_handler(self, activated):
        if not activated:
            self._launch_activity()

    def _activate_error_handler(self, err):
        logging.debug("Activity activation request failed %s" % err)

    def _create_reply_handler(self, xid):
        logging.debug("Activity created %s (%s)." %
            (self._activity_handle.activity_id, self._service_name))

    def _create_error_handler(self, err):
        logging.debug("Couldn't create activity %s (%s): %s" %
            (self._activity_handle.activity_id, self._service_name, err))
        self._shell.NotifyLaunchFailure(
                self.get_activity_id(), reply_handler=self._no_reply_handler,
                error_handler=self._notify_launch_failure_error_handler)

def create(service_name, activity_handle=None):
    """Create a new activity from its name."""
    if not activity_handle:
        activity_handle = ActivityHandle(create_activity_id())
    return ActivityCreationHandler(service_name, activity_handle)

def create_with_uri(service_name, uri):
    """Create a new activity and pass the uri as handle."""
    activity_handle = ActivityHandle(create_activity_id())
    activity_handle.uri = uri
    return ActivityCreationHandler(service_name, activity_handle)

def create_with_object_id(service_name, object_id):
    """Create a new activity and pass the object id as handle."""
    activity_handle = ActivityHandle(create_activity_id())
    activity_handle.object_id = object_id
    return ActivityCreationHandler(service_name, activity_handle)
<commit_msg>with the native factory which doesn't have introspection.<commit_after>"""Shell side object which manages request to start activity"""
# Copyright (C) 2006-2007 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import logging

import dbus
import gobject
import gtk

from sugar.presence import presenceservice
from sugar.activity.activityhandle import ActivityHandle
from sugar import util

import os

_SHELL_SERVICE = "org.laptop.Shell"
_SHELL_PATH = "/org/laptop/Shell"
_SHELL_IFACE = "org.laptop.Shell"

_ACTIVITY_FACTORY_INTERFACE = "org.laptop.ActivityFactory"

_RAINBOW_SERVICE_NAME = "org.laptop.security.Rainbow"
_RAINBOW_ACTIVITY_FACTORY_PATH = "/"
_RAINBOW_ACTIVITY_FACTORY_INTERFACE = "org.laptop.security.Rainbow"

def create_activity_id():
    """Generate a new, unique ID for this activity"""
    pservice = presenceservice.get_instance()

    # create a new unique activity ID
    i = 0
    act_id = None
    while i < 10:
        act_id = util.unique_id()
        i += 1

        # check through network activities
        found = False
        activities = pservice.get_activities()
        for act in activities:
            if act_id == act.props.id:
                found = True
                break
        if not found:
            return act_id
    raise RuntimeError("Cannot generate unique activity id.")

class ActivityCreationHandler(gobject.GObject):
    """Sugar-side activity creation interface

    This object uses a dbus method on the ActivityFactory
    service to create the new activity.  It generates
    GObject events in response to the success/failure of
    activity startup using callbacks to the service's
    create call.
    """

    def __init__(self, service_name, activity_handle):
        """Initialise the handler

        service_name -- the service name of the bundle factory
        activity_handle -- stores the values which are to
            be passed to the service to uniquely identify
            the activity to be created and the sharing
            service that may or may not be connected with it

            sugar.activity.activityhandle.ActivityHandle instance

        calls the "create" method on the service for this
        particular activity type and registers the
        _reply_handler and _error_handler methods on that
        call's results.

        The specific service which creates new instances of this
        particular type of activity is created during the activity
        registration process in shell bundle registry which creates
        service definition files for each registered bundle type.

        If the file '/etc/olpc-security' exists, then activity launching
        will be delegated to the prototype 'Rainbow' security service.
        """
        gobject.GObject.__init__(self)
        self._service_name = service_name
        self._activity_handle = activity_handle

        bus = dbus.SessionBus()

        bus_object = bus.get_object(_SHELL_SERVICE, _SHELL_PATH)
        self._shell = dbus.Interface(bus_object, _SHELL_IFACE)

        object_path = '/' + service_name.replace('.', '/')
        proxy_obj = bus.get_object(service_name, object_path,
                                   follow_name_owner_changes=True)
        self._factory = dbus.Interface(proxy_obj, _ACTIVITY_FACTORY_INTERFACE)

        if self.get_activity_id() != None:
            self._shell.ActivateActivity(self.get_activity_id(),
                        reply_handler=self._activate_reply_handler,
                        error_handler=self._activate_error_handler)
        else:
            self._launch_activity()

    def _launch_activity(self):
        self._shell.NotifyLaunch(
                    self._service_name, self.get_activity_id(),
                    reply_handler=self._no_reply_handler,
                    error_handler=self._notify_launch_error_handler)

        if not os.path.exists('/etc/olpc-security'):
            handle = self._activity_handle.get_dict()
            self._factory.create(dbus.Dictionary(handle, signature='ss'),
                                 timeout=120 * 1000,
                                 reply_handler=self._no_reply_handler,
                                 error_handler=self._create_error_handler)
        else:
            system_bus = dbus.SystemBus()
            factory = system_bus.get_object(_RAINBOW_SERVICE_NAME,
                                            _RAINBOW_ACTIVITY_FACTORY_PATH)
            factory.CreateActivity(
                    self._service_name,
                    self._activity_handle.get_dict(),
                    timeout=120 * 1000,
                    reply_handler=self._create_reply_handler,
                    error_handler=self._create_error_handler,
                    dbus_interface=_RAINBOW_ACTIVITY_FACTORY_INTERFACE)

    def get_activity_id(self):
        """Retrieve the unique identity for this activity"""
        return self._activity_handle.activity_id

    def _no_reply_handler(self, *args):
        pass

    def _notify_launch_failure_error_handler(self, err):
        logging.debug('Notify launch failure failed %s' % err)

    def _notify_launch_error_handler(self, err):
        logging.debug('Notify launch failed %s' % err)

    def _activate_reply_handler(self, activated):
        if not activated:
            self._launch_activity()

    def _activate_error_handler(self, err):
        logging.debug("Activity activation request failed %s" % err)

    def _create_reply_handler(self, xid):
        logging.debug("Activity created %s (%s)." %
            (self._activity_handle.activity_id, self._service_name))

    def _create_error_handler(self, err):
        logging.debug("Couldn't create activity %s (%s): %s" %
            (self._activity_handle.activity_id, self._service_name, err))
        self._shell.NotifyLaunchFailure(
                self.get_activity_id(), reply_handler=self._no_reply_handler,
                error_handler=self._notify_launch_failure_error_handler)

def create(service_name, activity_handle=None):
    """Create a new activity from its name."""
    if not activity_handle:
        activity_handle = ActivityHandle(create_activity_id())
    return ActivityCreationHandler(service_name, activity_handle)

def create_with_uri(service_name, uri):
    """Create a new activity and pass the uri as handle."""
    activity_handle = ActivityHandle(create_activity_id())
    activity_handle.uri = uri
    return ActivityCreationHandler(service_name, activity_handle)

def create_with_object_id(service_name, object_id):
    """Create a new activity and pass the object id as handle."""
    activity_handle = ActivityHandle(create_activity_id())
    activity_handle.object_id = object_id
    return ActivityCreationHandler(service_name, activity_handle)
<|endoftext|>