Пример #1
0
Файл: cmd.py Проект: yvess/desk
    def run(self):
        crm = get_crm_module(self.settings)
        server = Server(self.settings.couchdb_uri)
        db = server.get_db(self.settings.couchdb_db)

        invoice_cycle = InvoiceCycle(self.settings.invoice_nr)
        clients = db.view(
            self._cmd("client_is_billable"), include_docs=True
        )
        counter = 0
        for client in clients:
            if not self.settings.limit_client_id or client['id'] == self.settings.limit_client_id:
                # print(client['doc']['name'])
                invoice = Invoice(
                    self.settings, crm=crm,
                    client_doc=client['doc'],
                    invoice_cycle=invoice_cycle
                )
                invoice_start_date = min(
                    [d['start_date'] for d in invoice.doc['services'].itervalues()]
                )
                if invoice_start_date < invoice_cycle.doc['end_date']:
                    invoice.render_pdf()
                    invoice_cycle.add_invoice(invoice)
                    counter += 1
                    print(".", end="")
                if self.settings.max != 0 and counter >= self.settings.max:
                    break
        print("\n", "total", invoice_cycle.get_total())
Пример #2
0
class CouchDBServer(object):
    def __init__(self):
        self.__get_server_uri()
        self.__authenticate()
        self.__connect()

    def __get_server_uri(self):
        couchdb_port = config.couchdb.port if config.couchdb.protocol == 'http' else config.couchdb.ssl_port
        self.__couchdb_uri = "%s://%s:%s" % (config.couchdb.protocol, config.couchdb.host, couchdb_port)

    def __authenticate(self):
        user, passwd = config.couchdb.user, config.couchdb.password
        if all((user, passwd)):
            auth = restkit.BasicAuth(user, passwd)
            self.__auth_resource = CouchdbResource(filters=[auth])
        else:
            self.__auth_resource = None

    def __connect(self):
        self.__server = Server(uri=self.__couchdb_uri, resource_instance=self.__auth_resource)

    def list_workspaces(self):
        return filter(is_usable_workspace, self.__server.all_dbs())

    def get_workspace_handler(self, ws_name):
        return self.__server.get_db(ws_name)

    def get_or_create_db(self, ws_name):
        return self.__server.get_or_create_db(ws_name)
Пример #3
0
 def __init__(self, settings, crm, client_doc, invoice_cycle):
     self.invoice_template_dir = settings.invoice_template_dir
     self.output_dir = settings.invoice_output_dir
     self.tax = float(settings.invoice_tax)
     self.jinja_env = Environment(
         loader=FileSystemLoader(self.invoice_template_dir)
     )
     self.jinja_env.filters['nl2br'] = filters.nl2br
     self.jinja_env.filters['format_date'] = filters.format_date
     self.crm = crm
     self.client_id = client_doc['_id']
     try:
         self.extcrm_id = client_doc['extcrm_id']
     except KeyError:
         print(client_doc)
         raise KeyError
     self.client_doc = client_doc
     self.settings = settings
     self.invoice_cycle = invoice_cycle
     self.invoice_nr = invoice_cycle.current_nr
     server = Server(self.settings.couchdb_uri)
     self.db = server.get_db(self.settings.couchdb_db)
     if not Invoice.service_definitons:
         Invoice.load_service_definitions(self.db)
     self.setup_invoice()
Пример #4
0
class CouchDBServer(object):
    def __init__(self):
        self.__get_server_uri()
        self.__authenticate()
        self.__connect()

    def __get_server_uri(self):
        couchdb_port = config.couchdb.port if config.couchdb.protocol == 'http' else config.couchdb.ssl_port
        self.__couchdb_uri = "%s://%s:%s" % (config.couchdb.protocol,
                                             config.couchdb.host, couchdb_port)

    def __authenticate(self):
        user, passwd = config.couchdb.user, config.couchdb.password
        if (all((user, passwd))):
            auth = restkit.BasicAuth(user, passwd)
            self.__auth_resource = CouchdbResource(filters=[auth])
        else:
            self.__auth_resource = None

    def __connect(self):
        self.__server = Server(uri=self.__couchdb_uri,
                               resource_instance=self.__auth_resource)

    def list_workspaces(self):
        return filter(is_usable_workspace, self.__server.all_dbs())

    def get_workspace_handler(self, ws_name):
        return self.__server.get_db(ws_name)
Пример #5
0
 def __init__(self, settings, crm, client_doc, invoice_cycle):
     self.invoice_template_dir = settings.invoice_template_dir
     self.output_dir = settings.invoice_output_dir
     self.tax = float(settings.invoice_tax)
     self.home_country = settings.invoice_home_country if hasattr(settings, 'invoice_home_country', ) else None
     self.jinja_env = Environment(
         loader=FileSystemLoader(self.invoice_template_dir)
     )
     self.jinja_env.filters['nl2br'] = filters.nl2br
     self.jinja_env.filters['format_date'] = filters.format_date
     self.crm = crm
     self.client_id = client_doc['_id']
     try:
         self.extcrm_id = client_doc['extcrm_id']
     except KeyError:
         extcrm_id = client_doc['extcrm_id'] if 'extcrm_id' in client_doc else "None"
         print('\nNOT creating invoice missing extcrm_id:%s, %s' % (extcrm_id, client_doc['name']), client_doc)
         self.client_doc = None
         return
     self.client_doc = client_doc
     self.settings = settings
     self.invoice_cycle = invoice_cycle
     self.invoice_nr = invoice_cycle.current_nr
     server = Server(self.settings.couchdb_uri)
     self.db = server.get_db(self.settings.couchdb_db)
     if not Invoice.service_definitons:
         Invoice.load_service_definitions(self.db)
     self.setup_invoice()
Пример #6
0
class SettingsCommandDb(SettingsCommand):
    def set_settings(self, settings, hostname=os.uname()[1]):
        super(SettingsCommandDb, self).set_settings(settings, hostname)
        self.server = Server(uri=self.settings.couchdb_uri)
        self.db = self.server.get_db(self.settings.couchdb_db)

    def _cmd(self, cmd):
        return "{}/{}".format(self.settings.couchdb_db, cmd)
def get_prod_db(source_uri):
    """
    Get the production database object since we need to get some doc_ids from the prod database
    """
    prod_db_name = source_uri.split('/')[-1]
    prod_server = Server(uri=source_uri[:-len(prod_db_name)])
    prod_db = prod_server.get_db(prod_db_name)
    return prod_db
Пример #8
0
def get_detailed_status(options):
    total_tests = 0
    total_errors = 0
    server = Server(options.node)
    db = server.get_db(options.database)
    doc = get_build_doc(db, options.build)
    doc_content = db.open_doc(doc['_id'])
    tests_list = doc_content['_attachments'].keys()
    # TODO: Check for number of tests that ran
    print "List of tests against %s are %s " % (options.build, tests_list)
    failed_tests = []
    # Data struct to store information per test_class (attachment)
    # {test_name:{tests:<int>, errros:<int>, time:<float>}}
    test_data = {}
    for attachment, value in doc_content['_attachments'].items():
        errors_count = 0
        tests_count = 0
        print "Fetching attachment %s " % attachment
        file = db.fetch_attachment(doc, attachment)
        file = file.encode('ascii', 'ignore')
        xmldoc = etree.parse(StringIO.StringIO(file))
        root = xmldoc.getroot()
        for child in root:
            attributes = child.attrib
            for childish in child:
                # To print the error
                #print childish.text
                failed_tests.append(attributes.get('name'))
        attributes = root.attrib
        # To get root element attributes
        #print attributes
        name = attributes.get('name')
        errors_count = int(attributes.get('errors'))
        tests_count = int(attributes.get('tests'))
        total_tests += tests_count
        total_errors += errors_count
        print "Testname: %s, passed: %s, failed: %s" % (
            name, tests_count - errors_count, errors_count)
        test_data[name] = {}
        test_data[name]['tests'] = tests_count
        test_data[name]['errors'] = errors_count
        test_data[name]['time'] = float(attributes.get('time'))

    #print test_data
    text = "Passed %s out of %s tests on %s build\n" % (
        total_tests - total_errors, total_tests, options.build)
    num_failed = len(failed_tests)
    if num_failed > 0:
        text += "\nList of Failed tests:\n"
        for i in range(num_failed):
            text += "%s: %s\n" % (i + 1, failed_tests[i])

    print text
    return test_data
Пример #9
0
def get_detailed_status(options):
    total_tests = 0
    total_errors = 0
    server = Server(options.node)
    db = server.get_db(options.database)
    doc = get_build_doc(db, options.build)
    doc_content = db.open_doc(doc['_id'])
    tests_list = doc_content['_attachments'].keys()
    # TODO: Check for number of tests that ran
    print "List of tests against %s are %s " % (options.build, tests_list)
    failed_tests = []
    # Data struct to store information per test_class (attachment)
    # {test_name:{tests:<int>, errros:<int>, time:<float>}}
    test_data = {}
    for attachment, value in doc_content['_attachments'].items():
        errors_count = 0
        tests_count = 0
        print "Fetching attachment %s " % attachment
        file = db.fetch_attachment(doc, attachment)
        file = file.encode('ascii', 'ignore')
        xmldoc =  etree.parse(StringIO.StringIO(file))
        root = xmldoc.getroot()
        for child in root:
            attributes = child.attrib
            for childish in child:
                # To print the error
                #print childish.text
                failed_tests.append(attributes.get('name'))
        attributes = root.attrib
        # To get root element attributes
        #print attributes
        name = attributes.get('name')
        errors_count = int(attributes.get('errors'))
        tests_count = int(attributes.get('tests'))
        total_tests += tests_count
        total_errors += errors_count
        print "Testname: %s, passed: %s, failed: %s" % (name, tests_count-errors_count,
                                                        errors_count)
        test_data[name] = {}
        test_data[name]['tests'] = tests_count
        test_data[name]['errors'] = errors_count
        test_data[name]['time'] = float(attributes.get('time'))

    #print test_data
    text = "Passed %s out of %s tests on %s build\n" % (total_tests-total_errors, total_tests,
                                                        options.build)
    num_failed = len(failed_tests)
    if num_failed > 0:
        text += "\nList of Failed tests:\n"
        for i in range(num_failed):
            text += "%s: %s\n" % (i+1, failed_tests[i])

    print text
    return test_data
Пример #10
0
    def run(self):
        server = Server(self.settings.couchdb_uri)
        db = server.get_db(self.settings.couchdb_db)

        def next_migration(version, doc_id, doc_type):
            new_version = version + 1
            next_migration_name = "to%04d" % new_version
            if hasattr(migrations, next_migration_name):
                do_migration = getattr(migrations, next_migration_name)
                doc = db.get(doc_id)
                print('updating to:', new_version, doc_type, doc_id)
                do_migration(doc, doc_type, db)
                next_migration(new_version, doc_id, doc_type)

        for item in db.view(self._cmd("version")):
            version, doc_id, doc_type = item['key'], item['id'], item['value']
            next_migration(version, doc_id, doc_type)
Пример #11
0
    def run(self):
        server = Server(self.settings.couchdb_uri)
        db = server.get_db(self.settings.couchdb_db)
        provides = {}
        if hasattr(self.settings, 'worker_dns'):
            provides['domain'], worker_dns = [], self.settings.worker_dns
            dns_servers = map(
                lambda x: x.strip().split(':'), worker_dns.split(',')
            )
            for backend, name in dns_servers:
                provides['domain'].append({'backend': backend, 'name': name})

        worker_id = "worker-{}".format(self.hostname)
        d = {
            "_id": worker_id, "type": "worker", "hostname": self.hostname,
            "provides": provides
        }
        db.save_doc(d)
Пример #12
0
class CouchDbManager(AbstractPersistenceManager):
    """
    This is a couchdb manager for the workspace,
    it will load from the couchdb databases
    """
    def __init__(self, uri):
        super(CouchDbManager, self).__init__()
        getLogger(self).debug(
            "Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__serv = NoConectionServer()
        self._available = False
        try:
            if uri is not None:
                self.testCouchUrl(uri)
                url = urlparse(uri)
                getLogger(self).debug(
                    "Setting user,pass %s %s" % (url.username, url.password))
                self.__serv = Server(uri=uri)
                self.__serv.resource_class.credentials = (url.username, url.password)
                self._available = True
                self.pushReports()
                self._loadDbs()
        except:
            getLogger(self).warn("No route to couchdb server on: %s" % uri)
            getLogger(self).debug(traceback.format_exc())

    #@trap_timeout
    def _create(self, name):
        db = self.__serv.create_db(name.lower())
        return CouchDbConnector(db)

    #@trap_timeout
    def _delete(self, name):
        self.__serv.delete_db(name)

    #@trap_timeout
    def _loadDbs(self):
        conditions = lambda x: not x.startswith("_") and x != 'reports'
        for dbname in filter(conditions, self.__serv.all_dbs()):
            if dbname not in self.dbs.keys():
                getLogger(self).debug(
                    "Asking for dbname[%s], registering for lazy initialization" % dbname)
                self.dbs[dbname] = lambda x: self._loadDb(x)

    def _loadDb(self, dbname):
        db = self.__serv.get_db(dbname)
        seq = db.info()['update_seq']
        self.dbs[dbname] = CouchDbConnector(db, seq_num=seq) 
        return self.dbs[dbname]


    #@trap_timeout
    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        workspace = self.__serv.get_or_create_db("reports")
        vmanager.addView(reports, workspace)
        return self.__uri + "/reports/_design/reports/index.html"

    def lostConnectionResolv(self):
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchDbManager.testCouch(ur):
            self.__serv = Server(uri = ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val

    @staticmethod
    def testCouch(uri):
        if uri is not None:
            host, port = None, None
            try:
                import socket
                url = urlparse(uri)
                proto = url.scheme
                host = url.hostname
                port = url.port

                port = port if port else socket.getservbyname(proto)
                s = socket.socket()
                s.settimeout(1)
                s.connect((host, int(port)))
            except:
                return False
            #getLogger(CouchdbManager).info("Connecting Couch to: %s:%s" % (host, port))
            return True

    def testCouchUrl(self, uri):
        if uri is not None:
            url = urlparse(uri)
            proto = url.scheme
            host = url.hostname
            port = url.port
            self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))

    #@trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        getLogger(self).debug("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                getLogger(self).info("workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s" % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path, **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                getLogger(self).error(e)
                raise 

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace, dst, mutual = mutual, continuous  = continuous, create_target = ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous = continuous, **kwargs)
Пример #13
0
class CouchdbManager(PersistenceManager):
    """ This is a couchdb manager for the workspace, it will load from the 
    couchdb databases"""
    def __init__(self, uri):
        self._last_seq_ack = 0
        model.api.log("Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__dbs = {} 
        self.__seq_nums = {}
        self.__serv = NoConectionServer()
        self.mutex = threading.Lock()
        self._available = False
        try:
            self.testCouchUrl(uri)
            self.__serv = Server(uri = uri)
            self._available = True
        except:
            model.api.log("No route to couchdb server on: %s" % uri)

    def isAvailable(self):
        return self._available

    def lostConnectionResolv(self): 
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchdbManager.testCouch(ur):
            self.__serv = Server(uri = ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val



    @staticmethod
    def testCouch(uri):
        host, port = None, None
        try:
            import socket
            proto, netloc, _, _, _ = urlsplit(uri)
            host, port = splitport(netloc)
            port = port if port else socket.getservbyname(proto)
            s = socket.socket()
            s.settimeout(1)
            s.connect((host, int(port)))
        except:
            return False
        model.api.log("Connecting Couch to: %s:%s" % (host, port))
        return True



    def testCouchUrl(self, uri):
        _, netloc, _, _, _ = urlsplit(uri)
        host, port = splitport(netloc)
        self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))


    @trap_timeout
    def getWorkspacesNames(self):
        return filter(lambda x: not x.startswith("_"), self.__serv.all_dbs())

    def workspaceExists(self, name):
        return name in self.getWorkspacesNames()


    @trap_timeout
    def addWorkspace(self, aWorkspace):
        self.__serv.create_db(aWorkspace.lower())
        return self.__getDb(aWorkspace)

    @trap_timeout
    def addDocument(self, aWorkspaceName, documentId, aDocument):
        self.incrementSeqNumber(aWorkspaceName)
        self.__getDb(aWorkspaceName)[documentId] = aDocument

    @trap_timeout
    def saveDocument(self, aWorkspaceName, aDocument):
        self.incrementSeqNumber(aWorkspaceName)
        model.api.log("Saving document in remote workspace %s" % aWorkspaceName)
        self.__getDb(aWorkspaceName).save_doc(aDocument, use_uuids = True, force_update = True)

    @trap_timeout
    def __getDb(self, aWorkspaceName): 
        aWorkspaceName = aWorkspaceName.lower()
        model.api.log("Getting workspace [%s]" % aWorkspaceName)
        workspacedb = self.__dbs.get(aWorkspaceName, self.__serv.get_db(aWorkspaceName))
        if not self.__dbs.has_key(aWorkspaceName): 
            model.api.log("Asking couchdb for workspace [%s]" % aWorkspaceName)
            self.__dbs[aWorkspaceName] = workspacedb
            self.__seq_nums[aWorkspaceName] = workspacedb.info()['update_seq'] 
        return workspacedb

    @trap_timeout
    def getDocument(self, aWorkspaceName, documentId):
        model.api.log("Getting document for workspace [%s]" % aWorkspaceName)
        return self.__getDb(aWorkspaceName).get(documentId)

    @trap_timeout
    def checkDocument(self, aWorkspaceName, documentName):
        return  self.__getDb(aWorkspaceName).doc_exist(documentName)


    @trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        model.api.log("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                model.api.devlog("workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s" % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path, **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                model.api.devlog(e)
                raise 

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace, dst, mutual = mutual, continuous  = continuous, create_target = ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous = continuous, **kwargs)


    def getLastChangeSeq(self, workspaceName):
        self.mutex.acquire()
        seq = self.__seq_nums[workspaceName]
        self.mutex.release()
        return seq

    def setLastChangeSeq(self, workspaceName, seq_num):
        self.mutex.acquire()
        self.__seq_nums[workspaceName] = seq_num
        self.mutex.release()


    @trap_timeout
    def waitForDBChange(self, db_name, since = 0, timeout = 15000):
        """ Be warned this will return after the database has a change, if
        there was one before call it will return immediatly with the changes
        done"""
        changes = []
        last_seq = max(self.getLastChangeSeq(db_name), since)
        db = self.__getDb(db_name)
        with ChangesStream(db, feed="longpoll", since = last_seq, timeout = timeout) as stream:
            for change in stream:
                if change['seq'] > self.getLastChangeSeq(db_name):
                    changes.append(change)
            last_seq = reduce(lambda x,y:  max(y['seq'], x) , changes, self.getLastChangeSeq(db_name))
            self.setLastChangeSeq(db_name, last_seq)
        return changes

    @trap_timeout
    def delete_all_dbs(self):
        for db in self.__serv.all_dbs():
            self.__serv.delete_db(db)

    @trap_timeout
    def existWorkspace(self, name):
        return name in self.__serv.all_dbs()

    @trap_timeout
    def workspaceDocumentsIterator(self, workspaceName):
        return filter(lambda x: not x["id"].startswith("_"), self.__getDb(workspaceName).documents(include_docs=True))

    @trap_timeout
    def removeWorkspace(self, workspace_name):
        return self.__serv.delete_db(workspace_name) 

    @trap_timeout
    def remove(self, workspace, host_id):
        self.incrementSeqNumber(workspace)
        self.__dbs[workspace].delete_doc(host_id)

    @trap_timeout
    def compactDatabase(self, aWorkspaceName):
        self.__getDb(aWorkspaceName).compact()

    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        workspace = self.__serv.get_or_create_db("reports") 
        vmanager.addView(reports, workspace)
        return self.__uri + "/reports/_design/reports/index.html"


    def addViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName)
        for v in vmanager.getAvailableViews():
            vmanager.addView(v, workspace)

    def getViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName)
        return vmanager.getViews(workspace)

    def syncWorkspaceViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName) 
        installed_views = vmanager.getViews(workspace)
        for v in vmanager.getAvailableViews():
            if v not in installed_views: 
                vmanager.addView(v, workspace)

    def incrementSeqNumber(self, workspaceName):
        self.mutex.acquire()
        self.__seq_nums[workspaceName] += 1 
        self.mutex.release()
Пример #14
0
class ImportServices(object):
    def __init__(self, settings):
        self.service_tpl = {"type": "service", "state": "active"}
        self.docs, self.clients_extcrm_ids = [], {}
        self.settings = settings
        self.nr_cols = settings.nr_cols
        self.server = Server(self.settings.couchdb_uri)
        self.db = self.server.get_db(self.settings.couchdb_db)
        self.init_spreadsheet()

    def init_spreadsheet(self):
        spreadsheet = ezodf.opendoc(self.settings.src)
        sheet = spreadsheet.sheets[0]
        self.rows = sheet.rows()
        self.header = [
            c.value.lower() if hasattr(c.value, "lower") else c.value for c in self.rows.next()[: self.nr_cols]
        ]

    def process_row(self, row):
        for service_type in ["web", "email"]:
            if row[service_type]:
                try:
                    service_doc = self.service_tpl.copy()
                    service_doc["_id"] = "service-%s" % self.server.next_uuid()
                    if row["todoyu"] not in self.clients_extcrm_ids:
                        client_id = self.get_or_create_client(row)
                        self.clients_extcrm_ids[row["todoyu"]] = client_id
                    else:
                        client_id = self.clients_extcrm_ids[row["todoyu"]]
                    service_doc["service_type"] = service_type
                    service_doc["start_date"] = row["start_date"]
                    service_doc["client_id"] = client_id
                    if isinstance(row[service_type], dict):
                        service_doc.update(row[service_type])
                    else:
                        service_doc["package_type"] = row[service_type]

                    addon_key = "%s_addon_items" % service_type
                    if addon_key in row and row[addon_key]:
                        service_doc["addon_service_items"] = row[addon_key]

                    included_key = "%s_included_items" % service_type
                    if included_key in row and row[included_key]:
                        service_doc["included_service_items"] = row[included_key]
                    self.docs.append((service_doc["_id"], service_doc))
                except:
                    print("!!! couldn't import service")
                    pass

    def process_sheet(self):
        services = []
        i = 0
        for row in self.rows:
            i += 1
            if any([cell.value for cell in row[: self.nr_cols]]):
                cell_values = []
                for cell in row[: self.nr_cols]:
                    cell_is_python = hasattr(cell.value, "startswith") and (
                        cell.value.startswith("{") or cell.value.startswith("[")
                    )
                    if cell_is_python:
                        value = ast.literal_eval(cell.value)
                    else:
                        value = cell.value
                    cell_values.append(value)
                row_dict = dict(zip(self.header[: self.nr_cols], cell_values))
                services.append(row_dict)
            else:
                break
        return services

    def _cmd(self, cmd):
        return "{}/{}".format(self.settings.couchdb_db, cmd)

    def get_or_create_client(self, row):
        if row["org_name"]:
            name = row["org_name"]
        else:
            name = "%s %s" % (row["n_given"], row["n_family"])
        query_results = self.db.view(self._cmd("client_by_name"), key=name, include_docs=False)
        if query_results.count() == 1:
            client_doc = query_results.first()["value"]
        elif query_results.count() == 0:
            client_doc = {"type": "client"}
            client_doc["_id"] = "client-%s" % self.server.next_uuid()
        else:
            raise
        client_doc["is_billable"] = 1
        client_doc["extcrm_id"] = row["todoyu"]
        client_doc["name"] = name
        self.docs.append((client_doc["_id"], client_doc))

        return client_doc["_id"]

    def create_docs(self):
        self.rows = self.process_sheet()
        self.todoyu = Todoyu(self.settings)
        self.dest = "{}/services_json".format(os.path.dirname(self.settings.src))
        for row in self.rows:
            self.process_row(row)

    def create_files(self):
        self.create_docs()
        if os.path.exists(self.dest):
            shutil.rmtree(self.dest)
        os.mkdir(self.dest)
        json_files = FilesForCouch(self.docs, self.dest)
        json_files.create()

        if not self.settings.only_files:
            couch_up = CouchdbUploader(
                path=self.dest, couchdb_uri=self.settings.couchdb_uri, couchdb_db=self.settings.couchdb_db
            )

            for fname in os.listdir(self.dest):
                couch_up.put(data="@{}".format(fname), doc_id=fname[:-5])
Пример #15
0
class QueryServices(object):
    def __init__(self, settings):
        self.clients_extcrm_ids = {}
        self.settings = settings
        self.server = Server(self.settings.couchdb_uri)
        self.db = self.server.get_db(self.settings.couchdb_db)
        self.crm = get_crm_module(self.settings)

    def _cmd(self, cmd):
        return "{}/{}".format(self.settings.couchdb_db, cmd)

    def query(self):
        services = []
        startkey = [self.settings.service]
        endkey = [self.settings.service]
        only_billable = self.settings.only_billable

        if self.settings.service_packages:
            startkey.append(self.settings.service_packages)
            endkey.append(self.settings.service_packages)
            couchdb_view = 'service_package_addon'
        else:
            couchdb_view = 'service_addon'

        if self.settings.service_addons:
            startkey.append(self.settings.service_addons)
            endkey.append(self.settings.service_addons)
        else:
            if self.settings.service_packages:
                couchdb_view = 'service_package_addon'
                endkey.append({})
            else:
                couchdb_view = 'service_type'

        for item in self.db.view(
                self._cmd(couchdb_view),
                startkey=startkey, endkey=endkey, include_docs=True):
            if 'extcrm_id' in item['doc']:
                client_doc  = item['doc']
                extcrm_id = client_doc['extcrm_id']
                service_name = '-'.join([part for part in item['key'] if part])
                included_items = []
                is_billable = client_doc['is_billable'] if 'is_billable' in client_doc else False
                if 'value' in item and 'included_service_items' in item['value']:
                    included_items = [
                        included['itemid'] for included in item['value']['included_service_items']
                    ]
                included_items = ','.join(included_items)
                address_id = client_doc['extcrm_id'] if 'extcrm_id' in client_doc else None
                if 'extcrm_contact_id' in client_doc and client_doc['extcrm_contact_id']:
                    contact_id = client_doc['extcrm_contact_id']
                elif 'p' in extcrm_id:
                    for part in extcrm_id.split('-'):
                        if part.startswith('p'):
                            contact_id = part
                else:
                    contact_id = ''

                if not only_billable or only_billable and is_billable:
                    if address_id and all([
                        self.crm.has_contact(cid.strip()) for cid in contact_id.split(',')
                    ]):
                        contacts = [
                            self.crm.get_contact(cid.strip()) for cid in contact_id.split(',')
                        ]
                        services.append([
                            ','.join([contact.email for contact in contacts]),
                            ','.join([contact.name for contact in contacts]),
                            service_name,
                            included_items,
                            extcrm_id, contact_id
                        ])
                    else:
                        services.append([
                            "# No Email #", "# no contact#", service_name,
                            included_items,
                            extcrm_id, ''
                        ])
            else:
                print("*** no extcrm_id", item)
        for service in services:
            print(';'.join(service))
        print("total: %s" % len(services))
Пример #16
0
class CouchdbManager(PersistenceManager):
    """ This is a couchdb manager for the workspace, it will load from the 
    couchdb databases"""
    def __init__(self, uri):
        self._last_seq_ack = 0
        model.api.log("Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__dbs = {}
        self.__seq_nums = {}
        self.__serv = NoConectionServer()
        self.mutex = threading.Lock()
        self._available = False
        try:
            self.testCouchUrl(uri)
            url = urlparse(uri)
            print("Setting user,pass %s %s" % (url.username, url.password))
            self.__serv = Server(uri=uri)
            #print dir(self.__serv)
            self.__serv.resource_class.credentials = (url.username,
                                                      url.password)
            self._available = True
        except:
            model.api.log("No route to couchdb server on: %s" % uri)
            print(traceback.format_exc())

    def isAvailable(self):
        return self._available

    def lostConnectionResolv(self):
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchdbManager.testCouch(ur):
            self.__serv = Server(uri=ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val

    @staticmethod
    def testCouch(uri):
        host, port = None, None
        try:
            import socket
            url = urlparse(uri)
            proto = url.scheme
            host = url.hostname
            port = url.port

            port = port if port else socket.getservbyname(proto)
            s = socket.socket()
            s.settimeout(1)
            s.connect((host, int(port)))
        except:
            return False
        model.api.log("Connecting Couch to: %s:%s" % (host, port))
        return True

    def testCouchUrl(self, uri):
        url = urlparse(uri)
        proto = url.scheme
        host = url.hostname
        port = url.port
        self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))

    @trap_timeout
    def getWorkspacesNames(self):
        return filter(lambda x: not x.startswith("_"), self.__serv.all_dbs())

    def workspaceExists(self, name):
        return name in self.getWorkspacesNames()

    @trap_timeout
    def addWorkspace(self, aWorkspace):
        self.__serv.create_db(aWorkspace.lower())
        return self.__getDb(aWorkspace)

    @trap_timeout
    def addDocument(self, aWorkspaceName, documentId, aDocument):
        self.incrementSeqNumber(aWorkspaceName)
        self.__getDb(aWorkspaceName)[documentId] = aDocument

    @trap_timeout
    def saveDocument(self, aWorkspaceName, aDocument):
        self.incrementSeqNumber(aWorkspaceName)
        model.api.log("Saving document in remote workspace %s" %
                      aWorkspaceName)
        self.__getDb(aWorkspaceName).save_doc(aDocument,
                                              use_uuids=True,
                                              force_update=True)

    @trap_timeout
    def __getDb(self, aWorkspaceName):
        aWorkspaceName = aWorkspaceName.lower()
        model.api.log("Getting workspace [%s]" % aWorkspaceName)
        workspacedb = self.__dbs.get(aWorkspaceName,
                                     self.__serv.get_db(aWorkspaceName))
        if not self.__dbs.has_key(aWorkspaceName):
            model.api.log("Asking couchdb for workspace [%s]" % aWorkspaceName)
            self.__dbs[aWorkspaceName] = workspacedb
            self.__seq_nums[aWorkspaceName] = workspacedb.info()['update_seq']
        return workspacedb

    @trap_timeout
    def getDocument(self, aWorkspaceName, documentId):
        model.api.log("Getting document for workspace [%s]" % aWorkspaceName)
        return self.__getDb(aWorkspaceName).get(documentId)

    @trap_timeout
    def checkDocument(self, aWorkspaceName, documentName):
        return self.__getDb(aWorkspaceName).doc_exist(documentName)

    @trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        model.api.log("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                model.api.devlog(
                    "workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s"
                    % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path,
                                       **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                model.api.devlog(e)
                raise

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace,
                              dst,
                              mutual=mutual,
                              continuous=continuous,
                              create_target=ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous=continuous, **kwargs)

    def getLastChangeSeq(self, workspaceName):
        self.mutex.acquire()
        seq = self.__seq_nums[workspaceName]
        self.mutex.release()
        return seq

    def setLastChangeSeq(self, workspaceName, seq_num):
        self.mutex.acquire()
        self.__seq_nums[workspaceName] = seq_num
        self.mutex.release()

    @trap_timeout
    def waitForDBChange(self, db_name, since=0, timeout=15000):
        """ Be warned this will return after the database has a change, if
        there was one before call it will return immediatly with the changes
        done"""
        changes = []
        last_seq = max(self.getLastChangeSeq(db_name), since)
        db = self.__getDb(db_name)
        with ChangesStream(db,
                           feed="longpoll",
                           since=last_seq,
                           timeout=timeout) as stream:
            for change in stream:
                if change['seq'] > self.getLastChangeSeq(db_name):
                    changes.append(change)
            last_seq = reduce(lambda x, y: max(y['seq'], x), changes,
                              self.getLastChangeSeq(db_name))
            self.setLastChangeSeq(db_name, last_seq)
        return changes

    @trap_timeout
    def delete_all_dbs(self):
        for db in self.__serv.all_dbs():
            self.__serv.delete_db(db)

    @trap_timeout
    def existWorkspace(self, name):
        return name in self.__serv.all_dbs()

    @trap_timeout
    def workspaceDocumentsIterator(self, workspaceName):
        return filter(lambda x: not x["id"].startswith("_"),
                      self.__getDb(workspaceName).documents(include_docs=True))

    @trap_timeout
    def removeWorkspace(self, workspace_name):
        return self.__serv.delete_db(workspace_name)

    @trap_timeout
    def remove(self, workspace, host_id):
        self.incrementSeqNumber(workspace)
        self.__dbs[workspace].delete_doc(host_id)

    @trap_timeout
    def compactDatabase(self, aWorkspaceName):
        self.__getDb(aWorkspaceName).compact()

    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        workspace = self.__serv.get_or_create_db("reports")
        vmanager.addView(reports, workspace)
        return self.__uri + "/reports/_design/reports/index.html"

    def addViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName)
        for v in vmanager.getAvailableViews():
            vmanager.addView(v, workspace)

    def getViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName)
        return vmanager.getViews(workspace)

    def syncWorkspaceViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self.__getDb(workspaceName)
        installed_views = vmanager.getViews(workspace)
        for v in vmanager.getAvailableViews():
            if v not in installed_views:
                vmanager.addView(v, workspace)

    def incrementSeqNumber(self, workspaceName):
        self.mutex.acquire()
        self.__seq_nums[workspaceName] += 1
        self.mutex.release()
Пример #17
0
class IspmanDnsLDIF(LDIFParser):
    structure_map = {
        'a': ['host', 'ip'],
        'aaaa': ['host', 'ipv6'],
        'cname': ['alias', 'host'],
        'mx': ['host', 'priority'],
        'txt': ['name', 'txt'],
    }

    def __init__(self, input, output, settings, clients_ldif=None, editor=None):
        LDIFParser.__init__(self, input)
        self.domains = {}
        self.domains_lookup = (
            clients_ldif.domains_lookup if clients_ldif else None
        )
        self.editor = editor
        self.a_record_ips = set([])
        self.a_record_hosts = {}
        self.server = Server(settings.couchdb_uri)
        self.db = self.server.get_db(settings.couchdb_db)

    def handle(self, dn, entry):
        if dn.startswith('relativeDomainName='):
            domain = ".".join(
                [dc.split('=')[1] for dc in dn.split(',')
                 if dc.startswith('dc=')]
            )
            domain = domain.decode("utf-8").encode("iso8859-1")
            if domain not in self.domains:
                self.add_domain(domain)

            def cname(entry):
                self.domains[domain]['cname'].append(
                    {'alias': entry['relativeDomainName'][0].strip(),
                     'host': entry['cNAMERecord'][0].strip()}
                )

            def a(entry):
                host = entry['relativeDomainName'][0].strip()
                ip = entry['aRecord'][0].strip()
                self.domains[domain]['a'].append(
                    {'host': host,
                     'ip': ip}
                )
                self.a_record_ips.add(ip)
                full_host = "%s.%s" % (host, domain)
                if ip in self.a_record_hosts:
                    self.a_record_hosts[ip].append(full_host)
                else:
                    self.a_record_hosts[ip] = [full_host]

            def mx(entry):
                entry = entry['mXRecord'][0].split(' ')
                self.domains[domain]['mx'].append(
                    {'host': entry[1].strip(),
                     'priority': entry[0]}
                )

            def ns(entry):
                nameserver = entry['nSRecord'][0]
                self.domains[domain]['nameservers'].append(nameserver)
                self.domains[domain]['nameservers'].sort()

            if "cNAMERecord" in dn:
                cname(entry)
            elif "aRecord" in dn:
                a(entry)
            elif "mXRecord" in dn:
                mx(entry)
            elif "nSRecord" in dn:
                ns(entry)

    def add_domain(self, domain):
        if domain not in self.domains:
            next_uuid = self.server.next_uuid()
            self.domains[domain] = {
                '_id': 'domain-%s' % next_uuid,
                'state': 'new',
                'type': 'domain',
                'domain': domain,
                'a': [],
                'cname': [],
                'mx': [],
                'nameservers': [],
            }
            if self.domains_lookup:
                self.domains[domain]['client_id'] = (
                    self.domains_lookup[domain]
                )
            if self.editor:
                self.domains[domain]['editor'] = self.editor
Пример #18
0
class CouchDbManager(AbstractPersistenceManager):
    """
    This is a couchdb manager for the workspace,
    it will load from the couchdb databases
    """
    def __init__(self, uri):
        super(CouchDbManager, self).__init__()
        getLogger(self).debug(
            "Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__serv = NoConectionServer()
        self._available = False
        try:
            if uri is not None:
                self.testCouchUrl(uri)
                url = urlparse(uri)
                getLogger(self).debug(
                    "Setting user,pass %s %s" % (url.username, url.password))
                self.__serv = Server(uri=uri)
                self.__serv.resource_class.credentials = (url.username, url.password)
                self._available = True
                self.pushReports()
                self._loadDbs()
        except:
            getLogger(self).warn("No route to couchdb server on: %s" % uri)
            getLogger(self).debug(traceback.format_exc())

    #@trap_timeout
    def _create(self, name):
        db = self.__serv.create_db(name.lower())
        return CouchDbConnector(db)

    #@trap_timeout
    def _delete(self, name):
        self.__serv.delete_db(name)

    #@trap_timeout
    def _loadDbs(self):
        conditions = lambda x: not x.startswith("_") and x != 'reports'
        for dbname in filter(conditions, self.__serv.all_dbs()):
            if dbname not in self.dbs.keys():
                getLogger(self).debug(
                    "Asking for dbname[%s], registering for lazy initialization" % dbname)
                self.dbs[dbname] = lambda x: self._loadDb(x)

    def _loadDb(self, dbname):
        db = self.__serv.get_db(dbname)
        seq = db.info()['update_seq']
        self.dbs[dbname] = CouchDbConnector(db, seq_num=seq) 
        return self.dbs[dbname]


    #@trap_timeout
    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        workspace = self.__serv.get_or_create_db("reports")
        vmanager.addView(reports, workspace)
        return self.__uri + "/reports/_design/reports/index.html"

    def lostConnectionResolv(self):
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchDbManager.testCouch(ur):
            self.__serv = Server(uri = ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val

    @staticmethod
    def testCouch(uri):
        if uri is not None:
            host, port = None, None
            try:
                import socket
                url = urlparse(uri)
                proto = url.scheme
                host = url.hostname
                port = url.port

                port = port if port else socket.getservbyname(proto)
                s = socket.socket()
                s.settimeout(1)
                s.connect((host, int(port)))
            except:
                return False
            #getLogger(CouchdbManager).info("Connecting Couch to: %s:%s" % (host, port))
            return True

    def testCouchUrl(self, uri):
        if uri is not None:
            url = urlparse(uri)
            proto = url.scheme
            host = url.hostname
            port = url.port
            self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))

    #@trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        getLogger(self).debug("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                getLogger(self).info("workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s" % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path, **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                getLogger(self).error(e)
                raise 

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace, dst, mutual = mutual, continuous  = continuous, create_target = ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous = continuous, **kwargs)
Пример #19
0
class CouchdbManager(PersistenceManager):
    """ This is a couchdb manager for the workspace, it will load from the 
    couchdb databases"""
    def __init__(self, uri):
        self._last_seq_ack = 0
        getLogger(self).debug("Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__dbs = {} 
        self.__seq_nums = {}
        self.__serv = NoConectionServer()
        self.mutex = threading.Lock()
        self._available = False

        #setting the doc types to load from couch
        def get_types(subclasses):
            if len(subclasses):
                head = subclasses[0]
                tail = []
                if len(subclasses[1:]):
                    tail = subclasses[1:]
                return get_types(head.__subclasses__()) + [head.class_signature] + get_types(tail)
            return []
        self._model_object_types = get_types([ModelObject])
        try:
            if uri is not None:
                self.testCouchUrl(uri)
                url = urlparse(uri)
                getLogger(self).debug("Setting user,pass %s %s" % (url.username, url.password))
                self.__serv = Server(uri=uri)
                #print dir(self.__serv)
                self.__serv.resource_class.credentials = (url.username, url.password)
                self._available = True
        except:
            getLogger(self).warn("No route to couchdb server on: %s" % uri)
            getLogger(self).debug(traceback.format_exc())

    def isAvailable(self):
        return self._available

    def lostConnectionResolv(self): 
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchdbManager.testCouch(ur):
            self.__serv = Server(uri = ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val

    @staticmethod
    def testCouch(uri):
        if uri is not None:
            host, port = None, None
            try:
                import socket
                url = urlparse(uri)
                proto = url.scheme
                host = url.hostname
                port = url.port

                port = port if port else socket.getservbyname(proto)
                s = socket.socket()
                s.settimeout(1)
                s.connect((host, int(port)))
            except:
                return False
            getLogger(CouchdbManager).info("Connecting Couch to: %s:%s" % (host, port))
            return True

    def testCouchUrl(self, uri):
        if uri is not None:
            url = urlparse(uri)
            proto = url.scheme
            host = url.hostname
            port = url.port
            self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))


    @trap_timeout
    def getWorkspacesNames(self):
        return filter(lambda x: not x.startswith("_"), self.__serv.all_dbs())

    def workspaceExists(self, name):
        return name in self.getWorkspacesNames()


    @trap_timeout
    def addWorkspace(self, aWorkspace):
        self.__serv.create_db(aWorkspace.lower())
        return self._getDb(aWorkspace)

    @trap_timeout
    def addDocument(self, aWorkspaceName, documentId, aDocument):
        self._getDb(aWorkspaceName)
        self.incrementSeqNumber(aWorkspaceName)
        self._getDb(aWorkspaceName)[documentId] = aDocument

    @trap_timeout
    def saveDocument(self, aWorkspaceName, aDocument):
        self.incrementSeqNumber(aWorkspaceName)
        getLogger(self).debug("Saving document in remote workspace %s" % aWorkspaceName)
        return self._getDb(aWorkspaceName).save_doc(aDocument, use_uuids = True, force_update = True)

    def _getDb(self, aWorkspaceName):
        if not self.__dbs.has_key(aWorkspaceName):
            self.__getDb(aWorkspaceName)
        return self.__dbs.get(aWorkspaceName, None)

    @trap_timeout
    def __getDb(self, aWorkspaceName): 
        aWorkspaceName = aWorkspaceName.lower()
        getLogger(self).debug("Getting workspace [%s]" % aWorkspaceName)
        workspacedb = self.__dbs.get(aWorkspaceName, self.__serv.get_db(aWorkspaceName))
        if not self.__dbs.has_key(aWorkspaceName): 
            getLogger(self).debug("Asking couchdb for workspace [%s]" % aWorkspaceName)
            self.__dbs[aWorkspaceName] = workspacedb
            self.__seq_nums[aWorkspaceName] = workspacedb.info()['update_seq'] 


        return workspacedb

    @trap_timeout
    def getDocument(self, aWorkspaceName, documentId):
        getLogger(self).debug("Getting document for workspace [%s]" % aWorkspaceName)
        return self._getDb(aWorkspaceName).get(documentId)

    @trap_timeout
    def getDeletedDocument(self, aWorkspaceName, documentId, documentRev):
        return self._getDb(aWorkspaceName).get(documentId, rev=documentRev)

    @trap_timeout
    def checkDocument(self, aWorkspaceName, documentName):
        return  self._getDb(aWorkspaceName).doc_exist(documentName)


    @trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        getLogger(self).debug("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                getLogger(self).info("workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s" % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path, **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                getLogger(self).error(e)
                raise 

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace, dst, mutual = mutual, continuous  = continuous, create_target = ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous = continuous, **kwargs)


    def getLastChangeSeq(self, workspaceName):
        self.mutex.acquire()
        seq = self.__seq_nums[workspaceName]
        self.mutex.release()
        return seq

    def setLastChangeSeq(self, workspaceName, seq_num):
        self.mutex.acquire()
        self.__seq_nums[workspaceName] = seq_num
        self.mutex.release()


    @trap_timeout
    def waitForDBChange(self, db_name, since = 0, timeout = 15000):
        """ Be warned this will return after the database has a change, if
        there was one before call it will return immediatly with the changes
        done"""
        changes = []
        last_seq = max(self.getLastChangeSeq(db_name), since)
        db = self._getDb(db_name)
        with ChangesStream(db, feed="longpoll", since=last_seq, timeout=timeout) as stream:
            for change in stream:
                if change['seq'] > self.getLastChangeSeq(db_name):
                    self.setLastChangeSeq(db_name, change['seq'])
                    if not change['id'].startswith('_design'):
                        #fake doc type for deleted objects
                        doc = {'type': 'unknown', '_deleted': 'False', '_rev':[0]}
                        if not change.get('deleted'):
                            doc = self.getDocument(db_name, change['id'])
                        changes.append(change_factory.create(doc))
        if len(changes):
            getLogger(self).debug("Changes from another instance")
        return changes

    @trap_timeout
    def delete_all_dbs(self):
        for db in self.__serv.all_dbs():
            self.__serv.delete_db(db)

    @trap_timeout
    def existWorkspace(self, name):
        return name in self.__serv.all_dbs()

    @trap_timeout
    def workspaceDocumentsIterator(self, workspaceName): 
        return filter(self.filterConditions, self._getDb(workspaceName).documents(include_docs=True))

    def filterConditions(self, doc):
        ret = True
        ret = ret and not doc["id"].startswith("_")
        ret = ret and doc['doc']["type"] in self._model_object_types

        return ret

    @trap_timeout
    def removeWorkspace(self, workspace_name):
        return self.__serv.delete_db(workspace_name)

    @trap_timeout
    def remove(self, workspace, host_id):
        self.incrementSeqNumber(workspace)
        self.__dbs[workspace].delete_doc(host_id)

    @trap_timeout
    def compactDatabase(self, aWorkspaceName):
        self._getDb(aWorkspaceName).compact()

    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        workspace = self.__serv.get_or_create_db("reports") 
        vmanager.addView(reports, workspace)
        return self.__uri + "/reports/_design/reports/index.html"


    def addViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self._getDb(workspaceName)
        for v in vmanager.getAvailableViews():
            vmanager.addView(v, workspace)

    def getViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self._getDb(workspaceName)
        return vmanager.getViews(workspace)

    def syncWorkspaceViews(self, workspaceName):
        vmanager = ViewsManager()
        workspace = self._getDb(workspaceName) 
        installed_views = vmanager.getViews(workspace)
        for v in vmanager.getAvailableViews():
            if v not in installed_views: 
                vmanager.addView(v, workspace)

    def incrementSeqNumber(self, workspaceName):
        self.mutex.acquire()
        if not self.__seq_nums.has_key(workspaceName):
            self.__seq_nums[workspaceName] = 0
        self.__seq_nums[workspaceName] += 1 
        self.mutex.release()
Пример #20
0
import httplib2
import json

h = httplib2.Http()
resp, content = h.request('http://localhost:5984/jlblog','POST',json.dumps({'oi':1}),headers={'Content-Type':'application/json'})

resp, content = h.request('http://localhost:5984/jlblog/users','GET')
c = json.loads(content)

c.has_key('admin')
c.get('admin')

from couchdbkit import Server

s = Server()
db = s.get_db('jlblog')
db.save_doc(dict(oi=1))
Пример #21
0
class CouchDbManager(AbstractPersistenceManager):
    """
    This is a couchdb manager for the workspace,
    it will load from the couchdb databases
    """
    def __init__(self, uri):
        super(CouchDbManager, self).__init__()
        getLogger(self).debug("Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self.__serv = NoConectionServer()
        self._available = False
        try:
            if uri is not None:
                self.testCouchUrl(uri)
                url = urlparse(uri)
                getLogger(self).debug("Setting user,pass %s %s" %
                                      (url.username, url.password))
                self.__serv = Server(uri=uri)
                self.__serv.resource_class.credentials = (url.username,
                                                          url.password)
                self._available = True
                self.pushReports()
                self._loadDbs()
        except:
            getLogger(self).warn("No route to couchdb server on: %s" % uri)
            getLogger(self).debug(traceback.format_exc())

    #@trap_timeout
    def _create(self, name):
        db = self.__serv.create_db(name.lower())
        return CouchDbConnector(db)

    #@trap_timeout
    def _delete(self, name):
        self.__serv.delete_db(name)

    #@trap_timeout
    def _loadDbs(self):
        conditions = lambda x: not x.startswith("_"
                                                ) and x not in CONST_BLACKDBS
        try:
            for dbname in filter(conditions, self.__serv.all_dbs()):
                if dbname not in self.dbs.keys():
                    getLogger(self).debug(
                        "Asking for dbname[%s], registering for lazy initialization"
                        % dbname)
                    self.dbs[dbname] = lambda x: self._loadDb(x)
        except restkit.errors.RequestError as req_error:
            getLogger(self).error(
                "Couldn't load databases. "
                "The connection to the CouchDB was probably lost. ")

    def _loadDb(self, dbname):
        db = self.__serv.get_db(dbname)
        seq = db.info()['update_seq']
        self.dbs[dbname] = CouchDbConnector(db, seq_num=seq)
        return self.dbs[dbname]

    def refreshDbs(self):
        """Refresh databases using inherited method. On exception, asume
        no databases are available.
        """
        try:
            return AbstractPersistenceManager.refreshDbs()
        except:
            return []

    #@trap_timeout
    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        try:
            workspace = self.__serv.get_or_create_db("reports")
            vmanager.addView(reports, workspace)
        except:
            getLogger(self).warn(
                "Reports database couldn't be uploaded. You need to be an admin to do it"
            )
        return self.__uri + "/reports/_design/reports/index.html"

    def lostConnectionResolv(self):
        self._lostConnection = True
        self.__dbs.clear()
        self.__serv = NoConectionServer()

    def reconnect(self):
        ret_val = False
        ur = self.__uri
        if CouchDbManager.testCouch(ur):
            self.__serv = Server(uri=ur)
            self.__dbs.clear()
            self._lostConnection = False
            ret_val = True

        return ret_val

    @staticmethod
    def testCouch(uri):
        """Redirect to the module-level function of the name, which
        serves the same purpose and is used by other classes too."""
        return test_couch(uri)

    def testCouchUrl(self, uri):
        if uri is not None:
            url = urlparse(uri)
            proto = url.scheme
            host = url.hostname
            port = url.port
            self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))

    #@trap_timeout
    def replicate(self, workspace, *targets_dbs, **kwargs):
        getLogger(self).debug("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                getLogger(self).info(
                    "workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s"
                    % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path,
                                       **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                getLogger(self).error(e)
                raise

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace,
                              dst,
                              mutual=mutual,
                              continuous=continuous,
                              create_target=ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous=continuous, **kwargs)
Пример #22
0
class CouchDbManager(AbstractPersistenceManager):
    """
    This is a couchdb manager for the workspace,
    it will load from the couchdb databases
    """
    def __init__(self, uri, couch_exception_callback):
        super(CouchDbManager, self).__init__()
        getLogger(self).debug(
            "Initializing CouchDBManager for url [%s]" % uri)
        self._lostConnection = False
        self.__uri = uri
        self._available = False
        self.couch_exception_callback = couch_exception_callback
        test_couch_thread = threading.Thread(target=self.continuosly_check_connection)
        test_couch_thread.daemon = True
        test_couch_thread.start()
        try:
            if uri is not None:
                self.testCouchUrl(uri)
                url = urlparse(uri)
                getLogger(self).debug(
                    "Setting user,pass %s %s" % (url.username, url.password))
                self.__serv = Server(uri=uri)
                self.__serv.resource_class.credentials = (url.username, url.password)
                self._available = True
                self.pushReports()
                self._loadDbs()
        except:
            getLogger(self).warn("No route to couchdb server on: %s" % uri)
            getLogger(self).debug(traceback.format_exc())

    def continuosly_check_connection(self):
        """Intended to use on a separate thread. Call module-level
        function testCouch every second to see if response to the server_uri
        of the DB is still 200. Call the exception_callback if we can't access
        the server three times in a row.
        """
        tolerance = 0
        server_uri = self.__uri
        while True:
            time.sleep(1)
            test_was_successful = test_couch(server_uri)
            if test_was_successful:
                tolerance = 0
            else:
                tolerance += 1
                if tolerance == 3:
                    self.couch_exception_callback()
                    return False  # kill the thread if something went wrong

    def _create(self, name):
        db = self.__serv.create_db(name.lower())
        return CouchDbConnector(db)

    def _delete(self, name):
        self.__serv.delete_db(name)

    def _loadDbs(self):

        def conditions(database):
            begins_with_underscore = database.startswith("_")
            is_blacklisted = database in CONST_BLACKDBS
            return not begins_with_underscore and not is_blacklisted

        try:
            for dbname in filter(conditions, self.__serv.all_dbs()):
                if dbname not in self.dbs.keys():
                    getLogger(self).debug(
                        "Asking for dbname[%s], registering for lazy initialization" % dbname)
                    self.dbs[dbname] = lambda x: self._loadDb(x)
        except restkit.errors.RequestError as req_error:
            getLogger(self).error("Couldn't load databases. "
                                  "The connection to the CouchDB was probably lost. ")

    def _loadDb(self, dbname):
        db = self.__serv.get_db(dbname)
        seq = db.info()['update_seq']
        self.dbs[dbname] = CouchDbConnector(db, seq_num=seq)
        return self.dbs[dbname]

    def refreshDbs(self):
        """Refresh databases using inherited method. On exception, asume
        no databases are available.
        """
        try:
            return AbstractPersistenceManager.refreshDbs()
        except:
            return []

    def pushReports(self):
        vmanager = ViewsManager()
        reports = os.path.join(os.getcwd(), "views", "reports")
        try:
            workspace = self.__serv.get_or_create_db("reports")
            vmanager.addView(reports, workspace)
        except:
            getLogger(self).warn(
                "Reports database couldn't be uploaded. You need to be an admin to do it")
        return self.__uri + "/reports/_design/reports/index.html"

    @staticmethod
    def testCouch(uri):
        """Redirect to the module-level function of the name, which
        serves the same purpose and is used by other classes too."""
        return test_couch(uri)

    def testCouchUrl(self, uri):
        if uri is not None:
            url = urlparse(uri)
            host = url.hostname
            port = url.port
            self.test(host, int(port))

    def test(self, address, port):
        import socket
        s = socket.socket()
        s.settimeout(1)
        s.connect((address, port))

    def replicate(self, workspace, *targets_dbs, **kwargs):
        getLogger(self).debug("Targets to replicate %s" % str(targets_dbs))
        for target_db in targets_dbs:
            src_db_path = "/".join([self.__uri, workspace])
            dst_db_path = "/".join([target_db, workspace])
            try:
                getLogger(self).info("workspace: %s, src_db_path: %s, dst_db_path: %s, **kwargs: %s" % (workspace, src_db_path, dst_db_path, kwargs))
                self.__peerReplication(workspace, src_db_path, dst_db_path, **kwargs)
            except ResourceNotFound as e:
                raise e
            except Exception as e:
                getLogger(self).error(e)
                raise

    def __peerReplication(self, workspace, src, dst, **kwargs):
        mutual = kwargs.get("mutual", True)
        continuous = kwargs.get("continuous", True)
        ct = kwargs.get("create_target", True)

        self.__serv.replicate(workspace, dst, mutual = mutual, continuous  = continuous, create_target = ct)
        if mutual:
            self.__serv.replicate(dst, src, continuous = continuous, **kwargs)
Пример #23
0
class DocsProcessor(SettingsCommand):
    allowed_template_type = None  # needs to be set by subclass
    map_id = None  # needs to be set by subclass
    replace_id = None  # needs to be set by subclass
    _map_cache = None
    _map_cache_time = None

    @classmethod
    def map_cache(cls):
        if cls._map_cache_time and time.time() > (cls._map_cache_time + 3600):
            cls._map_cache = None
        return cls._map_cache

    @classmethod
    def set_map_cache(cls, value):
        cls._map_cache_time = time.time()
        cls._map_cache = value

    def __init__(self, settings, docs):
        self.set_settings(settings)
        template_ids, map_id = self.settings.template_ids, self.settings.map_id
        template_ids = template_ids.split(',') if template_ids else []
        self.server = Server(uri=self.settings.couchdb_uri)
        self.db = self.server.get_db(self.settings.couchdb_db)
        self.template_docs, self.map_keys = [], None
        if not template_ids:
            self.template_docs = self.get_all_templates()
        else:
            self.template_docs = self.get_templates(template_ids)
        if self.map_id:
            self.map_dict = self.get_map()
            self.map_keys = self.map_dict.keys()
        if self.replace_id:
            self.replace_dict = self.get_replace()
            self.replace_keys = self.replace_dict.keys()
        self.docs = docs

    def clean_template(self, template_doc):
        attrs_to_delete = [
            '_rev', 'type', 'template_type', 'template_autoload', 'name'
        ]
        for attr in attrs_to_delete:
            del template_doc[attr]
        if (hasattr(self, 'postprocess_tpl')
           and callable(self.postprocess_tpl)):
            template_doc = self.postprocess_tpl(template_doc)
        return template_doc

    def get_map(self):
        map_dict = self.map_cache()
        if map_dict:
            return map_dict
        try:
            map_dict = self.db.get(self.map_id)['map']
            self.set_map_cache(map_dict)
        except ResourceNotFound:
            pass
        return map_dict

    def get_replace(self):
        replace_dict = None
        try:
            replace_dict = self.db.get(self.replace_id)['replace']
        except ResourceNotFound:
            pass
        return replace_dict

    def get_templates(self, template_ids):
        docs = []
        for doc_id in template_ids:
            template_doc = self.clean_template(self.db.get(doc_id))
            docs.append(template_doc)
        return docs

    def get_all_templates(self):
        docs = []
        for t in self.db.view("%s/template" % (self.settings.couchdb_db)):
            template_doc = self.db.get(t['id'])
            if (template_doc['template_type'] == self.allowed_template_type
               and 'template_autoload' in template_doc
               and template_doc['template_autoload'] is True):
                docs.append(self.clean_template(template_doc))
        # assumption that templates with more keys will be checked first
        docs.sort(key=len)
        docs.reverse()
        return docs

    def is_child_of(self, parent, child):
        def is_child_of_inner(parent, child):
            for key, value in child.iteritems():
                if key in parent and (parent[key] == value or key == '_id'):
                    yield True
                else:
                    yield False
        is_child = all(is_child_of_inner(parent, child))
        return is_child

    def replace_with_template(self, doc, template):
        for key in template.keys():
            if key != '_id':
                del doc[key]
        doc['template_id'] = template['_id']

    def process_doc(self, doc):
        if self.template_docs:
            for template in self.template_docs:
                if self.is_child_of(doc, template):
                    self.replace_with_template(doc, template)
                    break
        if (hasattr(self, 'postprocess_doc')
           and callable(self.postprocess_doc)):
            doc = self.postprocess_doc(doc)
        return doc

    def process(self):
        for doc in self.docs:
            doc[1] = self.process_doc(doc[1])