From 8efe21d6c5b1fc2fd5d1bd02a3121810fff8bbc7 Mon Sep 17 00:00:00 2001 From: Violeta-Tejera <80209320+Violeta-Tejera@users.noreply.github.com> Date: Fri, 26 Jan 2024 15:20:18 +0100 Subject: [PATCH] Ready for 1st release --- api/__pycache__/repo.cpython-311.pyc | Bin 5099 -> 5267 bytes api/__pycache__/user.cpython-311.pyc | Bin 12861 -> 14444 bytes api/repo.py | 22 ++-- api/user.py | 117 ++++++++++++++++-- config.json | 8 +- githubwrapped.py | 43 ++++--- languages_extensions.db | Bin 69632 -> 49152 bytes requirements.txt | Bin 47 -> 98 bytes .../github_helpers.cpython-311.pyc | Bin 3089 -> 4585 bytes utils/__pycache__/helpers.cpython-311.pyc | Bin 2362 -> 3239 bytes utils/github_helpers.py | 62 ++++++++-- utils/helpers.py | 25 ++++ 12 files changed, 228 insertions(+), 49 deletions(-) diff --git a/api/__pycache__/repo.cpython-311.pyc b/api/__pycache__/repo.cpython-311.pyc index c6512528a00bb86f68efb9059f6ffd4d5a8f49e6..0dbb81de11637d96fd29146fade00819d51b5aa1 100644 GIT binary patch delta 678 zcma)4&x;c=6i%iy({{R36`5&!Z1K)+<#NB zce~-CYaNq3M-=rC#ncfvae5B6ye4Xi+jA@K3a{r;kGa%mPT!^V9k=IGcLPNY(%uy> z+yDUbCO)?pXf{bjMyOf`yI6GbX$RxtNp0QVUfDp@M6^14+m$@k3WyM(G|^mXzNw&} zNgyzi*%qgaf@Gr%NJ?R>m<+5OT$KaWshG{|I;`C@c!OvXb-+@XFqn{3gSN#)OlJ)G zGE3mP9x@nZ#u&0bY;iWRvmSC)IsH+sY}f7@bH#Ngr$*N%)qe4znPTkaCtFYP?c#lF z886+54wl}?-luH#$3ny@Ntj&7zb#CUv`lx)1|^zlp0F|)FdcKH#!Sfr`Qz|r%QHVn z-@@ViQ}_V4^Rw-pGka{=Vx<}XZBJ|uCNG%1qbAg%i_nip=zAM^LGh)1%-yb+^*E;4 zW*nFPfa~G-p{!Y@1{v{FwpY@WAbH$^m67%-$bA;9R{s4y+cbZ+f9Z;U3*#<+*_fk>ybgYo|Cp+i`~rGYxkCT| delta 489 zcma)$F-yZh6vyu+mo!b9MlBZ9796xv5FJD(5kXKv5Wy`VC305{Bx$)Mh?5wL8vMocdWe@v`trR)-R9htqRftOEE+(ZRwo3#bqPFJfH>VHWfYot*wlLB= z3%s5~!o}nOmZh?ksyl9U8XqSEc~RBTq4-cVHusZ24**pDW?aEe;#a1j-ma%gpSeMl zmbL)bnxM3L6kWKQH>aL-R2dtE%!7r;vVDb0r z5XQJ`&D7RKc}_%F!w7v2&>Jo%_tqQ+jlb0D7fe*eaHsDs#UW)($)~h(y><^sx-rVb( z+UXFQo4z@I-}5~0bKdjbbC2>S{_C>m`);?3W1n~4*pRnVH$7LUz94X%>r@r5l;v5p zqR1qN^R;}gn6KcnOkA$B#gc-S)Hqru)hi_|D>uLOn){SoD^{^G>q6{97x<%H>fm|) zf(-^~L|+%Ab<1hZecJM*I@tKOWz0%{B|KGs$-;5pGB0`8J+ zSdi`5CfgTX*uK`4b;wTaSmVCOl-~yV>L=@xU7y>hf5XlWaVK`QdAsFqhWhXh4)5zQ z!HK)uyl&auN=CPB67Qs5dtclmds=?n(}wdf=_1Y9rFu)Mw{2Dro7LOq6=l)H-Pa-R z#J)DKSN57vk{r&FhnWCRCt9 z+=+wtd+S+AmQ1kF{S&eh9$w?J{W#3*07lFX;s~=tc!XI$jxKOxu`S0r*2TwI6R%FH z&H1r%UQtl3ij-QF$f#D75wtj3B-JJL8+5&bTv~(Pas0%}Ptj+)|2{Fsua2t>(9p-_ zT1_Tsu}aY8QmwdhDOai}wS1)@8&l}2dqzCXN~gG)xxqDEoam!JcTZ3AOqj()w($OB z88W)=d00FTbiF#=$S9rn%+4@j`;Dw7VM?)jHAm#-D$}-DHD>&PCqc$Ql62iOE`A0W z%>v)@OwVcpTcjp|dyr;G8aPwb+mjYCa2hHj33{?;_7GDUH#C@3Lb)sXrB>aTKA)!V z>pcnS^T5^3%uWHnQr~n8)7QKcQ<}&Yr%7ZRXNF7wWr}u-qap#y9-T6P=$v@u0FxK# zB=4G>Cx)L%lYl2lpB6`?Yi#(gS=#kYhaaR(Xwq7ICTY9)GUPDOrRaNNRJ;LnhOB`g z-S0gz&18)k=}lErw_%x-uHI#OoH3^1nX z-@N<9=Yi4K*Kmv`dS~}69PELioE2_RQ&#C6aef1aQ_Q?yv37A}2%OSP%H7_m?L`<) zQ@-!eo+T<&mzGMk928tJ3kd-YsGp zf#KuKKv!ITK(#wjWk?3#ZTjFvV5+tW+JN~VhenxVjWTM8GBpZ32kJ?_tC0f$Oj6sx z!T#T~q4^YV^q@@#0{!!v{uZsNTRPBY$QfX5lfS^c6b(q?JCMofjnK$?D75j1f#2}_ zAL;F(TL%pFnQBeeZiDc;giji2mqf&FkUJ+AJ?l^KkJ0P?48K5s?N1LumA33VQ8EWo zpiRjMDhA@Vo#D|yn!i9xfr9%_AZD6}m%~5Ajo$^n#Pj#)Q=yllhKw_EZG}{J?xmUz zgvuqQHcMASsf~Y!PV$xjPmhPMFa@IPjh3ECa$bLg~m zlOJlmc=pbL&QM$AVCy|VvalF9E5@t@N=jhCBu76PK|H2kj2w3($PZpfzwuV&kfojv zGM}CrZXOECBU~!fO4Ul9Ttipc1q9{GW%c$_&Q~t4&SUrOuy$stmsJC< zt~;Z46gf|msRGg#%vQZ+&0|cSh4sT7Z>x*la%J)~y`4%8V{q6tLWLAz&P_1uU?_bz z^_=?@)ajO1r{0a{_P@&W0Xmb8Nn7?@4p$4g9I*n6RjCnjgBH_|)aL-LJ)Ih)iF0`O%NqN5NE8Xgw*Kr9ZixCt2tq^}|P zH5#2aV0d(77?5Fxtm{d`0QIcp0Er-qfLGETIxqmCfGK4FaIUorfD1w}2tlvz&~Z@+ zMNPOU;CdT%VGxip2*)5i)X+UT^n*^R^Q#%_9aD~goDq}S5m4)G2m>ItwU$A{ql<0D zb~bZoox75na@J#N-GTQ1PZ|Na5tG~qkcthVe>d-d;pt8aV@-~k&#Jb0mft5xP0ld> z9$2MeVnYJ!7{g2-VZF(<8|}$}=OHuZBHv}d>G-KgWE8{E*FH4=ks^ m<+y3(dA?~$@Lf#~%#-xh$xl3TPT*Op&URb%-`gXqiuo^CCQ3~J delta 3111 zcmb_eZ)_7~7{63)k<``iF*ofWSoiGJ9ujQ|p zO`T#08t@^JARizm7$6uzKN#bm#Kgo8YBG|Vkp+V$`bk1M6=V41`&`?*F0EgTx9rJ# zzvub=p5OD{`!0Jh{e{GTWV2Z*@+|yyTYfWgjz22&G8AQfc1k*YKo+N!sUwrpJwiju0o!ZEM;hwTvcGLL7KHf0Vh?Jq1AG=-VBylm$6#rz-bot*mPXt%Xl_o z-Clnym!x!T-P{TwwSNDU;`NOtRT4Z1boe};|H+Lk*^Cig2Ud!tLbaB62PiByl!vihpq} zc1@=h%M#G)XyJ#ktRN=F;3bDH=FW>PI2!rgScTiES_7MNwO12s$Fc+#kXu5DaNp6u z@5NUe38dZ^gqzN8&7we1VzH(s>>4A>KQz@dugr5koLBeRiM0v1RukbRtSuZl1lAqG{YlBKAA-`Xu5<%c;5>5!ku^Qa2sM} zHirm$!maIyB2P~x^V@PB>-(2&h##RieBx_!Um(j=$r%vmIT6o*KEMtvF6%c;P`Kk0 z_)92II2VCX<^%t4G<_RR)nA9Ph8W!kZ#4|k!|+2xOC4HVG*2s&N5<2#`U#aj)E)qT zFvb>^eZdxbFQkJLw#z8oMdPh_WX=2%e4VDRLT{`Q-U%Jc>p4^WbVfZCfJC)b;!)sLot(ze&?R*xeDWR*WRGXiTLQ z&wAk8sCj?#j=3a8XUz`>9c zqlIWEIh#~@$e(;X?}KscqB)tArY4d}813HDz5HT4=GGll|3P1`+$7cHE>fvWB;<@V hP3H^|+LWU(Y=L{-+k1~2Y0|E8TvG8r|0Sy$`Ug5zqk;ec diff --git a/api/repo.py b/api/repo.py index d9c0a66..867e2ce 100644 --- a/api/repo.py +++ b/api/repo.py @@ -2,8 +2,9 @@ Module providing functions for printing statistics of a GitHub repository. Functions: - - print_statistics_repo: Prints various statistics for a given repository, such as license, contributors, languages, - downloads, forks, issues, commits, stargazers, and releases. + - print_statistics_repo: Prints various statistics for a given + repository, such as license, contributors, languages, downloads, + forks, issues, commits, stargazers, and releases. Example: # Import necessary modules @@ -25,14 +26,21 @@ print_statistics_repo(user_data, repo) """ -from github import Github, Repository +from github import Repository from api.user import UserData import datetime + def print_statistics_repo(user: UserData, repo: Repository): + """Prints all statistics for a provided repo and user + + Args: + user (UserData): User we want to analyze from the point of view of this repo + repo (Repository): Repo + """ print(f"Showing repository statistics for {repo.full_name} in {user.year}") - # License + # License try: license = repo.get_license() except BaseException: @@ -40,13 +48,13 @@ def print_statistics_repo(user: UserData, repo: Repository): else: print("License: ", license.license.name) - # Contributors + # Contributors contributors = repo.get_contributors() print(f"This repository has {contributors.totalCount} contributors:") for c in contributors: print(f"- {c.login}") - # Languages + # Languages languages = repo.get_languages().keys() print( f"This repository is written in {len(languages)} different languages: ") @@ -79,7 +87,7 @@ def print_statistics_repo(user: UserData, repo: Repository): commits_made_by_user = user.repo_commit[repo]["total_count_author"] print( f"This repository has had {commits_this_year} commits on {user.year}, of which {commits_made_by_user} were made by you") - + # Stargazers stargazers = repo.get_stargazers_with_dates() stargazers_this_year = 0 diff --git a/api/user.py b/api/user.py index 566835c..69727a9 100644 --- a/api/user.py +++ b/api/user.py @@ -1,15 +1,17 @@ """ -Module providing a UserData class for handling GitHub user data and related functionalities. +Module: user_data_handler + +This module provides a UserData class for handling GitHub user data and related functionalities. Classes: UserData: A class for managing GitHub user data, repositories, commits, and more. -Functions: -- __init__: Initializes an instance of the UserData class. -- get_created_repos: Returns a list of repositories created by the user in a certain year. -- get_contributed_repos: Returns a list of repositories contributed to by the user in a certain year. -- get_languages_user: Returns language statistics for the user's contributions. -- get_commit_data: Returns data related to the user's commit history. +Methods: + - __init__: Initializes an instance of the UserData class. + - get_created_repos: Returns a list of repositories created by the user in a certain year. + - get_contributed_repos: Returns a list of repositories contributed to by the user in a certain year. + - get_languages_user: Returns language statistics for the user's contributions. + - get_commit_data: Returns data related to the user's commit history. Example: # Creating an instance of UserData @@ -33,6 +35,7 @@ # Getting repositories contributed to by the user in a certain year contributed_repos = user_data.get_contributed_repos() + """ from github import Github @@ -42,6 +45,10 @@ class UserData: + """ + Class to store the data from the users + """ + def __init__( self, github_instance: Github, @@ -49,7 +56,7 @@ def __init__( year: int, show_private: bool, show_repo_info: bool): - + self.__github_instance = github_instance self.__username = username self.__year = year @@ -71,96 +78,165 @@ def __init__( @property def github_instance(self): + """ + Getter for github_instance + """ return self.__github_instance @github_instance.setter def github_instance(self, value): + """ + Setter for github_instance + """ self.__github_instance = value @property def show_repo_info(self): + """ + Getter for show_repo_info + """ return self.__show_repo_info @show_repo_info.setter def show_repo_info(self, value): + """ + Setter for show_repo_info + """ self.__show_repo_info = value @property def username(self): + """ + Getter for username + """ return self.__username @username.setter def username(self, value): + """ + Setter for username + """ self.__username = value @property def year(self): + """ + Getter for year + """ return self.__year @year.setter def year(self, value): + """ + Setter for year + """ self.__year = value @property def show_private(self): + """ + Getter for show_private + """ return self.__show_private @show_private.setter def show_private(self, value): + """ + Setter for show_private + """ self.__show_private = value @property def user(self): + """ + Getter for user + """ return self.__user @user.setter def user(self, value): + """ + Setter for user + """ self.__user = value @property def commit_years(self): + """ + Getter for commit_years + """ return self.__commit_years @commit_years.setter def commit_years(self, value): + """ + Setter for commit_years + """ self.__commit_years = value @property def total_count(self): + """ + Getter for total_count + """ return self.__total_count @total_count.setter def total_count(self, value): + """ + Setter for total_count + """ self.__total_count = value @property def public_count(self): + """ + Getter for public_count + """ return self.__public_count @public_count.setter def public_count(self, value): + """ + Setter for public_count + """ self.__public_count = value @property def repo_commit(self): + """ + Getter for repo_commit + """ return self.__repo_commit @repo_commit.setter def repo_commit(self, value): + """ + Setter for repo_commit + """ self.__repo_commit = value @property def user_repos(self): + """ + Getter for user_repos + """ return self.__user_repos @user_repos.setter def user_repos(self, value): + """ + Setter for user_repos + """ self.__user_repos = value def __get_commit_years_basic_data(self): """ Gets basic data related to commits, such as the total count (and public total count) of commits of the year; and several data related to each repository + + Note: + - Method is private """ start = datetime(self.year, 1, 1, 0, 0, 0) end = datetime(self.year + 1, 1, 1, 0, 0, 0) @@ -200,6 +276,9 @@ def get_created_repos(self): """ Returns a list of the repos created by a user in a certain year. You can toggle whether or not you want to display the private repositories. + + Returns: + list: repos created by a user in a certain year """ repos = [r for r in self.user_repos if r.fork is False and r.created_at.year == self.year and r.owner == self.github_instance.get_user(self.username)] @@ -208,7 +287,11 @@ def get_created_repos(self): def get_contributed_repos(self): """ - Returns a list of the repos contributed to by a user in a certain year. + Returns a list of the repos contributed to by a + user in a certain year. + + Returns: + list: Repos contributed to by a user in a certain year """ repositories_return = [] @@ -221,7 +304,15 @@ def get_contributed_repos(self): # TODO: Reduce time: maybe instead of fetching by file we can get languages for each repo, but it might be an imprecise info (probably will). So a small db may be the best way to improve exec time for now. def get_languages_user(self): - + """ + Gets a dictionary with all the languages coded in this year, and the + number of file changes in each language + + Returns: + dict: dictionary with all the languages coded in this year, and the + number of file changes in each language + """ + language_stats = defaultdict(int) for repo in self.get_contributed_repos(): @@ -229,7 +320,8 @@ def get_languages_user(self): for file in commit.files: if (repo.visibility == "private" and self.show_private) or repo.visibility == "public": extension = '.' + file.filename.split('.')[-1] - language = get_language(extension, "languages_extensions.db") + language = get_language( + extension, "languages_extensions.db") language_stats[language] += file.changes return dict( @@ -242,6 +334,9 @@ def get_commit_data(self): """ Returns some commit dates data related to the longest commit streak duration, start and ending dates; and the total days with commits of the year + + Returns: + dict: Dictionary with commit data """ commit_dates = set() diff --git a/config.json b/config.json index f55a22f..121ee3a 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { - "username": "Violeta-Tejera", - "token": "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", - "year": 2023, - "showPrivate": false, + "username": "your username here", + "token": "your token here", + "year": 2022, + "showPrivate": true, "showRepoInfo": true } diff --git a/githubwrapped.py b/githubwrapped.py index c90bb20..db695cd 100644 --- a/githubwrapped.py +++ b/githubwrapped.py @@ -2,10 +2,14 @@ Main script for fetching and displaying various details related to a GitHub user. Functions: - - repositories_details: Displays information related to repositories, including those created and contributed to by the user. - - commits_details: Displays information related to commits made by the user, such as the number of commits, commit streak duration, etc. - - social_details: Displays social-related information, including stars received, top collaborators, new followers, and new accounts followed. - - main: Main entry point for the script, which orchestrates the execution of various functions. + - repositories_details: Displays information related to repositories, including + those created and contributed to by the user. + - commits_details: Displays information related to commits made by the user, + such as the number of commits, commit streak duration, etc. + - social_details: Displays social-related information, including stars received, + top collaborators, new followers, and new accounts followed. + - main: Main entry point for the script, which orchestrates the execution of + various functions. Example: python githubwrapped.py @@ -26,11 +30,10 @@ def repositories_details(user: UserData): Displays info. related to repositories """ - print("------------------------------------------------") print("Repositories and code") print("------------------------------------------------") - + # Repositories created this year repos = user.get_created_repos() print("Repositories created this year: ") @@ -48,21 +51,25 @@ def repositories_details(user: UserData): print_statistics_repo(user, r) print("\n") print("\n------------------------------------------------\n") - + # Languages top and count languages = user.get_languages_user() - print(f"You coded in more than {len(languages)} languages this year") languages_list = list(languages.items()) - if languages_list[0][0] != None or len(languages_list) == 0: - top_language = languages_list[0] + if len(languages_list) > 0: + print(f"You coded in more than {len(languages)} languages this year") + top_language = None + if languages_list[0][0] is not None: + top_language = languages_list[0] + + elif len(languages_list) > 1: + top_language = languages_list[1] + + for ll in languages_list: + print(ll) - else: - top_language = languages_list[1] - - for ll in languages_list: - print(ll) - print(top_language) - print(f"But your favourite was without a doubt {top_language}") + if top_language != None: + print(top_language) + print(f"But your favourite was without a doubt {top_language}") def commits_details(user: UserData): @@ -94,6 +101,7 @@ def commits_details(user: UserData): # Histogram of commits per month TODO (when GUI) + def main(): """ Main entry point for the script. This script performs all the functionality. @@ -125,4 +133,5 @@ def main(): current_time = now.strftime("%H:%M:%S") print("End: ", current_time) + main() diff --git a/languages_extensions.db b/languages_extensions.db index bd2ce3edbff3ea848b4f5fdbcd01e849c61089d0..72807d23db490e13a438b8d0d520b19a82e6dd7a 100644 GIT binary patch literal 49152 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 Umq=o*3QV88$XVHXc0 literal 47 ycmWHjbk8iwC{41pHPSQGGvo@WjCAz%v9&eRGXU~}QVUB{i%W_@vc`sb23!D5a}5>% diff --git a/utils/__pycache__/github_helpers.cpython-311.pyc b/utils/__pycache__/github_helpers.cpython-311.pyc index 1174b423242931849c64c077d30b559ad7798eda..cf0b9695eb01b4ba96902acf81662476302cbebe 100644 GIT binary patch literal 4585 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 str: Fetches the language corresponding to a + certain extension in the database corresponding to the filepath. If the database is not present + in that filepath, it will create the language database with github_languages_db. + +Dependencies: + - requests: Used for making HTTP requests to fetch GitHub language data. + - yaml: Used for parsing YAML data. + - os.path: Used for checking if a file exists at a given filepath. + - sqlite3: Used for SQLite database operations. +""" + import requests import yaml import os.path import sqlite3 + def github_languages_db(filepath): """ - Returns a dictionary that maps each extension to the name of a language known to Github. + Returns a dictionary that maps each extension to the name of a + language known to Github. + + Args: + filepath (string): Filepath to database """ url = 'https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml' response = requests.get(url) @@ -31,21 +56,38 @@ def github_languages_db(filepath): for lang, properties in github_languages.items(): extensions = properties.get("extensions", "") - if isinstance(extensions, str): - extensions_list = extensions.split() - elif isinstance(extensions, list): - extensions_list = extensions + type = properties.get("type", "") - for extension in extensions_list: - cursor.execute("INSERT OR REPLACE INTO language_mapping (extension, language) VALUES (?, ?)", (extension, lang)) + if type == "programming": + if isinstance(extensions, str): + extensions_list = extensions.split() + elif isinstance(extensions, list): + extensions_list = extensions -def get_language(extension, filepath): + for extension in extensions_list: + cursor.execute( + "INSERT OR REPLACE INTO language_mapping (extension, language) VALUES (?, ?)", (extension, lang)) + + +def get_language(extension: str, filepath: str) -> str: + """ Fetchs the language corresponding to a certain extension in the + database corresponding to the filepath. If database is not present in + that filepath, it will create the language database with github_languages_db + + Args: + extension (string): File extension + filepath (string): Filepath to database + + Returns: + str: Programming language corresponding to the extension + """ if not os.path.isfile(filepath): github_languages_db(filepath) with sqlite3.connect(filepath) as db: cursor = db.cursor() - cursor.execute("SELECT language FROM language_mapping WHERE extension = ?", (extension,)) + cursor.execute( + "SELECT language FROM language_mapping WHERE extension = ?", (extension,)) result = cursor.fetchone() return result[0] if result else None diff --git a/utils/helpers.py b/utils/helpers.py index d67ea59..9cd2c94 100644 --- a/utils/helpers.py +++ b/utils/helpers.py @@ -1,3 +1,28 @@ +""" +Module: github_connector + +This module provides functions for connecting to the GitHub API using a +token, disconnecting from the GitHub API, and loading JSON data from a file. + +Functions: + - connect(token: str) -> Github: Authenticates with the Github API using + the provided token. + - disconnect(github: Github): Closes the connection to the GitHub API. + - load_json(filepath: str) -> dict: Returns a Python object containing a + decoded JSON document if successful. + +Dependencies: + - github.Github: Used for interacting with the GitHub API. + - github.Auth: Used for authentication with the GitHub API. + - json: Used for reading and decoding JSON data from a file. + +Usage: + You can use the functions provided in this module to connect to the + GitHub API, disconnect from the API, and load JSON data from a file. + +""" + + from github import Github, Auth import json