Merge branch 'master' of /media/data_1/www/gogs/gogs-repositories/michigg/ofu-app

Conflicts:
	ofu_app/apps/events/utils/json_generator/jsons/events-fekide.json
	ofu_app/apps/food/utils/json_generator/jsons/cafete-erba.json
	ofu_app/apps/food/utils/json_generator/jsons/cafete-markus.json
	ofu_app/apps/food/utils/json_generator/jsons/mensa-austr.json
	ofu_app/apps/food/utils/json_generator/jsons/mensa-feki.json
This commit is contained in:
michigg 2017-10-25 00:29:05 +02:00
commit 0d452ec820
260 changed files with 51254 additions and 1450 deletions

View File

@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="useProjectProfile" value="false" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.5.3 (/usr/bin/python3.5)" project-jdk-type="Python SDK" />
</project>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ofu_app.iml" filepath="$PROJECT_DIR$/.idea/ofu_app.iml" />
</modules>
</component>
</project>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="ofu_app/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

View File

@ -1,987 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="f783ff92-97a9-4cab-8b91-b76bd998ba56" name="Default" comment="" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="CoverageDataManager">
<SUITE FILE_PATH="coverage/ofu_app$controller_json_food.coverage" NAME="controller-json-food Coverage Results" MODIFIED="1506703105217" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors/food/json_generator" />
<SUITE FILE_PATH="coverage/ofu_app$fekide_eventpage_parser.coverage" NAME="fekide-eventpage-parser Coverage Results" MODIFIED="1506732818806" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors/events/parser" />
<SUITE FILE_PATH="coverage/ofu_app$migrate_data__1_.coverage" NAME="migrate-data (1) Coverage Results" MODIFIED="1506734928822" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors/events" />
<SUITE FILE_PATH="coverage/ofu_app$collect_and_migrate.coverage" NAME="collect_and_migrate Coverage Results" MODIFIED="1506956141616" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors" />
<SUITE FILE_PATH="coverage/ofu_app$migrate_data.coverage" NAME="migrate-data Coverage Results" MODIFIED="1506814046322" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors/food" />
<SUITE FILE_PATH="coverage/ofu_app$controller_json_events.coverage" NAME="controller-json-events Coverage Results" MODIFIED="1506733064332" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/data_collectors/events/json_generator" />
<SUITE FILE_PATH="coverage/ofu_app$mensa_page_parser.coverage" NAME="mensa_page_parser Coverage Results" MODIFIED="1506961724724" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/apps/food/utils/parser" />
</component>
<component name="DjangoConsoleOptions" custom-start-script="import sys; print('Python %s on %s' % (sys.version, sys.platform))&#10;import django; print('Django %s' % django.get_version())&#10;sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;if 'setup' in dir(django): django.setup()&#10;import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)">
<option name="myCustomStartScript" value="import sys; print('Python %s on %s' % (sys.version, sys.platform))&#10;import django; print('Django %s' % django.get_version())&#10;sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;if 'setup' in dir(django): django.setup()&#10;import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="views.py" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/apps/food/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="160">
<caret line="12" column="58" lean-forward="false" selection-start-line="12" selection-start-column="58" selection-end-line="12" selection-end-column="58" />
<folding>
<element signature="e#24#63#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="models.py" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="356">
<caret line="39" column="43" lean-forward="false" selection-start-line="39" selection-start-column="43" selection-end-line="39" selection-end-column="43" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="daily_food.jinja" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/templates/food/daily_food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="8" lean-forward="false" selection-start-line="4" selection-start-column="3" selection-end-line="4" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>PIP</find>
</findStrings>
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/data_collectors/food/json/controller-json-food.py" />
<option value="$PROJECT_DIR$/data_collectors/food/parser/mensa-page-parser.py" />
<option value="$PROJECT_DIR$/templates/food/daily-food.jinja" />
<option value="$PROJECT_DIR$/food/urls.py" />
<option value="$PROJECT_DIR$/data_collectors/events/parser/fekide-eventpage-parser.py" />
<option value="$PROJECT_DIR$/food/models.py" />
<option value="$PROJECT_DIR$/events/models.py" />
<option value="$PROJECT_DIR$/events/urls.py" />
<option value="$PROJECT_DIR$/ofu_app/urls.py" />
<option value="$PROJECT_DIR$/events/views.py" />
<option value="$PROJECT_DIR$/food/views.py" />
<option value="$PROJECT_DIR$/templates/base.jinja" />
<option value="$PROJECT_DIR$/templates/events/week_events.jinja" />
<option value="$PROJECT_DIR$/templates/food/daily_food.jinja" />
<option value="$PROJECT_DIR$/templates/food/food.jinja" />
<option value="$PROJECT_DIR$/data_collectors/food/migrate-data.py" />
<option value="$PROJECT_DIR$/data_collectors/events/migrate-data.py" />
<option value="$PROJECT_DIR$/apps/events/views.py" />
<option value="$PROJECT_DIR$/data_collectors/events/json_generator/controller-json-events.py" />
<option value="$PROJECT_DIR$/data_collectors/food/json_generator/controller-json-food.py" />
<option value="$PROJECT_DIR$/data_collectors/collect_and_migrate.py" />
<option value="$PROJECT_DIR$/apps/food/management/commands/import.py" />
<option value="$PROJECT_DIR$/data_collectors/events/migrate_data.py" />
<option value="$PROJECT_DIR$/apps/events/management/commands/import.py" />
<option value="$PROJECT_DIR$/apps/events/utils/json_generator/controller_json_events.py" />
<option value="$PROJECT_DIR$/apps/food/utils/json_generator/controller_json_food.py" />
<option value="$PROJECT_DIR$/apps/food/utils/parser/mensa_page_parser.py" />
<option value="$PROJECT_DIR$/apps/food/utils/migrate_data.py" />
<option value="$PROJECT_DIR$/apps/events/admin.py" />
<option value="$PROJECT_DIR$/ofu_app/settings.py" />
<option value="$PROJECT_DIR$/apps/food/admin.py" />
<option value="$PROJECT_DIR$/apps/food/views.py" />
<option value="$PROJECT_DIR$/apps/food/models.py" />
</list>
</option>
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="ProjectFrameBounds">
<option name="y" value="27" />
<option name="width" value="1920" />
<option name="height" value="1053" />
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
<manualOrder />
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scratches" />
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="ofu_app" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="ofu_app" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="ofu_app" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="ofu_app" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="apps" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/apps/events" />
<recent name="$PROJECT_DIR$/data_collectors/events/parser" />
<recent name="$PROJECT_DIR$/food/static" />
<recent name="$PROJECT_DIR$/data_collectors/food/parser" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/apps/events/utils" />
<recent name="$PROJECT_DIR$/apps/food/utils" />
<recent name="$PROJECT_DIR$/apps/food" />
<recent name="$PROJECT_DIR$/apps/food/management/utils" />
<recent name="$PROJECT_DIR$/apps" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.mensa_page_parser">
<configuration default="false" name="migrate-data" type="PythonConfigurationType" factoryName="Python" activateToolWindowBeforeRun="false" temporary="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/data_collectors/food" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/apps/food/utils/migrate_data.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="false" name="controller-json-events" type="PythonConfigurationType" factoryName="Python" temporary="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/data_collectors/events/json_generator" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/data_collectors/events/json_generator/controller_json_events.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="false" name="migrate-data (1)" type="PythonConfigurationType" factoryName="Python" temporary="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/data_collectors/events" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/apps/events/utils/migrate_data.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="false" name="collect_and_migrate" type="PythonConfigurationType" factoryName="Python" temporary="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/data_collectors" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/data_collectors/collect_and_migrate.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="false" name="mensa_page_parser" type="PythonConfigurationType" factoryName="Python" temporary="true">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/apps/food/utils/parser" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/apps/food/utils/parser/mensa_page_parser.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="true" type="DjangoTestsConfigurationType" factoryName="Django tests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="TARGET" value="" />
<option name="SETTINGS_FILE" value="" />
<option name="CUSTOM_SETTINGS" value="false" />
<option name="USE_OPTIONS" value="false" />
<option name="OPTIONS" value="" />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerJest" factoryName="Jest">
<node-interpreter value="project" />
<working-dir value="" />
<envs />
<scope-kind value="ALL" />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerProtractor" factoryName="Protractor">
<config-file value="" />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
<method />
</configuration>
<configuration default="true" type="PyBehaveRunConfigurationType" factoryName="Behave">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="ADDITIONAL_ARGS" value="" />
<method />
</configuration>
<configuration default="true" type="PyLettuceRunConfigurationType" factoryName="Lettuce">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="ADDITIONAL_ARGS" value="" />
<method />
</configuration>
<configuration default="true" type="Python.DjangoServer" factoryName="Django server">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<option name="launchJavascriptDebuger" value="false" />
<option name="port" value="8000" />
<option name="host" value="" />
<option name="additionalOptions" value="" />
<option name="browserUrl" value="" />
<option name="runTestServer" value="false" />
<option name="runNoReload" value="false" />
<option name="useCustomRunCommand" value="false" />
<option name="customRunCommand" value="" />
<method />
</configuration>
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="/usr/bin/python3.5" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<method />
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<module name="ofu_app" />
<method />
</configuration>
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
<node-interpreter>project</node-interpreter>
<node-options />
<gulpfile />
<tasks />
<arguments />
<envs />
<method />
</configuration>
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
<command value="run" />
<scripts />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="tests" factoryName="Doctests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="SCRIPT_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="FOLDER_NAME" value="" />
<option name="TEST_TYPE" value="TEST_SCRIPT" />
<option name="PATTERN" value="" />
<option name="USE_PATTERN" value="false" />
<method />
</configuration>
<configuration default="true" type="tests" factoryName="Unittests">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;.&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method />
</configuration>
<configuration default="false" name="ofu_app" type="Python.DjangoServer" factoryName="Django server">
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<module name="ofu_app" />
<option name="launchJavascriptDebuger" value="false" />
<option name="port" value="8000" />
<option name="host" value="" />
<option name="additionalOptions" value="" />
<option name="browserUrl" value="" />
<option name="runTestServer" value="false" />
<option name="runNoReload" value="false" />
<option name="useCustomRunCommand" value="false" />
<option name="customRunCommand" value="" />
<method />
</configuration>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="Django server.ofu_app" />
<item index="1" class="java.lang.String" itemvalue="Python.migrate-data" />
<item index="2" class="java.lang.String" itemvalue="Python.controller-json-events" />
<item index="3" class="java.lang.String" itemvalue="Python.migrate-data (1)" />
<item index="4" class="java.lang.String" itemvalue="Python.collect_and_migrate" />
<item index="5" class="java.lang.String" itemvalue="Python.mensa_page_parser" />
</list>
<recent_temporary>
<list size="5">
<item index="0" class="java.lang.String" itemvalue="Python.mensa_page_parser" />
<item index="1" class="java.lang.String" itemvalue="Python.collect_and_migrate" />
<item index="2" class="java.lang.String" itemvalue="Python.migrate-data" />
<item index="3" class="java.lang.String" itemvalue="Python.migrate-data (1)" />
<item index="4" class="java.lang.String" itemvalue="Python.controller-json-events" />
</list>
</recent_temporary>
</component>
<component name="ShelveChangesManager" show_recycled="false">
<option name="remove_strategy" value="false" />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f783ff92-97a9-4cab-8b91-b76bd998ba56" name="Default" comment="" />
<created>1506687652024</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1506687652024</updated>
</task>
<servers />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="0" y="27" width="1920" height="1053" extended-state="7" />
<layout>
<window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.26602563" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32896176" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32896176" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Data View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32896176" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="processedProjectFiles" value="true" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<option name="time" value="4" />
</breakpoint-manager>
<watches-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/templates/food/food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="3" column="11" lean-forward="false" selection-start-line="3" selection-start-column="11" selection-end-line="3" selection-end-column="11" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/data_collectors/collect_and_migrate.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="100">
<caret line="5" column="72" lean-forward="true" selection-start-line="5" selection-start-column="72" selection-end-line="5" selection-end-column="72" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2980">
<caret line="149" column="18" lean-forward="false" selection-start-line="149" selection-start-column="18" selection-end-line="149" selection-end-column="18" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="200">
<caret line="12" column="12" lean-forward="false" selection-start-line="12" selection-start-column="4" selection-end-line="12" selection-end-column="12" />
<folding>
<element signature="e#24#63#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="3" column="11" lean-forward="false" selection-start-line="3" selection-start-column="11" selection-end-line="3" selection-end-column="11" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/events/week_events.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="11" lean-forward="false" selection-start-line="4" selection-start-column="11" selection-end-line="4" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/base.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="460">
<caret line="23" column="24" lean-forward="false" selection-start-line="23" selection-start-column="17" selection-end-line="23" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="120">
<caret line="13" column="35" lean-forward="false" selection-start-line="13" selection-start-column="35" selection-end-line="13" selection-end-column="35" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/daily_food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="8" lean-forward="false" selection-start-line="4" selection-start-column="3" selection-end-line="4" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2980">
<caret line="149" column="18" lean-forward="false" selection-start-line="149" selection-start-column="18" selection-end-line="149" selection-end-column="18" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="200">
<caret line="12" column="12" lean-forward="false" selection-start-line="12" selection-start-column="4" selection-end-line="12" selection-end-column="12" />
<folding>
<element signature="e#24#63#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="3" column="11" lean-forward="false" selection-start-line="3" selection-start-column="11" selection-end-line="3" selection-end-column="11" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/events/week_events.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="11" lean-forward="false" selection-start-line="4" selection-start-column="11" selection-end-line="4" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/base.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="460">
<caret line="23" column="24" lean-forward="false" selection-start-line="23" selection-start-column="17" selection-end-line="23" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="120">
<caret line="13" column="35" lean-forward="false" selection-start-line="13" selection-start-column="35" selection-end-line="13" selection-end-column="35" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/daily_food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="8" lean-forward="false" selection-start-line="4" selection-start-column="3" selection-end-line="4" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="780">
<caret line="39" column="9" lean-forward="false" selection-start-line="39" selection-start-column="9" selection-end-line="39" selection-end-column="9" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="480">
<caret line="24" column="69" lean-forward="false" selection-start-line="24" selection-start-column="69" selection-end-line="24" selection-end-column="69" />
<folding>
<element signature="e#24#63#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/migrate_data.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="20">
<caret line="1" column="24" lean-forward="true" selection-start-line="1" selection-start-column="24" selection-end-line="1" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/parser/cafete_page_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="460">
<caret line="23" column="4" lean-forward="false" selection-start-line="23" selection-start-column="4" selection-end-line="23" selection-end-column="4" />
<folding>
<element signature="e#24#63#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/food/static/bootstrap-4.0.0-beta-dist/js/bootstrap.js" />
<entry file="file://$PROJECT_DIR$/apps/events/utils/parser/univis_json_prettifier.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="296">
<caret line="136" column="29" lean-forward="false" selection-start-line="136" selection-start-column="20" selection-end-line="136" selection-end-column="29" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/utils/parser/fekide_eventpage_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1136">
<caret line="71" column="2" lean-forward="false" selection-start-line="71" selection-start-column="2" selection-end-line="71" selection-end-column="2" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="260">
<caret line="13" column="12" lean-forward="false" selection-start-line="13" selection-start-column="4" selection-end-line="13" selection-end-column="12" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="478">
<caret line="24" column="0" lean-forward="true" selection-start-line="0" selection-start-column="0" selection-end-line="24" selection-end-column="0" />
<folding>
<element signature="e#641#673#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="440">
<caret line="23" column="17" lean-forward="false" selection-start-line="23" selection-start-column="17" selection-end-line="23" selection-end-column="17" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="436">
<caret line="22" column="0" lean-forward="true" selection-start-line="22" selection-start-column="0" selection-end-line="22" selection-end-column="0" />
<folding>
<element signature="e#641#673#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/parser/cafete_page_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="33" column="28" lean-forward="false" selection-start-line="33" selection-start-column="25" selection-end-line="33" selection-end-column="28" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/events/week_events.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="11" lean-forward="false" selection-start-line="4" selection-start-column="11" selection-end-line="4" selection-end-column="11" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/base.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="460">
<caret line="23" column="24" lean-forward="false" selection-start-line="23" selection-start-column="17" selection-end-line="23" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="3" column="11" lean-forward="false" selection-start-line="3" selection-start-column="11" selection-end-line="3" selection-end-column="11" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/utils/parser/univis_eventpage_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="6" column="74" lean-forward="false" selection-start-line="6" selection-start-column="18" selection-end-line="6" selection-end-column="74" />
<folding>
<element signature="e#0#15#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/data_collectors/collect_and_migrate.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="40">
<caret line="2" column="0" lean-forward="false" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/management/commands/import_food.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="260">
<caret line="13" column="25" lean-forward="false" selection-start-line="13" selection-start-column="25" selection-end-line="13" selection-end-column="25" />
<folding>
<element signature="e#0#65#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/wsgi.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="23" lean-forward="false" selection-start-line="4" selection-start-column="23" selection-end-line="4" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/utils/migrate_data.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="617">
<caret line="31" column="0" lean-forward="true" selection-start-line="31" selection-start-column="0" selection-end-line="31" selection-end-column="0" />
<folding>
<element signature="e#0#11#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/management/commands/import_events.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="240">
<caret line="12" column="39" lean-forward="false" selection-start-line="12" selection-start-column="39" selection-end-line="12" selection-end-column="39" />
<folding>
<element signature="e#0#65#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/utils/json_generator/controller_json_events.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="660">
<caret line="33" column="40" lean-forward="false" selection-start-line="33" selection-start-column="40" selection-end-line="33" selection-end-column="40" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/parser/mensa_page_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="40">
<caret line="5" column="0" lean-forward="false" selection-start-line="5" selection-start-column="0" selection-end-line="5" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/food/daily_food.jinja">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="8" lean-forward="false" selection-start-line="4" selection-start-column="3" selection-end-line="4" selection-end-column="8" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/migrate_data.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="220">
<caret line="29" column="30" lean-forward="true" selection-start-line="29" selection-start-column="30" selection-end-line="29" selection-end-column="30" />
<folding>
<element signature="e#0#11#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/events/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="3" column="25" lean-forward="false" selection-start-line="3" selection-start-column="25" selection-end-line="3" selection-end-column="25" />
<folding>
<element signature="e#0#32#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ofu_app/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="240">
<caret line="39" column="1" lean-forward="false" selection-start-line="39" selection-start-column="1" selection-end-line="39" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="9" column="29" lean-forward="false" selection-start-line="9" selection-start-column="29" selection-end-line="9" selection-end-column="29" />
<folding>
<element signature="e#24#63#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="160">
<caret line="12" column="58" lean-forward="false" selection-start-line="12" selection-start-column="58" selection-end-line="12" selection-end-column="58" />
<folding>
<element signature="e#24#63#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/parser/fekide_happyhour_page_parser.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-564">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/utils/json_generator/controller_json_food.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="200">
<caret line="10" column="21" lean-forward="true" selection-start-line="10" selection-start-column="21" selection-end-line="10" selection-end-column="50" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/apps/food/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="356">
<caret line="39" column="43" lean-forward="false" selection-start-line="39" selection-start-column="43" selection-end-line="39" selection-end-column="43" />
<folding />
</state>
</provider>
</entry>
</component>
</project>

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class DonarConfig(AppConfig):
name = 'apps.donar'

View File

@ -0,0 +1,77 @@
from django.core.management.base import BaseCommand, CommandError
from apps.donar.models import VGN_Coords
def migrate_locations():
locations = []
locations.append(
{'location': 'Erba', 'vgn_key': 'coord%3A4418901%3A629758%3ANAV4%3ABamberg%2C An der Weberei 5',
'lat': '49.90316',
'lon': '10.86932'})
locations.append(
{'location': 'Feki', 'vgn_key': 'coord%3A4421412%3A629361%3ANAV4%3ABamberg%2C Feldkirchenstraße 21',
'lat': '49,9070328',
'lon': '10,9041714'})
locations.append(
{'location': 'Markushaus', 'vgn_key': 'coord%3A4419902%3A630599%3ANAV4%3ABamberg%2C Markusplatz 3',
'lat': '49.89552',
'lon': '10.88348'})
locations.append(
{'location': 'Austraße', 'vgn_key': 'coord%3A4420153%3A630781%3ANAV4%3ABamberg%2C An der Universität 7',
'lat': '49.89411',
'lon': '10.88726'})
locations.append(
{'location': 'Kranen', 'vgn_key': 'coord%3A4420141%3A630965%3ANAV4%3ABamberg%2C Am Kranen 10',
'lat': '49.89259',
'lon': '10.88701'})
locations.append(
{'location': 'Kärntenstr', 'vgn_key': 'coord%3A4421130%3A628738%3ANAV4%3ABamberg%2C Kärntenstraße 7',
'lat': '49.91256',
'lon': '10.90028'})
locations.append(
{'location': 'Kapellenstr', 'vgn_key': 'coord%3A4421682%3A631169%3ANAV4%3ABamberg%2C Kapellenstraße 13',
'lat': '49.89063',
'lon': '10.90846'})
locations.append(
{'location': 'Volkspark', 'vgn_key': 'coord%3A4423077%3A629976%3ANAV4%3ABamberg%2C Pödeldorfer Straße 180',
'lat': '49.90087',
'lon': '10.92998'})
locations.append(
{'location': 'K16', 'vgn_key': 'coord%3A4420069%3A630807%3ANAV4%3ABamberg%2C Kapuzinerstraße 16',
'lat': '48.127',
'lon': '11.5572'})
locations.append(
{'location': 'Zwinger', 'vgn_key': 'coord%3A4420461%3A631411%3ANAV4%3ABamberg%2C Am Zwinger 4',
'lat': '49.88843',
'lon': '10.8918'})
locations.append(
{'location': 'AULA', 'vgn_key': 'coord%3A4420062%3A631052%3ANAV4%3ABamberg%2C Dominikanerstraße 2',
'lat': '49.89165',
'lon': '10.88602'})
locations.append(
{'location': 'Fischstr', 'vgn_key': 'coord%3A4420141%3A630930%3ANAV4%3ABamberg%2C Fischstraße 5',
'lat': '49.89277',
'lon': '10.88717'})
locations.append(
{'location': 'Fleischstr', 'vgn_key': 'coord%3A4420204%3A630739%3ANAV4%3ABamberg%2C Fleischstraße 2',
'lat': '49.89453',
'lon': '10.88791'})
for location in locations:
location_obj, created = VGN_Coords.objects.get_or_create(name=location['location'], coords=location['vgn_key'],
latitude=location['lat'], longitude=location['lon'])
if not created:
print("Duplicate! Start Update: " + location['location'])
location_obj.name = location['location']
location_obj.coords = location['vgn_key']
location_obj.latitude = location['lat']
location_obj.longitude = location['lon']
class Command(BaseCommand):
help = "Imports Rooms from Univis PRG"
def add_arguments(self, parser):
pass
def handle(self, *args, **options):
migrate_locations()

View File

@ -0,0 +1,14 @@
from django.core.management.base import BaseCommand, CommandError
from apps.donar.models import Room
from apps.donar.utils import migrate_data
class Command(BaseCommand):
help = "Imports Rooms from Univis PRG"
def add_arguments(self, parser):
pass
def handle(self, *args, **options):
migrate_data.main()
self.stdout.write(self.style.SUCCESS('Successfully migrate data'))

View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-03 22:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Room',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('key', models.CharField(max_length=60)),
('address', models.CharField(max_length=60)),
('building_key', models.CharField(max_length=60)),
('floor', models.CharField(max_length=60)),
('name', models.CharField(max_length=60)),
('orgname', models.CharField(max_length=60)),
('short', models.CharField(max_length=60)),
],
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-03 22:16
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('donar', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='room',
name='short',
field=models.CharField(max_length=60, unique=True),
),
]

View File

@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-04 00:11
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('donar', '0002_auto_20171004_0016'),
]
operations = [
migrations.AddField(
model_name='room',
name='description',
field=models.CharField(default='', max_length=200),
),
migrations.AddField(
model_name='room',
name='size',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='address',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='building_key',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='floor',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='key',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='name',
field=models.CharField(default='', max_length=60),
),
migrations.AlterField(
model_name='room',
name='orgname',
field=models.CharField(default='', max_length=60),
),
]

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-17 13:34
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('donar', '0003_auto_20171004_0211'),
]
operations = [
migrations.CreateModel(
name='VGN_Coords',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('name', models.CharField(default='', max_length=60, unique=True)),
('coords', models.CharField(default='', max_length=60, unique=True)),
],
),
]

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-17 14:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('donar', '0004_vgn_coords'),
]
operations = [
migrations.AddField(
model_name='vgn_coords',
name='latitude',
field=models.CharField(default=0, max_length=60, unique=True),
preserve_default=False,
),
migrations.AddField(
model_name='vgn_coords',
name='longitude',
field=models.CharField(default=0, max_length=60, unique=True),
preserve_default=False,
),
migrations.AlterField(
model_name='vgn_coords',
name='coords',
field=models.CharField(max_length=60, unique=True),
),
migrations.AlterField(
model_name='vgn_coords',
name='name',
field=models.CharField(max_length=60, unique=True),
),
]

View File

@ -0,0 +1,25 @@
from django.db import models
MAX_LENGTH = 60
# Create your models here.
class Room(models.Model):
id = models.AutoField(primary_key=True)
key = models.CharField(max_length=MAX_LENGTH, default="")
address = models.CharField(max_length=MAX_LENGTH, default="")
building_key = models.CharField(max_length=MAX_LENGTH, default="")
floor = models.CharField(max_length=MAX_LENGTH, default="")
name = models.CharField(max_length=MAX_LENGTH, default="")
orgname = models.CharField(max_length=MAX_LENGTH, default="")
short = models.CharField(unique=True, max_length=MAX_LENGTH)
size = models.CharField(max_length=MAX_LENGTH, default="")
description = models.CharField(max_length=200, default="")
class VGN_Coords(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=MAX_LENGTH, unique=True)
coords = models.CharField(max_length=MAX_LENGTH, unique=True)
longitude = models.CharField(max_length=MAX_LENGTH, unique=True)
latitude = models.CharField(max_length=MAX_LENGTH, unique=True)

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

View File

@ -0,0 +1,66 @@
import json
from pprint import pprint
from django.db.utils import IntegrityError
from apps.donar.models import Room
from apps.donar.utils.parser import univis_rooms_parser
# CONFIG
UNIVIS_RPG_GuK = "http://univis.uni-bamberg.de/prg?search=rooms&department=Fakult%E4t%20Geistes-%20und%20Kulturwissenschaften&show=xml"
UNIVIS_RPG_SoWi = "http://univis.uni-bamberg.de/prg?search=rooms&department=Fakult%E4t%20Sozial-%20und%20Wirtschaftswissenschaften&show=xml"
UNIVIS_RPG_HuWi = "http://univis.uni-bamberg.de/prg?search=rooms&department=Fakult%E4t%20Humanwissenschaften&show=xml"
UNIVIS_RPG_WIAI = "http://univis.uni-bamberg.de/prg?search=rooms&department=Fakult%E4t%20Wirtschaftsinformatik&show=xml"
def getJsonFromFile(path):
with open(path, "r") as file:
return json.load(file)
def writeFekideDataInDB(data):
for room in data:
try:
key = ""
address = ""
building_key = ""
floor = ""
name = ""
orgname = ""
short = ""
size = ""
description = ""
if '@key' in room:
key = room['@key']
if 'address' in room:
address = room['address']
if 'buildingkey' in room:
building_key = room['buildingkey']
if 'floor' in room:
floor = room['floor']
if 'name' in room:
name = room['name']
if 'short' in room:
short = room['short']
if 'size' in room:
size = room['size']
if 'description' in room:
description = room['description']
Room.objects.create(key=key, address=address, building_key=building_key, floor=floor, name=name,
orgname=orgname, short=short, size=size, description=description)
except IntegrityError:
# ignored
break
def main():
# get food jsons
writeFekideDataInDB(univis_rooms_parser.parsePage(UNIVIS_RPG_GuK))
writeFekideDataInDB(univis_rooms_parser.parsePage(UNIVIS_RPG_SoWi))
writeFekideDataInDB(univis_rooms_parser.parsePage(UNIVIS_RPG_HuWi))
writeFekideDataInDB(univis_rooms_parser.parsePage(UNIVIS_RPG_WIAI))
pprint("Room: " + str(Room.objects.count()))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,29 @@
import requests
import datetime
import xmltodict
import json
from pprint import pprint
def loadPage(url: str):
return requests.get(url).content
def getDay():
return datetime.datetime.today().strftime("%A, %d.%m.%Y")
def getRoom(dict: dict):
rooms = []
for room in dict['UnivIS']['Room']:
rooms.append(room)
return rooms
def parsePage(url):
page = loadPage(url)
dict = xmltodict.parse(page)
rooms = getRoom(dict)
return rooms
# parsePage()

View File

@ -0,0 +1,38 @@
from django.shortcuts import render, redirect
from apps.donar.models import Room
from apps.donar.models import VGN_Coords
# Create your views here.
def home(request):
return render(request, 'donar/home.jinja', {})
def all_rooms(request):
rooms = Room.objects.all()
return render(request, 'donar/all_rooms.jinja', {'rooms': rooms})
def search_room(request):
id = request.GET.get('search_room', None)
if id:
# create a form instance and populate it with data from the request:
rooms = Room.objects.filter(short__contains=id)
return render(request, 'donar/search_rooms.jinja', {'id': id, 'rooms': rooms})
return render(request, 'donar/search_rooms.jinja', {})
def show_room(request, room):
room = Room.objects.get(short=room)
return render(request, 'donar/show_room.jinja', {'room': room})
def bus_connections(request):
locations = VGN_Coords.objects.all()
return render(request, 'donar/vgn_connections.jinja', {'locations': locations})
def vgn_redirect(request, position, vgn_coords):
return redirect('https://www.vgn.de/verbindungen/?to=' + position + '&td=' + vgn_coords)

View File

@ -11,6 +11,6 @@ class Command(BaseCommand):
pass
def handle(self, *args, **options):
controller_json_events.main("apps/events/utils/json_generator/jsons/")
migrate_data.main("apps/events/utils/json_generator/jsons/")
# controller_json_events.main("apps/events/utils/json_generator/jsons/")
migrate_data.main()
self.stdout.write(self.style.SUCCESS('Successfully migrate data'))

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-05 14:55
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Location',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('key', models.CharField(max_length=60)),
('name', models.CharField(max_length=60)),
],
),
migrations.AlterUniqueTogether(
name='event',
unique_together=set([]),
),
migrations.RemoveField(
model_name='event',
name='location',
),
migrations.AddField(
model_name='event',
name='location',
field=models.ManyToManyField(to='events.Location'),
),
]

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-05 16:07
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0002_auto_20171005_1655'),
]
operations = [
migrations.AddField(
model_name='event',
name='orgname',
field=models.CharField(blank=True, max_length=60),
),
migrations.AddField(
model_name='event',
name='presenter',
field=models.CharField(blank=True, max_length=60),
),
migrations.AlterField(
model_name='event',
name='link',
field=models.CharField(blank=True, max_length=60),
),
migrations.AlterField(
model_name='location',
name='key',
field=models.CharField(blank=True, max_length=60),
),
migrations.AlterUniqueTogether(
name='event',
unique_together=set([('date', 'time', 'title')]),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-05 17:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0003_auto_20171005_1807'),
]
operations = [
migrations.AlterField(
model_name='location',
name='name',
field=models.CharField(max_length=60, unique=True),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-05 18:04
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0004_auto_20171005_1923'),
]
operations = [
migrations.RenameField(
model_name='event',
old_name='location',
new_name='locations',
),
]

View File

@ -8,12 +8,26 @@ MAX_LENGTH = 60
# Create your models here.
class Event(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=MAX_LENGTH)
category = models.CharField(max_length=MAX_LENGTH)
link = models.CharField(max_length=MAX_LENGTH)
location = models.CharField(max_length=MAX_LENGTH)
time = models.TimeField(default=timezone.now)
date = models.DateField(default=timezone.now)
title = models.CharField(blank=False, max_length=MAX_LENGTH)
category = models.CharField(blank=False, max_length=MAX_LENGTH)
link = models.CharField(blank=True, max_length=MAX_LENGTH)
locations = models.ManyToManyField('Location', blank=False)
date = models.DateField(blank=False, default=timezone.now)
time = models.TimeField(blank=False, default=timezone.now)
presenter = models.CharField(blank=True, max_length=MAX_LENGTH)
orgname = models.CharField(blank=True, max_length=MAX_LENGTH)
def __str__(self):
return "Date: %s, Titel: %s" % (self.date.strftime("%Y.%m.%d"), self.title)
class Meta:
unique_together = ('date', 'location')
unique_together = ('date', 'time', 'title')
class Location(models.Model):
id = models.AutoField(primary_key=True)
key = models.CharField(blank=True, max_length=MAX_LENGTH)
name = models.CharField(blank=False, unique=True, max_length=MAX_LENGTH)
def __str__(self):
return str(self.name)

View File

@ -19,6 +19,7 @@ from apps.events import views
urlpatterns = [
url(r'^$', views.events_main_page, name='events-main'),
url(r'^today/$', views.day_events, name='day-events'),
url(r'^week/$', views.week_events, name='week-events'),
url(r'^all/$', views.all_events, name='all-events'),
]

File diff suppressed because one or more lines are too long

View File

@ -1,36 +1,146 @@
import json
from datetime import datetime
from datetime import timedelta
from pprint import pprint
from django.db.utils import IntegrityError
from apps.events.utils.parser import univis_eventpage_parser
from apps.events.utils.parser import fekide_eventpage_parser
from apps.events.models import Event
from apps.events.models import Event, Location
# JSON_FILES_PATH_EVENTS = "json_generator/jsons/"
JSON_FILES_PATH_EVENTS = "events/json_generator/jsons/"
UNIVIS_CATEGORY = 'Univis'
def getJsonFromFile(path):
with open(path, "r") as file:
return json.load(file)
# CONFIG
UNIVIS_RPG_GuK = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Geistes-%20und%20Kulturwissenschaften&show=xml"
UNIVIS_RPG_SoWi = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Sozial-%20und%20Wirtschaftswissenschaften&show=xml"
UNIVIS_RPG_HuWi = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Humanwissenschaften&show=xml"
UNIVIS_RPG_WIAI = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Wirtschaftsinformatik&show=xml"
def writeFekideDataInDB(data):
for date in data['dates']:
for event in date['events']:
try:
time = datetime.strptime(str(event['time']).split()[1], "%H:%M")
Event.objects.create(date=datetime.strptime(date['date'], "%d.%m.%Y"), category=event['category'],
link=event['link'], location=event['location'], title=event['title'], time=time)
Location.objects.create(name=event['location'])
except IntegrityError:
# print("Location %s already exists." % event['location'])
pass
try:
event_obj, new = Event.objects.get_or_create(date=datetime.strptime(date['date'], "%d.%m.%Y"),
title=event['title'])
if new:
event_obj.category = event['category']
event_obj.link = event['link']
event_obj.time = datetime.strptime(str(event['time']).split()[1], "%H:%M")
event_obj.locations.add(Location.objects.get(name=event['location']))
event_obj.save()
Event.objects.filter(title="").delete()
else:
print("Event %s already exists. Start Update" % str(event_obj.title))
event_obj.category = event['category']
event_obj.link = event['link']
event_obj.time = datetime.strptime(str(event['time']).split()[1], "%H:%M")
event_obj.locations.add(Location.objects.get(name=event['location']))
event_obj.save()
except IntegrityError:
# ignored
break
pass
def main(path=JSON_FILES_PATH_EVENTS):
# get food jsons
writeFekideDataInDB(getJsonFromFile(path + "events-fekide.json"))
def deleteUnivisObjects():
Event.objects.filter(category=UNIVIS_CATEGORY).delete()
Location.objects.all().delete()
def writeUnivisDataInDB(events, rooms, persons):
writeUnivisLocationsInDB(rooms)
writeUnivisEventsInDB(events)
def writeUnivisLocationsInDB(rooms):
for room in rooms:
if '@key' in room and 'short' in room:
try:
Location.objects.create(key=room['@key'], name=room['short'])
except IntegrityError:
print("Possible Duplicate! Start DB refresh")
try:
Location.objects.get(name=room['short']).key = room['@key']
except Exception as harderr:
print("Failed to refresh object" + harderr.args)
except Exception as err:
print(err.args)
def getLocationIDs(event):
rooms = []
if not isinstance(event['rooms']['room'], list):
rooms.append(event['rooms']['room']['UnivISRef']['@key'])
else:
for room_item in event['rooms']['room']:
rooms.append(room_item['UnivISRef']['@key'])
return rooms
def writeUnivisEventsInDB(events: list):
for event in events:
if 'calendar' in event and not event['calendar'] == 'nein' and 'internal' in event and event[
'internal'] == 'nein' and 'startdate' in event and 'enddate' in event:
startdate = datetime.strptime(event['startdate'], "%Y-%m-%d")
enddate = datetime.strptime(event['enddate'], "%Y-%m-%d")
if (startdate + timedelta(1)) >= enddate:
if 'title' in event and 'rooms' in event and 'starttime' in event:
# TODO: Add Description in
# TODO: Is there a better way to add Objects in DB?
event_obj = Event()
event_obj.save()
event_obj.title = event['title']
locations = getLocationIDs(event)
for location in locations:
event_obj.locations.add(Location.objects.get(key=location))
event_obj.time = event['starttime']
event_obj.date = event['startdate']
# TODO: Better Category handling
event_obj.category = UNIVIS_CATEGORY
if 'presenter' in event:
event_obj.presenter = event['presenter']
if 'orgname' in event:
event_obj.orgname = event['orgname']
try:
event_obj.save()
except IntegrityError:
# TODO: Update DB Object if duplicate detected
print("Found Duplicate!")
except Exception as err:
print(err.args)
Event.objects.filter(title="").delete()
def write_out_db_objects():
pprint("Event: " + str(Event.objects.count()))
pprint("Location: " + str(Location.objects.count()))
def main():
print("Aktueller Stand:")
write_out_db_objects()
# deleteUnivisObjects()
# events, rooms, persons = univis_eventpage_parser.parsePage(UNIVIS_RPG_HuWi)
# writeUnivisDataInDB(events, rooms, persons)
# events, rooms, persons = univis_eventpage_parser.parsePage(UNIVIS_RPG_SoWi)
# writeUnivisDataInDB(events, rooms, persons)
# events, rooms, persons = univis_eventpage_parser.parsePage(UNIVIS_RPG_GuK)
# writeUnivisDataInDB(events, rooms, persons)
# events, rooms, persons = univis_eventpage_parser.parsePage(UNIVIS_RPG_WIAI)
# writeUnivisDataInDB(events, rooms, persons)
writeFekideDataInDB(fekide_eventpage_parser.parsePage())
print("Neuer Stand:")
write_out_db_objects()
if __name__ == '__main__':

View File

@ -64,7 +64,6 @@ def getAllDates(url: str):
def parsePage():
pagecontent = {}
pagecontent['dates'] = getAllDates(LINK_FEKIDE_Events)
jsondata = json.dumps(pagecontent)
return jsondata
return pagecontent
# parsePage()

View File

@ -1,10 +1,14 @@
import requests
import datetime
import xmltodict
from pprint import pprint
import json
# CONFIG
UNIVIS_RPG_URL = "http://univis.uni-bamberg.de/prg?search=events&show=xml"
UNIVIS_RPG_GuK = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Geistes-%20und%20Kulturwissenschaften&show=xml"
UNIVIS_RPG_SoWi = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Sozial-%20und%20Wirtschaftswissenschaften&show=xml"
UNIVIS_RPG_HuWi = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Humanwissenschaften&show=xml"
UNIVIS_RPG_WIAI = "http://univis.uni-bamberg.de/prg?search=events&department=Fakult%E4t%20Wirtschaftsinformatik&show=xml"
def loadPage(url: str):
@ -39,15 +43,30 @@ def resolveDates(json):
event['enddate'] = end_datetime
def parsePage():
# {Univis: {'Event':[{,,,,},,,,]}}
page = loadPage(UNIVIS_RPG_URL)
dict = xmltodict.parse(page)
# resolveUnivisRefs(dict)
json_data = json.dumps(dict)
json_data = json.loads(json_data)
resolveDates(json_data)
json_data['last_execute'] = getDay()
return json.dumps(json_data)
def getEvents(dict):
events = []
for event in dict['UnivIS']['Event']:
events.append(event)
return events
# parsePage()
def getRooms(dict: dict):
rooms = []
for room in dict['UnivIS']['Room']:
rooms.append(room)
return rooms
def getPersons(dict: dict):
persons = []
for person in dict['UnivIS']['Person']:
persons.append(person)
return persons
def parsePage(url):
page = loadPage(url)
dict = xmltodict.parse(page)
return getEvents(dict), getRooms(dict), getPersons(dict)
# parsePage(UNIVIS_RPG_GuK)

View File

@ -1,32 +1,54 @@
import datetime
from time import time
from django.shortcuts import render
from apps.events.models import Event
# Helper Methods
def get_categories(events: list):
categories = []
for event in events:
if not categories.__contains__(event.category):
categories.append(event.category)
return categories
# Create your views here.
def events_main_page(request):
return render(request, "events/events.jinja")
return render(request, "events/home.jinja")
def all_events(request):
today = datetime.datetime.now()
all_future_events = Event.objects.filter(date__gte=today)
lastdate = all_future_events.last().date
all_future_events = Event.objects.filter(date__gte=today).order_by('date', 'time')
lastdate = Event.objects.latest('date').date
return render(request, "events/all_events.jinja", {
'startdate': today,
'events': all_future_events,
'enddate': lastdate,
'categories': get_categories(all_future_events),
})
def week_events(request):
today = datetime.datetime.now()
weekdelta = today + datetime.timedelta(7)
events = Event.objects.filter(date__gte=today, date__lte=weekdelta)
events = Event.objects.filter(date__gte=today, date__lte=weekdelta).order_by('date', 'time')
return render(request, "events/week_events.jinja", {
'startdate': today,
'enddate': weekdelta,
'events': events,
'categories': get_categories(events),
})
def day_events(request):
today = datetime.datetime.now()
events = Event.objects.filter(date=today).order_by('time')
return render(request, "events/day_events.jinja", {
'date': today,
'events': events,
'categories': get_categories(events),
})

View File

@ -0,0 +1,13 @@
from django.core.management.base import BaseCommand, CommandError
from apps.food.models import Menu, HappyHour, SingleFood
from apps.food.utils import migrate_data
class Command(BaseCommand):
help = "Imports Food from special Websites"
def add_arguments(self, parser):
pass
def handle(self, *args, **options):
migrate_data.delete()

View File

@ -1,8 +1,8 @@
from django.core.management.base import BaseCommand, CommandError
from apps.food.models import Menu, HappyHour, SingleFood
from apps.food.utils.json_generator import controller_json_food
from apps.food.utils import migrate_data
class Command(BaseCommand):
help = "Imports Food from special Websites"
@ -10,6 +10,4 @@ class Command(BaseCommand):
pass
def handle(self, *args, **options):
controller_json_food.main("apps/food/utils/json_generator/jsons/")
migrate_data.main("apps/food/utils/json_generator/jsons/")
migrate_data.main()

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-08 09:02
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('food', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='happyhour',
name='endtime',
field=models.TimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='happyhour',
name='starttime',
field=models.TimeField(default=django.utils.timezone.now),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-13 17:02
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('food', '0002_auto_20171008_1102'),
]
operations = [
migrations.AlterUniqueTogether(
name='happyhour',
unique_together=set([('date', 'location', 'starttime', 'endtime')]),
),
]

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-19 23:46
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('food', '0003_auto_20171013_1902'),
]
operations = [
migrations.AddField(
model_name='singlefood',
name='image',
field=models.ImageField(blank=True, upload_to='food/%Y/%m/'),
),
migrations.AddField(
model_name='singlefood',
name='rating',
field=models.FloatField(default=0),
),
]

View File

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-10-20 03:49
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('food', '0004_auto_20171020_0146'),
]
operations = [
migrations.AddField(
model_name='singlefood',
name='fifth_star',
field=models.SmallIntegerField(default=0),
),
migrations.AddField(
model_name='singlefood',
name='first_star',
field=models.SmallIntegerField(default=0),
),
migrations.AddField(
model_name='singlefood',
name='fourth_star',
field=models.SmallIntegerField(default=0),
),
migrations.AddField(
model_name='singlefood',
name='second_star',
field=models.SmallIntegerField(default=0),
),
migrations.AddField(
model_name='singlefood',
name='third_star',
field=models.SmallIntegerField(default=0),
),
]

View File

@ -16,28 +16,43 @@ class Menu(models.Model):
class Meta:
unique_together = ('date', 'location')
# def __str__(self):
# return self.date.strftime("%d.%m.%Y")
def __str__(self):
return "Date: %s, Location: %s" % (self.date.strftime("%d.%m.%Y"), self.location)
class SingleFood(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(unique=True, max_length=MAX_LENGTH)
image = models.ImageField(upload_to='food/%Y/%m/', blank=True)
rating = models.FloatField(default=0)
first_star = models.SmallIntegerField(default=0)
second_star = models.SmallIntegerField(default=0)
third_star = models.SmallIntegerField(default=0)
fourth_star = models.SmallIntegerField(default=0)
fifth_star = models.SmallIntegerField(default=0)
# def __str__(self):
# return self.name
def __str__(self):
return "%s Rating: %f" % (self.name, self.rating)
class Allergene(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(unique=True, max_length=MAX_LENGTH)
def __str__(self):
return self.name
class HappyHour(models.Model):
id = models.AutoField(primary_key=True)
date = models.DateField(default=timezone.now)
starttime = models.DateField(default=timezone.now)
endtime = models.DateField(default=timezone.now)
starttime = models.TimeField(default=timezone.now)
endtime = models.TimeField(default=timezone.now)
location = models.CharField(max_length=MAX_LENGTH)
description = models.CharField(max_length=MAX_LENGTH)
class Meta:
unique_together = ('date', 'location')
unique_together = ('date', 'location', 'starttime', 'endtime')
# def __str__(self):
# return "Date: %s, Location: %s" % (self.date.strftime("%Y.%m.%d"), self.location)
def __str__(self):
return "Date: %s, Location: %s" % (self.date.strftime("%Y.%m.%d"), self.location)

View File

@ -0,0 +1,17 @@
from apps.food.models import Menu, SingleFood
from rest_framework import serializers
class SingleFoodSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = SingleFood
fields = ('name',)
class MenuSerializer(serializers.HyperlinkedModelSerializer):
date = serializers.DateField(format='iso-8601')
menu = SingleFoodSerializer(many=True, read_only=True)
class Meta:
model = Menu
fields = ('date', 'location', 'menu')

View File

@ -13,14 +13,32 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.conf.urls import url, include
from rest_framework import routers
from apps.food import views
router = routers.DefaultRouter()
router.register(r'all', views.FoodViewSet)
router.register(r'loc/(?P<location>.+)/$', views.FoodList.as_view(), base_name="food-on-loaction")
router.register(r'date/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.FoodList.as_view(),
base_name="food-on-day")
# router.register(r'(?P<location>.+)/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.FoodList.as_view(), base_name="food-list")
urlpatterns = [
url(r'^$', views.food, name='food'),
# Daily Menus
url(r'^daily/$', views.daily_food, name='daily-food'),
url(r'^weekly/$', views.daily_food, name='weekly-food'),
url(r'^weekly/$', views.weekly_food, name='weekly-food'),
url(r'^all/$', views.food, name='all-food'),
url(r'^daily/rating/$', views.food_rating, name='rating-food'),
url(r'^weekly/rating/$', views.food_rating, name='rating-food'),
url(r'^api/', include(router.urls)),
url(r'^api/(?P<location>[a-zA-Z]+)/$', views.FoodList.as_view(), name='rating-food'),
url(r'^api/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.FoodList.as_view(),
name='rating-food'),
url(r'^api/(?P<location>[a-zA-Z]+)/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.FoodList.as_view(),
name='rating-food'),
]

View File

@ -1,60 +0,0 @@
from apps.food.utils.parser import mensa_page_parser, cafete_page_parser, fekide_happyhour_page_parser
# CONFIG
JSON_OUTPUT_DIR_FOOD = "./food/json_generator/jsons/"
# CONFIG SERVICE LINKS
LINK_FEKI_MENSA = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/speiseplaene.html?tx_thmensamenu_pi2%5Bmensen%5D=3&tx_thmensamenu_pi2%5Baction%5D=show&tx_thmensamenu_pi2%5Bcontroller%5D=Speiseplan&cHash=c3fe5ebb35e5fba3794f01878e798b7c"
LINK_AUSTR_MENSA = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/speiseplaene.html?tx_thmensamenu_pi2%5Bmensen%5D=2&tx_thmensamenu_pi2%5Baction%5D=show&tx_thmensamenu_pi2%5Bcontroller%5D=Speiseplan&cHash=511e047953ee1370c3b82c11a04624bb"
LINK_ERBA_CAFETE = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/sonderspeiseplaene/cafeteria-erba-insel.html"
LINK_MARKUS_CAFETE = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/sonderspeiseplaene/cafeteria-markusplatz.html"
LINK_FEKIDE_GUIDE = "https://www.feki.de/happyhour"
def writeToFile(jsonfile, root, filename):
with open((root + filename), "w") as file:
file.write(jsonfile)
def main(path=JSON_OUTPUT_DIR_FOOD):
try:
json_food_mensa_feki = mensa_page_parser.parsePage(LINK_FEKI_MENSA)
except IndexError:
print("Error")
json_food_mensa_feki = {}
try:
json_food_mensa_austr = mensa_page_parser.parsePage(LINK_AUSTR_MENSA)
except IndexError:
print("Error")
json_food_mensa_austr = {}
try:
json_food_cafete_erba = cafete_page_parser.parsePage(LINK_ERBA_CAFETE)
except IndexError:
print("Error")
json_food_cafete_erba = {}
try:
json_food_cafete_markus = cafete_page_parser.parsePage(LINK_MARKUS_CAFETE)
except IndexError:
print("Error")
json_food_cafete_markus = {}
try:
json_food_fekidehappyhours = fekide_happyhour_page_parser.parsePage(LINK_FEKIDE_GUIDE)
except IndexError:
print("Error")
json_food_fekidehappyhours = {}
# WRITE JSONS
writeToFile(json_food_mensa_feki, path, "mensa-feki.json")
writeToFile(json_food_mensa_austr, path, "mensa-austr.json")
writeToFile(json_food_cafete_erba, path, "cafete-erba.json")
writeToFile(json_food_cafete_markus, path, "cafete-markus.json")
writeToFile(json_food_fekidehappyhours, path, "happyhourguide-fekide.json")
if __name__ == "__main__":
main()

View File

@ -1 +0,0 @@
{"weekmenu": [{"menu": ["Rinderhacksteak an Cognacso\u00dfe und Sp\u00e4tzle"], "date": "24.07."}, {"menu": ["Gem\u00fcseschnitzel mit Kr\u00e4utercreme und Kartoffeln"], "date": "25.07."}, {"menu": ["Penne-Nudeln mit Hackfleischso\u00dfe"], "date": "26.07."}, {"menu": ["Kaiserschmarrn mit Apfelmus"], "date": "27.07."}], "execution_time": "Tuesday, 03.10.2017", "name": "Cafeteria Erba-Insel"}

View File

@ -1 +0,0 @@
{"weekmenu": [{"menu": ["Vegetarisches Chili sin Carne"], "date": "24.07."}, {"menu": ["Gem\u00fcseschnitzel mit Kr\u00e4utercreme und Kartoffeln"], "date": "25.07."}, {"menu": ["\u00dcberbackene Zucchini an Paprikaso\u00dfe mit P\u00fcree"], "date": "26.07."}, {"menu": ["Kaiserschmarrn mit Apfelmus"], "date": "27.07."}], "execution_time": "Tuesday, 03.10.2017", "name": "Cafeteria Markusplatz"}

View File

@ -1 +0,0 @@
{"execution_time": "Tuesday, 03.10.2017", "day": "Tuesday, 03.10.2017", "happyhours": []}

View File

@ -1 +0,0 @@
{"weekmenu": [{"menu": ["Pennenudeln mit Lachs, Spinat und Kirschtomaten", "Rinderhacksteak mit Cognac - Pfefferso\u00dfe", "Schneller Teller: H\u00e4hnchenspie\u00df mit Gefl\u00fcgelso\u00dfe, Bratkartoffeln und Blumenkohl", "Kartoffelgnocchi - Gem\u00fcsepfanne", "Dampfkartoffeln mit hausgemachtem Schnittlauchquark"], "date": "02.10."}, {"menu": [], "date": "03.10."}, {"menu": ["Siebenschwabenplatte mit Bratenso\u00dfe", "Putenbrustgeschnetzeltes in Pilzrahm", "Schneller Teller: Veganes Soja - Gem\u00fcsegeschnetzeltes mit Penine Rigate, Apfel", "\u00dcberbackene Zucchini \"mediterrane Art\" an Paprikaso\u00dfe"], "date": "04.10."}, {"menu": ["Chicken Burger mit Ananas Currydip", "Schneller Teller: Paprikagulsch vom Schwein mit Spiralnudeln und Rosenkohl", "Nudelgem\u00fcseauflauf", "Pizza \"Spinat & Hirtenk\u00e4se\""], "date": "05.10."}, {"menu": ["Schneller Teller: Seelachsfilet an \"S\u00fc\u00df - Scharfer\" Tomatenso\u00dfe, Langkornreis und Brokkoli", "Gyros mit hausgemachtem Tsatsiki", "Green Tacos mit Walnuss - Chili - P\u00e2t\u00e9", "Kartoffel Broccoli Gratin"], "date": "06.10."}], "execution_time": "Tuesday, 03.10.2017", "name": "Speiseplan f\u00fcr Austra\u00dfe Bamberg"}

View File

@ -1 +0,0 @@
{"weekmenu": [{"menu": ["Rinderhacksteak mit Cognac - Pfefferso\u00dfe", "Schneller Teller: H\u00e4hnchenspie\u00df mit Gefl\u00fcgelso\u00dfe, Bratkartoffeln und Blumenkohl", "Kartoffelgnocchi - Gem\u00fcsepfanne", "Dampfkartoffeln mit hausgemachtem Schnittlauchquark"], "date": "02.10."}, {"menu": [], "date": "03.10."}, {"menu": ["Siebenschwabenplatte mit Bratenso\u00dfe", "Putenbrustgeschnetzeltes in Pilzrahm", "Schneller Teller: Veganes Soja - Gem\u00fcsegeschnetzeltes mit Penine Rigate, Apfel", "\u00dcberbackene Zucchini \"mediterrane Art\" an Paprikaso\u00dfe"], "date": "04.10."}, {"menu": ["Chicken Burger mit Ananas Currydip", "Schneller Teller: Paprikagulsch vom Schwein mit Spiralnudeln und Rosenkohl", "Nudelgem\u00fcseauflauf", "Pizza \"Spinat & Hirtenk\u00e4se\""], "date": "05.10."}, {"menu": ["Schneller Teller: Seelachsfilet an \"S\u00fc\u00df - Scharfer\" Tomatenso\u00dfe, Langkornreis und Brokkoli", "Gyros mit hausgemachtem Tsatsiki", "Green Tacos mit Walnuss - Chili - P\u00e2t\u00e9", "Kartoffel Broccoli Gratin"], "date": "06.10."}], "execution_time": "Tuesday, 03.10.2017", "name": "Speiseplan f\u00fcr Feldkirchenstra\u00dfe Bamberg"}

View File

@ -3,9 +3,14 @@ from datetime import datetime
from pprint import pprint
from django.db.utils import IntegrityError
from apps.food.models import SingleFood, Menu, HappyHour
from apps.food.utils.parser import mensa_page_parser, fekide_happyhour_page_parser, cafete_page_parser
# JSON_FILES_PATH_FOOD = "json_generator/jsons/"
JSON_FILES_PATH_FOOD = "food/json_generator/jsons/"
# CONFIG SERVICE LINKS
LINK_FEKI_MENSA = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/speiseplaene.html?tx_thmensamenu_pi2%5Bmensen%5D=3&tx_thmensamenu_pi2%5Baction%5D=show&tx_thmensamenu_pi2%5Bcontroller%5D=Speiseplan&cHash=c3fe5ebb35e5fba3794f01878e798b7c"
LINK_AUSTR_MENSA = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/speiseplaene.html?tx_thmensamenu_pi2%5Bmensen%5D=2&tx_thmensamenu_pi2%5Baction%5D=show&tx_thmensamenu_pi2%5Bcontroller%5D=Speiseplan&cHash=511e047953ee1370c3b82c11a04624bb"
LINK_ERBA_CAFETE = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/sonderspeiseplaene/cafeteria-erba-insel.html"
LINK_MARKUS_CAFETE = "https://www.studentenwerk-wuerzburg.de/bamberg/essen-trinken/sonderspeiseplaene/cafeteria-markusplatz.html"
LINK_FEKIDE_GUIDE = "https://www.feki.de/happyhour"
def getJsonFromFile(path):
@ -14,6 +19,7 @@ def getJsonFromFile(path):
def writeStudentenwerkDataInDB(data):
data = json.loads(data)
for menu in data['weekmenu']:
foodlist = []
for single_food in menu['menu']:
@ -35,29 +41,51 @@ def writeStudentenwerkDataInDB(data):
def writeFekideDataInDB(data):
for happyhour_data in data['happyhours']:
time = str(happyhour_data['time']).replace(" ", "").split("-")
try:
HappyHour.objects.create(date=datetime.strptime(data['day'], "%A, %d.%m.%Y"),
location=happyhour_data['location'], description=happyhour_data['description'],
starttime=datetime.strptime(time[0], "%H:%M"),
endtime=datetime.strptime(time[1], "%H:%M"))
except IntegrityError:
# ignored
break
happyhour, new = HappyHour.objects.get_or_create(date=datetime.strptime(data['day'], "%A, %d.%m.%Y"),
location=happyhour_data['location'],
description=happyhour_data['description'],
starttime=datetime.strptime(time[0], "%H:%M").time(),
endtime=datetime.strptime(time[1], "%H:%M").time())
if not new:
happyhour.date = datetime.strptime(data['day'], "%A, %d.%m.%Y")
happyhour.location = happyhour_data['location']
happyhour.description = happyhour_data['description']
happyhour.starttime = datetime.strptime(time[0], "%H:%M").time()
happyhour.endtime = datetime.strptime(time[1], "%H:%M").time()
happyhour.save()
print("%s: Happy Hour: Location: %s, Description: %s" % (
str(happyhour.date.date()), str(happyhour.location), str(happyhour.description)))
def main(path=JSON_FILES_PATH_FOOD):
# get food jsons
writeStudentenwerkDataInDB(getJsonFromFile(path + "mensa-austr.json"))
writeStudentenwerkDataInDB(getJsonFromFile(path + "cafete-erba.json"))
writeStudentenwerkDataInDB(getJsonFromFile(path + "cafete-markus.json"))
writeStudentenwerkDataInDB(getJsonFromFile(path + "mensa-feki.json"))
json_food_fekide = getJsonFromFile(path + "happyhourguide-fekide.json")
writeFekideDataInDB(json_food_fekide)
def writeoutDBObjects():
pprint("SingleFood: " + str(SingleFood.objects.count()))
pprint("Menu: " + str(Menu.objects.count()))
pprint("HappyHour: " + str(HappyHour.objects.count()))
def delete():
happy_hours = HappyHour.objects.all()
print("Deleted following Happy Hours:")
for happy_hour in happy_hours:
print("%s: Happy Hour: Location: %s, Description: %s" % (
str(happy_hour.date), str(happy_hour.location), str(happy_hour.description)))
happy_hour.delete()
def main():
print("Aktueller Stand:")
writeoutDBObjects()
# get food jsons
writeStudentenwerkDataInDB(mensa_page_parser.parsePage(LINK_AUSTR_MENSA))
writeStudentenwerkDataInDB(mensa_page_parser.parsePage(LINK_FEKI_MENSA))
writeStudentenwerkDataInDB(cafete_page_parser.parsePage(LINK_ERBA_CAFETE))
writeStudentenwerkDataInDB(cafete_page_parser.parsePage(LINK_MARKUS_CAFETE))
writeFekideDataInDB(fekide_happyhour_page_parser.parsePage(LINK_FEKIDE_GUIDE))
print("Neuer Stand:")
writeoutDBObjects()
if __name__ == '__main__':
main()

View File

@ -2,6 +2,7 @@ import requests
from bs4 import BeautifulSoup
import json
import datetime
import re
SPEISEPLAN_NAME_SELECTOR = '.csc-default .csc-header .csc-firstHeader'
@ -16,18 +17,20 @@ def getFoodplanName(soup):
def getRightLine(lines):
foodlines = []
pattern = re.compile("[0-9]+.+[A-Z]+")
for line in list(lines):
if str(line).__contains__("<br/>"):
return line
return ""
line = line.getText()
if pattern.match(line):
foodlines.append(line)
return foodlines
def getFoodPerDay(soup):
days = []
lines = soup.select('.csc-default .bodytext')
line = getRightLine(lines)
foods = str(line).strip('<p class="bodytext">').strip('</').split("<br/>")
for food in foods:
foodlines = getRightLine(lines)
for food in foodlines:
dayObj = {}
day = str(food).split()[0]
foodName = str(food).replace(day, "").strip()

View File

@ -45,9 +45,7 @@ def parsePage(url: str):
pagecontent['happyhours'] = happyhours
pagecontent['day'] = getDay()
pagecontent['execution_time'] = datetime.datetime.today().strftime("%A, %d.%m.%Y")
jsondata = json.dumps(pagecontent)
return jsondata
return pagecontent
# LINK_FEKIDE_GUIDE = "https://www.feki.de/happyhour/wochenuebersicht"
# parsePage(LINK_FEKIDE_GUIDE)

View File

@ -43,7 +43,6 @@ def parsePage(url: str):
mensaSpeiseplan['weekmenu'] = days
mensaSpeiseplan['name'] = foodplan_name
mensaSpeiseplan['execution_time'] = datetime.datetime.today().strftime("%A, %d.%m.%Y")
# print(mensaSpeiseplan)
mensaSpeiseplanJson = json.dumps(mensaSpeiseplan)
return mensaSpeiseplanJson

View File

@ -5,19 +5,24 @@ import datetime
from django.shortcuts import render
from apps.food.models import Menu, HappyHour
from apps.food.models import Menu, HappyHour, SingleFood
from django.http import HttpResponse
from rest_framework import viewsets, generics
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from apps.food.serializers import MenuSerializer, SingleFoodSerializer
# Create your views here.
def daily_food(request):
today = datetime.datetime.now()
daily_menus = Menu.objects.filter(date__exact=today)
feki_menu = daily_menus.filter(location__contains="Feldkirchenstraße").last()
austr_menu = daily_menus.filter(location__contains="Austraße").last()
erba_cafete = daily_menus.filter(location__contains="Erba").last()
markus_cafete = daily_menus.filter(location__contains="markus").last()
feki_menu = Menu.objects.filter(date__exact=today).filter(location__contains="Feldkirchenstraße").last()
austr_menu = Menu.objects.filter(date__exact=today).filter(location__contains="Austraße").last()
erba_cafete = Menu.objects.filter(date__exact=today).filter(location__contains="Erba").last()
markus_cafete = Menu.objects.filter(date__exact=today).filter(location__contains="markus").last()
happy_hours = HappyHour.objects.filter(date__exact=today)
print(feki_menu.menu)
return render(request, "food/daily_food.jinja", {
'day': today,
'happy_hours': happy_hours,
@ -30,16 +35,16 @@ def daily_food(request):
def weekly_food(request):
today = datetime.datetime.now()
lastday = datetime.datetime.now() + datetime.timedelta(7)
lastday = today + datetime.timedelta(7)
weekly_menus = Menu.objects.filter(date__gte=today, date__lte=lastday)
feki_menu = weekly_menus.filter(location__contains="Feldkirchenstraße")
austr_menu = weekly_menus.filter(location__contains="Austraße")
erba_cafete = weekly_menus.filter(location__contains="Erba")
markus_cafete = weekly_menus.filter(location__contains="markus")
happy_hours = HappyHour.objects.filter(date__gte=today, date__lte=lastday)
print(feki_menu.menu)
return render(request, "food/daily_food.jinja", {
return render(request, "food/weekly_food.jinja", {
'day': today,
'lastday': lastday,
'happy_hours': happy_hours,
'feki_menu': feki_menu,
'austr_menu': austr_menu,
@ -65,5 +70,82 @@ def all_food(request):
def food(request):
return render(request, "food/food.jinja", {
return render(request, "food/home.jinja", {
})
def food_rating(request):
food_id = request.GET.get('food_id', None)
rating = request.GET.get('rating', None)
if food_id and rating:
print("ID: %s, RATING: %s" % (food_id, rating))
food = SingleFood.objects.get(id=food_id)
if rating == str(1):
food.first_star = food.first_star + 1
if rating == str(2):
food.second_star += 1
if rating == str(3):
food.third_star += 1
if rating == str(4):
food.fourth_star += 1
if rating == str(5):
food.fifth_star += 1
global_count = food.first_star + food.second_star + food.third_star + food.fourth_star + food.fifth_star
sum = food.first_star * 1 + food.second_star * 2 + food.third_star * 3 + food.fourth_star * 4 + food.fifth_star * 5
food.rating = sum / global_count
print("SUMME: " + str(sum / global_count))
food.save()
return HttpResponse(status=200)
return HttpResponse(status=404)
def food_image(request):
food_id = request.GET.get('food_id', None)
img = request.GET.get('img', None)
if food_id and img:
food = SingleFood.objects.get(id=food_id)
food.image = img
food.save()
return HttpResponse(status=200)
return HttpResponse(status=404)
@api_view(['GET'])
def serialize_daily_food(request, location="", year="", month="", day=""):
request_date = datetime.datetime.strptime((year + "-" + month + "-" + day), "%Y-%m-%d")
queryset = Menu.objects.filter(location__contains=location).filter(date__exact=request_date)
serializer = MenuSerializer(queryset)
return Response(serializer)
class FoodViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Menu.objects.all()
serializer_class = MenuSerializer
class FoodList(generics.ListAPIView):
serializer_class = MenuSerializer
def get_queryset(self):
"""
This view should return a list of all the purchases for
the user as determined by the username portion of the URL.
"""
if 'location' in self.kwargs:
location = self.kwargs['location']
else:
location = ""
if 'year' in self.kwargs and 'month' in self.kwargs and 'day' in self.kwargs:
request_date = datetime.datetime.strptime(
(self.kwargs['year'] + "-" + self.kwargs['month'] + "-" + self.kwargs['day']), "%Y-%m-%d")
else:
request_date = datetime.datetime.now()
print("LOCATION: " + location)
print("DATE: " + str(request_date))
return Menu.objects.filter(location__contains=location).filter(date__exact=request_date)

Binary file not shown.

14
ofu_app/ofu_app/jinja2.py Normal file
View File

@ -0,0 +1,14 @@
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update({
'static': staticfiles_storage.url,
'url': reverse,
})
return env

View File

@ -23,7 +23,7 @@ SECRET_KEY = '7tm($-7tz!co8762!)ptmj%)80)qa^z0odee*8-!be!i(a!p4j'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['mg-server.ddns.net', 'localhost', '127.0.0.1', ]
ALLOWED_HOSTS = ['mg-server.ddns.net', 'localhost', '127.0.0.1', '192.168.100.8', '141.13.129.250']
# Application definition
@ -37,43 +37,39 @@ INSTALLED_APPS = [
'django_jinja',
'apps.food',
'apps.events',
'apps.donar',
'rest_framework',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAdminUser',
],
'PAGE_SIZE': 10
}
# MIDDLEWARE = [
# 'django.middleware.security.SecurityMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
# 'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
# 'django.contrib.messages.middleware.MessageMiddleware',
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
# ]
ROOT_URLCONF = 'ofu_app.urls'
TEMPLATES = [
# {
# "BACKEND": "django_jinja.backend.Jinja2",
# 'DIRS': [
# os.path.join(BASE_DIR, 'templates'),
# ],
# "APP_DIRS": True,
# "OPTIONS": {
# "match_extension": ".jinja",
# "match_regex": r"^(?!admin/).*",
# "app_dirname": "templates",
# "context_processors": [
# "django.contrib.auth.context_processors.auth",
# "django.template.context_processors.debug",
# "django.template.context_processors.i18n",
# "django.template.context_processors.media",
# "django.template.context_processors.static",
# "django.template.context_processors.tz",
# "django.contrib.messages.context_processors.messages",
# ],
# },
#
# },
{
'BACKEND': 'django_jinja.backend.Jinja2',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
],
'APP_DIRS': True,
'OPTIONS': {
'environment': 'ofu_app.jinja2.environment'
},
},
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
@ -162,3 +158,6 @@ USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# FORCE_SCRIPT_NAME = "app"
# Media files should be stored here
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'

Binary file not shown.

View File

@ -24,4 +24,7 @@ urlpatterns = [
# -- Apps --
url(r'^food/', include('apps.food.urls')),
url(r'^events/', include('apps.events.urls')),
url(r'^donar/', include('apps.donar.urls')),
url(r'^links/$', views.links, name='links-home'),
url(r'^impressum/$', views.impressum, name='impressum'),
]

View File

@ -7,3 +7,11 @@ from django.shortcuts import render
# Create your views here.
def home(request):
return render(request, "home.jinja", {})
def links(request):
return render(request, "links/home.jinja", {})
def impressum(request):
return render(request, "impressum.jinja", {})

Binary file not shown.

View File

@ -0,0 +1,47 @@
#food-nav {
padding-top: 0;
padding-bottom: 0;
}
#food-nav .container, #food-nav .container .nav-link {
height: 100%;
}
.jump-up-menu {
position: fixed;
margin-bottom: 50px;
bottom: 0;
right: 0;
background: white;
display: none;
border: 1px solid #343a40;
border-top-left-radius: 3px;
}
#category-jump-up:hover .jump-up-menu, .jump-up-menu:hover {
display: block;
}
.jump-up-elem {
padding: 5px;
margin-bottom: 0;
border-bottom: 1px solid #343a40;
}
.jump-up-elem:hover {
background-color: #cfcfcf;
}
footer {
/*mb equal height in #food-nav*/
margin-bottom: 50px;
}
/** Sticky Bottom Nav **/
#food-nav {
z-index: 5000;
bottom: 0;
position: fixed;
width: 100%;
height: 50px;
}

View File

@ -0,0 +1,42 @@
footer {
/*mb equal height in #food-nav*/
margin-bottom: 60px;
}
/** Sticky Bottom Nav **/
#food-nav {
z-index: 5000;
bottom: 0;
position: fixed;
width: 100%;
height: 60px;
}
.food-name p {
margin-bottom: 0;
}
/** Picture Input **/
.pic-upload {
display: none !important;
}
.custom-pic-upload {
display: inline-block;
padding-right: 5px;
cursor: pointer;
}
.image-wrapper:active img {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: auto;
z-index: 8000;
}
.image-wrapper img {
width: 80px;
height: 80px;
}

View File

@ -0,0 +1,66 @@
#main-nav {
display: table;
position: fixed;
left: -200px;
top: 0;
background-color: transparent;
z-index: 5000;
height: 100%;
width: 200px;
-webkit-transition: left 0.5s; /* For Safari 3.1 to 6.0 */
transition: left 0.5s;
}
#main-nav .nav-wrapper {
display: table-cell;
vertical-align: middle;
}
#main-nav .inner-nav .menu-item {
padding: 10px;
padding-left: 20px;
width: 100%;
display: block;
background-color: #ffffff;
border: 1px solid #b1b1b1;
}
#main-nav .inner-nav .menu-item:last-child {
border-bottom-right-radius: 5px;
}
#main-nav .inner-nav .menu-item:hover {
background-color: #b1b1b1;
}
#main-nav .inner-nav .menu-head {
border-top-right-radius: 5px;
border: 1px solid #b1b1b1;
background-color: #ffffff;
display: block;
padding: 10px;
padding-left: 20px;
margin-bottom: 0;
text-transform: uppercase;
font-weight: bold;
}
#menu-button:hover #main-nav, #menu-button:active #main-nav {
left: 0;
}
#menu-button:hover i, #menu-button:active i {
color: red !important;
}
#menu-button {
text-align: center;
margin-top: 12px;;
height: 100%;
}
#menu-button i {
}

View File

@ -0,0 +1,97 @@
/**
* Created by michigg on 14.10.17.
*/
var endLat = '';
var endLon = '';
var startLat = 49.8955663;
var startLon = 10.886907899999999;
var accuracy = 1;
document.addEventListener('DOMContentLoaded', loadData);
document.addEventListener('DOMContentLoaded', resizeMap);
document.addEventListener('DOMContentLoaded', getPos);
window.onresize = resizeMap;
function loadData() {
var address = document.getElementById('nav_data').getAttribute('data-address')
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
generateMap(JSON.parse(this.response))
}
};
xhttp.open("GET", "https://nominatim.openstreetmap.org/search/?format=json&city=Bamberg&street=" + address, true);
xhttp.send();
}
function generateMap(streets) {
var address = document.getElementById('nav_data').getAttribute('data-address');
var address_short = document.getElementById('nav_data').getAttribute('data-short');
var zoomlevel = 13.5;
console.log(streets);
if (streets.length > 0) {
endLon = streets[0]['lon'];
endLat = streets[0]['lat'];
var map = L.map('map').setView([endLat, endLon], zoomlevel);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([endLat, endLon]).addTo(map)
.bindPopup(address_short + '</br>' + address)
.openPopup();
L.marker([startLat, startLon]).addTo(map)
.bindPopup('You are here!')
.openPopup();
L.circle([startLat, startLon], {
color: '#6b6b6b',
fillColor: '#6b6b6b',
fillOpacity: 0.4,
radius: accuracy
}).addTo(map);
}
}
function resizeMap() {
var height = window.innerHeight
document.getElementById('map').style.height = height + 'px'
}
/**
* save current position in global vars
*/
function getPos() {
if (navigator.geolocation) {
var geo_option = {
enableHighAccuracy: true
};
navigator.geolocation.getCurrentPosition(function (position) {
console.log(position);
startLat = position.coords.latitude;
startLon = position.coords.longitude;
accuracy = position.coords.accuracy;
console.log('Lat: ' + startLat + ' Lon: ' + startLon + ' Acc: ' + accuracy)
}, function (err) {
console.log(err.code);
console.log(err.message);
}, geo_option)
} else {
document.getElementById('map').innerHTML('Geolocation not available')
}
}
function makeRoute() {
console.log('make route')
console.log('set waypoints:\nStart: ' + startLat + ' Lo: ' + startLon + " \nEnd: " + endLat + ' Lo: ' + endLon)
L.Routing.control({
waypoints: [
L.latLng(startLat, startLon),
L.latLng(endLat, endLon)
]
}).addTo(map);
}

View File

@ -0,0 +1,55 @@
/**
* Created by michigg on 17.10.17.
*/
document.addEventListener('DOMContentLoaded', loadVGNPos);
function loadVGNPos() {
document.getElementById('vgn-links').style.visibility = "hidden";
getPos();
}
function getPos() {
lat = 49.90734;
lon = 10.90459;
if (navigator.geolocation) {
var geo_option = {
enableHighAccuracy: true
};
navigator.geolocation.getCurrentPosition(function (position) {
getVGNCoords(position.coords.latitude, position.coords.longitude)
}, function (err) {
console.log(err);
document.getElementById('err').textContent = "Leider konnte Ihre Position nicht ermittelt werden.";
}, geo_option)
}
}
function loadData(url) {
console.log("LOAD DATA")
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
setVGNLinks(JSON.parse(this.response))
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function getVGNCoords(lat, lon) {
console.log("getVGNCoords: " + lat + "/" + lon);
var url = "https://www.vgn.de/ib/site/tools/VN_PointDetail.php?Edition=de&lat=" + lat + "&lon=" + lon + "&mode=fnSetFromEFA&mode2=origin&_=1508264908632";
loadData(url);
}
function setVGNLinks(response) {
var type = response['ident']['type'];
var startpoint = response['ident']['name'];
console.log("Startpoint" + startpoint);
var connections = document.getElementsByClassName('connection');
for (var i = 0; i < connections.length; i++) {
connections[i].href = connections[i].href.replace('position', startpoint);
console.log(connections[i].href)
}
document.getElementById('vgn-links').style.visibility = "visible"
}

View File

@ -0,0 +1,19 @@
/**
* Created by michigg on 16.10.17.
*/
function showCategory(category) {
// TODO: Überarbeiten. Uni eigentlich /= Univis geht das auch schöner?
var events = document.getElementsByClassName('event');
for (var i = 0; i < events.length; i++) {
events[i].style.display = 'none';
}
for (var i = 0; i < events.length; i++) {
var classes = events[i].classList;
for (var j = 0; j < classes.length; j++) {
if (category.includes(classes[j])) {
console.log(events[i])
events[i].style.display = 'block';
}
}
}
}

View File

@ -0,0 +1,47 @@
document.addEventListener('DOMContentLoaded', add_img_class, true);
function add_img_class() {
console.log($('.food-item'));
$('.food-item').each(function () {
var food_id = $(this).data('food');
console.log("ITEM: " + $(this) + " FOOD-ID: " + food_id);
$(this).find('.image-wrapper').addClass('img-' + food_id);
$(this).find('.pic-upload').addClass('img-upload-' + food_id).on('change', function () {
readURL(this)
});
});
}
function readURL(obj) {
var inputClass = "img-upload-" + $(obj).attr('class').split(' ')[1].split('-')[2];
console.log(inputClass);
input = $('.' + inputClass)[0];
var file = input.files[0];
console.log(file);
if (window.FileReader) {
reader = new FileReader();
reader.onloadend = function (e) {
var picClass = "img-" + $(obj).attr('class').split(' ')[1].split('-')[2];
showUploadedItem(e.target.result, picClass);
};
reader.readAsDataURL(file);
}
}
function showUploadedItem(source, picClass) {
console.log("Show Image: " + picClass + " source: " + source);
$('.' + picClass).each(function () {
console.log(this);
var img = this.childNodes[0];
var placeholder = this.childNodes[1];
console.log(img);
$(img).attr('src', source);
placeholder.style.display = 'none';
});
}
function upload_image(source) {
}

View File

@ -0,0 +1,86 @@
/**
* Created by michigg on 20.10.17.
*/
document.addEventListener('DOMContentLoaded', rate_init);
/**
* setup page, Add event listener
*/
function rate_init() {
add_Stars();
$('.star').on("mouseenter mouseleave", function () {
showRating(this);
}).on("click", function () {
console.log('Click');
sendRating(this);
})
}
/**
* add rating stars to each food-item
*/
function add_Stars() {
console.log($('.food-item'));
$('.food-item').each(function () {
var food = $(this).data('food');
var rating = $(this).data('rating');
console.log("ITEM: " + $(this) + " FOOD-ID: " + food + " FOOD-RATING: " + rating);
for (var i = 0; i < 5; i++) {
$(this).find('.rating-wrapper').append('<i class="star-' + (i + 1) + '-' + food + ' fa fa-star-o star" aria-hidden="true"></i>');
}
buildRating(food, rating);
});
}
/**
* get user Rating
*
* @param obj
* chosen rate star
*/
function showRating(obj) {
splitted_id = $(obj).attr('class').split(' ')[0].split('-');
console.log(splitted_id);
var rating = splitted_id[1];
var food_id = splitted_id[2];
buildRating(food_id, rating);
}
/**
* build rating-stars for given rating
* @param food_id food which shall be rated
* @param rating int or double between 1-5; count of rating-stars
*/
function buildRating(food_id, rating) {
for (var i = 1; i < 6; i++) {
var icon_id = '.star-' + i + '-' + food_id;
if (i <= rating) {
$(icon_id).removeClass('fa-star-o').addClass('fa-star');
} else {
$(icon_id).removeClass('fa-star').addClass('fa-star-o');
}
}
}
/**
* Sends user Rating to server
*
* @param obj user Rating
*/
function sendRating(obj) {
console.log('Send');
splitted_id = $(obj).attr('class').split(' ')[0].split('-');
var rating = splitted_id[1];
var food_id = splitted_id[2];
//TODO: Better URL handling
var url = window.location.href + "rating/";
console.log(url);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
}
};
console.log(url + "?rating=" + rating + "&food_id=" + food_id);
xhttp.open("GET", url + "?rating=" + rating + "&food_id=" + food_id, true);
xhttp.send();
}

Binary file not shown.

View File

@ -0,0 +1,590 @@
# Bulma Changelog
## 0.6.0
### Breaking changes
* The new `$link` color is part of the `$colors` map. As a result, `.button.is-link` is a colored button now. Use `.button.is-text` if you want the underlined button.
* The deprecated `variables.sass` file has been removed.
* The deprecated `nav.sass` file has been removed.
### New features
* #1236 `.table` hover effect is opt-in, by using the `.is-hoverable` modifier class
* #1254 `.dropdown` now supports `.is-up` modifier
### Improvements
* #1257 Include placeholder mixin in `=input`
The `$link` color is used instead of `$primary` in the following components:
<table>
<tr>
<th>Variable</th>
<th>Old value</th>
<th>New value</th>
</tr>
<tr>
<td><code>$dropdown-item-active-color</code></td>
<td><code>$primary-invert</code></td>
<td><code>$link-invert</code></td>
</tr>
<tr>
<td><code>$dropdown-item-active-background-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$navbar-tab-hover-border-bottom-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$navbar-tab-active-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$navbar-tab-active-border-bottom-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$navbar-dropdown-item-active-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$tabs-link-active-border-bottom-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$tabs-link-active-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$tabs-toggle-link-active-background-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$tabs-toggle-link-active-border-color</code></td>
<td><code>$primary</code></td>
<td><code>$link</code></td>
</tr>
<tr>
<td><code>$tabs-toggle-link-active-color</code></td>
<td><code>$primary-invert</code></td>
<td><code>$link-invert</code></td>
</tr>
</table>
### Issues closed
* #708 Import variables in mixins
## 0.5.3
### New features
* #1101 `.card-header-title` can be centered with `.is-centered`
* #1189 `.input` readonly and `.is-static`
* #1189 `.textarea` readonly
### Issues closed
* #1177 Fix `.message .tag` combination
* #1167 Fix `pre code`
* #1207 Fix `.breadcrumb` alignment
## 0.5.2
### New features
* #842 `navbar` color modifiers
* #331 Support for third party icons
* Added `$button-focus-box-shadow-size` and `$button-focus-box-shadow-color` for customization
* Added `$input-focus-box-shadow-size` and `$input-focus-box-shadow-color` for customization
* Navbar tabs
### Issues closed
* #1168 Undefined variable: `$navbar-item`
* #930 Remove `vertical-align: top` for icons
* #735 Font awesome custom `font-size`
* #395 Font awesome stacked icons
* #1152 Level-items not centered horizontally on mobile
* #1147 Add `text-size-adjust: 100%` to `html`
* #1106 `pagination` docs
* #1063 `$family-primary` customization
## 0.5.1
### New features
* 🎉 #280 [File upload element](http://bulma.io/documentation/form/file/)
* `$container-offset` variable to determine the `.container` breakpoints
* #1001 Text case helpers
### Issues closed
* #1030 Add `!important` to non responsive display helpers
* #1020 Customizing `.navbar-item img` max height
* #998 `.navbar-dropdown` with **right** alignment
* #877 `.pagination` isn't using `$pagination-background`
* #989 `navbar-brand` overflowing on mobile
* #975 Variable `$table-head-color` isn't used
* #964 Tabs sass file throwing error with `!important`
* #949 `.is-size-7` helper is missing
## 0.5.0
### New features
* 🎉 [List of tags](http://bulma.io/documentation/elements/tag/#list-of-tags)
* New **variable naming system**: `component`-`subcomponent`-`state`-`property`
* Improved **customization** thanks to new set of variables
* #934 New `.is-shadowless` helper
Variable name changes (mostly appending `-color`):
<table>
<tr><th>From</th><th>To</th></tr>
<tr><td><code>$card</code></td><td><code>$card-color</code></td></tr>
<tr><td><code>$card-background</code></td><td><code>$card-background-color</code></td></tr>
<tr><td><code>$card-header</code></td><td><code>$card-header-color</code></td></tr>
<tr><td><code>$dropdown-item</code></td><td><code>$dropdown-item-color</code></td></tr>
<tr><td><code>$dropdown-content-background</code></td><td><code>$dropdown-content-background-color</code></td></tr>
<tr><td><code>$dropdown-item-hover-background</code></td><td><code>$dropdown-item-hover-background-color</code></td></tr>
<tr><td><code>$dropdown-item-hover</code></td><td><code>$dropdown-item-hover-color</code></td></tr>
<tr><td><code>$dropdown-item-active-background</code></td><td><code>$dropdown-item-active-background-color</code></td></tr>
<tr><td><code>$dropdown-item-active</code></td><td><code>$dropdown-item-active-color</code></td></tr>
<tr><td><code>$dropdown-divider-background</code></td><td><code>$dropdown-divider-background-color</code></td></tr>
<tr><td><code>$menu-item</code></td><td><code>$menu-item-color</code></td></tr>
<tr><td><code>$menu-item-hover</code></td><td><code>$menu-item-hover-color</code></td></tr>
<tr><td><code>$menu-item-hover-background</code></td><td><code>$menu-item-hover-background-color</code></td></tr>
<tr><td><code>$menu-item-active</code></td><td><code>$menu-item-active-color</code></td></tr>
<tr><td><code>$menu-item-active-background</code></td><td><code>$menu-item-active-background-color</code></td></tr>
<tr><td><code>$menu-label</code></td><td><code>$menu-label-color</code></td></tr>
<tr><td><code>$message-background</code></td><td><code>$message-background-color</code></td></tr>
<tr><td><code>$message-header-background</code></td><td><code>$message-header-background-color</code></td></tr>
<tr><td><code>$navbar-background</code></td><td><code>$navbar-background-color</code></td></tr>
<tr><td><code>$navbar-item</code></td><td><code>$navbar-item-color</code></td></tr>
<tr><td><code>$navbar-item-hover</code></td><td><code>$navbar-item-hover-color</code></td></tr>
<tr><td><code>$navbar-item-hover-background</code></td><td><code>$navbar-item-hover-background-color</code></td></tr>
<tr><td><code>$navbar-item-active</code></td><td><code>$navbar-item-active-color</code></td></tr>
<tr><td><code>$navbar-item-active-background</code></td><td><code>$navbar-item-active-background-color</code></td></tr>
<tr><td><code>$navbar-tab-hover-background</code></td><td><code>$navbar-tab-hover-background-color</code></td></tr>
<tr><td><code>$navbar-tab-hover-border-bottom</code></td><td><code>$navbar-tab-hover-border-bottom-color</code></td></tr>
<tr><td><code>$navbar-tab-active</code></td><td><code>$navbar-tab-active-color</code></td></tr>
<tr><td><code>$navbar-tab-active-background</code></td><td><code>$navbar-tab-active-background-color</code></td></tr>
<tr><td><code>$navbar-divider-background</code></td><td><code>$navbar-divider-background-color</code></td></tr>
<tr><td><code>$navbar-dropdown-item-hover</code></td><td><code>$navbar-dropdown-item-hover-color</code></td></tr>
<tr><td><code>$navbar-dropdown-item-hover-background</code></td><td><code>$navbar-dropdown-item-hover-background-color</code></td></tr>
<tr><td><code>$navbar-dropdown-item-active</code></td><td><code>$navbar-dropdown-item-active-color</code></td></tr>
<tr><td><code>$navbar-dropdown-item-active-background</code></td><td><code>$navbar-dropdown-item-active-background-color</code></td></tr>
<tr><td><code>$pagination</code></td><td><code>$pagination-color</code></td></tr>
<tr><td><code>$pagination-hover</code></td><td><code>$pagination-hover-color</code></td></tr>
<tr><td><code>$pagination-hover-border</code></td><td><code>$pagination-hover-border-color</code></td></tr>
<tr><td><code>$pagination-focus</code></td><td><code>$pagination-focus-color</code></td></tr>
<tr><td><code>$pagination-focus-border</code></td><td><code>$pagination-focus-border-color</code></td></tr>
<tr><td><code>$pagination-active</code></td><td><code>$pagination-active-color</code></td></tr>
<tr><td><code>$pagination-active-border</code></td><td><code>$pagination-active-border-color</code></td></tr>
<tr><td><code>$pagination-disabled</code></td><td><code>$pagination-disabled-color</code></td></tr>
<tr><td><code>$pagination-disabled-background</code></td><td><code>$pagination-disabled-background-color</code></td></tr>
<tr><td><code>$pagination-disabled-border</code></td><td><code>$pagination-disabled-border-color</code></td></tr>
<tr><td><code>$pagination-current</code></td><td><code>$pagination-current-color</code></td></tr>
<tr><td><code>$pagination-current-background</code></td><td><code>$pagination-current-background-color</code></td></tr>
<tr><td><code>$pagination-current-border</code></td><td><code>$pagination-current-border-color</code></td></tr>
<tr><td><code>$pagination-ellipsis</code></td><td><code>$pagination-ellipsis-color</code></td></tr>
<tr><td><code>$box</code></td><td><code>$box-color</code></td></tr>
<tr><td><code>$box-background</code></td><td><code>$box-background-color</code></td></tr>
<tr><td><code>$button</code></td><td><code>$button-color</code></td></tr>
<tr><td><code>$button-background</code></td><td><code>$button-background-color</code></td></tr>
<tr><td><code>$button-border</code></td><td><code>$button-border-color</code></td></tr>
<tr><td><code>$button-link</code></td><td><code>$button-link-color</code></td></tr>
<tr><td><code>$button-link-hover-background</code></td><td><code>$button-link-hover-background-color</code></td></tr>
<tr><td><code>$button-link-hover</code></td><td><code>$button-link-hover-color</code></td></tr>
<tr><td><code>$button-disabled-background</code></td><td><code>$button-disabled-background-color</code></td></tr>
<tr><td><code>$button-disabled-border</code></td><td><code>$button-disabled-border-color</code></td></tr>
<tr><td><code>$button-static</code></td><td><code>$button-static-color</code></td></tr>
<tr><td><code>$button-static-background</code></td><td><code>$button-static-background-color</code></td></tr>
<tr><td><code>$button-static-border</code></td><td><code>$button-static-border-color</code></td></tr>
<tr><td><code>$input</code></td><td><code>$input-color</code></td></tr>
<tr><td><code>$input-background</code></td><td><code>$input-background-color</code></td></tr>
<tr><td><code>$input-border</code></td><td><code>$input-border-color</code></td></tr>
<tr><td><code>$input-hover</code></td><td><code>$input-hover-color</code></td></tr>
<tr><td><code>$input-hover-border</code></td><td><code>$input-hover-border-color</code></td></tr>
<tr><td><code>$input-focus</code></td><td><code>$input-focus-color</code></td></tr>
<tr><td><code>$input-focus-border</code></td><td><code>$input-focus-border-color</code></td></tr>
<tr><td><code>$input-disabled</code></td><td><code>$input-disabled-color</code></td></tr>
<tr><td><code>$input-disabled-background</code></td><td><code>$input-disabled-background-color</code></td></tr>
<tr><td><code>$input-disabled-border</code></td><td><code>$input-disabled-border-color</code></td></tr>
<tr><td><code>$input-icon</code></td><td><code>$input-icon-color</code></td></tr>
<tr><td><code>$input-icon-active</code></td><td><code>$input-icon-active-color</code></td></tr>
<tr><td><code>$title</code></td><td><code>$title-color</code></td></tr>
<tr><td><code>$subtitle</code></td><td><code>$subtitle-color</code></td></tr>
<tr><td><code>$card-footer-border</code></td><td><code>$card-footer-border-top</code></td></tr>
<tr><td><code>$menu-list-border</code></td><td><code>$menu-list-border-left</code></td></tr>
<tr><td><code>$navbar-tab-hover-border</code></td><td><code>$navbar-tab-hover-border-bottom-color</code></td></tr>
<tr><td><code>$navbar-tab-active-border</code></td><td><code>$navbar-tab-active-border-bottom</code></td></tr>
<tr><td><code>$table-border</code></td><td><code>$table-cell-border</code></td></tr>
<tr><td><code>$table-row-even-background</code></td><td><code>$table-striped-row-even-background-color</code></td></tr>
<tr><td><code>$table-row-even-hover-background</code></td><td><code>$table-striped-row-even-hover-background-color</code></td></tr>
</table>
### Improved documentation
* [Starter template](http://bulma.io/documentation/overview/start/#starter-template)
* [Colors page](http://bulma.io/documentation/overview/colors/)
* [Typography helpers](http://bulma.io/documentation/modifiers/typography-helpers/)
* **Meta** information for all elements and components
* **Variables** information for most elements and components
### Issues closed
* #909 `.dropdown` wrapping
* #938 `.is-fullwidth` removed from docs
* #900 Variable `.navbar-item` for hover+active background/color
* #902 `.navbar-item` color overrides
## 0.4.4
### New features
* New [dropdown button](http://bulma.io/documentation/components/dropdown/)!
* The breakpoints and `.container` **gap** can be customized with the new `$gap` variable
* The `.container` has 2 new modifiers: `.is-widescreen` and `.is-fullhd`
### Issues closed
* Fix #26 `.textarea` element will honors `[rows]` attribute
* Fix #887 `body` scrollbar
* Fix #715 `.help` class behaviour in horizontal form `is-grouped` field
* Fix #842 Adding modifiers in `navbar`
* Fix #841 `.container` as direct child of `.navbar` moves `.navbar-menu` below `.navbar-brand`
* Fix #861 Box in hero as text and background white
* Fix #852 charset and version number
* Fix #856 JavaScript `.nav-burger` example
* Fix #821 Notification strong color
## 0.4.3
### New features
* New navbar with dropdown support
* Add new feature: Breadcrumb component (#632) @vinialbano
* Add Bloomer to README.md (#787) @AlgusDark
* Add responsive is-*-touch tags for .column sizes (#780) @tom-rb
* Adding 'is-hidden' to helpers in docs (#798) @aheuermann
* Add figure/figcaption as content element (#807) @werthen
* Add <sup> and <sub> support to content (#808) @werthen
* Add re-bulma and react-bulma (#809) @kulakowka
* Add is-halfheight to hero (#783) @felipeas
* Added a related project with Golang backend (#784) @Caiyeon
### Issues closed
* Fix #827 Breadcrumb and Navbar in docs
* Fix #824 Code examples broken because of `text-align: center`
* Fix #820 Loading spinner resizes with controls
* Fix #819 Remove `height: auto` from media elements
* Fix #790 Documentation typo
* Fix #814 Make use of +fullhd mixin for columns @Saboteur777
* Fix #781 Add min/max height/width to delete class size modifiers @ZackWard
* Fix #391 Section docs update
## 0.4.2
* Fix #728 selected row on striped table
* Fix #747 remove flex-shrink for is-expanded
* Fix #702 add icons support for select dropdown
* Fix #712 delete button as flexbox item
* Fix #759 static button
## 0.4.1
* Fix #568 max-width container
* Fix #589 notification delete
* Fix #272 nav-right without nav-menu
* Fix #616 hero and notification buttons
* Fix #607 has-addons z-index
* Feature #586 select color modifiers
* Fix #537 -ms-expand
* Fix #578 better `+center` mixin
* Fix #565 `dl` styles
* Fix #389 `pre` `margin-bottom`
* Fix #484 icon alignment
* Fix #506 bold nav menu
* Fix #581 nav container
* Fix #512 nav grouped buttons
* Fix #605 container example
* Fix #458 select expanded
* Fix #403 separate animations
* Fix #637 customize Bulma
* Fix #584 loading select
* Fix #571 control height
* Fix #634 is-grouped control
* Fix #676 checkbox/radio wrapping
* Feature #479 has-icons placement
* Fix #442 selected table row
* Fix #187 add customize page
* Fix #449 columns negative horizontal margin
* Fix #399 pagination wrapping
* Fix #227 color keys as strings
## 0.4.0
* **Default font-size is 16px**
* **New `.field` element ; `.control` repurposed**
* **New `.pagination` sizes**
* **New `$fullhd` breakpoint (1344px)**
* Remove monospace named fonts
* Remove icon spacing logic
* Split icon container dimensions and icon size
* Fix delete button by using pixels instead of (r)em
* Fix level on mobile
* Add new `.is-spaced` modifier for titles and subtitles
* Fix #487
* Fix #489
* Fix #502
* Fix #514
* Fix #524
* Fix #536
## 0.3.2
* Fix #478
## 0.3.1
* Fix #441
* Fix #443
## 0.3.0
* Use `rem` and `em` (!)
* Fix Font Awesome icons in buttons (!)
* Fix message colors (!)
* Use `{% capture %}` to ensure same display as code snippet (!)
* Move variables to their own file
* Remove small tag
* Add `:focus` state
* Fix table
* Remove table `.is-icon` and `.is-link`
* Add `.content` table
* Fix inputs with icons
* Input icons require the `.icon` container
* Deprecate `.media-number`
* Fix `.level-item` height
* Fix `.menu` spacing
* Deprecate `.menu-nav`
* Add invert outlined buttons
* Fix `.nav`
* Fix `.pagination`
* Fix `.tabs`
* Fix `.panel`
* Fix `.delete`
* Add mixins documentation
* Add functions documentation
## 0.2.2
* Fix: remove multiple imports
## 0.2.1
* Fix: container flex
* Fix: nav-item flex
* Fix: media-number flex
* Fix: new brand colors
## 0.2.0
* Added: new branding
* Added: modularity
* Added: grid folder
* Added: .github folder
## 0.1.1
* Remove `flex: 1` shorthand
## 0.1.0
* Fix #227
* Fix #232
* Fix #242
* Fix #243
* Fix #228
* Fix #245
* Fix #246
## 0.0.28
* BREAKING: `.control.is-grouped` now uses `.control` elements as direct children
* Fix #220
* Fix #214
* Fix #210
* Fix #206
* Fix #122
## 0.0.27
* Fix: #217
* Fix: #213
* Fix: #209
* Fix: #205
* Fix: #204
* Fix: #81
## 0.0.26
* Added: `.modal-card`
* Added: display responsive utilites
* Added: `.nav-center`
* Added: `.tabs ul` left center right
* Changed: `.navbar` renamed to `.level`
* Changed: `.header` renamed to `.nav`
* Deprecated: `.header`
* Deprecated: `.navbar`
* Fixed: `.hero` layout
## 0.0.25
* Added: `utilities/controls.sass` and `elements/form.sass`
* Added: new responsive classes
* Added: white/black and light/dark colors
* Changed: `.tabs` need `.icon` now
* Changed: cdnjs link doesn't include version
## 0.0.24
### Added
* `is-mobile` for the navbar
### Removed
* removed border between sections. Use `<hr class="is-marginless">` now
### Updated
* restructured files
* added back `inline-flex` for controls and tags
### Removed
* test tiles
## 0.0.23
### BREAKING
* `bulma` folder renamed to `sass` to avoid the redundant `bulma/bulma` path
* `variables.sass` moved to `/utilities`
* almost everything is singular now
* **elements** only have one class
* **components** have at least one sub-class
* `.content` moved to elements
* `.table` moved to elements
* `.message` moved to components
* `.table-icon`, `.table-link`, `.table-narrow` are now called `.is-icon`, `.is-link`, `.is-narrow`
### Added
* all variables are now `!default` so you can set your custom variables before importing Bulma
## 0.0.22
### Fixed
* links in hero subtitle
## 0.0.21
### Added
* `.column.is-narrow` to make a column `flex: none`
## 0.0.20
### Added
* `.has-icon` support for different `.input` sizes
## 0.0.19
### NEW!!!
* `.tile`
### BREAKING
* `.is-third` renamed to `.is-one-third`
* `.is-quarter` renamed to `.is-one-quarter`
### Added
* `.is-two-thirds`
* `.is-three-quarters`
### Changed
* `.delete` in `.tag` has no red
## 0.0.18
### BREAKING
* `.is-text-*` renamed to `.has-text-*`
* removed `.is-fullwidth` helper
### Added
* **small tag**: `.tag.is-small`
* 12th column classes
* `*-full` column classes
* `$family-code`
### Fixed
* disabled input with element
* `.table` last row with `th`
* `.card` color in `.hero`
* `.columns.is-gapless`
### Removed
* removed `box-shadow` from `.tag`
* custom checkboxes and radio buttons
### Updated
* `.tag` uses `display: inline-flex` now
## 0.0.17
### Added
* **pagination**: `.pagination`
* **horizontal forms**: `.control.is-horizontal`
* **help** text for form controls: `.help`
* **progress bars**: `.progress`
### Updated
* `.button` uses `display: inline-flex` now
* `.button` needs an `.icon` now
* `.control.is-grouped` renamed to `.control.has-addons`
* `.control.is-inline` renamed to `.control.is-grouped`
### Removed
* **helpers** `.is-inline` and `.is-block`

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Jeremy Thomas
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,92 @@
# [Bulma](http://bulma.io)
Bulma is a **modern CSS framework** based on [Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes).
<a target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/5pucRKHwhsqiAiYS1CdnS4SM/jgthms/bulma'> <img alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/5pucRKHwhsqiAiYS1CdnS4SM/jgthms/bulma.svg' /></a>
[![npm](https://img.shields.io/npm/v/bulma.svg)](https://www.npmjs.com/package/bulma)
[![npm](https://img.shields.io/npm/dm/bulma.svg)](https://www.npmjs.com/package/bulma)
[![Join the chat at https://gitter.im/jgthms/bulma](https://badges.gitter.im/jgthms/bulma.svg)](https://gitter.im/jgthms/bulma)
[![Build Status](https://travis-ci.org/jgthms/bulma.svg?branch=master)](https://travis-ci.org/jgthms/bulma)
<a href="http://bulma.io"><img src="https://raw.githubusercontent.com/jgthms/bulma/master/docs/images/bulma-banner.png" alt="Bulma: a Flexbox CSS framework" style="max-width:100%;" width="600" height="315"></a>
## Quick install
Bulma is constantly in development! Try it out now:
### NPM
```sh
npm install bulma
```
**or**
### Yarn
```sh
yarn add bulma
```
### Bower
```sh
bower install bulma
```
### CDN
[https://cdnjs.com/libraries/bulma](https://cdnjs.com/libraries/bulma)
Feel free to raise an issue or submit a pull request.
## CSS only
Bulma is a **CSS** framework. As such, the sole output is a single CSS file: [bulma.css](https://github.com/jgthms/bulma/blob/master/css/bulma.css)
You can either use that file, "out of the box", or download the Sass source files to customize the [variables](http://bulma.io/documentation/overview/variables/).
There is **no** JavaScript included. People generally want to use their own JS implementation (and usually already have one). Bulma can be considered "environment agnostic": it's just the style layer on top of the logic.
## Browser Support
Bulma uses [autoprefixer](https://github.com/postcss/autoprefixer) to make (most) Flexbox features compatible with earlier browser versions. According to [Can I use](http://caniuse.com/#feat=flexbox), Bulma is compatible with **recent** versions of:
* Chrome
* Edge
* Firefox
* Opera
* Safari
Internet Explorer (10+) is only partially supported.
## Documentation
The documentation resides in the [docs](docs) directory, and is built with the Ruby-based [Jekyll](https://jekyllrb.com/) tool.
Browse the [online documentation here.](http://bulma.io/documentation/overview/start/)
## Related projects
| Project | Description |
|------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| [Bulma with Attribute Modules](https://github.com/j5bot/bulma-attribute-selectors) | Adds support for attribute-based selectors. |
| [Bulma with Rails](https://github.com/joshuajansen/bulma-rails) | Integrates Bulma with the rails asset pipeline |
| [Vue Admin](https://github.com/vue-bulma/vue-admin) | Vue Admin framework powered by Bulma |
| [Bulmaswatch](https://github.com/jenil/bulmaswatch) | Free themes for Bulma |
| [Goldfish](https://github.com/Caiyeon/goldfish) | Vault UI with Bulma, Golang, and Vue Admin |
| [ember-bulma](https://github.com/open-tux/ember-bulma) | Ember addon providing a collection of UI components for Bulma |
| [Bloomer](https://bloomer.js.org) | A set of React components for Bulma |
| [Re-bulma](https://github.com/bokuweb/re-bulma) | Bulma components build with React |
| [React-bulma](https://github.com/kulakowka/react-bulma) | React.js components for Bulma |
| [Buefy](https://buefy.github.io) | Lightweight UI components for Vue.js based on Bulma |
| [vue-bulma-components](https://github.com/vouill/vue-bulma-components) | Bulma components for Vue.js with straightforward syntax |
| [BulmaJS](https://github.com/VizuaaLOG/BulmaJS) | Javascript integration for Bulma. Written in ES6 with a data-* API |
| [Bulma.styl](https://github.com/log1x/bulma.styl) | 1:1 Stylus translation of Bulma |
| [elm-bulma-classes](https://github.com/danielnarey/elm-bulma-classes) | Bulma prepared for usage with ELM |
| [Bulma Customizer](https://bulma-customizer.bstash.io/) | Bulma Customizer &#8211; Create your own **bespoke** Bulma build |
| [Fulma](https://mangelmaxime.github.io/Fulma/) | Wrapper around Bulma for [fable-react](https://github.com/fable-compiler/fable-react) |
## Copyright and license
Code copyright 2017 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/master/LICENSE).

View File

@ -0,0 +1,8 @@
@charset "utf-8"
/*! bulma.io v0.6.0 | MIT License | github.com/jgthms/bulma */
@import "sass/utilities/_all"
@import "sass/base/_all"
@import "sass/elements/_all"
@import "sass/components/_all"
@import "sass/grid/_all"
@import "sass/layout/_all"

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,116 @@
{
"_args": [
[
{
"raw": "bulma@0.6.0",
"scope": null,
"escapedName": "bulma",
"name": "bulma",
"rawSpec": "0.6.0",
"spec": "0.6.0",
"type": "version"
},
"/Users/jthomas/Desktop"
]
],
"_from": "bulma@0.6.0",
"_id": "bulma@0.6.0",
"_inCache": true,
"_location": "/bulma",
"_nodeVersion": "6.11.0",
"_npmOperationalInternal": {
"host": "s3://npm-registry-packages",
"tmp": "tmp/bulma-0.6.0.tgz_1507632062609_0.9745779144577682"
},
"_npmUser": {
"name": "jgthms",
"email": "bbxdesign@gmail.com"
},
"_npmVersion": "3.10.10",
"_phantomChildren": {},
"_requested": {
"raw": "bulma@0.6.0",
"scope": null,
"escapedName": "bulma",
"name": "bulma",
"rawSpec": "0.6.0",
"spec": "0.6.0",
"type": "version"
},
"_requiredBy": [
"#USER"
],
"_resolved": "https://registry.npmjs.org/bulma/-/bulma-0.6.0.tgz",
"_shasum": "4f5c5de582810d11aa0cfb1f30aec8a792d0d92c",
"_shrinkwrap": null,
"_spec": "bulma@0.6.0",
"_where": "/Users/jthomas/Desktop",
"author": {
"name": "Jeremy Thomas",
"email": "bbxdesign@gmail.com",
"url": "http://jgthms.com"
},
"bugs": {
"url": "https://github.com/jgthms/bulma/issues"
},
"dependencies": {},
"description": "Modern CSS framework based on Flexbox",
"devDependencies": {
"autoprefixer": "^7.1.1",
"node-sass": "^4.5.3",
"postcss-cli": "^4.1.0",
"rimraf": "^2.6.1"
},
"directories": {},
"dist": {
"shasum": "4f5c5de582810d11aa0cfb1f30aec8a792d0d92c",
"tarball": "https://registry.npmjs.org/bulma/-/bulma-0.6.0.tgz"
},
"files": [
"css",
"sass",
"bulma.sass",
"LICENSE",
"README.md"
],
"gitHead": "c39183cf474b99fb1c6b2dba8e0219a58d68c5be",
"homepage": "http://bulma.io",
"keywords": [
"css",
"sass",
"flexbox",
"responsive",
"framework"
],
"license": "MIT",
"main": "bulma.sass",
"maintainers": [
{
"name": "jgthms",
"email": "bbxdesign@gmail.com"
}
],
"name": "bulma",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/jgthms/bulma.git"
},
"scripts": {
"build": "npm run build-clean && npm run build-sass && npm run build-autoprefix",
"build-autoprefix": "postcss --use autoprefixer --map false --output css/bulma.css css/bulma.css",
"build-clean": "rimraf css",
"build-sass": "node-sass --output-style expanded --source-map true bulma.sass css/bulma.css",
"deploy": "npm run build && npm run docs",
"docs": "npm run docs-sass && npm run docs-autoprefix",
"docs-autoprefix": "postcss --use autoprefixer --map false --output docs/css/bulma-docs.css docs/css/bulma-docs.css",
"docs-sass": "node-sass --output-style expanded docs/bulma-docs.sass docs/css/bulma-docs.css",
"start": "npm run build-sass -- --watch",
"start-docs": "npm run docs-sass -- --watch",
"start-test": "npm run test-sass -- --watch",
"test-sass": "node-sass --output-style expanded docs/bulma-test.sass docs/css/bulma-test.css"
},
"style": "bulma/css/bulma.css",
"version": "0.6.0"
}

View File

@ -0,0 +1,5 @@
@charset "utf-8"
@import "minireset.sass"
@import "generic.sass"
@import "helpers.sass"

View File

@ -0,0 +1,127 @@
$body-background-color: #fff !default
$body-size: 16px !default
$body-rendering: optimizeLegibility !default
$body-family: $family-primary !default
$body-color: $text !default
$body-weight: $weight-normal !default
$body-line-height: 1.5 !default
$code-family: $family-code !default
$code-padding: 0.25em 0.5em 0.25em !default
$code-weight: normal !default
$code-size: 0.875em !default
$hr-background-color: $border !default
$hr-height: 1px !default
$hr-margin: 1.5rem 0 !default
$strong-color: $text-strong !default
$strong-weight: $weight-bold !default
html
background-color: $body-background-color
font-size: $body-size
-moz-osx-font-smoothing: grayscale
-webkit-font-smoothing: antialiased
min-width: 300px
overflow-x: hidden
overflow-y: scroll
text-rendering: $body-rendering
text-size-adjust: 100%
article,
aside,
figure,
footer,
header,
hgroup,
section
display: block
body,
button,
input,
select,
textarea
font-family: $body-family
code,
pre
-moz-osx-font-smoothing: auto
-webkit-font-smoothing: auto
font-family: $code-family
body
color: $body-color
font-size: 1rem
font-weight: $body-weight
line-height: $body-line-height
// Inline
a
color: $link
cursor: pointer
text-decoration: none
strong
color: currentColor
&:hover
color: $link-hover
code
background-color: $code-background
color: $code
font-size: $code-size
font-weight: $code-weight
padding: $code-padding
hr
background-color: $hr-background-color
border: none
display: block
height: $hr-height
margin: $hr-margin
img
height: auto
max-width: 100%
input[type="checkbox"],
input[type="radio"]
vertical-align: baseline
small
font-size: 0.875em
span
font-style: inherit
font-weight: inherit
strong
color: $strong-color
font-weight: $strong-weight
// Block
pre
+overflow-touch
background-color: $pre-background
color: $pre
font-size: 0.875em
overflow-x: auto
padding: 1.25rem 1.5rem
white-space: pre
word-wrap: normal
code
background-color: transparent
color: currentColor
font-size: 1em
padding: 0
table
td,
th
text-align: left
vertical-align: top
th
color: $text-strong

View File

@ -0,0 +1,203 @@
// Float
.is-clearfix
+clearfix
.is-pulled-left
float: left !important
.is-pulled-right
float: right !important
// Overflow
.is-clipped
overflow: hidden !important
// Overlay
.is-overlay
+overlay
// Typography
=typography-size($target:'')
@each $size in $sizes
$i: index($sizes, $size)
.is-size-#{$i}#{if($target == '', '', '-' + $target)}
font-size: $size !important
+typography-size()
+mobile
+typography-size('mobile')
+tablet
+typography-size('tablet')
+touch
+typography-size('touch')
+desktop
+typography-size('desktop')
+widescreen
+typography-size('widescreen')
+fullhd
+typography-size('fullhd')
$alignments: ('centered': 'center', 'justified': 'justify', 'left': 'left', 'right': 'right')
@each $alignment, $text-align in $alignments
.has-text-#{$alignment}
text-align: #{$text-align} !important
+mobile
.has-text-#{$alignment}-mobile
text-align: #{$text-align} !important
+tablet
.has-text-#{$alignment}-tablet
text-align: #{$text-align} !important
+tablet-only
.has-text-#{$alignment}-tablet-only
text-align: #{$text-align} !important
+touch
.has-text-#{$alignment}-touch
text-align: #{$text-align} !important
+desktop
.has-text-#{$alignment}-desktop
text-align: #{$text-align} !important
+desktop-only
.has-text-#{$alignment}-desktop-only
text-align: #{$text-align} !important
+widescreen
.has-text-#{$alignment}-widescreen
text-align: #{$text-align} !important
+widescreen-only
.has-text-#{$alignment}-widescreen-only
text-align: #{$text-align} !important
+fullhd
.has-text-#{$alignment}-fullhd
text-align: #{$text-align} !important
.is-capitalized
text-transform: capitalize !important
.is-lowercase
text-transform: lowercase !important
.is-uppercase
text-transform: uppercase !important
@each $name, $pair in $colors
$color: nth($pair, 1)
.has-text-#{$name}
color: $color !important
a.has-text-#{$name}
&:hover,
&:focus
color: darken($color, 10%) !important
@each $name, $shade in $shades
.has-text-#{$name}
color: $shade !important
.has-text-weight-light
font-weight: $weight-light !important
.has-text-weight-normal
font-weight: $weight-normal !important
.has-text-weight-semibold
font-weight: $weight-semibold !important
.has-text-weight-bold
font-weight: $weight-bold !important
// Visibility
$displays: 'block' 'flex' 'inline' 'inline-block' 'inline-flex'
@each $display in $displays
.is-#{$display}
display: #{$display} !important
+mobile
.is-#{$display}-mobile
display: #{$display} !important
+tablet
.is-#{$display}-tablet
display: #{$display} !important
+tablet-only
.is-#{$display}-tablet-only
display: #{$display} !important
+touch
.is-#{$display}-touch
display: #{$display} !important
+desktop
.is-#{$display}-desktop
display: #{$display} !important
+desktop-only
.is-#{$display}-desktop-only
display: #{$display} !important
+widescreen
.is-#{$display}-widescreen
display: #{$display} !important
+widescreen-only
.is-#{$display}-widescreen-only
display: #{$display} !important
+fullhd
.is-#{$display}-fullhd
display: #{$display} !important
.is-hidden
display: none !important
+mobile
.is-hidden-mobile
display: none !important
+tablet
.is-hidden-tablet
display: none !important
+tablet-only
.is-hidden-tablet-only
display: none !important
+touch
.is-hidden-touch
display: none !important
+desktop
.is-hidden-desktop
display: none !important
+desktop-only
.is-hidden-desktop-only
display: none !important
+widescreen
.is-hidden-widescreen
display: none !important
+widescreen-only
.is-hidden-widescreen-only
display: none !important
+fullhd
.is-hidden-fullhd
display: none !important
// Other
.is-marginless
margin: 0 !important
.is-paddingless
padding: 0 !important
.is-radiusless
border-radius: 0 !important
.is-shadowless
box-shadow: none !important
.is-unselectable
+unselectable

View File

@ -0,0 +1,80 @@
/*! minireset.css v0.0.2 | MIT License | github.com/jgthms/minireset.css */
// Blocks
html,
body,
p,
ol,
ul,
li,
dl,
dt,
dd,
blockquote,
figure,
fieldset,
legend,
textarea,
pre,
iframe,
hr,
h1,
h2,
h3,
h4,
h5,
h6
margin: 0
padding: 0
// Headings
h1,
h2,
h3,
h4,
h5,
h6
font-size: 100%
font-weight: normal
// List
ul
list-style: none
// Form
button,
input,
select,
textarea
margin: 0
// Box sizing
html
box-sizing: border-box
*
box-sizing: inherit
&:before,
&:after
box-sizing: inherit
// Media
img,
embed,
object,
audio,
video
max-width: 100%
// Iframe
iframe
border: 0
// Table
table
border-collapse: collapse
border-spacing: 0
td,
th
padding: 0
text-align: left

View File

@ -0,0 +1,14 @@
@charset "utf-8"
@import "breadcrumb.sass"
@import "card.sass"
@import "dropdown.sass"
@import "level.sass"
@import "media.sass"
@import "menu.sass"
@import "message.sass"
@import "modal.sass"
@import "navbar.sass"
@import "pagination.sass"
@import "panel.sass"
@import "tabs.sass"

View File

@ -0,0 +1,74 @@
$breadcrumb-item-color: $link !default
$breadcrumb-item-hover-color: $link-hover !default
$breadcrumb-item-active-color: $text-strong !default
$breadcrumb-item-separator-color: $text !default
.breadcrumb
+block
+unselectable
align-items: stretch
display: flex
font-size: $size-normal
overflow: hidden
overflow-x: auto
white-space: nowrap
a
align-items: center
color: $breadcrumb-item-color
display: flex
justify-content: center
padding: 0.5em 0.75em
&:hover
color: $breadcrumb-item-hover-color
li
align-items: center
display: flex
&:first-child a
padding-left: 0
&.is-active
a
color: $breadcrumb-item-active-color
cursor: default
pointer-events: none
& + li::before
color: $breadcrumb-item-separator-color
content: "\0002f"
ul, ol
align-items: center
display: flex
flex-grow: 1
flex-shrink: 0
justify-content: flex-start
.icon
&:first-child
margin-right: 0.5em
&:last-child
margin-left: 0.5em
// Alignment
&.is-centered
ol, ul
justify-content: center
&.is-right
ol, ul
justify-content: flex-end
// Sizes
&.is-small
font-size: $size-small
&.is-medium
font-size: $size-medium
&.is-large
font-size: $size-large
// Styles
&.has-arrow-separator
li + li::before
content: "\02192"
&.has-bullet-separator
li + li::before
content: "\02022"
&.has-dot-separator
li + li::before
content: "\000b7"
&.has-succeeds-separator
li + li::before
content: "\0227B"

View File

@ -0,0 +1,67 @@
$card-color: $text !default
$card-background-color: $white !default
$card-shadow: 0 2px 3px rgba($black, 0.1), 0 0 0 1px rgba($black, 0.1) !default
$card-header-color: $text-strong !default
$card-header-shadow: 0 1px 2px rgba($black, 0.1) !default
$card-header-weight: $weight-bold !default
$card-footer-border-top: 1px solid $border !default
.card
background-color: $card-background-color
box-shadow: $card-shadow
color: $card-color
max-width: 100%
position: relative
.card-header
align-items: stretch
box-shadow: $card-header-shadow
display: flex
.card-header-title
align-items: center
color: $card-header-color
display: flex
flex-grow: 1
font-weight: $card-header-weight
padding: 0.75rem
&.is-centered
justify-content: center
.card-header-icon
align-items: center
cursor: pointer
display: flex
justify-content: center
padding: 0.75rem
.card-image
display: block
position: relative
.card-content
padding: 1.5rem
.card-footer
border-top: $card-footer-border-top
align-items: stretch
display: flex
.card-footer-item
align-items: center
display: flex
flex-basis: 0
flex-grow: 1
flex-shrink: 0
justify-content: center
padding: 0.75rem
&:not(:last-child)
border-right: $card-footer-border-top
// Combinations
.card
.media:not(:last-child)
margin-bottom: 0.75rem

View File

@ -0,0 +1,74 @@
$dropdown-content-background-color: $white !default
$dropdown-content-arrow: $link !default
$dropdown-content-offset: 4px !default
$dropdown-content-radius: $radius !default
$dropdown-content-shadow: 0 2px 3px rgba($black, 0.1), 0 0 0 1px rgba($black, 0.1) !default
$dropdown-content-z: 20 !default
$dropdown-item-color: $grey-dark !default
$dropdown-item-hover-color: $black !default
$dropdown-item-hover-background-color: $background !default
$dropdown-item-active-color: $link-invert !default
$dropdown-item-active-background-color: $link !default
$dropdown-divider-background-color: $border !default
.dropdown
display: inline-flex
position: relative
vertical-align: top
&.is-active,
&.is-hoverable:hover
.dropdown-menu
display: block
&.is-right
.dropdown-menu
left: auto
right: 0
&.is-up
.dropdown-menu
bottom: 100%
padding-bottom: $dropdown-content-offset
padding-top: unset
top: auto
.dropdown-menu
display: none
left: 0
min-width: 12rem
padding-top: $dropdown-content-offset
position: absolute
top: 100%
z-index: $dropdown-content-z
.dropdown-content
background-color: $dropdown-content-background-color
border-radius: $dropdown-content-radius
box-shadow: $dropdown-content-shadow
padding-bottom: 0.5rem
padding-top: 0.5rem
.dropdown-item
color: $dropdown-item-color
display: block
font-size: 0.875rem
line-height: 1.5
padding: 0.375rem 1rem
position: relative
a.dropdown-item
padding-right: 3rem
white-space: nowrap
&:hover
background-color: $dropdown-item-hover-background-color
color: $dropdown-item-hover-color
&.is-active
background-color: $dropdown-item-active-background-color
color: $dropdown-item-active-color
.dropdown-divider
background-color: $dropdown-divider-background-color
border: none
display: block
height: 1px
margin: 0.5rem 0

View File

@ -0,0 +1,75 @@
.level
+block
align-items: center
justify-content: space-between
code
border-radius: $radius
img
display: inline-block
vertical-align: top
// Modifiers
&.is-mobile
display: flex
.level-left,
.level-right
display: flex
.level-left + .level-right
margin-top: 0
.level-item
&:not(:last-child)
margin-bottom: 0
&:not(.is-narrow)
flex-grow: 1
margin-right: 0.75rem
// Responsiveness
+tablet
display: flex
& > .level-item
&:not(.is-narrow)
flex-grow: 1
.level-item
align-items: center
display: flex
flex-basis: auto
flex-grow: 0
flex-shrink: 0
justify-content: center
.title,
.subtitle
margin-bottom: 0
// Responsiveness
+mobile
&:not(:last-child)
margin-bottom: 0.75rem
.level-left,
.level-right
flex-basis: auto
flex-grow: 0
flex-shrink: 0
.level-item
// Modifiers
&.is-flexible
flex-grow: 1
// Responsiveness
+tablet
&:not(:last-child)
margin-right: 0.75rem
.level-left
align-items: center
justify-content: flex-start
// Responsiveness
+mobile
& + .level-right
margin-top: 1.5rem
+tablet
display: flex
.level-right
align-items: center
justify-content: flex-end
// Responsiveness
+tablet
display: flex

View File

@ -0,0 +1,44 @@
.media
align-items: flex-start
display: flex
text-align: left
.content:not(:last-child)
margin-bottom: 0.75rem
.media
border-top: 1px solid rgba($border, 0.5)
display: flex
padding-top: 0.75rem
.content:not(:last-child),
.control:not(:last-child)
margin-bottom: 0.5rem
.media
padding-top: 0.5rem
& + .media
margin-top: 0.5rem
& + .media
border-top: 1px solid rgba($border, 0.5)
margin-top: 1rem
padding-top: 1rem
// Sizes
&.is-large
& + .media
margin-top: 1.5rem
padding-top: 1.5rem
.media-left,
.media-right
flex-basis: auto
flex-grow: 0
flex-shrink: 0
.media-left
margin-right: 1rem
.media-right
margin-left: 1rem
.media-content
flex-basis: auto
flex-grow: 1
flex-shrink: 1
text-align: left

View File

@ -0,0 +1,50 @@
$menu-item-color: $text !default
$menu-item-radius: $radius-small !default
$menu-item-hover-color: $text-strong !default
$menu-item-hover-background-color: $background !default
$menu-item-active-color: $link-invert !default
$menu-item-active-background-color: $link !default
$menu-list-border-left: 1px solid $border !default
$menu-label-color: $text-light !default
.menu
font-size: $size-normal
// Sizes
&.is-small
font-size: $size-small
&.is-medium
font-size: $size-medium
&.is-large
font-size: $size-large
.menu-list
line-height: 1.25
a
border-radius: $menu-item-radius
color: $menu-item-color
display: block
padding: 0.5em 0.75em
&:hover
background-color: $menu-item-hover-background-color
color: $menu-item-hover-color
// Modifiers
&.is-active
background-color: $menu-item-active-background-color
color: $menu-item-active-color
li
ul
border-left: $menu-list-border-left
margin: 0.75em
padding-left: 0.75em
.menu-label
color: $menu-label-color
font-size: 0.75em
letter-spacing: 0.1em
text-transform: uppercase
&:not(:first-child)
margin-top: 1em
&:not(:last-child)
margin-bottom: 1em

Some files were not shown because too many files have changed in this diff Show More