def setup(self, config, full_sync=False): self.storage = StorageFactory.get(config.get('storage')) self.services = self.setup_services(config, self.storage) self.setup_copydog(config.get('copydog')) self.setup_last_time_read(full_sync) self.mapper = Mapper(storage=self.storage, services=self.services, config=config) self.mapper.save_list_status_mapping() self.mapper.save_user_member_mapping()
class Watch(object): available_services = { 'redmine': RedmineAdapter, 'trello': TrelloAdapter } def __init__(self, config=None, full_sync=None): log.info('Copydog is on duty...') if config: self.setup(config, full_sync) def setup(self, config, full_sync=False): self.storage = StorageFactory.get(config.get('storage')) self.services = self.setup_services(config, self.storage) self.setup_copydog(config.get('copydog')) self.setup_last_time_read(full_sync) self.mapper = Mapper(storage=self.storage, services=self.services, config=config) self.mapper.save_list_status_mapping() self.mapper.save_user_member_mapping() def setup_copydog(self, options=False): if not options: return pandoc.PANDOC_PATH = options.get('pandoc', '/usr/bin/pandoc') self.beat_interval = options.get('beat', 60) def setup_services(self, config, storage): clients_config = config.clients services = {} for service_name, options in clients_config: service_class = self.available_services[service_name] services[service_name] = service_class(options, storage) return services def setup_last_time_read(self, full_sync=False): """ Ignoring last time read, when using full_sync, If launching for first time, make sure we're monitoring only recent changes. TODO: remove hardcoded services """ if full_sync: self.storage.reset_last_time_read() else: if not self.storage.get_last_time_read('redmine'): self.storage.mark_read('redmine') self.storage.mark_read('trello') def run(self): """ Run copydog in a loop, starting sync every N seconds (60 is default). """ self.scheduler = sched.scheduler(time.time, time.sleep) periodic(self.scheduler, self.beat_interval, self.sync) self.scheduler.run() def sync(self): groups = itertools.groupby(itertools.permutations(self.services, 2), lambda pair:pair[0]) for service_from_name, services in groups: service_from = self.services[service_from_name] issues = service_from.read() num_issues_read = 0 services = list(services) for issue in issues: if self.is_already_synced(issue): continue num_issues_read += 1 service_from.mark_read(issue) for service_from_name, service_to_name in services: service_to = self.services[service_to_name] if service_to.writable: service_to.write(issue) log.info('Read %s new issues from %s', num_issues_read, service_from) def is_already_synced(self, issue): """ Check issue needs sync Read from API last_updated > read from storage last_updated thus preventing clones """ last_time_synced = self.storage.get_last_time_updated(issue.client.service_name, issue) log.debug('Comparing %s <= %s (%s)' % (issue.last_updated, last_time_synced, (last_time_synced and issue.last_updated <= last_time_synced))) return last_time_synced and issue.last_updated <= last_time_synced