├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── Flutter-CI.yml
├── .gitignore
├── .travis.yml
├── .vscode
└── settings.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── app.json
├── docker-compose.yml
├── labellab-client
├── .dockerignore
├── .env.example
├── .eslintrc.js
├── .gitignore
├── Dockerfile
├── README.md
├── config
│ ├── env.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── prettier.config.js
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── __tests__
│ ├── components
│ │ ├── dashboard.test.js
│ │ ├── issueDetails.test.js
│ │ ├── issues.test.js
│ │ └── login.test.js
│ └── reducers
│ │ ├── authReducer.test.js
│ │ ├── projectReducers.test.js
│ │ └── registerReducer.test.js
│ ├── actions
│ ├── analytics.js
│ ├── auth.js
│ ├── image.js
│ ├── index.js
│ ├── issue.js
│ ├── label.js
│ ├── model.js
│ ├── notification.js
│ ├── project
│ │ ├── fetchDetails.js
│ │ ├── index.js
│ │ ├── logs.js
│ │ ├── member.js
│ │ ├── pathTracking.js
│ │ ├── projectDetails.js
│ │ ├── search.js
│ │ └── teams.js
│ ├── register.js
│ └── user.js
│ ├── components
│ ├── dashboard
│ │ ├── css
│ │ │ ├── dashboard.css
│ │ │ └── previous.css
│ │ ├── index.js
│ │ └── previous.js
│ ├── error
│ │ ├── css
│ │ │ └── notfound.css
│ │ ├── notFound.js
│ │ └── unauthorized.js
│ ├── index.js
│ ├── labeller
│ │ ├── CalcBoundsHOC.js
│ │ ├── Canvas.js
│ │ ├── Figure.js
│ │ ├── LabelingApp.js
│ │ ├── LabelingAppHistoryHOC.js
│ │ ├── LoadImageDataHOC.js
│ │ ├── Sidebar.js
│ │ ├── css
│ │ │ └── LabelingApp.css
│ │ ├── index.js
│ │ └── utils.js
│ ├── loading
│ │ └── index.js
│ ├── login
│ │ ├── ForgotPassword.js
│ │ ├── GithubOAuth.js
│ │ ├── GoogleOAuth.js
│ │ ├── ResetPassword.js
│ │ ├── css
│ │ │ ├── ForgotPassword.css
│ │ │ ├── ResetPassword.css
│ │ │ └── login.css
│ │ └── index.js
│ ├── logout
│ │ └── index.js
│ ├── model-editor
│ │ ├── classifierEditor.js
│ │ ├── css
│ │ │ ├── classifierEditor.css
│ │ │ └── modelEditor.css
│ │ ├── index.js
│ │ └── sub-modules
│ │ │ ├── addModelEntityModal.js
│ │ │ ├── css
│ │ │ ├── addModelEntityModal.css
│ │ │ ├── customBuilder.css
│ │ │ ├── exporter.css
│ │ │ ├── labelSelector.css
│ │ │ ├── modelTester.css
│ │ │ ├── preprocessingSelector.css
│ │ │ ├── trainingGraphs.css
│ │ │ ├── transferLearningBuilder.css
│ │ │ └── uploadBuilder.css
│ │ │ ├── customBuilder.js
│ │ │ ├── exporter.js
│ │ │ ├── labelSelector.js
│ │ │ ├── modelParameterEditor.js
│ │ │ ├── modelTester.js
│ │ │ ├── options
│ │ │ ├── layerOptions.js
│ │ │ ├── lossOptions.js
│ │ │ ├── metricOptions.js
│ │ │ ├── optimizerOptions.js
│ │ │ ├── preprocessingStepOptions.js
│ │ │ └── transferLearningOptions.js
│ │ │ ├── preprocessingSelector.js
│ │ │ ├── trainingGraphs.js
│ │ │ ├── transferLearningBuilder.js
│ │ │ └── uploadBuilder.js
│ ├── navbar
│ │ ├── css
│ │ │ ├── navbar.css
│ │ │ └── searchbar.css
│ │ ├── index.js
│ │ ├── notification.js
│ │ ├── project.js
│ │ └── searchbar.js
│ ├── profile
│ │ ├── css
│ │ │ ├── profile-card.css
│ │ │ └── profile.css
│ │ ├── index.js
│ │ └── profile-card.js
│ ├── project
│ │ ├── analytics.js
│ │ ├── chatroom.js
│ │ ├── css
│ │ │ ├── analytics.css
│ │ │ ├── chatroom.css
│ │ │ ├── images.css
│ │ │ ├── index.css
│ │ │ ├── issues.css
│ │ │ ├── labelItem.css
│ │ │ ├── models.css
│ │ │ ├── projectDesc.css
│ │ │ ├── searchUser.css
│ │ │ ├── sidebar.css
│ │ │ └── team.css
│ │ ├── images.js
│ │ ├── index.js
│ │ ├── issue
│ │ │ ├── issueActions.js
│ │ │ ├── issueDetails.js
│ │ │ └── issues.js
│ │ ├── label
│ │ │ ├── index.js
│ │ │ └── labelItem.js
│ │ ├── models.js
│ │ ├── path-tracking.js
│ │ ├── projectActivity.js
│ │ ├── projectDesc.js
│ │ ├── searchUser.js
│ │ ├── sidebar.js
│ │ ├── team.js
│ │ └── teamDetails.js
│ ├── redirect.js
│ └── register
│ │ ├── css
│ │ └── register.css
│ │ └── index.js
│ ├── constants
│ ├── analytics.js
│ ├── auth.js
│ ├── image.js
│ ├── index.js
│ ├── issue.js
│ ├── label.js
│ ├── model.js
│ ├── notification.js
│ ├── options.js
│ ├── project
│ │ ├── fetchDetails.js
│ │ ├── index.js
│ │ ├── logs.js
│ │ ├── member.js
│ │ ├── pathTracking.js
│ │ ├── projectDetails.js
│ │ ├── search.js
│ │ └── teams.js
│ ├── register.js
│ ├── test.js
│ └── user.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reducers
│ ├── analytics.js
│ ├── auth.js
│ ├── image.js
│ ├── index.js
│ ├── issue.js
│ ├── label.js
│ ├── logs.js
│ ├── model.js
│ ├── notification.js
│ ├── project.js
│ ├── register.js
│ ├── search.js
│ ├── searchUser.js
│ ├── teams.js
│ └── user.js
│ ├── serviceWorker.js
│ ├── static
│ └── icons
│ │ ├── github-logo.svg
│ │ └── search.svg
│ └── utils
│ ├── FetchAPI.js
│ ├── TestUtils.js
│ ├── cardLoader
│ ├── card-loader.css
│ └── index.js
│ ├── helpers.js
│ ├── pR.js
│ ├── store.js
│ ├── token.js
│ ├── validation.js
│ └── webSocket.js
├── labellab-flask
├── .dockerignore
├── .envsample
├── .flake8
├── .gcloudignore
├── Dockerfile
├── __init__.py
├── api
│ ├── __init__.py
│ ├── commands.py
│ ├── config.py
│ ├── controllers
│ │ ├── __init__.py
│ │ ├── analyticscontroller.py
│ │ ├── chatroomcontroller.py
│ │ ├── classificationscontroller.py
│ │ ├── commentcontroller.py
│ │ ├── imagescontroller.py
│ │ ├── issuecontroller.py
│ │ ├── labelscontroller.py
│ │ ├── logscontroller.py
│ │ ├── mlclassifierscontroller.py
│ │ ├── notificationscontroller.py
│ │ ├── projectscontroller.py
│ │ ├── teamscontroller.py
│ │ └── userscontroller.py
│ ├── extensions.py
│ ├── helpers
│ │ ├── __init__.py
│ │ ├── analytics.py
│ │ ├── chatroom.py
│ │ ├── classification.py
│ │ ├── comment.py
│ │ ├── email
│ │ │ ├── email_template.py
│ │ │ └── send_email.py
│ │ ├── image.py
│ │ ├── issue.py
│ │ ├── label.py
│ │ ├── labeldata.py
│ │ ├── log.py
│ │ ├── mlclassifier.py
│ │ ├── notification.py
│ │ ├── point.py
│ │ ├── project.py
│ │ ├── projectmember.py
│ │ ├── team.py
│ │ └── user.py
│ ├── main.py
│ ├── middleware
│ │ ├── comment_decorator.py
│ │ ├── image_access.py
│ │ ├── image_labelling_access.py
│ │ ├── issue_decorator.py
│ │ ├── label_access.py
│ │ ├── logs_decorator.py
│ │ ├── model_access.py
│ │ ├── project_admin_access.py
│ │ ├── project_member_access.py
│ │ └── project_owner_access.py
│ ├── models
│ │ ├── Classification.py
│ │ ├── Comment.py
│ │ ├── Image.py
│ │ ├── Issue.py
│ │ ├── Label.py
│ │ ├── LabelData.py
│ │ ├── Log.py
│ │ ├── MLClassifier.py
│ │ ├── Message.py
│ │ ├── Notification.py
│ │ ├── Point.py
│ │ ├── ProjectMembers.py
│ │ ├── Projects.py
│ │ ├── RevokedToken.py
│ │ ├── Team.py
│ │ ├── User.py
│ │ └── __init__.py
│ ├── routes
│ │ ├── __init__.py
│ │ ├── analytics.py
│ │ ├── chatroom.py
│ │ ├── classifications.py
│ │ ├── comments.py
│ │ ├── images.py
│ │ ├── issue.py
│ │ ├── labels.py
│ │ ├── logs.py
│ │ ├── ml_files.py
│ │ ├── mlclassifiers.py
│ │ ├── notifications.py
│ │ ├── projects.py
│ │ ├── static.py
│ │ ├── teams.py
│ │ └── users.py
│ └── serializers
│ │ ├── __init__.py
│ │ ├── classification.py
│ │ ├── comment.py
│ │ ├── image.py
│ │ ├── issue.py
│ │ ├── label.py
│ │ ├── labeldata.py
│ │ ├── mlclassifier.py
│ │ ├── notification.py
│ │ ├── point.py
│ │ ├── project.py
│ │ ├── projectmember.py
│ │ ├── team.py
│ │ └── user.py
├── app.py
├── app.yaml
├── boot.sh
├── docker.txt
├── docs
│ ├── Makefile
│ ├── labellab-flask.api.controllers.rst
│ ├── labellab-flask.api.helpers.rst
│ ├── labellab-flask.api.models.rst
│ ├── labellab-flask.api.routes.rst
│ ├── labellab-flask.api.rst
│ ├── labellab-flask.api.serializers.rst
│ ├── labellab-flask.rst
│ ├── labellab-flask.tests.rst
│ ├── make.bat
│ ├── modules.rst
│ └── source
│ │ ├── conf.py
│ │ └── index.rst
├── migrations
│ ├── README
│ ├── alembic.ini
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ │ └── f5462c8a9bc2_.py
├── ml
│ ├── classifier.py
│ ├── layer.py
│ ├── preprocessing.py
│ └── trainingplot.py
├── path_tracking
│ ├── __init__.py
│ ├── extract_exif.py
│ └── sample6.png
├── pre-commit-config.yaml
├── prod.txt
├── requirements.txt
├── tests
│ ├── __init__.py
│ ├── test_comment.py
│ ├── test_issue.py
│ ├── test_label.py
│ ├── test_login.py
│ ├── test_project_and_team.py
│ └── test_register.py
├── travis.txt
└── uploads
│ └── .gitignore
├── labellab-server
├── .dockerignore
├── .env.example
├── .eslintrc.json
├── .gitignore
├── Dockerfile
├── app.js
├── bin
│ └── www
├── config
│ ├── dbURI.js
│ ├── githubPassport.js
│ ├── googlePassport.js
│ ├── jwtSecret.js
│ ├── passport.js
│ └── test.js
├── controller
│ ├── analytics
│ │ └── analyticsControls.js
│ ├── auth
│ │ ├── auth.js
│ │ └── oauth.js
│ ├── classification
│ │ └── classificationControls.js
│ ├── image
│ │ └── imageControls.js
│ ├── label
│ │ └── labelControls.js
│ ├── project
│ │ └── projectControls.js
│ └── user
│ │ └── userControls.js
├── models
│ ├── classification.js
│ ├── image.js
│ ├── label.js
│ ├── project.js
│ ├── projectMembers.js
│ └── user.js
├── package-lock.json
├── package.json
├── public
│ ├── classifications
│ │ └── .gitignore
│ ├── img
│ │ └── .gitignore
│ ├── project
│ │ └── .gitignore
│ ├── stylesheets
│ │ └── style.css
│ └── uploads
│ │ └── .gitignore
├── routes
│ ├── analytics
│ │ └── routes.js
│ ├── auth
│ │ └── routes.js
│ ├── classification
│ │ └── routes.js
│ ├── image
│ │ └── routes.js
│ ├── label
│ │ └── routes.js
│ ├── project
│ │ └── routes.js
│ ├── routes.js
│ └── users
│ │ └── routes.js
├── test
│ ├── analytics.js
│ ├── auth.js
│ ├── classification.js
│ ├── info.js
│ ├── label.js
│ ├── project.js
│ └── user.js
├── utils
│ ├── authValidations.js
│ ├── color.js
│ ├── error.js
│ ├── labelData.js
│ ├── months.js
│ └── randomString.js
└── views
│ ├── authenticated.ejs
│ └── error.ejs
├── labellab_mobile
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .project
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── app
│ │ ├── .classpath
│ │ ├── .project
│ │ ├── .settings
│ │ │ └── org.eclipse.buildship.core.prefs
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin
│ │ │ │ └── org
│ │ │ │ │ └── scorelab
│ │ │ │ │ └── labellab_mobile
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── res
│ │ │ │ ├── drawable
│ │ │ │ ├── launch_background.xml
│ │ │ │ └── splash.png
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ │ └── values
│ │ │ │ └── styles.xml
│ │ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── assets
│ └── images
│ │ └── splash.png
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── Runner
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ └── Icon-App-83.5x83.5@2x.png
│ │ └── LaunchImage.imageset
│ │ │ ├── Contents.json
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ └── README.md
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
├── lib
│ ├── data
│ │ ├── interceptor
│ │ │ ├── backend_url_interceptor.dart
│ │ │ └── token_interceptor.dart
│ │ ├── local
│ │ │ ├── classifcation_provider.dart
│ │ │ ├── entities
│ │ │ │ ├── classification_entity.dart
│ │ │ │ ├── issue_entity.dart
│ │ │ │ └── project_entity.dart
│ │ │ ├── issue_provider.dart
│ │ │ ├── project_provider.dart
│ │ │ └── user_provider.dart
│ │ ├── remote
│ │ │ ├── dto
│ │ │ │ ├── api_response.dart
│ │ │ │ ├── google_user_request.dart
│ │ │ │ ├── login_response.dart
│ │ │ │ ├── refresh_response.dart
│ │ │ │ ├── register_response.dart
│ │ │ │ └── time_value.dart
│ │ │ ├── fake_server
│ │ │ │ └── fake_server.dart
│ │ │ ├── labellab_api.dart
│ │ │ └── labellab_api_impl.dart
│ │ └── repository.dart
│ ├── labellab_app.dart
│ ├── main.dart
│ ├── model
│ │ ├── auth_user.dart
│ │ ├── classification.dart
│ │ ├── classification_label.dart
│ │ ├── comment.dart
│ │ ├── group.dart
│ │ ├── image.dart
│ │ ├── issue.dart
│ │ ├── label.dart
│ │ ├── label_selection.dart
│ │ ├── location.dart
│ │ ├── log.dart
│ │ ├── mapper
│ │ │ ├── issue_mapper.dart
│ │ │ └── ml_model_mapper.dart
│ │ ├── member.dart
│ │ ├── message.dart
│ │ ├── ml_model.dart
│ │ ├── project.dart
│ │ ├── register_user.dart
│ │ ├── team.dart
│ │ ├── team_member.dart
│ │ ├── upload_image.dart
│ │ └── user.dart
│ ├── routing
│ │ ├── application.dart
│ │ ├── route_handler.dart
│ │ └── routes.dart
│ ├── screen
│ │ ├── backend_selection
│ │ │ ├── backend_selection_screen.dart
│ │ │ ├── backend_service_selector.dart
│ │ │ └── init_screen.dart
│ │ ├── classification
│ │ │ ├── classification_bloc.dart
│ │ │ ├── classification_screen.dart
│ │ │ └── classification_state.dart
│ │ ├── classify
│ │ │ ├── classify_bloc.dart
│ │ │ ├── classify_screen.dart
│ │ │ └── classify_state.dart
│ │ ├── history
│ │ │ ├── history_bloc.dart
│ │ │ ├── history_item.dart
│ │ │ ├── history_screen.dart
│ │ │ ├── history_search_screen.dart
│ │ │ └── history_state.dart
│ │ ├── home
│ │ │ ├── camera_button.dart
│ │ │ ├── home_screen.dart
│ │ │ ├── nav_item.dart
│ │ │ └── user_detail_loading.dart
│ │ ├── issue
│ │ │ ├── add_edit
│ │ │ │ └── add_edit_issue_screen.dart
│ │ │ ├── details
│ │ │ │ ├── issue_details_bloc.dart
│ │ │ │ ├── issue_details_screen.dart
│ │ │ │ ├── issue_details_state.dart
│ │ │ │ └── local_widget.dart
│ │ │ │ │ └── expnasion_tile.dart
│ │ │ └── issue_activity
│ │ │ │ ├── issue_activity_bloc.dart
│ │ │ │ ├── issue_activity_screen.dart
│ │ │ │ ├── issue_activity_state.dart
│ │ │ │ └── local_widgets
│ │ │ │ └── filter_issue_sheet.dart
│ │ ├── login
│ │ │ ├── github_signin_screen.dart
│ │ │ └── login_screen.dart
│ │ ├── main_screen.dart
│ │ ├── profile
│ │ │ ├── edit_info
│ │ │ │ └── edit_info_screen.dart
│ │ │ ├── profile_bloc.dart
│ │ │ ├── profile_screen.dart
│ │ │ ├── profile_state.dart
│ │ │ └── update_password
│ │ │ │ └── update_password_screen.dart
│ │ ├── project
│ │ │ ├── add_edit
│ │ │ │ └── add_edit_project_screen.dart
│ │ │ ├── add_edit_group
│ │ │ │ └── add_edit_group.dart
│ │ │ ├── add_edit_label
│ │ │ │ └── add_edit_label_dialog.dart
│ │ │ ├── add_edit_model
│ │ │ │ └── add_edit_model_dialog.dart
│ │ │ ├── add_member
│ │ │ │ ├── project_add_member_bloc.dart
│ │ │ │ ├── project_add_member_screen.dart
│ │ │ │ └── project_add_member_state.dart
│ │ │ ├── add_team_dialog
│ │ │ │ └── add_team_dialog.dart
│ │ │ ├── chat
│ │ │ │ ├── chat_screen.dart
│ │ │ │ ├── chat_screen_bloc.dart
│ │ │ │ ├── chat_screen_state.dart
│ │ │ │ └── local_widgets
│ │ │ │ │ ├── message_bubble.dart
│ │ │ │ │ ├── message_input.dart
│ │ │ │ │ └── messages_list.dart
│ │ │ ├── common
│ │ │ │ ├── label_selection_list.dart
│ │ │ │ └── label_selection_painter.dart
│ │ │ ├── detail
│ │ │ │ ├── project_detail_bloc.dart
│ │ │ │ ├── project_detail_screen.dart
│ │ │ │ └── project_detail_state.dart
│ │ │ ├── label_tool
│ │ │ │ ├── label_tool_bloc.dart
│ │ │ │ ├── label_tool_screen.dart
│ │ │ │ └── label_tool_state.dart
│ │ │ ├── ml_model
│ │ │ │ └── history
│ │ │ │ │ ├── model_history_bloc.dart
│ │ │ │ │ ├── model_history_screen.dart
│ │ │ │ │ └── model_history_state.dart
│ │ │ ├── project_activity
│ │ │ │ ├── local_widgets
│ │ │ │ │ ├── filter_bottom_sheet.dart
│ │ │ │ │ └── filter_dropdown.dart
│ │ │ │ ├── project_activity_bloc.dart
│ │ │ │ ├── project_activity_screen.dart
│ │ │ │ └── project_activity_state.dart
│ │ │ ├── project_bloc.dart
│ │ │ ├── project_item.dart
│ │ │ ├── project_screen.dart
│ │ │ ├── project_search_screen.dart
│ │ │ ├── project_state.dart
│ │ │ ├── team_details
│ │ │ │ ├── local_widgets
│ │ │ │ │ └── add_team_member_dialog.dart
│ │ │ │ ├── team_details_bloc.dart
│ │ │ │ ├── team_details_screen.dart
│ │ │ │ └── team_details_state.dart
│ │ │ ├── upload_image
│ │ │ │ ├── project_upload_image_bloc.dart
│ │ │ │ ├── project_upload_image_screen.dart
│ │ │ │ └── project_upload_image_state.dart
│ │ │ ├── view_group
│ │ │ │ ├── add_images
│ │ │ │ │ ├── group_add_images_bloc.dart
│ │ │ │ │ ├── group_add_images_screen.dart
│ │ │ │ │ └── group_add_images_state.dart
│ │ │ │ ├── project_view_group_bloc.dart
│ │ │ │ ├── project_view_group_screen.dart
│ │ │ │ └── project_view_group_state.dart
│ │ │ ├── view_image
│ │ │ │ ├── project_view_image_bloc.dart
│ │ │ │ ├── project_view_image_screen.dart
│ │ │ │ └── project_view_image_state.dart
│ │ │ ├── view_image_path
│ │ │ │ ├── project_image_path_bloc.dart
│ │ │ │ ├── project_image_path_screen.dart
│ │ │ │ └── project_image_path_state.dart
│ │ │ └── view_more_images
│ │ │ │ ├── project_more_images_bloc.dart
│ │ │ │ ├── project_more_images_screen.dart
│ │ │ │ └── project_more_images_state.dart
│ │ ├── sign_up
│ │ │ └── sign_up_screen.dart
│ │ └── train
│ │ │ ├── dialogs
│ │ │ ├── add_class_dialog.dart
│ │ │ ├── add_layer_dialog.dart
│ │ │ ├── add_step_dialog.dart
│ │ │ └── dto
│ │ │ │ ├── layer_dto.dart
│ │ │ │ ├── model_dto.dart
│ │ │ │ └── step_dto.dart
│ │ │ ├── model_train_bloc.dart
│ │ │ ├── model_train_screen.dart
│ │ │ └── model_train_state.dart
│ ├── state
│ │ └── auth_state.dart
│ ├── util
│ │ └── util.dart
│ └── widgets
│ │ ├── color_box.dart
│ │ ├── custom_dropdown.dart
│ │ ├── delete_confirm_dialog.dart
│ │ ├── empty_placeholder.dart
│ │ ├── group_item.dart
│ │ ├── issue_list_tile.dart
│ │ ├── label_icon_button.dart
│ │ ├── label_text_field.dart
│ │ ├── label_text_form_field.dart
│ │ ├── leave_project_confirm_dialog.dart
│ │ ├── line_chart.dart
│ │ ├── recent_activity_list_tile.dart
│ │ ├── selected_image.dart
│ │ └── team_item.dart
├── pubspec.yaml
├── screenshots
│ ├── add_image
│ │ ├── ss_1.png
│ │ ├── ss_2.png
│ │ └── ss_3.png
│ ├── classification
│ │ ├── ss_1.png
│ │ └── ss_2.png
│ ├── create_label
│ │ ├── ss_1.png
│ │ └── ss_2.png
│ ├── create_project
│ │ ├── ss_1.png
│ │ ├── ss_2.png
│ │ └── ss_3.png
│ ├── edit_image
│ │ ├── ss_1.png
│ │ ├── ss_2.png
│ │ └── ss_3.png
│ ├── image_path
│ │ ├── ss_1.png
│ │ └── ss_2.png
│ ├── initial
│ │ ├── ss_1.png
│ │ └── ss_2.png
│ ├── label_image
│ │ ├── ss_1.png
│ │ ├── ss_2.png
│ │ ├── ss_3.png
│ │ └── ss_4.png
│ └── sign_in
│ │ ├── ss_1.png
│ │ └── ss_2.png
└── test
│ ├── classifications_test.dart
│ ├── comment_test.dart
│ ├── images_test.dart
│ ├── issue_screen_test
│ └── create_issue_test.dart
│ ├── issue_test.dart
│ ├── labels_test.dart
│ ├── login_screen_test.dart
│ ├── logs_test.dart
│ ├── mock_labellab_api.dart
│ ├── mock_labellab_api_impl.dart
│ ├── profile_test.dart
│ ├── project_test.dart
│ ├── sign_up_screen_test.dart
│ ├── teams_test.dart
│ ├── train_test.dart
│ └── wrapper
│ └── material_wrapper.dart
├── package.json
├── pyproject.toml
├── reference
├── Design.png
├── Labellab-ER.mwb
├── Labellab-sql-script.sql
├── images
│ ├── back-skip.png
│ ├── bounding-box.png
│ ├── edit-elephant-1.png
│ ├── labeller.png
│ ├── labels.png
│ ├── polygon.png
│ ├── shortcut.png
│ ├── sidebar.png
│ └── watch.png
└── labellab.v2.yaml
└── static.json
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/Flutter-CI.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | paths:
4 | - 'labellab_mobile/**'
5 | name: Test, Build and Release apk
6 |
7 | jobs:
8 | build:
9 | name: Build APK
10 | runs-on: ubuntu-latest
11 |
12 | defaults:
13 | run:
14 | working-directory: ./labellab_mobile
15 |
16 | steps:
17 | - uses: actions/checkout@v1
18 | - uses: actions/setup-java@v1
19 | with:
20 | java-version: '12.x'
21 | - uses: subosito/flutter-action@v1
22 | with:
23 | flutter-version: '3.0.1'
24 |
25 | - run: flutter clean
26 | - run: flutter pub get
27 |
28 | # - run: flutter format --set-exit-if-changed .
29 |
30 |
31 | # Test case are failing flutter SDk
32 | # - run: flutter test
33 |
34 | # Build APk (Some issue here)
35 | # - run: flutter build apk
36 | # - run: flutter build apk --debug --split-per-abi
37 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "prettier.jsxSingleQuote": true,
3 | "prettier.semi": false,
4 | "prettier.singleQuote": true
5 | }
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3"
2 |
3 | services:
4 |
5 | flask_server:
6 | build: ./labellab-flask
7 | working_dir: /usr/labellab/labellab-flask
8 | ports:
9 | - 5000:5000
10 | volumes:
11 | - ./labellab-flask:/usr/labellab/labellab-flask
12 | restart: always
13 | links:
14 | - mysql:dbserver
15 | environment:
16 | FLASK_ENV: development
17 |
18 | mysql:
19 | image: "mysql/mysql-server:5.7"
20 | restart: always
21 |
22 | client:
23 | build: ./labellab-client
24 | working_dir: /usr/labellab/labellab-client
25 | ports:
26 | - 3000:3000
27 | volumes:
28 | - ./labellab-client/:/usr/labellab/labellab-client
29 | environment:
30 | - NODE_ENV=development
31 |
--------------------------------------------------------------------------------
/labellab-client/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | Dockerfile*
4 | docker-compose*
5 | .dockerignore
6 | .git
7 | .gitignore
8 | .env
9 | */bin
10 | */obj
11 | README.md
12 | LICENSE
13 | .vscode
--------------------------------------------------------------------------------
/labellab-client/.env.example:
--------------------------------------------------------------------------------
1 | REACT_APP_HOST=
2 | REACT_APP_SERVER_ENVIRONMENT=
3 | REACT_APP_SERVER_PORT=
4 | REACT_APP_GOOGLE_CLIENT_ID=
5 | REACT_APP_GOOGLE_MAPS_API_KEY=
6 |
--------------------------------------------------------------------------------
/labellab-client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true
6 | },
7 | extends: [
8 | 'eslint:recommended',
9 | 'plugin:react/recommended',
10 | 'react-app',
11 | 'plugin:prettier/recommended',
12 | 'prettier/react'
13 | ],
14 | parser: 'babel-eslint',
15 | parserOptions: {
16 | ecmaVersion: 2018,
17 | sourceType: 'module'
18 | },
19 | rules: {
20 | 'no-unused-vars': [
21 | 'off',
22 | { vars: 'all', args: 'after-used', ignoreRestSiblings: false }
23 | ],
24 | 'no-console': 'off',
25 | 'prettier/prettier': ['warn', { semi: false, singleQuote: true }],
26 | "react/prop-types": 0
27 | },
28 | settings: {
29 | react: {
30 | createClass: 'createReactClass',
31 | pragma: 'React',
32 | version: 'detect',
33 | flowVersion: '0.53'
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/labellab-client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/labellab-client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8
2 |
3 | RUN mkdir -p /usr/labellab/labellab-client
4 | WORKDIR /usr/labellab/labellab-client
5 |
6 | ENV PATH /usr/app/node_modules/.bin:$PATH
7 |
8 |
9 | COPY package.json /usr/labellab/labellab-client
10 | RUN npm install --silent
11 |
12 | EXPOSE 3000
13 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/labellab-client/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/labellab-client/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/labellab-client/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: false,
3 | singleQuote: true
4 | }
5 |
--------------------------------------------------------------------------------
/labellab-client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-client/public/favicon.ico
--------------------------------------------------------------------------------
/labellab-client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/labellab-client/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 40vmin;
8 | pointer-events: none;
9 | }
10 |
11 | .App-header {
12 | background-color: #282c34;
13 | min-height: 100vh;
14 | display: flex;
15 | flex-direction: column;
16 | align-items: center;
17 | justify-content: center;
18 | font-size: calc(10px + 2vmin);
19 | color: white;
20 | }
21 |
22 | .App-link {
23 | color: #61dafb;
24 | }
25 |
26 | @keyframes App-logo-spin {
27 | from {
28 | transform: rotate(0deg);
29 | }
30 | to {
31 | transform: rotate(360deg);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/labellab-client/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import AppIndex from './components/index'
3 | import './App.css'
4 |
5 | export default class App extends Component {
6 | render() {
7 | return
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/labellab-client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import App from './App'
4 |
5 | it('renders without crashing', () => {
6 | setTimeout(() => {
7 | const div = document.createElement('div')
8 | ReactDOM.render(, div)
9 | ReactDOM.unmountComponentAtNode(div)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/labellab-client/src/__tests__/reducers/registerReducer.test.js:
--------------------------------------------------------------------------------
1 | import {
2 | REGISTER_FAILURE,
3 | REGISTER_REQUEST,
4 | REGISTER_SUCCESS
5 | } from "../../constants/index";
6 | import register from "../../reducers/register";
7 |
8 | const initState = {
9 | isRegistering: false,
10 | error: false,
11 | errField: '',
12 | statusText: ''
13 | }
14 |
15 | describe("Register Reducer", () => {
16 | it("Should return the default state", () => {
17 | const newState = register(undefined, {});
18 | expect(newState).toEqual(initState);
19 | });
20 | it("Should send a register request", () => {
21 | const newState = register(initState, {
22 | type: REGISTER_REQUEST
23 | });
24 | expect(newState).toEqual({
25 | ...initState,
26 | isRegistering: true,
27 | error: false
28 | });
29 | });
30 | it("Should register a user", () => {
31 | const mockPayload = { statusText: "OK" }
32 | const newState = register(initState, {
33 | type: REGISTER_SUCCESS,
34 | payload: mockPayload
35 | });
36 | expect(newState).toEqual({
37 | ...initState,
38 | isRegistering: false,
39 | statusText: mockPayload,
40 | error: false
41 | });
42 | });
43 | });
--------------------------------------------------------------------------------
/labellab-client/src/actions/index.js:
--------------------------------------------------------------------------------
1 | export * from './auth'
2 | export * from './register'
3 | export * from './user'
4 | export * from './project/index'
5 | export * from './label'
6 | export * from './image'
7 | export * from './issue'
8 | export * from './analytics'
9 | export * from './model'
10 | export * from './notification'
11 |
--------------------------------------------------------------------------------
/labellab-client/src/actions/project/pathTracking.js:
--------------------------------------------------------------------------------
1 | import {
2 | FETCH_COORDINATES_FAILURE,
3 | FETCH_COORDINATES_REQUEST,
4 | FETCH_COORDINATES_SUCCESS
5 | } from '../../constants/index'
6 |
7 | import FetchApi from '../../utils/FetchAPI'
8 |
9 | export const fetchCoordinates = (projectId) => {
10 | return dispatch => {
11 | dispatch(request())
12 | FetchApi.get('/api/v1/project/polylines/' + projectId)
13 | .then(res => {
14 | dispatch(success(res.data.body))
15 | })
16 | .catch(err => {
17 | if (err.response) {
18 | err.response.data
19 | ? dispatch(failure(err.response.data.msg))
20 | : dispatch(failure(err.response.statusText, null))
21 | }
22 | })
23 | }
24 | function request() {
25 | return { type: FETCH_COORDINATES_REQUEST }
26 | }
27 | function success(data) {
28 | return { type: FETCH_COORDINATES_SUCCESS, payload: data }
29 | }
30 | function failure(error) {
31 | return { type: FETCH_COORDINATES_FAILURE, payload: error }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/labellab-client/src/actions/project/search.js:
--------------------------------------------------------------------------------
1 | import { SEARCH_PROJECTS, SEARCH_PROJECTS_FAILURE } from '../../constants/index'
2 |
3 | import FetchApi from '../../utils/FetchAPI'
4 |
5 | export const getSearchProjects = query => {
6 | return dispatch => {
7 | if (!query) {
8 | query = 'null'
9 | }
10 | FetchApi('GET', '/api/v1/project/search/' + query, null, true)
11 | .then(response => {
12 | dispatch(success(response.data.body))
13 | })
14 | .catch(err => {
15 | if (err.response) {
16 | err.response.data
17 | ? dispatch(
18 | failure(err.response.data.msg, err.response.data.err_field)
19 | )
20 | : dispatch(failure(err.response.statusText, null))
21 | }
22 | })
23 | }
24 | function success(data) {
25 | return { type: SEARCH_PROJECTS, payload: data }
26 | }
27 | function failure(error) {
28 | return { type: SEARCH_PROJECTS_FAILURE, payload: error }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/labellab-client/src/actions/register.js:
--------------------------------------------------------------------------------
1 | import {
2 | REGISTER_REQUEST,
3 | REGISTER_SUCCESS,
4 | REGISTER_FAILURE
5 | } from '../constants/index'
6 |
7 | import FetchApi from '../utils/FetchAPI'
8 |
9 | export const userRegister = (data, callback) => {
10 | return dispatch => {
11 | dispatch(request())
12 | FetchApi.post('/api/v1/auth/register', data)
13 | .then(() => {
14 | dispatch(success())
15 | callback()
16 | })
17 | .catch(err => {
18 | if (err.response) {
19 | err.response.data
20 | ? dispatch(
21 | failure(err.response.data.msg, err.response.data.err_field)
22 | )
23 | : dispatch(failure(err.response.statusText, null))
24 | }
25 | })
26 | }
27 | function request() {
28 | return { type: REGISTER_REQUEST }
29 | }
30 | function success() {
31 | return { type: REGISTER_SUCCESS, payload: 'Please log in to continue.' }
32 | }
33 | function failure(error, other) {
34 | return { type: REGISTER_FAILURE, payload: error, other: other }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/labellab-client/src/components/dashboard/css/dashboard.css:
--------------------------------------------------------------------------------
1 | .dashboard-parent {
2 | height: 100% !important;
3 | width: 100%;
4 | background: #e5e5e5;
5 | min-height: 100vh !important;
6 | }
7 |
8 | .dashboard-container {
9 | width: 80%;
10 | margin: auto;
11 | }
12 |
13 | .create-project-button {
14 | padding: 2em 0;
15 | }
16 |
17 | .modal-actions {
18 | display: flex;
19 | flex-direction: column;
20 | align-items: center;
21 | }
22 |
23 | .modal-actions > div {
24 | padding-top: 1.5em;
25 | }
26 |
27 | .modal-actions:last-child {
28 | display: block;
29 | text-align: center;
30 | padding-bottom: 1.5em;
31 | }
32 |
33 | /* Added padding for the mobile view between the title and the card */
34 | @media only screen and (max-width: 768px) {
35 | .mobile-padding {
36 | padding-bottom: 10px !important;
37 | }
38 |
39 | .create-button {
40 | width: 100%;
41 | color: white !important;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/labellab-client/src/components/dashboard/css/previous.css:
--------------------------------------------------------------------------------
1 | .previous-card-image {
2 | width: 100% !important;
3 | }
4 |
5 | .card-headers .header {
6 | width: 100%;
7 | overflow-wrap: break-word;
8 | }
9 |
--------------------------------------------------------------------------------
/labellab-client/src/components/error/css/notfound.css:
--------------------------------------------------------------------------------
1 | .main {
2 | height: 50vh;
3 | display: flex;
4 | justify-content: center;
5 | align-items: center;
6 | }
7 | .heading {
8 | display: flex;
9 | flex-direction: row;
10 | justify-content: center;
11 | font-size: 5em;
12 |
13 | }
14 | .green {
15 | color: green
16 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/error/notFound.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Link } from 'react-router-dom'
3 | import { Header, Button } from 'semantic-ui-react'
4 | import './css/notfound.css'
5 | class NotFound extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
4
13 |
0
14 |
4
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default NotFound
34 |
--------------------------------------------------------------------------------
/labellab-client/src/components/error/unauthorized.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Link } from 'react-router-dom'
3 | import { Header, Button } from 'semantic-ui-react'
4 | import './css/notfound.css'
5 | class Unauthorized extends Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 |
4
13 |
0
14 |
1
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default Unauthorized
34 |
--------------------------------------------------------------------------------
/labellab-client/src/components/labeller/CalcBoundsHOC.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent, forwardRef } from 'react'
2 | import { CRS, LatLngBounds } from 'leaflet'
3 |
4 | export const maxZoom = 7
5 | export function withBounds(Comp) {
6 | class CalcBoundsLayer extends PureComponent {
7 | calcBounds() {
8 | const crs = CRS.Simple
9 | const { height, width } = this.props
10 |
11 | if (!height || !width) return null
12 |
13 | const southWest = crs.unproject({ x: 0, y: height }, maxZoom - 1)
14 | const northEast = crs.unproject({ x: width, y: 0 }, maxZoom - 1)
15 | const bounds = new LatLngBounds(southWest, northEast)
16 |
17 | return bounds
18 | }
19 |
20 | render() {
21 | const { forwardedRef, ...rest } = this.props
22 | const bounds = this.calcBounds()
23 | if (!bounds) return null
24 | return
25 | }
26 | }
27 |
28 | function exp(props, ref) {
29 | return
30 | }
31 | return forwardRef(exp)
32 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/labeller/css/LabelingApp.css:
--------------------------------------------------------------------------------
1 | .leaflet-container {
2 | height: 100%;
3 | width: 100%;
4 | }
5 |
6 | html,
7 | body,
8 | #root > *,
9 | .ui.grid {
10 | height: 100%;
11 | min-height: 100%;
12 | }
13 |
14 | .leaflet-container {
15 | cursor: inherit !important;
16 | }
17 |
18 | .item.disabled {
19 | opacity: 0.5;
20 | }
21 |
22 | .vertex.editing.finished {
23 | cursor: move !important;
24 | }
25 |
26 | .midpoint {
27 | cursor: copy !important;
28 | }
29 |
30 | .vertex:not(.finished).first {
31 | cursor: cell !important;
32 | }
33 |
--------------------------------------------------------------------------------
/labellab-client/src/components/loading/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { connect } from 'react-redux'
3 |
4 | class Loading extends Component {
5 | render() {
6 | return Loading........
7 | }
8 | }
9 |
10 | export default connect(
11 | null,
12 | null
13 | )(Loading)
14 |
--------------------------------------------------------------------------------
/labellab-client/src/components/login/css/ForgotPassword.css:
--------------------------------------------------------------------------------
1 | .emailForm {
2 | display: flex;
3 | justify-content: center;
4 | }
5 |
6 | .mainBody {
7 | text-align: center;
8 | margin-top: 9rem;
9 | }
10 |
11 | .sendMail {
12 | margin-left: 20px;
13 | }
14 |
15 | .btn-home {
16 | margin: 20px auto !important;
17 | }
18 |
19 | @media only screen and (max-width: 767px) {
20 | .emailForm {
21 | flex-direction: column;
22 | margin-left: 40px;
23 | margin-right: 40px;
24 | }
25 |
26 | .sendMail {
27 | margin-left: 0;
28 | margin-top: 20px;
29 | }
30 | }
31 |
32 | .error-msg {
33 | text-align: left;
34 | margin: 2px 0px;
35 | color: #9f3a38;
36 | font-weight: 500;
37 | }
38 |
--------------------------------------------------------------------------------
/labellab-client/src/components/login/css/ResetPassword.css:
--------------------------------------------------------------------------------
1 | .errorResettingPassword{
2 |
3 | }
4 | .successBody{
5 | text-align: center;
6 | margin-top: 8rem;
7 | }
8 | .failureBody{
9 | text-align: center;
10 | margin-top: 8rem;
11 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/login/css/login.css:
--------------------------------------------------------------------------------
1 | @media only screen and (max-width: 600px) {
2 | .login-parent {
3 | width: 80% !important;
4 | }
5 | }
6 |
7 | .login-grand-parent {
8 | display: flex;
9 | flex-direction: column;
10 | height: 100vh;
11 | }
12 |
13 | .login-parent {
14 | margin-top: 5em;
15 | width: 30%;
16 | margin-left: auto;
17 | margin-right: auto;
18 | }
19 |
20 | .login-oauth-icon {
21 | display: flex;
22 | justify-content: space-evenly;
23 | margin: 2em 0 2em;
24 | }
25 |
26 | .login-oauth-icon div {
27 | max-width: 15vw;
28 | }
29 |
30 | .login-icons {
31 | width: 45px;
32 | }
33 |
34 | .action {
35 | padding: 1em 0;
36 | }
37 |
38 | .login-form {
39 | margin-top: 2em;
40 | }
41 |
42 | .github-login {
43 | width: 11vw;
44 | height: 3rem;
45 | background: black;
46 | opacity: 0.6;
47 | color: white;
48 | box-shadow: 0px 1px 4px black;
49 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/logout/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { connect } from 'react-redux'
3 | import PropTypes from 'prop-types'
4 | import { logout } from '../../actions/index'
5 | class Logout extends Component {
6 | componentDidMount() {
7 | this.props.logout(this.callback)
8 | }
9 | callback = () => {
10 | this.props.history.push('/login')
11 | }
12 | render() {
13 | return <>>
14 | }
15 | }
16 |
17 | Logout.propTypes = {
18 | history: PropTypes.object,
19 | logout: PropTypes.func
20 | }
21 |
22 | const mapActionToProps = dispatch => {
23 | return {
24 | logout: callback => {
25 | return dispatch(logout(callback))
26 | }
27 | }
28 | }
29 |
30 | export default connect(
31 | null,
32 | mapActionToProps
33 | )(Logout)
34 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/css/classifierEditor.css:
--------------------------------------------------------------------------------
1 | .classifier-column-heading {
2 | text-align: center;
3 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/css/modelEditor.css:
--------------------------------------------------------------------------------
1 | .model-editor {
2 | display: flex;
3 | flex-direction: column;
4 | margin: auto;
5 | padding-top: 1em;
6 | width: 95%;
7 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/addModelEntityModal.css:
--------------------------------------------------------------------------------
1 | .add-entity-modal {
2 | align-items: center;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | .entity-settings {
8 | display: flex;
9 | flex-direction: row;
10 | justify-content: space-around;
11 | margin: 1em;
12 | flex-wrap: wrap;
13 | }
14 |
15 | .entity-settings-option {
16 | margin: 0.5em;
17 | }
18 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/customBuilder.css:
--------------------------------------------------------------------------------
1 | .custom-card {
2 | text-align: center;
3 | }
4 |
5 | .question-icon {
6 | cursor: pointer;
7 | padding: 1em;
8 | }
9 |
10 | .layer-label-container {
11 | align-items: center;
12 | background-color: #e8e8e8;
13 | border-radius: 5px;
14 | display: flex;
15 | font-weight: 600;
16 | justify-content: space-between;
17 | margin-bottom: 0.4em;
18 | padding: 0.5rem;
19 | width: 100%;
20 | }
21 |
22 | .layer-delete-icon {
23 | align-self: flex-end;
24 | cursor: pointer;
25 | padding-left: 0.2em;
26 | }
27 |
28 | .layer-edit-icon {
29 | cursor: pointer;
30 | padding-left: 0.5em;
31 | }
32 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/exporter.css:
--------------------------------------------------------------------------------
1 | .exporter-card {
2 | text-align: center;
3 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/labelSelector.css:
--------------------------------------------------------------------------------
1 | .add-new-label-btn {
2 | padding-top: 1em;
3 | }
4 |
5 | .label-card {
6 | padding: 1em;
7 | text-align: left;
8 | }
9 |
10 | .label-header-row {
11 | margin-left: 0.5em;
12 | margin-right: 0.5em;
13 | margin-top: 0.3em;
14 | margin-bottom: -1em;
15 | flex-direction: row;
16 | justify-content: space-between;
17 | align-items: center;
18 | }
19 |
20 | .label-name {
21 | color: #393939;
22 | font-size: 1.6em;
23 | display: inline;
24 | }
25 |
26 | .label-type-icon {
27 | padding-left: 0.5em;
28 | }
29 |
30 | .label-delete-icon {
31 | float: right;
32 | }
33 |
34 | .label-count {
35 | align-self: flex-end;
36 | margin: 0.5em;
37 | }
38 |
39 | .label-images {
40 | display: flex;
41 | align-items: center;
42 | justify-content: flex-start;
43 | width: 95%;
44 | margin: auto;
45 | overflow-x: scroll;
46 | }
47 |
48 | .label-images::-webkit-scrollbar {
49 | display: none;
50 | }
51 |
52 | .label-image {
53 | border-radius: 5px;
54 | height: 100px;
55 | margin-left: 1em;
56 | width: auto;
57 | }
58 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/modelTester.css:
--------------------------------------------------------------------------------
1 | .model-tester-card {
2 | text-align: center;
3 | }
4 |
5 | .inputfile {
6 | width: 0.1px;
7 | height: 0.1px;
8 | opacity: 0;
9 | overflow: hidden;
10 | position: absolute;
11 | z-index: -1;
12 | }
13 |
14 | .progress-bar-list {
15 | display: 'flex';
16 | flex-direction: 'column';
17 | width: 100%;
18 | }
19 |
20 | .test-card-top {
21 | padding-left: 0.6em;
22 | padding-right: 0.6em;
23 | display: flex;
24 | align-items: center;
25 | justify-content: space-between;
26 | }
27 |
28 | .preview-image {
29 | max-height: 8em;
30 | max-width: 10em;
31 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/preprocessingSelector.css:
--------------------------------------------------------------------------------
1 | .preprocessing-card {
2 | text-align: left;
3 | }
4 |
5 | .preprocessing-card-header-row {
6 | display: flex;
7 | flex-direction: row;
8 | justify-content: center;
9 | align-items: center;
10 | margin-bottom: -1em;
11 | }
12 |
13 | .preprocessing-card-header {
14 | width: 100%;
15 | text-align: center;
16 | }
17 |
18 | .preprocessing-card-add-btn {
19 | margin-top: -1em;
20 | margin-left: auto;
21 | }
22 |
23 | .preprocessing-card-bottom-row {
24 | margin-top: -1em;
25 | }
26 |
27 | .preprocessing-step-label {
28 | display: inline-block;
29 | margin-top: 0.4em;
30 | margin-right: 0.4em;
31 | }
32 |
33 | .step-delete-icon {
34 | cursor: pointer;
35 | padding-left: 0.2em;
36 | }
37 |
38 | .step-edit-icon {
39 | cursor: pointer;
40 | padding-left: 0.5em;
41 | }
42 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/trainingGraphs.css:
--------------------------------------------------------------------------------
1 | .training-graphs-card {
2 | text-align: center;
3 | }
4 |
5 | .training-graphs {
6 | display: flex;
7 | align-items: center;
8 | justify-content: space-evenly;
9 | overflow-x: scroll;
10 | }
11 |
12 | .training-graphs::-webkit-scrollbar {
13 | display: none;
14 | }
15 |
16 | .training-graph {
17 | height: 10em;
18 | width: auto;
19 | }
20 |
21 | .training-results {
22 | display: flex;
23 | align-items: center;
24 | justify-content: space-evenly;
25 | }
26 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/transferLearningBuilder.css:
--------------------------------------------------------------------------------
1 | .transfer-learning-card {
2 | text-align: center;
3 | }
4 |
5 | .question-icon {
6 | cursor: pointer;
7 | padding: 1em;
8 | }
9 |
10 | .layer-label-container {
11 | align-items: center;
12 | background-color: #e8e8e8;
13 | border-radius: 5px;
14 | display: flex;
15 | font-weight: 600;
16 | justify-content: space-between;
17 | margin-bottom: 0.4em;
18 | padding: 0.5rem;
19 | width: 100%;
20 | }
21 |
22 | .layer-delete-icon {
23 | align-self: flex-end;
24 | cursor: pointer;
25 | padding-left: 0.2em;
26 | }
27 |
28 | .layer-edit-icon {
29 | cursor: pointer;
30 | padding-left: 0.5em;
31 | }
32 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/css/uploadBuilder.css:
--------------------------------------------------------------------------------
1 | .upload-model-card {
2 | text-align: center;
3 | }
4 |
5 | .question-icon {
6 | cursor: pointer;
7 | padding: 1em;
8 | }
9 |
10 | .inputfile {
11 | width: 0.1px;
12 | height: 0.1px;
13 | opacity: 0;
14 | overflow: hidden;
15 | position: absolute;
16 | z-index: -1;
17 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/options/lossOptions.js:
--------------------------------------------------------------------------------
1 | const lossOptions = ['Binary Cross Entropy', 'Categorical Cross Entropy']
2 |
3 | export default lossOptions
4 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/options/metricOptions.js:
--------------------------------------------------------------------------------
1 | const metricOptions = ['Accuracy']
2 |
3 | export default metricOptions
4 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/options/optimizerOptions.js:
--------------------------------------------------------------------------------
1 | const optimizerOptions = [
2 | 'Adadelta',
3 | 'Adagrad',
4 | 'Adam',
5 | 'Adamax',
6 | 'Ftrl',
7 | 'Nadam',
8 | 'RMSProp',
9 | 'SGD'
10 | ]
11 |
12 | export default optimizerOptions
13 |
--------------------------------------------------------------------------------
/labellab-client/src/components/model-editor/sub-modules/options/transferLearningOptions.js:
--------------------------------------------------------------------------------
1 | const transferLearningOptions = [
2 | 'DenseNet121',
3 | 'DenseNet169',
4 | 'DenseNet201',
5 | 'InceptionResNetV2',
6 | 'InceptionV3',
7 | 'MobileNet',
8 | 'MobileNetV2',
9 | 'NASNetLarge',
10 | 'NASNetMobile',
11 | 'ResNet50',
12 | 'ResNet101',
13 | 'ResNet152',
14 | 'ResNet101V2',
15 | 'ResNet152V2',
16 | 'ResNet50V2',
17 | 'VGG16',
18 | 'VGG19',
19 | 'Xception'
20 | ]
21 |
22 | export default transferLearningOptions
23 |
--------------------------------------------------------------------------------
/labellab-client/src/components/navbar/css/searchbar.css:
--------------------------------------------------------------------------------
1 | .searchbar-parent {
2 | width: 340px;
3 | height: 46px;
4 | border-radius: 5px;
5 | }
6 |
7 | @media only screen and (min-width: 600px) {
8 | .searchbar-parent {
9 | position: absolute;
10 | margin-left: 184px;
11 | }
12 | }
13 |
14 | .size {
15 | /* font-size: 1.1em !important; */
16 | }
17 |
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/analytics.css:
--------------------------------------------------------------------------------
1 | .project-analytics-parent {
2 | margin: 0 2rem 2rem 0;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | .analytics-row {
8 | display: flex;
9 | flex-direction: row;
10 | justify-content: space-evenly;
11 | }
12 |
13 | .project-analytics-section {
14 | width: 100%;
15 | padding: 1em;
16 | box-shadow: 0px 0px 5px #ccc;
17 | border: 1px solid #ccc;
18 | border-radius: 20px;
19 | }
20 |
21 | .analytics-column {
22 | padding-left: 0px !important;
23 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/images.css:
--------------------------------------------------------------------------------
1 | .image-parent {
2 | padding: 1em;
3 | display: flex;
4 | flex-direction: row;
5 | flex-wrap: wrap;
6 | }
7 | .image-parent img {
8 | padding: 0 1em !important;
9 | }
10 | .image-file-input {
11 | width: 0.1px;
12 | height: 0.1px;
13 | opacity: 0;
14 | overflow: hidden;
15 | position: absolute;
16 | z-index: -1;
17 | margin: 10px;
18 | }
19 | .flex {
20 | display: flex;
21 | }
22 | .image-table-body {
23 | flex: 1;
24 | overflow-y: auto;
25 | overflow-x: hidden;
26 | }
27 | .max-size-error {
28 | color: red;
29 | }
30 | .custom-margin {
31 | margin-bottom: 1rem !important;
32 | }
33 | .image-table-container {
34 | width: 100%;
35 | padding-right: 20px;
36 | }
37 | .image-table {
38 | display: flex;
39 | flex-direction: column;
40 | height: 30em;
41 | margin-right: 200px;
42 | background-color: red;
43 | }
44 |
45 | .max-size-error {
46 | color: red;
47 | }
48 | .custom-margin {
49 | margin-bottom: 1rem !important;
50 | }
51 | .image-table-container {
52 | width: 100%;
53 | padding-right: 20px;
54 | }
55 |
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/index.css:
--------------------------------------------------------------------------------
1 | .project-main {
2 | display: flex;
3 | flex-direction: row;
4 | }
5 |
6 | .project-non-side-section {
7 | width: 100%;
8 | margin-right: unset !important;
9 | margin-top: 4em;
10 | }
11 |
12 | .margin-v {
13 | margin: 10px 0px !important;
14 | }
15 |
16 | @media only screen and (max-width: 767px) {
17 | .project-main {
18 | margin: 0 !important;
19 | flex-direction: column;
20 | }
21 |
22 | .project-non-side-section {
23 | padding: 10px;
24 | max-width: unset !important;
25 | width: 100% !important;
26 | margin-right: auto;
27 | min-height: 50%;
28 | }
29 | }
30 |
31 | .labelDropdown {
32 | margin-left: 25vw;
33 | }
34 |
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/issues.css:
--------------------------------------------------------------------------------
1 | .issue-status-label {
2 | width: 100%
3 | }
4 | .center {
5 | text-align: center !important;
6 | }
7 | .left {
8 | text-align: left !important;
9 | }
10 | .user-icon {
11 | font-size: 2.4em !important;
12 | color: grey;
13 | margin-top: 0.5rem !important;
14 | }
15 | .issue-header {
16 | text-align: left !important;
17 | cursor: pointer;
18 | }
19 | .issue-item {
20 | text-align: center !important;
21 | }
22 | .issue-activity {
23 | color: black !important;
24 | }
25 | .comment-section {
26 | height: 30vh;
27 | overflow-y: scroll;
28 | display: flex;
29 | flex-direction: column-reverse;
30 | }
31 | .activity-section {
32 | height: 30vh;
33 | overflow-y: scroll;
34 | }
35 | .detail-header {
36 | margin-bottom: 0.5em !important;
37 | }
38 | .ui.header:last-child {
39 | margin-top: 0;
40 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/labelItem.css:
--------------------------------------------------------------------------------
1 | .modal-actions {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | }
6 |
7 | .modal-actions > div {
8 | padding-bottom: 1.5em;
9 | padding-top: 1.5em;
10 | }
11 |
12 | .label-container {
13 | overflow: auto
14 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/models.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-client/src/components/project/css/models.css
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/searchUser.css:
--------------------------------------------------------------------------------
1 | .searchbar-user-parent{
2 | float: left;
3 | margin-bottom: 1em;
4 | }
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/sidebar.css:
--------------------------------------------------------------------------------
1 | .sidebar-container {
2 | display: flex;
3 | align-items: center;
4 | flex-direction: column;
5 | }
6 |
7 | .sidebar-parent {
8 | width: 25%;
9 | display: flex;
10 | align-items: center;
11 | flex-direction: column;
12 | justify-content: space-between;
13 | }
14 | .profile-first-leftbar {
15 | margin: 1em;
16 | }
17 | .sidebar-image-button {
18 | display: flex;
19 | flex-direction: row;
20 | justify-content: center;
21 | }
22 | .sidebar-menu-parent {
23 | margin-top: 2em;
24 | margin-bottom: 2em;
25 | display: flex;
26 | flex-direction: row;
27 | justify-content: center;
28 | }
29 | .delete-project-button {
30 | margin-top: 2rem !important;
31 | width: 100%;
32 | }
33 |
34 | @media only screen and (max-width: 767px) {
35 | .delete-project-button {
36 | margin: 2rem 0 0 0 !important;
37 | width: 100%;
38 | }
39 |
40 | .sidebar-parent {
41 | width: 100%;
42 | margin: 0 !important;
43 | display: flex;
44 | align-items: center;
45 | flex-direction: column;
46 | justify-content: space-between;
47 | }
48 |
49 | .sidebar-menu-parent {
50 | width: 100%;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/labellab-client/src/components/project/css/team.css:
--------------------------------------------------------------------------------
1 | .add-member-button {
2 | padding: 2em 0;
3 | }
4 | .add-member {
5 | color: white !important;
6 | }
7 | .team-remove-user-icon:hover {
8 | cursor: pointer;
9 | }
10 |
11 | .ui.container {
12 | margin-left: unset !important;
13 | }
14 |
15 | .all-teams {
16 | margin-right: 20px !important;
17 | }
18 |
19 | .my-team {
20 | margin: 0 !important;
21 | }
22 |
23 | .team-management-conatiner {
24 | display: flex !important;
25 | flex-direction: row !important;
26 | }
27 |
28 | @media only screen and (max-width: 767px) {
29 | .ui.container {
30 | width: 100% !important;
31 | }
32 | }
33 |
34 | .team-item {
35 | cursor: pointer;
36 | }
37 |
--------------------------------------------------------------------------------
/labellab-client/src/components/redirect.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Header } from 'semantic-ui-react'
3 | class Redirect extends Component {
4 | // componentDidMount() {
5 | // let token = window.location.search.substring(1)
6 | // if (token) {
7 | // setToken(TOKEN_TYPE, token, true)
8 | // }
9 | // }
10 | render() {
11 | return (
12 |
13 |
14 |
15 | )
16 | }
17 | }
18 |
19 | export default Redirect
20 |
--------------------------------------------------------------------------------
/labellab-client/src/components/register/css/register.css:
--------------------------------------------------------------------------------
1 | @media only screen and (max-width: 600px) {
2 | .register-parent {
3 | width: 80% !important;
4 | }
5 | .register-submit {
6 | width: 100% !important;
7 | }
8 | }
9 |
10 | .register-parent {
11 | display: flex;
12 | flex-direction: column;
13 | height: 100%;
14 | padding: 5em 0px;
15 | width: 30%;
16 | margin-left: auto;
17 | margin-right: auto;
18 | box-sizing: border-box;
19 | }
20 |
21 | .errorText {
22 | color: #9f3a38;
23 | padding: 0px 10px 10px 10px;
24 | }
25 |
26 | .register-form {
27 | margin-top: 1.2em;
28 | }
29 |
30 | .register-login {
31 | padding: 1em 0;
32 | }
33 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/analytics.js:
--------------------------------------------------------------------------------
1 | export const ANALYTICS_TIME_LABEL_FAILURE = 'ANALYTICS_TIME_LABEL_FAILURE',
2 | ANALYTICS_TIME_LABEL_REQUEST = 'ANALYTICS_TIME_LABEL_REQUEST',
3 | ANALYTICS_TIME_LABEL_SUCCESS = 'ANALYTICS_TIME_LABEL_SUCCESS',
4 | ANALYTICS_COUNT_LABEL_FAILURE = 'ANALYTICS_COUNT_LABEL_FAILURE',
5 | ANALYTICS_COUNT_LABEL_REQUEST = 'ANALYTICS_COUNT_LABEL_REQUEST',
6 | ANALYTICS_COUNT_LABEL_SUCCESS = 'ANALYTICS_COUNT_LABEL_SUCCESS',
7 | ISSUE_ANALYTICS_FAILURE = 'ISSUE_ANALYTICS_FAILURE',
8 | ISSUE_ANALYTICS_REQUEST = 'ISSUE_ANALYTICS_REQUEST',
9 | ISSUE_ANALYTICS_SUCCESS = 'ISSUE_ANALYTICS_SUCCESS'
10 |
11 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/auth.js:
--------------------------------------------------------------------------------
1 | export const LOGIN_REQUEST = 'LOGIN_REQUEST',
2 | LOGIN_SUCCESS = 'LOGIN_SUCCESS',
3 | LOGIN_FAILURE = 'LOGIN_FAILURE',
4 | SET_USER_AUTH = 'SET_USER_AUTH',
5 | LOGOUT_REQUEST = 'LOGOUT_REQUEST',
6 | LOGOUT_SUCCESS = 'LOGOUT_SUCCESS',
7 | SEND_EMAIL_REQUEST = 'SEND_EMAIL_REQUEST',
8 | SENT_EMAIL_SUCCESS = 'SENT_EMAIL_SUCCESS',
9 | EMAIL_SENT_FAILURE = 'EMAIL_SENT_FAILURE',
10 | VERIFY_TOKEN_REQUEST = 'VERIFY_TOKEN_REQUEST',
11 | VERIFY_TOKEN_SUCCESS = 'VERIFY_TOKEN_SUCCESS',
12 | VERIFY_TOKEN_FAILURE = 'VERIFY_TOKEN_FAILURE',
13 | UPDATE_PASSWORD_REQUEST = 'UPDATE_PASSWORD_REQUEST',
14 | UPDATE_PASSWORD_SUCCESS = 'UPDATE_PASSWORD_SUCCESS',
15 | UPDATE_PASSWORD_FAILURE = 'UPDATE_PASSWORD_FAILURE',
16 | OAUTH_LOGIN_REQUEST = 'OAUTH_LOGIN_REQUEST',
17 | OAUTH_LOGIN_SUCCESS = 'OAUTH_LOGIN_SUCCESS',
18 | OAUTH_LOGIN_FAILURE = 'OAUTH_LOGIN_FAILURE',
19 | GITHUB_OAUTH_REQUEST = 'GITHUB_OAUTH_REQUEST',
20 | GITHUB_OAUTH_SUCCESS = 'GITHUB_OAUTH_SUCCESS',
21 | GITHUB_OAUTH_FAILURE = 'GITHUB_OAUTH_FAILURE',
22 | GITHUB_OAUTH_CALLBACK_REQUEST = 'GITHUB_OAUTH_CALLBACK_REQUEST',
23 | GITHUB_OAUTH_CALLBACK_SUCCESS = 'GITHUB_OAUTH_CALLBACK_SUCCESS',
24 | GITHUB_OAUTH_CALLBACK_FAILURE = 'GITHUB_OAUTH_CALLBACK_FAILURE'
25 |
26 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/image.js:
--------------------------------------------------------------------------------
1 | export const POST_IMAGE_REQUEST = 'POST_IMAGE_REQUEST',
2 | POST_IMAGE_SUCCESS = 'POST_IMAGE_SUCCESS',
3 | POST_IMAGE_FAILURE = 'POST_IMAGE_FAILURE',
4 | FETCH_IMAGE_FAILURE = 'FETCH_IMAGE_FAILURE',
5 | FETCH_IMAGE_REQUEST = 'FETCH_IMAGE_REQUEST',
6 | FETCH_IMAGE_SUCCESS = 'FETCH_IMAGE_SUCCESS',
7 | DELETE_IMAGE_REQUEST = 'DELETE_IMAGE_REQUEST',
8 | DELETE_IMAGE_FAILURE = 'DELETE_IMAGE_FAILURE',
9 | DELETE_IMAGE_SUCCESS = 'DELETE_IMAGE_SUCCESS',
10 | SET_IMAGE_STATE = 'SET_IMAGE_STATE'
11 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/index.js:
--------------------------------------------------------------------------------
1 | export * from './auth'
2 | export * from './register'
3 | export * from './user'
4 | export * from './project/index'
5 | export * from './image'
6 | export * from './issue'
7 | export * from './label'
8 | export * from './analytics'
9 | export * from './model'
10 | export * from './notification'
11 | export const TOKEN_TYPE = 'access_token'
12 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/label.js:
--------------------------------------------------------------------------------
1 | export const CREATE_LABEL_REQUEST = 'CREATE_LABEL_REQUEST',
2 | CREATE_LABEL_SUCCESS = 'CREATE_LABEL_SUCCESS',
3 | CREATE_LABEL_FAILURE = 'CREATE_LABEL_FAILURE',
4 | UPDATE_LABEL_FAILURE = 'UPDATE_LABEL_FAILURE',
5 | UPDATE_LABEL_REQUEST = 'UPDATE_LABEL_REQUEST',
6 | UPDATE_LABEL_SUCCESS = 'UPDATE_LABEL_SUCCESS',
7 | DELETE_LABEL_FAILURE = 'DELETE_LABEL_FAILURE',
8 | DELETE_LABEL_REQUEST = 'DELETE_LABEL_REQUEST',
9 | DELETE_LABEL_SUCCESS = 'DELETE_LABEL_SUCCESS',
10 | UPDATE_A_LABEL_FAILURE = 'UPDATE_A_LABEL_FAILURE',
11 | UPDATE_A_LABEL_REQUEST = 'UPDATE_A_LABEL_REQUEST',
12 | UPDATE_A_LABEL_SUCCESS = 'UPDATE_A_LABEL_SUCCESS'
13 |
14 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/notification.js:
--------------------------------------------------------------------------------
1 | export const FETCH_NOTIFICATION_REQUEST = 'FETCH_NOTIFICATION_REQUEST',
2 | FETCH_NOTIFICATION_SUCCESS = 'FETCH_NOTIFICATION_SUCCESS',
3 | FETCH_NOTIFICATION_FAILURE = 'FETCH_NOTIFICATION_FAILURE',
4 | REMOVE_TOAST_NOTIFICATION = 'REMOVE_TOAST_NOTIFICATION',
5 | RECEIVE_NOTIFICATION = 'RECEIVE_NOTIFICATION'
6 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/fetchDetails.js:
--------------------------------------------------------------------------------
1 | export const FETCH_PROJECT_REQUEST = 'FETCH_PROJECT_REQUEST',
2 | FETCH_PROJECT_SUCCESS = 'FETCH_PROJECT_SUCCESS',
3 | FETCH_PROJECT_FAILURE = 'FETCH_PROJECT_FAILURE',
4 | FETCH_PROJECT_ALL_FAILURE = 'FETCH_PROJECT_ALL_FAILURE',
5 | FETCH_PROJECT_ALL_REQUEST = 'FETCH_PROJECT_ALL_REQUEST',
6 | FETCH_PROJECT_ALL_SUCCESS = 'FETCH_PROJECT_ALL_SUCCESS',
7 | FETCH_LABEL_SUCCESS = 'FETCH_LABEL_SUCCESS',
8 | FETCH_LABEL_REQUEST = 'FETCH_LABEL_REQUEST',
9 | FETCH_LABEL_FAILURE = 'FETCH_LABEL_FAILURE',
10 | FETCH_PROJECT_ROLES_REQUEST = 'FETCH_PROJECT_ROLES_REQUEST',
11 | FETCH_PROJECT_ROLES_SUCCESS = 'FETCH_PROJECT_ROLES_SUCCESS',
12 | FETCH_PROJECT_ROLES_FAILURE = 'FETCH_PROJECT_ROLES_FAILURE'
13 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/index.js:
--------------------------------------------------------------------------------
1 | export * from './member'
2 | export * from './fetchDetails'
3 | export * from './search'
4 | export * from './projectDetails'
5 | export * from './teams'
6 | export * from './pathTracking'
7 | export * from './logs'
8 | export const DELETE_PROJECT_REQUEST = 'DELETE_PROJECT_REQUEST',
9 | DELETE_PROJECT_FAILURE = 'DELETE_PROJECT_FAILURE',
10 | DELETE_PROJECT_SUCCESS = 'DELETE_PROJECT_SUCCESS',
11 | LEAVE_PROJECT_REQUEST = 'LEAVE_PROJECT_REQUEST',
12 | LEAVE_PROJECT_SUCCESS = 'LEAVE_PROJECT_SUCCESS',
13 | LEAVE_PROJECT_FAILURE = 'LEAVE_PROJECT_FAILURE'
14 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/logs.js:
--------------------------------------------------------------------------------
1 | export const FETCH_PROJECT_LOGS_REQUEST = 'FETCH_PROJECT_LOGS_REQUEST',
2 | FETCH_PROJECT_LOGS_SUCCESS = 'FETCH_PROJECT_LOGS_SUCCESS',
3 | FETCH_PROJECT_LOGS_FAILURE = 'FETCH_PROJECT_LOGS_FAILURE',
4 | FETCH_CATEGORY_SPECIFIC_LOGS_REQUEST = 'FETCH_CATEGORY_SPECIFIC_LOGS_REQUEST',
5 | FETCH_CATEGORY_SPECIFIC_LOGS_SUCCESS = 'FETCH_CATEGORY_SPECIFIC_LOGS_SUCCESS',
6 | FETCH_CATEGORY_SPECIFIC_LOGS_FAILURE = 'FETCH_CATEGORY_SPECIFIC_LOGS_FAILURE',
7 | FETCH_MEMBER_SPECIFIC_LOGS_REQUEST = 'FETCH_MEMBER_SPECIFIC_LOGS_REQUEST',
8 | FETCH_MEMBER_SPECIFIC_LOGS_SUCCESS = 'FETCH_MEMBER_SPECIFIC_LOGS_SUCCESS',
9 | FETCH_MEMBER_SPECIFIC_LOGS_FAILURE = 'FETCH_MEMBER_SPECIFIC_LOGS_FAILURE',
10 | FETCH_ENTITY_SPECIFIC_LOGS_REQUEST = 'FETCH_ENTITY_SPECIFIC_LOGS_REQUEST',
11 | FETCH_ENTITY_SPECIFIC_LOGS_SUCCESS = 'FETCH_ENTITY_SPECIFIC_LOGS_SUCCESS',
12 | FETCH_ENTITY_SPECIFIC_LOGS_FAILURE = 'FETCH_ENTITY_SPECIFIC_LOGS_FAILURE'
13 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/member.js:
--------------------------------------------------------------------------------
1 | export const DELETE_MEMBER_FAILURE = 'DELETE_MEMBER_FAILURE',
2 | DELETE_MEMBER_REQUEST = 'DELETE_MEMBER_REQUEST',
3 | DELETE_MEMBER_SUCCESS = 'DELETE_MEMBER_SUCCESS',
4 | ADD_MEMBER_REQUEST = 'ADD_MEMBER_REQUEST',
5 | ADD_MEMBER_SUCCESS = 'ADD_MEMBER_SUCCESS',
6 | ADD_MEMBER_FAILURE = 'ADD_MEMBER_FAILURE'
7 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/pathTracking.js:
--------------------------------------------------------------------------------
1 | export const FETCH_COORDINATES_FAILURE = 'FETCH_COORDINATES_FAILURE',
2 | FETCH_COORDINATES_REQUEST = 'FETCH_COORDINATES_REQUEST',
3 | FETCH_COORDINATES_SUCCESS = 'FETCH_COORDINATES_SUCCESS'
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/projectDetails.js:
--------------------------------------------------------------------------------
1 | export const INITIALIZE_PROJECT_REQUEST = 'INITIALIZE_PROJECT_REQUEST',
2 | INITIALIZE_PROJECT_SUCCESS = 'INITIALIZE_PROJECT_SUCCESS',
3 | INITIALIZE_PROJECT_FAILURE = 'INITIALIZE_PROJECT_FAILURE',
4 | UPDATE_PROJECT_REQUEST = 'UPDATE_PROJECT_REQUEST',
5 | UPDATE_PROJECT_SUCCESS = 'UPDATE_PROJECT_SUCCESS',
6 | UPDATE_PROJECT_FAILURE = 'UPDATE_PROJECT_FAILURE'
7 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/search.js:
--------------------------------------------------------------------------------
1 | export const SEARCH_PROJECTS = 'SEARCH_PROJECTS',
2 | SEARCH_PROJECTS_FAILURE = 'SEARCH_PROJECTS_FAILURE'
3 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/project/teams.js:
--------------------------------------------------------------------------------
1 | export const FETCH_TEAMS_FAILURE = 'FETCH_TEAMS_FAILURE',
2 | FETCH_TEAMS_REQUEST = 'FETCH_TEAMS_REQUEST',
3 | FETCH_TEAMS_SUCCESS = 'FETCH_TEAMS_SUCCESS',
4 | DELETE_TEAM_FAILURE = 'DELETE_TEAM_FAILURE',
5 | DELETE_TEAM_REQUEST = 'DELETE_TEAM_REQUEST',
6 | DELETE_TEAM_SUCCESS = 'DELETE_TEAM_SUCCESS',
7 | FETCH_TEAM_REQUEST = 'FETCH_TEAM_REQUEST',
8 | FETCH_TEAM_SUCCESS = 'FETCH_TEAM_SUCCESS',
9 | FETCH_TEAM_FAILURE = 'FETCH_TEAM_FAILURE',
10 | UPDATE_TEAM_REQUEST = 'UPDATE_TEAM_REQUEST',
11 | UPDATE_TEAM_SUCCESS = 'UPDATE_TEAM_SUCCESS',
12 | UPDATE_TEAM_FAILURE = 'UPDATE_TEAM_FAILURE',
13 | ADD_TEAM_MEMBER_REQUEST = 'ADD_TEAM_MEMBER_REQUEST',
14 | ADD_TEAM_MEMBER_SUCCESS = 'ADD_TEAM_MEMBER_SUCCESS',
15 | ADD_TEAM_MEMBER_FAILURE = 'ADD_TEAM_MEMBER_FAILURE',
16 | REMOVE_TEAM_MEMBER_REQUEST = 'REMOVE_TEAM_MEMBER_REQUEST',
17 | REMOVE_TEAM_MEMBER_SUCCESS = 'REMOVE_TEAM_MEMBER_SUCCESS',
18 | REMOVE_TEAM_MEMBER_FAILURE = 'REMOVE_TEAM_MEMBER_FAILURE',
19 | FETCH_TEAM_MESSAGES_REQUEST = 'FETCH_TEAM_MESSAGES_REQUEST',
20 | FETCH_TEAM_MESSAGES_SUCCESS = 'FETCH_TEAM_MESSAGES_SUCCESS',
21 | FETCH_TEAM_MESSAGES_FAILURE = 'FETCH_TEAM_MESSAGES_FAILURE',
22 | SEND_MESSAGE = 'SEND_MESSAGE',
23 | RECEIVE_MESSAGE = 'RECEIVE_MESSAGE'
24 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/register.js:
--------------------------------------------------------------------------------
1 | export const REGISTER_REQUEST = 'REGISTER_REQUEST',
2 | REGISTER_SUCCESS = 'REGISTER_SUCCESS',
3 | REGISTER_FAILURE = 'REGISTER_FAILURE'
4 |
--------------------------------------------------------------------------------
/labellab-client/src/constants/user.js:
--------------------------------------------------------------------------------
1 | export const SET_USER_DATA_REQUEST = 'SET_USER_DATA_REQUEST',
2 | SET_USER_DATA_SUCCESS = 'SET_USER_DATA_SUCCESS',
3 | SET_USER_DATA_FAILURE = 'SET_USER_DATA_FAILURE',
4 | UPLOAD_USER_IMAGE_REQUEST = 'UPLOAD_USER_IMAGE_REQUEST',
5 | UPLOAD_USER_IMAGE_SUCCESS = 'UPLOAD_USER_IMAGE_SUCCESS',
6 | UPLOAD_USER_IMAGE_FAILURE = 'UPLOAD_USER_IMAGE_FAILURE',
7 | FETCH_COUNT_FAILURE = 'FETCH_COUNT_FAILURE',
8 | FETCH_COUNT_REQUEST = 'FETCH_COUNT_REQUEST',
9 | FETCH_COUNT_SUCCESS = 'FETCH_COUNT_SUCCESS',
10 | FETCH_ALL_USERS_REQUEST = 'FETCH_ALL_USERS_REQUEST',
11 | FETCH_ALL_USERS_SUCCESS = 'FETCH_ALL_USERS_SUCCESS',
12 | FETCH_ALL_USERS_FAILURE = 'FETCH_ALL_USERS_FAILURE',
13 | SEARCH_USER = 'SEARCH_USER',
14 | SEARCH_USER_FAILURE = 'SEARCH_USER_FAILURE',
15 | EDIT_USER_INFO = 'EDIT_USER_INFO',
16 | EDIT_USER_INFO_FAILURE = 'EDIT_USER_INFO_FAILURE'
17 |
--------------------------------------------------------------------------------
/labellab-client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | }
5 | body .canvas-container {
6 | position: fixed;
7 | bottom: 0;
8 | right: 0;
9 | z-index: -5000;
10 | opacity: 0;
11 | }
--------------------------------------------------------------------------------
/labellab-client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 | import { Provider } from 'react-redux'
4 | import { store } from './utils/store'
5 | import './index.css'
6 | import 'semantic-ui-css/semantic.min.css'
7 | import App from './App'
8 | import * as serviceWorker from './serviceWorker'
9 | ReactDOM.render(
10 |
11 |
12 | ,
13 | document.getElementById('root')
14 | )
15 |
16 | // If you want your app to work offline and load faster, you can change
17 | // unregister() to register() below. Note this comes with some pitfalls.
18 | // Learn more about service workers: https://bit.ly/CRA-PWA
19 | serviceWorker.unregister()
20 |
--------------------------------------------------------------------------------
/labellab-client/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import auth from './auth'
3 | import register from './register'
4 | import user from './user'
5 | import project from './project'
6 | import image from './image'
7 | import issues from './issue'
8 | import label from './label'
9 | import searchProjects from './search'
10 | import searchUser from './searchUser'
11 | import analytics from './analytics'
12 | import model from './model'
13 | import teams from './teams'
14 | import logs from './logs'
15 | import notifications from './notification'
16 |
17 | const rootReducers = combineReducers({
18 | auth,
19 | register,
20 | user,
21 | searchProjects,
22 | searchUser,
23 | analytics,
24 | model,
25 | projects: project,
26 | images: image,
27 | labels: label,
28 | teams,
29 | logs,
30 | issues,
31 | notifications
32 | })
33 |
34 | export default rootReducers
35 |
--------------------------------------------------------------------------------
/labellab-client/src/reducers/register.js:
--------------------------------------------------------------------------------
1 | import {
2 | REGISTER_FAILURE,
3 | REGISTER_REQUEST,
4 | REGISTER_SUCCESS
5 | } from '../constants/index'
6 | const intialState = {
7 | isRegistering: false,
8 | error: false,
9 | errField: '',
10 | statusText: ''
11 | }
12 | const register = (state = intialState, action) => {
13 | switch (action.type) {
14 | case REGISTER_REQUEST:
15 | return {
16 | ...state,
17 | isRegistering: true,
18 | error: false
19 | }
20 | case REGISTER_SUCCESS:
21 | return {
22 | ...state,
23 | isRegistering: false,
24 | statusText: action.payload,
25 | error: false
26 | }
27 | case REGISTER_FAILURE:
28 | return {
29 | ...state,
30 | isRegistering: false,
31 | statusText: action.payload,
32 | errField: action.other,
33 | error: true
34 | }
35 | default:
36 | return state
37 | }
38 | }
39 |
40 | export default register
41 |
--------------------------------------------------------------------------------
/labellab-client/src/reducers/search.js:
--------------------------------------------------------------------------------
1 | import { SEARCH_PROJECTS, SEARCH_PROJECTS_FAILURE } from '../constants/index'
2 | const searchProjects = (state = [], action) => {
3 | switch (action.type) {
4 | case SEARCH_PROJECTS:
5 | return action.payload
6 | case SEARCH_PROJECTS_FAILURE:
7 | return action.payload
8 | default:
9 | return state
10 | }
11 | }
12 | export default searchProjects
13 |
--------------------------------------------------------------------------------
/labellab-client/src/reducers/searchUser.js:
--------------------------------------------------------------------------------
1 | import { SEARCH_USER, SEARCH_USER_FAILURE } from '../constants/index'
2 | const searchUser = (state = [], action) => {
3 | switch (action.type) {
4 | case SEARCH_USER:
5 | return action.payload
6 | case SEARCH_USER_FAILURE:
7 | return action.payload
8 | default:
9 | return state
10 | }
11 | }
12 | export default searchUser
13 |
--------------------------------------------------------------------------------
/labellab-client/src/utils/TestUtils.js:
--------------------------------------------------------------------------------
1 | import checkPropTypes from "check-prop-types";
2 | import { applyMiddleware, createStore } from "redux";
3 | import { middleware } from "./store";
4 | import rootReducers from "../reducers";
5 |
6 | export const findByTestAttr = (component, attr) => {
7 | const wrapper = component.find(`[className='${attr}']`);
8 | return wrapper;
9 | };
10 |
11 | export const checkProps = (component, expectedProps) => {
12 | const propsErr = checkPropTypes(
13 | component.propTypes,
14 | expectedProps,
15 | "props",
16 | component.name
17 | );
18 | return propsErr;
19 | };
20 |
21 | export const testStore = initialState => {
22 | const createStoreWithMiddleware = applyMiddleware(...middleware)(
23 | createStore
24 | );
25 | return createStoreWithMiddleware(rootReducers, initialState);
26 | };
--------------------------------------------------------------------------------
/labellab-client/src/utils/cardLoader/card-loader.css:
--------------------------------------------------------------------------------
1 | .card-loader-height {
2 | height: 125px;
3 | }
4 |
--------------------------------------------------------------------------------
/labellab-client/src/utils/helpers.js:
--------------------------------------------------------------------------------
1 | export const isEmptyObject = obj => Object.keys(obj).length === 0
2 |
3 | export const isEmpty = obj => obj === '' || obj === null || obj === 0
4 |
5 | export const isLengthBetween = (obj, range) =>
6 | obj.length >= range.min && obj.length <= range.max
7 |
8 | export const isEmail = email =>
9 | /^[a-zA-Z0-9._%+-]+@[A-Za-z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email)
10 |
11 | export const isMobilePhone = phone => /^(\+?91|0)?[789]\d{9}$/.test(phone)
12 |
13 | export const validateForm = ({ errors, ...rest }) => {
14 | let valid = true
15 |
16 | // validate errors being empty
17 | Object.values(errors).forEach(val => {
18 | val.length && (valid = false)
19 | })
20 |
21 | // validate if form is empty
22 | Object.values(rest).forEach(val => {
23 | typeof val !== 'boolean' && !val.length && (valid = false)
24 | })
25 |
26 | return valid
27 | }
28 |
--------------------------------------------------------------------------------
/labellab-client/src/utils/pR.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Route, Redirect } from 'react-router-dom'
3 | import { hasToken } from '../utils/token'
4 | import { TOKEN_TYPE } from '../constants/index'
5 | const PrivateRoute = ({ component: Component, ...rest }) => (
6 |
9 | hasToken(TOKEN_TYPE) ? (
10 |
11 | ) : (
12 |
15 | )
16 | }
17 | />
18 | )
19 |
20 | export default PrivateRoute
21 |
--------------------------------------------------------------------------------
/labellab-client/src/utils/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, compose, applyMiddleware } from 'redux'
2 | import thunk from 'redux-thunk'
3 | import rootReducer from '../reducers/index'
4 |
5 | const initialState = {}
6 | export const middleware = [thunk]
7 | const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
8 |
9 | export const store = createStore(
10 | rootReducer,
11 | initialState,
12 | composeEnhancers(applyMiddleware(...middleware))
13 | )
14 |
--------------------------------------------------------------------------------
/labellab-client/src/utils/webSocket.js:
--------------------------------------------------------------------------------
1 | import openSocket from 'socket.io-client'
2 |
3 | const URL = `http://${process.env.REACT_APP_HOST}:${process.env.REACT_APP_SERVER_PORT}`
4 |
5 | const socket = openSocket(URL, { transports: ['polling'] })
6 |
7 | export default socket
8 |
--------------------------------------------------------------------------------
/labellab-flask/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | Dockerfile*
4 | docker-compose*
5 | .dockerignore
6 | .git
7 | .gitignore
8 | .env
9 | */bin
10 | */obj
11 | README.md
12 | LICENSE
13 | .vscode
--------------------------------------------------------------------------------
/labellab-flask/.envsample:
--------------------------------------------------------------------------------
1 | export FLASK_APP="app.py"
2 | export FLASK_ENV=""
3 | export FLASK_CONFIG=""
4 |
5 | export DEV_DATABASE_URL= "mysql+pymysql://" + username + ":" + password + "@" + host + "/labellab"
6 | export TEST_DATABASE_URL="mysql+pymysql://" + username + ":" + password + "@" + host + "/test_labellab"
7 | export DATABASE_URL=""
8 |
9 | export API_KEY=""
--------------------------------------------------------------------------------
/labellab-flask/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore = E203, E266, E501, W503, F403, F401
3 | max-line-length = 79
4 | max-complexity = 18
5 | select = B,C,E,F,W,T4,B9
--------------------------------------------------------------------------------
/labellab-flask/.gcloudignore:
--------------------------------------------------------------------------------
1 | # This file specifies files that are *not* uploaded to Google Cloud Platform
2 | # using gcloud. It follows the same syntax as .gitignore, with the addition of
3 | # "#!include" directives (which insert the entries of the given .gitignore-style
4 | # file at that point).
5 | #
6 | # For more information, run:
7 | # $ gcloud topic gcloudignore
8 | #
9 | .gcloudignore
10 | # If you would like to upload your .git directory, .gitignore file or files
11 | # from your .gitignore file, remove the corresponding line
12 | # below:
13 | .git
14 | .gitignore
15 |
16 | # Python pycache:
17 | __pycache__/
18 | # Ignored by the build system
19 | /setup.cfg
--------------------------------------------------------------------------------
/labellab-flask/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.7
2 |
3 | RUN pip3 install --upgrade pip
4 |
5 | ENV FLASK_APP app.py
6 | ENV FLASK_CONFIG docker
7 |
8 | RUN mkdir -p /usr/labellab/labellab-flask
9 | WORKDIR /usr/labellab/labellab-flask
10 |
11 | COPY requirements.txt requirements.txt
12 | COPY docker.txt docker.txt
13 | RUN pip install -r docker.txt
14 | COPY ./boot.sh /boot.sh
15 |
16 | RUN chmod +x /boot.sh
17 |
18 | EXPOSE 5000
19 |
20 | ENTRYPOINT [ "/boot.sh" ]
--------------------------------------------------------------------------------
/labellab-flask/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/controllers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/controllers/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/helpers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/helpers/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/helpers/chatroom.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import desc
2 |
3 | from api.extensions import db
4 | from api.models.Message import Message
5 |
6 | # Get all messages of a team
7 | def get_all_messages(team_id):
8 | messages = Message.query.filter_by(team_id=team_id).order_by(desc('timestamp')).all()
9 | return list(map(lambda message: to_json(message), messages))
10 |
11 | # Save message
12 | def save_message(message):
13 | db.session.add(message)
14 | db.session.commit()
15 | return to_json(message)
16 |
17 | def to_json(message):
18 | return {
19 | 'id': message.id,
20 | 'body': message.body,
21 | 'team_id': message.team_id,
22 | 'user_id': message.user_id,
23 | 'username': message.username,
24 | 'entity_type': message.entity_type,
25 | 'entity_id': message.entity_id,
26 | 'timestamp': str(message.timestamp),
27 | }
--------------------------------------------------------------------------------
/labellab-flask/api/helpers/notification.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import desc
2 |
3 | from api.extensions import db
4 | from api.models.Notification import Notification
5 | from api.serializers.notification import NotificationSchema
6 |
7 | notification_schema = NotificationSchema()
8 | notifications_schema = NotificationSchema(many =True)
9 |
10 | # Fetch all notifications related to a user
11 | def fetch_all_user_notifications(user_id):
12 | notifications = Notification.query.filter_by(user_id=user_id).all()
13 | return list(map(lambda notification: to_json(notification), notifications))
14 |
15 | # Save a notification to db
16 | def save_notification(notification):
17 | db.session.add(notification)
18 | db.session.commit()
19 | return notification_schema.dump(notification).data
20 |
21 | def to_json(notification):
22 | return {
23 | 'id': notification.id,
24 | 'message': notification.message,
25 | 'type': notification.type,
26 | 'user_id': notification.user_id
27 | }
28 |
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/comment_decorator.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.comment import find_by_id
6 |
7 | def comment_exists(fun):
8 | @wraps(fun)
9 | def wrap(*args, **kwargs):
10 |
11 | # Get comment id
12 | comment_id = kwargs.get('comment_id')
13 | comment = find_by_id(comment_id)
14 |
15 | if not comment:
16 | response = {
17 | 'success': False,
18 | 'msg': 'comment does not exist',
19 | }
20 | return make_response(jsonify(response)), 404
21 |
22 | return fun(*args, **kwargs)
23 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/image_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def image_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user does not have images or admin role, then unauthorized
29 | if 'admin' not in user_roles and 'images' not in user_roles:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only a images team member can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/image_labelling_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def image_labelling_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user does not have image labelling or admin role, then unauthorized
29 | if 'admin' not in user_roles and 'image labelling' not in user_roles:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only a image labelling team member can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/issue_decorator.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.issue import find_by_id
6 |
7 | def issue_exists(fun):
8 | @wraps(fun)
9 | def wrap(*args, **kwargs):
10 |
11 | # Get issue id
12 | issue_id = kwargs.get('issue_id')
13 | issue = find_by_id(issue_id)
14 |
15 | if not issue:
16 | response = {
17 | 'success': False,
18 | 'msg': 'Issue does not exist',
19 | }
20 | return make_response(jsonify(response)), 404
21 |
22 | return fun(*args, **kwargs)
23 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/label_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def label_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user does not have labels or admin role, then unauthorized
29 | if 'admin' not in user_roles and 'labels' not in user_roles:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only a labels team member can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/model_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def model_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user does not have models or admin role, then unauthorized
29 | if 'admin' not in user_roles and 'models' not in user_roles:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only a models team member can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/project_admin_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def admin_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user does not have admin role, then unauthorized
29 | if 'admin' not in user_roles:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only an admin can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/project_member_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 | from api.helpers.user import get_user_roles
7 |
8 | def project_member_only(fun):
9 | @wraps(fun)
10 | def wrap(*args, **kwargs):
11 |
12 | # Get current user
13 | user_id = get_jwt_identity()
14 |
15 | # Get project and admin_id
16 | project_id = kwargs.get('project_id')
17 | project = find_by_project_id(project_id)
18 |
19 | if not project:
20 | response = {
21 | 'success': False,
22 | 'msg': 'Project does not exist',
23 | }
24 | return make_response(jsonify(response)), 404
25 |
26 | user_roles = get_user_roles(user_id, project_id)
27 |
28 | # If current user has no roles in the project, then unauthorized
29 | if len(user_roles) == 0:
30 | response = {
31 | 'success': False,
32 | 'msg': 'Only a project member can access this route',
33 | }
34 | return make_response(jsonify(response)), 401
35 |
36 | # Else continue
37 | return fun(*args, **kwargs)
38 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/middleware/project_owner_access.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 | from flask import jsonify, make_response
3 | from flask_jwt_extended import get_jwt_identity
4 |
5 | from api.helpers.project import find_by_project_id
6 |
7 | def project_owner_only(fun):
8 | @wraps(fun)
9 | def wrap(*args, **kwargs):
10 |
11 | # Get current user
12 | user_id = get_jwt_identity()
13 |
14 | # Get project and admin_id
15 | project_id = kwargs.get('project_id')
16 | project = find_by_project_id(project_id)
17 |
18 | if not project:
19 | response = {
20 | 'success': False,
21 | 'msg': 'Project does not exist',
22 | }
23 | return make_response(jsonify(response)), 404
24 |
25 | admin_id = project['admin_id']
26 |
27 | # If current user is not equal to project admin, then unauthorized
28 | if user_id != admin_id:
29 | response = {
30 | 'success': False,
31 | 'msg': 'Only project owner can access this route',
32 | }
33 | return make_response(jsonify(response)), 401
34 |
35 | # Else continue
36 | return fun(*args, **kwargs)
37 | return wrap
--------------------------------------------------------------------------------
/labellab-flask/api/models/Classification.py:
--------------------------------------------------------------------------------
1 | from flask import current_app
2 | from datetime import datetime
3 |
4 | from api.extensions import db, Base
5 |
6 |
7 | class Classification(db.Model):
8 | # This model holds information about classification requests by a user
9 |
10 | __tablename__ = "classification"
11 |
12 | id = db.Column(db.Integer, primary_key=True)
13 | image_name = db.Column(db.String(255), nullable=False,)
14 | image_url = db.Column(db.String(255), nullable=False,)
15 | label = db.Column(db.String(255))
16 | confidence = db.Column(db.Float)
17 | user_id = db.Column(db.Integer,
18 | db.ForeignKey(
19 | 'user.id', ondelete="cascade", onupdate="cascade"),
20 | nullable=False)
21 | classified_at = db.Column(db.DateTime, default=datetime.now())
22 |
23 | def __init__(self, image_name, image_url, label, confidence, user_id):
24 | self.image_name = image_name
25 | self.image_url = image_url
26 | self.label = label
27 | self.confidence = confidence
28 | self.user_id = user_id
29 |
30 | def __repr__(self):
31 | """
32 | Returns the object reprensentation
33 | """
34 | return "" % self.image_name
35 |
--------------------------------------------------------------------------------
/labellab-flask/api/models/Log.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from api.extensions import db
4 |
5 | class Log(db.Model):
6 | id = db.Column(db.Integer, primary_key=True)
7 | message = db.Column(db.String(120), nullable=False)
8 | category = db.Column(db.String(20), nullable=False)
9 | entity_type = db.Column(db.String(10))
10 | entity_id = db.Column(db.Integer)
11 | user_id = db.Column(db.Integer, nullable=False)
12 | username = db.Column(db.String(20), nullable=False)
13 | project_id = db.Column(db.Integer, nullable=False)
14 | timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
15 |
16 | def __init__(self, message, category, entity_type, entity_id, user_id, project_id, username):
17 | self.message = message
18 | self.category = category
19 | self.entity_type = entity_type
20 | self.entity_id = entity_id
21 | self.user_id = user_id
22 | self.project_id = project_id
23 | self.username = username
--------------------------------------------------------------------------------
/labellab-flask/api/models/Message.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from api.extensions import db
4 |
5 | class Message(db.Model):
6 | id = db.Column(db.Integer, primary_key=True)
7 | body = db.Column(db.String(200), nullable=False)
8 | team_id = db.Column(db.Integer, nullable=False)
9 | user_id = db.Column(db.Integer, nullable=False)
10 | username = db.Column(db.String(20), nullable=False)
11 | entity_type = db.Column(db.String(10))
12 | entity_id = db.Column(db.Integer)
13 | timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
14 |
15 | def __init__(self, body, team_id, user_id, username, entity_type=None, entity_id=None):
16 | self.body = body
17 | self.team_id = team_id
18 | self.user_id = user_id
19 | self.username = username
20 | self.entity_type = entity_type
21 | self.entity_id = entity_id
22 |
--------------------------------------------------------------------------------
/labellab-flask/api/models/Notification.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from flask import current_app
3 |
4 | from api.extensions import db, Base
5 |
6 | class Notification(db.Model):
7 | """
8 | This model holds information about a notification
9 | """
10 | __tablename__ = "notification"
11 |
12 | id = db.Column(db.Integer, primary_key=True)
13 | message = db.Column(db.String(200), nullable=False)
14 | user_id = db.Column(db.Integer,db.ForeignKey('user.id', ondelete="cascade", onupdate="cascade"), nullable=False)
15 | type = db.Column(db.String(50), nullable=False)
16 |
17 | def __init__(self, message, user_id, type):
18 | self.message = message
19 | self.user_id = user_id
20 | self.type = type
21 |
22 | def __repr__(self):
23 | """
24 | Returns the object representation
25 | """
26 | return "" % self.message
27 |
--------------------------------------------------------------------------------
/labellab-flask/api/models/Point.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from flask import current_app
3 |
4 | from api.extensions import db, Base
5 |
6 | class Point(db.Model):
7 | """
8 | This model holds information about the point of a particular
9 | label to an image.
10 | """
11 | __tablename__ = "point"
12 |
13 | id = db.Column(db.String(45), primary_key=True)
14 | y_coordinate = db.Column(db.Float, nullable=False)
15 | x_coordinate = db.Column(db.Float, nullable=False)
16 | labeldata_id = db.Column(db.String(45),
17 | db.ForeignKey('labeldata.id', ondelete="cascade", onupdate="cascade"),
18 | nullable=False)
19 |
20 | def __init__(self, id, y_coordinate, x_coordinate, labeldata_id):
21 | """
22 | Initializes the Point instance
23 | """
24 | self.id = id
25 | self.labeldata_id = labeldata_id
26 | self.y_coordinate = y_coordinate
27 | self.x_coordinate = x_coordinate
28 |
29 | def __repr__(self):
30 | """
31 | Returns the object reprensentation
32 | """
33 | return "" % self.id
34 |
--------------------------------------------------------------------------------
/labellab-flask/api/models/ProjectMembers.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from flask import current_app, jsonify
3 |
4 | from api.extensions import db, Base
5 |
6 | class ProjectMember(db.Model):
7 | """
8 | This model holds information about a projectmember registered
9 | """
10 | __tablename__ = "projectmember"
11 |
12 | id = db.Column(db.Integer, primary_key=True)
13 | user_id = db.Column(db.Integer,
14 | db.ForeignKey('user.id', ondelete="cascade", onupdate="cascade"),
15 | nullable=False)
16 | team_id = db.Column(db.Integer,
17 | db.ForeignKey('team.id', ondelete="cascade", onupdate="cascade"),
18 | nullable=False)
19 |
20 | def __init__(self, user_id, team_id):
21 | """
22 | Initializes the projectMember instance
23 | """
24 | self.user_id = user_id
25 | self.team_id = team_id
26 |
27 | def __repr__(self):
28 | """
29 | Returns the object reprensentation
30 | """
31 | return "" % self.id
32 |
--------------------------------------------------------------------------------
/labellab-flask/api/models/RevokedToken.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from flask import current_app
3 |
4 | from api.extensions import db, Base
5 |
6 | class RevokedToken(db.Model):
7 | """
8 | This model holds information about revoked tokens, users who have logged out
9 | """
10 |
11 | __tablename__ = "revoked_token"
12 | id = db.Column(db.Integer, primary_key=True)
13 | jti = db.Column(db.String(120))
14 |
15 | def add(self):
16 | db.session.add(self)
17 | db.session.commit()
18 |
19 | @classmethod
20 | def is_jti_blacklisted(cls, jti):
21 | query = cls.query.filter_by(jti=jti).first()
22 | return bool(query)
--------------------------------------------------------------------------------
/labellab-flask/api/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/models/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/routes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/routes/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/routes/analytics.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import analyticscontroller
4 |
5 | analyticsprint = Blueprint("analytics", __name__)
6 |
7 | analyticsprint.add_url_rule(
8 | "/time_label/get/",
9 | view_func=analyticscontroller.analyticsController["time_label"],
10 | methods=["GET"]
11 | )
12 |
13 | analyticsprint.add_url_rule(
14 | "/label_counts/get/",
15 | view_func=analyticscontroller.analyticsController["label_counts"],
16 | methods=["GET"]
17 | )
18 |
19 | analyticsprint.add_url_rule(
20 | "/issue_analytics/get/",
21 | view_func=analyticscontroller.analyticsController["issue_analytics"],
22 | methods=["GET"]
23 | )
24 |
--------------------------------------------------------------------------------
/labellab-flask/api/routes/chatroom.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import chatroomcontroller
4 |
5 | chatroomprint = Blueprint('chatroom', __name__)
6 |
7 | chatroomprint.add_url_rule(
8 | '/chatroom/',
9 | view_func=chatroomcontroller.chatroom_controller['get_messages'],
10 | methods=["GET"]
11 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/classifications.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import classificationscontroller
4 |
5 | classificationsprint = Blueprint("classifications", __name__)
6 |
7 | classificationsprint.add_url_rule(
8 | "/classification/classify",
9 | view_func=classificationscontroller.classificationController["classify_image"],
10 | methods=["POST"])
11 |
12 | classificationsprint.add_url_rule(
13 | "/classification/get/",
14 | view_func=classificationscontroller.classificationController["get_classification"],
15 | methods=["GET"])
16 |
17 | classificationsprint.add_url_rule(
18 | "/classification/all",
19 | view_func=classificationscontroller.classificationController["get_all_classifications"],
20 | methods=["GET"])
21 |
22 | classificationsprint.add_url_rule(
23 | "/classification/delete/",
24 | view_func=classificationscontroller.classificationController["delete_classification"],
25 | methods=["DELETE"])
26 |
--------------------------------------------------------------------------------
/labellab-flask/api/routes/comments.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import commentcontroller
4 |
5 | commentsprint = Blueprint("comments", __name__)
6 |
7 | commentsprint.add_url_rule(
8 | "/comment/create/",
9 | view_func=commentcontroller.commentController["add_comment"],
10 | methods=["POST"]
11 | )
12 |
13 | commentsprint.add_url_rule(
14 | "/comment/get/",
15 | view_func=commentcontroller.commentController["get_all_comment"],
16 | methods=["GET"]
17 | )
18 |
19 | commentsprint.add_url_rule(
20 | "/comment/comment_info//",
21 | view_func=commentcontroller.commentController["comment"],
22 | methods=["GET","DELETE","PUT"]
23 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/images.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import imagescontroller
4 |
5 | imagesprint = Blueprint("images", __name__)
6 |
7 | imagesprint.add_url_rule(
8 | "/image/create/",
9 | view_func=imagescontroller.imageController["save_image"],
10 | methods=["POST"]
11 | )
12 |
13 | imagesprint.add_url_rule(
14 | "/image/get/",
15 | view_func=imagescontroller.imageController["get_all_images"],
16 | methods=["GET"]
17 | )
18 |
19 | imagesprint.add_url_rule(
20 | "/image/get_image//",
21 | view_func=imagescontroller.imageController["get_image"],
22 | methods=["GET"]
23 | )
24 |
25 | imagesprint.add_url_rule(
26 | "/image/delete/",
27 | view_func=imagescontroller.imageController["delete_images"],
28 | methods=["POST"]
29 | )
30 |
31 | imagesprint.add_url_rule(
32 | "/image/update/",
33 | view_func=imagescontroller.imageController["update_labels"],
34 | methods=["PUT"]
35 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/labels.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import labelscontroller
4 |
5 | labelsprint = Blueprint("labels", __name__)
6 |
7 | labelsprint.add_url_rule(
8 | "/label/create/",
9 | view_func=labelscontroller.labelController["create_label"],
10 | methods=["POST"]
11 | )
12 |
13 | labelsprint.add_url_rule(
14 | "/label/get/",
15 | view_func=labelscontroller.labelController["get_all_labels"],
16 | methods=["GET"]
17 | )
18 |
19 | labelsprint.add_url_rule(
20 | "/label/label_info//",
21 | view_func=labelscontroller.labelController["label"],
22 | methods=["GET","DELETE","PUT"]
23 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/logs.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers.logscontroller import logs_controller
4 |
5 | logs_blueprint = Blueprint("logs", __name__)
6 |
7 | logs_blueprint.add_url_rule(
8 | '/logs/',
9 | view_func=logs_controller['fetch_project_logs'],
10 | methods=['GET'],
11 | )
12 |
13 | logs_blueprint.add_url_rule(
14 | '/logs//category/',
15 | view_func=logs_controller['fetch_category_logs'],
16 | methods=['GET'],
17 | )
18 |
19 | logs_blueprint.add_url_rule(
20 | '/logs//user/',
21 | view_func=logs_controller['fetch_user_logs'],
22 | methods=['GET'],
23 | )
24 |
25 | logs_blueprint.add_url_rule(
26 | '/logs//entity//',
27 | view_func=logs_controller['fetch_entity_logs'],
28 | methods=['GET'],
29 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/ml_files.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask import Blueprint, render_template, send_from_directory
3 |
4 | from api.config import config
5 |
6 | mlfilesprint = Blueprint("ml_files", __name__)
7 |
8 | def ml_files_route(filename, folder):
9 | if filename != "" and os.path.exists(config['development'].ML_FILES_DIR + '/' + folder + '/' + filename):
10 | return send_from_directory(config['development'].ML_FILES_DIR + '/' + folder, filename)
11 | else:
12 | return render_template('index.html')
13 |
14 | mlfilesprint.add_url_rule(
15 | "//",
16 | view_func=ml_files_route,
17 | methods=["GET"]
18 | )
19 |
--------------------------------------------------------------------------------
/labellab-flask/api/routes/notifications.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers.notificationscontroller import notifications_controller
4 |
5 | notificationsprint = Blueprint("notifications", __name__)
6 |
7 | notificationsprint.add_url_rule(
8 | '/notifications',
9 | view_func=notifications_controller['fetch_user_notifications'],
10 | methods=['GET'],
11 | )
--------------------------------------------------------------------------------
/labellab-flask/api/routes/static.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask import Blueprint, render_template, send_from_directory
3 |
4 | from api.config import config
5 |
6 | staticprint = Blueprint("static", __name__)
7 |
8 |
9 | def static_route(filename, folder):
10 | if filename != "" and os.path.exists(config['development'].UPLOAD_FOLDER + '/' + str(folder) + '/' + filename):
11 | return send_from_directory(config['development'].UPLOAD_FOLDER + '/' + str(folder), filename)
12 | else:
13 | return render_template('index.html')
14 |
15 |
16 | def static_classifications_route(filename, folder):
17 | if filename != "" and os.path.exists(config['development'].UPLOAD_FOLDER + '/classifications/' + str(folder) + '/' + filename):
18 | return send_from_directory(config['development'].UPLOAD_FOLDER + '/classifications/' + str(folder), filename)
19 | else:
20 | return render_template('index.html')
21 |
22 |
23 | staticprint.add_url_rule(
24 | "//",
25 | view_func=static_route,
26 | methods=["GET"]
27 | )
28 |
29 | staticprint.add_url_rule(
30 | "/classifications//",
31 | view_func=static_classifications_route,
32 | methods=["GET"]
33 | )
34 |
--------------------------------------------------------------------------------
/labellab-flask/api/routes/teams.py:
--------------------------------------------------------------------------------
1 | from flask import Blueprint
2 |
3 | from api.controllers import teamscontroller
4 |
5 | teamsprint = Blueprint("teams", __name__)
6 |
7 | teamsprint.add_url_rule(
8 | "/team/get/",
9 | view_func=teamscontroller.teamController["get_all_teams"],
10 | methods=["GET"]
11 | )
12 |
13 | teamsprint.add_url_rule(
14 | "/team/team_info//",
15 | view_func=teamscontroller.teamController["team"],
16 | methods=["GET","DELETE","PUT"]
17 | )
18 |
19 | teamsprint.add_url_rule(
20 | "/team/add_team_member//",
21 | view_func=teamscontroller.teamController["add_team_member"],
22 | methods=["POST"]
23 | )
24 |
25 | teamsprint.add_url_rule(
26 | "/team/remove_team_member//",
27 | view_func=teamscontroller.teamController["remove_team_member"],
28 | methods=["POST"]
29 | )
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/api/serializers/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/classification.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 |
5 |
6 | class ClassificationSchema(ma.ModelSchema):
7 | # Serializer for Classification
8 |
9 | id = fields.Int(dump_only=True)
10 | image_name = fields.Str()
11 | image_url = fields.Str()
12 | label = fields.Str()
13 | confidence = fields.Float()
14 | user_id = fields.Int(dump_only=True)
15 | classified_at = fields.DateTime()
16 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/comment.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 |
5 | class CommentSchema(ma.ModelSchema):
6 | """
7 | Serializer class for Comments
8 | """
9 |
10 | id = fields.Int(dump_only=True)
11 | body = fields.Str()
12 | issue_id = fields.Int(dump_only=True)
13 | user_id = fields.Int(dump_only=True)
14 | username=fields.Str(dump_only=True)
15 | thumbnail = fields.Str()
16 | timestamp = fields.DateTime(format='%Y-%m-%d %H:%M:%S', dump_only=True)
17 |
18 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/image.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.labeldata import LabelDataSchema
5 |
6 | class ImageSchema(ma.ModelSchema):
7 | """
8 | Serializer class for image
9 | """
10 |
11 | id = fields.Int(dump_only=True)
12 | image_name = fields.Str()
13 | image_url = fields.Str()
14 | height = fields.Int()
15 | width = fields.Int()
16 | labelled = fields.Bool()
17 | project_id = fields.Int(dump_only=True)
18 | labeldata = fields.Nested(LabelDataSchema, many=True)
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/issue.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 |
5 | class IssueSchema(ma.ModelSchema):
6 | """
7 | Serializer class for issue
8 | """
9 |
10 | id = fields.Int(dump_only=True)
11 | title = fields.Str()
12 | description = fields.Str()
13 | project_id = fields.Int(dump_only=True)
14 | created_by = fields.Int(dump_only=True)
15 | assignee_id = fields.Int()
16 | team_id = fields.Int()
17 | category = fields.Str()
18 | priority = fields.Str()
19 | status = fields.Str()
20 | entity_type = fields.Str()
21 | entity_id = fields.Int()
22 | due_date = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
23 | created_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S', dump_only=True)
24 | updated_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
25 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/label.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.labeldata import LabelDataSchema
5 |
6 | class LabelSchema(ma.ModelSchema):
7 | """
8 | Serializer class for label
9 | """
10 |
11 | id = fields.Int(dump_only=True)
12 | label_name = fields.Str()
13 | label_type = fields.Str()
14 | count = fields.Int()
15 | project_id = fields.Int(dump_only=True)
16 | created_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S', dump_only=True)
17 | labeldata = fields.Nested(LabelDataSchema, many=True)
18 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/labeldata.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields, post_dump
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.point import PointSchema
5 |
6 | class LabelDataSchema(ma.ModelSchema):
7 | """
8 | Serializer class for labeldata
9 | """
10 |
11 | id = fields.Str(dump_only=True)
12 | months_passed = fields.Int()
13 | image_id = fields.Int(dump_only=True)
14 | label_id = fields.Int(dump_only=True)
15 | points = fields.Nested(PointSchema, many=True)
16 |
17 | @post_dump(pass_many=True)
18 | def data(self, data, many, **kwargs):
19 | from api.helpers.label import get_label_type
20 | res_data = {}
21 | try:
22 | for i in range(len(data)):
23 | if res_data.get(data[i]['label_id']) is None:
24 | res_data[data[i]['label_id']] = []
25 | label_type = get_label_type(data[i]['label_id'])
26 | data[i]['label_type'] = label_type
27 | res_data[data[i]['label_id']].append(data[i])
28 | return res_data
29 | except Exception as err:
30 | print(err)
31 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/mlclassifier.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.label import LabelSchema
5 |
6 | class MLClassifierSchema(ma.ModelSchema):
7 | """
8 | Serializer class for ML Classifier
9 | """
10 |
11 | id = fields.Int(dump_only=True)
12 | name = fields.Str()
13 | type = fields.Str()
14 | source = fields.Str()
15 | preprocessing_steps_json_url = fields.Str()
16 | layers_json_url = fields.Str()
17 | train = fields.Float()
18 | test = fields.Float()
19 | validation = fields.Float()
20 | epochs = fields.Int()
21 | batch_size = fields.Int()
22 | learning_rate = fields.Float()
23 | loss = fields.Str()
24 | optimizer = fields.Str()
25 | metric = fields.Str()
26 | loss_graph_url = fields.Str()
27 | accuracy_graph_url = fields.Str()
28 | saved_model_url = fields.Str()
29 | transfer_source = fields.Str()
30 | project_id = fields.Int(dump_only=True)
31 | labels = fields.Nested(LabelSchema, many=True)
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/notification.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 |
5 | class NotificationSchema(ma.ModelSchema):
6 | """
7 | Serializer class for Notifications
8 | """
9 | id = fields.Int(dump_only=True)
10 | message = fields.Str()
11 | type = fields.Str()
12 | user_id = fields.Int(dump_only=True)
13 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/point.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 |
5 | class PointSchema(ma.ModelSchema):
6 | """
7 | Serializer class for Point
8 | """
9 |
10 | id = fields.Str(dump_only=True)
11 | lng = fields.Float(attribute="y_coordinate")
12 | lat = fields.Float(attribute="x_coordinate")
13 | labeldata_id = fields.Str(dump_only=True)
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/project.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.image import ImageSchema
5 | from api.serializers.label import LabelSchema
6 | from api.serializers.issue import IssueSchema
7 |
8 | class ProjectSchema(ma.ModelSchema):
9 | """
10 | Serializer class for project
11 | """
12 |
13 | id = fields.Int(dump_only=True)
14 | project_name = fields.Str()
15 | project_description = fields.Str()
16 | admin_id = fields.Int(dump_only=True)
17 | images = fields.Nested(ImageSchema, many=True)
18 | labels = fields.Nested(LabelSchema, many=True)
19 | issues = fields.Nested(IssueSchema, many=True)
20 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/projectmember.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import ma
4 |
5 | class ProjectMemberSchema(ma.ModelSchema):
6 | """
7 | Serializer class for projectmember
8 | """
9 |
10 | user_id = fields.Int(dump_only=True)
11 | team_id = fields.Int(dump_only=True)
12 |
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/team.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import db, ma
4 | from api.serializers.projectmember import ProjectMemberSchema
5 |
6 | class TeamSchema(ma.ModelSchema):
7 | """
8 | Serializer class for team
9 | """
10 |
11 | id = fields.Int(dump_only=True)
12 | team_name = fields.Str()
13 | role = fields.Str()
14 | project_id = fields.Int(dump_only=True)
15 | team_members = fields.Nested(ProjectMemberSchema, many=True)
--------------------------------------------------------------------------------
/labellab-flask/api/serializers/user.py:
--------------------------------------------------------------------------------
1 | from marshmallow import Schema, fields
2 |
3 | from api.extensions import ma
4 | from api.serializers.project import ProjectSchema
5 | from api.serializers.projectmember import ProjectMemberSchema
6 |
7 | class UserSchema(ma.ModelSchema):
8 | """
9 | Serializer class for user
10 | """
11 |
12 | id = fields.Int(dump_only=True)
13 | name = fields.Str()
14 | username = fields.Str()
15 | email = fields.Str()
16 | thumbnail = fields.Str()
17 | projects = fields.Nested(ProjectSchema, many=True)
18 | project_members = fields.Nested(ProjectMemberSchema, many=True)
19 |
--------------------------------------------------------------------------------
/labellab-flask/app.py:
--------------------------------------------------------------------------------
1 | import os
2 | from dotenv import load_dotenv
3 | from flask import render_template
4 |
5 | import sys
6 | sys.path.insert(0,os.getcwd())
7 | dotenv_path = os.path.join(os.path.dirname(__file__), ".env")
8 | if os.path.exists(dotenv_path):
9 | load_dotenv(dotenv_path)
10 |
11 | from api.main import create_app
12 | from api.extensions import socketio
13 |
14 | app = create_app(os.getenv("FLASK_CONFIG") or "default")
15 |
16 | @app.route("/", defaults={"path": ""})
17 | @app.route("/")
18 | def default_route(path):
19 | return render_template('index.html')
20 |
21 | if __name__ == "__main__":
22 | socketio.run(app, host='0.0.0.0', port=5000, debug=True)
23 |
--------------------------------------------------------------------------------
/labellab-flask/app.yaml:
--------------------------------------------------------------------------------
1 | runtime: python37
2 | entrypoint: gunicorn -b :$PORT app:app
--------------------------------------------------------------------------------
/labellab-flask/boot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | exec flask run
--------------------------------------------------------------------------------
/labellab-flask/docker.txt:
--------------------------------------------------------------------------------
1 | -r requirements.txt
--------------------------------------------------------------------------------
/labellab-flask/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/labellab-flask/docs/labellab-flask.rst:
--------------------------------------------------------------------------------
1 | labellab\-flask package
2 | =======================
3 |
4 | Subpackages
5 | -----------
6 |
7 | .. toctree::
8 | :maxdepth: 4
9 |
10 | labellab-flask.api
11 | labellab-flask.tests
12 |
13 | Submodules
14 | ----------
15 |
16 | labellab\-flask.app module
17 | --------------------------
18 |
19 | .. automodule:: labellab-flask.app
20 | :members:
21 | :undoc-members:
22 | :show-inheritance:
23 |
24 | Module contents
25 | ---------------
26 |
27 | .. automodule:: labellab-flask
28 | :members:
29 | :undoc-members:
30 | :show-inheritance:
31 |
--------------------------------------------------------------------------------
/labellab-flask/docs/labellab-flask.tests.rst:
--------------------------------------------------------------------------------
1 | labellab\-flask.tests package
2 | =============================
3 |
4 | Submodules
5 | ----------
6 |
7 | labellab\-flask.tests.test\_login module
8 | ----------------------------------------
9 |
10 | .. automodule:: labellab-flask.tests.test_login
11 | :members:
12 | :undoc-members:
13 | :show-inheritance:
14 |
15 | labellab\-flask.tests.test\_project module
16 | ------------------------------------------
17 |
18 | .. automodule:: labellab-flask.tests.test_project
19 | :members:
20 | :undoc-members:
21 | :show-inheritance:
22 |
23 | labellab\-flask.tests.test\_register module
24 | -------------------------------------------
25 |
26 | .. automodule:: labellab-flask.tests.test_register
27 | :members:
28 | :undoc-members:
29 | :show-inheritance:
30 |
31 | Module contents
32 | ---------------
33 |
34 | .. automodule:: labellab-flask.tests
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
--------------------------------------------------------------------------------
/labellab-flask/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/labellab-flask/docs/modules.rst:
--------------------------------------------------------------------------------
1 | labellab-flask
2 | ==============
3 |
4 | .. toctree::
5 | :maxdepth: 4
6 |
7 | labellab-flask
8 |
--------------------------------------------------------------------------------
/labellab-flask/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. Labellab-Flask documentation master file, created by
2 | sphinx-quickstart on Sat Aug 15 22:57:00 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Labellab-Flask's documentation!
7 | ==========================================
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 | :caption: Contents:
12 |
13 |
14 |
15 | Indices and tables
16 | ==================
17 |
18 | * :ref:`genindex`
19 | * :ref:`modindex`
20 | * :ref:`search`
21 |
--------------------------------------------------------------------------------
/labellab-flask/migrations/README:
--------------------------------------------------------------------------------
1 | Generic single-database configuration.
--------------------------------------------------------------------------------
/labellab-flask/migrations/alembic.ini:
--------------------------------------------------------------------------------
1 | # A generic, single database configuration.
2 |
3 | [alembic]
4 | # template used to generate migration files
5 | # file_template = %%(rev)s_%%(slug)s
6 |
7 | # set to 'true' to run the environment during
8 | # the 'revision' command, regardless of autogenerate
9 | # revision_environment = false
10 |
11 |
12 | # Logging configuration
13 | [loggers]
14 | keys = root,sqlalchemy,alembic
15 |
16 | [handlers]
17 | keys = console
18 |
19 | [formatters]
20 | keys = generic
21 |
22 | [logger_root]
23 | level = WARN
24 | handlers = console
25 | qualname =
26 |
27 | [logger_sqlalchemy]
28 | level = WARN
29 | handlers =
30 | qualname = sqlalchemy.engine
31 |
32 | [logger_alembic]
33 | level = INFO
34 | handlers =
35 | qualname = alembic
36 |
37 | [handler_console]
38 | class = StreamHandler
39 | args = (sys.stderr,)
40 | level = NOTSET
41 | formatter = generic
42 |
43 | [formatter_generic]
44 | format = %(levelname)-5.5s [%(name)s] %(message)s
45 | datefmt = %H:%M:%S
46 |
--------------------------------------------------------------------------------
/labellab-flask/migrations/script.py.mako:
--------------------------------------------------------------------------------
1 | """${message}
2 |
3 | Revision ID: ${up_revision}
4 | Revises: ${down_revision | comma,n}
5 | Create Date: ${create_date}
6 |
7 | """
8 | from alembic import op
9 | import sqlalchemy as sa
10 | ${imports if imports else ""}
11 |
12 | # revision identifiers, used by Alembic.
13 | revision = ${repr(up_revision)}
14 | down_revision = ${repr(down_revision)}
15 | branch_labels = ${repr(branch_labels)}
16 | depends_on = ${repr(depends_on)}
17 |
18 |
19 | def upgrade():
20 | ${upgrades if upgrades else "pass"}
21 |
22 |
23 | def downgrade():
24 | ${downgrades if downgrades else "pass"}
25 |
--------------------------------------------------------------------------------
/labellab-flask/path_tracking/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/path_tracking/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/path_tracking/sample6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/path_tracking/sample6.png
--------------------------------------------------------------------------------
/labellab-flask/pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/ambv/black
3 | rev: stable
4 | hooks:
5 | - id: black
6 | language_version: python3.6
7 | - repo: https://github.com/pre-commit/pre-commit-hooks
8 | rev: v1.2.3
9 | hooks:
10 | - id: flake8
--------------------------------------------------------------------------------
/labellab-flask/prod.txt:
--------------------------------------------------------------------------------
1 | -r requirements.txt
2 | gunicorn==20.0.4
--------------------------------------------------------------------------------
/labellab-flask/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab-flask/tests/__init__.py
--------------------------------------------------------------------------------
/labellab-flask/uploads/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/labellab-server/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | Dockerfile*
4 | docker-compose*
5 | .dockerignore
6 | .git
7 | .gitignore
8 | .env
9 | */bin
10 | */obj
11 | README.md
12 | LICENSE
13 | .vscode
--------------------------------------------------------------------------------
/labellab-server/.env.example:
--------------------------------------------------------------------------------
1 | HOST=
2 | PORT=
3 | JWT_SECRET=
4 | DB_HOST=
5 | DB_NAME=
6 | DB_CLUSTER=
7 | DB_USERNAME=
8 | DB_PASSWORD=
9 | GOOGLE_CLIENT_ID=
10 | GOOGLE_CLIENT_SECRET=
11 | GITHUB_CLIENT_ID=
12 | GITHUB_CLIENT_SECRET=
13 | EMAIL_PASSWORD =
14 | EMAIL_ADDRESS =
15 | REACT_APP_HOST=
--------------------------------------------------------------------------------
/labellab-server/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true,
4 | "browser": true,
5 | "commonjs": true,
6 | "es6": true
7 | },
8 | "extends": "eslint:recommended",
9 | "parserOptions": {
10 | "ecmaVersion": 2018,
11 | "sourceType": "module"
12 | },
13 | "rules": {
14 | "no-unused-vars": ["off", { "vars": "all", "args": "after-used", "ignoreRestSiblings": false }],
15 | "no-console": "off",
16 | "indent": [
17 | "error",
18 | "tab"
19 | ],
20 | "linebreak-style": [
21 | "error",
22 | "unix"
23 | ],
24 | "quotes": [
25 | "error",
26 | "single"
27 | ],
28 | "semi": [
29 | "error",
30 | "never"
31 | ]
32 | }
33 | }
--------------------------------------------------------------------------------
/labellab-server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node
2 |
3 | RUN mkdir -p /usr/labellab/labellab-server
4 | WORKDIR /usr/labellab/labellab-server
5 |
6 | COPY package.json /usr/labellab/labellab-server
7 | RUN npm install
8 | COPY . /usr/labellab/labellab-server
9 | EXPOSE 4000
10 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/labellab-server/config/dbURI.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('dotenv').config()
3 |
4 | var dbHost = process.env.DB_HOST || 'localhost'
5 | var dbName = process.env.DB_NAME
6 | var dbCluster = process.env.DB_CLUSTER
7 | var dbUser = process.env.DB_USERNAME
8 | var dbPass = process.env.DB_PASSWORD
9 |
10 | let mongoURI
11 |
12 | if (dbName && dbUser && dbPass) {
13 | mongoURI =
14 | '' + dbHost + '://' + dbUser + ':' + dbPass + '@' + dbCluster + '/' + dbName
15 | } else if (process.env.MONGODB_URI) {
16 | mongoURI = process.env.MONGODB_URI
17 | } else {
18 | mongoURI = ''
19 | }
20 |
21 | module.exports = {
22 | mongoURI: mongoURI,
23 | }
24 |
--------------------------------------------------------------------------------
/labellab-server/config/jwtSecret.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('dotenv').config()
3 |
4 | var jwtSecret = process.env.JWT_SECRET
5 |
6 | if(!jwtSecret){
7 | jwtSecret = 'JWTSECRET'
8 | }
9 |
10 | module.exports = {
11 | jwtSecret:jwtSecret
12 | }
--------------------------------------------------------------------------------
/labellab-server/controller/auth/oauth.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('dotenv').config()
3 |
4 | const jwt = require('jwt-simple')
5 | const secret = require('../../config/jwtSecret').jwtSecret
6 |
7 | function createtoken(user) {
8 | const timestamp = new Date().getTime()
9 | return jwt.encode({ sub: user.id, iat: timestamp }, secret)
10 | }
11 |
12 | module.exports.signin = function signin(req, res, next) {
13 | res.render('authenticated.ejs', { token: createtoken(req.user) })
14 | }
15 |
--------------------------------------------------------------------------------
/labellab-server/models/classification.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const ClassificationSchema = new mongoose.Schema({
4 | user: {
5 | type: mongoose.Schema.Types.ObjectId,
6 | ref: 'User'
7 | },
8 | imageUrl: {
9 | type: String,
10 | required: true
11 | },
12 | label: [
13 | {
14 | type: Object
15 | }
16 | ],
17 | createdAt: {
18 | type: Date,
19 | default: Date.now
20 | }
21 | })
22 |
23 | module.exports = mongoose.model('Classification', ClassificationSchema)
24 |
--------------------------------------------------------------------------------
/labellab-server/models/image.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const ImageSchema = new mongoose.Schema({
4 | project: {
5 | type: mongoose.Schema.Types.ObjectId,
6 | ref: 'Project'
7 | },
8 | imageName: {
9 | type: String,
10 | required: true
11 | },
12 | imageUrl: {
13 | type: String,
14 | required: true
15 | },
16 | labelData: {
17 | type: Object
18 | },
19 | height: {
20 | type: Number
21 | },
22 | width: {
23 | type: Number
24 | },
25 | labelled: {
26 | type: Boolean,
27 | default: false
28 | },
29 | createdAt: {
30 | type: Date,
31 | default: Date.now
32 | }
33 | })
34 |
35 | module.exports = mongoose.model('Image', ImageSchema)
36 |
--------------------------------------------------------------------------------
/labellab-server/models/label.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | var LabelSchema = new mongoose.Schema({
4 | project: {
5 | type: mongoose.Schema.Types.ObjectId,
6 | ref: 'Project'
7 | },
8 | id: {
9 | type: String,
10 | unique: true
11 | },
12 | name: {
13 | type: String
14 | },
15 | type: {
16 | type: String
17 | },
18 | createdAt: {
19 | type: Date,
20 | default: Date.now
21 | },
22 | count: {
23 | type: Number,
24 | required: false,
25 | default: 0
26 | }
27 | })
28 |
29 | module.exports = mongoose.model('Label', LabelSchema)
30 |
--------------------------------------------------------------------------------
/labellab-server/models/project.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const ProjectSchema = new mongoose.Schema({
4 | user: {
5 | type: mongoose.Schema.Types.ObjectId,
6 | ref: 'User'
7 | },
8 | projectName: {
9 | type: String,
10 | required: true
11 | },
12 | projectDescription: {
13 | type: String,
14 | default: 'Image labelling'
15 | },
16 | createdAt: {
17 | type: Date,
18 | default: Date.now
19 | },
20 | image: [
21 | {
22 | type: mongoose.Schema.Types.ObjectId,
23 | ref: 'Image'
24 | }
25 | ],
26 | members: [
27 | {
28 | type: mongoose.Schema.Types.ObjectId,
29 | ref: 'ProjectMembers'
30 | }
31 | ],
32 | labels: [
33 | {
34 | type: mongoose.Schema.Types.ObjectId,
35 | ref: 'Label'
36 | }
37 | ]
38 | })
39 |
40 | module.exports = mongoose.model('Project', ProjectSchema)
41 |
--------------------------------------------------------------------------------
/labellab-server/models/projectMembers.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const ProjectMembersSchema = new mongoose.Schema({
4 | member: {
5 | type: mongoose.Schema.Types.ObjectId,
6 | ref: 'User'
7 | },
8 | projectId: {
9 | type: mongoose.Schema.Types.ObjectId,
10 | ref: 'Project'
11 | },
12 | createdAt: {
13 | type: Date,
14 | default: Date.now
15 | },
16 | role: {
17 | type: String,
18 | default: 'Member'
19 | }
20 | })
21 |
22 | module.exports = mongoose.model('ProjectMembers', ProjectMembersSchema)
23 |
--------------------------------------------------------------------------------
/labellab-server/public/classifications/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/labellab-server/public/img/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/labellab-server/public/project/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/labellab-server/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/labellab-server/public/uploads/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/labellab-server/routes/analytics/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var passport = require('passport')
3 | const router = express.Router()
4 | const requireAuth = passport.authenticate('jwt', { session: false })
5 |
6 | // Include controllers of each route
7 | const analyticsControls = require('../../controller/analytics/analyticsControls')
8 |
9 | // GET method
10 | // To fetch time-label dataset of a project
11 | router.get(
12 | '/:projectId/timeLabel/get',
13 | requireAuth,
14 | analyticsControls.timeLabel
15 | )
16 |
17 | // GET method
18 | // To fetch counts of how often a label is used in a project
19 | router.get(
20 | '/:projectId/labelCount/get',
21 | requireAuth,
22 | analyticsControls.countLabel
23 | )
24 |
25 | module.exports = router
26 |
--------------------------------------------------------------------------------
/labellab-server/routes/classification/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var passport = require('passport')
3 | const router = express.Router()
4 | const requireAuth = passport.authenticate('jwt', { session: false })
5 |
6 | // Include controllers of each route
7 | const classificationControls = require('../../controller/classification/classificationControls')
8 |
9 | // POST method
10 | // To process a new classification
11 | router.post('/classify', requireAuth, classificationControls.classify)
12 |
13 | // GET method
14 | // To fetch all classification of the user
15 | router.get('/get', requireAuth, classificationControls.fetchClassification)
16 |
17 | // GET method
18 | // To fetch a classification
19 | router.get('/get/:classificationId', requireAuth, classificationControls.fetchClassificationId)
20 |
21 | // DELETE method
22 | // To delete a classification
23 | router.delete('/delete/:classificationId', requireAuth, classificationControls.deleteClassificationId)
24 |
25 | module.exports = router
26 |
--------------------------------------------------------------------------------
/labellab-server/routes/image/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var passport = require('passport')
3 | const router = express.Router()
4 | const requireAuth = passport.authenticate('jwt', { session: false })
5 |
6 | // Include controllers of each route
7 | const imageControls = require('../../controller/image/imageControls')
8 |
9 | // POST method
10 | // To post image of a project
11 | router.post('/:projectId/create', requireAuth, imageControls.postImage)
12 |
13 | // GET method
14 | // To fetch a image
15 | router.get('/:imageId/get', requireAuth, imageControls.fetchImageId)
16 |
17 | // PUT method
18 | // To update labelData details
19 | router.put('/:imageId/update', requireAuth, imageControls.updateLabels)
20 |
21 | // DELETE method
22 | // To delete image
23 | router.delete('/delete', requireAuth, imageControls.deleteImage)
24 |
25 | module.exports = router
26 |
--------------------------------------------------------------------------------
/labellab-server/routes/label/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var passport = require('passport')
3 | const router = express.Router()
4 | const requireAuth = passport.authenticate('jwt', { session: false })
5 |
6 | // Include controllers of each route
7 | const labelControls = require('../../controller/label/labelControls')
8 |
9 | // POST method
10 | // To post label of a project
11 | router.post('/:projectId/create', requireAuth, labelControls.createLabel)
12 |
13 | // PUT method
14 | // To update label of a project
15 | router.put('/:labelId/update', requireAuth, labelControls.updateLabel)
16 |
17 | // GET method
18 | // To fetch labels of a project
19 | router.get('/:projectId/get', requireAuth, labelControls.fetchLabel)
20 |
21 | // DELETE method
22 | // To delete labels of a project
23 | router.delete('/:labelId/delete', requireAuth, labelControls.deleteLabel)
24 |
25 | module.exports = router
26 |
--------------------------------------------------------------------------------
/labellab-server/routes/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var router = express.Router()
3 |
4 | // API's path
5 | var authRoute = require('./auth/routes')
6 | var usersRoute = require('./users/routes')
7 | var projectRoute = require('./project/routes')
8 | var imageRoutes = require('./image/routes')
9 | var labelRoutes = require('./label/routes')
10 | var analyticsRoutes = require('./analytics/routes')
11 | var classificationRoutes = require('./classification/routes')
12 |
13 | // Routes
14 | // -> /api/auth/
15 | router.use('/api/v1/auth', authRoute)
16 | router.use('/api/v1/users', usersRoute)
17 | router.use('/api/v1/project', projectRoute)
18 | router.use('/api/v1/image', imageRoutes)
19 | router.use('/api/v1/label', labelRoutes)
20 | router.use('/api/v1/analytics', analyticsRoutes)
21 | router.use('/api/v1/classification', classificationRoutes)
22 |
23 | module.exports = router
24 |
--------------------------------------------------------------------------------
/labellab-server/routes/users/routes.js:
--------------------------------------------------------------------------------
1 | var express = require('express')
2 | var passport = require('passport')
3 | const router = express.Router()
4 | const requireAuth = passport.authenticate('jwt', { session: false })
5 |
6 | // Include controllers of each route
7 | const userControls = require('../../controller/user/userControls')
8 |
9 | // GET method
10 | // To fetch user information
11 | router.get('/info', requireAuth, userControls.userInfo)
12 |
13 | // PUT method
14 | // To fetch user information
15 | router.put('/edit', requireAuth, userControls.editInfo)
16 |
17 | // GET method
18 | // To fetch user information of a given user
19 | router.get('/search/:query', requireAuth, userControls.searchUser)
20 |
21 | // GET method
22 | // To fetch user info count
23 | router.get('/fetchCount', requireAuth, userControls.countInfo)
24 |
25 | // POST method
26 | // To upload user image
27 | router.post('/uploadImage', requireAuth, userControls.userUploadImage)
28 |
29 | module.exports = router
30 |
--------------------------------------------------------------------------------
/labellab-server/utils/color.js:
--------------------------------------------------------------------------------
1 | const colorData = [
2 | 'rgba(255, 99, 132, 0.6)',
3 | 'rgba(54, 162, 235, 0.6)',
4 | 'rgba(255, 206, 86, 0.6)',
5 | 'rgba(75, 192, 192, 0.6)',
6 | 'rgba(153, 102, 255, 0.6)',
7 | 'rgba(255, 159, 64, 0.6)',
8 | 'rgba(255, 99, 110, 0.6)',
9 | 'rgba(54, 150, 200, 0.6)',
10 | 'rgba(255, 150, 255, 0.6)',
11 | 'rgba(75, 255, 255, 0.6)',
12 | 'rgba(255, 102, 255, 0.6)',
13 | 'rgba(255, 50, 200, 0.6)',
14 | 'rgba(255, 255, 132, 0.6)'
15 | ]
16 |
17 | exports.getColor = function(num) {
18 | let final = []
19 | for (let i = 1; i <= num; i++) {
20 | final.push(colorData[i % colorData.length])
21 | }
22 | return final
23 | }
24 |
--------------------------------------------------------------------------------
/labellab-server/utils/error.js:
--------------------------------------------------------------------------------
1 | const handleError = (err, res) => {
2 | const { statusCode, message } = err;
3 | res.status(statusCode).json({
4 | status: "error",
5 | statusCode,
6 | message
7 | });
8 | };
9 |
10 | module.exports = {
11 | handleError
12 | }
--------------------------------------------------------------------------------
/labellab-server/utils/labelData.js:
--------------------------------------------------------------------------------
1 | const monthData = [
2 | 'January',
3 | 'February',
4 | 'March',
5 | 'April',
6 | 'May',
7 | 'June',
8 | 'July',
9 | 'August',
10 | 'September',
11 | 'October',
12 | 'November',
13 | 'December'
14 | ]
15 | exports.getLabelData = function(labelData) {
16 | let final = []
17 | for (let i = 0; i < 6; i++) {
18 | final.push(0)
19 | }
20 | let currentDate = new Date()
21 | let currentMonth = currentDate.getMonth()
22 |
23 | for (let i = 0; i < labelData.length; i++) {
24 | final[currentMonth - labelData[i]]++
25 | }
26 |
27 | return final
28 | }
29 |
30 | exports.getLabelCounts = function(labels) {
31 | let countData = {
32 | labels: [],
33 | datasets: [
34 | {
35 | data: [],
36 | backgroundColor: [],
37 | hoverBackgroundColor: []
38 | }
39 | ]
40 | }
41 | labels.forEach(label => {
42 | countData.labels.push(label.name)
43 | label.count
44 | ? countData.datasets[0].data.push(label.count)
45 | : countData.datasets[0].data.push(0)
46 | countData.datasets[0].backgroundColor.push(
47 | '#' + ((Math.random() * 0xffffff) << 0).toString(16)
48 | )
49 | })
50 |
51 | return countData
52 | }
53 |
--------------------------------------------------------------------------------
/labellab-server/utils/months.js:
--------------------------------------------------------------------------------
1 | const monthData = [
2 | 'January',
3 | 'February',
4 | 'March',
5 | 'April',
6 | 'May',
7 | 'June',
8 | 'July',
9 | 'August',
10 | 'September',
11 | 'October',
12 | 'November',
13 | 'December'
14 | ]
15 | exports.getMonths = function(num) {
16 | let final = []
17 | let currentDate = new Date()
18 | let currentMonth = currentDate.getMonth()
19 |
20 | for (
21 | let i = monthData.length + currentMonth;
22 | i > monthData.length + currentMonth - num;
23 | i--
24 | ) {
25 | final.push(monthData[i % monthData.length])
26 | }
27 |
28 | return final
29 | }
30 |
--------------------------------------------------------------------------------
/labellab-server/utils/randomString.js:
--------------------------------------------------------------------------------
1 | exports.makeid = function(length) {
2 | var result = ''
3 | var characters =
4 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
5 | var charactersLength = characters.length
6 | for (var i = 0; i < length; i++) {
7 | result += characters.charAt(Math.floor(Math.random() * charactersLength))
8 | }
9 | return result
10 | }
11 |
--------------------------------------------------------------------------------
/labellab-server/views/authenticated.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Authenticated
5 |
6 |
7 | Authenticated successfully.
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/labellab-server/views/error.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Something went wrong!
6 |
7 |
8 |
--------------------------------------------------------------------------------
/labellab_mobile/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/labellab_mobile/README.md:
--------------------------------------------------------------------------------
1 | # LabelLab Mobile App
2 |
3 | ### Mobile client for LabelLab, built using [Flutter](https://flutter.dev/)
4 |
5 |
6 |
7 |
12 |
13 |
14 |
15 | ## Guide
16 |
17 | - Please follow these [instructions](https://github.com/scorelab/LabelLab/wiki/Mobile-Development-Setup) to setup the mobile application on your local system or build an APK.
18 |
19 | - To learn more about the application, check out the [Mobile Wiki](https://github.com/scorelab/LabelLab/wiki/Mobile-Screenshots)
20 |
--------------------------------------------------------------------------------
/labellab_mobile/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/labellab_mobile/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/kotlin/org/scorelab/labellab_mobile/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.scorelab.labellab_mobile
2 |
3 |
4 | import io.flutter.embedding.android.FlutterActivity
5 |
6 |
7 | class MainActivity: FlutterActivity() {
8 | }
9 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | -
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/drawable/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/drawable/splash.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/labellab_mobile/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/labellab_mobile/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.1.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | classpath 'com.google.gms:google-services:4.3.10'
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | google()
18 | jcenter()
19 | }
20 | }
21 |
22 | rootProject.buildDir = '../build'
23 | subprojects {
24 | project.buildDir = "${rootProject.buildDir}/${project.name}"
25 | }
26 | subprojects {
27 | project.evaluationDependsOn(':app')
28 | }
29 |
30 | task clean(type: Delete) {
31 | delete rootProject.buildDir
32 | }
33 |
--------------------------------------------------------------------------------
/labellab_mobile/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableJetifier=true
3 | android.useAndroidX=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/labellab_mobile/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https://services.gradle.org/distributions/gradle-7.4-all.zip
7 |
--------------------------------------------------------------------------------
/labellab_mobile/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/labellab_mobile/assets/images/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/assets/images/splash.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scorelab/LabelLab/080a7cc7fa5a32b042535b1e1214b60bf5881501/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/labellab_mobile/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/labellab_mobile/lib/data/interceptor/token_interceptor.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:labellab_mobile/data/repository.dart';
3 |
4 | class RetryOnAuthFailInterceptor extends Interceptor {
5 | Dio? _dio;
6 | RetryOnAuthFailInterceptor(this._dio);
7 |
8 | @override
9 | Future onError(DioError err, ErrorInterceptorHandler handler) async {
10 | if (err.response != null && err.response!.statusCode == 401) {
11 | _dio!.interceptors.requestLock.lock();
12 | _dio!.interceptors.responseLock.lock();
13 |
14 | Repository().refreshToken();
15 |
16 | _dio!.interceptors.requestLock.unlock();
17 | _dio!.interceptors.responseLock.unlock();
18 |
19 | return handler.resolve(err.response!);
20 | }
21 |
22 | return handler.next(err);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/labellab_mobile/lib/data/local/entities/classification_entity.dart:
--------------------------------------------------------------------------------
1 | import 'package:labellab_mobile/model/classification.dart';
2 |
3 | class ClassificationEntity extends Classification {
4 | static const String table = 'classification';
5 | static const String columnId = '_id';
6 | static const String columnImageURL = 'image_url';
7 |
8 | ClassificationEntity.from(Classification classification) {
9 | this.id = classification.id;
10 | this.imageUrl = classification.imageUrl;
11 | }
12 |
13 | ClassificationEntity.fromMap(Map map) {
14 | id = map[columnId];
15 | imageUrl = map[columnImageURL];
16 | }
17 |
18 | Map toMap() {
19 | var map = {
20 | "image_url": imageUrl,
21 | };
22 | if (id != null) {
23 | map[columnId] = id;
24 | }
25 | return map;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/labellab_mobile/lib/data/local/entities/issue_entity.dart:
--------------------------------------------------------------------------------
1 | import 'package:labellab_mobile/model/issue.dart';
2 |
3 | class IssueEntity extends Issue {
4 | static const String table = 'issue';
5 | static const String columnId = '_id';
6 | static const String columnName = 'issue_title';
7 | static const String columnDescription = 'description';
8 |
9 | IssueEntity.from(Issue issue) {
10 | this.id = issue.id;
11 | this.issueTitle = issue.issueTitle;
12 | this.description = issue.description;
13 | }
14 |
15 | IssueEntity.fromMap(Map map) {
16 | id = map[columnId];
17 | issueTitle = map[columnName];
18 | description = map[columnDescription];
19 | }
20 |
21 | Map toMap() {
22 | var map = {columnName: issueTitle};
23 | if (id != null) {
24 | map[columnId] = id;
25 | }
26 | if (description != null) {
27 | map[columnDescription] = description;
28 | }
29 | return map;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/labellab_mobile/lib/data/local/entities/project_entity.dart:
--------------------------------------------------------------------------------
1 | import 'package:labellab_mobile/model/project.dart';
2 |
3 | class ProjectEntity extends Project {
4 | static const String table = 'project';
5 | static const String columnId = '_id';
6 | static const String columnName = 'name';
7 | static const String columnDescription = 'description';
8 |
9 | ProjectEntity.from(Project project) {
10 | this.id = project.id;
11 | this.name = project.name;
12 | this.description = project.description;
13 | }
14 |
15 | ProjectEntity.fromMap(Map map) {
16 | id = map[columnId];
17 | name = map[columnName];
18 | description = map[columnDescription];
19 | }
20 |
21 | Map toMap() {
22 | var map = {columnName: name};
23 | if (id != null) {
24 | map[columnId] = id;
25 | }
26 | if (description != null) {
27 | map[columnDescription] = description;
28 | }
29 | return map;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/labellab_mobile/lib/data/local/issue_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:labellab_mobile/model/issue.dart';
2 | import 'package:sqflite/sqflite.dart';
3 |
4 | import 'entities/issue_entity.dart';
5 |
6 | class IssueProvider {
7 | static const String _path = "labellab/issue";
8 |
9 | late Database db;
10 |
11 | Future open() async {
12 | db = await openDatabase(_path, version: 1,
13 | onCreate: (Database db, int version) async {
14 | await db.execute('''
15 | create table ${IssueEntity.table} (
16 | ${IssueEntity.columnId} text primary key,
17 | ${IssueEntity.columnDescription} text,
18 | ${IssueEntity.columnName} text not null)
19 | ''');
20 | });
21 | }
22 |
23 |
24 | Future?> getIssues() async {
25 | List