Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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
Example #9
0
 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")