Пример #1
0
 def setUp(self):
     self.user = User.objects.create_user('testuser', '*****@*****.**', 'testPass')
     self.client.login(username='******', password='******')
     # Create test data
     ml = FakeList("*****@*****.**")
     ml.subject_prefix = u"[example] "
     # Create 3 threads
     messages = []
     for msgnum in range(3):
         msg = Message()
         msg["From"] = "*****@*****.**"
         msg["Message-ID"] = "<id%d>" % (msgnum+1)
         msg["Subject"] = "Dummy message"
         msg.set_payload("Dummy message")
         self.store.add_to_list(ml, msg)
         messages.append(msg)
     # 1st is unread, 2nd is read, 3rd is updated
     LastView.objects.create(list_address="*****@*****.**", user=self.user,
                             threadid=get_message_id_hash("<id2>"))
     LastView.objects.create(list_address="*****@*****.**", user=self.user,
                             threadid=get_message_id_hash("<id3>"))
     msg4 = Message()
     msg4["From"] = "*****@*****.**"
     msg4["Message-ID"] = "<id4>"
     msg4["Subject"] = "Dummy message"
     msg4["In-Reply-To"] = "<id3>"
     msg4.set_payload("Dummy message")
     self.store.add_to_list(ml, msg4)
Пример #2
0
 def setUp(self):
     self.user = User.objects.create_user('testuser', '*****@*****.**', 'testPass')
     self.client.login(username='******', password='******')
     store = kittystore.get_store(SettingsModule(), debug=False, auto_create=True)
     self.client.defaults = {"kittystore.store": store,
                             "HTTP_USER_AGENT": "testbot",
                             }
     # Create test data
     ml = FakeList("*****@*****.**")
     ml.subject_prefix = u"[example] "
     # Create 3 threads
     messages = []
     for msgnum in range(3):
         msg = Message()
         msg["From"] = "*****@*****.**"
         msg["Message-ID"] = "<id%d>" % (msgnum+1)
         msg["Subject"] = "Dummy message"
         msg.set_payload("Dummy message")
         store.add_to_list(ml, msg)
         messages.append(msg)
     # 1st is unread, 2nd is read, 3rd is updated
     LastView.objects.create(list_address="*****@*****.**", user=self.user,
                             threadid=get_message_id_hash("<id2>"))
     LastView.objects.create(list_address="*****@*****.**", user=self.user,
                             threadid=get_message_id_hash("<id3>"))
     msg4 = Message()
     msg4["From"] = "*****@*****.**"
     msg4["Message-ID"] = "<id4>"
     msg4["Subject"] = "Dummy message"
     msg4["In-Reply-To"] = "<id3>"
     msg4.set_payload("Dummy message")
     store.add_to_list(ml, msg4)
Пример #3
0
 def setUp(self):
     self.user = User.objects.create_user('testuser', '*****@*****.**',
                                          'testPass')
     self.client.login(username='******', password='******')
     store = kittystore.get_store(SettingsModule(), debug=False)
     ml = FakeList("*****@*****.**")
     ml.subject_prefix = u"[example] "
     # Create 3 threads
     messages = []
     for msgnum in range(3):
         msg = Message()
         msg["From"] = "*****@*****.**"
         msg["Message-ID"] = "<id%d>" % (msgnum + 1)
         msg["Subject"] = "Dummy message"
         msg.set_payload("Dummy message")
         store.add_to_list(ml, msg)
         messages.append(msg)
     # 1st is unread, 2nd is read, 3rd is updated
     LastView.objects.create(list_address="*****@*****.**",
                             user=self.user,
                             threadid=get_message_id_hash("<id2>"))
     LastView.objects.create(list_address="*****@*****.**",
                             user=self.user,
                             threadid=get_message_id_hash("<id3>"))
     msg4 = Message()
     msg4["From"] = "*****@*****.**"
     msg4["Message-ID"] = "<id4>"
     msg4["Subject"] = "Dummy message"
     msg4["In-Reply-To"] = "<id3>"
     msg4.set_payload("Dummy message")
     store.add_to_list(ml, msg4)
     # Factory
     defaults = {"kittystore.store": store, "HTTP_USER_AGENT": "testbot"}
     self.factory = RequestFactory(**defaults)
Пример #4
0
 def check_neighbors(thread, expected_prev, expected_next):
     thread_id = get_message_id_hash("<id%s_1>" % thread)
     prev_th, next_th = self.store.get_thread_neighbors(
         "example-list", thread_id)
     # convert to something I can compare
     prev_th = prev_th and prev_th.thread_id
     expected_prev = expected_prev and \
             get_message_id_hash("<id%s_1>" % expected_prev)
     next_th = next_th and next_th.thread_id
     expected_next = expected_next and \
             get_message_id_hash("<id%s_1>" % expected_next)
     # compare
     self.assertEqual(prev_th, expected_prev)
     self.assertEqual(next_th, expected_next)
Пример #5
0
 def check_neighbors(thread, expected_prev, expected_next):
     thread_id = get_message_id_hash("<id%s_1>" % thread)
     prev_th, next_th = self.store.get_thread_neighbors(
             "example-list", thread_id)
     # convert to something I can compare
     prev_th = prev_th and prev_th.thread_id
     expected_prev = expected_prev and \
             get_message_id_hash("<id%s_1>" % expected_prev)
     next_th = next_th and next_th.thread_id
     expected_next = expected_next and \
             get_message_id_hash("<id%s_1>" % expected_next)
     # compare
     self.assertEqual(prev_th, expected_prev)
     self.assertEqual(next_th, expected_next)
Пример #6
0
 def test_vote_down(self):
     url = reverse('message_vote', args=("*****@*****.**",
                   get_message_id_hash("msg")))
     resp = self.client.post(url, {"vote": "-1"})
     self.assertEqual(resp.status_code, 200)
     result = json.loads(resp.content)
     self.assertEqual(result["like"], 0)
     self.assertEqual(result["dislike"], 1)
Пример #7
0
 def test_vote_down(self):
     url = reverse('message_vote',
                   args=("*****@*****.**", get_message_id_hash("msg")))
     resp = self.client.post(url, {"vote": "-1"})
     self.assertEqual(resp.status_code, 200)
     result = json.loads(resp.content)
     self.assertEqual(result["like"], 0)
     self.assertEqual(result["dislike"], 1)
Пример #8
0
    def add_to_list(self, list_name, message):
        """Add the message to a specific list of the store.

        :param list_name: The fully qualified list name to which the
            message should be added.
        :param message: An email.message.Message instance containing at
            least a unique Message-ID header.  The message will be given
            an X-Message-ID-Hash header, overriding any existing such
            header.
        :returns: The calculated X-Message-ID-Hash header.
        :raises ValueError: if the message is missing a Message-ID 
            header.
            The storage service is also allowed to raise this exception
            if it find, but disallows collisions.
        """
        email = get_class_object(list_to_table_name(list_name), 'email',
                        MetaData(self.engine), create=True)
        if not message.has_key("Message-Id"):
            raise ValueError("No 'Message-Id' header in email", message)
        msg_id = message['Message-Id'].strip("<>")
        msg_id_hash = get_message_id_hash(msg_id)
        if self.get_message_by_id_from_list(list_name, msg_id) is not None:
            print ("Duplicate email from %s: %s" %
                   (message['From'], message.get('Subject', '""')))
            return msg_id_hash

        # Find thread id
        ref, thread_id = get_ref_and_thread_id(message, list_name, self)
        if thread_id is None:
            # make up the thread_id if not found
            thread_id = msg_id_hash

        from_name, from_email = parseaddr(message['From'])
        from_name = header_to_unicode(from_name)
        full = message.as_string()
        scrubber = Scrubber(list_name, message, self)
        payload = scrubber.scrub() # modifies the message in-place

        #category = 'Question' # TODO: enum + i18n ?
        #if ('agenda' in message.get('Subject', '').lower() or
        #        'reminder' in message.get('Subject', '').lower()):
        #    # i18n!
        #    category = 'Agenda'

        mail = email(
            sender=from_name,
            email=from_email,
            subject=header_to_unicode(message.get('Subject')),
            content=payload.encode("utf-8"),
            date=parsedate(message.get("Date")),
            message_id=msg_id,
            stable_url_id=msg_id_hash,
            thread_id=thread_id,
            references=ref,
            full=full,
            )
        self.session.add(mail)
        return msg_id_hash
Пример #9
0
 def test_thread(self):
     responses = []
     for msgnum in range(3):
         threadid = get_message_id_hash("<id%d>" % (msgnum+1))
         response = self.client.get(reverse('thread', args=(
                     "*****@*****.**", threadid)))
         responses.append(response)
     # There's always one icon in the right column, so all counts are +1
     self.assertContains(responses[0], "fa-envelope", count=2, status_code=200)
     self.assertContains(responses[1], "fa-envelope", count=1, status_code=200)
     self.assertContains(responses[2], "fa-envelope", count=2, status_code=200)
Пример #10
0
 def test_thread(self):
     responses = []
     for msgnum in range(3):
         threadid = get_message_id_hash("<id%d>" % (msgnum+1))
         request = self.factory.get(reverse('thread',
                     args=["*****@*****.**", threadid]))
         request.user = self.user
         response = thread_index(request, "*****@*****.**", threadid)
         responses.append(response)
     # There's always one icon in the right column, so all counts are +1
     self.assertContains(responses[0], "icon-eye-close", count=2, status_code=200)
     self.assertContains(responses[1], "icon-eye-close", count=1, status_code=200)
     self.assertContains(responses[2], "icon-eye-close", count=2, status_code=200)
Пример #11
0
    def permalink(self, mlist, msg):
        """Return the url to the message in the archive.

        This url points directly to the message in the archive.  This method
        only calculates the url, it does not actually archive the message.

        :param mlist: The IMailingList object.
        :param msg: The message object.
        :returns: The url string or None if the message's archive url cannot
            be calculated.
        """
        msg_id = msg['Message-Id'].strip().strip("<>")
        msg_hash = get_message_id_hash(msg_id)
        return urljoin(self.store_url, reverse('message_index',
                    kwargs={"mlist_fqdn": mlist.fqdn_listname,
                            "message_id_hash": msg_hash}))
Пример #12
0
 def test_thread(self):
     responses = []
     for msgnum in range(3):
         threadid = get_message_id_hash("<id%d>" % (msgnum + 1))
         response = self.client.get(
             reverse('thread', args=("*****@*****.**", threadid)))
         responses.append(response)
     # There's always one icon in the right column, so all counts are +1
     self.assertContains(responses[0],
                         "icon-eye-close",
                         count=2,
                         status_code=200)
     self.assertContains(responses[1],
                         "icon-eye-close",
                         count=1,
                         status_code=200)
     self.assertContains(responses[2],
                         "icon-eye-close",
                         count=2,
                         status_code=200)
Пример #13
0
    def permalink(self, mlist, msg):
        """Return the url to the message in the archive.

        This url points directly to the message in the archive.  This method
        only calculates the url, it does not actually archive the message.

        :param mlist: The IMailingList object.
        :param msg: The message object.
        :returns: The url string or None if the message's archive url cannot
            be calculated.
        """
        msg_id = msg['Message-Id'].strip().strip("<>")
        msg_hash = get_message_id_hash(msg_id)
        return urljoin(
            self.base_url,
            reverse('message_index',
                    kwargs={
                        "mlist_fqdn": mlist.fqdn_listname,
                        "message_id_hash": msg_hash
                    }))
Пример #14
0
 def test_unauth_vote(self):
     self.client.logout()
     url = reverse('message_vote', args=("*****@*****.**",
                   get_message_id_hash("msg")))
     resp = self.client.post(url, {"vote": "1"})
     self.assertEqual(resp.status_code, 403)
Пример #15
0
 def test_unauth_vote(self):
     self.client.logout()
     url = reverse('message_vote',
                   args=("*****@*****.**", get_message_id_hash("msg")))
     resp = self.client.post(url, {"vote": "1"})
     self.assertEqual(resp.status_code, 403)
Пример #16
0
 def __init__(self, list_name, message_id):
     self.list_name = unicode(list_name)
     self.message_id = unicode(message_id)
     self.message_id_hash = unicode(get_message_id_hash(self.message_id))
Пример #17
0
 def __init__(self, *args, **kw):
     Base.__init__(self, *args, **kw)
     if "message_id_hash" not in kw:
         self.message_id_hash = unicode(get_message_id_hash(self.message_id))
Пример #18
0
 def __init__(self, list_name, message_id):
     self.list_name = unicode(list_name)
     self.message_id = unicode(message_id)
     self.message_id_hash = unicode(get_message_id_hash(self.message_id))