def next_repo( queue, local=False ): """Gets next collection_path or time til next ready to be updated @param queue: @param local: Boolean Use local per-collection locks or global lock. @returns: collection_path or (msg,timedelta) """ collection_path = None message = None next_available = None # sorts collections in ascending order by timestamp collections = sorted(queue['collections']) # now choose if local: # choose first collection that is not locked for timestamp,cid in collections: if datetime.now() > timestamp: ci = Identifier(id=cid) if not Collection.from_identifier(ci).locked(): return ci.path_abs() if (not next_available) or (timestamp < next_available): next_available = timestamp else: # global lock - just take the first collection for timestamp,cid in collections: if datetime.now() > timestamp: ci = Identifier(id=cid) return ci.path_abs() if (not next_available) or (timestamp < next_available): next_available = timestamp return ('notready',next_available)
def sync_status( collection_path, git_status, timestamp, cache_set=False, force=False ): """Cache collection repo sync status info for collections list page. Used in both .collections() and .sync_status_ajax(). TODO do we need to cache this any more? we're writing this to REPO/.gitstatus @param collection: @param cache_set: Run git-status if data is not cached """ # IMPORTANT: DO NOT call collection.gitstatus() it will loop cidentifier = Identifier(collection_path) collection_id = cidentifier.id key = COLLECTION_SYNC_STATUS_CACHE_KEY % collection_id data = cache.get(key) if force or (not data and cache_set): # we're just getting this so we can call Collection.locked disposable_collection = Collection.from_identifier(cidentifier) # now: status = 'unknown' if dvcs.synced(git_status): status = 'synced' elif dvcs.ahead(git_status): status = 'ahead' elif dvcs.behind(git_status): status = 'behind' elif dvcs.conflicted(git_status): status = 'conflicted' elif disposable_collection.locked(): status = 'locked' if isinstance(timestamp, datetime): timestamp = timestamp.strftime(settings.TIMESTAMP_FORMAT) data = { 'timestamp': timestamp, 'status': status, 'color': SYNC_STATUS_BOOTSTRAP_COLOR[status], 'row': '#%s' % collection_id, 'cell': '#%s td.status' % collection_id, } cache.set(key, data, COLLECTION_STATUS_TIMEOUT) return data
def queue_generate( base_dir, repos_orgs ): """Generates a new queue file @param base_dir: Absolute path to Store dir @param repos_orgs: Output of gitolite.get_repos_orgs. @returns: queue understandable by queue_loads, queue_dumps """ log('regenerating gitstatus queue') queue = {'collections': []} cids = [] # gitstatuses for path in status_paths(base_dir): collection_id = path.replace(tmp_dir(base_dir), '').replace('/','').replace('.status', '') status = read(base_dir, collection_id) # read timestamp from .status file queue['collections'].append( (status['timestamp'],collection_id) ) cids.append(collection_id) # collections without gitstatuses epoch = datetime.fromtimestamp(0) for o in repos_orgs: repo,org = o.split('-') for path in Collection.collection_paths(base_dir, repo, org): collection_id = os.path.basename(path) if not collection_id in cids: cids.append(collection_id) queue['collections'].append( (epoch,collection_id) ) queue['generated'] = datetime.now() return queue
def next_repo( queue, local=False ): """Gets next collection_path or time til next ready to be updated @param queue: @param local: Boolean Use local per-collection locks or global lock. @returns: collection_path or (msg,timedelta) """ collection_path = None message = None next_available = None # sorts collections in ascending order by timestamp collections = sorted(queue['collections']) # now choose if local: # choose first collection that is not locked for timestamp,cid in collections: if datetime.now() > timestamp: cpath = os.path.join(settings.MEDIA_BASE, cid) collection = Collection.from_json(cpath) if not collection.locked(): collection_path = cpath return collection_path if (not next_available) or (timestamp < next_available): next_available = timestamp else: # global lock - just take the first collection for timestamp,cid in collections: if datetime.now() > timestamp: collection_path = os.path.join(settings.MEDIA_BASE, cid) return collection_path if (not next_available) or (timestamp < next_available): next_available = timestamp return ('notready',next_available)