mirror of
https://git.kotyczka.ch/developers/django.git
synced 2025-04-05 15:25:08 +02:00
Merge branch 'develop' into 'main'
Initial Merge See merge request developers/django!1
This commit is contained in:
commit
66d8762e97
4
.gitignore
vendored
Executable file
4
.gitignore
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
virtualenv
|
||||
pyapp/queue/data/*
|
||||
pyapp/*/__pycache__
|
||||
.idea/
|
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
31
.idea/codeStyles
generated
Normal file
31
.idea/codeStyles
generated
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="false">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="false">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
</code_scheme>
|
||||
</component>
|
||||
</project>
|
6
.idea/copyright/amétiq.xml
generated
Normal file
6
.idea/copyright/amétiq.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="myName" value="amétiq" />
|
||||
<option name="notice" value="Copyright (c) &#36;today.year. by amétiq AG" />
|
||||
</copyright>
|
||||
</component>
|
408
.idea/dbnavigator.xml
generated
Normal file
408
.idea/dbnavigator.xml
generated
Normal file
@ -0,0 +1,408 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||
<autoscroll-to-editor value="false" />
|
||||
<autoscroll-from-editor value="true" />
|
||||
<show-object-properties value="true" />
|
||||
<loaded-nodes />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||
<open-files />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.Settings">
|
||||
<connections />
|
||||
<browser-settings>
|
||||
<general>
|
||||
<display-mode value="TABBED" />
|
||||
<navigation-history-size value="100" />
|
||||
<show-object-details value="false" />
|
||||
</general>
|
||||
<filters>
|
||||
<object-type-filter>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="true" />
|
||||
<object-type name="ROLE" enabled="true" />
|
||||
<object-type name="PRIVILEGE" enabled="true" />
|
||||
<object-type name="CHARSET" enabled="true" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||
<object-type name="NESTED_TABLE" enabled="true" />
|
||||
<object-type name="COLUMN" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="true" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||
<object-type name="ARGUMENT" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="true" />
|
||||
<object-type name="CLUSTER" enabled="true" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</object-type-filter>
|
||||
</filters>
|
||||
<sorting>
|
||||
<object-type name="COLUMN" sorting-type="NAME" />
|
||||
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
|
||||
</sorting>
|
||||
<default-editors>
|
||||
<object-type name="VIEW" editor-type="SELECTION" />
|
||||
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||
<object-type name="TYPE" editor-type="SELECTION" />
|
||||
</default-editors>
|
||||
</browser-settings>
|
||||
<navigation-settings>
|
||||
<lookup-filters>
|
||||
<lookup-objects>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="false" />
|
||||
<object-type name="ROLE" enabled="false" />
|
||||
<object-type name="PRIVILEGE" enabled="false" />
|
||||
<object-type name="CHARSET" enabled="false" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="false" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="false" />
|
||||
<object-type name="CLUSTER" enabled="false" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</lookup-objects>
|
||||
<force-database-load value="false" />
|
||||
<prompt-connection-selection value="true" />
|
||||
<prompt-schema-selection value="true" />
|
||||
</lookup-filters>
|
||||
</navigation-settings>
|
||||
<dataset-grid-settings>
|
||||
<general>
|
||||
<enable-zooming value="true" />
|
||||
<enable-column-tooltip value="true" />
|
||||
</general>
|
||||
<sorting>
|
||||
<nulls-first value="true" />
|
||||
<max-sorting-columns value="4" />
|
||||
</sorting>
|
||||
<audit-columns>
|
||||
<column-names value="" />
|
||||
<visible value="true" />
|
||||
<editable value="false" />
|
||||
</audit-columns>
|
||||
</dataset-grid-settings>
|
||||
<dataset-editor-settings>
|
||||
<text-editor-popup>
|
||||
<active value="false" />
|
||||
<active-if-empty value="false" />
|
||||
<data-length-threshold value="100" />
|
||||
<popup-delay value="1000" />
|
||||
</text-editor-popup>
|
||||
<values-actions-popup>
|
||||
<show-popup-button value="true" />
|
||||
<element-count-threshold value="1000" />
|
||||
<data-length-threshold value="250" />
|
||||
</values-actions-popup>
|
||||
<general>
|
||||
<fetch-block-size value="100" />
|
||||
<fetch-timeout value="30" />
|
||||
<trim-whitespaces value="true" />
|
||||
<convert-empty-strings-to-null value="true" />
|
||||
<select-content-on-cell-edit value="true" />
|
||||
<large-value-preview-active value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<prompt-filter-dialog value="true" />
|
||||
<default-filter-type value="BASIC" />
|
||||
</filters>
|
||||
<qualified-text-editor text-length-threshold="300">
|
||||
<content-types>
|
||||
<content-type name="Text" enabled="true" />
|
||||
<content-type name="Properties" enabled="true" />
|
||||
<content-type name="XML" enabled="true" />
|
||||
<content-type name="DTD" enabled="true" />
|
||||
<content-type name="HTML" enabled="true" />
|
||||
<content-type name="XHTML" enabled="true" />
|
||||
<content-type name="Java" enabled="true" />
|
||||
<content-type name="SQL" enabled="true" />
|
||||
<content-type name="PL/SQL" enabled="true" />
|
||||
<content-type name="JSON" enabled="true" />
|
||||
<content-type name="JSON5" enabled="true" />
|
||||
<content-type name="Groovy" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
<content-type name="Manifest" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
<record-navigation>
|
||||
<navigation-target value="VIEWER" />
|
||||
</record-navigation>
|
||||
</dataset-editor-settings>
|
||||
<code-editor-settings>
|
||||
<general>
|
||||
<show-object-navigation-gutter value="false" />
|
||||
<show-spec-declaration-navigation-gutter value="true" />
|
||||
<enable-spellchecking value="true" />
|
||||
<enable-reference-spellchecking value="false" />
|
||||
</general>
|
||||
<confirmations>
|
||||
<save-changes value="false" />
|
||||
<revert-changes value="true" />
|
||||
<exit-on-changes value="ASK" />
|
||||
</confirmations>
|
||||
</code-editor-settings>
|
||||
<code-completion-settings>
|
||||
<filters>
|
||||
<basic-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="false" />
|
||||
<filter-element type="OBJECT" id="view" selected="false" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||
<filter-element type="OBJECT" id="index" selected="false" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||
<filter-element type="OBJECT" id="function" selected="false" />
|
||||
<filter-element type="OBJECT" id="package" selected="false" />
|
||||
<filter-element type="OBJECT" id="type" selected="false" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</basic-filter>
|
||||
<extended-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</extended-filter>
|
||||
</filters>
|
||||
<sorting enabled="true">
|
||||
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||
<sorting-element type="OBJECT" id="column" />
|
||||
<sorting-element type="OBJECT" id="table" />
|
||||
<sorting-element type="OBJECT" id="view" />
|
||||
<sorting-element type="OBJECT" id="materialized view" />
|
||||
<sorting-element type="OBJECT" id="index" />
|
||||
<sorting-element type="OBJECT" id="constraint" />
|
||||
<sorting-element type="OBJECT" id="trigger" />
|
||||
<sorting-element type="OBJECT" id="synonym" />
|
||||
<sorting-element type="OBJECT" id="sequence" />
|
||||
<sorting-element type="OBJECT" id="procedure" />
|
||||
<sorting-element type="OBJECT" id="function" />
|
||||
<sorting-element type="OBJECT" id="package" />
|
||||
<sorting-element type="OBJECT" id="type" />
|
||||
<sorting-element type="OBJECT" id="dimension" />
|
||||
<sorting-element type="OBJECT" id="cluster" />
|
||||
<sorting-element type="OBJECT" id="dblink" />
|
||||
<sorting-element type="OBJECT" id="schema" />
|
||||
<sorting-element type="OBJECT" id="role" />
|
||||
<sorting-element type="OBJECT" id="user" />
|
||||
<sorting-element type="RESERVED_WORD" id="function" />
|
||||
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||
</sorting>
|
||||
<format>
|
||||
<enforce-code-style-case value="true" />
|
||||
</format>
|
||||
</code-completion-settings>
|
||||
<execution-engine-settings>
|
||||
<statement-execution>
|
||||
<fetch-block-size value="100" />
|
||||
<execution-timeout value="20" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<focus-result value="false" />
|
||||
<prompt-execution value="false" />
|
||||
</statement-execution>
|
||||
<script-execution>
|
||||
<command-line-interfaces />
|
||||
<execution-timeout value="300" />
|
||||
</script-execution>
|
||||
<method-execution>
|
||||
<execution-timeout value="30" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<parameter-history-size value="10" />
|
||||
</method-execution>
|
||||
</execution-engine-settings>
|
||||
<operation-settings>
|
||||
<transactions>
|
||||
<uncommitted-changes>
|
||||
<on-project-close value="ASK" />
|
||||
<on-disconnect value="ASK" />
|
||||
<on-autocommit-toggle value="ASK" />
|
||||
</uncommitted-changes>
|
||||
<multiple-uncommitted-changes>
|
||||
<on-commit value="ASK" />
|
||||
<on-rollback value="ASK" />
|
||||
</multiple-uncommitted-changes>
|
||||
</transactions>
|
||||
<session-browser>
|
||||
<disconnect-session value="ASK" />
|
||||
<kill-session value="ASK" />
|
||||
<reload-on-filter-change value="false" />
|
||||
</session-browser>
|
||||
<compiler>
|
||||
<compile-type value="KEEP" />
|
||||
<compile-dependencies value="ASK" />
|
||||
<always-show-controls value="false" />
|
||||
</compiler>
|
||||
</operation-settings>
|
||||
<ddl-file-settings>
|
||||
<extensions>
|
||||
<mapping file-type-id="VIEW" extensions="vw" />
|
||||
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||
</extensions>
|
||||
<general>
|
||||
<lookup-ddl-files value="true" />
|
||||
<create-ddl-files value="false" />
|
||||
<synchronize-ddl-files value="true" />
|
||||
<use-qualified-names value="false" />
|
||||
<make-scripts-rerunnable value="true" />
|
||||
</general>
|
||||
</ddl-file-settings>
|
||||
<general-settings>
|
||||
<regional-settings>
|
||||
<date-format value="MEDIUM" />
|
||||
<number-format value="UNGROUPED" />
|
||||
<locale value="SYSTEM_DEFAULT" />
|
||||
<use-custom-formats value="false" />
|
||||
</regional-settings>
|
||||
<environment>
|
||||
<environment-types>
|
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||
</environment-types>
|
||||
<visibility-settings>
|
||||
<connection-tabs value="true" />
|
||||
<dialog-headers value="true" />
|
||||
<object-editor-tabs value="true" />
|
||||
<script-editor-tabs value="false" />
|
||||
<execution-result-tabs value="true" />
|
||||
</visibility-settings>
|
||||
</environment>
|
||||
</general-settings>
|
||||
</component>
|
||||
</project>
|
3
.idea/dictionaries/kotyczka.xml
generated
Normal file
3
.idea/dictionaries/kotyczka.xml
generated
Normal file
@ -0,0 +1,3 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="kotyczka" />
|
||||
</component>
|
110
.idea/misc.xml
generated
Normal file
110
.idea/misc.xml
generated
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownProjectSettings" wasCopied="true">
|
||||
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="true" showSelectionInPreview="true" openRemoteLinks="true" replaceUnicodeEmoji="false" lastLayoutSetsDefault="false">
|
||||
<PanelProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
|
||||
</PanelProvider>
|
||||
</PreviewSettings>
|
||||
<ParserSettings gitHubSyntaxChange="false" emojiShortcuts="0" emojiImages="0">
|
||||
<PegdownExtensions>
|
||||
<option name="ABBREVIATIONS" value="false" />
|
||||
<option name="ANCHORLINKS" value="true" />
|
||||
<option name="ASIDE" value="false" />
|
||||
<option name="ATXHEADERSPACE" value="true" />
|
||||
<option name="AUTOLINKS" value="true" />
|
||||
<option name="DEFINITIONS" value="false" />
|
||||
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
|
||||
<option name="FENCED_CODE_BLOCKS" value="true" />
|
||||
<option name="FOOTNOTES" value="false" />
|
||||
<option name="HARDWRAPS" value="false" />
|
||||
<option name="HTML_DEEP_PARSER" value="false" />
|
||||
<option name="INSERTED" value="false" />
|
||||
<option name="QUOTES" value="false" />
|
||||
<option name="RELAXEDHRULES" value="true" />
|
||||
<option name="SMARTS" value="false" />
|
||||
<option name="STRIKETHROUGH" value="true" />
|
||||
<option name="SUBSCRIPT" value="false" />
|
||||
<option name="SUPERSCRIPT" value="false" />
|
||||
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
|
||||
<option name="SUPPRESS_INLINE_HTML" value="false" />
|
||||
<option name="TABLES" value="true" />
|
||||
<option name="TASKLISTITEMS" value="true" />
|
||||
<option name="TOC" value="false" />
|
||||
<option name="WIKILINKS" value="true" />
|
||||
</PegdownExtensions>
|
||||
<ParserOptions>
|
||||
<option name="ADMONITION_EXT" value="false" />
|
||||
<option name="ATTRIBUTES_EXT" value="false" />
|
||||
<option name="COMMONMARK_LISTS" value="false" />
|
||||
<option name="DUMMY" value="false" />
|
||||
<option name="EMOJI_SHORTCUTS" value="true" />
|
||||
<option name="ENUMERATED_REFERENCES_EXT" value="false" />
|
||||
<option name="FLEXMARK_FRONT_MATTER" value="false" />
|
||||
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="true" />
|
||||
<option name="GFM_TABLE_RENDERING" value="true" />
|
||||
<option name="GITBOOK_URL_ENCODING" value="false" />
|
||||
<option name="GITHUB_LISTS" value="true" />
|
||||
<option name="GITHUB_WIKI_LINKS" value="true" />
|
||||
<option name="GITLAB_EXT" value="false" />
|
||||
<option name="GITLAB_MATH_EXT" value="false" />
|
||||
<option name="GITLAB_MERMAID_EXT" value="false" />
|
||||
<option name="HEADER_ID_NON_ASCII_TO_LOWERCASE" value="false" />
|
||||
<option name="HEADER_ID_NO_DUPED_DASHES" value="false" />
|
||||
<option name="JEKYLL_FRONT_MATTER" value="false" />
|
||||
<option name="MACROS_EXT" value="false" />
|
||||
<option name="NO_TEXT_ATTRIBUTES" value="false" />
|
||||
<option name="PARSE_HTML_ANCHOR_ID" value="false" />
|
||||
<option name="PLANTUML_FENCED_CODE" value="false" />
|
||||
<option name="PUML_FENCED_CODE" value="false" />
|
||||
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
|
||||
</ParserOptions>
|
||||
</ParserSettings>
|
||||
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false" imageUriSerials="false" addDocTypeHtml="true" noParaTags="false" plantUmlConversion="0" mathConversion="-1">
|
||||
<GeneratorProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
|
||||
</GeneratorProvider>
|
||||
<headerTop />
|
||||
<headerBottom />
|
||||
<bodyTop />
|
||||
<bodyBottom />
|
||||
</HtmlSettings>
|
||||
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssUriSerial="true" isCssTextEnabled="false" isDynamicPageWidth="true">
|
||||
<StylesheetProvider>
|
||||
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
|
||||
</StylesheetProvider>
|
||||
<ScriptProviders />
|
||||
<cssText />
|
||||
<cssUriHistory />
|
||||
</CssSettings>
|
||||
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetPathType="2" targetExt="" useTargetExt="false" noCssNoScripts="false" useElementStyleAttribute="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
|
||||
<LinkMapSettings>
|
||||
<textMaps />
|
||||
</LinkMapSettings>
|
||||
</component>
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id />
|
||||
</State>
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="PyConsoleOptionsProvider">
|
||||
<option name="myShowDebugConsoleByDefault" value="true" />
|
||||
</component>
|
||||
<component name="uidesigner-configuration">
|
||||
<option name="INSTRUMENT_CLASSES" value="false" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/django.iml" filepath="$PROJECT_DIR$/django.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
17
.vscode/settings.json
vendored
Normal file
17
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"python.testing.pytestArgs": [
|
||||
"pyapp"
|
||||
],
|
||||
"python.testing.unittestEnabled": false,
|
||||
"python.testing.pytestEnabled": true,
|
||||
"sqltools.connections": [
|
||||
{
|
||||
"previewLimit": 50,
|
||||
"driver": "SQLite",
|
||||
"name": "test-db",
|
||||
"group": "django",
|
||||
"database": "${workspaceFolder:django}/pyapp/db.sqlite3"
|
||||
}
|
||||
],
|
||||
"sqltools.useNodeRuntime": true
|
||||
}
|
19
Dockerfile
Executable file
19
Dockerfile
Executable file
@ -0,0 +1,19 @@
|
||||
# Dockerfile
|
||||
|
||||
# The first instruction is what image we want to base our container on
|
||||
# We Use an official Python runtime as a parent image
|
||||
FROM python:3.11-bookworm
|
||||
|
||||
# Allows docker to cache installed dependencies between builds
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Mounts the application code to the image
|
||||
COPY ./demo /app
|
||||
WORKDIR /app
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
# runs the production server
|
||||
ENTRYPOINT ["python3", "manage.py"]
|
||||
CMD ["runserver", "0.0.0.0:8000"]
|
26
README.MD
Executable file
26
README.MD
Executable file
@ -0,0 +1,26 @@
|
||||
-- Tutorial of django
|
||||
https://duckduckgo.com/?q=django+tutorial&iax=videos&ia=videos&iai=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dsm1mokevMWk
|
||||
|
||||
-- Make a root folder named xy
|
||||
python3 -m venv virtualenv
|
||||
#### Activate the virutal environment
|
||||
source virtualenv/bin/activate
|
||||
#### Install django
|
||||
python3 -m pip install django
|
||||
## Start the project
|
||||
django-admin startproject pyapp
|
||||
## install an app
|
||||
python3 manage.py startapp pyapp
|
||||
|
||||
python3 manage.py createsuperuser
|
||||
python3 manage.py migrate
|
||||
|
||||
-- Django calling Rest Services ?
|
||||
python3 manage.py runserver
|
||||
|
||||
-- Django DB Initialisation
|
||||
# creating the model
|
||||
python3 manage.py makemigrations
|
||||
# creating the table
|
||||
python3 manage.py migrate
|
||||
|
1
build-docker-image.sh
Normal file
1
build-docker-image.sh
Normal file
@ -0,0 +1 @@
|
||||
docker build -f Dockerfile -t docker.kotyczka.ch/django-app:latest
|
9
django.iml
Normal file
9
django.iml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
30
docker-compose-queue.yml
Executable file
30
docker-compose-queue.yml
Executable file
@ -0,0 +1,30 @@
|
||||
version: '3'
|
||||
services:
|
||||
rabbitmq:
|
||||
image: rabbitmq:management
|
||||
container_name: mq
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- RABBITMQ_DEFAULT_USER=mqadmin
|
||||
- RABBITMQ_DEFAULT_PASS=3Mnj29jKBsFybc
|
||||
# - RABBITMQ_SSL_CERTFILE=/cert_rabbitmq/testca/cacert.pem
|
||||
# - RABBITMQ_SSL_KEYFILE=/cert_rabbitmq/server/cert.pem
|
||||
# - RABBITMQ_SSL_CACERTFILE=/cert_rabbitmq/server/key.pem
|
||||
ports:
|
||||
# The standard AMQP protocol port
|
||||
- '5672:5672'
|
||||
# HTTP management UI
|
||||
- '15672:15672'
|
||||
volumes:
|
||||
- ./demo/pyapp/queue/data/:/var/lib/rabbitmq/
|
||||
- ./demo/pyapp/queue/log/:/var/log/rabbitmq/
|
||||
- ./data:/var/lib/rabbitmq/
|
||||
# - ./certs/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
|
||||
# - ./certs/root.crt:/etc/ssl/rmq-cacert.pem:ro
|
||||
# - ./certs/server.crt:/etc/ssl/rmq-cert.pem:ro
|
||||
# - ./certs/server.key:/etc/ssl/rmq-key.pem:ro
|
||||
networks:
|
||||
- ametiq
|
||||
networks:
|
||||
ametiq:
|
||||
external: true
|
16
docker-compose.yml
Executable file
16
docker-compose.yml
Executable file
@ -0,0 +1,16 @@
|
||||
version: '3'
|
||||
services:
|
||||
django:
|
||||
container_name: demo
|
||||
image: docker.kotyczka.ch/django-app:latest
|
||||
build:
|
||||
context: .
|
||||
ports:
|
||||
- "9000:8000"
|
||||
- "7070:8080"
|
||||
networks:
|
||||
- ametiq
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
ametiq:
|
||||
external: true
|
BIN
pyapp/db.sqlite3
Executable file
BIN
pyapp/db.sqlite3
Executable file
Binary file not shown.
22
pyapp/manage.py
Executable file
22
pyapp/manage.py
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE','pyapp.settings')
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
0
pyapp/pyapp/__init__.py
Executable file
0
pyapp/pyapp/__init__.py
Executable file
BIN
pyapp/pyapp/__pycache__/__init__.cpython-311.pyc
Executable file
BIN
pyapp/pyapp/__pycache__/__init__.cpython-311.pyc
Executable file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/admin.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/admin.cpython-311.pyc
Normal file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/apps.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/apps.cpython-311.pyc
Normal file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/models.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/models.cpython-311.pyc
Normal file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/settings.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/settings.cpython-311.pyc
Normal file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/urls.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/urls.cpython-311.pyc
Normal file
Binary file not shown.
BIN
pyapp/pyapp/__pycache__/wsgi.cpython-311.pyc
Normal file
BIN
pyapp/pyapp/__pycache__/wsgi.cpython-311.pyc
Normal file
Binary file not shown.
5
pyapp/pyapp/admin.py
Executable file
5
pyapp/pyapp/admin.py
Executable file
@ -0,0 +1,5 @@
|
||||
from django.contrib import admin
|
||||
from pyapp.models import ShoppingItem
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(ShoppingItem)
|
5
pyapp/pyapp/apps.py
Executable file
5
pyapp/pyapp/apps.py
Executable file
@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
class PyappConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'pyapp'
|
16
pyapp/pyapp/asgi.py
Executable file
16
pyapp/pyapp/asgi.py
Executable file
@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for pyapp project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pyapp.settings')
|
||||
|
||||
application = get_asgi_application()
|
18
pyapp/pyapp/models.py
Executable file
18
pyapp/pyapp/models.py
Executable file
@ -0,0 +1,18 @@
|
||||
from django.db import models
|
||||
from datetime import date
|
||||
|
||||
|
||||
class ShoppingItem(models.Model):
|
||||
created_at = models.DateField(default=date.today)
|
||||
name = models.CharField(max_length=120)
|
||||
done = models.BooleanField(default=False)
|
||||
price = models.DecimalField(max_digits=10, decimal_places=2, default = 0.0)
|
||||
quantity = models.PositiveIntegerField()
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id) + ' - ' + self.name
|
||||
|
||||
class Product(models.Model):
|
||||
title = models.CharField(max_length=120)
|
||||
content= models.TextField(blank=True, null=True)
|
||||
price = models.DecimalField(max_digits=15,decimal_places=2,default=99.99)
|
BIN
pyapp/pyapp/queue/__pycache__/config.cpython-311.pyc
Executable file
BIN
pyapp/pyapp/queue/__pycache__/config.cpython-311.pyc
Executable file
Binary file not shown.
45
pyapp/pyapp/queue/ampq_client.py
Executable file
45
pyapp/pyapp/queue/ampq_client.py
Executable file
@ -0,0 +1,45 @@
|
||||
import optparse
|
||||
from proton import Message
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton.reactor import Container
|
||||
|
||||
|
||||
class Client(MessagingHandler):
|
||||
def __init__(self, url, requests):
|
||||
super(Client, self).__init__()
|
||||
self.url = url
|
||||
self.requests = requests
|
||||
|
||||
def on_start(self, event):
|
||||
self.sender = event.container.create_sender(self.url)
|
||||
self.receiver = event.container.create_receiver(self.sender.connection, None, dynamic=True)
|
||||
|
||||
def next_request(self):
|
||||
if self.receiver.remote_source.address:
|
||||
req = Message(reply_to=self.receiver.remote_source.address, body=self.requests[0])
|
||||
self.sender.send(req)
|
||||
|
||||
def on_link_opened(self, event):
|
||||
if event.receiver == self.receiver:
|
||||
self.next_request()
|
||||
|
||||
def on_message(self, event):
|
||||
print("%s => %s" % (self.requests.pop(0), event.message.body))
|
||||
if self.requests:
|
||||
self.next_request()
|
||||
else:
|
||||
event.connection.close()
|
||||
|
||||
|
||||
REQUESTS = ["Twas brillig, and the slithy toves",
|
||||
"Did gire and gymble in the wabe.",
|
||||
"All mimsy were the borogroves,",
|
||||
"And the mome raths outgrabe."]
|
||||
|
||||
parser = optparse.OptionParser(usage="usage: %prog [options]",
|
||||
description="Send requests to the supplied address and print responses.")
|
||||
parser.add_option("-a", "--address", default="localhost:5672/examples",
|
||||
help="address to which messages are sent (default %default)")
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
Container(Client(opts.address, args or REQUESTS)).run()
|
29
pyapp/pyapp/queue/ampq_receiver.py
Executable file
29
pyapp/pyapp/queue/ampq_receiver.py
Executable file
@ -0,0 +1,29 @@
|
||||
import optparse
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
from proton import Message
|
||||
from proton.utils import BlockingConnection
|
||||
from proton.handlers import IncomingMessageHandler
|
||||
|
||||
broker = '5672' ##os.getenv('AMQP_BROKER_HOST_PORT')
|
||||
queue = 'proton' ##os.getenv('AMQP_ADDRESS')
|
||||
user_arg = 'smx' ##os.getenv('AMQP_USER')
|
||||
userpw_arg = 'smx' ##os.getenv('AMQP_USER_PASSWORD')
|
||||
|
||||
conn = BlockingConnection(broker, user=user_arg, password=userpw_arg)
|
||||
receiver = conn.create_receiver(queue)
|
||||
|
||||
count = 0
|
||||
try:
|
||||
while True:
|
||||
msg = receiver.receive(timeout=None)
|
||||
count += 1
|
||||
print("got message, processing for two seconds...")
|
||||
sys.stdout.flush()
|
||||
time.sleep(2)
|
||||
receiver.accept()
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
print ("All done. Processed ", count, " messages.")
|
52
pyapp/pyapp/queue/ampq_sender.py
Executable file
52
pyapp/pyapp/queue/ampq_sender.py
Executable file
@ -0,0 +1,52 @@
|
||||
from __future__ import print_function, unicode_literals
|
||||
import optparse
|
||||
from proton import Message
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton.reactor import Container
|
||||
from proton.utils import BlockingConnection
|
||||
from django.conf import settings
|
||||
|
||||
broker = '5672' ##os.getenv('AMQP_BROKER_HOST_PORT')
|
||||
queue = 'proton' ##os.getenv('AMQP_ADDRESS')
|
||||
user_arg = 'smx' ##os.getenv('AMQP_USER')
|
||||
userpw_arg = 'smx' ##os.getenv('AMQP_USER_PASSWORD')
|
||||
|
||||
class Send(MessagingHandler):
|
||||
def __init__(self, url, messages):
|
||||
super(Send, self).__init__()
|
||||
self.url = url
|
||||
self.sent = 0
|
||||
self.confirmed = 0
|
||||
self.total = messages
|
||||
|
||||
def on_start(self, event):
|
||||
event.container.create_sender(self.url)
|
||||
|
||||
def on_sendable(self, event):
|
||||
while event.sender.credit and self.sent < self.total:
|
||||
msg = Message(id=(self.sent+1), body={'sequence':(self.sent+1)})
|
||||
event.sender.send(msg)
|
||||
self.sent += 1
|
||||
|
||||
def on_accepted(self, event):
|
||||
self.confirmed += 1
|
||||
if self.confirmed == self.total:
|
||||
print("all messages confirmed")
|
||||
event.connection.close()
|
||||
|
||||
def on_disconnected(self, event):
|
||||
self.sent = self.confirmed
|
||||
|
||||
conn = BlockingConnection(broker, user=user_arg, password=userpw_arg)
|
||||
|
||||
parser = optparse.OptionParser(usage="usage: %prog [options]",
|
||||
description="Send messages to the supplied address.")
|
||||
parser.add_option("-a", "--address", default="0.0.0.0:16161/examples",
|
||||
help="address to which messages are sent (default %default)")
|
||||
parser.add_option("-m", "--messages", type="int", default=100,
|
||||
help="number of messages to send (default %default)")
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
try:
|
||||
Container(Send(opts.address, opts.messages)).run()
|
||||
except KeyboardInterrupt: pass
|
51
pyapp/pyapp/queue/ampq_server.py
Executable file
51
pyapp/pyapp/queue/ampq_server.py
Executable file
@ -0,0 +1,51 @@
|
||||
import optparse
|
||||
import sys
|
||||
from proton import Condition, Message, Url
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton.reactor import Container
|
||||
|
||||
exit_status = 0
|
||||
|
||||
|
||||
class Server(MessagingHandler):
|
||||
def __init__(self, url, address):
|
||||
super(Server, self).__init__()
|
||||
self.url = url
|
||||
self.address = address
|
||||
|
||||
def on_start(self, event):
|
||||
print("Listening on", self.url)
|
||||
self.container = event.container
|
||||
self.conn = event.container.connect(self.url, desired_capabilities="ANONYMOUS-RELAY")
|
||||
|
||||
def on_connection_opened(self, event):
|
||||
if event.connection.remote_offered_capabilities and 'ANONYMOUS-RELAY' in event.connection.remote_offered_capabilities:
|
||||
self.receiver = event.container.create_receiver(self.conn, self.address)
|
||||
self.server = self.container.create_sender(self.conn, None)
|
||||
else:
|
||||
global exit_status
|
||||
print("Server needs a broker which supports ANONYMOUS-RELAY", file=sys.stderr)
|
||||
exit_status = 1
|
||||
c = event.connection
|
||||
c.condition = Condition('amqp:not-implemented', description="ANONYMOUS-RELAY required")
|
||||
c.close()
|
||||
|
||||
def on_message(self, event):
|
||||
print("Received", event.message)
|
||||
self.server.send(Message(address=event.message.reply_to, body=event.message.body.upper(),
|
||||
correlation_id=event.message.correlation_id))
|
||||
|
||||
|
||||
parser = optparse.OptionParser(usage="usage: %prog [options]")
|
||||
parser.add_option("-a", "--address", default="localhost:5672/examples",
|
||||
help="address from which messages are received (default %default)")
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
url = Url(opts.address)
|
||||
|
||||
try:
|
||||
Container(Server(url, url.path)).run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
sys.exit(exit_status)
|
96
pyapp/pyapp/queue/client_http.py
Executable file
96
pyapp/pyapp/queue/client_http.py
Executable file
@ -0,0 +1,96 @@
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
from tornado.gen import coroutine
|
||||
from tornado.concurrent import Future
|
||||
from proton import Message
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton_tornado import Container
|
||||
|
||||
|
||||
class Client(MessagingHandler):
|
||||
def __init__(self, host, address):
|
||||
super(Client, self).__init__()
|
||||
self.host = host
|
||||
self.address = address
|
||||
self.sent = []
|
||||
self.pending = []
|
||||
self.reply_address = None
|
||||
self.sender = None
|
||||
self.receiver = None
|
||||
|
||||
def on_start(self, event):
|
||||
conn = event.container.connect(self.host)
|
||||
self.sender = event.container.create_sender(conn, self.address)
|
||||
self.receiver = event.container.create_receiver(conn, None, dynamic=True)
|
||||
|
||||
def on_link_opened(self, event):
|
||||
if event.receiver == self.receiver:
|
||||
self.reply_address = event.link.remote_source.address
|
||||
self.do_request()
|
||||
|
||||
def on_sendable(self, event):
|
||||
self.do_request()
|
||||
|
||||
def on_message(self, event):
|
||||
if self.sent:
|
||||
request, future = self.sent.pop(0)
|
||||
print("%s => %s" % (request, event.message.body))
|
||||
future.set_result(event.message.body)
|
||||
self.do_request()
|
||||
|
||||
def do_request(self):
|
||||
if self.pending and self.reply_address and self.sender.credit:
|
||||
request, future = self.pending.pop(0)
|
||||
self.sent.append((request, future))
|
||||
req = Message(reply_to=self.reply_address, body=request)
|
||||
self.sender.send(req)
|
||||
|
||||
def request(self, body):
|
||||
future = Future()
|
||||
self.pending.append((body, future))
|
||||
self.do_request()
|
||||
self.container.touch()
|
||||
return future
|
||||
|
||||
|
||||
class ExampleHandler(tornado.web.RequestHandler):
|
||||
def initialize(self, client):
|
||||
self.client = client
|
||||
|
||||
def get(self):
|
||||
self._write_open()
|
||||
self._write_form()
|
||||
self._write_close()
|
||||
|
||||
@coroutine
|
||||
def post(self):
|
||||
response = yield self.client.request(self.get_body_argument("message"))
|
||||
self.set_header("Content-Type", "text/html")
|
||||
self._write_open()
|
||||
self._write_form()
|
||||
self.write("Response: " + response)
|
||||
self._write_close()
|
||||
|
||||
def _write_open(self):
|
||||
self.write('<html><body>')
|
||||
|
||||
def _write_close(self):
|
||||
self.write('</body></html>')
|
||||
|
||||
def _write_form(self):
|
||||
self.write('<form action="/client" method="POST">'
|
||||
'Request: <input type="text" name="message">'
|
||||
'<input type="submit" value="Submit">'
|
||||
'</form>')
|
||||
|
||||
|
||||
loop = tornado.ioloop.IOLoop.instance()
|
||||
client = Client("localhost:5672", "examples")
|
||||
client.container = Container(client, loop=loop)
|
||||
client.container.initialise()
|
||||
app = tornado.web.Application([tornado.web.url(r"/client", ExampleHandler, dict(client=client))])
|
||||
app.listen(8888)
|
||||
try:
|
||||
loop.start()
|
||||
except KeyboardInterrupt:
|
||||
loop.stop()
|
5
pyapp/pyapp/queue/config.py
Executable file
5
pyapp/pyapp/queue/config.py
Executable file
@ -0,0 +1,5 @@
|
||||
username = 'smx'
|
||||
password = 'smx'
|
||||
|
||||
#username = 'mqadmin'
|
||||
#password = '3Mnj29jKBsFybc'
|
0
pyapp/pyapp/queue/connect.json
Executable file
0
pyapp/pyapp/queue/connect.json
Executable file
79
pyapp/pyapp/queue/db_receive.py
Executable file
79
pyapp/pyapp/queue/db_receive.py
Executable file
@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import optparse
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton.reactor import ApplicationEvent, Container, EventInjector
|
||||
from db_common import Db
|
||||
|
||||
|
||||
class Recv(MessagingHandler):
|
||||
def __init__(self, url, count):
|
||||
super(Recv, self).__init__(auto_accept=False)
|
||||
self.url = url
|
||||
self.delay = 0
|
||||
self.last_id = None
|
||||
self.expected = count
|
||||
self.received = 0
|
||||
self.accepted = 0
|
||||
self.db = Db("dst_db", EventInjector())
|
||||
|
||||
def on_start(self, event):
|
||||
event.container.selectable(self.db.injector)
|
||||
e = ApplicationEvent("id_loaded")
|
||||
e.container = event.container
|
||||
self.db.get_id(e)
|
||||
|
||||
def on_id_loaded(self, event):
|
||||
self.last_id = event.id
|
||||
event.container.create_receiver(self.url)
|
||||
|
||||
def on_record_inserted(self, event):
|
||||
self.accept(event.delivery)
|
||||
self.accepted += 1
|
||||
if self.accepted == self.expected:
|
||||
event.connection.close()
|
||||
self.db.close()
|
||||
|
||||
def on_message(self, event):
|
||||
id = int(event.message.id)
|
||||
if (not self.last_id) or id > self.last_id:
|
||||
if self.expected == 0 or self.received < self.expected:
|
||||
self.received += 1
|
||||
self.last_id = id
|
||||
self.db.insert(id, event.message.body, ApplicationEvent("record_inserted", delivery=event.delivery))
|
||||
print("inserted message %s" % id)
|
||||
else:
|
||||
self.release(event.delivery)
|
||||
else:
|
||||
self.accept(event.delivery)
|
||||
|
||||
|
||||
parser = optparse.OptionParser(usage="usage: %prog [options]")
|
||||
parser.add_option("-a", "--address", default="localhost:5672/examples",
|
||||
help="address from which messages are received (default %default)")
|
||||
parser.add_option("-m", "--messages", type="int", default=0,
|
||||
help="number of messages to receive; 0 receives indefinitely (default %default)")
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
try:
|
||||
Container(Recv(opts.address, opts.messages)).run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
110
pyapp/pyapp/queue/db_send.py
Executable file
110
pyapp/pyapp/queue/db_send.py
Executable file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import optparse
|
||||
import queue
|
||||
|
||||
|
||||
from proton import Message
|
||||
from proton.handlers import MessagingHandler
|
||||
from proton.reactor import ApplicationEvent, Container, EventInjector
|
||||
from db_common import Db
|
||||
|
||||
|
||||
class Send(MessagingHandler):
|
||||
def __init__(self, url, count):
|
||||
super(Send, self).__init__()
|
||||
self.url = url
|
||||
self.delay = 0
|
||||
self.sent = 0
|
||||
self.confirmed = 0
|
||||
self.load_count = 0
|
||||
self.records = queue.Queue(maxsize=50)
|
||||
self.target = count
|
||||
self.db = Db("src_db", EventInjector())
|
||||
|
||||
def keep_sending(self):
|
||||
return self.target == 0 or self.sent < self.target
|
||||
|
||||
def on_start(self, event):
|
||||
self.container = event.container
|
||||
self.container.selectable(self.db.injector)
|
||||
self.sender = self.container.create_sender(self.url)
|
||||
|
||||
def on_records_loaded(self, event):
|
||||
if self.records.empty():
|
||||
if event.subject == self.load_count:
|
||||
print("Exhausted available data, waiting to recheck...")
|
||||
# check for new data after 5 seconds
|
||||
self.container.schedule(5, self)
|
||||
else:
|
||||
self.send()
|
||||
|
||||
def request_records(self):
|
||||
if not self.records.full():
|
||||
print("loading records...")
|
||||
self.load_count += 1
|
||||
self.db.load(self.records, event=ApplicationEvent(
|
||||
"records_loaded", link=self.sender, subject=self.load_count))
|
||||
|
||||
def on_sendable(self, event):
|
||||
self.send()
|
||||
|
||||
def send(self):
|
||||
while self.sender.credit and not self.records.empty():
|
||||
if not self.keep_sending():
|
||||
return
|
||||
record = self.records.get(False)
|
||||
id = record['id']
|
||||
self.sender.send(Message(id=id, durable=True, body=record['description']), tag=str(id))
|
||||
self.sent += 1
|
||||
print("sent message %s" % id)
|
||||
self.request_records()
|
||||
|
||||
def on_settled(self, event):
|
||||
id = int(event.delivery.tag)
|
||||
self.db.delete(id)
|
||||
print("settled message %s" % id)
|
||||
self.confirmed += 1
|
||||
if self.confirmed == self.target:
|
||||
event.connection.close()
|
||||
self.db.close()
|
||||
|
||||
def on_disconnected(self, event):
|
||||
self.db.reset()
|
||||
self.sent = self.confirmed
|
||||
|
||||
def on_timer_task(self, event):
|
||||
print("Rechecking for data...")
|
||||
self.request_records()
|
||||
|
||||
|
||||
parser = optparse.OptionParser(usage="usage: %prog [options]",
|
||||
description="Send messages to the supplied address.")
|
||||
parser.add_option("-a", "--address", default="localhost:5672/examples",
|
||||
help="address to which messages are sent (default %default)")
|
||||
parser.add_option("-m", "--messages", type="int", default=0,
|
||||
help="number of messages to send; 0 sends indefinitely (default %default)")
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
try:
|
||||
Container(Send(opts.address, opts.messages)).run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
22
pyapp/pyapp/queue/queue_consumer.py
Executable file
22
pyapp/pyapp/queue/queue_consumer.py
Executable file
@ -0,0 +1,22 @@
|
||||
import pika, time, config
|
||||
#declaring the credentials needed for connection like host, port, username, password, exchange etc
|
||||
credentials= pika.PlainCredentials(username= config.username, password= config.password)
|
||||
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
|
||||
channel = connection.channel()
|
||||
channel.exchange_declare('pydev', durable=True, exchange_type='topic')
|
||||
#defining callback functions responding to corresponding queue callbacks
|
||||
def callbackFunctionForQueueA(ch,method,properties,body):
|
||||
print('Got a message from Queue A: ', body)
|
||||
def callbackFunctionForQueueB(ch,method,properties,body):
|
||||
print('Got a message from Queue B: ', body)
|
||||
def callbackFunctionForQueueC(ch,method,properties,body):
|
||||
print('Got a message from Queue C: ', body)
|
||||
#Attaching consumer callback functions to respective queues that we wrote above
|
||||
channel.basic_consume(queue='A', on_message_callback=callbackFunctionForQueueA, auto_ack=True)
|
||||
channel.basic_consume(queue='B', on_message_callback=callbackFunctionForQueueB, auto_ack=True)
|
||||
channel.basic_consume(queue='C', on_message_callback=callbackFunctionForQueueC, auto_ack=True)
|
||||
#this will be command for starting the consumer session
|
||||
channel.start_consuming()
|
||||
##time.sleep(2)
|
||||
##channel.stop_consuming()
|
||||
channel.close()
|
23
pyapp/pyapp/queue/queue_producer.py
Executable file
23
pyapp/pyapp/queue/queue_producer.py
Executable file
@ -0,0 +1,23 @@
|
||||
import pika
|
||||
##import amqp
|
||||
import config
|
||||
#declaring the credentials needed for connection like host, port, username, password, exchange etc
|
||||
credentials= pika.PlainCredentials(username= config.username, password= config.password)
|
||||
connection= pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=61616, credentials= credentials))
|
||||
channel = connection.channel()
|
||||
channel.exchange_declare(exchange='pydev', durable=True, exchange_type='topic')
|
||||
channel.queue_declare(queue= 'A')
|
||||
channel.queue_bind(exchange='pydev', queue='A', routing_key='A')
|
||||
channel.queue_declare(queue= 'B')
|
||||
channel.queue_bind(exchange='pydev', queue='B', routing_key='B')
|
||||
channel.queue_declare(queue= 'C')
|
||||
channel.queue_bind(exchange='pydev', queue='C', routing_key='C')
|
||||
#messaging to queue named C
|
||||
message_spec= 'Only this channel can see this message'
|
||||
message_all= 'Welcome to python queue handling...'
|
||||
channel.basic_publish(exchange='pydev', routing_key='A', body= message_all)
|
||||
channel.basic_publish(exchange='pydev', routing_key='B', body= message_all)
|
||||
channel.basic_publish(exchange='pydev', routing_key='C', body= message_all)
|
||||
channel.basic_publish(exchange='pydev', routing_key='B', body= message_spec)
|
||||
channel.basic_publish(exchange='pydev', routing_key='C', body= message_spec)
|
||||
channel.close()
|
6
pyapp/pyapp/queue/send.py
Executable file
6
pyapp/pyapp/queue/send.py
Executable file
@ -0,0 +1,6 @@
|
||||
import stomp
|
||||
|
||||
conn = stomp.Connection()
|
||||
conn.connect('smx', 'smx', wait=True)
|
||||
conn.send(content_type='application/raw',body=' Hello Stomp ', destination='/queue/test')
|
||||
conn.disconnect()
|
39
pyapp/pyapp/queue/test.py
Executable file
39
pyapp/pyapp/queue/test.py
Executable file
@ -0,0 +1,39 @@
|
||||
import stomp
|
||||
from stomp.listener import TestListener
|
||||
import testutils
|
||||
|
||||
|
||||
##@pytest.fixture()
|
||||
def conn():
|
||||
conn = stomp.Connection11(get_artemis_host())
|
||||
conn.set_listener("testlistener", TestListener("123", print_to_log=True))
|
||||
conn.connect(get_artemis_user(), get_artemis_password(), wait=True)
|
||||
yield conn
|
||||
conn.disconnect(receipt=None)
|
||||
|
||||
|
||||
##@pytest.fixture()
|
||||
def conn2():
|
||||
conn2 = stomp.Connection11(get_artemis_host())
|
||||
conn2.set_listener("testlistener", TestListener("456", print_to_log=True))
|
||||
conn2.connect(get_artemis_user(), get_artemis_password(), wait=True, headers={'consumerWindowSize': 0})
|
||||
yield conn2
|
||||
conn2.disconnect(receipt=None)
|
||||
|
||||
|
||||
class TestArtemis(object):
|
||||
|
||||
def test_send_to_artemis(self, conn):
|
||||
conn.subscribe(destination="/queue/test", id=1, ack="auto")
|
||||
|
||||
conn.send(body="this is a test", destination="/queue/test", receipt="123")
|
||||
|
||||
validate_send(conn)
|
||||
|
||||
def test_prefetchsize(self, conn2):
|
||||
conn2.subscribe(destination="/queue/test2", id=2, ack="auto", headers={'consumerWindowSize': 0})
|
||||
|
||||
conn2.send(body="testing sending a message after subscribing with prefetch",
|
||||
destination="/queue/test2", receipt="456")
|
||||
|
||||
validate_send(conn2)
|
7
pyapp/pyapp/serializers.py
Executable file
7
pyapp/pyapp/serializers.py
Executable file
@ -0,0 +1,7 @@
|
||||
from rest_framework import serializers
|
||||
from pyapp.models import ShoppingItem
|
||||
|
||||
class ShoppingItemSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ShoppingItem
|
||||
fields = '__all__'
|
148
pyapp/pyapp/settings.py
Executable file
148
pyapp/pyapp/settings.py
Executable file
@ -0,0 +1,148 @@
|
||||
"""
|
||||
Django settings for pyapp project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.0.1.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-z$@7i%n)hn)=5-c8!%)y1-493jkohy8=s-xq8=iu(aud)xx0_+'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'pyapp_api',
|
||||
'pyapp',
|
||||
]
|
||||
|
||||
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',
|
||||
]
|
||||
|
||||
CORS_ORIGIN_ALLOW_ALL = False
|
||||
CORS_ORIGIN_WHITELIST = (
|
||||
'http://localhost:8000',
|
||||
)
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||
'PAGE_SIZE': 10
|
||||
}
|
||||
|
||||
ROOT_URLCONF = 'pyapp.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'pyapp.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||
|
||||
# DATABASES = {
|
||||
# 'default': {
|
||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||
# }
|
||||
# }
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'pyapp',
|
||||
'USER': 'pyapp',
|
||||
'PASSWORD': 'kotyczka',
|
||||
'HOST': '192.168.0.9',
|
||||
'PORT': '5434',
|
||||
}}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||
|
||||
STATIC_URL = 'static/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
|
60
pyapp/pyapp/templates/pyapp.html
Executable file
60
pyapp/pyapp/templates/pyapp.html
Executable file
@ -0,0 +1,60 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>PyApp Inventory</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
header {
|
||||
background-color: green;
|
||||
display: flex;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 40px;
|
||||
width: 40 px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
font-size: 32 px;
|
||||
background-color: white;
|
||||
height: 30px;
|
||||
box-shadow: 2px 2px 2px rgba(0,0,0,0.01);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>PyApp Item List Inventory</h1>
|
||||
</header>
|
||||
{% for item in all_items %}
|
||||
<div class="list-item">
|
||||
<input type="checkbox"> {{item.name}}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<button onclick="addItem()">+</button>
|
||||
<script>
|
||||
function addItem() {
|
||||
let itemName = prompt('Neues Element hinzufügen');
|
||||
let token = '{{csrf_token}}';
|
||||
let formData = new FormData();
|
||||
formData.append('itemName',itemName);
|
||||
formData.append('csrfmiddlewaretoken',token);
|
||||
fetch('/pyapp/', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
window.location.reload();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
3
pyapp/pyapp/tests.py
Executable file
3
pyapp/pyapp/tests.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
28
pyapp/pyapp/urls.py
Executable file
28
pyapp/pyapp/urls.py
Executable file
@ -0,0 +1,28 @@
|
||||
"""
|
||||
URL configuration for pyapp project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.0/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from pyapp import views
|
||||
from django.contrib import admin
|
||||
from django.urls import path,include
|
||||
from pyapp.views import pyapp_home
|
||||
from pyapp_api import urls as pyapp_urls
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.index, name= "index"),
|
||||
path('admin/', admin.site.urls),
|
||||
path("pyapp/", views.pyapp_home, name= "Item List App"),
|
||||
path('api/', include(pyapp_urls)),
|
||||
]
|
35
pyapp/pyapp/views.py
Executable file
35
pyapp/pyapp/views.py
Executable file
@ -0,0 +1,35 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from pyapp.models import ShoppingItem
|
||||
from rest_framework import viewsets
|
||||
from pyapp.serializers import ShoppingItemSerializer
|
||||
|
||||
class ShoppingItemViewSet(viewsets.ModelViewSet):
|
||||
queryset = ShoppingItem.objects.all()
|
||||
serializer_class = ShoppingItemSerializer
|
||||
|
||||
def index(response):
|
||||
return HttpResponse("Welcome to the Pyapp Item List")
|
||||
|
||||
def pyapp_home(request):
|
||||
if request.method == 'POST':
|
||||
print('Received Data',request.POST['itemName'])
|
||||
ShoppingItem.objects.create(name= request.POST['itemName'])
|
||||
all_items = ShoppingItem.objects.all()
|
||||
return render(request,'pyapp.html',{'all_items': all_items})
|
||||
|
||||
def api_home(request,endpoint, params={"message": "Your JSON Repsonse"}):
|
||||
body = request.body
|
||||
data = {}
|
||||
try:
|
||||
data = json.loads(body)
|
||||
except:
|
||||
pass
|
||||
print(request.GET)
|
||||
print(data)
|
||||
data['params'] = dict(request.GET)
|
||||
data['headers'] = dict(request.headers)
|
||||
data['content_type'] = request.content_type
|
||||
return JsonResponse(data)
|
||||
|
||||
##return JsonResponse()
|
66
pyapp/pyapp/window/address.py
Executable file
66
pyapp/pyapp/window/address.py
Executable file
@ -0,0 +1,66 @@
|
||||
import tkinter as tk
|
||||
|
||||
# Create a new window with the title "Address Entry Form"
|
||||
window = tk.Tk()
|
||||
window.title("Address Entry Form")
|
||||
|
||||
# Create a new frame `frm_form` to contain the Label
|
||||
# and Entry widgets for entering address information
|
||||
frm_form = tk.Frame(relief=tk.SUNKEN, borderwidth=3)
|
||||
# Pack the frame into the window
|
||||
frm_form.pack()
|
||||
|
||||
# List of field labels
|
||||
labels = [
|
||||
"First Name:",
|
||||
"Last Name:",
|
||||
"Address Line 1:",
|
||||
"Address Line 2:",
|
||||
"City:",
|
||||
"State/Province:",
|
||||
"Postal Code:",
|
||||
"Country:",
|
||||
]
|
||||
|
||||
# Loop over the list of field labels
|
||||
for idx, text in enumerate(labels):
|
||||
# Create a Label widget with the text from the labels list
|
||||
label = tk.Label(master=frm_form, text=text)
|
||||
# Create an Entry widget
|
||||
entry = tk.Entry(master=frm_form, width=50)
|
||||
# Use the grid geometry manager to place the Label and
|
||||
# Entry widgets in the row whose index is idx
|
||||
label.grid(row=idx, column=0, sticky="e")
|
||||
entry.grid(row=idx, column=1)
|
||||
|
||||
# Create a new frame `frm_buttons` to contain the
|
||||
# Submit and Clear buttons. This frame fills the
|
||||
# whole window in the horizontal direction and has
|
||||
# 5 pixels of horizontal and vertical padding.
|
||||
frm_buttons = tk.Frame()
|
||||
frm_buttons.pack(fill=tk.X, ipadx=5, ipady=5)
|
||||
|
||||
# Create an event handler
|
||||
def handle_keypress(event):
|
||||
"""Print the character associated to the key pressed"""
|
||||
print(event.char)
|
||||
|
||||
# Bind keypress event to handle_keypress()
|
||||
window.bind("<Key>", handle_keypress)
|
||||
|
||||
def handle_click(event):
|
||||
print("Adress was submitted")
|
||||
|
||||
# Create the "Submit" button and pack it to the
|
||||
# right side of `frm_buttons`
|
||||
btn_submit = tk.Button(master=frm_buttons, text="Submit")
|
||||
btn_submit.pack(side=tk.RIGHT, padx=10, ipadx=10)
|
||||
btn_submit.bind("<Button-1>", handle_click)
|
||||
|
||||
# Create the "Clear" button and pack it to the
|
||||
# right side of `frm_buttons`
|
||||
btn_clear = tk.Button(master=frm_buttons, text="Clear")
|
||||
btn_clear.pack(side=tk.RIGHT, ipadx=10)
|
||||
|
||||
# Start the application
|
||||
window.mainloop()
|
47
pyapp/pyapp/window/basic.py
Executable file
47
pyapp/pyapp/window/basic.py
Executable file
@ -0,0 +1,47 @@
|
||||
import tkinter as tk
|
||||
|
||||
window = tk.Tk()
|
||||
label = tk.Label(
|
||||
text="Python rocks!",
|
||||
foreground="white", # Set the text color to white
|
||||
background="black" # Set the background color to black
|
||||
)
|
||||
|
||||
border_effects = {
|
||||
"flat": tk.FLAT,
|
||||
"sunken": tk.SUNKEN,
|
||||
"raised": tk.RAISED,
|
||||
"groove": tk.GROOVE,
|
||||
"ridge": tk.RIDGE,
|
||||
}
|
||||
for relief_name, relief in border_effects.items():
|
||||
frame = tk.Frame(master=window, relief=relief, borderwidth=5)
|
||||
frame.pack(side=tk.LEFT)
|
||||
label = tk.Label(master=frame, text=relief_name)
|
||||
label.pack()
|
||||
|
||||
label.pack()
|
||||
entry = tk.Entry()
|
||||
entry.pack()
|
||||
|
||||
name = entry.get()
|
||||
|
||||
frame_a = tk.Frame()
|
||||
|
||||
|
||||
label_a = tk.Label(master=frame_a, text="Personalliste")
|
||||
label_a.pack()
|
||||
|
||||
frame_a.pack()
|
||||
|
||||
text_box = tk.Text()
|
||||
text_box.pack()
|
||||
|
||||
frame_b = tk.Frame()
|
||||
label_b = tk.Label(master=frame_b, text="I'm in Frame B")
|
||||
label_b.pack()
|
||||
frame_b.pack()
|
||||
|
||||
|
||||
window.mainloop()
|
||||
print(name)
|
5
pyapp/pyapp/window/config.py
Executable file
5
pyapp/pyapp/window/config.py
Executable file
@ -0,0 +1,5 @@
|
||||
username = 'smx'
|
||||
password = 'smx'
|
||||
|
||||
#username = 'mqadmin'
|
||||
#password = '3Mnj29jKBsFybc'
|
17
pyapp/pyapp/window/dice.py
Executable file
17
pyapp/pyapp/window/dice.py
Executable file
@ -0,0 +1,17 @@
|
||||
import random
|
||||
import tkinter as tk
|
||||
|
||||
def roll():
|
||||
lbl_result["text"] = str(random.randint(1, 6))
|
||||
|
||||
window = tk.Tk()
|
||||
window.columnconfigure(0, minsize=150)
|
||||
window.rowconfigure([0, 1], minsize=50)
|
||||
|
||||
btn_roll = tk.Button(text="Roll", command=roll)
|
||||
lbl_result = tk.Label()
|
||||
|
||||
btn_roll.grid(row=0, column=0, sticky="nsew")
|
||||
lbl_result.grid(row=1, column=0)
|
||||
|
||||
window.mainloop()
|
94
pyapp/pyapp/window/edit.py
Executable file
94
pyapp/pyapp/window/edit.py
Executable file
@ -0,0 +1,94 @@
|
||||
import tkinter as tk
|
||||
import config as conf
|
||||
import pika
|
||||
|
||||
from tkinter.filedialog import askopenfilename, asksaveasfilename
|
||||
|
||||
def send_queue_message():
|
||||
exchange_name = 'simple-editor'
|
||||
message_all = 'Sent from RabbitMQ'
|
||||
|
||||
print(message_all)
|
||||
credentials= pika.PlainCredentials(username= conf.username, password= conf.password)
|
||||
connection= pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
|
||||
channel= connection.channel()
|
||||
channel.exchange_declare(exchange = exchange_name, durable = True, exchange_type = 'topic')
|
||||
channel.queue_declare(queue = 'AllInfo')
|
||||
txt = txt_edit.get("1.0", tk.END)
|
||||
channel.queue_bind(exchange = exchange_name, queue = 'AllInfo', routing_key = 'new')
|
||||
channel.basic_publish(exchange = exchange_name, routing_key = 'new', body = txt)
|
||||
channel.close()
|
||||
|
||||
def get_queue_message():
|
||||
exchange_name = 'simple-editor'
|
||||
credentials= pika.PlainCredentials(username= conf.username, password= conf.password)
|
||||
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5672, credentials= credentials))
|
||||
channel = connection.channel()
|
||||
channel.exchange_declare(exchange_name, durable=True, exchange_type='topic')
|
||||
txt_edit.delete("1.0", tk.END)
|
||||
|
||||
def callback(ch,method,properties,body):
|
||||
message = 'Message from Queue Part: ' + body.decode("utf-8")
|
||||
txt_edit.insert(tk.END, message)
|
||||
ch.basic_publish('exchange_not_exist', routing_key='new',cbody='Nope this is wrong')
|
||||
##ch.basic_ack(delivery_tag = method.delivery_tag + 1)
|
||||
# Display the message parts
|
||||
channel.queue_bind(exchange = exchange_name, queue = 'AllInfo', routing_key = 'new')
|
||||
channel.basic_consume(queue='AllInfo', on_message_callback=callback, auto_ack=True)
|
||||
##channel.consume(queue = 'AllInfo')
|
||||
|
||||
# Close the channel and the connection
|
||||
channel.close()
|
||||
connection.close()
|
||||
message_all = 'Retrieved from RabbitMQ'
|
||||
print(message_all)
|
||||
|
||||
def open_file():
|
||||
"""Open a file for editing."""
|
||||
filepath = askopenfilename(
|
||||
filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")]
|
||||
)
|
||||
if not filepath:
|
||||
return
|
||||
txt_edit.delete("1.0", tk.END)
|
||||
with open(filepath, mode="r", encoding="utf-8") as input_file:
|
||||
text = input_file.read()
|
||||
txt_edit.insert(tk.END, text)
|
||||
window.title(f"Simple Text Editor - {filepath}")
|
||||
|
||||
def save_file():
|
||||
"""Save the current file as a new file."""
|
||||
filepath = asksaveasfilename(
|
||||
defaultextension=".txt",
|
||||
filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")],
|
||||
)
|
||||
if not filepath:
|
||||
return
|
||||
with open(filepath, mode="w", encoding="utf-8") as output_file:
|
||||
text = txt_edit.get("1.0", tk.END)
|
||||
output_file.write(text)
|
||||
window.title(f"Simple Text Editor - {filepath}")
|
||||
|
||||
window = tk.Tk()
|
||||
window.title("Simple Text Editor")
|
||||
|
||||
window.rowconfigure(0, minsize=800, weight=1)
|
||||
window.columnconfigure(1, minsize=800, weight=1)
|
||||
|
||||
|
||||
txt_edit = tk.Text(window)
|
||||
frm_buttons = tk.Frame(window, relief=tk.RAISED, bd=2)
|
||||
btn_open = tk.Button(frm_buttons, text="Open", command=open_file)
|
||||
btn_save = tk.Button(frm_buttons, text="Save As...", command=save_file)
|
||||
btn_send = tk.Button(frm_buttons, text="Send", command=send_queue_message)
|
||||
btn_receive = tk.Button(frm_buttons, text="Receive", command=get_queue_message)
|
||||
|
||||
btn_open.grid(row=0, column=0, sticky="ew", padx=5, pady=5)
|
||||
btn_save.grid(row=1, column=0, sticky="ew", padx=5)
|
||||
btn_send.grid(row=2, column=0, sticky="ew", padx=5, pady=5)
|
||||
btn_receive.grid(row=3, column=0, sticky="ew", padx=5, pady=5)
|
||||
|
||||
frm_buttons.grid(row=0, column=0, sticky="ns")
|
||||
txt_edit.grid(row=0, column=1, sticky="nsew")
|
||||
|
||||
window.mainloop()
|
41
pyapp/pyapp/window/temp.py
Executable file
41
pyapp/pyapp/window/temp.py
Executable file
@ -0,0 +1,41 @@
|
||||
import tkinter as tk
|
||||
|
||||
def fahrenheit_to_celsius():
|
||||
"""Convert the value for Fahrenheit to Celsius and insert the
|
||||
result into lbl_result.
|
||||
"""
|
||||
fahrenheit = ent_temperature.get()
|
||||
celsius = (5 / 9) * (float(fahrenheit) - 32)
|
||||
lbl_result["text"] = f"{round(celsius, 2)} \N{DEGREE CELSIUS}"
|
||||
|
||||
# Set up the window
|
||||
window = tk.Tk()
|
||||
window.title("Temperature Converter")
|
||||
window.resizable(width=False, height=False)
|
||||
|
||||
# Create the Fahrenheit entry frame with an Entry
|
||||
# widget and label in it
|
||||
frm_entry = tk.Frame(master=window)
|
||||
ent_temperature = tk.Entry(master=frm_entry, width=10)
|
||||
lbl_temp = tk.Label(master=frm_entry, text="\N{DEGREE FAHRENHEIT}")
|
||||
|
||||
# Layout the temperature Entry and Label in frm_entry
|
||||
# using the .grid() geometry manager
|
||||
ent_temperature.grid(row=0, column=0, sticky="e")
|
||||
lbl_temp.grid(row=0, column=1, sticky="w")
|
||||
|
||||
# Create the conversion Button and result display Label
|
||||
btn_convert = tk.Button(
|
||||
master=window,
|
||||
text="\N{RIGHTWARDS BLACK ARROW}",
|
||||
command=fahrenheit_to_celsius
|
||||
)
|
||||
lbl_result = tk.Label(master=window, text="\N{DEGREE CELSIUS}")
|
||||
|
||||
# Set up the layout using the .grid() geometry manager
|
||||
frm_entry.grid(row=0, column=0, padx=10)
|
||||
btn_convert.grid(row=0, column=1, pady=10)
|
||||
lbl_result.grid(row=0, column=2, padx=10)
|
||||
|
||||
# Run the application
|
||||
window.mainloop()
|
16
pyapp/pyapp/wsgi.py
Executable file
16
pyapp/pyapp/wsgi.py
Executable file
@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for pyapp project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pyapp.settings')
|
||||
|
||||
application = get_wsgi_application()
|
0
pyapp/pyapp_api/__init__.py
Executable file
0
pyapp/pyapp_api/__init__.py
Executable file
3
pyapp/pyapp_api/admin.py
Executable file
3
pyapp/pyapp_api/admin.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
10
pyapp/pyapp_api/api-client.py
Executable file
10
pyapp/pyapp_api/api-client.py
Executable file
@ -0,0 +1,10 @@
|
||||
import requests
|
||||
|
||||
endpoint = "https://httpbin.org/status/200"
|
||||
endpoint = "https://httpbin.org/anything"
|
||||
endpoint = "http://localhost:8000/api"
|
||||
|
||||
get_response = requests.get(endpoint) # HTTP get request
|
||||
print(get_response.text)
|
||||
|
||||
# REST API -> Web API
|
6
pyapp/pyapp_api/apps.py
Executable file
6
pyapp/pyapp_api/apps.py
Executable file
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PyappApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'pyapp_api'
|
0
pyapp/pyapp_api/migrations/__init__.py
Executable file
0
pyapp/pyapp_api/migrations/__init__.py
Executable file
BIN
pyapp/pyapp_api/migrations/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
pyapp/pyapp_api/migrations/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
3
pyapp/pyapp_api/models.py
Executable file
3
pyapp/pyapp_api/models.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
13
pyapp/pyapp_api/serializers.py
Normal file
13
pyapp/pyapp_api/serializers.py
Normal file
@ -0,0 +1,13 @@
|
||||
from rest_framework import serializers
|
||||
from pyapp.models import ShoppingItem
|
||||
from pyapp.models import Product
|
||||
|
||||
class ShoppingItemSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ShoppingItem
|
||||
fields = '__all__'
|
||||
|
||||
class ProductSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Product
|
||||
fields = '__all__'
|
3
pyapp/pyapp_api/tests.py
Executable file
3
pyapp/pyapp_api/tests.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
9
pyapp/pyapp_api/urls.py
Normal file
9
pyapp/pyapp_api/urls.py
Normal file
@ -0,0 +1,9 @@
|
||||
from django.urls import path,include
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
|
||||
from pyapp_api import views
|
||||
|
||||
urlpatterns = [
|
||||
path('items/', views.item_list),
|
||||
path('items/<int:pk>/', views.item_detail),
|
||||
]
|
52
pyapp/pyapp_api/views.py
Executable file
52
pyapp/pyapp_api/views.py
Executable file
@ -0,0 +1,52 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.decorators import api_view
|
||||
from django.http.response import JsonResponse
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status, permissions, viewsets
|
||||
from pyapp.models import ShoppingItem, Product
|
||||
from .serializers import ShoppingItemSerializer, ProductSerializer
|
||||
|
||||
@api_view(['GET', 'POST'])
|
||||
def item_list(request):
|
||||
"""
|
||||
List all ShoppingItems, or create a new snippet.
|
||||
"""
|
||||
if request.method == 'GET':
|
||||
ShoppingItems = ShoppingItem.objects.all()
|
||||
serializer = ShoppingItemSerializer(ShoppingItems, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
elif request.method == 'POST':
|
||||
serializer = ShoppingItemSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@api_view(['GET', 'PUT', 'DELETE'])
|
||||
def item_detail(request, pk):
|
||||
"""
|
||||
Retrieve, update or delete a code snippet.
|
||||
"""
|
||||
try:
|
||||
ShoppingItems = ShoppingItem.objects.get(pk=pk)
|
||||
except ShoppingItem.DoesNotExist:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
if request.method == 'GET':
|
||||
serializer = ShoppingItemSerializer(ShoppingItem)
|
||||
return Response(serializer.data)
|
||||
|
||||
elif request.method == 'PUT':
|
||||
serializer = ShoppingItemSerializer(ShoppingItem, data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
elif request.method == 'DELETE':
|
||||
ShoppingItem.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
19
pyapp/sql-scripts
Normal file
19
pyapp/sql-scripts
Normal file
@ -0,0 +1,19 @@
|
||||
-- database: /Users/kotyczka/repositories/kotyczka/apps/django/pyapp/db.sqlite3
|
||||
|
||||
-- Drücken Sie die ▷-Schaltfläche oben rechts im Fenster, um die gesamte Datei auszuführen.
|
||||
|
||||
insert into pyapp_shoppingitem
|
||||
SELECT * FROM migration_shoppingitem;
|
||||
commit;
|
||||
|
||||
create table pyapp_shoppingitem as select * from migration_shoppingitem where 1 = 0;
|
||||
commit;
|
||||
|
||||
drop table pyapp_product
|
||||
commit;
|
||||
|
||||
|
||||
|
||||
select * from pyapp_shoppingitem;
|
||||
|
||||
delete from pyapp_shoppingitem where name like 'Proxy';
|
1
pyapp/starter/build.sh
Executable file
1
pyapp/starter/build.sh
Executable file
@ -0,0 +1 @@
|
||||
docker build -t docker.kotyczka.ch/django-app:latest .
|
3
pyapp/starter/demo_native_starter.sh
Executable file
3
pyapp/starter/demo_native_starter.sh
Executable file
@ -0,0 +1,3 @@
|
||||
python3 manage.py runserver 9990
|
||||
|
||||
##python3 manage.py startapp banking-app
|
1
requirements.txt
Executable file
1
requirements.txt
Executable file
@ -0,0 +1 @@
|
||||
Django==5.0.1
|
1
start_composer.sh
Executable file
1
start_composer.sh
Executable file
@ -0,0 +1 @@
|
||||
docker-compose up -d
|
1
start_virtual.sh
Executable file
1
start_virtual.sh
Executable file
@ -0,0 +1 @@
|
||||
source virtualenv/bin/activate
|
2
stop_composer.sh
Executable file
2
stop_composer.sh
Executable file
@ -0,0 +1,2 @@
|
||||
docker-compose down -v
|
||||
docker rmi docker.kotyczka.ch/django-app:latest
|
Loading…
x
Reference in New Issue
Block a user