def update(self, thresh=1, from_resources=None, save=True): """Given an existing .zenodo.json file, update it with contributors from an allcontributors file. """ self.thresh = thresh self.load_data() bot.info("Updating %s" % self.filename) # Read in contributors, and update cache (also runs update_lookup) self.lookup = self.data.get("contributor", []) self.update_cache() # Get fields from repo self.update_metadata() self.update_from_logins(from_resources.get("login", [])) self.update_from_orcids(from_resources.get("orcid", [])) self.update_from_names(from_resources.get("name", [])) self.update_from_emails(from_resources.get("email", [])) self.data["contributor"] = self.lookup if save: write_json(self.data, self.filename) return self.data
def init(self, force=False, from_resources=None, save=True): """Given an allcontributors file (we default to the one expected) and a preference to force, write the empty file to the repository. If the file exists and force is false, exit on error. If the user has not provided a full repository name and it's not in the environment, also exit on error Arguments: - repo (str) : the full name of the repository on GitHub - force (bool) : if the contributors file exists, overwrite - filename (str) : default filename to write to. """ filename = self.params.get("--allcontrib-file", self.filename) if os.path.exists(filename) and not force: sys.exit("%s exists, set --force to overwrite." % filename) bot.info(f"Generating {filename} for {self.repo.uid}") owner, repo = self.repo.uid.split("/")[:2] # Write metadata to empty all contributors file. metadata = { "projectName": repo, "projectOwner": owner, "repoType": "github", "repoHost": "https://github.com", "files": ["README.md"], "imageSize": 100, "commit": True, "commitConvention": "none", "contributors": [], "contributorsPerLine": 7, } if save: write_json(metadata, filename) return metadata
def update(self, params=None, repo=None, contributors=None, thresh=1): """Given an existing contributors file, use the GitHub API to retrieve all contributors, and then use subprocess to update the file """ params = params or {} self.thresh = thresh filename = params.get("--allcontrib-file", self.filename) if not os.path.exists(filename): sys.exit( "%s does not exist, set --allcontrib-filename or run init to create" % self.filename) bot.info(f"Updating {filename}") # Get optional (or default) contributor type ctype = params.get("--allcontrib-type", "code") if ctype not in self.contribution_types: sys.exit( f"Invalid contribution type {ctype}. See https://allcontributors.org/docs/en/emoji-key for types." ) # Load the previous contributors, create a lookup data = read_json(filename) self.lookup = {x["login"]: x for x in data.get("contributors", [])} self._repo = "%s/%s" % (data["projectOwner"], data["projectName"]) self.update_cache() # Update the lookup for login, metadata in self.cache.items(): if login in self.lookup: entry = self.lookup[login] else: entry = { "login": login, "name": metadata.get("name") or login, "avatar_url": self.contributors.get(login, {}).get("avatar_url"), "profile": metadata.get("blog") or self.contributors.get(login, {}).get("html_url"), "contributions": [ctype], } if ctype not in entry["contributions"]: entry["contributions"].append(ctype) self.lookup[login] = entry # Update the contributors data["contributors"] = list(self.lookup.values()) write_json(data, filename) return data
def update(self, thresh=1, from_resources=None, save=True): """Given an existing contributors file, use the GitHub API to retrieve all contributors, and then use subprocess to update the file """ self.thresh = thresh self.load_data() from_resources = from_resources or {} bot.info(f"Updating {self.filename}") # Get optional (or default) contributor type ctype = self.params.get("--allcontrib-type", "code") if ctype not in self.contribution_types: sys.exit( f"Invalid contribution type {ctype}. See https://allcontributors.org/docs/en/emoji-key for types." ) # Sanity check that we have the correct repository repo = "%s/%s" % (self.data["projectOwner"], self.data["projectName"]) if repo != self.repo.uid: bot.warning( f"Found different repository {repo} in {self.filename}, updating from {self.repo.uid}" ) self._repo = GitHubRepository(repo) # Update the cache from GitHub, and .tributors lookup self.update_cache() # Parse over logins, start with existing values self.lookup = { x["login"]: x for x in self.data.get("contributors", []) if "login" in x } self.extras = [ x for x in self.data.get("contributors", []) if "login" not in x ] # This client only supports update from names and logins self.update_from_logins(from_resources.get("login", []), ctype) self.update_from_names(from_resources.get("names", []), ctype) self.update_from_orcids(from_resources.get("orcid", [])) self.update_from_emails(from_resources.get("email", [])) # Update the contributors self.data["contributors"] = list(self.lookup.values()) + self.extras if save: write_json(self.data, self.filename) return self.data
def init(self, repo, params=None, force=False, contributors=None): """Generate an empty .zenodo.json if it doesn't exist """ params = params or {} # A doi is required doi = params.get("--doi") if not doi: sys.exit("Please provide the zenodo doi with --doi") # Zenodo file defaults to expected .zenodo.json zenodo_file = params.get("--zenodo-file", self.filename) if os.path.exists(zenodo_file) and not force: sys.exit("%s exists, set --force to overwrite." % zenodo_file) bot.info("Generating %s" % zenodo_file) self._repo = get_github_repository(repo) record = get_zenodo_record(doi) # Assume we want to add known contributors creators = record["metadata"].get("creators", []) self.update_cache() for login, metadata in self.cache.items(): entry = {"name": metadata.get("name") or login} if "orcid" in metadata: entry["orcid"] = metadata["orcid"] if "bio" in metadata or "affiliation" in metadata: entry["affilitation"] = metadata.get("affiliation", metadata.get("bio")) creators.append(entry) # Get keywords from GitHub topis keywords = get_topics(self.repo) keywords = list(set(record["metadata"]["keywords"] + keywords)) # Update final metadata metadata = { "creators": creators, "upload_type": record["metadata"]["resource_type"]["type"], "keywords": keywords, "access_right": record["metadata"]["access_right"], "license": record["metadata"]["license"]["id"], } write_json(metadata, zenodo_file) return metadata
def init(self, force=False, from_resources=None, save=True): """Generate an empty .zenodo.json if it doesn't exist """ from_resources = from_resources or {} doi = self.params.get("--doi") # Zenodo file defaults to expected .zenodo.json zenodo_file = self.params.get("--zenodo-file", self.filename) if os.path.exists(zenodo_file) and not force: sys.exit("%s exists, set --force to overwrite." % zenodo_file) bot.info("Generating %s" % zenodo_file) # If a doi is provided, generate record = None self.data["creators"] = [] if doi: record = get_zenodo_record(doi) self.data["creators"] = record["metadata"].get("creators", []) self.update_cache(update_lookup=False) # Update zenodo file from GitHub logins (default) or other self.update_from_logins(from_resources.get("login", [])) self.update_from_orcids(from_resources.get("orcid", [])) self.update_from_names(from_resources.get("name", [])) self.update_from_emails(from_resources.get("email", [])) # Update final metadata metadata = { "creators": self.data["creators"], "upload_type": "software", "keywords": self.repo.topics(), } # If we have a zenodo record, update it if record: metadata["upload_type"] = record["metadata"]["resource_type"][ "type"] metadata["keywords"] = self.repo.topics( record["metadata"]["keywords"]) metadata["access_right"] = record["metadata"]["access_right"] metadata["license"] = record["metadata"]["license"]["id"] if save: write_json(metadata, zenodo_file) return metadata
def update(self, thresh=1, from_resources=None, save=True): """Given an existing .zenodo.json file, update it with contributors from an allcontributors file. """ from_resources = from_resources or {} self.thresh = thresh self.load_data() bot.info("Updating %s" % self.filename) self.update_cache() # Here we can only reasonable update from orcids (not logins) self.update_orcids() self.update_from_emails(from_resources.get("email", [])) self.update_from_orcids(from_resources.get("orcid", [])) self.update_from_names(from_resources.get("names", [])) if save: write_json(self.data, self.filename) return self.data
def update(self, repo=None, params=None, contributors=None, thresh=1): """Given an existing .zenodo.json file, update it with contributors from an allcontributors file. """ params = params or {} self.thresh = thresh zenodo_file = params.get("--zenodo-file", self.filename) # Ensure contributors file and zenodo.json exist if not os.path.exists(zenodo_file): sys.exit("%s does not exist" % zenodo_file) bot.info("Updating %s" % zenodo_file) # We don't currently have a reliable identifier for zenodo, so we recreate each time data = read_json(zenodo_file) self.lookup = data.get("creators", []) creators = [] self._repo = get_github_repository(repo) self.update_cache() for login, metadata in self.cache.items(): entry = {"name": metadata.get("name") or login} if login in self.cache: for field in ["name", "affiliation", "orcid"]: if field in self.cache[login]: entry[field] = self.cache[login][field] if "orcid" in metadata and "orcid" not in entry: entry["orcid"] = metadata["orcid"] if "affiliation" in metadata and "affiliation" not in entry: entry["affilitation"] = metadata["affiliation"] creators.append(entry) data["creators"] = creators write_json(data, zenodo_file) return data
def save_cache(self): """Save the current self.cache to the cache file .tributors in the PWD """ if not self.skip_cache: bot.debug("Saving cache to .tributors") write_json(self.cache, ".tributors")