diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9bb66378..dfdb3584 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,4 +20,3 @@ jobs: tags: ${{ steps.metadata.outputs.tags }} labels: ${{ steps.metadata.outputs.labels }} containerfiles: Dockerfile - diff --git a/.github/workflows/validate_configs.yaml b/.github/workflows/validate_configs.yaml new file mode 100644 index 00000000..21611c03 --- /dev/null +++ b/.github/workflows/validate_configs.yaml @@ -0,0 +1,15 @@ +name: Validate configuration files +on: [push, pull_request] + +jobs: + validate-config: + runs-on: ubuntu-latest + steps: + - name: Check out sources + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11.5' + - name: Validate configuration files + run: python validate_github_repos.py diff --git a/Contributing.md b/Contributing.md index ca441f19..69ea93c9 100644 --- a/Contributing.md +++ b/Contributing.md @@ -21,6 +21,36 @@ The institution blocks look like this: } ``` +**Generate V4 UUID:** https://www.uuidgenerator.net/version4 + +**Important:** oid as seen in [github_repos.json](/github_repos.json) will be created automaticly when updating the Database, so it doesn't need to be added by you. + +**Important:** +sector needs to be one of these: +- FoodBeverage +- Gov_Companies +- Gov_Federal +- IT +- Communities +- Gov_Cities +- Gov_Cantons +- Media +- NGOs +- ResearchAndEducation +- Banking +- Others +- Insurances +- Pharma +- PolitcalParties + Just edit or append a new block to the file and make a pull request. If everything is correct it will be added and updated on the website. + +### What are ts and why are they set to null + +ts are timestamps that are used to check when that organization/institution were crawled. + +"null" is the intial value so that the new organization/institution will be crawled with the next crawl run. + +After that it will be overwritte in the database. \ No newline at end of file diff --git a/Dev.md b/Dev.md index aee326b9..7b3acc72 100644 --- a/Dev.md +++ b/Dev.md @@ -6,23 +6,43 @@ ### Env Variables -These are the env variables that need to be set-up (.env.sample file as template): -- MONGO_READ: The connection string -- MONGO_DATABASE: Which database to use -- GITHUB_TOKEN: The Github token -- LOG_PATH: The path for the log files to be saved in -- DATA_PATH: The path for the data files to be saved in +These are the env variables that need to be set-up (.env.sample file as template) (.env.sample file as template): +- MONGO_READ: The connection string. Can be found in Keepass +- MONGO_DATABASE: Which database to use. production or testingNew +- GITHUB_TOKEN: The Github token. Can be found in Keepass +- LOG_PATH: The path for the log files to be saved in. Somewhere on your system. +- DATA_PATH: The path for the data files to be saved in. Somewhere on your system. ### Run Backend > - From root cd into */oss-api*
-> - Run npm i to install all the necessary packages -> - Finally you can start the dec server with **npm run start:dev** +> - Run **npm i** to install all the necessary packages +> - Finally you can start the dev server with **npm run start:dev** ## Frontend **Pre-requirements:** AngularJS, npm, finished backend setup > - From root cd into */frontend*
-> - Run npm i to install all the necessary packages
-> - Finally you can start the dev server with **npm run start** \ No newline at end of file +> - Run **npm i** to install all the necessary packages
+> - Finally you can start the dev server with **npm run start** + + +# Update Institutions + +Once someone has updated the github_repos.json file and the pull request was merged, the new or updated insitution must be added to the database. + +This can be done in 4 easy steps: + +1. Pull Repository +2. Enter the connection string, which can be found in Keepass, into the URI field of MongoCompass. + +![MongoCompass Connection string](/assets/images/MongoConnection.png) + +3. Choose the **production** DB and then todoInstitution collection. + +![Mongo choose DB](/assets/images/MongoDB.png) + +4. Press **Add Data -> Import file** and choose github_repos.json. Keep in mind that *Stop on errors* needs to be unchecked. Then just click *Import*. + +![Add new Data to DB](/assets/images/AddData.png) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 78b416f7..7e26a5fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18 as backendBuild +FROM node:20.6.0-alpine3.17 as backendBuild LABEL stage=build ENV NODE_ENV=PRODUCTION @@ -10,7 +10,7 @@ RUN npm install RUN npm run build -FROM node:18 as frontendBuild +FROM node:20.6.0-alpine3.17 as frontendBuild LABEL stage=build ENV NODE_ENV=PRODUCTION @@ -24,7 +24,7 @@ RUN npm install RUN npm run build:prod -FROM node:18 as prod +FROM node:20.6.0-alpine3.17 as prod COPY --from=backendBuild dist dist diff --git a/assets/images/AddData.png b/assets/images/AddData.png new file mode 100644 index 00000000..ccccdfbb Binary files /dev/null and b/assets/images/AddData.png differ diff --git a/assets/images/MongoConnection.png b/assets/images/MongoConnection.png new file mode 100644 index 00000000..5e3eb24c Binary files /dev/null and b/assets/images/MongoConnection.png differ diff --git a/assets/images/MongoDB.png b/assets/images/MongoDB.png new file mode 100644 index 00000000..484b600d Binary files /dev/null and b/assets/images/MongoDB.png differ diff --git a/frontend/src/app/data.service.ts b/frontend/src/app/data.service.ts index 8a3c0c17..c72bf289 100644 --- a/frontend/src/app/data.service.ts +++ b/frontend/src/app/data.service.ts @@ -78,6 +78,25 @@ export class DataService { return repoData; } + async loadRepoDataDetailView(config: { + search?: string; + sort?: string; + direction?: 'ASC' | 'DESC'; + page?: string; + count?: string; + includeForks?: string; + }) { + const repoData = await this.http + .get<{ + repositories: Repository[]; + total: number; + }>(`${environment.api}institutionRepositories`, { + params: config, + }) + .toPromise(); + return repoData; + } + async loadUserData(config: { search: string; sort: string; diff --git a/frontend/src/app/institution-detail-view/institution-detail-view.component.ts b/frontend/src/app/institution-detail-view/institution-detail-view.component.ts index e78a5704..a5db7314 100644 --- a/frontend/src/app/institution-detail-view/institution-detail-view.component.ts +++ b/frontend/src/app/institution-detail-view/institution-detail-view.component.ts @@ -68,23 +68,17 @@ export class InstitutionDetailViewComponent implements OnInit { content: 'total_num_contributors', toNiceName: false, }, - { + /*{ text: 'Own repositories forks:', content: 'total_num_own_repo_forks', toNiceName: false, - }, + },*/ { text: 'Forks in repositories:', content: 'total_num_forks_in_repos', toNiceName: false, }, { text: 'Commits:', content: 'total_num_commits', toNiceName: false }, - { - text: 'Pull requests:', - content: 'total_pull_requests', - toNiceName: false, - }, - { text: 'Issues:', content: 'total_issues', toNiceName: false }, { text: 'Stars:', content: 'total_num_stars', toNiceName: false }, { text: 'Watchers:', content: 'total_num_watchers', toNiceName: false }, { @@ -94,7 +88,7 @@ export class InstitutionDetailViewComponent implements OnInit { }, { text: 'Total pull requests:', - content: 'total_pull_requests_all', + content: 'total_pull_requests', toNiceName: false, }, { @@ -102,7 +96,7 @@ export class InstitutionDetailViewComponent implements OnInit { content: 'total_pull_requests_closed', toNiceName: false, }, - { text: 'Total issues:', content: 'total_issues_all', toNiceName: false }, + { text: 'Total issues:', content: 'total_issues', toNiceName: false }, { text: 'Total closed issues:', content: 'total_issues_closed', @@ -265,7 +259,7 @@ export class InstitutionDetailViewComponent implements OnInit { reloadData() { this.dataService - .loadRepoData({ + .loadRepoDataDetailView({ sort: this.activeSort, direction: this.sortDirection, page: this.page.toString(), diff --git a/frontend/src/app/pipes/toNiceName.pipe.ts b/frontend/src/app/pipes/toNiceName.pipe.ts index eeec262a..a5a2734d 100644 --- a/frontend/src/app/pipes/toNiceName.pipe.ts +++ b/frontend/src/app/pipes/toNiceName.pipe.ts @@ -4,6 +4,8 @@ import { Pipe, PipeTransform } from '@angular/core'; export class ToNiceNamePipe implements PipeTransform { sectors: { original: string; nice: string }[] = [ { original: 'ResearchAndEducation', nice: 'Research and education' }, + { original: 'FoodBeverage', nice: 'Food and Beverage' }, + { original: 'PolitcalParties', nice: 'Politcal Parties' }, { original: 'NGOs', nice: 'NGOs' }, { original: 'Media', nice: 'Media' }, { original: 'Insurances', nice: 'Insurances' }, @@ -22,7 +24,7 @@ export class ToNiceNamePipe implements PipeTransform { transform(value: any): string { if (!value) return ''; const name: any = this.sectors.find( - (sector) => sector.original === value.toString() + (sector) => sector.original === value.toString(), ); return name ? name.nice : value; } diff --git a/frontend/src/app/ranking/ranking.component.html b/frontend/src/app/ranking/ranking.component.html index 2da132f2..bd1c4a87 100644 --- a/frontend/src/app/ranking/ranking.component.html +++ b/frontend/src/app/ranking/ranking.component.html @@ -37,9 +37,19 @@

{{ sectorObj.sector | toNiceName }} - {{ sectorObj.count }} +
+ {{ sectorObj.sector | toNiceName }} + {{ sectorObj.count }} +
+ [dataSource]="dataSource" class="mat-elevation-z8" matSort + matSortStart="desc" matSortActive="num_repos" matSortDirection="desc" (matSortChange)="sortingUpdate($event)" diff --git a/frontend/src/app/repositories-ranking/repositories-ranking.component.html b/frontend/src/app/repositories-ranking/repositories-ranking.component.html index 74064e75..e23e944f 100644 --- a/frontend/src/app/repositories-ranking/repositories-ranking.component.html +++ b/frontend/src/app/repositories-ranking/repositories-ranking.component.html @@ -35,6 +35,7 @@

Ranking of {{ numRepositories }} Repositories.

[dataSource]="dataSource" class="mat-elevation-z8" matSort + matSortStart="desc" matSortActive="num_commits" matSortDirection="desc" (matSortChange)="sortingUpdate($event)" diff --git a/frontend/src/app/repository-detail-view/repository-detail-view.component.ts b/frontend/src/app/repository-detail-view/repository-detail-view.component.ts index 66873877..99aa7ea9 100644 --- a/frontend/src/app/repository-detail-view/repository-detail-view.component.ts +++ b/frontend/src/app/repository-detail-view/repository-detail-view.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, Inject } from '@angular/core'; -import { lowerCase } from 'lodash-es'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @Component({ @@ -9,11 +8,11 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; }) export class RepositoryDetailViewComponent implements OnInit { repositoryStats: object[] = [ - { text: 'Archived:', content: 'archived', toNiceName: true }, - { text: 'Institution:', content: 'institution_name_de', toNiceName: false }, + { text: 'Archived:', content: 'archived', toNiceName: false }, + { text: 'Institution:', content: 'institution', toNiceName: false }, { text: 'Organization:', - content: 'organisation_name_de', + content: 'organization', toNiceName: false, }, { @@ -28,7 +27,7 @@ export class RepositoryDetailViewComponent implements OnInit { }, { text: 'Commits last year:', - content: 'last_years_commits', + content: 'num_commits', toNiceName: false, }, // { text: 'License:', content: 'license', toNiceName: false }, @@ -70,7 +69,7 @@ export class RepositoryDetailViewComponent implements OnInit { constructor( private dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: any + @Inject(MAT_DIALOG_DATA) public data: any, ) {} ngOnInit(): void { diff --git a/frontend/src/app/user-ranking/user-ranking.component.html b/frontend/src/app/user-ranking/user-ranking.component.html index 9f06a952..2cad3c94 100644 --- a/frontend/src/app/user-ranking/user-ranking.component.html +++ b/frontend/src/app/user-ranking/user-ranking.component.html @@ -27,6 +27,7 @@

Ranking of {{ numUsers }} users.

[dataSource]="dataSource" class="mat-elevation-z8" matSort + matSortStart="desc" matSortActive="last_years_commits" matSortDirection="desc" (matSortChange)="sortingUpdate($event)" diff --git a/githubRepoValidation.py b/githubRepoValidation.py deleted file mode 100755 index 9e1274f2..00000000 --- a/githubRepoValidation.py +++ /dev/null @@ -1,24 +0,0 @@ -import json, sys - -def fileError(err): - print("File is not formatted correctly:") - print(err) - sys.exit(1) - -repos = open('github_repos.json') -data = json.load(repos) - -for item in data: - if(type(item["uuid"]) is not str or not item["uuid"]): fileError(item) - if(type(item["sector"]) is not str or not item["sector"]): fileError(item) - if(type(item["shortname"]) is not str or not item["shortname"]): fileError(item) - if(type(item["name_de"]) is not str or not item["name_de"]): fileError(item) - orgs = item["orgs"] - for org in orgs: - if(type(org) is not dict): fileError(org) - if not org["name"] : fileError(org) - -repos.close() -print("File ok") - - diff --git a/github_repos.json b/github_repos.json index 81fb625e..364b5bdd 100644 --- a/github_repos.json +++ b/github_repos.json @@ -1,4 +1,824 @@ + [ + { + "uuid": "f7448553-a475-4c21-889f-9cde0987039e", + "sector": "IT", + "ts": null, + "shortname": "ABB", + "name_de": "ABB", + "orgs": [ + { + "name": "abb", + "ts": null + } + ] + }, + { + "uuid": "adc1a89b-916c-4bdd-a81a-36104d0afcf2", + "sector": "IT", + "ts": null, + "shortname": "Accenture", + "name_de": "Accenture", + "orgs": [ + { + "name": "Accenture", + "ts": null + } + ] + }, + { + "uuid": "c212ccac-d5e7-4d65-8c2c-cc596360eecb", + "sector": "Pharma", + "ts": null, + "shortname": "Actelion", + "name_de": "Actelion", + "orgs": [ + { + "name": "Actelion", + "ts": null + } + ] + }, + { + "uuid": "4a94b561-395e-4f90-a500-a4ac1cfe3c33", + "sector": "Others", + "ts": null, + "shortname": "Adecco", + "name_de": "Adecco", + "orgs": [ + { + "name": "Adecco-Business-Transformation", + "ts": null + } + ] + }, + { + "uuid": "c501ce24-184f-49cc-922f-42995084ab51", + "sector": "IT", + "ts": null, + "shortname": "Adobe", + "name_de": "Adobe Systems (Schweiz)", + "orgs": [ + { + "name": "Adobe, Inc.", + "ts": null + } + ] + }, + { + "uuid": "496dd242-faf2-4b41-8131-b1fb31e98937", + "sector": "Others", + "ts": null, + "shortname": "APG", + "name_de": "APG SGA", + "orgs": [ + { + "name": "APG|SGA Allgemeine Plakatgesellschaft AG", + "ts": null + } + ] + }, + { + "uuid": "65773e97-abd9-4f04-a538-c9b3466fd97f", + "sector": "Others", + "ts": null, + "shortname": "Archroma", + "name_de": "Archroma Management", + "orgs": [ + { + "name": "Archroma Management GmbH", + "ts": null + } + ] + }, + { + "uuid": "7513ea3f-30d4-48c1-aae1-137690a51935", + "sector": "Others", + "ts": null, + "shortname": "Axpo", + "name_de": "Axpo Holding", + "orgs": [ + { + "name": "Axpo Group", + "ts": null + } + ] + }, + { + "uuid": "ebd5854d-df63-47f9-aad5-25eb48e7e148", + "sector": "Others", + "ts": null, + "shortname": "Bertschi", + "name_de": "Bertschi", + "orgs": [ + { + "name": "Bertschi AG", + "ts": null + } + ] + }, + { + "uuid": "7f2ae193-19e2-4403-abd0-a18f56f6a859", + "sector": "Others", + "ts": null, + "shortname": "CH Media", + "name_de": "CH Media", + "orgs": [ + { + "name": "CH Media", + "ts": null + } + ] + }, + { + "uuid": "17ed5672-a45b-4448-9302-3c4215f1544b", + "sector": "Pharma", + "ts": null, + "shortname": "Clariant", + "name_de": "Clariant", + "orgs": [ + { + "name": "Clariant", + "ts": null + } + ] + }, + { + "uuid": "525cf832-fcef-45ed-9170-0d49d90a0b80", + "sector": "Others", + "ts": null, + "shortname": "Competec", + "name_de": "Competec", + "orgs": [ + { + "name": "Competec", + "ts": null + } + ] + }, + { + "uuid": "4b5a4e81-d2f5-480c-ae84-46759f19690f", + "sector": "Others", + "ts": null, + "shortname": "Dormakaba ", + "name_de": "Dormakaba Holding", + "orgs": [ + { + "name": "dormakaba", + "ts": null + } + ] + }, + { + "uuid": "c811397e-fea5-4191-82e9-22a2cd2c15d7", + "sector": "Others", + "ts": null, + "shortname": "E+H", + "name_de": "Endress+Hauser", + "orgs": [ + { + "name": "Endress+Hauser SE+Co. KG, \nEndress+Hauser Process Solutions AG", + "ts": null + } + ] + }, + { + "uuid": "57170729-5c3d-4f50-9829-a4ac4704d278", + "sector": "Others", + "ts": null, + "shortname": "Engie Services", + "name_de": "Engie Services", + "orgs": [ + { + "name": "ENGIE", + "ts": null + } + ] + }, + { + "uuid": "ca9ee647-6ae5-4250-98b8-614fcf217b47", + "sector": "Gov_Companies", + "ts": null, + "shortname": "HUG", + "name_de": "Hôpitaux universitaires de Genève", + "orgs": [ + { + "name": "Hôpitaux Universitaires de Genève", + "ts": null + } + ] + }, + { + "uuid": "4c29cad4-0756-4bd4-8e3b-c77f6866b3e9", + "sector": "Others", + "ts": null, + "shortname": "Inficon", + "name_de": "Inficon Holding", + "orgs": [ + { + "name": "INFICON Spot", + "ts": null + } + ] + }, + { + "uuid": "17d4b31b-7bfd-4c5f-9ec3-4c1ffe4a06fe", + "sector": "IT", + "ts": null, + "shortname": "Infosys", + "name_de": "Infosys Consulting Holding", + "orgs": [ + { + "name": "Infosys Ltd", + "ts": null + } + ] + }, + { + "uuid": "77c19b3f-8ba2-4ca6-8f4d-a3c0c12ea447", + "sector": "Others", + "ts": null, + "shortname": "Kudelski", + "name_de": "Kudelski", + "orgs": [ + { + "name": "Kudelski Security", + "ts": null + } + ] + }, + { + "uuid": "55862f84-69c8-4078-805f-525ceb06e7ce", + "sector": "Others", + "ts": null, + "shortname": "Kühne + Nagel ", + "name_de": "Kühne + Nagel International", + "orgs": [ + { + "name": "Kuehne + Nagel (AG & Co.) KG", + "ts": null + } + ] + }, + { + "uuid": "da4b4a10-3629-4455-925b-7c5e6cc27f8e", + "sector": "IT", + "ts": null, + "shortname": "Leonteq", + "name_de": "Leonteq", + "orgs": [ + { + "name": "Leonteq Securities AG", + "ts": null + } + ] + }, + { + "uuid": "0c9a9b4c-8029-4544-a7be-14651fa9ad20", + "sector": "IT", + "ts": null, + "shortname": "Logitech", + "name_de": "Logitech International", + "orgs": [ + { + "name": "Logitech, Inc.", + "ts": null + } + ] + }, + { + "uuid": "ade90755-5418-42a6-be66-1985eab42c7b", + "sector": "Others", + "ts": null, + "shortname": "Globus", + "name_de": "Magazine zum Globus", + "orgs": [ + { + "name": "Magazine zum Globus AG", + "ts": null + } + ] + }, + { + "uuid": "58ff77ad-3952-47f7-b9a5-d4bf8ddd1ca7", + "sector": "Others", + "ts": null, + "shortname": "Mercuria", + "name_de": "Mercuria Energy Trading", + "orgs": [ + { + "name": "MercuriaApp", + "ts": null + } + ] + }, + { + "uuid": "4e8efa03-dd42-45aa-ba26-20c318247fc5", + "sector": "Others", + "ts": null, + "shortname": "Microspot", + "name_de": "Microspot", + "orgs": [ + { + "name": "Microspot / Interdiscount", + "ts": null + } + ] + }, + { + "uuid": "a471d4d4-8063-4c26-9e23-89addbac3334", + "sector": "FoodBeverage/Others", + "ts": null, + "shortname": "Migros", + "name_de": "Migros-Konzern", + "orgs": [ + { + "name": "Migros", + "ts": null + } + ] + }, + { + "uuid": "ce6996e3-cb27-4369-90d5-93cf51a2c9db", + "sector": "Pharma", + "ts": null, + "shortname": "Novartis", + "name_de": "Novartis", + "orgs": [ + { + "name": "Novartis, NovartisAPI", + "ts": null + } + ] + }, + { + "uuid": "3591b733-f5da-409e-afc6-aacd6273e2c9", + "sector": "Others", + "ts": null, + "shortname": "On ", + "name_de": "On Running Shoes", + "orgs": [ + { + "name": "On", + "ts": null + } + ] + }, + { + "uuid": "5e371f42-e86d-4a55-bb4e-de17027dfc3f", + "sector": "FoodBeverage", + "ts": null, + "shortname": "Pistor ", + "name_de": "Pistor Holding", + "orgs": [ + { + "name": "Pistor AG", + "ts": null + } + ] + }, + { + "uuid": "2c4ae3d9-b615-4fba-81f0-58ef70bd74f1", + "sector": "Gov_Companies", + "ts": null, + "shortname": "PostLogistics", + "name_de": "PostLogistics", + "orgs": [ + { + "name": "Swiss Post YellowCube", + "ts": null + } + ] + }, + { + "uuid": "c14b1c4c-bc18-4f5b-9dc0-ab2b6ef90da5", + "sector": "Others", + "ts": null, + "shortname": "Richemont", + "name_de": "Richemont", + "orgs": [ + { + "name": "Richemont International SA, Richemont", + "ts": null + } + ] + }, + { + "uuid": "3f1f5eaa-3384-4b74-839c-e608a0636dab", + "sector": "Media", + "ts": null, + "shortname": "Ringier", + "name_de": "Ringier", + "orgs": [ + { + "name": "Ringier Data Services", + "ts": null + } + ] + }, + { + "uuid": "f67749b8-4d03-499f-b1ee-ccaf709090ec", + "sector": "Others", + "ts": null, + "shortname": "Sensition", + "name_de": "Sensirion Holding", + "orgs": [ + { + "name": "Sensirion AG", + "ts": null + } + ] + }, + { + "uuid": "366c2629-68cf-4855-83d5-b0157c4d70a6", + "sector": "Others", + "ts": null, + "shortname": "Sonova", + "name_de": "Sonova Holding", + "orgs": [ + { + "name": "Sonova Group", + "ts": null + } + ] + }, + { + "uuid": "7584ed2c-64ac-4973-899c-8c39e6591f3a", + "sector": "IT", + "ts": null, + "shortname": "Swisscom ", + "name_de": "Swisscom", + "orgs": [ + { + "name": "Swisscom, Swisscom Data, Analytics & AI, Swisscom Trust Services \nSwisscom Event & Media Solutions, \nSwisscom Blockchain AG, \nSwisscom - Big Data Team ,", + "ts": null + } + ] + }, + { + "uuid": "e738715f-47ab-4e1f-ac50-2f43fa7613e2", + "sector": "IT", + "ts": null, + "shortname": "Symantec", + "name_de": "Symantec Switzerland", + "orgs": [ + { + "name": "Symantec", + "ts": null + } + ] + }, + { + "uuid": "000d30ce-83c3-4127-aa44-2a95c7278110", + "sector": "Others", + "ts": null, + "shortname": "TAG", + "name_de": "TAG Heuer", + "orgs": [ + { + "name": "TAG Heuer", + "ts": null + } + ] + }, + { + "uuid": "dd2e1e51-9281-4160-a197-216dd1f623d0", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Tecan", + "name_de": "Tecan Group", + "orgs": [ + { + "name": "Tecan Genomics", + "ts": null + } + ] + }, + { + "uuid": "c1bc4822-da74-470a-a29b-324da0f04625", + "sector": "IT", + "ts": null, + "shortname": "Temenos", + "name_de": "Temenos Group", + "orgs": [ + { + "name": "Temenos", + "ts": null + } + ] + }, + { + "uuid": "71385583-fa3c-4f00-a175-4f9fb231cd72", + "sector": "Others", + "ts": null, + "shortname": "TetraPak", + "name_de": "Tetra Pak International", + "orgs": [ + { + "name": "TetraPak, Tetra Pak API Products, \nTetra Pak Decision Science", + "ts": null + } + ] + }, + { + "uuid": "668eb3a8-7c7a-467f-8332-e40660285abc", + "sector": "Gov_Companies", + "ts": null, + "shortname": "TPG", + "name_de": "Transports publics genevois", + "orgs": [ + { + "name": "TPGwidget", + "ts": null + } + ] + }, + { + "uuid": "7494a563-072a-4b7a-ac3e-50beef5b2873", + "sector": "IT", + "ts": null, + "shortname": "u-blox", + "name_de": "u-blox Holding", + "orgs": [ + { + "name": "u-blox", + "ts": null + } + ] + }, + { + "uuid": "af2a2ffd-4c8d-44d8-8535-9bb52b41554a", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "ETHZ", + "name_de": "ETHZ ASL", + "orgs": [ + { + "name": "ETHZ ASL", + "ts": null + } + ] + }, + { + "uuid": "53e45692-d7bc-456a-841b-661512111ddb", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Kanti Glarus", + "name_de": "Kantonsschule Glarus", + "orgs": [ + { + "name": "Kantonsschule Glarus", + "ts": null + } + ] + }, + { + "uuid": "fd0c01bd-b50d-4732-9e99-b9ea86b7e3c0", + "sector": "Gov_Federal", + "ts": null, + "shortname": "BIT", + "name_de": "Bundesamt für Informatik und Telekommunikation BIT", + "orgs": [ + { + "name": "Swiss Admin, BIT - SI-DIP", + "ts": null + } + ] + }, + { + "uuid": "32447166-ebd3-4266-ba20-632803549b58", + "sector": "Gov_Federal", + "ts": null, + "shortname": "KOST", + "name_de": "Koordinationsstelle für dauerhafte Archivierung elektronischer Unterlagen KOST", + "orgs": [ + { + "name": "KOST-CECO", + "ts": null + } + ] + }, + { + "uuid": "b3247fff-45fa-4a00-8b04-3f6b169cfe32", + "sector": "Gov_Federal", + "ts": null, + "shortname": "Swisscovid", + "name_de": "Swisscovid", + "orgs": [ + { + "name": "SwissCovid", + "ts": null + } + ] + }, + { + "uuid": "4f9535a9-b3ce-4345-834a-5cda33fa9c9e", + "sector": "Gov_Federal", + "ts": null, + "shortname": "Swisstopo", + "name_de": "Bundesamt für Landestopografie swisstopo", + "orgs": [ + { + "name": "swisstopo", + "ts": null + } + ] + }, + { + "uuid": "7bda98f4-ac9b-4a5c-976a-a95042d74904", + "sector": "Gov_Federal", + "ts": null, + "shortname": "Schweizer Armee", + "name_de": "Schweizer Armee", + "orgs": [ + { + "name": "Zentrum digitale Medien der Armee", + "ts": null + } + ] + }, + { + "uuid": "12b66f37-224a-4a2a-b3fe-f4bff689061c", + "sector": "Gov_Federal", + "ts": null, + "shortname": "Visualize", + "name_de": "visualize.admin.ch", + "orgs": [ + { + "name": "Visualize Admin", + "ts": null + } + ] + }, + { + "uuid": "5730cbdc-3a9a-49ea-a391-ac15188ad093", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Universität Zürich", + "name_de": "Völkerkundemuseum der Universität Zürich", + "orgs": [ + { + "name": "Völkerkundemuseum der Universität Zürich", + "ts": null + } + ] + }, + { + "uuid": "ad4ccb3e-32a6-4761-b9b5-b72f7b49f960", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Universität St. Gallen", + "name_de": "Universität St. Gallen", + "orgs": [ + { + "name": "Universität St. Gallen", + "ts": null + } + ] + }, + { + "uuid": "b140f10e-71ad-4a07-ac9b-8ba665eed002", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Universität Basel", + "name_de": "Universität Basel", + "orgs": [ + { + "name": "Atmosphärenwissenschaften | Universität Basel", + "ts": null + } + ] + }, + { + "uuid": "f426f2b0-38cf-4dd2-a089-5329e3f1e591", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "Universität Bern", + "name_de": "Universität Bern", + "orgs": [ + { + "name": "Institut für Kommunikations- und Medienwissenschaft, Universität Bern", + "ts": null + } + ] + }, + { + "uuid": "ab9c34a4-21bf-4314-bcaf-155f8a8692b1", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "FHNW", + "name_de": "Fachhochschule Nordwestschweiz", + "orgs": [ + { + "name": "Fachhochschule Nordwestschweiz, FHNW ISE (Post-)Quantum Cryptography, Institut Geomatik, Fachhochschule Nordwestschweiz - Computer Science, \nBiomedical Informatics \nBACnet/IT by IMVS (FHNW) \nFHNW - Institute Geomatics", + "ts": null + } + ] + }, + { + "uuid": "26316daa-56b4-4079-ac8d-6c61bea49fca", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "FHGR", + "name_de": "University of Applied Sciences of the Grisons", + "orgs": [ + { + "name": "University of Applied Sciences of the Grisons", + "ts": null + } + ] + }, + { + "uuid": "8307bf57-a5b2-47a7-b21c-72528c2f17e4", + "sector": "ResearchAndEducation", + "ts": null, + "shortname": "EPFL", + "name_de": "Universität EPFL", + "orgs": [ + { + "name": "GameLab UNIL-EPFL", + "ts": null + } + ] + }, + { + "uuid": "c478ad7a-5be6-402a-b059-36097c022b4e", + "sector": "City", + "ts": null, + "shortname": "Luzern", + "name_de": "Luzern", + "orgs": [ + { + "name": "StadtLuzernIO, Stadt Luzern", + "ts": null + } + ] + }, + { + "uuid": "99713263-9e7a-44a0-94ec-f7086d60a6dc", + "sector": "City", + "ts": null, + "shortname": "Basel-Stadt", + "name_de": "Basel-Stadt, \nStaatsarchiv Basel-Stadt ", + "orgs": [ + { + "name": "Fachstelle für Open Government Data Basel-Stadt", + "ts": null + } + ] + }, + { + "uuid": "b5e2e982-9d2b-48e0-b4cf-252a12e6fdb1", + "sector": "City", + "ts": null, + "shortname": "Bern", + "name_de": "Bern", + "orgs": [ + { + "name": "Bildungs- und Kulturdirektion, Mittelschul- und Berufsbildungsamt, Fachbereich Informatikanwendungen", + "ts": null + } + ] + }, + { + "uuid": "38b82c5e-9a3c-42f8-ac5d-6016dde2d8f3", + "sector": "City", + "ts": null, + "shortname": "Winterthur", + "name_de": "Winterthur", + "orgs": [ + { + "name": "PRW,\nGeoinformation Winterthur", + "ts": null + } + ] + }, + { + "uuid": "447c2995-8cb1-4496-b1d0-ad9047be3ff2", + "sector": "City", + "ts": null, + "shortname": "Vevey", + "name_de": "Vevey", + "orgs": [ + { + "name": "SIT Vevey", + "ts": null + } + ] + }, + { + "uuid": "1969095b-9103-46e5-8d19-66a58bbb425e", + "sector": "City", + "ts": null, + "shortname": "Kriens", + "name_de": "Kriens", + "orgs": [ + { + "name": "Stadt Kriens", + "ts": null + } + ] + }, { "_id": { "$oid": "64556a7f27723ef6d6a4c841" @@ -23,7 +843,7 @@ "sector": "IT", "ts": null, "shortname": "4teamwork", - "name_de": "4teamwork AG", + "name_de": "Fabasoft 4teamwork AG", "orgs": [ { "name": "4teamwork", @@ -90,15 +910,15 @@ "name_de": "Adfinis AG", "orgs": [ { - "name": "adfinis-forks", + "name": "adfinis", "ts": null }, { - "name": "projectcaluma", + "name": "adfinis-forks", "ts": null }, { - "name": "adfinis", + "name": "projectcaluma", "ts": null } ] @@ -444,6 +1264,16 @@ ] }, { + "uuid": "26156d9b-593e-4546-8715-a074e7eaf43c", + "sector": "IT", + "ts": null, + "shortname": "friendly", + "name_de": "Friendly", + "orgs": [ + { "name": "friendlydotch", "ts": null } + ] +}, +{ "_id": { "$oid": "64556a7f27723ef6d6a4c85c" }, @@ -578,12 +1408,16 @@ "uuid": "66e054eb-a175-441c-91cd-1bb17217fda3", "sector": "IT", "ts": null, - "shortname": "itigo", - "name_de": "ITIGO AG", + "shortname": "occ", + "name_de": "Open Circle AG", "orgs": [ { "name": "itigoag", "ts": null + }, + { + "name": "open-circle-ltd", + "ts": null } ] }, @@ -1731,22 +2565,6 @@ } ] }, - { - "_id": { - "$oid": "64556a7f27723ef6d6a4c8a8" - }, - "uuid": "ca0b8296-531c-4186-b49d-8d3b9e53b95d", - "sector": "Others", - "ts": null, - "shortname": "EVAplusAPI", - "name_de": "EVA+ API", - "orgs": [ - { - "name": "EVAplusAPI", - "ts": null - } - ] - }, { "_id": { "$oid": "64556a7f27723ef6d6a4c8a9" @@ -1838,15 +2656,15 @@ "name_de": "SBB", "orgs": [ { - "name": "openTdataCH", + "name": "SchweizerischeBundesbahnen", "ts": null }, { - "name": "sbb-api", + "name": "openTdataCH", "ts": null }, { - "name": "SchweizerischeBundesbahnen", + "name": "sbb-api", "ts": null } ] @@ -2568,22 +3386,6 @@ } ] }, - { - "_id": { - "$oid": "64556a7f27723ef6d6a4c8d4" - }, - "uuid": "6b5a2caa-2eaf-4cea-bbda-b58cf61a0266", - "sector": "ResearchAndEducation", - "ts": null, - "shortname": "fcbg", - "name_de": "Fondation Campus Biotech Geneva", - "orgs": [ - { - "name": "fcbg-hnp", - "ts": null - } - ] - }, { "_id": { "$oid": "64556a7f27723ef6d6a4c8d5" @@ -2738,6 +3540,10 @@ "shortname": "unibe", "name_de": "Universität Bern", "orgs": [ + { + "name": "id-unibe-ch", + "ts": null + }, { "name": "kogpsy", "ts": null @@ -2774,10 +3580,6 @@ "name": "zmk-unibe-ch", "ts": null }, - { - "name": "id-unibe-ch", - "ts": null - }, { "name": "IAM-CGG", "ts": null diff --git a/oss-api/package-lock.json b/oss-api/package-lock.json index 57ae43d8..2b4c9cd5 100644 --- a/oss-api/package-lock.json +++ b/oss-api/package-lock.json @@ -273,9 +273,9 @@ } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -328,9 +328,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5809,9 +5809,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -6954,9 +6954,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -9611,9 +9611,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -9891,9 +9891,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -9935,9 +9935,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -14132,9 +14132,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -15004,9 +15004,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -16946,9 +16946,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wrap-ansi": { diff --git a/oss-api/src/api/api.controller.ts b/oss-api/src/api/api.controller.ts index 3b29d32b..fe25e747 100644 --- a/oss-api/src/api/api.controller.ts +++ b/oss-api/src/api/api.controller.ts @@ -28,14 +28,10 @@ import { import { UserQueryDto } from './dto/user-query.dto'; import { RepositoryQueryDto } from './dto/repository-query.dto'; import { RepositoryQueryPipe } from 'src/repository-query.pipe'; -import { DataService } from '../data/data.service'; @Controller('api') export class ApiController { - constructor( - private mongoDbService: MongoDbService, - private dataService: DataService, - ) {} + constructor(private mongoDbService: MongoDbService) {} private sectors = [ 'IT', 'Communities', @@ -77,7 +73,7 @@ export class ApiController { @Query() queryDto: RepositoryQueryDto, ): Promise { const queryConfig = queryDto; - return await this.handleRepositories(queryConfig); + return await this.handleRepositories(queryConfig, false); } @Get('paginatedUsers') @@ -87,6 +83,15 @@ export class ApiController { return await this.handleUsers(queryConfig); } + @Get('institutionRepositories') + @UsePipes(new RepositoryQueryPipe(), new ValidationPipe({ transform: true })) + async findRepositoriesDetailView( + @Query() queryDto: RepositoryQueryDto, + ): Promise { + const queryConfig = queryDto; + return await this.handleRepositories(queryConfig, true); + } + @Get('latestUpdate') async findLatestUpdate() { return (await this.mongoDbService.latestUpdate())[0]; @@ -143,6 +148,7 @@ export class ApiController { */ private async handleRepositories( queryConfig: RepositoryQueryConfig, + detailedView: boolean, ): Promise { const includeForks = queryConfig.includeForks ? [false, true] : [false]; let condition: Object[] = [ @@ -150,10 +156,14 @@ export class ApiController { fork: { $in: includeForks }, }, ]; - if (queryConfig.search.length > 0) { + if (queryConfig.search.length > 0 && !detailedView) { condition.push({ $text: { $search: queryConfig.search }, }); + } else if (detailedView) { + condition.push({ + institution: queryConfig.search, + }); } let repositories = await this.mongoDbService.findRepositoryWithConditions( queryConfig.sort, diff --git a/oss-api/src/data/data.service.ts b/oss-api/src/data/data.service.ts index dd53b323..28a57906 100644 --- a/oss-api/src/data/data.service.ts +++ b/oss-api/src/data/data.service.ts @@ -135,23 +135,17 @@ export class DataService { case Method.Commit: data.commits = data.commits.concat(parsedData); break; - case Method.PullRequest: - const pullData = parsedData as GitHubPull; - if (pullData.state == 'all') { - data.allPulls = data.allPulls.concat(parsedData); - } - if (pullData.state == 'closed') { - data.closedPulls = data.closedPulls.concat(parsedData); - } + case Method.PullRequestAll: + data.allPulls = data.allPulls.concat(parsedData); break; - case Method.Issue: - const issueData = parsedData as GitHubIssue; - if ((issueData.state = 'all')) { - data.allIssues.concat(parsedData); - } - if ((issueData.state = 'closed')) { - data.closedIssues.concat(parsedData); - } + case Method.PullRequestClosed: + data.closedPulls = data.closedPulls.concat(parsedData); + break; + case Method.IssueAll: + data.allIssues = data.allIssues.concat(parsedData); + break; + case Method.IssueClosed: + data.closedIssues = data.closedIssues.concat(parsedData); break; case Method.Comment: data.commitComments = data.commitComments.concat(parsedData); @@ -250,6 +244,7 @@ export class DataService { aheadByCommits: number, ): Promise { log(`Creating repo info for repo ${repositoryData.repository.name}`); + repositoryData.allIssues; const repositoryStats: RepositoryStats = { num_forks: repositoryData.repository.forks_count, num_contributors: repositoryData.contributors.length, diff --git a/oss-api/src/github-crawler/github-crawler.service.ts b/oss-api/src/github-crawler/github-crawler.service.ts index ccec2eca..c88f0c6a 100644 --- a/oss-api/src/github-crawler/github-crawler.service.ts +++ b/oss-api/src/github-crawler/github-crawler.service.ts @@ -554,7 +554,7 @@ export class GithubCrawlerService { return null; } this.writeRawResponseToFile( - Method.PullRequest, + state == 'all' ? Method.PullRequestAll : Method.PullRequestClosed, institutionName, 'repository', orgName, @@ -618,7 +618,7 @@ export class GithubCrawlerService { return null; } this.writeRawResponseToFile( - Method.Issue, + state == 'all' ? Method.IssueAll : Method.IssueClosed, institutionName, 'repository', orgName, diff --git a/oss-api/src/interfaces.ts b/oss-api/src/interfaces.ts index 169496d6..7717c8eb 100644 --- a/oss-api/src/interfaces.ts +++ b/oss-api/src/interfaces.ts @@ -2280,8 +2280,10 @@ export enum Method { Repository = 'get_github_repo', Contributor = 'get_github_contributors', Commit = 'get_github_commits', - PullRequest = 'get_github_pull_requests', - Issue = 'get_github_issues', + PullRequestAll = 'get_github_pull_requests_all', + PullRequestClosed = 'get_github_pull_requests_closed', + IssueClosed = 'get_github_issues_closed', + IssueAll = 'get_github_issues_all', Comment = 'get_github_commit_comments', Language = 'get_github_langauges', CompareCommit = 'compare_github_commits', diff --git a/oss-api/src/mongo-db/mongo-db.service.ts b/oss-api/src/mongo-db/mongo-db.service.ts index 0ab3cfd6..ab7c46f3 100644 --- a/oss-api/src/mongo-db/mongo-db.service.ts +++ b/oss-api/src/mongo-db/mongo-db.service.ts @@ -399,6 +399,7 @@ export class MongoDbService implements OnApplicationShutdown, OnModuleInit { created_at: 1, updated_at: 1, logo: 1, + archived: 1, }, }, { diff --git a/oss-api/src/telemetry/telemetry.service.ts b/oss-api/src/telemetry/telemetry.service.ts index 1d566fb4..1521c1d4 100644 --- a/oss-api/src/telemetry/telemetry.service.ts +++ b/oss-api/src/telemetry/telemetry.service.ts @@ -34,12 +34,30 @@ export class TelemetryService { description: 'The Date of the lastest crawl', }, ); + const observableokStatus = meter.createObservableCounter( + 'observable_ok_status', + { + description: 'The count of ok status', + }, + ); + const observableErrorStatus = meter.createObservableCounter( + 'observable_error_status', + { + description: 'The count of error status', + }, + ); observableRepoCounter.addCallback((observableResult) => { observableResult.observe(this.repoCounter, attributes); }); observableTimestamp.addCallback((observableResult) => { observableResult.observe(this.latestCrawl, attributes); }); + observableokStatus.addCallback((observableResult) => { + observableResult.observe(this.okStatus, attributes); + }); + observableErrorStatus.addCallback((observableResult) => { + observableResult.observe(this.errorStatus, attributes); + }); } public setRepoCount(repoCount: number) { diff --git a/validate_github_repos.py b/validate_github_repos.py new file mode 100755 index 00000000..b3b25f2d --- /dev/null +++ b/validate_github_repos.py @@ -0,0 +1,30 @@ +import json, sys + + +def fileError(err): + print("File is not formatted correctly:") + print(err) + sys.exit(1) + + +repos = open("github_repos.json") +data = json.load(repos) + +for item in data: + if type(item["uuid"]) is not str or not item["uuid"]: + fileError(item) + if type(item["sector"]) is not str or not item["sector"]: + fileError(item) + if type(item["shortname"]) is not str or not item["shortname"]: + fileError(item) + if type(item["name_de"]) is not str or not item["name_de"]: + fileError(item) + orgs = item["orgs"] + for org in orgs: + if type(org) is not dict: + fileError(org) + if not org["name"]: + fileError(org) + +repos.close() +print("File ok")