mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Merge pull request #550 from stumpylog/feature-mail-consume-improve-docs
Feature mail consume improve docs
This commit is contained in:
		| @@ -61,13 +61,13 @@ class FlagMailAction(BaseMailAction): | ||||
|  | ||||
|  | ||||
| def get_rule_action(rule): | ||||
|     if rule.action == MailRule.ACTION_FLAG: | ||||
|     if rule.action == MailRule.AttachmentAction.FLAG: | ||||
|         return FlagMailAction() | ||||
|     elif rule.action == MailRule.ACTION_DELETE: | ||||
|     elif rule.action == MailRule.AttachmentAction.DELETE: | ||||
|         return DeleteMailAction() | ||||
|     elif rule.action == MailRule.ACTION_MOVE: | ||||
|     elif rule.action == MailRule.AttachmentAction.MOVE: | ||||
|         return MoveMailAction() | ||||
|     elif rule.action == MailRule.ACTION_MARK_READ: | ||||
|     elif rule.action == MailRule.AttachmentAction.MARK_READ: | ||||
|         return MarkReadMailAction() | ||||
|     else: | ||||
|         raise NotImplementedError("Unknown action.")  # pragma: nocover | ||||
| @@ -89,11 +89,11 @@ def make_criterias(rule): | ||||
|  | ||||
|  | ||||
| def get_mailbox(server, port, security): | ||||
|     if security == MailAccount.IMAP_SECURITY_NONE: | ||||
|     if security == MailAccount.ImapSecurity.NONE: | ||||
|         mailbox = MailBoxUnencrypted(server, port) | ||||
|     elif security == MailAccount.IMAP_SECURITY_STARTTLS: | ||||
|     elif security == MailAccount.ImapSecurity.STARTTLS: | ||||
|         mailbox = MailBox(server, port, starttls=True) | ||||
|     elif security == MailAccount.IMAP_SECURITY_SSL: | ||||
|     elif security == MailAccount.ImapSecurity.SSL: | ||||
|         mailbox = MailBox(server, port) | ||||
|     else: | ||||
|         raise NotImplementedError("Unknown IMAP security")  # pragma: nocover | ||||
| @@ -112,10 +112,10 @@ class MailAccountHandler(LoggingMixin): | ||||
|             return None | ||||
|  | ||||
|     def get_title(self, message, att, rule): | ||||
|         if rule.assign_title_from == MailRule.TITLE_FROM_SUBJECT: | ||||
|         if rule.assign_title_from == MailRule.TitleSource.FROM_SUBJECT: | ||||
|             return message.subject | ||||
|  | ||||
|         elif rule.assign_title_from == MailRule.TITLE_FROM_FILENAME: | ||||
|         elif rule.assign_title_from == MailRule.TitleSource.FROM_FILENAME: | ||||
|             return os.path.splitext(os.path.basename(att.filename))[0] | ||||
|  | ||||
|         else: | ||||
| @@ -126,20 +126,20 @@ class MailAccountHandler(LoggingMixin): | ||||
|     def get_correspondent(self, message: MailMessage, rule): | ||||
|         c_from = rule.assign_correspondent_from | ||||
|  | ||||
|         if c_from == MailRule.CORRESPONDENT_FROM_NOTHING: | ||||
|         if c_from == MailRule.CorrespondentSource.FROM_NOTHING: | ||||
|             return None | ||||
|  | ||||
|         elif c_from == MailRule.CORRESPONDENT_FROM_EMAIL: | ||||
|         elif c_from == MailRule.CorrespondentSource.FROM_EMAIL: | ||||
|             return self._correspondent_from_name(message.from_) | ||||
|  | ||||
|         elif c_from == MailRule.CORRESPONDENT_FROM_NAME: | ||||
|         elif c_from == MailRule.CorrespondentSource.FROM_NAME: | ||||
|             from_values = message.from_values | ||||
|             if from_values is not None and len(from_values.name) > 0: | ||||
|                 return self._correspondent_from_name(from_values.name) | ||||
|             else: | ||||
|                 return self._correspondent_from_name(message.from_) | ||||
|  | ||||
|         elif c_from == MailRule.CORRESPONDENT_FROM_CUSTOM: | ||||
|         elif c_from == MailRule.CorrespondentSource.FROM_CUSTOM: | ||||
|             return rule.assign_correspondent | ||||
|  | ||||
|         else: | ||||
| @@ -274,7 +274,8 @@ class MailAccountHandler(LoggingMixin): | ||||
|  | ||||
|             if ( | ||||
|                 not att.content_disposition == "attachment" | ||||
|                 and rule.attachment_type == MailRule.ATTACHMENT_TYPE_ATTACHMENTS_ONLY | ||||
|                 and rule.attachment_type | ||||
|                 == MailRule.AttachmentProcessing.ATTACHMENTS_ONLY | ||||
|             ): | ||||
|                 self.log( | ||||
|                     "debug", | ||||
|   | ||||
| @@ -0,0 +1,37 @@ | ||||
| # Generated by Django 4.0.3 on 2022-03-28 17:40 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("paperless_mail", "0008_auto_20210516_0940"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name="mailrule", | ||||
|             name="action", | ||||
|             field=models.PositiveIntegerField( | ||||
|                 choices=[ | ||||
|                     (1, "Mark as read, don't process read mails"), | ||||
|                     (2, "Flag the mail, don't process flagged mails"), | ||||
|                     (3, "Move to specified folder"), | ||||
|                     (4, "Delete"), | ||||
|                 ], | ||||
|                 default=3, | ||||
|                 verbose_name="action", | ||||
|             ), | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name="mailrule", | ||||
|             name="folder", | ||||
|             field=models.CharField( | ||||
|                 default="INBOX", | ||||
|                 help_text="Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server.", | ||||
|                 max_length=256, | ||||
|                 verbose_name="folder", | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
| @@ -8,15 +8,10 @@ class MailAccount(models.Model): | ||||
|         verbose_name = _("mail account") | ||||
|         verbose_name_plural = _("mail accounts") | ||||
|  | ||||
|     IMAP_SECURITY_NONE = 1 | ||||
|     IMAP_SECURITY_SSL = 2 | ||||
|     IMAP_SECURITY_STARTTLS = 3 | ||||
|  | ||||
|     IMAP_SECURITY_OPTIONS = ( | ||||
|         (IMAP_SECURITY_NONE, _("No encryption")), | ||||
|         (IMAP_SECURITY_SSL, _("Use SSL")), | ||||
|         (IMAP_SECURITY_STARTTLS, _("Use STARTTLS")), | ||||
|     ) | ||||
|     class ImapSecurity(models.IntegerChoices): | ||||
|         NONE = 1, _("No encryption") | ||||
|         SSL = 2, _("Use SSL") | ||||
|         STARTTLS = 3, _("Use STARTTLS") | ||||
|  | ||||
|     name = models.CharField(_("name"), max_length=256, unique=True) | ||||
|  | ||||
| @@ -34,8 +29,8 @@ class MailAccount(models.Model): | ||||
|  | ||||
|     imap_security = models.PositiveIntegerField( | ||||
|         _("IMAP security"), | ||||
|         choices=IMAP_SECURITY_OPTIONS, | ||||
|         default=IMAP_SECURITY_SSL, | ||||
|         choices=ImapSecurity.choices, | ||||
|         default=ImapSecurity.SSL, | ||||
|     ) | ||||
|  | ||||
|     username = models.CharField(_("username"), max_length=256) | ||||
| @@ -61,48 +56,25 @@ class MailRule(models.Model): | ||||
|         verbose_name = _("mail rule") | ||||
|         verbose_name_plural = _("mail rules") | ||||
|  | ||||
|     ATTACHMENT_TYPE_ATTACHMENTS_ONLY = 1 | ||||
|     ATTACHMENT_TYPE_EVERYTHING = 2 | ||||
|     class AttachmentProcessing(models.IntegerChoices): | ||||
|         ATTACHMENTS_ONLY = 1, _("Only process attachments.") | ||||
|         EVERYTHING = 2, _("Process all files, including 'inline' " "attachments.") | ||||
|  | ||||
|     ATTACHMENT_TYPES = ( | ||||
|         (ATTACHMENT_TYPE_ATTACHMENTS_ONLY, _("Only process attachments.")), | ||||
|         ( | ||||
|             ATTACHMENT_TYPE_EVERYTHING, | ||||
|             _("Process all files, including 'inline' " "attachments."), | ||||
|         ), | ||||
|     ) | ||||
|     class AttachmentAction(models.IntegerChoices): | ||||
|         DELETE = 1, _("Mark as read, don't process read mails") | ||||
|         MOVE = 2, _("Flag the mail, don't process flagged mails") | ||||
|         MARK_READ = 3, _("Move to specified folder") | ||||
|         FLAG = 4, _("Delete") | ||||
|  | ||||
|     ACTION_DELETE = 1 | ||||
|     ACTION_MOVE = 2 | ||||
|     ACTION_MARK_READ = 3 | ||||
|     ACTION_FLAG = 4 | ||||
|     class TitleSource(models.IntegerChoices): | ||||
|         FROM_SUBJECT = 1, _("Use subject as title") | ||||
|         FROM_FILENAME = 2, _("Use attachment filename as title") | ||||
|  | ||||
|     ACTIONS = ( | ||||
|         (ACTION_MARK_READ, _("Mark as read, don't process read mails")), | ||||
|         (ACTION_FLAG, _("Flag the mail, don't process flagged mails")), | ||||
|         (ACTION_MOVE, _("Move to specified folder")), | ||||
|         (ACTION_DELETE, _("Delete")), | ||||
|     ) | ||||
|  | ||||
|     TITLE_FROM_SUBJECT = 1 | ||||
|     TITLE_FROM_FILENAME = 2 | ||||
|  | ||||
|     TITLE_SELECTOR = ( | ||||
|         (TITLE_FROM_SUBJECT, _("Use subject as title")), | ||||
|         (TITLE_FROM_FILENAME, _("Use attachment filename as title")), | ||||
|     ) | ||||
|  | ||||
|     CORRESPONDENT_FROM_NOTHING = 1 | ||||
|     CORRESPONDENT_FROM_EMAIL = 2 | ||||
|     CORRESPONDENT_FROM_NAME = 3 | ||||
|     CORRESPONDENT_FROM_CUSTOM = 4 | ||||
|  | ||||
|     CORRESPONDENT_SELECTOR = ( | ||||
|         (CORRESPONDENT_FROM_NOTHING, _("Do not assign a correspondent")), | ||||
|         (CORRESPONDENT_FROM_EMAIL, _("Use mail address")), | ||||
|         (CORRESPONDENT_FROM_NAME, _("Use name (or mail address if not available)")), | ||||
|         (CORRESPONDENT_FROM_CUSTOM, _("Use correspondent selected below")), | ||||
|     ) | ||||
|     class CorrespondentSource(models.IntegerChoices): | ||||
|         FROM_NOTHING = 1, _("Do not assign a correspondent") | ||||
|         FROM_EMAIL = 2, _("Use mail address") | ||||
|         FROM_NAME = 3, _("Use name (or mail address if not available)") | ||||
|         FROM_CUSTOM = 4, _("Use correspondent selected below") | ||||
|  | ||||
|     name = models.CharField(_("name"), max_length=256, unique=True) | ||||
|  | ||||
| @@ -119,7 +91,10 @@ class MailRule(models.Model): | ||||
|         _("folder"), | ||||
|         default="INBOX", | ||||
|         max_length=256, | ||||
|         help_text=_("Subfolders must be separated by dots."), | ||||
|         help_text=_( | ||||
|             "Subfolders must be separated by a delimiter, often a dot ('.') or" | ||||
|             " slash ('/'), but it varies by mail server.", | ||||
|         ), | ||||
|     ) | ||||
|  | ||||
|     filter_from = models.CharField( | ||||
| @@ -161,8 +136,8 @@ class MailRule(models.Model): | ||||
|  | ||||
|     attachment_type = models.PositiveIntegerField( | ||||
|         _("attachment type"), | ||||
|         choices=ATTACHMENT_TYPES, | ||||
|         default=ATTACHMENT_TYPE_ATTACHMENTS_ONLY, | ||||
|         choices=AttachmentProcessing.choices, | ||||
|         default=AttachmentProcessing.ATTACHMENTS_ONLY, | ||||
|         help_text=_( | ||||
|             "Inline attachments include embedded images, so it's best " | ||||
|             "to combine this option with a filename filter.", | ||||
| @@ -171,8 +146,8 @@ class MailRule(models.Model): | ||||
|  | ||||
|     action = models.PositiveIntegerField( | ||||
|         _("action"), | ||||
|         choices=ACTIONS, | ||||
|         default=ACTION_MARK_READ, | ||||
|         choices=AttachmentAction.choices, | ||||
|         default=AttachmentAction.MARK_READ, | ||||
|     ) | ||||
|  | ||||
|     action_parameter = models.CharField( | ||||
| @@ -190,8 +165,8 @@ class MailRule(models.Model): | ||||
|  | ||||
|     assign_title_from = models.PositiveIntegerField( | ||||
|         _("assign title from"), | ||||
|         choices=TITLE_SELECTOR, | ||||
|         default=TITLE_FROM_SUBJECT, | ||||
|         choices=TitleSource.choices, | ||||
|         default=TitleSource.FROM_SUBJECT, | ||||
|     ) | ||||
|  | ||||
|     assign_tag = models.ForeignKey( | ||||
| @@ -212,8 +187,8 @@ class MailRule(models.Model): | ||||
|  | ||||
|     assign_correspondent_from = models.PositiveIntegerField( | ||||
|         _("assign correspondent from"), | ||||
|         choices=CORRESPONDENT_SELECTOR, | ||||
|         default=CORRESPONDENT_FROM_NOTHING, | ||||
|         choices=CorrespondentSource.choices, | ||||
|         default=CorrespondentSource.FROM_NOTHING, | ||||
|     ) | ||||
|  | ||||
|     assign_correspondent = models.ForeignKey( | ||||
|   | ||||
| @@ -246,13 +246,13 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|  | ||||
|         rule = MailRule( | ||||
|             name="a", | ||||
|             assign_correspondent_from=MailRule.CORRESPONDENT_FROM_NOTHING, | ||||
|             assign_correspondent_from=MailRule.CorrespondentSource.FROM_NOTHING, | ||||
|         ) | ||||
|         self.assertIsNone(handler.get_correspondent(message, rule)) | ||||
|  | ||||
|         rule = MailRule( | ||||
|             name="b", | ||||
|             assign_correspondent_from=MailRule.CORRESPONDENT_FROM_EMAIL, | ||||
|             assign_correspondent_from=MailRule.CorrespondentSource.FROM_EMAIL, | ||||
|         ) | ||||
|         c = handler.get_correspondent(message, rule) | ||||
|         self.assertIsNotNone(c) | ||||
| @@ -264,7 +264,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|  | ||||
|         rule = MailRule( | ||||
|             name="c", | ||||
|             assign_correspondent_from=MailRule.CORRESPONDENT_FROM_NAME, | ||||
|             assign_correspondent_from=MailRule.CorrespondentSource.FROM_NAME, | ||||
|         ) | ||||
|         c = handler.get_correspondent(message, rule) | ||||
|         self.assertIsNotNone(c) | ||||
| @@ -275,7 +275,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|  | ||||
|         rule = MailRule( | ||||
|             name="d", | ||||
|             assign_correspondent_from=MailRule.CORRESPONDENT_FROM_CUSTOM, | ||||
|             assign_correspondent_from=MailRule.CorrespondentSource.FROM_CUSTOM, | ||||
|             assign_correspondent=someone_else, | ||||
|         ) | ||||
|         c = handler.get_correspondent(message, rule) | ||||
| @@ -289,9 +289,15 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|  | ||||
|         handler = MailAccountHandler() | ||||
|  | ||||
|         rule = MailRule(name="a", assign_title_from=MailRule.TITLE_FROM_FILENAME) | ||||
|         rule = MailRule( | ||||
|             name="a", | ||||
|             assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|         ) | ||||
|         self.assertEqual(handler.get_title(message, att, rule), "this_is_the_file") | ||||
|         rule = MailRule(name="b", assign_title_from=MailRule.TITLE_FROM_SUBJECT) | ||||
|         rule = MailRule( | ||||
|             name="b", | ||||
|             assign_title_from=MailRule.TitleSource.FROM_SUBJECT, | ||||
|         ) | ||||
|         self.assertEqual(handler.get_title(message, att, rule), "the message title") | ||||
|  | ||||
|     def test_handle_message(self): | ||||
| @@ -302,7 +308,10 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         ) | ||||
|  | ||||
|         account = MailAccount() | ||||
|         rule = MailRule(assign_title_from=MailRule.TITLE_FROM_FILENAME, account=account) | ||||
|         rule = MailRule( | ||||
|             assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|             account=account, | ||||
|         ) | ||||
|  | ||||
|         result = self.mail_account_handler.handle_message(message, rule) | ||||
|  | ||||
| @@ -346,7 +355,10 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         ) | ||||
|  | ||||
|         account = MailAccount() | ||||
|         rule = MailRule(assign_title_from=MailRule.TITLE_FROM_FILENAME, account=account) | ||||
|         rule = MailRule( | ||||
|             assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|             account=account, | ||||
|         ) | ||||
|  | ||||
|         result = self.mail_account_handler.handle_message(message, rule) | ||||
|  | ||||
| @@ -369,7 +381,10 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         ) | ||||
|  | ||||
|         account = MailAccount() | ||||
|         rule = MailRule(assign_title_from=MailRule.TITLE_FROM_FILENAME, account=account) | ||||
|         rule = MailRule( | ||||
|             assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|             account=account, | ||||
|         ) | ||||
|  | ||||
|         result = self.mail_account_handler.handle_message(message, rule) | ||||
|  | ||||
| @@ -392,9 +407,9 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|  | ||||
|         account = MailAccount() | ||||
|         rule = MailRule( | ||||
|             assign_title_from=MailRule.TITLE_FROM_FILENAME, | ||||
|             assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|             account=account, | ||||
|             attachment_type=MailRule.ATTACHMENT_TYPE_EVERYTHING, | ||||
|             attachment_type=MailRule.AttachmentProcessing.EVERYTHING, | ||||
|         ) | ||||
|  | ||||
|         result = self.mail_account_handler.handle_message(message, rule) | ||||
| @@ -427,7 +442,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|             self.async_task.reset_mock() | ||||
|             account = MailAccount() | ||||
|             rule = MailRule( | ||||
|                 assign_title_from=MailRule.TITLE_FROM_FILENAME, | ||||
|                 assign_title_from=MailRule.TitleSource.FROM_FILENAME, | ||||
|                 account=account, | ||||
|                 filter_attachment_filename=pattern, | ||||
|             ) | ||||
| @@ -452,7 +467,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MARK_READ, | ||||
|             action=MailRule.AttachmentAction.MARK_READ, | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual(len(self.bogus_mailbox.messages), 3) | ||||
| @@ -475,7 +490,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_DELETE, | ||||
|             action=MailRule.AttachmentAction.DELETE, | ||||
|             filter_subject="Invoice", | ||||
|         ) | ||||
|  | ||||
| @@ -496,7 +511,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_FLAG, | ||||
|             action=MailRule.AttachmentAction.FLAG, | ||||
|             filter_subject="Invoice", | ||||
|         ) | ||||
|  | ||||
| @@ -519,7 +534,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|             filter_subject="Claim", | ||||
|         ) | ||||
| @@ -565,7 +580,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|             filter_subject="Claim", | ||||
|         ) | ||||
| @@ -586,7 +601,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|             filter_subject="Claim", | ||||
|             order=1, | ||||
| @@ -595,7 +610,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule2", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|             filter_subject="Claim", | ||||
|             order=2, | ||||
| @@ -625,7 +640,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         _ = MailRule.objects.create( | ||||
|             name="testrule", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|         ) | ||||
|  | ||||
| @@ -650,9 +665,9 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|             name="testrule", | ||||
|             filter_from="amazon@amazon.de", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_MOVE, | ||||
|             action=MailRule.AttachmentAction.MOVE, | ||||
|             action_parameter="spam", | ||||
|             assign_correspondent_from=MailRule.CORRESPONDENT_FROM_EMAIL, | ||||
|             assign_correspondent_from=MailRule.CorrespondentSource.FROM_EMAIL, | ||||
|         ) | ||||
|  | ||||
|         self.mail_account_handler.handle_mail_account(account) | ||||
| @@ -687,7 +702,7 @@ class TestMail(DirectoriesMixin, TestCase): | ||||
|         rule = MailRule.objects.create( | ||||
|             name="testrule3", | ||||
|             account=account, | ||||
|             action=MailRule.ACTION_DELETE, | ||||
|             action=MailRule.AttachmentAction.DELETE, | ||||
|             filter_subject="Claim", | ||||
|         ) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 shamoon
					shamoon