Skip to content

Commit

Permalink
Merge pull request #375 from hpi-swa-teaching/develop
Browse files Browse the repository at this point in the history
all changes from the 2020 swt group
  • Loading branch information
JuliaJoch committed Aug 2, 2020
2 parents 05fac55 + a2379c9 commit 41b2f3d
Show file tree
Hide file tree
Showing 456 changed files with 1,702 additions and 1,164 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# This is a basic workflow to help you get started with Actions
on: [push, pull_request]

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
jobs:
# This workflow contains a single job called "build"
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
# Select platform(s)
os: [ ubuntu-latest, windows-latest ]
# Select compatible Smalltalk image(s)
smalltalk: [ Squeak64-trunk, Squeak64-5.3, Squeak64-5.2 ]
name: ${{ matrix.smalltalk }} on ${{ matrix.os }}
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: hpi-swa/setup-smalltalkCI@v1
with:
smalltalk-version: ${{ matrix.smalltalk }}
- run: smalltalkci -s ${{ matrix.smalltalk }}
timeout-minutes: 15
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

74 changes: 58 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# IMAPClient [![Build Status](https://travis-ci.org/hpi-swa-teaching/IMAPClient.svg?branch=develop)](https://travis-ci.org/hpi-swa-teaching/IMAPClient) [![Coverage Status](https://coveralls.io/repos/github/hpi-swa-teaching/IMAPClient/badge.svg?branch=develop)](https://coveralls.io/github/hpi-swa-teaching/IMAPClient?branch=develop)

We proudly present our IMAP Client for Smalltalk Squeak, which we developed and improved during the summer term 2018 of the Software Engineering course.
Welcome to our IMAP Client project. We are a team of 4th semester IT-Systems Engineering students and are happy to take over this project for the sixth iteration.
This project is part of a lecture in Softwareengineering techniques and will be contributing to our final grade, so we are giving it our best ;)
As this is a student project, it will mostly be worked on during the summer terms. Therefore our time with this project is limited to the end of july.

In case of any questions, feel free to contact us.

## Installation
1. Get [Squeak 5.2 or later](http://www.squeak.org)
Expand All @@ -22,38 +26,78 @@ You can open the tool with the command `ICFolderDialog new` or using a Menu Entr

## Configuration
You can customize the number of mails, which are fetched on the initial update process, and the number of mails which are loaded if you press the `Load older Mails` Button. Default are 100 and 10. Change `ICFolder>>numbersOfHeadersToFetch{AtLoaderOlderMail | AtTheBeginning}`
This will not regard the e-mails that are already persisted on your disk, so if you have some e-mails in a Maildir directory, all of them will be read no matter what you defined here.

## Features
- Manage different accounts

![](screenshots/manage_accounts.png)
![](screenshots/addAccount.png)
You can add an account by clicking the `+` button. You will then be prompted to enter the account information needed to establish a connection with the server.

- Fetch new mails from the server

![](screenshots/update_mails.png)
![](screenshots/updating.png)
Mails are automatically fetched on login. If you wish to update and resynchronize with the server, click the update button.

- Delete & move mails
![](screenshots/move.png)
A right click on any mail will show you your options. Deleting a mail automatically moves it to the trash folder. If you want to revert a deletion, you can simply navigate to the trash folder and move the email back to another folder.
When you want to permanently delete emails, right click on the trash folder and choose expunge. This will dump your trash folder permanently.

- Flag and read emails
A right click on any mail will show you your options. You can flag an email for later use or mark it as seen if you do not want to be disturbed by it beeing highlighted anymore. Also you can mark already seen mails as unseen again.
![](screenshots/flag.png)
![](screenshots/unflag.png)

- See unseen mails immediately.
All unseen mails will be highlighted and the number of unseen mails per folder can be seen next to the folder name.

![](screenshots/move_mails.png)
- See unseen mails immediately + Search Mails
- Search Mails
![](screenshots/search.png)
You can enter a search string into the search bar at the top. Right next to the search bar you can see, how many search results you got for the current search.

![](screenshots/search_mails.png)
- Display emails correctly (parse different encodings)
- Parse different encodings

- Reflect server changes back to Client. If you're accessing your mails for a different device, and deleting/moving them, just press the update button in the Client, and every change should be correctly updated.
- Reflect server changes back to Client.
If you're accessing your mails for a different device, and deleting/moving them, just press the update button in the Client, and every change should be correctly updated.

- Display emails correctly (parse different encodings)
- Sort mails by different categories.
![](screenshots/sort.png)
By default all sortings are ascending. Double clicking the button will switch do descending order.

- Addressbook.
![](screenshots/addressbook.png)
You can open the addressbook by clicking the button with the person icon. The adressbook holds all sender addresses of mails from any of the currently logged in accounts.

## Usage
Start the IMAP Client with `ICFolderDialog new`. Add new Accounts with the `+` Button. We tested the functionality with the HPI OWA Accounts. But other accounts should work fine.
Start the IMAP Client with `ICFolderDialog new`. Add new Accounts with the `+` Button. We tested the functionality with web.de Accounts. But other accounts should work fine.
The hpi owa accounts are known to be relatively large, as calendar and contact meta information is also sent to our client as folder objects. Therefore it might not entirely load in the requested time of 5 seconds.

For HPI accounts use the following login info:
```
Server: owa.hpi.de
Port: 993
Username: surname.lastname
Password: xxxxxxx
Use SSL: True
```
For web.de accounts use the following login info:
```
Server: imap.web.de
Port: 993
Username: username
Password: xxxxxxx
Use SSL: True
```

## Security
Your password isn't stored on disk, but visible to your Squeak environment. After closing the IMAP-Client and reopening it your are welcomed by a password prompt to re-enter your credentials.
Your password isn't stored on disk, but will be visible to your Squeak environment. It is immediately deleted after login, so you will not be able to retrieve it afterwards, but be aware that we are no security experts and you might not want to test this with a high severity account.
After closing the IMAP-Client and reopening it your are welcomed by a password prompt to re-enter your credentials.

## Known Problems

As this project has lived through many iterations, there are a couple of known issues that we could not resolve during the few months we spend with this project.
If you encounter any problem while using our IMAP client, have a look at the Issues of this GitHub Project. Most of them are probably already known to us.
In case your problem has not been reported yet, feel free to post a new issue and describe what you did to get the problem, what the unexpected behaviour was and what behaviour you would have expected.
Thank you in anvance for contributing to making this project better by reporting any problems that we are not yet aware of!

## Documentation

Expand All @@ -68,6 +112,4 @@ Hava a look at the GitHub Project Wiki to find more insights into the project.

2019: Paul Methfessel, Martin Taraz, Otto Kissig, Tim Garrels, Felix Rindt

## Questions

If you have any question, feel free to drop us a line :-)
2020: Henrik Guhl, Lorenz Woth, Niko Hastrich, Julia Joch
1 change: 1 addition & 0 deletions packages/IMAPClient-Core.package/.squot-contents
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
SquotTrackedObjectMetadata {
#objectClassName : #PackageInfo,
#objectsReplacedByNames : true,
#serializer : #SquotCypressCodeSerializer
}
10 changes: 10 additions & 0 deletions packages/IMAPClient-Core.package/ICAccountInfo.class/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
An ICAccountInfo is a dataobject holding information needed to connect to a server such as server address and user credentials. It also ensures basic IMAP datatype validity.

Instance Variables

accountName: Name of the account set by the user.
host: Hostname of the IMAP server.
port: Port of the IMAP service on the server. Default: 993.
username: Username to login at the IMAP server.
password: Password of the user to login at the server. Will be deleted after login.


Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ instance creation
newWith: aDataDictionary

^ self new
accountName: (aDataDictionary at: 'accountName');
host: (aDataDictionary at: 'address');
port: ((aDataDictionary at: 'port') asNumber);
username: (aDataDictionary at: 'username');
password: (aDataDictionary at: 'password');
ssl: (aDataDictionary at: 'ssl')
accountName: (aDataDictionary at: 'accountName' ifAbsent: [nil]);
host: (aDataDictionary at: 'address' ifAbsent: [self invalidHost]);
port: ((aDataDictionary at: 'port' ifAbsent: [self invalidPort]) asNumber);
username: (aDataDictionary at: 'username' ifAbsent: [self invalidUsername]);
password: (aDataDictionary at: 'password' ifAbsent: [self invalidPassword]);
ssl: (aDataDictionary at: 'ssl' ifAbsent: [self initialSsl])
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
comparing
= anotherAccountInfo
^ (self class = anotherAccountInfo class)
and: [self asDictionary = anotherAccountInfo asDictionary]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
validating
accountNameUnused

^ ICEndPoint connectionConfigurations
noneSatisfy: [:each | (self accountName) = (each accountName)]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
accessing
converting
asDictionary

| dict |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
validation
validating
canConvert: aString

^ ('"|\\' asRegex matchesIn: aString) isEmpty
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
action
eraseStoredPassword

self password: ''
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
validation
validating
hasValidServerInfo

^ self host ~= self class invalidHost
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
validation
validating
hasValidUserInfo

^ self username ~= self class invalidUsername
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
comparing
hash
"Answer an integer value that is related to the identity of the receiver."

^ self username bitXor: (self accountName bitXor: (self host bitXor: self port hash))
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
validation
validating
isValid

^ self hasValidServerInfo and: [self hasValidUserInfo]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
accessing
missingFields

^ (self asDictionary select: [ :value | (value asString isEmpty) | (value = nil asString) ]) keys
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
accessing
converting
passwordAsIMAPString

^ '"', self password, '"'
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
accessing
converting
usernameAsIMAPString

^ '"', self username, '"'
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@
"invalidPassword" : "tg 7/10/2019 20:10",
"invalidPort" : "tg 7/10/2019 20:09",
"invalidUsername" : "tg 7/10/2019 20:10",
"newWith:" : "mt 7/26/2019 15:19" },
"newWith:" : "NH 7/15/2020 10:14" },
"instance" : {
"=" : "NH 7/15/2020 10:31",
"accountName" : "tg 7/10/2019 20:20",
"accountName:" : "tg 7/10/2019 17:35",
"accountNameUnused" : "NH 7/15/2020 09:58",
"asDictionary" : "tg 7/18/2019 23:07",
"canConvert:" : "fr 7/26/2019 15:37",
"eraseStoredPassword" : "LW 7/31/2020 11:39",
"hasValidServerInfo" : "tg 7/15/2019 12:08",
"hasValidUserInfo" : "tg 7/15/2019 12:08",
"hash" : "LW 8/1/2020 12:04",
"host" : "tg 7/10/2019 20:06",
"host:" : "tg 7/10/2019 17:11",
"isValid" : "fr 7/26/2019 15:57",
"missingFields" : "JJ 6/12/2020 11:43",
"password" : "tg 7/15/2019 12:11",
"password:" : "tg 7/10/2019 17:18",
"passwordAsIMAPString" : "tg 7/10/2019 17:18",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"classvars" : [
],
"commentStamp" : "tg 7/15/2019 12:14",
"commentStamp" : "LW 8/1/2020 11:20",
"instvars" : [
"accountName",
"host",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
An ICAddressBook is a collection for the user's contacts containing email addresses of all accounts.
This is a singleton which can be accessed with #new.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
instance creation
new
Instance ifNil: [Instance := super new: 10].
^ Instance
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
action
addEmail: aString

self addIfNotPresent: aString

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
initialize
feedMeWithEntries: anEmailCollection

anEmailCollection do: [:emailAccount |
self
readRootFoldersMailsFrom: emailAccount;
readChildFoldersMailsFrom: emailAccount.]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
action
find: anEntry

| index |
index := self indexOf: anEntry.
^ self at: index
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
initialize
readChildFoldersMailsFrom: anEmailAccount

anEmailAccount rootFolder recursiveChildFolders do: [:childFolder |
childFolder emails do: [:childFolderEmail |
self addEmail: childFolderEmail senderAddressFromHeader]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
initialize
readRootFoldersMailsFrom: anEmailAccount

anEmailAccount rootFolder emails do: [:rootFolderEmail |
self addEmail: rootFolderEmail senderAddressFromHeader]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"class" : {
"new" : "hg 6/24/2020 12:34" },
"instance" : {
"addEmail:" : "LW 6/16/2020 09:51",
"feedMeWithEntries:" : "LW 6/16/2020 09:51",
"find:" : "LW 6/16/2020 09:51",
"readChildFoldersMailsFrom:" : "LW 6/16/2020 09:50",
"readRootFoldersMailsFrom:" : "LW 6/10/2020 13:32" } }
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"category" : "IMAPClient-Core",
"classinstvars" : [
],
"classvars" : [
"Instance" ],
"commentStamp" : "LW 8/1/2020 11:23",
"instvars" : [
],
"name" : "ICAddressBook",
"pools" : [
],
"super" : "OrderedCollection",
"type" : "normal" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
instance creation
newFromJsonStream: aStream

^ self basicNew
deserializeFrom: (Json readFrom: aStream);
initialize;
yourself
12 changes: 12 additions & 0 deletions packages/IMAPClient-Core.package/ICEmail.class/instance/^equals.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
comparing
= anObject
"Answer whether the receiver and anObject represent the same object."

self == anObject
ifTrue: [ ^ true ].
self class = anObject class
ifFalse: [ ^ false ].
^ self header = anObject header
and: [
self messageID = anObject messageID
and: [ self body = anObject body and: [ self folder = anObject folder and: [ self uniqueID = anObject uniqueID ] ] ] ]
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
print
converting
bodyAsString

^ self body asString
Expand Down
Loading

0 comments on commit 41b2f3d

Please sign in to comment.