├── LICENSE
├── Observables
├── .angular-cli.json
├── .editorconfig
├── .gitignore
├── README.md
├── e2e
│ ├── app.e2e-spec.ts
│ ├── app.po.ts
│ └── tsconfig.e2e.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
│ ├── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ └── app.module.ts
│ ├── assets
│ │ └── .gitkeep
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── styles.css
│ ├── test.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.spec.json
│ └── typings.d.ts
├── tsconfig.json
└── tslint.json
├── README.md
├── assets
├── managePro.png
├── problem-details.png
├── project-architecture.png
└── sign-in.png
├── executor
├── Dockerfile
├── executor_server.py
├── executor_utils.py
├── executor_utils.pyc
└── requirements.txt
├── launcher.sh
├── oj-client
├── .editorconfig
├── README.md
├── angular-cli.json
├── e2e
│ ├── app.e2e-spec.ts
│ ├── app.po.ts
│ └── tsconfig.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
│ ├── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── app.routes.ts
│ │ ├── components
│ │ │ ├── editor
│ │ │ │ ├── editor.component.css
│ │ │ │ ├── editor.component.html
│ │ │ │ ├── editor.component.spec.ts
│ │ │ │ └── editor.component.ts
│ │ │ ├── navbar
│ │ │ │ ├── navbar.component.css
│ │ │ │ ├── navbar.component.html
│ │ │ │ ├── navbar.component.spec.ts
│ │ │ │ └── navbar.component.ts
│ │ │ ├── new-problem
│ │ │ │ ├── new-problem.component.css
│ │ │ │ ├── new-problem.component.html
│ │ │ │ ├── new-problem.component.spec.ts
│ │ │ │ └── new-problem.component.ts
│ │ │ ├── problem-detail
│ │ │ │ ├── problem-detail.component.css
│ │ │ │ ├── problem-detail.component.html
│ │ │ │ ├── problem-detail.component.spec.ts
│ │ │ │ └── problem-detail.component.ts
│ │ │ ├── problem-list
│ │ │ │ ├── problem-list.component.css
│ │ │ │ ├── problem-list.component.html
│ │ │ │ ├── problem-list.component.spec.ts
│ │ │ │ └── problem-list.component.ts
│ │ │ └── profile
│ │ │ │ ├── profile.component.css
│ │ │ │ ├── profile.component.html
│ │ │ │ ├── profile.component.spec.ts
│ │ │ │ └── profile.component.ts
│ │ ├── mock-problems.ts
│ │ ├── models
│ │ │ └── problem.model.ts
│ │ ├── pipes
│ │ │ ├── search.pipe.spec.ts
│ │ │ └── search.pipe.ts
│ │ └── services
│ │ │ ├── auth-guard.service.spec.ts
│ │ │ ├── auth-guard.service.ts
│ │ │ ├── auth.service.spec.ts
│ │ │ ├── auth.service.ts
│ │ │ ├── collaboration.service.spec.ts
│ │ │ ├── collaboration.service.ts
│ │ │ ├── data.service.spec.ts
│ │ │ ├── data.service.ts
│ │ │ ├── input.service.spec.ts
│ │ │ └── input.service.ts
│ ├── assets
│ │ ├── .gitkeep
│ │ └── colors.ts
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── styles.css
│ ├── test.ts
│ └── tsconfig.json
└── tslint.json
└── oj-server
├── models
└── problemModel.js
├── modules
└── redisClient.js
├── package.json
├── routes
├── index.js
└── rest.js
├── server.js
└── services
├── SocketService.js
└── problemService.js
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 xiyouMc
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Observables/.angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "project": {
4 | "name": "observables"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "test": "test.ts",
18 | "tsconfig": "tsconfig.app.json",
19 | "testTsconfig": "tsconfig.spec.json",
20 | "prefix": "app",
21 | "styles": [
22 | "styles.css"
23 | ],
24 | "scripts": [],
25 | "environmentSource": "environments/environment.ts",
26 | "environments": {
27 | "dev": "environments/environment.ts",
28 | "prod": "environments/environment.prod.ts"
29 | }
30 | }
31 | ],
32 | "e2e": {
33 | "protractor": {
34 | "config": "./protractor.conf.js"
35 | }
36 | },
37 | "lint": [
38 | {
39 | "project": "src/tsconfig.app.json"
40 | },
41 | {
42 | "project": "src/tsconfig.spec.json"
43 | },
44 | {
45 | "project": "e2e/tsconfig.e2e.json"
46 | }
47 | ],
48 | "test": {
49 | "karma": {
50 | "config": "./karma.conf.js"
51 | }
52 | },
53 | "defaults": {
54 | "styleExt": "css",
55 | "component": {}
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Observables/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/Observables/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 |
10 | # IDEs and editors
11 | /.idea
12 | .project
13 | .classpath
14 | .c9/
15 | *.launch
16 | .settings/
17 | *.sublime-workspace
18 |
19 | # IDE - VSCode
20 | .vscode/*
21 | !.vscode/settings.json
22 | !.vscode/tasks.json
23 | !.vscode/launch.json
24 | !.vscode/extensions.json
25 |
26 | # misc
27 | /.sass-cache
28 | /connect.lock
29 | /coverage/*
30 | /libpeerconnection.log
31 | npm-debug.log
32 | testem.log
33 | /typings
34 |
35 | # e2e
36 | /e2e/*.js
37 | /e2e/*.map
38 |
39 | #System Files
40 | .DS_Store
41 | Thumbs.db
42 |
--------------------------------------------------------------------------------
/Observables/README.md:
--------------------------------------------------------------------------------
1 | # Observables
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-rc.1.
4 |
5 | ## Development server
6 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
7 |
8 | ## Code scaffolding
9 |
10 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
11 |
12 | ## Build
13 |
14 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
15 |
16 | ## Running unit tests
17 |
18 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
19 |
20 | ## Running end-to-end tests
21 |
22 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
23 | Before running the tests make sure you are serving the app via `ng serve`.
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
28 |
--------------------------------------------------------------------------------
/Observables/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { ObservablesPage } from './app.po';
2 |
3 | describe('observables App', () => {
4 | let page: ObservablesPage;
5 |
6 | beforeEach(() => {
7 | page = new ObservablesPage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('app works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/Observables/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | export class ObservablesPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Observables/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "declaration": false,
5 | "moduleResolution": "node",
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "lib": [
9 | "es2016"
10 | ],
11 | "outDir": "../dist/out-tsc-e2e",
12 | "module": "commonjs",
13 | "target": "es6",
14 | "types":[
15 | "jasmine",
16 | "node"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Observables/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular/cli'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular/cli/plugins/karma')
14 | ],
15 | client:{
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | files: [
19 | { pattern: './src/test.ts', watched: false }
20 | ],
21 | preprocessors: {
22 | './src/test.ts': ['@angular/cli']
23 | },
24 | mime: {
25 | 'text/x-typescript': ['ts','tsx']
26 | },
27 | coverageIstanbulReporter: {
28 | reports: [ 'html', 'lcovonly' ],
29 | fixWebpackSourcePaths: true
30 | },
31 | angularCli: {
32 | environment: 'dev'
33 | },
34 | reporters: config.angularCli && config.angularCli.codeCoverage
35 | ? ['progress', 'coverage-istanbul']
36 | : ['progress', 'kjhtml'],
37 | port: 9876,
38 | colors: true,
39 | logLevel: config.LOG_INFO,
40 | autoWatch: true,
41 | browsers: ['Chrome'],
42 | singleRun: false
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/Observables/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "observables",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "build": "ng build",
9 | "test": "ng test",
10 | "lint": "ng lint",
11 | "e2e": "ng e2e"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/common": "^2.4.0",
16 | "@angular/compiler": "^2.4.0",
17 | "@angular/core": "^2.4.0",
18 | "@angular/forms": "^2.4.0",
19 | "@angular/http": "^2.4.0",
20 | "@angular/platform-browser": "^2.4.0",
21 | "@angular/platform-browser-dynamic": "^2.4.0",
22 | "@angular/router": "^3.4.0",
23 | "core-js": "^2.4.1",
24 | "rxjs": "^5.1.0",
25 | "zone.js": "^0.7.6"
26 | },
27 | "devDependencies": {
28 | "@angular/cli": "1.0.0-rc.1",
29 | "@angular/compiler-cli": "^2.4.0",
30 | "@types/jasmine": "2.5.38",
31 | "@types/node": "~6.0.60",
32 | "codelyzer": "~2.0.0",
33 | "jasmine-core": "~2.5.2",
34 | "jasmine-spec-reporter": "~3.2.0",
35 | "karma": "~1.4.1",
36 | "karma-chrome-launcher": "~2.0.0",
37 | "karma-cli": "~1.0.1",
38 | "karma-jasmine": "~1.1.0",
39 | "karma-jasmine-html-reporter": "^0.2.2",
40 | "karma-coverage-istanbul-reporter": "^0.2.0",
41 | "protractor": "~5.1.0",
42 | "ts-node": "~2.0.0",
43 | "tslint": "~4.4.2",
44 | "typescript": "~2.0.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Observables/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './e2e/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | beforeLaunch: function() {
23 | require('ts-node').register({
24 | project: 'e2e/tsconfig.e2e.json'
25 | });
26 | },
27 | onPrepare() {
28 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/Observables/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/Observables/src/app/app.component.css
--------------------------------------------------------------------------------
/Observables/src/app/app.component.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/Observables/src/app/app.component.html
--------------------------------------------------------------------------------
/Observables/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 |
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async(() => {
7 | TestBed.configureTestingModule({
8 | declarations: [
9 | AppComponent
10 | ],
11 | }).compileComponents();
12 | }));
13 |
14 | it('should create the app', async(() => {
15 | const fixture = TestBed.createComponent(AppComponent);
16 | const app = fixture.debugElement.componentInstance;
17 | expect(app).toBeTruthy();
18 | }));
19 |
20 | it(`should have as title 'app works!'`, async(() => {
21 | const fixture = TestBed.createComponent(AppComponent);
22 | const app = fixture.debugElement.componentInstance;
23 | expect(app.title).toEqual('app works!');
24 | }));
25 |
26 | it('should render title in a h1 tag', async(() => {
27 | const fixture = TestBed.createComponent(AppComponent);
28 | fixture.detectChanges();
29 | const compiled = fixture.debugElement.nativeElement;
30 | expect(compiled.querySelector('h1').textContent).toContain('app works!');
31 | }));
32 | });
33 |
--------------------------------------------------------------------------------
/Observables/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Observable } from 'rxjs/Rx';
3 | import { Subject } from 'rxjs/Rx';
4 | import {Http, Response} from '@angular/http';
5 |
6 | @Component({
7 | selector: 'app-root',
8 | templateUrl: './app.component.html',
9 | styleUrls: ['./app.component.css']
10 | })
11 | export class AppComponent {
12 |
13 | constructor(private http: Http) {}
14 |
15 | ngOnInit() :void {
16 | const source$ = Observable.from(['Adam', 'Bill', 'Cow'])
17 | .map(v => v.toUpperCase())
18 | .map(v => 'I am' + v);
19 | source$.subscribe(
20 | v => console.log(v),
21 | err => console.error(err),
22 | () => console.log('completed')
23 | );
24 |
25 | }
26 |
27 | // getUser(username) {
28 | // return this.http.get('https://api.github.com/users/' + username);
29 | // }
30 |
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Observables/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 | import { HttpModule } from '@angular/http';
5 |
6 | import { AppComponent } from './app.component';
7 |
8 | @NgModule({
9 | declarations: [
10 | AppComponent
11 | ],
12 | imports: [
13 | BrowserModule,
14 | FormsModule,
15 | HttpModule
16 | ],
17 | providers: [],
18 | bootstrap: [AppComponent]
19 | })
20 | export class AppModule { }
21 |
--------------------------------------------------------------------------------
/Observables/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/Observables/src/assets/.gitkeep
--------------------------------------------------------------------------------
/Observables/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/Observables/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/Observables/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/Observables/src/favicon.ico
--------------------------------------------------------------------------------
/Observables/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Observables
6 |
7 |
8 |
9 |
10 |
11 |
12 | Loading...
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Observables/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule);
12 |
--------------------------------------------------------------------------------
/Observables/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/set';
35 |
36 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
37 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
38 |
39 | /** IE10 and IE11 requires the following to support `@angular/animation`. */
40 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
41 |
42 |
43 | /** Evergreen browsers require these. **/
44 | import 'core-js/es6/reflect';
45 | import 'core-js/es7/reflect';
46 |
47 |
48 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/
49 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
50 |
51 |
52 |
53 | /***************************************************************************************************
54 | * Zone JS is required by Angular itself.
55 | */
56 | import 'zone.js/dist/zone'; // Included with Angular CLI.
57 |
58 |
59 |
60 | /***************************************************************************************************
61 | * APPLICATION IMPORTS
62 | */
63 |
64 | /**
65 | * Date, currency, decimal and percent pipes.
66 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
67 | */
68 | // import 'intl'; // Run `npm install --save intl`.
69 |
--------------------------------------------------------------------------------
/Observables/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/Observables/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare var __karma__: any;
17 | declare var require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | const context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/Observables/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "declaration": false,
5 | "moduleResolution": "node",
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "lib": [
9 | "es2016",
10 | "dom"
11 | ],
12 | "outDir": "../out-tsc/app",
13 | "target": "es5",
14 | "module": "es2015",
15 | "baseUrl": "",
16 | "types": []
17 | },
18 | "exclude": [
19 | "test.ts",
20 | "**/*.spec.ts"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/Observables/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "declaration": false,
5 | "moduleResolution": "node",
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "lib": [
9 | "es2016"
10 | ],
11 | "outDir": "../out-tsc/spec",
12 | "module": "commonjs",
13 | "target": "es6",
14 | "baseUrl": "",
15 | "types": [
16 | "jasmine",
17 | "node"
18 | ]
19 | },
20 | "files": [
21 | "test.ts"
22 | ],
23 | "include": [
24 | "**/*.spec.ts"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/Observables/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: {
3 | id: string;
4 | };
5 |
--------------------------------------------------------------------------------
/Observables/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "target": "es5",
11 | "lib": [
12 | "es2016",
13 | "dom"
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Observables/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "callable-types": true,
7 | "class-name": true,
8 | "comment-format": [
9 | true,
10 | "check-space"
11 | ],
12 | "curly": true,
13 | "eofline": true,
14 | "forin": true,
15 | "import-blacklist": [true, "rxjs"],
16 | "import-spacing": true,
17 | "indent": [
18 | true,
19 | "spaces"
20 | ],
21 | "interface-over-type-literal": true,
22 | "label-position": true,
23 | "max-line-length": [
24 | true,
25 | 140
26 | ],
27 | "member-access": false,
28 | "member-ordering": [
29 | true,
30 | "static-before-instance",
31 | "variables-before-functions"
32 | ],
33 | "no-arg": true,
34 | "no-bitwise": true,
35 | "no-console": [
36 | true,
37 | "debug",
38 | "info",
39 | "time",
40 | "timeEnd",
41 | "trace"
42 | ],
43 | "no-construct": true,
44 | "no-debugger": true,
45 | "no-duplicate-variable": true,
46 | "no-empty": false,
47 | "no-empty-interface": true,
48 | "no-eval": true,
49 | "no-inferrable-types": [true, "ignore-params"],
50 | "no-shadowed-variable": true,
51 | "no-string-literal": false,
52 | "no-string-throw": true,
53 | "no-switch-case-fall-through": true,
54 | "no-trailing-whitespace": true,
55 | "no-unused-expression": true,
56 | "no-use-before-declare": true,
57 | "no-var-keyword": true,
58 | "object-literal-sort-keys": false,
59 | "one-line": [
60 | true,
61 | "check-open-brace",
62 | "check-catch",
63 | "check-else",
64 | "check-whitespace"
65 | ],
66 | "prefer-const": true,
67 | "quotemark": [
68 | true,
69 | "single"
70 | ],
71 | "radix": true,
72 | "semicolon": [
73 | "always"
74 | ],
75 | "triple-equals": [
76 | true,
77 | "allow-null-check"
78 | ],
79 | "typedef-whitespace": [
80 | true,
81 | {
82 | "call-signature": "nospace",
83 | "index-signature": "nospace",
84 | "parameter": "nospace",
85 | "property-declaration": "nospace",
86 | "variable-declaration": "nospace"
87 | }
88 | ],
89 | "typeof-compare": true,
90 | "unified-signatures": true,
91 | "variable-name": false,
92 | "whitespace": [
93 | true,
94 | "check-branch",
95 | "check-decl",
96 | "check-operator",
97 | "check-separator",
98 | "check-type"
99 | ],
100 |
101 | "directive-selector": [true, "attribute", "app", "camelCase"],
102 | "component-selector": [true, "element", "app", "kebab-case"],
103 | "use-input-property-decorator": true,
104 | "use-output-property-decorator": true,
105 | "use-host-property-decorator": true,
106 | "no-input-rename": true,
107 | "no-output-rename": true,
108 | "use-life-cycle-interface": true,
109 | "use-pipe-transform-interface": true,
110 | "component-class-suffix": true,
111 | "directive-class-suffix": true,
112 | "no-access-missing-member": true,
113 | "templates-use-public": true,
114 | "invoke-injectable": true
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Collaborative Online Judge System
2 | This is a project to implement a web-based collaborative code editor which supports multiple users editing simultaneously.
3 | I designed a single-page web application for coding, running, and compiling problems.
4 | To refactored and improved system throughput, I used decoupling services based on RESTful API and loaded balancing by Nginx.
5 |
6 | ## Tech Stack
7 | Frontend: Angular2 + TypeScript + Bootstrap + Auth0 + ACE
8 | Backend: Socket.io + Express + MongoDB + Redis + Python + Flask + AWS + Nginx + PM2
9 |
10 | ## Project Architecture
11 |
12 |
13 | ## Demo
14 | #### Before sign-in
15 | 
16 | #### After authentication
17 | 
18 | #### Code excutor
19 | 
20 |
--------------------------------------------------------------------------------
/assets/managePro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/assets/managePro.png
--------------------------------------------------------------------------------
/assets/problem-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/assets/problem-details.png
--------------------------------------------------------------------------------
/assets/project-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/assets/project-architecture.png
--------------------------------------------------------------------------------
/assets/sign-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/assets/sign-in.png
--------------------------------------------------------------------------------
/executor/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:16.04
2 |
3 | MAINTAINER Chan Mao
4 |
5 | RUN apt-get update
6 | RUN apt-get install -y gcc
7 | RUN apt-get install -y g++
8 | RUN apt-get install -y openjdk-8-jdk
9 | RUN apt-get install -y python
10 |
--------------------------------------------------------------------------------
/executor/executor_server.py:
--------------------------------------------------------------------------------
1 | import executor_utils as eu
2 |
3 | import json
4 |
5 | from flask import Flask
6 | from flask import jsonify
7 | from flask import request
8 |
9 | app = Flask(__name__)
10 |
11 | @app.route("/")
12 | def hello():
13 | return "Hehe"
14 |
15 | @app.route("/build_and_run", methods=["POST"])
16 | def build_and_run():
17 | print "Got called: %s" % (request.data)
18 | data = json.loads(request.data)
19 |
20 | if 'code' not in data or 'lang' not in data:
21 | return "You should provide both 'code' and 'lang'"
22 | code = data['code']
23 | lang = data['lang']
24 |
25 | print "API got called with code: %s in %s" % (code, lang)
26 |
27 | result = eu.build_and_run(code, lang)
28 | return jsonify(result)
29 |
30 | if __name__ == "__main__":
31 | eu.load_image()
32 | app.run()
33 |
--------------------------------------------------------------------------------
/executor/executor_utils.py:
--------------------------------------------------------------------------------
1 | import docker
2 | import os
3 | import shutil
4 | import uuid
5 |
6 | from docker.errors import *
7 |
8 | IMAGE_NAME = "qianmao/cs503_coj_demo_1"
9 |
10 | CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
11 | TEMP_BUILD_DIR = "%s/tmp/" % CURRENT_DIR
12 |
13 | SOURCE_FILE_NAMES = {
14 | "java" : "Example.java",
15 | 'python' : 'example.py'
16 | }
17 |
18 | BINARY_NAMES = {
19 | "java" : "Example",
20 | 'python' : 'example.py'
21 | }
22 |
23 | BUILD_COMMANDS = {
24 | "java" : "javac",
25 | "python" : "python"
26 | }
27 |
28 | EXECUTE_COMMANDS = {
29 | "java" : "java",
30 | "python" : "python"
31 | }
32 |
33 | client = docker.from_env()
34 |
35 | def load_image():
36 | try:
37 | client.images.get(IMAGE_NAME)
38 | except ImageNotFound:
39 | print "Image not found locally. Loading from Dockerhub..."
40 | client.images.pull(IMAGE_NAME)
41 | except APIError:
42 | print "Image not found locally. DockerHub is not accessible."
43 | return
44 | print "Image:[%s] loaded" % IMAGE_NAME
45 |
46 | def build_and_run(code, lang):
47 | result = {'build': None, 'run': None, 'error': None}
48 |
49 | source_file_parent_dir_name = uuid.uuid4()
50 | source_file_host_dir = "%s/%s" % (TEMP_BUILD_DIR, source_file_parent_dir_name)
51 | source_file_guest_dir = "/test/%s" % (source_file_parent_dir_name)
52 | make_dir(source_file_host_dir)
53 |
54 | with open('%s/%s' % (source_file_host_dir, SOURCE_FILE_NAMES[lang]), 'w') as source_file:
55 | source_file.write(code)
56 |
57 | try:
58 | client.containers.run(
59 | image=IMAGE_NAME,
60 | command="%s %s" % (BUILD_COMMANDS[lang], SOURCE_FILE_NAMES[lang]),
61 | volumes={source_file_host_dir: {'bind': source_file_guest_dir, 'mode': 'rw'}},
62 | working_dir=source_file_guest_dir)
63 | print "Source built."
64 | result['build'] = 'OK'
65 | except ContainerError as e:
66 | print "Build failed."
67 | result['build'] = e.stderr
68 | shutil.rmtree(source_file_host_dir)
69 | return result
70 |
71 | try:
72 | log = client.containers.run(
73 | image=IMAGE_NAME,
74 | command="%s %s" % (EXECUTE_COMMANDS[lang], BINARY_NAMES[lang]),
75 | volumes={source_file_host_dir: {'bind': source_file_guest_dir, 'mode': 'rw'}},
76 | working_dir=source_file_guest_dir)
77 | print "Executed."
78 | result['run'] = log
79 | except ContainerError as e:
80 | print "Execution failed."
81 | result['run'] = e.stderr
82 | shutil.rmtree(source_file_host_dir)
83 | return result
84 |
85 | shutil.rmtree(source_file_host_dir)
86 | return result
87 |
88 | def make_dir(dir):
89 | try:
90 | os.mkdir(dir)
91 | print "Temp build directory [%s] created." % dir
92 | except OSError:
93 | print "Temp build directory [%s] exists." % dir
94 |
--------------------------------------------------------------------------------
/executor/executor_utils.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/executor/executor_utils.pyc
--------------------------------------------------------------------------------
/executor/requirements.txt:
--------------------------------------------------------------------------------
1 | docker
2 | Flask
3 |
--------------------------------------------------------------------------------
/launcher.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | fuser -k 3000/tcp
3 | fuser -k 5000/tcp
4 |
5 | service redis_6379 start
6 | cd ./oj-server
7 | npm install
8 | nodemon server.js &
9 | cd ../oj-client
10 | npm install
11 | ng build --watch &
12 | cd ../executor
13 | pip install -r requirements.txt
14 | python executor_server.py &
15 |
16 | echo "=================================================="
17 | read -p "PRESS [ENTER] TO TERMINATE PROCESSES." PRESSKEY
18 |
19 | fuser -k 3000/tcp
20 | fuser -k 5000/tcp
21 | service redis_6379 stop
22 |
--------------------------------------------------------------------------------
/oj-client/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/oj-client/README.md:
--------------------------------------------------------------------------------
1 | # OjClient
2 |
3 | This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.28.3.
4 |
5 | ## Development server
6 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
7 |
8 | ## Code scaffolding
9 |
10 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
11 |
12 | ## Build
13 |
14 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
15 |
16 | ## Running unit tests
17 |
18 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
19 |
20 | ## Running end-to-end tests
21 |
22 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
23 | Before running the tests make sure you are serving the app via `ng serve`.
24 |
25 | ## Deploying to GitHub Pages
26 |
27 | Run `ng github-pages:deploy` to deploy to GitHub Pages.
28 |
29 | ## Further help
30 |
31 | To get more help on the `angular-cli` use `ng help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
32 |
--------------------------------------------------------------------------------
/oj-client/angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": {
3 | "version": "1.0.0-beta.28.3",
4 | "name": "oj-client"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "../public",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "test": "test.ts",
18 | "tsconfig": "tsconfig.json",
19 | "prefix": "app",
20 | "styles": [
21 | "styles.css",
22 | "../node_modules/bootstrap/dist/css/bootstrap.css"
23 | ],
24 | "scripts": [
25 | "../node_modules/jquery/dist/jquery.js",
26 | "../node_modules/bootstrap/dist/js/bootstrap.js",
27 | "../node_modules/ace-builds/src-min-noconflict/ace.js",
28 | "../node_modules/ace-builds/src-min-noconflict/theme-eclipse.js",
29 | "../node_modules/ace-builds/src-min-noconflict/mode-java.js",
30 | "../node_modules/ace-builds/src-min-noconflict/mode-c_cpp.js",
31 | "../node_modules/ace-builds/src-min-noconflict/mode-python.js"
32 |
33 |
34 | ],
35 | "environmentSource": "environments/environment.ts",
36 | "environments": {
37 | "dev": "environments/environment.ts",
38 | "prod": "environments/environment.prod.ts"
39 | }
40 | }
41 | ],
42 | "e2e": {
43 | "protractor": {
44 | "config": "./protractor.conf.js"
45 | }
46 | },
47 | "lint": [
48 | {
49 | "files": "src/**/*.ts",
50 | "project": "src/tsconfig.json"
51 | },
52 | {
53 | "files": "e2e/**/*.ts",
54 | "project": "e2e/tsconfig.json"
55 | }
56 | ],
57 | "test": {
58 | "karma": {
59 | "config": "./karma.conf.js"
60 | }
61 | },
62 | "defaults": {
63 | "styleExt": "css",
64 | "prefixInterfaces": false,
65 | "inline": {
66 | "style": false,
67 | "template": false
68 | },
69 | "spec": {
70 | "class": false,
71 | "component": true,
72 | "directive": true,
73 | "module": false,
74 | "pipe": true,
75 | "service": true
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/oj-client/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { OjClientPage } from './app.po';
2 |
3 | describe('oj-client App', function() {
4 | let page: OjClientPage;
5 |
6 | beforeEach(() => {
7 | page = new OjClientPage();
8 | });
9 |
10 | it('should display message saying app works', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('app works!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/oj-client/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, element, by } from 'protractor';
2 |
3 | export class OjClientPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/oj-client/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "declaration": false,
5 | "emitDecoratorMetadata": true,
6 | "experimentalDecorators": true,
7 | "module": "commonjs",
8 | "moduleResolution": "node",
9 | "outDir": "../dist/out-tsc-e2e",
10 | "sourceMap": true,
11 | "target": "es5",
12 | "typeRoots": [
13 | "../node_modules/@types"
14 | ]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/oj-client/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', 'angular-cli'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-remap-istanbul'),
12 | require('angular-cli/plugins/karma')
13 | ],
14 | files: [
15 | { pattern: './src/test.ts', watched: false }
16 | ],
17 | preprocessors: {
18 | './src/test.ts': ['angular-cli']
19 | },
20 | mime: {
21 | 'text/x-typescript': ['ts','tsx']
22 | },
23 | remapIstanbulReporter: {
24 | reports: {
25 | html: 'coverage',
26 | lcovonly: './coverage/coverage.lcov'
27 | }
28 | },
29 | angularCli: {
30 | config: './angular-cli.json',
31 | environment: 'dev'
32 | },
33 | reporters: config.angularCli && config.angularCli.codeCoverage
34 | ? ['progress', 'karma-remap-istanbul']
35 | : ['progress'],
36 | port: 9876,
37 | colors: true,
38 | logLevel: config.LOG_INFO,
39 | autoWatch: true,
40 | browsers: ['Chrome'],
41 | singleRun: false
42 | });
43 | };
44 |
--------------------------------------------------------------------------------
/oj-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oj-client",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "angular-cli": {},
6 | "scripts": {
7 | "ng": "ng",
8 | "start": "ng serve",
9 | "test": "ng test",
10 | "pree2e": "webdriver-manager update --standalone false --gecko false",
11 | "e2e": "protractor"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/common": "^2.3.1",
16 | "@angular/compiler": "^2.3.1",
17 | "@angular/core": "^2.3.1",
18 | "@angular/forms": "^2.3.1",
19 | "@angular/http": "^2.3.1",
20 | "@angular/platform-browser": "^2.3.1",
21 | "@angular/platform-browser-dynamic": "^2.3.1",
22 | "@angular/router": "^3.3.1",
23 | "ace-builds": "^1.2.6",
24 | "angular2-jwt": "^0.1.28",
25 | "bootstrap": "^3.3.7",
26 | "core-js": "^2.4.1",
27 | "jquery": "^3.1.1",
28 | "rxjs": "^5.0.1",
29 | "ts-helpers": "^1.1.1",
30 | "zone.js": "^0.7.2"
31 | },
32 | "devDependencies": {
33 | "@angular/cli": "1.0.0-rc.1",
34 | "@angular/compiler-cli": "^2.3.1",
35 | "@types/jasmine": "2.5.38",
36 | "@types/node": "^6.0.42",
37 | "codelyzer": "~2.0.0-beta.1",
38 | "jasmine-core": "2.5.2",
39 | "jasmine-spec-reporter": "2.5.0",
40 | "karma": "1.2.0",
41 | "karma-chrome-launcher": "^2.0.0",
42 | "karma-cli": "^1.0.1",
43 | "karma-jasmine": "^1.0.2",
44 | "karma-remap-istanbul": "^0.2.1",
45 | "protractor": "~4.0.13",
46 | "ts-node": "1.2.1",
47 | "tslint": "^4.3.0",
48 | "typescript": "~2.0.3"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/oj-client/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | /*global jasmine */
5 | var SpecReporter = require('jasmine-spec-reporter');
6 |
7 | exports.config = {
8 | allScriptsTimeout: 11000,
9 | specs: [
10 | './e2e/**/*.e2e-spec.ts'
11 | ],
12 | capabilities: {
13 | 'browserName': 'chrome'
14 | },
15 | directConnect: true,
16 | baseUrl: 'http://localhost:4200/',
17 | framework: 'jasmine',
18 | jasmineNodeOpts: {
19 | showColors: true,
20 | defaultTimeoutInterval: 30000,
21 | print: function() {}
22 | },
23 | useAllAngular2AppRoots: true,
24 | beforeLaunch: function() {
25 | require('ts-node').register({
26 | project: 'e2e'
27 | });
28 | },
29 | onPrepare: function() {
30 | jasmine.getEnv().addReporter(new SpecReporter());
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/app.component.css
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 |
3 | import { TestBed, async } from '@angular/core/testing';
4 | import { AppComponent } from './app.component';
5 |
6 | describe('AppComponent', () => {
7 | beforeEach(() => {
8 | TestBed.configureTestingModule({
9 | declarations: [
10 | AppComponent
11 | ],
12 | });
13 | TestBed.compileComponents();
14 | });
15 |
16 | it('should create the app', async(() => {
17 | const fixture = TestBed.createComponent(AppComponent);
18 | const app = fixture.debugElement.componentInstance;
19 | expect(app).toBeTruthy();
20 | }));
21 |
22 | it(`should have as title 'app works!'`, async(() => {
23 | const fixture = TestBed.createComponent(AppComponent);
24 | const app = fixture.debugElement.componentInstance;
25 | expect(app.title).toEqual('app works!');
26 | }));
27 |
28 | it('should render title in a h1 tag', async(() => {
29 | const fixture = TestBed.createComponent(AppComponent);
30 | fixture.detectChanges();
31 | const compiled = fixture.debugElement.nativeElement;
32 | expect(compiled.querySelector('h1').textContent).toContain('app works!');
33 | }));
34 | });
35 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 | export class AppComponent {
9 | title = 'app works again!';
10 | }
11 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 | import { ReactiveFormsModule } from '@angular/forms';
5 | import { HttpModule } from '@angular/http';
6 |
7 | import { routing } from "./app.routes";
8 |
9 | import { AppComponent } from './app.component';
10 | import { ProblemListComponent } from './components/problem-list/problem-list.component';
11 | import { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';
12 |
13 | import { DataService } from "./services/data.service";
14 | import { AuthService } from "./services/auth.service";
15 | import { AuthGuardService } from "./services/auth-guard.service";
16 | import { CollaborationService } from "./services/collaboration.service";
17 | import { InputService } from "./services/input.service";
18 |
19 | import { NewProblemComponent } from './components/new-problem/new-problem.component';
20 | import { NavbarComponent } from './components/navbar/navbar.component';
21 | import { ProfileComponent } from './components/profile/profile.component';
22 | import { EditorComponent } from './components/editor/editor.component';
23 | import { SearchPipe } from './pipes/search.pipe';
24 |
25 | @NgModule({
26 | declarations: [
27 | AppComponent,
28 | ProblemListComponent,
29 | ProblemDetailComponent,
30 | NewProblemComponent,
31 | NavbarComponent,
32 | ProfileComponent,
33 | EditorComponent,
34 | SearchPipe
35 | ],
36 | imports: [
37 | BrowserModule,
38 | FormsModule,
39 | ReactiveFormsModule,
40 | HttpModule,
41 | routing
42 | ],
43 | providers: [{
44 | provide: "data",
45 | useClass: DataService
46 | }, {
47 | provide: "auth",
48 | useClass: AuthService
49 | }, {
50 | provide: "authGuard",
51 | useClass: AuthGuardService
52 | }, {
53 | provide: "collaboration",
54 | useClass: CollaborationService
55 | }, {
56 | provide: "input",
57 | useClass: InputService
58 | }],
59 | bootstrap: [AppComponent]
60 | })
61 | export class AppModule { }
62 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes, RouterModule } from "@angular/router";
2 | import { ProblemListComponent } from './components/problem-list/problem-list.component';
3 | import { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';
4 | import { ProfileComponent } from './components/profile/profile.component';
5 |
6 |
7 | const routes: Routes = [
8 | {
9 | path: '',
10 | redirectTo: 'problems',
11 | pathMatch: 'full'
12 | },
13 | {
14 | path: 'problems',
15 | component: ProblemListComponent
16 | },
17 | {
18 | path: 'problems/:id',
19 | component: ProblemDetailComponent
20 | },
21 | {
22 | path: 'profile',
23 | canActivate: ['authGuard'],
24 | component: ProfileComponent
25 | }, {
26 | path: '**',
27 | redirectTo: 'problems'
28 | }
29 | ];
30 |
31 | export const routing = RouterModule.forRoot(routes);
32 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.css:
--------------------------------------------------------------------------------
1 | @media screen {
2 | #editor {
3 | height: 600px;
4 | }
5 | .lang-select {
6 | width: 100px;
7 | margin-right: 10px;
8 | }
9 | header .btn {
10 | margin: 0 5px;
11 | }
12 | footer .btn {
13 | margin: 0 5px;
14 | }
15 | .editor-footer, .editor-header {
16 | margin: 10px 0;
17 | }
18 | .cursor {
19 | /*position:absolute;*/
20 | background: rgba(0, 250, 0, 0.5);
21 | z-index: 40;
22 | width: 2px!important
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.html:
--------------------------------------------------------------------------------
1 |
2 |
34 |
35 |
38 |
39 |
40 | {{output}}
41 |
42 |
43 |
46 |
47 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.spec.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/components/editor/editor.component.spec.ts
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit, Inject} from '@angular/core';
2 |
3 | import {ActivatedRoute, Params} from '@angular/router';
4 |
5 | declare var ace: any;
6 |
7 | @Component({
8 | selector: 'app-editor',
9 | templateUrl: './editor.component.html',
10 | styleUrls: ['./editor.component.css']
11 | })
12 | export class EditorComponent implements OnInit {
13 |
14 | editor: any;
15 |
16 | public languages: string[] = ['Java', 'C++', 'Python'];
17 | language: string = 'Java'; // default
18 |
19 | sessionId: string;
20 |
21 | output: string;
22 |
23 | defaultContent = {
24 | 'Java': `public class Example {
25 | public static void main(String[] args) {
26 | // Type your Java code here
27 | }
28 | }`,
29 | 'C++': `#include
30 | using namespace std;
31 |
32 | int main() {
33 | // Type your C++ code here
34 | return 0;
35 | }`,
36 | 'Python': `class Solution:
37 | def example():
38 | # Write your Python code here`
39 | };
40 |
41 | constructor(@Inject('collaboration') private collaboration,
42 | @Inject('data') private data,
43 | private route: ActivatedRoute) {
44 |
45 | }
46 |
47 | ngOnInit() {
48 | this.route.params
49 | .subscribe(params => {
50 | this.sessionId = params['id'];
51 | this.initEditor();
52 | });
53 | }
54 |
55 | initEditor() {
56 | this.editor = ace.edit('editor');
57 | this.editor.setTheme('ace/theme/eclipse');
58 | this.resetEditor();
59 | this.editor.$blockScrolling = Infinity;
60 |
61 | document.getElementsByTagName('textarea')[0].focus();
62 |
63 | this.collaboration.init(this.editor, this.sessionId);
64 | this.editor.lastAppliedChange = null;
65 |
66 | this.editor.on('change', (e) => {
67 | console.log('editor changes: ' + JSON.stringify(e));
68 | if (this.editor.lastAppliedChange != e) {
69 | this.collaboration.change(JSON.stringify(e));
70 | }
71 | });
72 |
73 | this.editor.getSession().getSelection().on("changeCursor", () => {
74 | let cursor = this.editor.getSession().getSelection().getCursor();
75 | console.log('cursor moves: ' + JSON.stringify(cursor));
76 | this.collaboration.cursorMove(JSON.stringify(cursor));
77 | });
78 |
79 | this.collaboration.restoreBuffer();
80 | }
81 |
82 | setLanguage(language: string): void {
83 | this.language = language;
84 | this.resetEditor();
85 | }
86 |
87 | resetEditor(): void {
88 | this.editor.getSession().setMode('ace/mode/' + this.language.toLowerCase());
89 | this.editor.setValue(this.defaultContent[this.language]);
90 | this.output = '';
91 | }
92 |
93 | submit(): void {
94 | let userCode = this.editor.getValue();
95 | let data = {
96 | user_code: userCode,
97 | lang: this.language.toLowerCase()
98 | };
99 | this.data.buildAndRun(data)
100 | .then(res => this.output = res.text);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/components/navbar/navbar.component.css
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
42 |
43 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { NavbarComponent } from './navbar.component';
4 |
5 | describe('NavbarComponent', () => {
6 | let component: NavbarComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ NavbarComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(NavbarComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
2 | import { FormControl } from '@angular/forms';
3 | import { Subscription } from 'rxjs/Subscription';
4 | import { Router } from '@angular/router';
5 | import 'rxjs/add/operator/debounceTime';
6 |
7 | @Component({
8 | selector: 'app-navbar',
9 | templateUrl: './navbar.component.html',
10 | styleUrls: ['./navbar.component.css']
11 | })
12 | export class NavbarComponent implements OnInit {
13 |
14 | title = "COJ";
15 |
16 | username = "";
17 |
18 | searchBox: FormControl = new FormControl();
19 | subscription: Subscription;
20 |
21 | constructor(@Inject('auth') private auth,
22 | @Inject('input') private input,
23 | private router: Router) { }
24 |
25 | ngOnInit() {
26 | if (this.auth.authenticated()) {
27 | this.username = this.auth.getProfile().nickname;
28 | }
29 |
30 | this.subscription = this.searchBox
31 | .valueChanges
32 | .debounceTime(200)
33 | .subscribe(
34 | term => {
35 | this.input.changeInput(term);
36 | }
37 | );
38 | }
39 |
40 | ngOnDestroy() {
41 | this.subscription.unsubscribe();
42 | }
43 |
44 | searchProblem(): void {
45 | this.router.navigate(['/problems']);
46 | }
47 |
48 | login(): void {
49 | this.auth.login()
50 | .then(profile => this.username = profile.nickname);
51 | }
52 |
53 | logout(): void {
54 | this.auth.logout();
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/components/new-problem/new-problem.component.css
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.html:
--------------------------------------------------------------------------------
1 |
29 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { NewProblemComponent } from './new-problem.component';
4 |
5 | describe('NewProblemComponent', () => {
6 | let component: NewProblemComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ NewProblemComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(NewProblemComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Inject } from '@angular/core';
2 | import { Problem } from "../../models/problem.model";
3 |
4 | const DEFAULT_PROBLEM: Problem = Object.freeze({
5 | id: 0,
6 | name: "",
7 | desc: "",
8 | difficulty: "Easy"
9 | });
10 |
11 | @Component({
12 | selector: 'app-new-problem',
13 | templateUrl: './new-problem.component.html',
14 | styleUrls: ['./new-problem.component.css']
15 | })
16 | export class NewProblemComponent implements OnInit {
17 |
18 | public difficulties = ["Easy", "Medium", "Hard", "Super"];
19 |
20 | newProblem: Problem = Object.assign({}, DEFAULT_PROBLEM);
21 |
22 | constructor(@Inject("data") private data,
23 | @Inject("authGuard") private authGuard ) { }
24 |
25 | ngOnInit() {
26 | }
27 |
28 | addProblem(): void {
29 | this.data.addProblem(this.newProblem)
30 | .catch(error => console.log(error._body));
31 | this.newProblem = Object.assign({}, DEFAULT_PROBLEM);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/components/problem-detail/problem-detail.component.css
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{problem.id}}. {{problem.name}}
6 |
7 |
8 | {{problem.desc}}
9 |
10 |
11 |
12 |
13 |
16 |
17 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { ProblemDetailComponent } from './problem-detail.component';
7 |
8 | describe('ProblemDetailComponent', () => {
9 | let component: ProblemDetailComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [ ProblemDetailComponent ]
15 | })
16 | .compileComponents();
17 | }));
18 |
19 | beforeEach(() => {
20 | fixture = TestBed.createComponent(ProblemDetailComponent);
21 | component = fixture.componentInstance;
22 | fixture.detectChanges();
23 | });
24 |
25 | it('should create', () => {
26 | expect(component).toBeTruthy();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Inject } from '@angular/core';
2 | import { Problem } from "../../models/problem.model";
3 | import { ActivatedRoute} from "@angular/router";
4 |
5 | @Component({
6 | selector: 'app-problem-detail',
7 | templateUrl: './problem-detail.component.html',
8 | styleUrls: ['./problem-detail.component.css']
9 | })
10 | export class ProblemDetailComponent implements OnInit {
11 |
12 | problem: Problem;
13 |
14 | constructor(
15 | private route: ActivatedRoute,
16 | @Inject("data") private data
17 | ) { }
18 |
19 | ngOnInit() {
20 | this.route.params.subscribe(params => {
21 | this.data.getProblem(+params['id'])
22 | .then(problem => this.problem = problem);
23 | });
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.css:
--------------------------------------------------------------------------------
1 | .difficulty {
2 | min-width: 65px;
3 | margin-right: 10px;
4 | }
5 |
6 | .label.difficulty {
7 | padding-top: 0.6em;
8 | color: #fbfdfa;
9 | font-size: 12px;
10 | }
11 |
12 | .title {
13 | font-size: 1.2em;
14 | }
15 |
16 | .diff-easy {
17 | background-color: #42ebf4;
18 | }
19 |
20 | .diff-medium {
21 | background-color: #92cf5c;
22 | }
23 |
24 | .diff-hard {
25 | background-color: #dd0d1e;
26 | }
27 |
28 | .diff-super {
29 | background-color: #8d16e2;
30 | }
31 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
My birthday is {{birthday | date: 'fullDate' | uppercase }}
4 |
My account balance is {{money | currency }}
5 |
My credit card Apt is {{Apr | percent }}
6 |
12 |
13 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { ProblemListComponent } from './problem-list.component';
7 |
8 | describe('ProblemListComponent', () => {
9 | let component: ProblemListComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [ ProblemListComponent ]
15 | })
16 | .compileComponents();
17 | }));
18 |
19 | beforeEach(() => {
20 | fixture = TestBed.createComponent(ProblemListComponent);
21 | component = fixture.componentInstance;
22 | fixture.detectChanges();
23 | });
24 |
25 | it('should create', () => {
26 | expect(component).toBeTruthy();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Inject } from '@angular/core';
2 | import { Problem } from "../../models/problem.model";
3 | import { Subscription } from 'rxjs/Subscription';
4 |
5 |
6 | @Component({
7 | selector: 'app-problem-list',
8 | templateUrl: './problem-list.component.html',
9 | styleUrls: ['./problem-list.component.css']
10 | })
11 | export class ProblemListComponent implements OnInit {
12 |
13 | problems: Problem[] = [];
14 | subscriptionProblems: Subscription;
15 |
16 | birthday = new Date();
17 | money = 25;
18 | Apr = 0.21;
19 |
20 | searchTerm: string = '';
21 | subscriptionInput: Subscription;
22 |
23 | constructor(@Inject("data") private data,
24 | @Inject("input") private input) { }
25 |
26 | ngOnInit() {
27 | this.getProblems();
28 | this.getSearchTerm();
29 | }
30 |
31 | getProblems(): void {
32 | this.subscriptionProblems = this.data.getProblems()
33 | .subscribe(problems => this.problems = problems);
34 | }
35 |
36 | getSearchTerm(): void {
37 | this.subscriptionInput = this.input.getInput()
38 | .subscribe(
39 | inputTerm => this.searchTerm = inputTerm
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/profile/profile.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sugarac/angular-online-judge/1037d15d0e64e33ee52fe4323d59ba42b9dc77ed/oj-client/src/app/components/profile/profile.component.css
--------------------------------------------------------------------------------
/oj-client/src/app/components/profile/profile.component.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
22 |
23 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/profile/profile.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ProfileComponent } from './profile.component';
4 |
5 | describe('ProfileComponent', () => {
6 | let component: ProfileComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ProfileComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ProfileComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/profile/profile.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Inject } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-profile',
5 | templateUrl: './profile.component.html',
6 | styleUrls: ['./profile.component.css']
7 | })
8 | export class ProfileComponent implements OnInit {
9 | email: string = '';
10 | username: string = '';
11 |
12 | constructor(@Inject('auth') private auth) { }
13 |
14 | ngOnInit() {
15 | let profile = this.auth.getProfile();
16 | this.email = profile.email;
17 | this.username = profile.nickname;
18 | }
19 |
20 | resetPassword() {
21 | this.auth.resetPassword();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/oj-client/src/app/mock-problems.ts:
--------------------------------------------------------------------------------
1 | import { Problem } from "./models/problem.model";
2 |
3 | export const PROBLEMS: Problem[] = [
4 | {
5 | id: 1,
6 | name: "Two Sum",
7 | desc: `Given an array of integers, find two numbers such that they add up to a specific target number.
8 |
9 | The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are NOT zero-based.`,
10 | difficulty: "easy"
11 | },
12 | {
13 | id: 2,
14 | name: "3Sum",
15 | desc: `Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.`,
16 | difficulty: "medium"
17 | },
18 | {
19 | id: 3,
20 | name: "4Sum",
21 | desc: `Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
22 |
23 | Find all unique quadruplets in the array which gives the sum of target.`,
24 | difficulty: "medium"
25 | },
26 | {
27 | id: 4,
28 | name: "Triangle Count",
29 | desc: `Given an array of integers, how many three numbers can be found in the array, so that we can build an triangle whose three edges length is the three numbers that we find?`,
30 | difficulty: "hard"
31 | },
32 | {
33 | id: 5,
34 | name: "Sliding Window Maximum",
35 | desc: `Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration from the start of the array, find the maximum number inside the window at each moving.`,
36 | difficulty: "super"
37 | }
38 | ];
39 |
--------------------------------------------------------------------------------
/oj-client/src/app/models/problem.model.ts:
--------------------------------------------------------------------------------
1 | export class Problem {
2 | id: number;
3 | name: string;
4 | desc: string;
5 | difficulty: string;
6 | }
7 |
--------------------------------------------------------------------------------
/oj-client/src/app/pipes/search.pipe.spec.ts:
--------------------------------------------------------------------------------
1 | import { SearchPipe } from './search.pipe';
2 |
3 | describe('SearchPipe', () => {
4 | it('create an instance', () => {
5 | const pipe = new SearchPipe();
6 | expect(pipe).toBeTruthy();
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/oj-client/src/app/pipes/search.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | import { Problem } from '../models/problem.model';
4 |
5 | @Pipe({
6 | name: 'search'
7 | })
8 | export class SearchPipe implements PipeTransform {
9 |
10 | transform(problems: Problem[], term: string): Problem[] {
11 | console.log(problems);
12 | return problems.filter(
13 | problem => problem.name.toLowerCase().includes(term));
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/auth-guard.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { AuthGuardService } from './auth-guard.service';
4 |
5 | describe('AuthGuardService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [AuthGuardService]
9 | });
10 | });
11 |
12 | it('should ...', inject([AuthGuardService], (service: AuthGuardService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/auth-guard.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Inject } from '@angular/core';
2 | import { Router, CanActivate } from '@angular/router';
3 |
4 | @Injectable()
5 | export class AuthGuardService implements CanActivate {
6 |
7 | constructor(@Inject('auth') private auth, private router: Router) { }
8 |
9 | canActivate() {
10 | if (this.auth.authenticated()) {
11 | return true;
12 | } else {
13 | // redirect to home page if not logged in
14 | this.router.navigate(['/problems']);
15 | return false;
16 | }
17 | }
18 |
19 | isAdmin(): boolean {
20 | if (this.auth.authenticated() && this.auth.getProfile().roles.includes('Admin')) {
21 | return true;
22 | } else {
23 | return false;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/auth.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { AuthService } from './auth.service';
4 |
5 | describe('AuthService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [AuthService]
9 | });
10 | });
11 |
12 | it('should ...', inject([AuthService], (service: AuthService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/auth.service.ts:
--------------------------------------------------------------------------------
1 | // app/auth.service.ts
2 |
3 | import { Injectable } from '@angular/core';
4 | import { tokenNotExpired } from 'angular2-jwt';
5 | import { Http, Response, Headers } from '@angular/http';
6 | import 'rxjs/add/operator/toPromise';
7 |
8 | // Avoid name not found warnings
9 | declare var Auth0Lock: any;
10 |
11 | @Injectable()
12 | export class AuthService {
13 | // Configure Auth0
14 | clientId = 'oKBLizpdfjbRhIfvcUytmrmji0L1DUBA';
15 | domain = 'bittiger503codelab.auth0.com';
16 | lock = new Auth0Lock(this.clientId, this.domain, {});
17 |
18 | constructor(private http: Http) {
19 |
20 | }
21 |
22 | public login(): Promise