INIT
This commit is contained in:
commit
1ef959b606
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Файлы, игнорируемые по умолчанию
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Запросы HTTP-клиента в редакторе
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
10
.idea/ChatSockerRSA.iml
generated
Normal file
10
.idea/ChatSockerRSA.iml
generated
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.11 (ChatSockerRSA)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
619
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
619
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,619 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="CommandLineInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="CythonUsageBeforeDeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false">
|
||||||
|
<Languages>
|
||||||
|
<language minSize="54" name="Python" />
|
||||||
|
</Languages>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="4">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="%}{%" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="maxlength" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="href" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="article.status" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="10">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="noscript" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="embed" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="script" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="small" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="style" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="td" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="li" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PoetryPackageVersionsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyAbstractClassInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyArgumentEqualDefaultInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyArgumentListInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyAssignmentToLoopOrWithParameterInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyAsyncCallInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyAttributeOutsideInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyAugmentAssignmentInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyBroadExceptionInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyByteLiteralInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyCallingNonCallableInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyChainedComparisonsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyClassHasNoInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyClassVarInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyClassicStyleClassInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyComparisonWithNoneInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true">
|
||||||
|
<option name="ourVersions">
|
||||||
|
<value>
|
||||||
|
<list size="5">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="3.13" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="3.11" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="3.12" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="3.10" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="3.9" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</scope>
|
||||||
|
<option name="ourVersions">
|
||||||
|
<value>
|
||||||
|
<list size="5">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="3.13" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="3.12" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="3.11" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="3.10" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="3.9" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDataclassInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDecoratorInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDefaultArgumentInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDeprecationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDictCreationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDictDuplicateKeysInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDocstringTypesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyDunderSlotsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyExceptClausesOrderInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyExceptionInheritInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyFinalInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyFromFutureImportInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyGlobalUndefinedInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyInconsistentIndentationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyIncorrectDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyInitNewSignatureInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyInterpreterInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyListCreationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMandatoryEncodingInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMethodFirstArgAssignmentInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMethodMayBeStaticInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMethodOverridingInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMethodParametersInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMissingConstructorInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMissingOrEmptyDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyMissingTypeHintsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyNamedTupleInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyNestedDecoratorsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyNewStyleGenericSyntaxInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyNonAsciiCharInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyNoneFunctionAssignmentInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyOldStyleClassesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyOverloadsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyOverridesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="119">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="asyncpg" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="psycopg2" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="uvloop" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="httptools" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="eventlet" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="tqdm" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="yadisk" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="certifi" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="charset-normalizer" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="requests" />
|
||||||
|
<item index="10" class="java.lang.String" itemvalue="urllib3" />
|
||||||
|
<item index="11" class="java.lang.String" itemvalue="idna" />
|
||||||
|
<item index="12" class="java.lang.String" itemvalue="pathspec" />
|
||||||
|
<item index="13" class="java.lang.String" itemvalue="djlint" />
|
||||||
|
<item index="14" class="java.lang.String" itemvalue="PyYAML" />
|
||||||
|
<item index="15" class="java.lang.String" itemvalue="tzdata" />
|
||||||
|
<item index="16" class="java.lang.String" itemvalue="asgiref" />
|
||||||
|
<item index="17" class="java.lang.String" itemvalue="EditorConfig" />
|
||||||
|
<item index="18" class="java.lang.String" itemvalue="click" />
|
||||||
|
<item index="19" class="java.lang.String" itemvalue="html-tag-names" />
|
||||||
|
<item index="20" class="java.lang.String" itemvalue="sqlparse" />
|
||||||
|
<item index="21" class="java.lang.String" itemvalue="regex" />
|
||||||
|
<item index="22" class="java.lang.String" itemvalue="colorama" />
|
||||||
|
<item index="23" class="java.lang.String" itemvalue="Django" />
|
||||||
|
<item index="24" class="java.lang.String" itemvalue="ruff" />
|
||||||
|
<item index="25" class="java.lang.String" itemvalue="cssbeautifier" />
|
||||||
|
<item index="26" class="java.lang.String" itemvalue="html-void-elements" />
|
||||||
|
<item index="27" class="java.lang.String" itemvalue="jsbeautifier" />
|
||||||
|
<item index="28" class="java.lang.String" itemvalue="tomli" />
|
||||||
|
<item index="29" class="java.lang.String" itemvalue="pytils" />
|
||||||
|
<item index="30" class="java.lang.String" itemvalue="Pillow" />
|
||||||
|
<item index="31" class="java.lang.String" itemvalue="mysqlclient" />
|
||||||
|
<item index="32" class="java.lang.String" itemvalue="Werkzeug" />
|
||||||
|
<item index="33" class="java.lang.String" itemvalue="Flask-WTF" />
|
||||||
|
<item index="34" class="java.lang.String" itemvalue="Flask-MySQLdb" />
|
||||||
|
<item index="35" class="java.lang.String" itemvalue="MarkupSafe" />
|
||||||
|
<item index="36" class="java.lang.String" itemvalue="itsdangerous" />
|
||||||
|
<item index="37" class="java.lang.String" itemvalue="Jinja2" />
|
||||||
|
<item index="38" class="java.lang.String" itemvalue="Flask" />
|
||||||
|
<item index="39" class="java.lang.String" itemvalue="email-validator" />
|
||||||
|
<item index="40" class="java.lang.String" itemvalue="dnspython" />
|
||||||
|
<item index="41" class="java.lang.String" itemvalue="alembic" />
|
||||||
|
<item index="42" class="java.lang.String" itemvalue="async-timeout" />
|
||||||
|
<item index="43" class="java.lang.String" itemvalue="Flask-Principal" />
|
||||||
|
<item index="44" class="java.lang.String" itemvalue="Flask-Uploads" />
|
||||||
|
<item index="45" class="java.lang.String" itemvalue="python-dotenv" />
|
||||||
|
<item index="46" class="java.lang.String" itemvalue="cachelib" />
|
||||||
|
<item index="47" class="java.lang.String" itemvalue="redis" />
|
||||||
|
<item index="48" class="java.lang.String" itemvalue="Flask-Migrate" />
|
||||||
|
<item index="49" class="java.lang.String" itemvalue="Mako" />
|
||||||
|
<item index="50" class="java.lang.String" itemvalue="Markdown" />
|
||||||
|
<item index="51" class="java.lang.String" itemvalue="Flask-Session" />
|
||||||
|
<item index="52" class="java.lang.String" itemvalue="requests-oauthlib" />
|
||||||
|
<item index="53" class="java.lang.String" itemvalue="PyJWT" />
|
||||||
|
<item index="54" class="java.lang.String" itemvalue="social-auth-app-django" />
|
||||||
|
<item index="55" class="java.lang.String" itemvalue="oauthlib" />
|
||||||
|
<item index="56" class="java.lang.String" itemvalue="cffi" />
|
||||||
|
<item index="57" class="java.lang.String" itemvalue="cryptography" />
|
||||||
|
<item index="58" class="java.lang.String" itemvalue="defusedxml" />
|
||||||
|
<item index="59" class="java.lang.String" itemvalue="pycparser" />
|
||||||
|
<item index="60" class="java.lang.String" itemvalue="pytz" />
|
||||||
|
<item index="61" class="java.lang.String" itemvalue="python3-openid" />
|
||||||
|
<item index="62" class="java.lang.String" itemvalue="social-auth-core" />
|
||||||
|
<item index="63" class="java.lang.String" itemvalue="protobuf" />
|
||||||
|
<item index="64" class="java.lang.String" itemvalue="nodeenv" />
|
||||||
|
<item index="65" class="java.lang.String" itemvalue="identify" />
|
||||||
|
<item index="66" class="java.lang.String" itemvalue="pyflakes" />
|
||||||
|
<item index="67" class="java.lang.String" itemvalue="dill" />
|
||||||
|
<item index="68" class="java.lang.String" itemvalue="pycodestyle" />
|
||||||
|
<item index="69" class="java.lang.String" itemvalue="flake8" />
|
||||||
|
<item index="70" class="java.lang.String" itemvalue="tomlkit" />
|
||||||
|
<item index="71" class="java.lang.String" itemvalue="filelock" />
|
||||||
|
<item index="72" class="java.lang.String" itemvalue="platformdirs" />
|
||||||
|
<item index="73" class="java.lang.String" itemvalue="mccabe" />
|
||||||
|
<item index="74" class="java.lang.String" itemvalue="typing_extensions" />
|
||||||
|
<item index="75" class="java.lang.String" itemvalue="virtualenv" />
|
||||||
|
<item index="76" class="java.lang.String" itemvalue="pylint-protobuf" />
|
||||||
|
<item index="77" class="java.lang.String" itemvalue="distlib" />
|
||||||
|
<item index="78" class="java.lang.String" itemvalue="isort" />
|
||||||
|
<item index="79" class="java.lang.String" itemvalue="cfgv" />
|
||||||
|
<item index="80" class="java.lang.String" itemvalue="exceptiongroup" />
|
||||||
|
<item index="81" class="java.lang.String" itemvalue="pytest" />
|
||||||
|
<item index="82" class="java.lang.String" itemvalue="iniconfig" />
|
||||||
|
<item index="83" class="java.lang.String" itemvalue="pluggy" />
|
||||||
|
<item index="84" class="java.lang.String" itemvalue="packaging" />
|
||||||
|
<item index="85" class="java.lang.String" itemvalue="gunicorn" />
|
||||||
|
<item index="86" class="java.lang.String" itemvalue="referencing" />
|
||||||
|
<item index="87" class="java.lang.String" itemvalue="python-crontab" />
|
||||||
|
<item index="88" class="java.lang.String" itemvalue="python-dateutil" />
|
||||||
|
<item index="89" class="java.lang.String" itemvalue="psycopg2-binary" />
|
||||||
|
<item index="90" class="java.lang.String" itemvalue="wcwidth" />
|
||||||
|
<item index="91" class="java.lang.String" itemvalue="astroid" />
|
||||||
|
<item index="92" class="java.lang.String" itemvalue="kombu" />
|
||||||
|
<item index="93" class="java.lang.String" itemvalue="click-didyoumean" />
|
||||||
|
<item index="94" class="java.lang.String" itemvalue="jsonschema-specifications" />
|
||||||
|
<item index="95" class="java.lang.String" itemvalue="drf-spectacular" />
|
||||||
|
<item index="96" class="java.lang.String" itemvalue="rpds-py" />
|
||||||
|
<item index="97" class="java.lang.String" itemvalue="celery" />
|
||||||
|
<item index="98" class="java.lang.String" itemvalue="cron-descriptor" />
|
||||||
|
<item index="99" class="java.lang.String" itemvalue="prompt-toolkit" />
|
||||||
|
<item index="100" class="java.lang.String" itemvalue="djangorestframework" />
|
||||||
|
<item index="101" class="java.lang.String" itemvalue="vine" />
|
||||||
|
<item index="102" class="java.lang.String" itemvalue="billiard" />
|
||||||
|
<item index="103" class="java.lang.String" itemvalue="jsonschema" />
|
||||||
|
<item index="104" class="java.lang.String" itemvalue="uritemplate" />
|
||||||
|
<item index="105" class="java.lang.String" itemvalue="django-celery-beat" />
|
||||||
|
<item index="106" class="java.lang.String" itemvalue="six" />
|
||||||
|
<item index="107" class="java.lang.String" itemvalue="django-celery-results" />
|
||||||
|
<item index="108" class="java.lang.String" itemvalue="amqp" />
|
||||||
|
<item index="109" class="java.lang.String" itemvalue="attrs" />
|
||||||
|
<item index="110" class="java.lang.String" itemvalue="django-axes" />
|
||||||
|
<item index="111" class="java.lang.String" itemvalue="pylint" />
|
||||||
|
<item index="112" class="java.lang.String" itemvalue="django-redis" />
|
||||||
|
<item index="113" class="java.lang.String" itemvalue="django-timezone-field" />
|
||||||
|
<item index="114" class="java.lang.String" itemvalue="click-repl" />
|
||||||
|
<item index="115" class="java.lang.String" itemvalue="click-plugins" />
|
||||||
|
<item index="116" class="java.lang.String" itemvalue="inflection" />
|
||||||
|
<item index="117" class="java.lang.String" itemvalue="pyproject_hooks" />
|
||||||
|
<item index="118" class="java.lang.String" itemvalue="python-docx" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</scope>
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="119">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="asyncpg" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="psycopg2" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="uvloop" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="httptools" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="eventlet" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="tqdm" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="yadisk" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="certifi" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="charset-normalizer" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="requests" />
|
||||||
|
<item index="10" class="java.lang.String" itemvalue="urllib3" />
|
||||||
|
<item index="11" class="java.lang.String" itemvalue="idna" />
|
||||||
|
<item index="12" class="java.lang.String" itemvalue="pathspec" />
|
||||||
|
<item index="13" class="java.lang.String" itemvalue="djlint" />
|
||||||
|
<item index="14" class="java.lang.String" itemvalue="PyYAML" />
|
||||||
|
<item index="15" class="java.lang.String" itemvalue="tzdata" />
|
||||||
|
<item index="16" class="java.lang.String" itemvalue="asgiref" />
|
||||||
|
<item index="17" class="java.lang.String" itemvalue="EditorConfig" />
|
||||||
|
<item index="18" class="java.lang.String" itemvalue="click" />
|
||||||
|
<item index="19" class="java.lang.String" itemvalue="html-tag-names" />
|
||||||
|
<item index="20" class="java.lang.String" itemvalue="sqlparse" />
|
||||||
|
<item index="21" class="java.lang.String" itemvalue="regex" />
|
||||||
|
<item index="22" class="java.lang.String" itemvalue="colorama" />
|
||||||
|
<item index="23" class="java.lang.String" itemvalue="Django" />
|
||||||
|
<item index="24" class="java.lang.String" itemvalue="ruff" />
|
||||||
|
<item index="25" class="java.lang.String" itemvalue="cssbeautifier" />
|
||||||
|
<item index="26" class="java.lang.String" itemvalue="html-void-elements" />
|
||||||
|
<item index="27" class="java.lang.String" itemvalue="jsbeautifier" />
|
||||||
|
<item index="28" class="java.lang.String" itemvalue="tomli" />
|
||||||
|
<item index="29" class="java.lang.String" itemvalue="pytils" />
|
||||||
|
<item index="30" class="java.lang.String" itemvalue="Pillow" />
|
||||||
|
<item index="31" class="java.lang.String" itemvalue="mysqlclient" />
|
||||||
|
<item index="32" class="java.lang.String" itemvalue="Werkzeug" />
|
||||||
|
<item index="33" class="java.lang.String" itemvalue="Flask-WTF" />
|
||||||
|
<item index="34" class="java.lang.String" itemvalue="Flask-MySQLdb" />
|
||||||
|
<item index="35" class="java.lang.String" itemvalue="MarkupSafe" />
|
||||||
|
<item index="36" class="java.lang.String" itemvalue="itsdangerous" />
|
||||||
|
<item index="37" class="java.lang.String" itemvalue="Jinja2" />
|
||||||
|
<item index="38" class="java.lang.String" itemvalue="Flask" />
|
||||||
|
<item index="39" class="java.lang.String" itemvalue="email-validator" />
|
||||||
|
<item index="40" class="java.lang.String" itemvalue="dnspython" />
|
||||||
|
<item index="41" class="java.lang.String" itemvalue="alembic" />
|
||||||
|
<item index="42" class="java.lang.String" itemvalue="async-timeout" />
|
||||||
|
<item index="43" class="java.lang.String" itemvalue="Flask-Principal" />
|
||||||
|
<item index="44" class="java.lang.String" itemvalue="Flask-Uploads" />
|
||||||
|
<item index="45" class="java.lang.String" itemvalue="python-dotenv" />
|
||||||
|
<item index="46" class="java.lang.String" itemvalue="cachelib" />
|
||||||
|
<item index="47" class="java.lang.String" itemvalue="redis" />
|
||||||
|
<item index="48" class="java.lang.String" itemvalue="Flask-Migrate" />
|
||||||
|
<item index="49" class="java.lang.String" itemvalue="Mako" />
|
||||||
|
<item index="50" class="java.lang.String" itemvalue="Markdown" />
|
||||||
|
<item index="51" class="java.lang.String" itemvalue="Flask-Session" />
|
||||||
|
<item index="52" class="java.lang.String" itemvalue="requests-oauthlib" />
|
||||||
|
<item index="53" class="java.lang.String" itemvalue="PyJWT" />
|
||||||
|
<item index="54" class="java.lang.String" itemvalue="social-auth-app-django" />
|
||||||
|
<item index="55" class="java.lang.String" itemvalue="oauthlib" />
|
||||||
|
<item index="56" class="java.lang.String" itemvalue="cffi" />
|
||||||
|
<item index="57" class="java.lang.String" itemvalue="cryptography" />
|
||||||
|
<item index="58" class="java.lang.String" itemvalue="defusedxml" />
|
||||||
|
<item index="59" class="java.lang.String" itemvalue="pycparser" />
|
||||||
|
<item index="60" class="java.lang.String" itemvalue="pytz" />
|
||||||
|
<item index="61" class="java.lang.String" itemvalue="python3-openid" />
|
||||||
|
<item index="62" class="java.lang.String" itemvalue="social-auth-core" />
|
||||||
|
<item index="63" class="java.lang.String" itemvalue="protobuf" />
|
||||||
|
<item index="64" class="java.lang.String" itemvalue="nodeenv" />
|
||||||
|
<item index="65" class="java.lang.String" itemvalue="identify" />
|
||||||
|
<item index="66" class="java.lang.String" itemvalue="pyflakes" />
|
||||||
|
<item index="67" class="java.lang.String" itemvalue="dill" />
|
||||||
|
<item index="68" class="java.lang.String" itemvalue="pycodestyle" />
|
||||||
|
<item index="69" class="java.lang.String" itemvalue="flake8" />
|
||||||
|
<item index="70" class="java.lang.String" itemvalue="tomlkit" />
|
||||||
|
<item index="71" class="java.lang.String" itemvalue="filelock" />
|
||||||
|
<item index="72" class="java.lang.String" itemvalue="platformdirs" />
|
||||||
|
<item index="73" class="java.lang.String" itemvalue="mccabe" />
|
||||||
|
<item index="74" class="java.lang.String" itemvalue="typing_extensions" />
|
||||||
|
<item index="75" class="java.lang.String" itemvalue="virtualenv" />
|
||||||
|
<item index="76" class="java.lang.String" itemvalue="pylint-protobuf" />
|
||||||
|
<item index="77" class="java.lang.String" itemvalue="distlib" />
|
||||||
|
<item index="78" class="java.lang.String" itemvalue="isort" />
|
||||||
|
<item index="79" class="java.lang.String" itemvalue="cfgv" />
|
||||||
|
<item index="80" class="java.lang.String" itemvalue="exceptiongroup" />
|
||||||
|
<item index="81" class="java.lang.String" itemvalue="pytest" />
|
||||||
|
<item index="82" class="java.lang.String" itemvalue="iniconfig" />
|
||||||
|
<item index="83" class="java.lang.String" itemvalue="pluggy" />
|
||||||
|
<item index="84" class="java.lang.String" itemvalue="packaging" />
|
||||||
|
<item index="85" class="java.lang.String" itemvalue="gunicorn" />
|
||||||
|
<item index="86" class="java.lang.String" itemvalue="referencing" />
|
||||||
|
<item index="87" class="java.lang.String" itemvalue="python-crontab" />
|
||||||
|
<item index="88" class="java.lang.String" itemvalue="python-dateutil" />
|
||||||
|
<item index="89" class="java.lang.String" itemvalue="psycopg2-binary" />
|
||||||
|
<item index="90" class="java.lang.String" itemvalue="wcwidth" />
|
||||||
|
<item index="91" class="java.lang.String" itemvalue="astroid" />
|
||||||
|
<item index="92" class="java.lang.String" itemvalue="kombu" />
|
||||||
|
<item index="93" class="java.lang.String" itemvalue="click-didyoumean" />
|
||||||
|
<item index="94" class="java.lang.String" itemvalue="jsonschema-specifications" />
|
||||||
|
<item index="95" class="java.lang.String" itemvalue="drf-spectacular" />
|
||||||
|
<item index="96" class="java.lang.String" itemvalue="rpds-py" />
|
||||||
|
<item index="97" class="java.lang.String" itemvalue="celery" />
|
||||||
|
<item index="98" class="java.lang.String" itemvalue="cron-descriptor" />
|
||||||
|
<item index="99" class="java.lang.String" itemvalue="prompt-toolkit" />
|
||||||
|
<item index="100" class="java.lang.String" itemvalue="djangorestframework" />
|
||||||
|
<item index="101" class="java.lang.String" itemvalue="vine" />
|
||||||
|
<item index="102" class="java.lang.String" itemvalue="billiard" />
|
||||||
|
<item index="103" class="java.lang.String" itemvalue="jsonschema" />
|
||||||
|
<item index="104" class="java.lang.String" itemvalue="uritemplate" />
|
||||||
|
<item index="105" class="java.lang.String" itemvalue="django-celery-beat" />
|
||||||
|
<item index="106" class="java.lang.String" itemvalue="six" />
|
||||||
|
<item index="107" class="java.lang.String" itemvalue="django-celery-results" />
|
||||||
|
<item index="108" class="java.lang.String" itemvalue="amqp" />
|
||||||
|
<item index="109" class="java.lang.String" itemvalue="attrs" />
|
||||||
|
<item index="110" class="java.lang.String" itemvalue="django-axes" />
|
||||||
|
<item index="111" class="java.lang.String" itemvalue="pylint" />
|
||||||
|
<item index="112" class="java.lang.String" itemvalue="django-redis" />
|
||||||
|
<item index="113" class="java.lang.String" itemvalue="django-timezone-field" />
|
||||||
|
<item index="114" class="java.lang.String" itemvalue="click-repl" />
|
||||||
|
<item index="115" class="java.lang.String" itemvalue="click-plugins" />
|
||||||
|
<item index="116" class="java.lang.String" itemvalue="inflection" />
|
||||||
|
<item index="117" class="java.lang.String" itemvalue="pyproject_hooks" />
|
||||||
|
<item index="118" class="java.lang.String" itemvalue="python-docx" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPandasSeriesToListInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="E712" />
|
||||||
|
<option value="W605" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</scope>
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="E712" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true">
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N806" />
|
||||||
|
<option value="N802" />
|
||||||
|
<option value="N813" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</scope>
|
||||||
|
<option name="ignoredErrors">
|
||||||
|
<list>
|
||||||
|
<option value="N806" />
|
||||||
|
<option value="N802" />
|
||||||
|
<option value="N813" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPropertyAccessInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyPropertyDefinitionInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyProtectedMemberInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyProtocolInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyRedeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyRedundantParenthesesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyRelativeImportInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyReturnFromInitInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PySetFunctionToLiteralInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyShadowingBuiltinsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyShadowingNamesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PySimplifyBooleanCheckInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PySingleQuotedDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyStatementEffectInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyStringFormatInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyStubPackagesCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PySuperArgumentsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTestParametrizedInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTestUnpassedFixtureInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTrailingSemicolonInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTupleAssignmentBalanceInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTupleItemAssignmentInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTypeCheckerInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTypeHintsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyTypedDictInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnboundLocalVariableInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnnecessaryBackslashInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnreachableCodeInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WARNING" enabled="true">
|
||||||
|
<option name="ignoredIdentifiers">
|
||||||
|
<list>
|
||||||
|
<option value="private_key" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</scope>
|
||||||
|
<option name="ignoredIdentifiers">
|
||||||
|
<list>
|
||||||
|
<option value="None" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PyUnusedLocalInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<scope name="All Changed Files" level="WEAK WARNING" enabled="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="TaskProblemsInspection" enabled="true" level="ERROR" enabled_by_default="true" editorAttributes="TEXT_STYLE_ERROR" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
17
.idea/material_theme_project_new.xml
generated
Normal file
17
.idea/material_theme_project_new.xml
generated
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="MaterialThemeProjectNewConfig">
|
||||||
|
<option name="metadata">
|
||||||
|
<MTProjectMetadataState>
|
||||||
|
<option name="migrated" value="true" />
|
||||||
|
<option name="pristineConfig" value="false" />
|
||||||
|
<option name="userId" value="-1e21af8c:195a4ec3861:-7ffe" />
|
||||||
|
</MTProjectMetadataState>
|
||||||
|
</option>
|
||||||
|
<option name="titleBarState">
|
||||||
|
<MTProjectTitleBarConfigState>
|
||||||
|
<option name="overrideColor" value="false" />
|
||||||
|
</MTProjectTitleBarConfigState>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.11 (ChatSockerRSA)" />
|
||||||
|
</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$/.idea/ChatSockerRSA.iml" filepath="$PROJECT_DIR$/.idea/ChatSockerRSA.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="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
396
CSRSA_client.py
Normal file
396
CSRSA_client.py
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
import socket
|
||||||
|
import threading
|
||||||
|
import rsa
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
import urwid
|
||||||
|
import sys
|
||||||
|
import locale
|
||||||
|
|
||||||
|
|
||||||
|
class ChatClient:
|
||||||
|
def __init__(self, host='127.0.0.1', port=5555):
|
||||||
|
# Настройка локализации
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
os.environ['LANG'] = 'ru_RU.UTF-8'
|
||||||
|
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
self.nickname = None
|
||||||
|
self.client_public_key = None
|
||||||
|
self.client_private_key = None
|
||||||
|
self.server_public_key = None
|
||||||
|
self.current_chat = []
|
||||||
|
self.file_transfers = {}
|
||||||
|
self.current_file = None
|
||||||
|
self.input_history = []
|
||||||
|
self.history_index = -1
|
||||||
|
self.last_update = time.time()
|
||||||
|
self.update_interval = 5 # Интервал обновления в секундах
|
||||||
|
|
||||||
|
# Цветовая схема
|
||||||
|
self.palette = [
|
||||||
|
('header', 'white', 'dark blue'),
|
||||||
|
('chat', 'light gray', 'black'),
|
||||||
|
('input', 'white', 'black'),
|
||||||
|
('status', 'white', 'dark blue'),
|
||||||
|
('nick', 'light cyan', 'black'),
|
||||||
|
('server', 'light green', 'black'),
|
||||||
|
('file', 'yellow', 'black'),
|
||||||
|
('error', 'light red', 'black'),
|
||||||
|
('own', 'light magenta', 'black'),
|
||||||
|
('highlight', 'black', 'light gray'),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.generate_keys()
|
||||||
|
self.setup_client()
|
||||||
|
self.setup_ui()
|
||||||
|
|
||||||
|
def generate_keys(self):
|
||||||
|
(self.client_public_key, self.client_private_key) = rsa.newkeys(2048)
|
||||||
|
|
||||||
|
def setup_client(self):
|
||||||
|
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
self.client.connect((self.host, self.port))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Не удалось подключиться к серверу: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def setup_ui(self):
|
||||||
|
# Создаем виджеты чата
|
||||||
|
self.chat_content = urwid.SimpleListWalker([])
|
||||||
|
self.chat_list = urwid.ListBox(self.chat_content)
|
||||||
|
|
||||||
|
# Исправленная строка - правильно закрываем скобки Frame
|
||||||
|
chat_frame = urwid.Frame(
|
||||||
|
urwid.AttrMap(self.chat_list, 'chat'),
|
||||||
|
header=urwid.AttrMap(urwid.Text(" ЧАТ "), 'header'))
|
||||||
|
|
||||||
|
# Поле ввода
|
||||||
|
self.input_edit = urwid.Edit(caption="Сообщение: ")
|
||||||
|
input_pile = urwid.Pile([
|
||||||
|
urwid.AttrMap(self.input_edit, 'input'),
|
||||||
|
urwid.Divider('-')
|
||||||
|
])
|
||||||
|
|
||||||
|
# Статус бар
|
||||||
|
self.status_text = urwid.Text("")
|
||||||
|
status_bar = urwid.AttrMap(self.status_text, 'status')
|
||||||
|
|
||||||
|
# Главный layout
|
||||||
|
self.main_frame = urwid.Frame(
|
||||||
|
body=chat_frame,
|
||||||
|
footer=urwid.Pile([
|
||||||
|
input_pile,
|
||||||
|
status_bar
|
||||||
|
])
|
||||||
|
)
|
||||||
|
|
||||||
|
# Главный цикл
|
||||||
|
self.loop = urwid.MainLoop(
|
||||||
|
self.main_frame,
|
||||||
|
palette=self.palette,
|
||||||
|
unhandled_input=self.handle_input
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle_input(self, key):
|
||||||
|
if key == 'enter':
|
||||||
|
self.process_command(self.input_edit.get_edit_text())
|
||||||
|
self.input_edit.set_edit_text("")
|
||||||
|
self.history_index = -1
|
||||||
|
elif key == 'up':
|
||||||
|
self.navigate_history(-1)
|
||||||
|
elif key == 'down':
|
||||||
|
self.navigate_history(1)
|
||||||
|
elif key == 'f1':
|
||||||
|
self.show_help()
|
||||||
|
elif key == 'ctrl u':
|
||||||
|
self.input_edit.set_edit_text("")
|
||||||
|
|
||||||
|
def navigate_history(self, direction):
|
||||||
|
if not self.input_history:
|
||||||
|
return
|
||||||
|
|
||||||
|
if direction == -1 and abs(self.history_index) < len(self.input_history):
|
||||||
|
self.history_index -= 1
|
||||||
|
elif direction == 1 and self.history_index < -1:
|
||||||
|
self.history_index += 1
|
||||||
|
|
||||||
|
if -len(self.input_history) <= self.history_index <= -1:
|
||||||
|
self.input_edit.set_edit_text(self.input_history[self.history_index])
|
||||||
|
|
||||||
|
def process_command(self, msg):
|
||||||
|
if not msg.strip():
|
||||||
|
return
|
||||||
|
|
||||||
|
# Добавляем в историю
|
||||||
|
self.input_history.append(msg)
|
||||||
|
if len(self.input_history) > 100:
|
||||||
|
self.input_history.pop(0)
|
||||||
|
|
||||||
|
if msg.lower() == '/exit':
|
||||||
|
self.client.close()
|
||||||
|
raise urwid.ExitMainLoop()
|
||||||
|
elif msg.lower() == '/help':
|
||||||
|
self.show_help()
|
||||||
|
elif msg.lower() in ('y', 'n') and hasattr(self, 'current_file') and self.current_file.get('awaiting_response'):
|
||||||
|
response = '/accept_file' if msg.lower() == 'y' else '/reject_file'
|
||||||
|
encrypted_response = rsa.encrypt(response.encode('utf-8'), self.server_public_key)
|
||||||
|
self.client.send(encrypted_response)
|
||||||
|
|
||||||
|
if msg.lower() == 'y':
|
||||||
|
self.add_message(f"[ФАЙЛ] Ожидайте получения файла {self.current_file['file_name']}...", 'file')
|
||||||
|
else:
|
||||||
|
self.add_message(f"[ФАЙЛ] Вы отказались от получения файла {self.current_file['file_name']}", 'file')
|
||||||
|
|
||||||
|
del self.current_file
|
||||||
|
self.set_status("")
|
||||||
|
elif msg.startswith('/file'):
|
||||||
|
self.send_file(msg)
|
||||||
|
else:
|
||||||
|
# Отображаем свое сообщение
|
||||||
|
self.add_message(f"{self.nickname}: {msg}", 'own')
|
||||||
|
|
||||||
|
# Отправляем на сервер
|
||||||
|
try:
|
||||||
|
encrypted_msg = rsa.encrypt(msg.encode('utf-8'), self.server_public_key)
|
||||||
|
self.client.send(encrypted_msg)
|
||||||
|
except Exception as e:
|
||||||
|
self.add_message(f"[ОШИБКА] Не удалось отправить сообщение: {str(e)}", 'error')
|
||||||
|
|
||||||
|
def send_file(self, command):
|
||||||
|
try:
|
||||||
|
parts = command.split(' ', 2)
|
||||||
|
if len(parts) < 3:
|
||||||
|
self.add_message("[ОШИБКА] Использование: /file <получатель> <путь_к_файлу>", 'error')
|
||||||
|
self.set_status("Используйте: /file <ник> <путь_к_файлу>")
|
||||||
|
return
|
||||||
|
|
||||||
|
recipient = parts[1]
|
||||||
|
file_path = parts[2]
|
||||||
|
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
self.add_message(f"[ОШИБКА] Файл {file_path} не найден", 'error')
|
||||||
|
self.set_status(f"Файл не найден: {file_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
file_size = os.path.getsize(file_path)
|
||||||
|
if file_size > 1024 * 1024: # 1MB лимит
|
||||||
|
self.add_message("[ОШИБКА] Файл слишком большой (макс. 1MB)", 'error')
|
||||||
|
self.set_status("Файл слишком большой (макс. 1MB)")
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
file_data = f.read()
|
||||||
|
|
||||||
|
file_name = os.path.basename(file_path)
|
||||||
|
full_command = f"/file {recipient} {file_name} {file_data.decode('latin1')}"
|
||||||
|
|
||||||
|
encrypted_msg = rsa.encrypt(full_command.encode('latin1'), self.server_public_key)
|
||||||
|
self.client.send(encrypted_msg)
|
||||||
|
|
||||||
|
self.add_message(f"[ФАЙЛ] Запрос на отправку {file_name} пользователю {recipient} отправлен", 'file')
|
||||||
|
self.set_status(f"Запрос на отправку файла {file_name} отправлен")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.add_message(f"[ОШИБКА при отправке файла] {str(e)}", 'error')
|
||||||
|
self.set_status("Ошибка при отправке файла")
|
||||||
|
|
||||||
|
def receive(self):
|
||||||
|
try:
|
||||||
|
# Получаем публичный ключ сервера
|
||||||
|
self.server_public_key = rsa.PublicKey.load_pkcs1(self.client.recv(2048))
|
||||||
|
|
||||||
|
# Отправляем свой публичный ключ
|
||||||
|
self.client.send(self.client_public_key.save_pkcs1())
|
||||||
|
|
||||||
|
# Получаем никнейм
|
||||||
|
self.set_status("Введите ваш никнейм и нажмите Enter")
|
||||||
|
while not self.nickname:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Отправляем никнейм на сервер
|
||||||
|
encrypted_nickname = rsa.encrypt(self.nickname.encode('utf-8'), self.server_public_key)
|
||||||
|
self.client.send(encrypted_nickname)
|
||||||
|
self.set_status(f"Подключено как {self.nickname}")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
encrypted_msg = self.client.recv(4096)
|
||||||
|
if not encrypted_msg:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Расшифровываем сообщение
|
||||||
|
msg = rsa.decrypt(encrypted_msg, self.client_private_key).decode('utf-8')
|
||||||
|
|
||||||
|
if msg.startswith('/file_notification'):
|
||||||
|
self.handle_file_notification(msg)
|
||||||
|
elif msg.startswith('/file_data'):
|
||||||
|
self.handle_file_data(msg)
|
||||||
|
else:
|
||||||
|
self.add_message(msg, 'server' if msg.startswith('[СЕРВЕР]') else 'nick')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.add_message(f"[ОШИБКА] {str(e)}", 'error')
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
self.add_message(f"[ОШИБКА] {str(e)}", 'error')
|
||||||
|
finally:
|
||||||
|
self.client.close()
|
||||||
|
raise urwid.ExitMainLoop()
|
||||||
|
|
||||||
|
def handle_file_notification(self, notification):
|
||||||
|
parts = notification.split(' ', 2)
|
||||||
|
if len(parts) < 3:
|
||||||
|
return
|
||||||
|
|
||||||
|
sender = parts[1]
|
||||||
|
file_name = parts[2]
|
||||||
|
|
||||||
|
self.add_message(f"[ФАЙЛ] {sender} хочет отправить вам файл: {file_name}", 'file')
|
||||||
|
self.set_status(f"Принять файл {file_name} от {sender}? (y/n)")
|
||||||
|
|
||||||
|
self.current_file = {
|
||||||
|
'sender': sender,
|
||||||
|
'file_name': file_name,
|
||||||
|
'awaiting_response': True
|
||||||
|
}
|
||||||
|
|
||||||
|
def handle_file_data(self, file_data):
|
||||||
|
if not hasattr(self, 'current_file'):
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
downloads_dir = Path("downloads")
|
||||||
|
downloads_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
file_path = downloads_dir / self.current_file['file_name']
|
||||||
|
|
||||||
|
with open(file_path, 'wb') as f:
|
||||||
|
f.write(file_data[len('/file_data '):].encode('latin1'))
|
||||||
|
|
||||||
|
self.add_message(f"[ФАЙЛ] Файл {self.current_file['file_name']} сохранен в {file_path}", 'file')
|
||||||
|
self.set_status(f"Файл получен: {self.current_file['file_name']}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.add_message(f"[ОШИБКА] Не удалось сохранить файл: {str(e)}", 'error')
|
||||||
|
finally:
|
||||||
|
if hasattr(self, 'current_file'):
|
||||||
|
del self.current_file
|
||||||
|
|
||||||
|
def add_message(self, text, style=None):
|
||||||
|
if style:
|
||||||
|
self.chat_content.append(urwid.AttrMap(urwid.Text(text), style))
|
||||||
|
else:
|
||||||
|
self.chat_content.append(urwid.Text(text))
|
||||||
|
|
||||||
|
# Автопрокрутка вниз
|
||||||
|
if len(self.chat_content) > 0:
|
||||||
|
self.chat_list.set_focus(len(self.chat_content) - 1)
|
||||||
|
|
||||||
|
def set_status(self, message, timeout=3):
|
||||||
|
self.status_text.set_text(f" {message} ")
|
||||||
|
if timeout > 0:
|
||||||
|
threading.Timer(timeout, lambda: self.set_status("")).start()
|
||||||
|
|
||||||
|
def update_ui(self, loop=None, user_data=None):
|
||||||
|
"""Функция для обновления интерфейса"""
|
||||||
|
current_time = time.time()
|
||||||
|
if current_time - self.last_update >= self.update_interval:
|
||||||
|
self.last_update = current_time
|
||||||
|
# Здесь можно добавить любые обновления интерфейса
|
||||||
|
# Например, обновление времени в статус баре
|
||||||
|
self.loop.draw_screen()
|
||||||
|
|
||||||
|
# Планируем следующее обновление
|
||||||
|
self.loop.set_alarm_in(self.update_interval, self.update_ui)
|
||||||
|
|
||||||
|
def show_help(self):
|
||||||
|
help_text = [
|
||||||
|
"СПРАВКА ПО МЕССЕНДЖЕРУ",
|
||||||
|
"",
|
||||||
|
"Основные команды:",
|
||||||
|
"/exit - Выйти из программы",
|
||||||
|
"/help - Показать эту справку",
|
||||||
|
"",
|
||||||
|
"Отправка файлов:",
|
||||||
|
"/file <ник> <путь> - Отправить файл указанному пользователю",
|
||||||
|
"Пример: /file user2 /home/user/image.jpg",
|
||||||
|
"",
|
||||||
|
"При получении файла:",
|
||||||
|
"1. Вы получите уведомление о входящем файле",
|
||||||
|
"2. Введите 'y' для принятия или 'n' для отказа",
|
||||||
|
"",
|
||||||
|
"Горячие клавиши:",
|
||||||
|
"F1 - Показать/скрыть справку",
|
||||||
|
"Стрелки вверх/вниз - История сообщений",
|
||||||
|
"Ctrl+U - Очистить поле ввода"
|
||||||
|
]
|
||||||
|
|
||||||
|
help_box = urwid.ListBox(urwid.SimpleListWalker([
|
||||||
|
urwid.AttrMap(urwid.Text(line), 'highlight') for line in help_text
|
||||||
|
]))
|
||||||
|
|
||||||
|
overlay = urwid.Overlay(
|
||||||
|
urwid.LineBox(help_box, title="Помощь"),
|
||||||
|
self.main_frame,
|
||||||
|
align='center',
|
||||||
|
width=('relative', 80),
|
||||||
|
valign='middle',
|
||||||
|
height=('relative', 80)
|
||||||
|
)
|
||||||
|
|
||||||
|
def exit_help(key):
|
||||||
|
if key in ('f1', 'esc', 'enter'):
|
||||||
|
self.loop.widget = self.main_frame
|
||||||
|
|
||||||
|
self.loop.widget = overlay
|
||||||
|
self.loop.unhandled_input = exit_help
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# Получаем никнейм
|
||||||
|
self.set_status("Введите ваш никнейм и нажмите Enter")
|
||||||
|
|
||||||
|
def set_nickname(edit, new_edit_text):
|
||||||
|
if new_edit_text.strip():
|
||||||
|
self.nickname = new_edit_text.strip()
|
||||||
|
self.input_edit.set_edit_text("")
|
||||||
|
self.loop.unhandled_input = self.handle_input
|
||||||
|
self.set_status(f"Подключено как {self.nickname}")
|
||||||
|
self.input_edit.set_caption("Сообщение: ")
|
||||||
|
# Запускаем периодическое обновление интерфейса
|
||||||
|
self.loop.set_alarm_in(self.update_interval, self.update_ui)
|
||||||
|
|
||||||
|
self.input_edit.set_caption("Никнейм: ")
|
||||||
|
self.loop.unhandled_input = lambda key: (
|
||||||
|
key == 'enter' and set_nickname(None, self.input_edit.get_edit_text())
|
||||||
|
)
|
||||||
|
|
||||||
|
# Запускаем поток для получения сообщений
|
||||||
|
receive_thread = threading.Thread(target=self.receive, daemon=True)
|
||||||
|
receive_thread.start()
|
||||||
|
|
||||||
|
# Запускаем главный цикл
|
||||||
|
self.loop.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
host = sys.argv[1]
|
||||||
|
port = int(sys.argv[2]) if len(sys.argv) > 2 else 5555
|
||||||
|
client = ChatClient(host, port)
|
||||||
|
else:
|
||||||
|
client = ChatClient()
|
||||||
|
|
||||||
|
client.run()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
if hasattr(client, 'client'):
|
||||||
|
client.client.close()
|
||||||
|
sys.exit(0)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка: {str(e)}")
|
||||||
|
sys.exit(1)
|
143
CSRSA_server.py
Normal file
143
CSRSA_server.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import socket
|
||||||
|
import threading
|
||||||
|
import rsa
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class Server:
|
||||||
|
def __init__(self, host='0.0.0.0', port=5555):
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
||||||
|
self.clients = {}
|
||||||
|
self.public_keys = {}
|
||||||
|
self.server_public_key = None
|
||||||
|
self.server_private_key = None
|
||||||
|
self.generate_keys()
|
||||||
|
self.setup_server()
|
||||||
|
|
||||||
|
def generate_keys(self):
|
||||||
|
(self.server_public_key, self.server_private_key) = rsa.newkeys(2048)
|
||||||
|
|
||||||
|
def setup_server(self):
|
||||||
|
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
self.server.bind((self.host, self.port))
|
||||||
|
self.server.listen()
|
||||||
|
|
||||||
|
def broadcast(self, message, sender=None):
|
||||||
|
for client in self.clients:
|
||||||
|
if client != sender:
|
||||||
|
try:
|
||||||
|
client_public_key = self.public_keys[client]
|
||||||
|
encrypted_msg = rsa.encrypt(message.encode(), client_public_key)
|
||||||
|
client.send(encrypted_msg)
|
||||||
|
except:
|
||||||
|
self.remove_client(client)
|
||||||
|
|
||||||
|
def handle_client(self, client):
|
||||||
|
try:
|
||||||
|
# Отправляем клиенту публичный ключ сервера
|
||||||
|
client.send(self.server_public_key.save_pkcs1())
|
||||||
|
|
||||||
|
# Получаем публичный ключ клиента
|
||||||
|
client_public_key = rsa.PublicKey.load_pkcs1(client.recv(2048))
|
||||||
|
self.public_keys[client] = client_public_key
|
||||||
|
|
||||||
|
# Получаем имя клиента
|
||||||
|
encrypted_name = client.recv(1024)
|
||||||
|
client_name = rsa.decrypt(encrypted_name, self.server_private_key).decode()
|
||||||
|
self.clients[client] = client_name
|
||||||
|
|
||||||
|
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {client_name} подключился.")
|
||||||
|
self.broadcast(f"[СЕРВЕР] {client_name} присоединился к чату!", client)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
encrypted_msg = client.recv(4096)
|
||||||
|
if not encrypted_msg:
|
||||||
|
break
|
||||||
|
|
||||||
|
msg = rsa.decrypt(encrypted_msg, self.server_private_key).decode()
|
||||||
|
|
||||||
|
if msg.startswith('/file'):
|
||||||
|
self.handle_file_transfer(client, msg)
|
||||||
|
else:
|
||||||
|
self.broadcast(f"{self.clients[client]}: {msg}", client)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ОШИБКА] {e}")
|
||||||
|
break
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ОШИБКА] {e}")
|
||||||
|
finally:
|
||||||
|
self.remove_client(client)
|
||||||
|
|
||||||
|
def handle_file_transfer(self, sender, command):
|
||||||
|
try:
|
||||||
|
parts = command.split(' ', 3)
|
||||||
|
if len(parts) < 4:
|
||||||
|
return
|
||||||
|
|
||||||
|
recipient_name = parts[1]
|
||||||
|
file_name = parts[2]
|
||||||
|
file_data = parts[3].encode()
|
||||||
|
|
||||||
|
# Находим получателя
|
||||||
|
recipient = None
|
||||||
|
for client in self.clients:
|
||||||
|
if self.clients[client] == recipient_name:
|
||||||
|
recipient = client
|
||||||
|
break
|
||||||
|
|
||||||
|
if recipient:
|
||||||
|
# Отправляем уведомление получателю
|
||||||
|
notification = f"/file_notification {self.clients[sender]} {file_name}"
|
||||||
|
encrypted_notification = rsa.encrypt(notification.encode(), self.public_keys[recipient])
|
||||||
|
recipient.send(encrypted_notification)
|
||||||
|
|
||||||
|
# Ждем подтверждения
|
||||||
|
response = rsa.decrypt(recipient.recv(1024), self.server_private_key).decode()
|
||||||
|
if response == "/accept_file":
|
||||||
|
# Отправляем файл
|
||||||
|
encrypted_file_data = rsa.encrypt(file_data, self.public_keys[recipient])
|
||||||
|
recipient.send(encrypted_file_data)
|
||||||
|
sender.send(rsa.encrypt(f"[СЕРВЕР] Файл {file_name} отправлен {recipient_name}".encode(),
|
||||||
|
self.public_keys[sender]))
|
||||||
|
else:
|
||||||
|
sender.send(rsa.encrypt(f"[СЕРВЕР] {recipient_name} отказался принять файл".encode(),
|
||||||
|
self.public_keys[sender]))
|
||||||
|
else:
|
||||||
|
sender.send(
|
||||||
|
rsa.encrypt(f"[СЕРВЕР] Пользователь {recipient_name} не найден".encode(), self.public_keys[sender]))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[ОШИБКА при передаче файла] {e}")
|
||||||
|
|
||||||
|
def remove_client(self, client):
|
||||||
|
if client in self.clients:
|
||||||
|
name = self.clients[client]
|
||||||
|
del self.clients[client]
|
||||||
|
if client in self.public_keys:
|
||||||
|
del self.public_keys[client]
|
||||||
|
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {name} отключился.")
|
||||||
|
self.broadcast(f"[СЕРВЕР] {name} покинул чат.", client)
|
||||||
|
client.close()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Сервер запущен на {self.host}:{self.port}")
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
client, address = self.server.accept()
|
||||||
|
print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] Новое соединение с {address[0]}:{address[1]}")
|
||||||
|
|
||||||
|
thread = threading.Thread(target=self.handle_client, args=(client,))
|
||||||
|
thread.start()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nСервер останавливается...")
|
||||||
|
finally:
|
||||||
|
self.server.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
server = Server()
|
||||||
|
server.run()
|
Loading…
Reference in New Issue
Block a user