`#?wt%{*!f378yedRC^GhsdUs
zktYlZ{1E!Jyi(dX1&O8v!n7(wUUV4JqpXVQQA$_Tq{O6{DY2S8X9J}Vh(nahRBmM$94LO>v{1nD30&L>}?p4ZOEc){kJM
zf%wall~XJ7H~o3SF0#vz>+`qOX~##={Dzv0x$zY}+7Tf^gh-8E>+sk@|Dm`;C*%gk
zOh$v)D~@Vu)o}b+vD{vS98)tL9+VtkY8*ZlKrG;?J6;3Krz(!9nQF#Jwlw7vbSEx>
zsB~h@Um8wJ?KOwtYXa5{;&;ceYj(HIY|mo3BHcFZO-gd9c)Z*zP=B^lyjfWyQk*(;q3e954A#
z*!~m6+5vYWv=$p_Q59#Vf`3y`}c6
zcKcPhX9A!EWbSl%`>x-ID};{#1IWBkesg!B`^y7siKDBDqsysMqSsFJt{kxweWf@1
z<^$!<{cD{ES33_b2Ud=iItT2|fq8#9wrlZDF}4pLJGO7B|H%iX*bm%(iE%4FT!4oa
zzYmje>~rt@&(}KkuXgM&bsVre4lJKoKJl!(7&~8zowtF82JO&bQ5ZBZmM*mHB@g4r
z_=bE7y?|Y1h(`Qy21nt}(L>Nn@=b6uP!UeoJ=az|SA-7a*;>l=6?zslehhzh`R7Sl
z@aOxPZ=9nT0+TI{*99WQxhP($&bA!5xY1Ju=(w7O)We|YGt5PtP)bjy;ky9fW>nqB
zFe!Zx6)??Z2?T=_Tb}Kmt;zNY&YjVfTw3j;=Rq0Y*MKj7QsFs{E0aCN|MZl}(PHCM
zCT|rRpEBtxHa-<0%Ec=LNMVvyE3K@0`V&?)lSGV*FTGbGP_0~I)ia(|&7`}7yTDZl
g(j~83uRxB2{iiT+L)y?j!f}D6_6mV&OTx_bZz;$!n*aa+
literal 0
HcmV?d00001
diff --git a/api/repo.py b/api/repo.py
new file mode 100644
index 0000000..34b015d
--- /dev/null
+++ b/api/repo.py
@@ -0,0 +1,10 @@
+from github import Github
+
+def get_statistics_repo(github_instance, repo, year): # commits, pull requests, issues,...
+ pass
+
+def get_descr_repo(github_instance, repo, year):
+ pass
+
+def get_contributors_repo(github_instance, repo, year):
+ pass
\ No newline at end of file
diff --git a/api/user.py b/api/user.py
new file mode 100644
index 0000000..bbfc444
--- /dev/null
+++ b/api/user.py
@@ -0,0 +1,67 @@
+from github import Github, Repository
+from utils.github_helpers import get_github_languages
+from datetime import datetime
+from collections import defaultdict
+
+def get_created_repos(github_instance: Github, username: str, year: int, showPrivate=False):
+ """
+ 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.
+ """
+
+ if showPrivate == True:
+ user = github_instance.get_user() # authenticated user can get private repos too
+ user_repos = user.get_repos(visibility='all')
+ else:
+ user = github_instance.get_user(username)
+ user_repos = user.get_repos()
+
+ repos = [r for r in user_repos if r.fork is False and r.created_at.year == year and r.owner == github_instance.get_user(username)]
+
+ return repos
+
+def get_contributed_repos(github_instance: Github, username: str, year: int):
+ """
+ Returns a list of the repos contributed to by a user in a certain year.
+ """
+
+ user = github_instance.get_user(username)
+ repos = []
+
+ repos += get_created_repos(github_instance, username, year)
+
+ for event in user.get_events():
+ if event.type == "PushEvent" and event.created_at.year == year:
+ repo = event.repo
+ if repo not in repos:
+ repos.append(repo)
+
+ return repos
+
+def get_languages_user(github_instance: Github, username: str, year: int, showPrivate=False):
+ """
+ Returns a dictionary that maps every language (with at least 1 line of code) with the
+ quantity of lines of code written on year "year" by user "username".
+ """
+ user = github_instance.get_user(username)
+ try:
+ github_languages = get_github_languages()
+ except:
+ print("Error: Unable to get languages. Aborting now")
+
+ language_stats = defaultdict(int)
+
+ date_since = datetime(year, 1, 1, 0, 0, 0)
+ date_until = datetime(year + 1, 1, 1, 0, 0, 0)
+
+ for repo in user.get_repos():
+ for commit in repo.get_commits(since=date_since, until=date_until, author=user):
+ for file in commit.files:
+ extension = '.' + file.filename.split('.')[-1]
+ language = github_languages.get(extension, 'Unknown')
+ language_stats[language] += file.changes
+
+ return dict(sorted(language_stats.items(), key=lambda x:x[1], reverse=True))
+
+def get_statistics_user(github_instance: Github, username, year):
+ pass
diff --git a/config.json b/config.json
new file mode 100644
index 0000000..a01b686
--- /dev/null
+++ b/config.json
@@ -0,0 +1,6 @@
+{
+ "username": "Violeta-Tejera",
+ "token": "YOUR TOKEN HERE",
+ "year": 2023,
+ "showPrivate": true
+}
\ No newline at end of file
diff --git a/funciones b/funciones
new file mode 100644
index 0000000..8deaaf5
--- /dev/null
+++ b/funciones
@@ -0,0 +1,7 @@
+repositorios:
+
+get_collaborators
+get_contributors
+get_stargazers
+
+atributos de repo:
diff --git a/githubwrapped.py b/githubwrapped.py
new file mode 100644
index 0000000..44a58f2
--- /dev/null
+++ b/githubwrapped.py
@@ -0,0 +1,67 @@
+from utils.helpers import *
+from api.repo import *
+from api.user import *
+
+def repositories_details(github, username, year, showPrivate):
+ print("------------------------------------------------")
+ print("Repositories and code")
+ print("------------------------------------------------")
+ repos = get_created_repos(github, username, year, showPrivate=showPrivate)
+ print("Repositories created this year: ")
+ for r in repos:
+ print(r.full_name, " Top Language: ", r.language)
+ print("------------------------------------------------")
+ repos = get_contributed_repos(github, username, year)
+ print("Repositories contributed to this year: ")
+ for r in repos:
+ print(r.full_name, " Top Language: ", r.language)
+ print("------------------------------------------------")
+ languages = get_languages_user(github, username, year)
+ print(f"You coded in more than {len(languages)} languages this year")
+ languages_list = list(languages.items())
+ if languages_list[0][0] != 'Unknown' or len(languages_list) == 0:
+ top_language = languages_list[0]
+ else:
+ top_language = languages_list[1]
+ print(f"But your favourite was without a doubt {top_language[0]}")
+
+def commits_details(github, username, year, showPrivate):
+ ### Commits
+ print("Commits")
+
+ # Num. of commits of the year
+
+ # Max streak of commits (dates)
+
+ # Max streak of days without commits (dates)
+
+ # Histogram of commits per month
+
+def social_details(github, username, year, showPrivate):
+ ### Social
+ print("Social")
+ # Stars (Given and received)
+
+ # Top 2 collaborators
+
+ # Num de nuevos seguidores
+
+ # Num de nuevas cuentas seguidas
+
+def main():
+ filename = "config.json"
+ jsonfile = load_json(filename)
+
+ username = jsonfile.get('username')
+ token = jsonfile.get('token')
+ year = jsonfile.get('year')
+ showPrivate = jsonfile.get('showPrivate')
+
+ github = connect(token)
+
+ if github:
+ repositories_details(github, username, year, showPrivate)
+
+ disconnect(github)
+
+main()
diff --git a/utils/__init__.py b/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/utils/__pycache__/__init__.cpython-311.pyc b/utils/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5ca67f213645ff2314b4896ccc0f7b3807243b1f
GIT binary patch
literal 190
zcmZ3^%ge<81b@?8Q$h4&5CH>>P{wCAAY(d13PUi1CZpdH^iI30B%PfhH*DI*}#bJ}1pHiBWYFESxG#uoHVtyd;ftit!@dE>lC}IYR0RUW>
BG3WpQ
literal 0
HcmV?d00001
diff --git a/utils/__pycache__/github_helpers.cpython-311.pyc b/utils/__pycache__/github_helpers.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bf6dca0b851cc4a105bf667bd729ab105077a95e
GIT binary patch
literal 1677
zcmZ`(&ube;6rPn<)=G=LHblt5HrdEMSdML#kfgyRhSUuyZ7HQ`6EJGj_3qeSXSJ)&
zjGD--j7fVC#ZXZS@llt!6jLblPw1gJYK+TsxER
zOdO~OJ@Y;E#j`B%El0{j?oh2)Q!fA%Lo_1$5OdJ0u^j#1*r7LKC08<{ot}Ki5`APh
zI>3J*14+2i+L?~@SM7t^=UbOMuIR>ZLGZ4$`;9BY
zA(6IL<0_0#F)I?As+#H_64S9YQc~H5#?-u4peok%4HZ9S*rwo9nFBto+FBl~&KfMT
zG<&_Mtz-4E?K}zm_e{1?TwMsjx9)E+R-lWS4AGt}tOuSV#YA^(Kx7NLlh3qgGnNTJ
zCS{qtMj0kxulDDz;wDWg0LI9#SoV?~CBRpa2T;NPrDCvPEWEG~1!Qfi0jz7YZeQ
z0os>4Uky<=yoNoXD5Y<>S^G<#AaxLwR&eccf{yCN>>*C}ov<0Oj#J~QD
zf6;MScPtB<4o8g!M=NOG&xl<1LoR{%SGtvVjG~2?$Xj6gR~UU4L@O)^LK7)F!P7+Y
WPVh9*bbavG5~qZz7J5?zIsOCsWwZSN
literal 0
HcmV?d00001
diff --git a/utils/__pycache__/helpers.cpython-311.pyc b/utils/__pycache__/helpers.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5020ada4ebe096f3117920788d094c9eacaf5625
GIT binary patch
literal 2334
zcmaJ?O=ufO6rR~1X=LliiCnw+u`^8?s7h$uf}s{6p!}7_iEElP#l~RP+L5%byeno`
zaV+GLh91-sXc7!IltNBvN_s1W7E-9&TTc?`V3ryRJ@uyIri7gOW+cm&;%0XD?VEY?
zzL|aV-nU;zB0UJ&@4r>pWeuS}MQ6JyEoJKrD67asCeEV;JdGEWX$6bEl2@lyQ)OC4
zF||*%Y2DNr20Z|JzzoW90(#I?uAoHdF9DcP{J=Ywmn+WsTB_*fCVbsB<>_UN+eh1wnX
z%(6P)#{Cj~rF5cVREEzxhP?2OQvi7lNYFAp?B3?u{)G4%x
z6MAW^heCruG262;7IWz$1dn<-Mw?NjsmXU~(Y5TX9F(z?J_+n=1_ZeD`jk_oIpaE`
zbBx(E?btR;d(5PsvyEZ60Kqsd9Xijs!zuX5^_B!|bDboeNCY|L2=eu-;=s5Fq))QU
zn-#vkUf`DP`Fh^TTDBiLe@6O~{zQDNq
zMq$Yhw!W0_18A{vcLl^v)F2_fe=`=pU0OR{i_vfxaZ{v+PM
zn!K01duruWg=~^YH9G#o+mBDf3+@`ZR413JiLLe!EP-rQJFcAF3KsSyroBIx5rXY~FDp>zaGmP98W`
zY4juKEVmVANR^3%!UdoBdRllTFy9Y7S1e3(aJAC*+nc@Zp!j$!)yE`W8y@h&(;
z+mwLK%!`Rlos%1sqY0IZ;_@|t<_7>iV`W`&&_FuPoD2!TS%J-u!uTP0+