├── .dockerignore ├── .github └── workflows │ └── gradle.yml ├── .gitignore ├── .gitlab-ci.yml ├── .tx └── config ├── Dockerfile ├── LICENSE ├── README.md ├── TODO.md ├── build.gradle ├── cli-lanterna ├── build.gradle └── src │ └── main │ └── groovy │ └── com │ └── muwire │ └── clilanterna │ ├── AddCommentView.groovy │ ├── BrowseModel.groovy │ ├── BrowseView.groovy │ ├── CertificateWrapper.groovy │ ├── ChatConsoleModel.groovy │ ├── ChatConsoleView.groovy │ ├── CliLanterna.groovy │ ├── CliSettings.groovy │ ├── DownloadDetailsView.groovy │ ├── DownloaderWrapper.groovy │ ├── DownloadsModel.groovy │ ├── DownloadsView.groovy │ ├── FilesModel.groovy │ ├── FilesView.groovy │ ├── MainWindowView.groovy │ ├── PersonaWrapper.groovy │ ├── ResultComparators.groovy │ ├── ResultsModel.groovy │ ├── ResultsView.groovy │ ├── SearchModel.groovy │ ├── SearchView.groovy │ ├── SharedFileWrapper.groovy │ ├── SortPrompt.groovy │ ├── SortType.java │ ├── TrustEntryWrapper.groovy │ ├── TrustListModel.groovy │ ├── TrustListView.groovy │ ├── TrustListWrapper.groovy │ ├── TrustModel.groovy │ ├── TrustView.groovy │ ├── UpdateTextView.groovy │ ├── UploadsModel.groovy │ ├── UploadsView.groovy │ ├── ViewCertificatesModel.groovy │ ├── ViewCertificatesView.groovy │ └── ViewCommentView.groovy ├── cli ├── build.gradle └── src │ └── main │ └── groovy │ └── com │ └── muwire │ └── cli │ ├── Cli.groovy │ ├── CliDownloader.groovy │ └── FileList.groovy ├── core ├── build.gradle └── src │ ├── main │ ├── groovy │ │ └── com │ │ │ └── muwire │ │ │ └── core │ │ │ ├── Core.groovy │ │ │ ├── Event.groovy │ │ │ ├── EventBus.groovy │ │ │ ├── MWModule.groovy │ │ │ ├── MuWireSettings.groovy │ │ │ ├── RestartEvent.groovy │ │ │ ├── RouterConnectedEvent.groovy │ │ │ ├── RouterDisconnectedEvent.groovy │ │ │ ├── Service.groovy │ │ │ ├── SplitPattern.groovy │ │ │ ├── UILoadedEvent.groovy │ │ │ ├── chat │ │ │ ├── ChatAction.java │ │ │ ├── ChatClient.groovy │ │ │ ├── ChatCommand.groovy │ │ │ ├── ChatConnection.groovy │ │ │ ├── ChatConnectionAttemptStatus.java │ │ │ ├── ChatConnectionEvent.groovy │ │ │ ├── ChatDisconnectionEvent.groovy │ │ │ ├── ChatLink.java │ │ │ ├── ChatManager.groovy │ │ │ ├── ChatMessageEvent.groovy │ │ │ ├── ChatServer.groovy │ │ │ ├── LocalChatLink.groovy │ │ │ ├── UIConnectChatEvent.groovy │ │ │ ├── UIDisconnectChatEvent.groovy │ │ │ └── UserDisconnectedEvent.groovy │ │ │ ├── collections │ │ │ ├── CollectionDownloadedEvent.groovy │ │ │ ├── CollectionFetchStatus.java │ │ │ ├── CollectionFetchStatusEvent.groovy │ │ │ ├── CollectionFetchedEvent.groovy │ │ │ ├── CollectionLoadedEvent.groovy │ │ │ ├── CollectionManager.groovy │ │ │ ├── CollectionUnsharedEvent.groovy │ │ │ ├── CollectionsClient.groovy │ │ │ ├── FileCollection.groovy │ │ │ ├── FileCollectionBuilder.groovy │ │ │ ├── FileCollectionItem.groovy │ │ │ ├── InvalidCollectionException.groovy │ │ │ ├── StringPathTree.groovy │ │ │ ├── UICollectionCreatedEvent.groovy │ │ │ ├── UICollectionDeletedEvent.groovy │ │ │ ├── UICollectionFetchEvent.groovy │ │ │ └── UIDownloadCollectionEvent.groovy │ │ │ ├── connection │ │ │ ├── Connection.groovy │ │ │ ├── ConnectionAcceptor.groovy │ │ │ ├── ConnectionEstablisher.groovy │ │ │ ├── ConnectionEvent.groovy │ │ │ ├── ConnectionManager.groovy │ │ │ ├── DisconnectionEvent.groovy │ │ │ ├── Endpoint.groovy │ │ │ ├── I2PAcceptor.groovy │ │ │ ├── I2PConnector.groovy │ │ │ ├── LeafConnection.groovy │ │ │ ├── LeafConnectionManager.groovy │ │ │ ├── MessageUtil.groovy │ │ │ ├── PeerConnection.groovy │ │ │ ├── UltrapeerConnection.groovy │ │ │ └── UltrapeerConnectionManager.groovy │ │ │ ├── content │ │ │ ├── ContentControlEvent.groovy │ │ │ ├── ContentManager.groovy │ │ │ ├── KeywordMatcher.groovy │ │ │ ├── Match.groovy │ │ │ ├── MatchAction.java │ │ │ ├── Matcher.groovy │ │ │ └── RegexMatcher.groovy │ │ │ ├── download │ │ │ ├── BadHashException.groovy │ │ │ ├── CopyingDownloader.groovy │ │ │ ├── DownloadHopelessEvent.groovy │ │ │ ├── DownloadManager.groovy │ │ │ ├── DownloadRejectedException.groovy │ │ │ ├── DownloadSession.groovy │ │ │ ├── DownloadStartedEvent.groovy │ │ │ ├── Downloader.groovy │ │ │ ├── HashListSession.groovy │ │ │ ├── HeadSession.groovy │ │ │ ├── NetworkDownloader.groovy │ │ │ ├── Pieces.groovy │ │ │ ├── SessionSupport.groovy │ │ │ ├── SourceDiscoveredEvent.groovy │ │ │ ├── SourceVerifiedEvent.groovy │ │ │ ├── UIDownloadCancelledEvent.groovy │ │ │ ├── UIDownloadEvent.groovy │ │ │ ├── UIDownloadLinkEvent.groovy │ │ │ ├── UIDownloadPausedEvent.groovy │ │ │ └── UIDownloadResumedEvent.groovy │ │ │ ├── filecert │ │ │ ├── Certificate.groovy │ │ │ ├── CertificateClient.groovy │ │ │ ├── CertificateCreatedEvent.groovy │ │ │ ├── CertificateFetchEvent.groovy │ │ │ ├── CertificateFetchStatus.java │ │ │ ├── CertificateFetchedEvent.groovy │ │ │ ├── CertificateManager.groovy │ │ │ ├── UICreateCertificateEvent.groovy │ │ │ ├── UIFetchCertificatesEvent.groovy │ │ │ └── UIImportCertificateEvent.groovy │ │ │ ├── filefeeds │ │ │ ├── FeedClient.groovy │ │ │ ├── FeedFetchEvent.groovy │ │ │ ├── FeedItemFetchedEvent.groovy │ │ │ ├── FeedItemLoadedEvent.groovy │ │ │ ├── FeedItems.groovy │ │ │ ├── FeedLoadedEvent.groovy │ │ │ ├── FeedManager.groovy │ │ │ ├── UIDownloadFeedItemEvent.groovy │ │ │ ├── UIFeedConfigurationEvent.groovy │ │ │ ├── UIFeedDeletedEvent.groovy │ │ │ ├── UIFeedUpdateEvent.groovy │ │ │ ├── UIFilePublishedEvent.groovy │ │ │ └── UIFileUnpublishedEvent.groovy │ │ │ ├── files │ │ │ ├── AllFilesLoadedEvent.groovy │ │ │ ├── BasePersisterService.groovy │ │ │ ├── DirectoryUnsharedEvent.groovy │ │ │ ├── DirectoryWatchedEvent.groovy │ │ │ ├── DirectoryWatcher.groovy │ │ │ ├── FileDownloadedEvent.groovy │ │ │ ├── FileHashedEvent.groovy │ │ │ ├── FileHasher.groovy │ │ │ ├── FileHashingEvent.groovy │ │ │ ├── FileListCallback.java │ │ │ ├── FileLoadedEvent.groovy │ │ │ ├── FileManager.groovy │ │ │ ├── FileModifiedEvent.groovy │ │ │ ├── FileSharedEvent.groovy │ │ │ ├── FileTree.groovy │ │ │ ├── FileTreeCallback.java │ │ │ ├── FileUnsharedEvent.groovy │ │ │ ├── HasherService.groovy │ │ │ ├── InfoHashEvent.groovy │ │ │ ├── NegativeFiles.groovy │ │ │ ├── PersisterDoneEvent.groovy │ │ │ ├── PersisterFolderService.groovy │ │ │ ├── PersisterService.groovy │ │ │ ├── SideCarFileEvent.groovy │ │ │ ├── UICommentEvent.groovy │ │ │ └── directories │ │ │ │ ├── UISyncDirectoryEvent.groovy │ │ │ │ ├── Visibility.java │ │ │ │ ├── WatchedDirectoriesLoadedEvent.groovy │ │ │ │ ├── WatchedDirectory.groovy │ │ │ │ ├── WatchedDirectoryConfigurationEvent.groovy │ │ │ │ ├── WatchedDirectoryConvertedEvent.groovy │ │ │ │ ├── WatchedDirectoryConverter.groovy │ │ │ │ ├── WatchedDirectoryManager.groovy │ │ │ │ └── WatchedDirectorySyncEvent.groovy │ │ │ ├── hostcache │ │ │ ├── CacheClient.groovy │ │ │ ├── CacheServers.groovy │ │ │ ├── DB2CSV.groovy │ │ │ ├── H2HostCache.groovy │ │ │ ├── Host.groovy │ │ │ ├── HostCache.groovy │ │ │ ├── HostDiscoveredEvent.groovy │ │ │ ├── HostMCProfile.groovy │ │ │ └── SimpleHostCache.groovy │ │ │ ├── mesh │ │ │ ├── Mesh.groovy │ │ │ └── MeshManager.groovy │ │ │ ├── messenger │ │ │ ├── InvalidMessageException.groovy │ │ │ ├── MWMessage.groovy │ │ │ ├── MWMessageAttachment.groovy │ │ │ ├── MessageFolderLoadingEvent.groovy │ │ │ ├── MessageLoadedEvent.groovy │ │ │ ├── MessageReceivedEvent.groovy │ │ │ ├── MessageSentEvent.groovy │ │ │ ├── Messenger.groovy │ │ │ ├── UIDownloadAttachmentEvent.groovy │ │ │ ├── UIFolderCreateEvent.groovy │ │ │ ├── UIFolderDeleteEvent.groovy │ │ │ ├── UIMessageDeleteEvent.groovy │ │ │ ├── UIMessageEvent.groovy │ │ │ ├── UIMessageMovedEvent.groovy │ │ │ └── UIMessageReadEvent.groovy │ │ │ ├── mulinks │ │ │ ├── CollectionMuLink.groovy │ │ │ ├── FileMuLink.groovy │ │ │ ├── InvalidMuLinkException.groovy │ │ │ └── MuLink.groovy │ │ │ ├── profile │ │ │ ├── MWProfileFetchEvent.groovy │ │ │ ├── MWProfileFetcher.groovy │ │ │ └── UIProfileFetchEvent.groovy │ │ │ ├── search │ │ │ ├── BrowseManager.groovy │ │ │ ├── BrowseSession.groovy │ │ │ ├── BrowseStatus.java │ │ │ ├── BrowseStatusEvent.groovy │ │ │ ├── DeleteEvent.groovy │ │ │ ├── InvalidSearchResultException.groovy │ │ │ ├── QueryEvent.groovy │ │ │ ├── ResponderCache.groovy │ │ │ ├── ResultsEvent.groovy │ │ │ ├── ResultsParser.groovy │ │ │ ├── ResultsSender.groovy │ │ │ ├── SearchEvent.groovy │ │ │ ├── SearchIndex.groovy │ │ │ ├── SearchManager.groovy │ │ │ ├── UIBrowseDirEvent.groovy │ │ │ ├── UIBrowseEvent.groovy │ │ │ ├── UIResultBatchEvent.groovy │ │ │ ├── UIResultEvent.groovy │ │ │ ├── UnexpectedResultsException.groovy │ │ │ └── UpsertEvent.groovy │ │ │ ├── tracker │ │ │ └── TrackerResponder.groovy │ │ │ ├── trust │ │ │ ├── RemoteTrustList.groovy │ │ │ ├── TrustEvent.groovy │ │ │ ├── TrustService.groovy │ │ │ ├── TrustServiceLoadedEvent.groovy │ │ │ ├── TrustSubscriber.groovy │ │ │ ├── TrustSubscriptionEvent.groovy │ │ │ └── TrustSubscriptionUpdatedEvent.groovy │ │ │ ├── update │ │ │ ├── AutoUpdater.java │ │ │ ├── UpdateAvailableEvent.groovy │ │ │ ├── UpdateClient.groovy │ │ │ ├── UpdateDownloadedEvent.groovy │ │ │ └── UpdateServers.groovy │ │ │ ├── upload │ │ │ ├── ContentRequest.groovy │ │ │ ├── ContentUploader.groovy │ │ │ ├── HashListRequest.groovy │ │ │ ├── HashListUploader.groovy │ │ │ ├── HeadRequest.groovy │ │ │ ├── HeadUploader.groovy │ │ │ ├── MeshUploader.groovy │ │ │ ├── Range.groovy │ │ │ ├── Request.groovy │ │ │ ├── UploadEvent.groovy │ │ │ ├── UploadFinishedEvent.groovy │ │ │ ├── UploadManager.groovy │ │ │ └── Uploader.groovy │ │ │ └── util │ │ │ ├── JULLog.groovy │ │ │ ├── MuWireLogManager.groovy │ │ │ └── PathTree.groovy │ ├── java │ │ ├── com │ │ │ └── muwire │ │ │ │ └── core │ │ │ │ ├── Constants.java │ │ │ │ ├── DownloadedFile.java │ │ │ │ ├── InfoHash.java │ │ │ │ ├── InvalidNicknameException.java │ │ │ │ ├── InvalidSignatureException.java │ │ │ │ ├── Name.java │ │ │ │ ├── Persona.java │ │ │ │ ├── SharedFile.java │ │ │ │ ├── connection │ │ │ │ └── ConnectionAttemptStatus.java │ │ │ │ ├── filefeeds │ │ │ │ ├── Feed.java │ │ │ │ ├── FeedFetchStatus.java │ │ │ │ ├── FeedItem.java │ │ │ │ └── InvalidFeedItemException.java │ │ │ │ ├── hostcache │ │ │ │ └── CrawlerResponse.java │ │ │ │ ├── profile │ │ │ │ ├── MWProfile.java │ │ │ │ ├── MWProfileFetchStatus.java │ │ │ │ ├── MWProfileHeader.java │ │ │ │ └── MWProfileImageFormat.java │ │ │ │ ├── search │ │ │ │ └── SearchIndexImpl.java │ │ │ │ ├── trust │ │ │ │ └── TrustLevel.java │ │ │ │ └── util │ │ │ │ ├── BandwidthCounter.java │ │ │ │ ├── DataUtil.java │ │ │ │ ├── FixedSizeFIFOSet.java │ │ │ │ ├── MessageThrottle.java │ │ │ │ ├── PathTreeCallback.java │ │ │ │ ├── PathTreeListCallback.java │ │ │ │ └── SenderThrottle.java │ │ └── net │ │ │ └── metanotionz │ │ │ ├── io │ │ │ ├── RAIFile.java │ │ │ ├── RandomAccessInterface.java │ │ │ ├── SerialStreams.java │ │ │ ├── Serializer.java │ │ │ ├── block │ │ │ │ ├── BlockFile.java │ │ │ │ ├── FreeListBlock.java │ │ │ │ └── index │ │ │ │ │ ├── BSkipLevels.java │ │ │ │ │ ├── BSkipList.java │ │ │ │ │ └── BSkipSpan.java │ │ │ └── data │ │ │ │ ├── IntBytes.java │ │ │ │ ├── LongBytes.java │ │ │ │ ├── NullBytes.java │ │ │ │ └── StringBytes.java │ │ │ └── util │ │ │ └── skiplist │ │ │ ├── SkipIterator.java │ │ │ ├── SkipLevels.java │ │ │ ├── SkipList.java │ │ │ └── SkipSpan.java │ └── resources │ │ └── defaults │ │ └── i2p.properties │ └── test │ └── groovy │ ├── com │ └── muwire │ │ └── core │ │ ├── Destinations.groovy │ │ ├── EventBusTest.groovy │ │ ├── InfoHashTest.groovy │ │ ├── Personas.groovy │ │ ├── SplitPatternTest.groovy │ │ ├── connection │ │ ├── ConnectionAcceptorTest.groovy │ │ └── ConnectionEstablisherTest.groovy │ │ ├── download │ │ ├── DownloadSessionTest.groovy │ │ └── PiecesTest.groovy │ │ ├── files │ │ ├── FileHasherTest.groovy │ │ ├── FileManagerTest.groovy │ │ ├── FileTreeTest.groovy │ │ ├── HasherServiceTest.groovy │ │ ├── PersisterServiceLoadingTest.groovy │ │ └── PersisterServiceSavingTest.groovy │ │ ├── hostcache │ │ └── HostCacheTest.groovy │ │ ├── search │ │ └── SearchIndexTest.groovy │ │ ├── trust │ │ └── TrustServiceTest.groovy │ │ ├── upload │ │ ├── RequestParsingTest.groovy │ │ └── UploaderTest.groovy │ │ └── util │ │ ├── DataUtilTest.groovy │ │ ├── FixedSizeFIFOSetTest.groovy │ │ ├── MessageThrottleTest.groovy │ │ ├── PathTreeTest.groovy │ │ └── SenderThrottleTest.groovy │ └── net │ └── metanotionz │ └── io │ └── RAIFileTest.groovy ├── doc ├── architecture.md ├── binary-pongs.md ├── chat.md ├── collections.md ├── crawler.md ├── design.md ├── download-mesh.md ├── gnutella-differences.md ├── infohash-upgrade.md ├── web-of-trust.md └── wire-protocol.md ├── docker └── rootfs │ ├── etc │ ├── cont-init.d │ │ └── 00-app-user-map.sh │ └── muwire │ │ └── MuWire.default.properties │ └── startapp.sh ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── gui ├── .lazybones │ ├── artifact-template-1.15.1.zip │ └── stored-params.properties ├── build.gradle ├── gradle │ ├── code-coverage.gradle │ ├── code-quality.gradle │ ├── docs.gradle │ ├── integration-test.gradle │ ├── package.gradle │ ├── publishing.gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── griffon-app │ ├── conf │ │ └── Config.groovy │ ├── controllers │ │ └── com │ │ │ └── muwire │ │ │ └── gui │ │ │ ├── AddCommentController.groovy │ │ │ ├── AddContactController.groovy │ │ │ ├── AdvancedSharingController.groovy │ │ │ ├── BrowseController.groovy │ │ │ ├── CertificateControlController.groovy │ │ │ ├── CertificateWarningController.groovy │ │ │ ├── ChatMonitorController.groovy │ │ │ ├── ChatRoomController.groovy │ │ │ ├── ChatServerController.groovy │ │ │ ├── CloseWarningController.groovy │ │ │ ├── CollectionTabController.groovy │ │ │ ├── CollectionWarningController.groovy │ │ │ ├── CollectionWizardController.groovy │ │ │ ├── CollectionsToolController.groovy │ │ │ ├── ContentPanelController.groovy │ │ │ ├── DownloadPreviewController.groovy │ │ │ ├── EventListController.groovy │ │ │ ├── FeedConfigurationController.groovy │ │ │ ├── FetchCertificatesController.groovy │ │ │ ├── I2PStatusController.groovy │ │ │ ├── LibrarySyncController.groovy │ │ │ ├── MainFrameController.groovy │ │ │ ├── MessageFolderController.groovy │ │ │ ├── MuWireStatusController.groovy │ │ │ ├── MyFeedController.groovy │ │ │ ├── NewMessageController.groovy │ │ │ ├── OptionsController.groovy │ │ │ ├── PublishPreviewController.groovy │ │ │ ├── SearchTabController.groovy │ │ │ ├── SharedFileController.groovy │ │ │ ├── ShowCommentController.groovy │ │ │ ├── ShutdownWindowController.groovy │ │ │ ├── SignController.groovy │ │ │ ├── SystemStatusController.groovy │ │ │ ├── TrustListController.groovy │ │ │ ├── UpdateController.groovy │ │ │ ├── WatchedDirectoryController.groovy │ │ │ ├── chat │ │ │ └── ChatFavoritesController.groovy │ │ │ ├── contacts │ │ │ └── ContactSelectorController.groovy │ │ │ ├── profile │ │ │ ├── EditProfileController.groovy │ │ │ └── ViewProfileController.groovy │ │ │ ├── resultdetails │ │ │ ├── CertificateListController.groovy │ │ │ ├── CertificateTabController.groovy │ │ │ ├── CollectionListController.groovy │ │ │ ├── MiniCollectionTabController.groovy │ │ │ ├── ResultDetailsFrameController.groovy │ │ │ └── ResultDetailsTabsController.groovy │ │ │ ├── tools │ │ │ └── RuleWizardController.groovy │ │ │ └── wizard │ │ │ └── WizardController.groovy │ ├── i18n │ │ ├── messages.properties │ │ ├── messages_cs.properties │ │ ├── messages_de.properties │ │ ├── messages_fr.properties │ │ ├── messages_ja.properties │ │ ├── messages_sq.properties │ │ └── messages_tr.properties │ ├── lifecycle │ │ ├── Initialize.groovy │ │ ├── Ready.groovy │ │ └── Shutdown.groovy │ ├── models │ │ └── com │ │ │ └── muwire │ │ │ └── gui │ │ │ ├── AddCommentModel.groovy │ │ │ ├── AddContactModel.groovy │ │ │ ├── AdvancedSharingModel.groovy │ │ │ ├── BrowseModel.groovy │ │ │ ├── CertificateControlModel.groovy │ │ │ ├── CertificateWarningModel.groovy │ │ │ ├── ChatMonitorModel.groovy │ │ │ ├── ChatRoomModel.groovy │ │ │ ├── ChatServerModel.groovy │ │ │ ├── CloseWarningModel.groovy │ │ │ ├── CollectionTabModel.groovy │ │ │ ├── CollectionWarningModel.groovy │ │ │ ├── CollectionWizardModel.groovy │ │ │ ├── CollectionsToolModel.groovy │ │ │ ├── ContentPanelModel.groovy │ │ │ ├── DownloadPreviewModel.groovy │ │ │ ├── EventListModel.groovy │ │ │ ├── FeedConfigurationModel.groovy │ │ │ ├── FetchCertificatesModel.groovy │ │ │ ├── I2PStatusModel.groovy │ │ │ ├── LibrarySyncModel.groovy │ │ │ ├── MainFrameModel.groovy │ │ │ ├── MessageFolderModel.groovy │ │ │ ├── MuWireStatusModel.groovy │ │ │ ├── MyFeedModel.groovy │ │ │ ├── NewMessageModel.groovy │ │ │ ├── OptionsModel.groovy │ │ │ ├── PublishPreviewModel.groovy │ │ │ ├── SearchTabModel.groovy │ │ │ ├── SharedFileModel.groovy │ │ │ ├── ShowCommentModel.groovy │ │ │ ├── ShutdownWindowModel.groovy │ │ │ ├── SignModel.groovy │ │ │ ├── SystemStatusModel.groovy │ │ │ ├── TrustListModel.groovy │ │ │ ├── UpdateModel.groovy │ │ │ ├── WatchedDirectoryModel.groovy │ │ │ ├── chat │ │ │ └── ChatFavoritesModel.groovy │ │ │ ├── contacts │ │ │ └── ContactSelectorModel.groovy │ │ │ ├── profile │ │ │ ├── EditProfileModel.groovy │ │ │ └── ViewProfileModel.groovy │ │ │ ├── resultdetails │ │ │ ├── CertificateListModel.groovy │ │ │ ├── CertificateTabModel.groovy │ │ │ ├── CollectionListModel.groovy │ │ │ ├── MiniCollectionTabModel.groovy │ │ │ ├── ResultDetailsFrameModel.groovy │ │ │ └── ResultDetailsTabsModel.groovy │ │ │ ├── tools │ │ │ └── RuleWizardModel.groovy │ │ │ └── wizard │ │ │ └── WizardModel.groovy │ ├── resources │ │ ├── MuWire-128x128.png │ │ ├── MuWire-16x16.png │ │ ├── MuWire-32x32.png │ │ ├── MuWire-48x48.png │ │ ├── MuWire-64x64.png │ │ ├── application.properties │ │ ├── close_tab.png │ │ ├── comment.png │ │ ├── connections.png │ │ ├── copy.png │ │ ├── distrusted.png │ │ ├── down_arrow.png │ │ ├── edit_profile.png │ │ ├── email.png │ │ ├── griffon.png │ │ ├── i2plogo.png │ │ ├── neutral.png │ │ ├── outbox.png │ │ ├── resources.properties │ │ ├── restart.png │ │ ├── search.png │ │ ├── trusted.png │ │ ├── up_arrow.png │ │ ├── update.png │ │ └── yes.png │ └── views │ │ └── com │ │ └── muwire │ │ └── gui │ │ ├── AddCommentView.groovy │ │ ├── AddContactView.groovy │ │ ├── AdvancedSharingView.groovy │ │ ├── BrowseView.groovy │ │ ├── CertificateControlView.groovy │ │ ├── CertificateWarningView.groovy │ │ ├── ChatMonitorView.groovy │ │ ├── ChatRoomView.groovy │ │ ├── ChatServerView.groovy │ │ ├── CloseWarningView.groovy │ │ ├── CollectionTabView.groovy │ │ ├── CollectionWarningView.groovy │ │ ├── CollectionWizardView.groovy │ │ ├── CollectionsToolView.groovy │ │ ├── ContentPanelView.groovy │ │ ├── DownloadPreviewView.groovy │ │ ├── EventListView.groovy │ │ ├── FeedConfigurationView.groovy │ │ ├── FetchCertificatesView.groovy │ │ ├── I2PStatusView.groovy │ │ ├── LibrarySyncView.groovy │ │ ├── MainFrameView.groovy │ │ ├── MessageFolderView.groovy │ │ ├── MuWireStatusView.groovy │ │ ├── MyFeedView.groovy │ │ ├── NewMessageView.groovy │ │ ├── OptionsView.groovy │ │ ├── PublishPreviewView.groovy │ │ ├── SearchTabView.groovy │ │ ├── SharedFileView.groovy │ │ ├── ShowCommentView.groovy │ │ ├── ShutdownWindowView.groovy │ │ ├── SignView.groovy │ │ ├── SystemStatusView.groovy │ │ ├── TrustListView.groovy │ │ ├── UpdateView.groovy │ │ ├── WatchedDirectoryView.groovy │ │ ├── chat │ │ └── ChatFavoritesView.groovy │ │ ├── contacts │ │ └── ContactSelectorView.groovy │ │ ├── profile │ │ ├── EditProfileView.groovy │ │ └── ViewProfileView.groovy │ │ ├── resultdetails │ │ ├── CertificateListView.groovy │ │ ├── CertificateTabView.groovy │ │ ├── CollectionListView.groovy │ │ ├── MiniCollectionTabView.groovy │ │ ├── ResultDetailsFrameView.groovy │ │ └── ResultDetailsTabsView.groovy │ │ ├── tools │ │ └── RuleWizardView.groovy │ │ └── wizard │ │ └── WizardView.groovy ├── shadow │ └── services │ │ └── griffon.core.injection.Module └── src │ ├── integration-test │ └── groovy │ │ └── com │ │ └── muwire │ │ └── gui │ │ ├── ContentPanelIntegrationTest.groovy │ │ ├── EventListIntegrationTest.groovy │ │ ├── I2PStatusIntegrationTest.groovy │ │ ├── MainFrameIntegrationTest.groovy │ │ ├── MuWireStatusIntegrationTest.groovy │ │ ├── OptionsIntegrationTest.groovy │ │ ├── SearchTabIntegrationTest.groovy │ │ └── TrustListIntegrationTest.groovy │ ├── main │ ├── groovy │ │ └── com │ │ │ └── muwire │ │ │ └── gui │ │ │ ├── ChatNotificator.groovy │ │ │ ├── DateRenderer.groovy │ │ │ ├── DownloadPreviewer.groovy │ │ │ ├── DownloadProgressRenderer.groovy │ │ │ ├── DownloadStateRenderer.groovy │ │ │ ├── DownloaderComparator.groovy │ │ │ ├── InterimTreeNode.groovy │ │ │ ├── LNFs.groovy │ │ │ ├── Launcher.groovy │ │ │ ├── LibraryTreeModel.groovy │ │ │ ├── MWErrorDisplayer.groovy │ │ │ ├── MWMessageStatus.groovy │ │ │ ├── MWMessageTransferable.groovy │ │ │ ├── MWTransferable.groovy │ │ │ ├── MessageNotificator.groovy │ │ │ ├── NotifyService.groovy │ │ │ ├── PathTreeRenderer.groovy │ │ │ ├── PersonaCellRenderer.groovy │ │ │ ├── PersonaComparator.groovy │ │ │ ├── ResultAndTargets.groovy │ │ │ ├── ResultNameTableCellRenderer.groovy │ │ │ ├── ResultTree.groovy │ │ │ ├── ResultTreeModel.groovy │ │ │ ├── ResultTreeRenderer.groovy │ │ │ ├── SearchField.groovy │ │ │ ├── SearchFieldEditor.groovy │ │ │ ├── SearchFieldModel.groovy │ │ │ ├── SharedFileNameComparator.groovy │ │ │ ├── SharedFileNameRenderer.groovy │ │ │ ├── SharedTreeRenderer.groovy │ │ │ ├── SizeFormatter.groovy │ │ │ ├── SizeRenderer.groovy │ │ │ ├── SortedTreeNode.groovy │ │ │ ├── TableUtil.groovy │ │ │ ├── TreeExpansions.groovy │ │ │ ├── TreeUtil.groovy │ │ │ ├── TrustCellRenderer.groovy │ │ │ ├── UIResultEventComparator.groovy │ │ │ ├── UISettings.groovy │ │ │ ├── chat │ │ │ ├── ChatEntry.groovy │ │ │ ├── ChatEntryPane.groovy │ │ │ ├── ChatFavorite.groovy │ │ │ ├── ChatFavorites.groovy │ │ │ ├── CollectionLinkLabel.groovy │ │ │ ├── FileLinkLabel.groovy │ │ │ ├── MuLinkLabel.groovy │ │ │ └── MuLinkPanel.groovy │ │ │ ├── contacts │ │ │ ├── ContactChooser.groovy │ │ │ ├── ContactChooserEditor.groovy │ │ │ ├── ContactChooserModel.groovy │ │ │ ├── ContactChooserPOP.groovy │ │ │ ├── ContactChooserTextPane.groovy │ │ │ ├── POPLabel.groovy │ │ │ └── PersonaOrProfileListCellRenderer.groovy │ │ │ ├── linux │ │ │ └── DBUSNotifyService.groovy │ │ │ ├── profile │ │ │ ├── AbstractPOP.groovy │ │ │ ├── PersonaOrProfileCellRenderer.groovy │ │ │ ├── PersonaOrProfileComparator.groovy │ │ │ ├── PersonaPOP.groovy │ │ │ ├── ProfileHeaderPOP.groovy │ │ │ ├── ResultPOP.groovy │ │ │ ├── TrustPOP.groovy │ │ │ └── ViewProfileHelper.groovy │ │ │ ├── resultdetails │ │ │ └── ResultListCellRenderer.groovy │ │ │ ├── win │ │ │ └── PrioritySetter.groovy │ │ │ └── wizard │ │ │ ├── DirectoriesStep.groovy │ │ │ ├── EmbeddedRouterStep.groovy │ │ │ ├── ExternalRouterStep.groovy │ │ │ ├── LastStep.groovy │ │ │ ├── NicknameStep.groovy │ │ │ ├── TunnelStep.groovy │ │ │ ├── WizardDefaults.groovy │ │ │ └── WizardStep.groovy │ └── java │ │ ├── com │ │ └── muwire │ │ │ └── gui │ │ │ ├── CopyPasteSupport.java │ │ │ ├── HTMLSanitizer.java │ │ │ ├── RightClickSupport.java │ │ │ ├── SmartScroller.java │ │ │ ├── Translator.java │ │ │ ├── profile │ │ │ ├── IdenticonGenerator.java │ │ │ ├── ImagePanel.java │ │ │ ├── ImageScaler.java │ │ │ ├── PersonaOrProfile.java │ │ │ ├── ProfileConstants.java │ │ │ └── ThumbnailIcon.java │ │ │ └── win │ │ │ └── MWKernel32.java │ │ └── org │ │ └── freedesktop │ │ ├── GetServerInformationTuple.java │ │ └── Notifications.java │ └── test │ └── java │ └── com │ └── muwire │ └── gui │ └── HTMLSanitizerTest.java ├── host-cache ├── build.gradle ├── logging │ └── logging.properties ├── scripts │ └── count_total.py └── src │ ├── main │ └── groovy │ │ └── com │ │ └── muwire │ │ └── hostcache │ │ ├── Crawler.groovy │ │ ├── Host.groovy │ │ ├── HostCache.groovy │ │ ├── HostPool.groovy │ │ └── Pinger.groovy │ └── test │ └── groovy │ └── com │ └── muwire │ └── hostcache │ ├── CrawlerTest.groovy │ ├── Destinations.groovy │ └── HostPoolTest.groovy ├── images └── i2cp_config.png ├── logging ├── 0_logging.properties ├── 1_logging.properties ├── 2_logging.properties ├── 3_logging.properties └── 4_logging.properties ├── mwmodules ├── build.gradle └── src │ └── main │ └── groovy │ └── QueryLogger.groovy ├── pinger ├── build.gradle └── src │ └── main │ └── groovy │ └── com │ └── muwire │ └── pinger │ └── Pinger.groovy ├── settings.gradle ├── tracker ├── build.gradle └── src │ └── main │ └── groovy │ └── com │ └── muwire │ └── tracker │ ├── Host.groovy │ ├── Pinger.groovy │ ├── SetupWizard.groovy │ ├── Swarm.groovy │ ├── SwarmManager.groovy │ ├── TrackRequest.java │ ├── Tracker.groovy │ ├── TrackerProperties.groovy │ ├── TrackerService.java │ ├── TrackerServiceImpl.groovy │ ├── TrackerStatus.groovy │ └── WebServerConfiguration.groovy └── update-server ├── build.gradle └── src └── main └── groovy └── com └── muwire └── update └── UpdateServer.groovy /.dockerignore: -------------------------------------------------------------------------------- 1 | # Dot directories 2 | .gradle/ 3 | .idea/ 4 | .git/ 5 | 6 | # Build directories 7 | build/ 8 | **/build/ 9 | 10 | # We execute COPY . . 11 | # Modifying these files would unnecessarily invalidate the build context 12 | Dockerfile 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | **/bin 3 | **/.settings 4 | **/build 5 | .gradle 6 | **/.project 7 | **/.classpath 8 | **/*.rej 9 | **/*.orig 10 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = he: iw, id: in, ru_RU: ru, sv_SE: sv, tr_TR: tr, uk_UA: uk, yi: ji, zh_CN: zh 4 | 5 | [muwire.muwire-plugin] 6 | file_filter = webui/locale/messages_.po 7 | source_file = webui/locale/messages_en.po 8 | source_lang = en 9 | minimum_perc = 10 10 | 11 | [muwire.MWGUI] 12 | type = UNICODEPROPERTIES 13 | file_filter = gui/griffon-app/i18n/messages_.properties 14 | source_file = gui/griffon-app/i18n/messages.properties 15 | source_lang = en 16 | minimum_perc = 10 17 | -------------------------------------------------------------------------------- /cli-lanterna/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | repositories { 4 | jcenter() 5 | mavenLocal() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0' 10 | } 11 | } 12 | 13 | apply plugin : 'application' 14 | application { 15 | mainClassName = 'com.muwire.clilanterna.CliLanterna' 16 | applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties','-Xmx256M'] 17 | applicationName = 'MuWire-cli' 18 | } 19 | 20 | apply plugin : 'com.github.johnrengelman.shadow' 21 | 22 | 23 | dependencies { 24 | implementation project(":core") 25 | implementation 'com.googlecode.lanterna:lanterna:3.0.1' 26 | } 27 | 28 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/CertificateWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.filecert.Certificate 4 | 5 | class CertificateWrapper { 6 | private final Certificate certificate 7 | CertificateWrapper(Certificate certificate) { 8 | this.certificate = certificate 9 | } 10 | 11 | public String toString() { 12 | certificate.issuer.getHumanReadableName() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/CliSettings.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | class CliSettings { 4 | 5 | boolean clearCancelledDownloads 6 | boolean clearFinishedDownloads 7 | boolean clearUploads 8 | 9 | CliSettings(Properties props) { 10 | clearCancelledDownloads = Boolean.parseBoolean(props.getProperty("clearCancelledDownloads","true")) 11 | clearFinishedDownloads = Boolean.parseBoolean(props.getProperty("clearFinishedDownloads", "false")) 12 | clearUploads = Boolean.parseBoolean(props.getProperty("clearUploads", "false")) 13 | } 14 | 15 | void write(OutputStream os) { 16 | Properties props = new Properties() 17 | props.with { 18 | setProperty("clearCancelledDownloads", String.valueOf(clearCancelledDownloads)) 19 | setProperty("clearFinishedDownloads", String.valueOf(clearFinishedDownloads)) 20 | setProperty("clearUploads", String.valueOf(clearUploads)) 21 | 22 | store(os, "CLI Properties") 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/DownloaderWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.download.Downloader 4 | 5 | class DownloaderWrapper { 6 | final Downloader downloader 7 | DownloaderWrapper(Downloader downloader) { 8 | this.downloader = downloader 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | downloader.file.getName() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/PersonaWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.Persona 4 | 5 | class PersonaWrapper { 6 | private final Persona persona 7 | PersonaWrapper(Persona persona) { 8 | this.persona = persona 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | persona.getHumanReadableName() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/ResultComparators.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.search.UIResultEvent 4 | 5 | class ResultComparators { 6 | public static final Comparator NAME_ASC = new Comparator() { 7 | public int compare(UIResultEvent a, UIResultEvent b) { 8 | a.name.compareTo(b.name) 9 | } 10 | } 11 | 12 | public static final Comparator NAME_DESC = NAME_ASC.reversed() 13 | 14 | public static final Comparator SIZE_ASC = new Comparator() { 15 | public int compare(UIResultEvent a, UIResultEvent b) { 16 | Long.compare(a.size, b.size) 17 | } 18 | } 19 | 20 | public static final Comparator SIZE_DESC = SIZE_ASC.reversed() 21 | } 22 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/SharedFileWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.SharedFile 4 | 5 | class SharedFileWrapper { 6 | private final SharedFile sharedFile 7 | 8 | SharedFileWrapper(SharedFile sharedFile) { 9 | this.sharedFile = sharedFile 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | sharedFile.getCachedPath() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/SortType.java: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna; 2 | 3 | public enum SortType { 4 | NAME_ASC,NAME_DESC,SIZE_ASC,SIZE_DESC 5 | } 6 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/TrustEntryWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.trust.TrustService 4 | 5 | class TrustEntryWrapper { 6 | TrustService.TrustEntry entry 7 | } 8 | -------------------------------------------------------------------------------- /cli-lanterna/src/main/groovy/com/muwire/clilanterna/TrustListWrapper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.clilanterna 2 | 3 | import com.muwire.core.trust.RemoteTrustList 4 | 5 | class TrustListWrapper { 6 | private final RemoteTrustList trustList 7 | TrustListWrapper(RemoteTrustList trustList) { 8 | this.trustList = trustList 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | trustList.persona.getHumanReadableName() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cli/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | repositories { 4 | jcenter() 5 | mavenLocal() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0' 10 | } 11 | } 12 | 13 | apply plugin : 'application' 14 | mainClassName = 'com.muwire.cli.Cli' 15 | apply plugin : 'com.github.johnrengelman.shadow' 16 | 17 | applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties'] 18 | 19 | dependencies { 20 | implementation project(":core") 21 | } 22 | 23 | -------------------------------------------------------------------------------- /cli/src/main/groovy/com/muwire/cli/FileList.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.cli 2 | 3 | import com.muwire.core.util.DataUtil 4 | 5 | import groovy.json.JsonSlurper 6 | import net.i2p.data.Base64 7 | 8 | class FileList { 9 | public static void main(String [] args) { 10 | if (args.length < 1) { 11 | println "pass files.json as argument" 12 | System.exit(1) 13 | } 14 | 15 | def slurper = new JsonSlurper() 16 | File filesJson = new File(args[0]) 17 | filesJson.eachLine { 18 | def json = slurper.parseText(it) 19 | String name = DataUtil.readi18nString(Base64.decode(json.file)) 20 | println "$name,$json.length,$json.pieceSize,$json.infoHash" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/Event.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import java.util.concurrent.atomic.AtomicLong 4 | 5 | class Event { 6 | 7 | private static final AtomicLong SEQ_NO = new AtomicLong(); 8 | final long seqNo 9 | final long timestamp 10 | boolean vetoed 11 | 12 | Event() { 13 | seqNo = SEQ_NO.getAndIncrement() 14 | timestamp = System.currentTimeMillis() 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | "seqNo $seqNo timestamp $timestamp" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/MWModule.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | interface MWModule { 4 | public String getName() 5 | public void init(Core core) 6 | public void start() 7 | public void stop() 8 | } 9 | 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/RestartEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | /** triggers a restart of MuWire */ 4 | class RestartEvent extends Event{ 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/RouterConnectedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import net.i2p.client.I2PSession 4 | import net.i2p.client.streaming.I2PSocketManager 5 | 6 | class RouterConnectedEvent extends Event { 7 | I2PSession session 8 | I2PSocketManager socketManager 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/RouterDisconnectedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | class RouterDisconnectedEvent extends Event { 4 | } 5 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/Service.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | abstract class Service { 4 | 5 | volatile boolean loaded 6 | 7 | abstract void load() 8 | 9 | void waitForLoad() { 10 | while (!loaded) 11 | Thread.sleep(10) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/UILoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | class UILoadedEvent extends Event { 4 | } 5 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatAction.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat; 2 | 3 | public enum ChatAction { 4 | JOIN(true, false, true, false), 5 | LEAVE(false, false, true, false), 6 | SAY(false, false, true, false), 7 | LIST(true, true, true, false), 8 | HELP(true, true, true, false), 9 | INFO(true, true, true, false), 10 | JOINED(true, true, false, false), 11 | PROFILE(true, false, false, false), 12 | TRUST(true, false, true, true), 13 | DISTRUST(true, false, true, true); 14 | 15 | final boolean console; 16 | final boolean stateless; 17 | final boolean user; 18 | final boolean local; 19 | ChatAction(boolean console, boolean stateless, boolean user, boolean local) { 20 | this.console = console; 21 | this.stateless = stateless; 22 | this.user = user; 23 | this.local = local; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatCommand.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | class ChatCommand { 4 | final ChatAction action 5 | final String payload 6 | final String source 7 | ChatCommand(String source) { 8 | if (source.charAt(0) != '/') 9 | throw new Exception("command doesn't start with / $source") 10 | 11 | int position = 1 12 | StringBuilder sb = new StringBuilder() 13 | while(position < source.length()) { 14 | char c = source.charAt(position) 15 | if (c == ' ') 16 | break 17 | sb.append(c) 18 | position++ 19 | } 20 | String command = sb.toString().toUpperCase() 21 | action = ChatAction.valueOf(command) 22 | if (position < source.length()) 23 | payload = source.substring(position + 1) 24 | else 25 | payload = "" 26 | this.source = source 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatConnectionAttemptStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat; 2 | 3 | public enum ChatConnectionAttemptStatus { 4 | CONNECTING, SUCCESSFUL, REJECTED, FAILED, DISCONNECTED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatConnectionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class ChatConnectionEvent extends Event { 7 | ChatConnectionAttemptStatus status 8 | Persona persona 9 | ChatLink connection 10 | String defaultRoom 11 | 12 | public String toString() { 13 | super.toString() + " " + persona.getHumanReadableName() + " " + status.toString() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatDisconnectionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class ChatDisconnectionEvent extends Event { 7 | Persona persona 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatLink.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat; 2 | 3 | import java.io.Closeable; 4 | 5 | import com.muwire.core.Persona; 6 | import com.muwire.core.profile.MWProfileHeader; 7 | 8 | public interface ChatLink extends Closeable { 9 | public Persona getPersona(); 10 | public MWProfileHeader getProfileHeader(); 11 | public boolean isUp(); 12 | public void sendChat(ChatMessageEvent e); 13 | public void sendLeave(Persona p); 14 | public void sendPing(); 15 | public Object nextEvent() throws InterruptedException; 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/ChatMessageEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class ChatMessageEvent extends Event { 7 | UUID uuid 8 | String payload 9 | Persona sender, host 10 | ChatLink link 11 | String room 12 | long chatTime 13 | byte [] sig 14 | } 15 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/LocalChatLink.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.profile.MWProfileHeader 4 | 5 | import java.util.concurrent.BlockingQueue 6 | import java.util.concurrent.LinkedBlockingQueue 7 | 8 | import com.muwire.core.Persona 9 | 10 | import groovy.util.logging.Log 11 | 12 | @Log 13 | class LocalChatLink implements ChatLink { 14 | 15 | public static final LocalChatLink INSTANCE = new LocalChatLink() 16 | 17 | private final BlockingQueue messages = new LinkedBlockingQueue() 18 | 19 | private LocalChatLink() {} 20 | 21 | @Override 22 | public void close() throws IOException { 23 | } 24 | 25 | @Override 26 | public void sendChat(ChatMessageEvent e) { 27 | messages.put(e) 28 | } 29 | 30 | @Override 31 | public void sendLeave(Persona p) { 32 | messages.put(p) 33 | } 34 | 35 | @Override 36 | public void sendPing() {} 37 | 38 | @Override 39 | public Object nextEvent() { 40 | messages.take() 41 | } 42 | 43 | @Override 44 | public boolean isUp() { 45 | true 46 | } 47 | 48 | public Persona getPersona() { 49 | null 50 | } 51 | 52 | public MWProfileHeader getProfileHeader() { 53 | null 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/UIConnectChatEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIConnectChatEvent extends Event { 7 | Persona host 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/UIDisconnectChatEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIDisconnectChatEvent extends Event { 7 | Persona host 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/chat/UserDisconnectedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.chat 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UserDisconnectedEvent extends Event { 7 | Persona user 8 | Persona host 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionDownloadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class CollectionDownloadedEvent extends Event { 6 | FileCollection collection 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionFetchStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections; 2 | 3 | public enum CollectionFetchStatus { 4 | CONNECTING, FETCHING, FINISHED, FAILED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionFetchStatusEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class CollectionFetchStatusEvent extends Event { 6 | CollectionFetchStatus status 7 | int count 8 | UUID uuid 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionFetchedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | 6 | class CollectionFetchedEvent extends Event { 7 | FileCollection collection 8 | UUID uuid 9 | InfoHash infoHash 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class CollectionLoadedEvent extends Event { 6 | FileCollection collection 7 | boolean local 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/CollectionUnsharedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class CollectionUnsharedEvent extends Event { 6 | FileCollection collection 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/InvalidCollectionException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | class InvalidCollectionException extends Exception { 4 | 5 | public InvalidCollectionException() { 6 | super(); 7 | } 8 | 9 | public InvalidCollectionException(String message, Throwable cause, boolean enableSuppression, 10 | boolean writableStackTrace) { 11 | super(message, cause, enableSuppression, writableStackTrace); 12 | } 13 | 14 | public InvalidCollectionException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public InvalidCollectionException(String message) { 19 | super(message); 20 | } 21 | 22 | public InvalidCollectionException(Throwable cause) { 23 | super(cause); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/UICollectionCreatedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class UICollectionCreatedEvent extends Event { 6 | FileCollection collection 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/UICollectionDeletedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | 5 | class UICollectionDeletedEvent extends Event { 6 | FileCollection collection 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/UICollectionFetchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class UICollectionFetchEvent extends Event { 8 | UUID uuid 9 | Persona host 10 | Set infoHashes 11 | boolean everything 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/collections/UIDownloadCollectionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.collections 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class UIDownloadCollectionEvent extends Event { 8 | 9 | FileCollection collection 10 | InfoHash infoHash 11 | Set items 12 | Persona host 13 | boolean sequential 14 | boolean full 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/connection/ConnectionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection 2 | 3 | import com.muwire.core.Event 4 | 5 | import net.i2p.data.Destination 6 | 7 | class ConnectionEvent extends Event { 8 | 9 | Endpoint endpoint 10 | boolean incoming 11 | Boolean leaf // can be null if uknown 12 | ConnectionAttemptStatus status 13 | 14 | @Override 15 | public String toString() { 16 | "ConnectionEvent ${super.toString()} endpoint: $endpoint incoming: $incoming leaf : $leaf status : $status" 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/connection/DisconnectionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection 2 | 3 | import com.muwire.core.Event 4 | 5 | import net.i2p.data.Destination 6 | 7 | class DisconnectionEvent extends Event { 8 | 9 | Destination destination 10 | 11 | @Override 12 | public String toString() { 13 | "DisconnectionEvent ${super.toString()} destination:${destination.toBase32()}" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/connection/Endpoint.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection 2 | 3 | import java.util.concurrent.atomic.AtomicBoolean 4 | import java.util.logging.Level 5 | 6 | import groovy.util.logging.Log 7 | import net.i2p.data.Destination 8 | 9 | @Log 10 | class Endpoint implements Closeable { 11 | final Destination destination 12 | final InputStream inputStream 13 | final OutputStream outputStream 14 | final def toClose 15 | 16 | private final AtomicBoolean closed = new AtomicBoolean() 17 | 18 | Endpoint(Destination destination, InputStream inputStream, OutputStream outputStream, def toClose) { 19 | this.destination = destination 20 | this.inputStream = inputStream 21 | this.outputStream = outputStream 22 | this.toClose = toClose 23 | } 24 | 25 | @Override 26 | public void close() { 27 | if (!closed.compareAndSet(false, true)) { 28 | log.log(Level.WARNING,"Close loop detected for ${destination.toBase32()}", new Exception()) 29 | return 30 | } 31 | if (inputStream != null) { 32 | try {inputStream.close()} catch (Exception ignore) {} 33 | } 34 | if (toClose != null) { 35 | try {toClose.reset()} catch (Exception ignore) {} 36 | } 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | "destination: ${destination.toBase32()}" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/connection/LeafConnection.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection 2 | 3 | import java.io.InputStream 4 | import java.io.OutputStream 5 | 6 | import com.muwire.core.EventBus 7 | import com.muwire.core.MuWireSettings 8 | import com.muwire.core.hostcache.HostCache 9 | import com.muwire.core.trust.TrustService 10 | 11 | import net.i2p.data.Destination 12 | 13 | /** 14 | * Connection where the other side is a leaf. 15 | * Such connections can only be incoming. 16 | * @author zab 17 | */ 18 | class LeafConnection extends Connection { 19 | 20 | public LeafConnection(EventBus eventBus, Endpoint endpoint, HostCache hostCache, 21 | TrustService trustService, MuWireSettings settings) { 22 | super(eventBus, endpoint, true, hostCache, trustService, settings); 23 | } 24 | 25 | @Override 26 | protected void read() { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | @Override 32 | protected void write(Object message) { 33 | // TODO Auto-generated method stub 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/connection/UltrapeerConnection.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection 2 | 3 | import java.io.InputStream 4 | import java.io.OutputStream 5 | 6 | import com.muwire.core.EventBus 7 | import com.muwire.core.hostcache.HostCache 8 | import com.muwire.core.trust.TrustService 9 | 10 | import net.i2p.data.Destination 11 | 12 | /** 13 | * Connection where this side is a leaf and the 14 | * other side an ultrapeer. Such connections can only 15 | * be outgoing 16 | * @author zab 17 | */ 18 | class UltrapeerConnection extends Connection { 19 | 20 | public UltrapeerConnection(EventBus eventBus, Endpoint endpoint, HostCache hostCache, TrustService trustService) { 21 | super(eventBus, endpoint, false, hostCache, trustService) 22 | } 23 | 24 | @Override 25 | protected void read() { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | @Override 31 | protected void write(Object message) { 32 | if (message instanceof Map) { 33 | writeJsonMessage(message) 34 | } else { 35 | writeBinaryMessage(message) 36 | } 37 | } 38 | 39 | private void writeJsonMessage(def message) { 40 | 41 | } 42 | 43 | private void writeBinaryMessage(def message) { 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/ContentControlEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content 2 | 3 | import com.muwire.core.Event 4 | 5 | class ContentControlEvent extends Event { 6 | String term 7 | boolean regex 8 | MatchAction action 9 | String name 10 | boolean add 11 | Matcher matcher 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/KeywordMatcher.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content 2 | 3 | class KeywordMatcher extends Matcher { 4 | private final String keyword 5 | KeywordMatcher(String keyword, MatchAction action, String name) { 6 | super(action, name) 7 | this.keyword = keyword 8 | } 9 | 10 | @Override 11 | protected boolean match(List searchTerms) { 12 | boolean found = false 13 | searchTerms.each { 14 | if (keyword == it) 15 | found = true 16 | } 17 | found 18 | } 19 | 20 | @Override 21 | public String getTerm() { 22 | keyword 23 | } 24 | 25 | @Override 26 | public int hashCode() { 27 | keyword.hashCode() 28 | } 29 | 30 | @Override 31 | public boolean equals(Object o) { 32 | if (!(o instanceof KeywordMatcher)) 33 | return false 34 | KeywordMatcher other = (KeywordMatcher) o 35 | keyword.equals(other.keyword) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/Match.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content 2 | 3 | import com.muwire.core.Persona 4 | 5 | class Match { 6 | Persona persona 7 | String [] keywords 8 | long timestamp 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/MatchAction.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content; 2 | 3 | public enum MatchAction { 4 | RECORD, DROP, BLOCK 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/Matcher.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content 2 | 3 | import com.muwire.core.search.QueryEvent 4 | 5 | abstract class Matcher { 6 | final List matches = Collections.synchronizedList(new ArrayList<>()) 7 | final Set uuids = new HashSet<>() 8 | private final MatchAction action 9 | final String name 10 | 11 | Matcher(MatchAction action, String name) { 12 | this.action = action 13 | this.name = name 14 | } 15 | 16 | protected abstract boolean match(List searchTerms); 17 | 18 | public abstract String getTerm(); 19 | 20 | public MatchAction process(QueryEvent qe) { 21 | def terms = qe.searchEvent.searchTerms 22 | if (!match(terms)) 23 | return null 24 | if (uuids.add(qe.searchEvent.uuid)) { 25 | long now = System.currentTimeMillis() 26 | matches << new Match(persona : qe.originator, keywords : terms, timestamp : now) 27 | } 28 | action 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/content/RegexMatcher.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.content 2 | 3 | import java.util.regex.Pattern 4 | import java.util.stream.Collectors 5 | 6 | class RegexMatcher extends Matcher { 7 | private final Pattern pattern 8 | RegexMatcher(String pattern, MatchAction action, String name) { 9 | super(action, name) 10 | this.pattern = Pattern.compile(pattern) 11 | } 12 | 13 | @Override 14 | protected boolean match(List keywords) { 15 | String combined = keywords.join(" ") 16 | return pattern.matcher(combined).find() 17 | } 18 | 19 | @Override 20 | public String getTerm() { 21 | pattern.pattern() 22 | } 23 | 24 | @Override 25 | public int hashCode() { 26 | pattern.pattern().hashCode() 27 | } 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (!(o instanceof RegexMatcher)) 32 | return false 33 | RegexMatcher other = (RegexMatcher) o 34 | pattern.pattern() == other.pattern.pattern() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/BadHashException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | class BadHashException extends Exception { 4 | 5 | public BadHashException() { 6 | super(); 7 | } 8 | 9 | public BadHashException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 10 | super(message, cause, enableSuppression, writableStackTrace); 11 | } 12 | 13 | public BadHashException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | 17 | public BadHashException(String message) { 18 | super(message); 19 | } 20 | 21 | public BadHashException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/DownloadHopelessEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | 5 | class DownloadHopelessEvent extends Event { 6 | Downloader downloader 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/DownloadRejectedException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | class DownloadRejectedException extends Exception { 4 | DownloadRejectedException() { 5 | super() 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/DownloadStartedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | 5 | class DownloadStartedEvent extends Event { 6 | Downloader downloader 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/SessionSupport.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.util.DataUtil 4 | 5 | import java.nio.charset.StandardCharsets 6 | 7 | class SessionSupport { 8 | static void writeInteractionHeaders(OutputStream os, boolean browse, boolean chat, 9 | boolean feed, boolean message) throws IOException { 10 | if (browse) 11 | os.write("Browse: true\r\n".getBytes(StandardCharsets.US_ASCII)) 12 | if (feed) 13 | os.write("Feed: true\r\n".getBytes(StandardCharsets.US_ASCII)) 14 | if (chat) 15 | os.write("Chat: true\r\n".getBytes(StandardCharsets.US_ASCII)) 16 | if (message) 17 | os.write("Message: true\r\n".getBytes(StandardCharsets.US_ASCII)) 18 | } 19 | 20 | static void writeXHave(OutputStream os, Pieces pieces) throws IOException { 21 | String xHave = DataUtil.encodeXHave(pieces.getDownloaded(), pieces.nPieces) 22 | os.write("X-Have: $xHave\r\n\r\n".getBytes(StandardCharsets.US_ASCII)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/SourceDiscoveredEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class SourceDiscoveredEvent extends Event { 8 | InfoHash infoHash 9 | Persona source 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/SourceVerifiedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | 6 | import net.i2p.data.Destination 7 | 8 | class SourceVerifiedEvent extends Event { 9 | InfoHash infoHash 10 | Destination source 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/UIDownloadCancelledEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIDownloadCancelledEvent extends Event { 6 | Downloader downloader 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/UIDownloadEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.search.UIResultEvent 5 | 6 | import net.i2p.data.Destination 7 | 8 | class UIDownloadEvent extends Event { 9 | 10 | UIResultEvent[] result 11 | Set sources 12 | File target, toShare 13 | boolean sequential 14 | } 15 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/UIDownloadLinkEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class UIDownloadLinkEvent extends Event { 8 | Persona host 9 | InfoHash infoHash 10 | String fileName 11 | long length 12 | int pieceSizePow2 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/UIDownloadPausedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIDownloadPausedEvent extends Event { 6 | } 7 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/download/UIDownloadResumedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.download 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIDownloadResumedEvent extends Event { 6 | } 7 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/CertificateCreatedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | 5 | class CertificateCreatedEvent extends Event { 6 | Certificate certificate 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/CertificateFetchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class CertificateFetchEvent extends Event { 8 | CertificateFetchStatus status 9 | int count 10 | Persona user 11 | InfoHash infoHash 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/CertificateFetchStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert; 2 | 3 | public enum CertificateFetchStatus { 4 | CONNECTING, FETCHING, DONE, FAILED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/CertificateFetchedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class CertificateFetchedEvent extends Event { 8 | Certificate certificate 9 | Persona user 10 | InfoHash infoHash 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/UICreateCertificateEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class UICreateCertificateEvent extends Event { 7 | SharedFile sharedFile 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/UIFetchCertificatesEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class UIFetchCertificatesEvent extends Event { 8 | Persona host 9 | InfoHash infoHash 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filecert/UIImportCertificateEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filecert 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIImportCertificateEvent extends Event { 6 | Certificate certificate 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/FeedFetchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class FeedFetchEvent extends Event { 7 | Persona host 8 | FeedFetchStatus status 9 | int totalItems 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/FeedItemFetchedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | 5 | class FeedItemFetchedEvent extends Event { 6 | FeedItem item 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/FeedItemLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | 5 | class FeedItemLoadedEvent extends Event { 6 | FeedItem item 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/FeedLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | 5 | class FeedLoadedEvent extends Event { 6 | Feed feed 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIDownloadFeedItemEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIDownloadFeedItemEvent extends Event { 6 | FeedItem item 7 | File target 8 | boolean sequential 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIFeedConfigurationEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | 5 | /** 6 | * Emitted when configuration of a feed changes. 7 | * The object should already contain the updated values. 8 | */ 9 | class UIFeedConfigurationEvent extends Event { 10 | Feed feed 11 | boolean newFeed 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIFeedDeletedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIFeedDeletedEvent extends Event { 7 | Persona host 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIFeedUpdateEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIFeedUpdateEvent extends Event { 7 | Persona host 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIFilePublishedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class UIFilePublishedEvent extends Event { 7 | SharedFile sf 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/filefeeds/UIFileUnpublishedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class UIFileUnpublishedEvent extends Event { 7 | SharedFile sf 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/AllFilesLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | class AllFilesLoadedEvent extends Event { 6 | int failed 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/DirectoryUnsharedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | class DirectoryUnsharedEvent extends Event { 6 | File[] directories 7 | boolean deleted 8 | 9 | public String toString() { 10 | super.toString() + " unshared directories "+ Arrays.toString(directories) + " deleted $deleted" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/DirectoryWatchedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | class DirectoryWatchedEvent extends Event { 6 | File directory 7 | boolean watch 8 | 9 | String toString() { 10 | "DirectoryWatchedEvent ${super.toString()} directory:$directory watch:$watch" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileDownloadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.DownloadedFile 4 | import com.muwire.core.Event 5 | import com.muwire.core.InfoHash 6 | import com.muwire.core.download.Downloader 7 | 8 | import net.i2p.data.Destination 9 | 10 | class FileDownloadedEvent extends Event { 11 | Downloader downloader 12 | DownloadedFile downloadedFile 13 | File parentToShare 14 | InfoHash infoHash, collectionInfoHash 15 | boolean confidential 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileHashedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.SharedFile 6 | 7 | class FileHashedEvent extends Event { 8 | 9 | SharedFile sharedFile 10 | String error 11 | 12 | /** 13 | * This will be non-null in case of a re-hash. 14 | */ 15 | SharedFile original 16 | 17 | @Override 18 | public String toString() { 19 | super.toString() + " sharedFile " + sharedFile?.file?.getAbsolutePath() + " error: $error" 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileHashingEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class FileHashingEvent extends Event { 7 | 8 | File hashingFile 9 | 10 | @Override 11 | public String toString() { 12 | super.toString() + " hashingFile " + hashingFile.getAbsolutePath() 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileListCallback.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files; 2 | 3 | import java.io.File; 4 | 5 | public interface FileListCallback { 6 | 7 | public void onFile(File f, T value); 8 | 9 | public void onDirectory(File f); 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.SharedFile 6 | 7 | class FileLoadedEvent extends Event { 8 | 9 | SharedFile loadedFile 10 | InfoHash infoHash 11 | String source 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileModifiedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class FileModifiedEvent extends Event { 7 | SharedFile[] sharedFiles 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileSharedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | class FileSharedEvent extends Event { 6 | 7 | File file 8 | boolean fromWatch 9 | 10 | @Override 11 | public String toString() { 12 | return super.toString() + " file: "+file.getAbsolutePath() + " fromWatch: $fromWatch" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileTreeCallback.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files; 2 | 3 | import java.io.File; 4 | 5 | public interface FileTreeCallback { 6 | public void onDirectoryEnter(File file); 7 | public void onDirectoryLeave(); 8 | public void onFile(File file, T value); 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/FileUnsharedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class FileUnsharedEvent extends Event { 7 | SharedFile[] unsharedFiles 8 | boolean deleted 9 | /** 10 | * true if the files are implicitly removed as part of unsharing a folder. 11 | */ 12 | boolean implicit 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/InfoHashEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | 6 | class InfoHashEvent extends Event { 7 | File file 8 | InfoHash infoHash 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/PersisterDoneEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | /** 6 | * Should be triggered by the old PersisterService 7 | * once it has finished reading the old file 8 | * 9 | * @see PersisterService 10 | */ 11 | class PersisterDoneEvent extends Event{ 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/SideCarFileEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | 5 | class SideCarFileEvent extends Event { 6 | File file 7 | 8 | @Override 9 | public String toString() { 10 | return super.toString() + " file: "+file.getAbsolutePath() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/UICommentEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class UICommentEvent extends Event { 7 | SharedFile sharedFile 8 | String oldComment 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/UISyncDirectoryEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Event 4 | 5 | class UISyncDirectoryEvent extends Event { 6 | File directory 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/Visibility.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories; 2 | 3 | public enum Visibility { 4 | EVERYONE, CONTACTS, CUSTOM 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/WatchedDirectoriesLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Event 4 | 5 | /** 6 | * Notification that all watched directories have been loaded 7 | * from disk. 8 | */ 9 | class WatchedDirectoriesLoadedEvent extends Event { 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/WatchedDirectoryConfigurationEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | import com.muwire.core.profile.MWProfileHeader 6 | 7 | class WatchedDirectoryConfigurationEvent extends Event { 8 | /** directory selected by user or by converter */ 9 | File directory 10 | 11 | /** actual directories to apply, enriched by FileManager */ 12 | File [] toApply 13 | 14 | boolean autoWatch 15 | int syncInterval 16 | boolean subfolders 17 | Visibility visibility 18 | Set customVisibility 19 | Set customVisibilityHeaders 20 | } 21 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/WatchedDirectoryConvertedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Event 4 | 5 | /** 6 | * Emitted when converting an old watched directory entry to the 7 | * new format. 8 | */ 9 | class WatchedDirectoryConvertedEvent extends Event { 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/WatchedDirectoryConverter.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.files.AllFilesLoadedEvent 5 | 6 | /** 7 | * converts the setting-based format to new folder-based format. 8 | */ 9 | class WatchedDirectoryConverter { 10 | 11 | private final Core core 12 | 13 | WatchedDirectoryConverter(Core core) { 14 | this.core = core 15 | } 16 | 17 | void convert() { 18 | core.getMuOptions().getWatchedDirectories().each { 19 | File directory = new File(it) 20 | directory = directory.getCanonicalFile() 21 | core.eventBus.publish(new WatchedDirectoryConfigurationEvent(directory : directory, autoWatch: true)) 22 | } 23 | core.getMuOptions().getWatchedDirectories().clear() 24 | core.saveMuSettings() 25 | core.eventBus.publish(new WatchedDirectoryConvertedEvent()) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/files/directories/WatchedDirectorySyncEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.files.directories 2 | 3 | import com.muwire.core.Event 4 | 5 | class WatchedDirectorySyncEvent extends Event { 6 | File directory 7 | long when 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/hostcache/HostDiscoveredEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.hostcache 2 | 3 | import com.muwire.core.Event 4 | 5 | import net.i2p.data.Destination 6 | 7 | class HostDiscoveredEvent extends Event { 8 | 9 | Destination destination 10 | boolean fromHostcache 11 | 12 | @Override 13 | public String toString() { 14 | "HostDiscoveredEvent ${super.toString()} destination:${destination.toBase32()} from hostcache $fromHostcache" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/InvalidMessageException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | class InvalidMessageException extends Exception { 4 | 5 | public InvalidMessageException() { 6 | super(); 7 | } 8 | 9 | public InvalidMessageException(String message, Throwable cause, boolean enableSuppression, 10 | boolean writableStackTrace) { 11 | super(message, cause, enableSuppression, writableStackTrace); 12 | } 13 | 14 | public InvalidMessageException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public InvalidMessageException(String message) { 19 | super(message); 20 | } 21 | 22 | public InvalidMessageException(Throwable cause) { 23 | super(cause); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/MessageFolderLoadingEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class MessageFolderLoadingEvent extends Event { 6 | String name 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/MessageLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.profile.MWProfileHeader 5 | 6 | class MessageLoadedEvent extends Event { 7 | MWMessage message 8 | String folder 9 | boolean unread 10 | MWProfileHeader profileHeader 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/MessageReceivedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.profile.MWProfileHeader 5 | 6 | class MessageReceivedEvent extends Event { 7 | MWMessage message 8 | MWProfileHeader profileHeader 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/MessageSentEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class MessageSentEvent extends Event { 6 | MWMessage message 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIDownloadAttachmentEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIDownloadAttachmentEvent extends Event { 7 | Persona sender 8 | MWMessageAttachment attachment 9 | boolean sequential 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIFolderCreateEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIFolderCreateEvent extends Event { 6 | String name 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIFolderDeleteEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIFolderDeleteEvent extends Event { 6 | String name 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIMessageDeleteEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIMessageDeleteEvent extends Event { 6 | MWMessage message 7 | String folder 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIMessageEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIMessageEvent extends Event { 6 | MWMessage message 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIMessageMovedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIMessageMovedEvent extends Event { 6 | MWMessage message 7 | String from, to 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/messenger/UIMessageReadEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.messenger 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIMessageReadEvent extends Event { 6 | MWMessage message 7 | String folder 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/mulinks/InvalidMuLinkException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.mulinks 2 | 3 | class InvalidMuLinkException extends Exception { 4 | InvalidMuLinkException(String message) { 5 | super(message) 6 | } 7 | 8 | InvalidMuLinkException(String message, Throwable cause) { 9 | super(message, cause) 10 | } 11 | 12 | InvalidMuLinkException(Throwable cause) { 13 | super(cause) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/profile/MWProfileFetchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.profile 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class MWProfileFetchEvent extends Event { 7 | MWProfileFetchStatus status 8 | Persona host 9 | UUID uuid 10 | MWProfile profile 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/profile/UIProfileFetchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.profile 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIProfileFetchEvent extends Event { 7 | UUID uuid 8 | Persona host 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/BrowseStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search; 2 | 3 | public enum BrowseStatus { 4 | CONNECTING, FETCHING, FINISHED, FAILED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/BrowseStatusEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class BrowseStatusEvent extends Event { 7 | Persona host 8 | BrowseStatus status 9 | BrowseSession session 10 | int totalResults 11 | int currentItems 12 | UUID uuid 13 | } 14 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/DeleteEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | 5 | import net.i2p.data.Base32 6 | import net.i2p.data.Destination 7 | 8 | class DeleteEvent extends Event { 9 | byte [] infoHash 10 | Destination leaf 11 | 12 | @Override 13 | public String toString() { 14 | "DeleteEvent ${super.toString()} infoHash:${Base32.encode(infoHash)} leaf:${leaf.toBase32()}" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/InvalidSearchResultException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | class InvalidSearchResultException extends Exception { 4 | 5 | public InvalidSearchResultException() { 6 | super(); 7 | // TODO Auto-generated constructor stub 8 | } 9 | 10 | public InvalidSearchResultException(String message, Throwable cause) { 11 | super(message, cause); 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | public InvalidSearchResultException(String message) { 16 | super(message); 17 | // TODO Auto-generated constructor stub 18 | } 19 | 20 | public InvalidSearchResultException(Throwable cause) { 21 | super(cause); 22 | // TODO Auto-generated constructor stub 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/QueryEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | import net.i2p.data.Destination 7 | 8 | class QueryEvent extends Event { 9 | 10 | SearchEvent searchEvent 11 | boolean firstHop, local 12 | Destination replyTo 13 | Persona originator 14 | Destination receivedOn 15 | byte[] sig 16 | long queryTime 17 | byte[] sig2 18 | 19 | String toString() { 20 | "searchEvent: $searchEvent firstHop:$firstHop, replyTo:${replyTo.toBase32()}" + 21 | "originator: ${originator.getHumanReadableName()} receivedOn: ${receivedOn.toBase32()}" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/ResponderCache.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.download.SourceVerifiedEvent 4 | import com.muwire.core.util.FixedSizeFIFOSet 5 | 6 | import net.i2p.data.Destination 7 | 8 | /** 9 | * Caches destinations that have recently responded to with results. 10 | */ 11 | class ResponderCache { 12 | 13 | private final FixedSizeFIFOSet cache 14 | 15 | ResponderCache(int capacity) { 16 | cache = new FixedSizeFIFOSet<>(capacity) 17 | } 18 | 19 | synchronized void onUIResultBatchEvent(UIResultBatchEvent e) { 20 | cache.add(e.results[0].sender.destination) 21 | } 22 | 23 | synchronized void onSourceVerifiedEvent(SourceVerifiedEvent e) { 24 | cache.add(e.source) 25 | } 26 | 27 | synchronized boolean hasResponded(Destination d) { 28 | cache.contains(d) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/ResultsEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.SharedFile 5 | 6 | class ResultsEvent extends Event { 7 | 8 | SearchEvent searchEvent 9 | SharedFile[] results 10 | UUID uuid 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/SearchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.Persona 6 | 7 | class SearchEvent extends Event { 8 | 9 | List searchTerms 10 | byte [] searchHash 11 | UUID uuid 12 | boolean oobInfohash 13 | boolean searchComments 14 | boolean compressedResults 15 | Persona persona 16 | boolean collections 17 | boolean searchPaths 18 | boolean regex 19 | boolean profile 20 | 21 | String toString() { 22 | def infoHash = null 23 | if (searchHash != null) 24 | infoHash = new InfoHash(searchHash) 25 | "searchTerms: $searchTerms searchHash:$infoHash, uuid:$uuid " + 26 | "oobInfohash:$oobInfohash searchComments:$searchComments " + 27 | "compressedResults:$compressedResults regex:$regex" + 28 | "profile:$profile" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/UIBrowseDirEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIBrowseDirEvent extends Event { 6 | UUID uuid 7 | String[] path 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/UIBrowseEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class UIBrowseEvent extends Event { 7 | UUID uuid 8 | Persona host 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/UIResultBatchEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | 5 | class UIResultBatchEvent extends Event { 6 | UUID uuid 7 | UIResultEvent[] results 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/UnexpectedResultsException.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | class UnexpectedResultsException extends Exception { 4 | 5 | public UnexpectedResultsException() { 6 | super(); 7 | } 8 | 9 | public UnexpectedResultsException(String message, Throwable cause, boolean enableSuppression, 10 | boolean writableStackTrace) { 11 | super(message, cause, enableSuppression, writableStackTrace); 12 | } 13 | 14 | public UnexpectedResultsException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public UnexpectedResultsException(String message) { 19 | super(message); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/search/UpsertEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.search 2 | 3 | import com.muwire.core.Event 4 | 5 | import net.i2p.data.Base32 6 | import net.i2p.data.Destination 7 | 8 | class UpsertEvent extends Event { 9 | 10 | Set names 11 | byte [] infoHash 12 | Destination leaf 13 | 14 | @Override 15 | public String toString() { 16 | "UpsertEvent ${super.toString()} names:$names infoHash:${Base32.encode(infoHash)} leaf:${leaf.toBase32()}" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/trust/RemoteTrustList.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust 2 | 3 | import java.util.concurrent.ConcurrentHashMap 4 | 5 | import com.muwire.core.Persona 6 | import com.muwire.core.trust.TrustService.TrustEntry 7 | 8 | import net.i2p.util.ConcurrentHashSet 9 | 10 | class RemoteTrustList { 11 | public enum Status { NEW, UPDATING, UPDATED, UPDATE_FAILED } 12 | 13 | final Persona persona 14 | final Set good, bad 15 | volatile long timestamp 16 | volatile boolean forceUpdate 17 | Status status = Status.NEW 18 | 19 | RemoteTrustList(Persona persona) { 20 | this.persona = persona 21 | good = new ConcurrentHashSet<>() 22 | bad = new ConcurrentHashSet<>() 23 | } 24 | 25 | @Override 26 | public boolean equals(Object o) { 27 | if (!(o instanceof RemoteTrustList)) 28 | return false 29 | RemoteTrustList other = (RemoteTrustList)o 30 | persona == other.persona 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/trust/TrustEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | import com.muwire.core.profile.MWProfile 6 | import com.muwire.core.profile.MWProfileHeader 7 | 8 | class TrustEvent extends Event { 9 | 10 | Persona persona 11 | TrustLevel level 12 | String reason 13 | MWProfileHeader profileHeader 14 | MWProfile profile 15 | } 16 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/trust/TrustServiceLoadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust 2 | 3 | import com.muwire.core.Event 4 | 5 | class TrustServiceLoadedEvent extends Event { 6 | } 7 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/trust/TrustSubscriptionEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.Persona 5 | 6 | class TrustSubscriptionEvent extends Event { 7 | Persona persona 8 | boolean subscribe 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/trust/TrustSubscriptionUpdatedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust 2 | 3 | import com.muwire.core.Event 4 | 5 | class TrustSubscriptionUpdatedEvent extends Event { 6 | RemoteTrustList trustList 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/update/AutoUpdater.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.update; 2 | 3 | import com.muwire.core.Core; 4 | 5 | public interface AutoUpdater { 6 | void init(Core core); 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/update/UpdateAvailableEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.update 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.InfoHash 5 | 6 | class UpdateAvailableEvent extends Event { 7 | String version 8 | String signer 9 | String infoHash 10 | String text 11 | } 12 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/update/UpdateDownloadedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.update 2 | 3 | import com.muwire.core.Event 4 | 5 | class UpdateDownloadedEvent extends Event { 6 | String version 7 | String signer 8 | String text 9 | File updateFile 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/update/UpdateServers.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.update 2 | 3 | import net.i2p.data.Destination 4 | 5 | class UpdateServers { 6 | static final Destination UPDATE_SERVER = new Destination("VJYAiCPZHNLraWvLkeRLxRiT4PHAqNqRO1nH240r7u1noBw8Pa~-lJOhKR7CccPkEN8ejSi4H6XjqKYLC8BKLVLeOgnAbedUVx81MV7DETPDdPEGV4RVu6YDFri7-tJOeqauGHxtlXT44YWuR69xKrTG3u4~iTWgxKnlBDht9Q3aVpSPFD2KqEizfVxolqXI0zmAZ2xMi8jfl0oe4GbgHrD9hR2FYj6yKfdqcUgHVobY4kDdJt-u31QqwWdsQMEj8Y3tR2XcNaITEVPiAjoKgBrYwB4jddWPNaT4XdHz76d9p9Iqes7dhOKq3OKpk6kg-bfIKiEOiA1mY49fn5h8pNShTqV7QBhh4CE4EDT3Szl~WsLdrlHUKJufSi7erEMh3coF7HORpF1wah2Xw7q470t~b8dKGKi7N7xQsqhGruDm66PH9oE9Kt9WBVBq2zORdPRtRM61I7EnrwDlbOkL0y~XpvQ3JKUQKdBQ3QsOJt8CHlhHHXMMbvqhntR61RSDBQAEAAcAAA==") 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/ContentRequest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | class ContentRequest extends HeadRequest { 4 | Range range 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/HashListRequest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | class HashListRequest extends Request { 4 | } 5 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/HeadRequest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | class HeadRequest extends Request { 4 | int have 5 | boolean browse, feed, chat, message 6 | } 7 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/HeadUploader.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | import com.muwire.core.Persona 4 | import com.muwire.core.connection.Endpoint 5 | import com.muwire.core.mesh.Mesh 6 | 7 | import java.nio.charset.StandardCharsets 8 | 9 | class HeadUploader extends MeshUploader { 10 | 11 | private final Persona downloader 12 | 13 | HeadUploader(File file, HeadRequest request, Endpoint endpoint, Mesh mesh, boolean confidential) { 14 | super(file, request, endpoint, mesh, confidential) 15 | this.downloader = request.downloader 16 | } 17 | 18 | @Override 19 | void respond() { 20 | OutputStream os = endpoint.getOutputStream() 21 | os.write("200 OK\r\n".getBytes(StandardCharsets.US_ASCII)) // what else can be said? 22 | writeMesh(downloader) 23 | writeHeadSupport() 24 | writeConfidential() 25 | os.write("\r\n".getBytes(StandardCharsets.US_ASCII)) 26 | os.flush() 27 | } 28 | 29 | @Override 30 | int getProgress() { 31 | return 100 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/Range.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | class Range { 4 | final long start, end 5 | 6 | Range(long start, long end) { 7 | this.start = start 8 | this.end = end 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/UploadEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | import com.muwire.core.Event 4 | import com.muwire.core.profile.MWProfileHeader 5 | 6 | public class UploadEvent extends Event { 7 | Uploader uploader 8 | boolean first 9 | MWProfileHeader profileHeader 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/upload/UploadFinishedEvent.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.upload 2 | 3 | import com.muwire.core.Event 4 | 5 | class UploadFinishedEvent extends Event { 6 | Uploader uploader 7 | } 8 | -------------------------------------------------------------------------------- /core/src/main/groovy/com/muwire/core/util/MuWireLogManager.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util 2 | 3 | import net.i2p.I2PAppContext 4 | import net.i2p.util.Log 5 | import net.i2p.util.LogManager 6 | 7 | class MuWireLogManager extends LogManager { 8 | 9 | private static final Map, Log> classLogs = new HashMap<>() 10 | private static final Map stringLogs = new HashMap<>() 11 | 12 | MuWireLogManager() { 13 | super(I2PAppContext.getGlobalContext()) 14 | } 15 | 16 | 17 | @Override 18 | public synchronized Log getLog(Class cls, String name) { 19 | if (cls != null) { 20 | Log rv = classLogs.get(cls) 21 | if (rv == null) { 22 | rv = new JULLog(cls) 23 | classLogs.put(cls, rv) 24 | } 25 | return rv 26 | } 27 | 28 | Log rv = stringLogs.get(name) 29 | if (rv == null) { 30 | rv = new JULLog(name) 31 | stringLogs.put(name, rv) 32 | } 33 | rv 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/DownloadedFile.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.Set; 6 | 7 | import net.i2p.data.Destination; 8 | 9 | public class DownloadedFile extends SharedFile { 10 | 11 | private final Set sources; 12 | 13 | public DownloadedFile(File file, byte[] root, int pieceSize, long sharedTime, Set sources) 14 | throws IOException { 15 | super(file, root, pieceSize, sharedTime); 16 | this.sources = sources; 17 | } 18 | 19 | public Set getSources() { 20 | return sources; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/InvalidNicknameException.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core; 2 | 3 | public class InvalidNicknameException extends Exception { 4 | 5 | public InvalidNicknameException() { 6 | } 7 | 8 | public InvalidNicknameException(String message) { 9 | super(message); 10 | } 11 | 12 | public InvalidNicknameException(Throwable cause) { 13 | super(cause); 14 | } 15 | 16 | public InvalidNicknameException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public InvalidNicknameException(String message, Throwable cause, boolean enableSuppression, 21 | boolean writableStackTrace) { 22 | super(message, cause, enableSuppression, writableStackTrace); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/InvalidSignatureException.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core; 2 | 3 | public class InvalidSignatureException extends Exception { 4 | 5 | public InvalidSignatureException(String message, Throwable cause) { 6 | super(message, cause); 7 | } 8 | 9 | public InvalidSignatureException(String message) { 10 | super(message); 11 | } 12 | 13 | public InvalidSignatureException(Throwable cause) { 14 | super(cause); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/connection/ConnectionAttemptStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.connection; 2 | 3 | public enum ConnectionAttemptStatus { 4 | SUCCESSFUL, REJECTED, FAILED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/filefeeds/FeedFetchStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds; 2 | 3 | public enum FeedFetchStatus { 4 | IDLE(false), 5 | CONNECTING(true), 6 | FETCHING(true), 7 | FINISHED(false), 8 | FAILED(false); 9 | 10 | private final boolean active; 11 | 12 | FeedFetchStatus(boolean active) { 13 | this.active = active; 14 | } 15 | 16 | public boolean isActive() { 17 | return active; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/filefeeds/InvalidFeedItemException.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.filefeeds; 2 | 3 | public class InvalidFeedItemException extends Exception { 4 | 5 | public InvalidFeedItemException() { 6 | super(); 7 | } 8 | 9 | public InvalidFeedItemException(String message, Throwable cause, boolean enableSuppression, 10 | boolean writableStackTrace) { 11 | super(message, cause, enableSuppression, writableStackTrace); 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | public InvalidFeedItemException(String message, Throwable cause) { 16 | super(message, cause); 17 | // TODO Auto-generated constructor stub 18 | } 19 | 20 | public InvalidFeedItemException(String message) { 21 | super(message); 22 | // TODO Auto-generated constructor stub 23 | } 24 | 25 | public InvalidFeedItemException(Throwable cause) { 26 | super(cause); 27 | // TODO Auto-generated constructor stub 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/hostcache/CrawlerResponse.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.hostcache; 2 | 3 | /** 4 | * Whether this host should answer to crawler queries 5 | * @author zab 6 | * 7 | */ 8 | public enum CrawlerResponse { 9 | ALL, REGISTERED, NONE 10 | } 11 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/profile/MWProfileFetchStatus.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.profile; 2 | 3 | public enum MWProfileFetchStatus { 4 | CONNECTING, FETCHING, FAILED, FINISHED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/profile/MWProfileImageFormat.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.profile; 2 | 3 | public enum MWProfileImageFormat { 4 | PNG, JPG 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/trust/TrustLevel.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.trust; 2 | 3 | public enum TrustLevel { 4 | TRUSTED, NEUTRAL, DISTRUSTED 5 | } 6 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/util/FixedSizeFIFOSet.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | public class FixedSizeFIFOSet { 9 | 10 | private final int capacity; 11 | private final Set set = new HashSet<>(); 12 | private final Deque fifo = new ArrayDeque<>(); 13 | 14 | public FixedSizeFIFOSet(final int capacity) { 15 | this.capacity = capacity; 16 | } 17 | 18 | public boolean contains(T element) { 19 | return set.contains(element); 20 | } 21 | 22 | public void add(T element) { 23 | if (!set.contains(element)) { 24 | if (set.size() == capacity) { 25 | T toRemove = fifo.removeLast(); 26 | set.remove(toRemove); 27 | } 28 | fifo.addFirst(element); 29 | set.add(element); 30 | } else { 31 | fifo.remove(element); 32 | fifo.addFirst(element); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/util/MessageThrottle.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util; 2 | 3 | public class MessageThrottle { 4 | 5 | private final long interval; 6 | private final int allowed; 7 | 8 | private final long[] timestamps; 9 | private long lastMsg; 10 | private int idx; 11 | 12 | public MessageThrottle(long interval, int allowed) { 13 | this.interval = interval; 14 | this.allowed = allowed; 15 | this.timestamps = new long[allowed]; 16 | } 17 | 18 | long lastMsg() { 19 | return lastMsg; 20 | } 21 | 22 | public boolean allow(long now) { 23 | lastMsg = now; 24 | final long previous = timestamps[idx]; 25 | if (previous == 0 || now - previous > interval) { 26 | timestamps[idx++] = now; 27 | if (idx == allowed) 28 | idx = 0; 29 | return true; 30 | } 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/util/PathTreeCallback.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util; 2 | 3 | import java.nio.file.Path; 4 | 5 | public interface PathTreeCallback { 6 | void onDirectoryEnter(Path path, I value); 7 | void onDirectoryLeave(); 8 | void onLeaf(Path path, T value); 9 | } 10 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/util/PathTreeListCallback.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util; 2 | 3 | import java.nio.file.Path; 4 | 5 | public interface PathTreeListCallback { 6 | void onLeaf(Path path, T value); 7 | void onDirectory(Path path, I value); 8 | } 9 | -------------------------------------------------------------------------------- /core/src/main/java/com/muwire/core/util/SenderThrottle.java: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util; 2 | 3 | import com.muwire.core.Persona; 4 | 5 | import java.util.HashMap; 6 | import java.util.Iterator; 7 | import java.util.Map; 8 | 9 | public class SenderThrottle { 10 | private final long interval; 11 | private final int allowed; 12 | 13 | private final Map throttleMap = 14 | new HashMap<>(); 15 | 16 | public SenderThrottle(long interval, int allowed) { 17 | this.interval = interval; 18 | this.allowed = allowed; 19 | } 20 | 21 | public boolean allow(long now, Persona sender) { 22 | MessageThrottle throttle = throttleMap.computeIfAbsent(sender, 23 | p -> {return new MessageThrottle(interval, allowed);}); 24 | return throttle.allow(now); 25 | } 26 | 27 | public int clear(long now) { 28 | int rv = 0; 29 | for (Iterator> iterator = throttleMap.entrySet().iterator(); 30 | iterator.hasNext();) { 31 | Map.Entry entry = iterator.next(); 32 | if (now - entry.getValue().lastMsg() > interval) { 33 | iterator.remove(); 34 | rv++; 35 | } 36 | } 37 | return rv; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/resources/defaults/i2p.properties: -------------------------------------------------------------------------------- 1 | inbound.nickname=MuWire 2 | outbound.nickname=MuWire 3 | inbound.length=3 4 | inbound.quantity=4 5 | outbound.length=3 6 | outbound.quantity=4 7 | i2cp.tcp.host=127.0.0.1 8 | i2cp.tcp.port=7654 9 | router.excludePeerCaps=KLMNO 10 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/Destinations.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import net.i2p.data.Destination 4 | 5 | class Destinations { 6 | 7 | Destination dest1 = new Destination("KvwWPKMSAtzf7Yruj8TQaHi2jaQpSNsXJskbpmSBTxkcYlDB2GllH~QBu-cs4FSYdaRmKDUUx7793jjnYJgTMbrjqeIL5-BTORZ09n6PUfhSejDpJjdkUxaV1OHRatfYs70RNBv7rvdj1-nXUow5tMfOJtoWVocUoKefUGFQFbJLDDkBqjm1kFyKFZv6m6S6YqXxBgVB1qYicooy67cNQF5HLUFtP15pk5fMDNGz5eNCjPfC~2Gp8FF~OpSy92HT0XN7uAMJykPcbdnWfcvVwqD7eS0K4XEnsqnMPLEiMAhqsugEFiFqtB3Wmm7UHVc03lcAfRhr1e2uZBNFTtM2Uol4MD5sCCKRZVHGcH-WGPSEz0BM5YO~Xi~dQ~N3NVud32PVzhh8xoGcAlhTqMqAbRJndCv-H6NflX90pYmbirCTIDOaR9758mThrqX0d4CwCn4jFXer52l8Qe8CErGoLuB-4LL~Gwrn7R1k7ZQc2PthkqeW8MfigyiN7hZVkul9AAAA") 8 | Destination dest2 = new Destination("KvwWPKMSAtzf7Yruj8TQaHi2jaQpSNsXJskbpmSBTxkcYlDB2GllH~QBu-cs4FSYdaRmKDUUx7793jjnYJgTMbrjqeIL5-BTORZ09n6PUfhSejDpJjdkUxaV1OHRatfYs70RNBv7rvdj1-nXUow5tMfOJtoWVocUoKefUGFQFbJLDDkBqjm1kFyKFZv6m6S6YqXxBgVB1qYicooy67cNQF5HLUFtP15pk5fMDNGz5eNCjPfC~2Gp8FF~OpSy92HT0XN7uAMJykPcbdnWfcvVwqD7eS0K4XEnsqnMPLEiMAhqsugEFiFqtB3Wmm7UHVc03lcAfRhr1e2uZBNFTtM2Uol4MD5sCCKRZVHGcH-WGPSEz0BM5YO~Xi~dQ~N3NVud32PVzhh8xoGcAlhTqMqAbRJndCv-H6NflX90pYmbirCTIDOaR9758mThrqX0d4CwCn4jFXer52l8Qe8CErGoLuB-4LL~Gwrn7R1k7ZQc2PthkqeW8MfigyiN7hZVkul8AAAA") 9 | } 10 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/EventBusTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import org.junit.Test 4 | 5 | class EventBusTest { 6 | 7 | class FakeEvent extends Event {} 8 | 9 | class FakeEventHandler { 10 | def onFakeEvent(FakeEvent e) { 11 | assert e == fakeEvent 12 | } 13 | } 14 | 15 | FakeEvent fakeEvent = new FakeEvent() 16 | 17 | EventBus bus = new EventBus() 18 | def handler = new FakeEventHandler() 19 | 20 | @Test 21 | void testDynamicEvent() { 22 | bus.register(FakeEvent.class, handler) 23 | bus.publish(fakeEvent) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/InfoHashTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals 4 | 5 | import org.junit.Test 6 | 7 | class InfoHashTest { 8 | 9 | @Test 10 | void testEmpty() { 11 | byte [] empty = new byte[0x1 << 6]; 12 | def ih = InfoHash.fromHashList(empty) 13 | def ih2 = new InfoHash("6ws72qwrniqdaj4y55xngcmxtnbqapjdedm7b2hktay2sj2z7nfq"); 14 | assertEquals(ih, ih2); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/SplitPatternTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core 2 | 3 | import org.junit.Test 4 | 5 | class SplitPatternTest { 6 | 7 | @Test 8 | void testReplaceCharacters() { 9 | assert SplitPattern.termify("a_b.c") == ['a','b','c'] 10 | } 11 | 12 | @Test 13 | void testPhrase() { 14 | assert SplitPattern.termify('"siamese cat"') == ['siamese cat'] 15 | } 16 | 17 | @Test 18 | void testInvalidPhrase() { 19 | assert SplitPattern.termify('"siamese cat') == ['siamese', 'cat'] 20 | } 21 | 22 | @Test 23 | void testManyPhrases() { 24 | assert SplitPattern.termify('"siamese cat" any cat "persian cat"') == 25 | ['siamese cat','any','cat','persian cat'] 26 | } 27 | 28 | @Test 29 | void testNewLine() { 30 | def s = "first\nsecond" 31 | s = s.replaceAll(SplitPattern.SPLIT_PATTERN, " ") 32 | s = s.split(" ") 33 | assert s.length == 2 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/util/MessageThrottleTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util 2 | 3 | import org.junit.Test 4 | 5 | class MessageThrottleTest { 6 | 7 | @Test 8 | public void testThrottleOne() { 9 | def throttle = new MessageThrottle(100, 1) 10 | assert throttle.allow(1) 11 | assert !throttle.allow(2) 12 | assert !throttle.allow(10) 13 | assert throttle.allow(102) 14 | } 15 | 16 | @Test 17 | public void testAllowThree() { 18 | def throttle = new MessageThrottle(100, 3) 19 | assert throttle.allow(1) 20 | assert throttle.allow(2) 21 | assert throttle.allow(3) 22 | 23 | assert !throttle.allow(101) 24 | 25 | assert throttle.allow(102) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/test/groovy/com/muwire/core/util/SenderThrottleTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.core.util 2 | 3 | import com.muwire.core.Personas 4 | import org.junit.Test 5 | 6 | class SenderThrottleTest { 7 | 8 | 9 | private static Personas personas = new Personas() 10 | 11 | @Test 12 | public void testSenders() { 13 | def throttle = new SenderThrottle(100, 1) 14 | assert throttle.allow(1, personas.persona1) 15 | assert throttle.allow(1, personas.persona2) 16 | 17 | assert !throttle.allow(2, personas.persona1) 18 | assert !throttle.allow(2, personas.persona2) 19 | } 20 | 21 | @Test 22 | public void testClear() { 23 | def throttle = new SenderThrottle(100, 1) 24 | 25 | assert throttle.clear(1) == 0 26 | 27 | throttle.allow(1, personas.persona1) 28 | 29 | assert throttle.clear(1) == 0 30 | assert throttle.clear( 102) == 1 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /doc/binary-pongs.md: -------------------------------------------------------------------------------- 1 | # Upgrade to binary pongs 2 | 3 | ### Motivation 4 | 5 | The current intra-peer protocol is JSON, which means messages need to be ascii-armored. This is not as optimal as a binary protocol, especially when sending large blobs like I2P destinations. 6 | 7 | ### Upgrade path 8 | 9 | The pinging node sends pings with the `version` field set to 2. 10 | 11 | Upon receiving pings with version 2, the responding node will send a binary Pong. 12 | 13 | ### Pong format: 14 | 15 | ``` 16 | byte 0: message type, fixed at 1 for "Pong" 17 | byte 1: version, fixed at 2 18 | bytes 2-18: UUID of the Pong 19 | byte 19: number of destinations contained in this Pong 20 | bytes 20-end: destinations 21 | ``` 22 | 23 | ### Other benefits 24 | 25 | With the reduced size of Pong messages each Pong can carry more destinations. Also, the default maximum number of connections can be increased. 26 | -------------------------------------------------------------------------------- /doc/crawler.md: -------------------------------------------------------------------------------- 1 | # Crawling 2 | 3 | Crawling the network is one possible method for a HostCache to discover currently active nodes on the network. 4 | 5 | ### Crawler Ping 6 | 7 | The crawler ping is a message sent in a signed datagram to the target ultrapeer. It contains uncompressed JSON payload with the message type, version and an UUID: 8 | 9 | ``` 10 | { 11 | type: "CrawlerPing", 12 | version: 1, 13 | uuid: "asdf-1234-..." 14 | } 15 | ``` 16 | 17 | ### Crawler Pong 18 | 19 | A node responds with the following message, also in a signed datagram. It contains the list of Destinations that the node is currently connected to. Since the datagram is limited in size, not all Destinations will be able to fit in it, but that should be fine for the purpose of discovery. The "uuid" field must match that of the CrawlerPing. 20 | 21 | ``` 22 | { 23 | type: "CrawlerPong", 24 | version: 1, 25 | uuid: "asdf-1234-...", 26 | clientVersion: "MuWire 1.2.3", 27 | leafSlots: true, 28 | peerSlots: true, 29 | peers: [ b64.1, b64.2...] 30 | } 31 | ``` 32 | 33 | * The `peerSlots` field is set to `true` if the responding node has available connection slots 34 | * The `leafSlots` field is effectively ignored 35 | 36 | ### Operator control 37 | 38 | The operator of the ultrapeer can choose to allow anyone to crawl their node, or just the bundled HostCaches, or nobody at all. 39 | -------------------------------------------------------------------------------- /doc/download-mesh.md: -------------------------------------------------------------------------------- 1 | # Download Mesh / Partial Sharing 2 | 3 | MuWire uses a system similar to Gnutella's "Alternate Location" download mesh management system, however it is simplified to account for I2P's strengths and borrows a bit from BitTorrent's "Have" message. 4 | 5 | ### "X-Have" header 6 | 7 | With every request a downloader makes it sends an "X-Have" header containing the Base64-encoded representation of a bitfield where bits set to 1 represent pieces of the file that the downloader already has. To make partial file sharing possible, if the uploader does not have the complete file it also sends this header in every response. If the header is missing it is assumed the uploader has the complete file. 8 | 9 | ### "X-Alt" header 10 | 11 | The uploader can recommend other uploaders to the downloader via the "X-Alt" header. The format of this header is a comma-separated list of Base64-encoded Personas that have previously reported having at least one piece of the file to the uploader via the "X-Have" header. 12 | 13 | 14 | ### Differences from Gnutella 15 | 16 | Unlike Gnutella the uploader is the sole repository where possible sources of the file are tracked. There is no negative "X-Nalt" header to prevent attacking the download mesh by mass downvoting of sources. 17 | -------------------------------------------------------------------------------- /docker/rootfs/etc/cont-init.d/00-app-user-map.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | 3 | # 4 | # Add the app user to the password and group databases. This is needed just to 5 | # make sure that mapping between the user/group ID and its name is possible. 6 | # 7 | 8 | set -e # Exit immediately if a command exits with a non-zero status. 9 | set -u # Treat unset variables as an error. 10 | 11 | cp /defaults/passwd /etc/passwd 12 | cp /defaults/group /etc/group 13 | cp /defaults/shadow /etc/shadow 14 | chown root:shadow /etc/shadow 15 | chmod 640 /etc/shadow 16 | 17 | echo "$APP_USER:x:$USER_ID:$GROUP_ID::${APP_HOME:-/dev/null}:/sbin/nologin" >> /etc/passwd 18 | echo "$APP_USER:x:$GROUP_ID:" >> /etc/group 19 | 20 | # Make sure APP_HOME is editable by the user 21 | if [[ -n "$APP_HOME" ]] ; then 22 | chown -R "$APP_USER" "$APP_HOME" 23 | chmod -R u+rw "$APP_HOME" 24 | fi 25 | 26 | # vim:ft=sh:ts=4:sw=4:et:sts=4 27 | -------------------------------------------------------------------------------- /docker/rootfs/etc/muwire/MuWire.default.properties: -------------------------------------------------------------------------------- 1 | #This file is UTF-8 2 | #Tue Jan 14 12:08:47 GMT 2020 3 | meshExpiration=60 4 | autoDownloadUpdate=true 5 | hostHopelessInterval=1440 6 | uploadSlotsPerUser=-1 7 | downloadLocation=/output 8 | allowTrustLists=true 9 | embeddedRouter=false 10 | incompleteLocation=/incompletes 11 | outBw=128 12 | searchExtraHop=false 13 | shareHiddenFiles=false 14 | advertiseChat=true 15 | totalUploadSlots=-1 16 | hostClearInterval=15 17 | searchComments=true 18 | downloadSequentialRatio=0.8 19 | maxChatConnectios=-1 20 | trustListInterval=1 21 | crawlerResponse=REGISTERED 22 | browseFiles=true 23 | lastUpdateCheck=1579003533112 24 | hostRejectInterval=1 25 | inBw=256 26 | leaf=false 27 | updateCheckInterval=24 28 | plugin=false 29 | downloadRetryInterval=60 30 | speedSmoothSeconds=60 31 | allowUntrusted=true 32 | shareDownloadedFiles=true 33 | startChatServer=false 34 | updateType=jar 35 | i2cpHost=172.17.0.1 36 | -------------------------------------------------------------------------------- /docker/rootfs/startapp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Explicitly define HOME otherwise it might not have been set 4 | export HOME=/muwire 5 | 6 | echo "Starting MuWire" 7 | exec /muwire/bin/MuWire 8 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group = com.muwire 2 | version = 0.8.13 3 | i2pVersion = 2.6.0 4 | groovyVersion = 3.0.9 5 | griffonVersion= 2.15.1 6 | slf4jVersion = 1.7.25 7 | spockVersion = 1.1-groovy-2.4 8 | grailsVersion=4.0.0 9 | gorm.version=7.0.2.RELEASE 10 | griffonEnv=prod 11 | 12 | # parallel build - disable this if on slow machine 13 | org.gradle.parallel=true 14 | 15 | # javac properties 16 | sourceCompatibility=1.8 17 | targetCompatibility=1.8 18 | compilerArgs=-Xlint:unchecked,cast,path,divzero,empty,path,finally,overrides 19 | 20 | # plugin properties 21 | author = zab@mail.i2p 22 | signer = zab@mail.i2p 23 | keystorePassword=changeit 24 | websiteURL=http://muwire.i2p 25 | updateURLsu3=http://muwire.i2p/MuWire-update.su3 26 | 27 | pack200=false 28 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gui/.lazybones/artifact-template-1.15.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/.lazybones/artifact-template-1.15.1.zip -------------------------------------------------------------------------------- /gui/.lazybones/stored-params.properties: -------------------------------------------------------------------------------- 1 | #Lazybones saved template parameters 2 | #Wed May 29 15:31:25 BST 2019 3 | package=com.muwire.gui 4 | version=0.0.1 5 | griffonVersion=2.15.1 6 | className=Gui 7 | group=com.muwire 8 | artifactId=gui 9 | -------------------------------------------------------------------------------- /gui/gradle/code-coverage.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'jacoco' 2 | 3 | jacoco { 4 | toolVersion = '0.7.9' 5 | } 6 | 7 | jacocoTestReport { 8 | group = 'Reporting' 9 | description = 'Generate Jacoco coverage reports after running tests.' 10 | additionalSourceDirs = project.files(sourceSets.main.allSource.srcDirs) 11 | sourceDirectories = project.files(sourceSets.main.allSource.srcDirs) 12 | classDirectories = project.files(sourceSets.main.output) 13 | reports { 14 | xml.enabled = true 15 | csv.enabled = false 16 | html.enabled = true 17 | } 18 | } -------------------------------------------------------------------------------- /gui/gradle/publishing.gradle: -------------------------------------------------------------------------------- 1 | 2 | jar { 3 | manifest { 4 | attributes( 5 | 'Built-By' : System.properties['user.name'], 6 | 'Build-Timestamp': new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(new Date()), 7 | 'Build-Revision' : versioning.info.commit, 8 | 'Created-By' : "Gradle ${gradle.gradleVersion}", 9 | 'Build-Jdk' : "${System.properties['java.version']} (${System.properties['java.vendor']} ${System.properties['java.vm.version']})", 10 | 'Build-OS' : "${System.properties['os.name']} ${System.properties['os.arch']} ${System.properties['os.version']}" 11 | ) 12 | } 13 | } -------------------------------------------------------------------------------- /gui/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gui/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/AdvancedSharingController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | import com.muwire.core.Core 10 | import com.muwire.core.files.directories.UISyncDirectoryEvent 11 | 12 | @ArtifactProviderFor(GriffonController) 13 | class AdvancedSharingController { 14 | @MVCMember @Nonnull 15 | AdvancedSharingModel model 16 | @MVCMember @Nonnull 17 | AdvancedSharingView view 18 | 19 | @ControllerAction 20 | void sync() { 21 | def wd = view.selectedWatchedDirectory() 22 | if (wd == null) 23 | return 24 | def event = new UISyncDirectoryEvent(directory : wd.directory) 25 | model.core.eventBus.publish(event) 26 | } 27 | 28 | @ControllerAction 29 | void close() { 30 | view.dialog.setVisible(false) 31 | } 32 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/CertificateControlController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | import com.muwire.core.filecert.Certificate 10 | 11 | @ArtifactProviderFor(GriffonController) 12 | class CertificateControlController { 13 | @MVCMember @Nonnull 14 | CertificateControlModel model 15 | @MVCMember @Nonnull 16 | CertificateControlView view 17 | 18 | @ControllerAction 19 | void showComment() { 20 | Certificate cert = view.getSelectedSertificate() 21 | if (cert == null || cert.comment == null) 22 | return 23 | 24 | def params = [:] 25 | params['text'] = cert.comment.name 26 | mvcGroup.createMVCGroup("show-comment", params).destroy() 27 | } 28 | 29 | @ControllerAction 30 | void close() { 31 | view.dialog.setVisible(false) 32 | } 33 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/CertificateWarningController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class CertificateWarningController { 11 | @MVCMember @Nonnull 12 | CertificateWarningView view 13 | 14 | UISettings settings 15 | File home 16 | 17 | @ControllerAction 18 | void dismiss() { 19 | if (view.checkbox.model.isSelected()) { 20 | settings.certificateWarning = false 21 | File propsFile = new File(home, "gui.properties") 22 | propsFile.withOutputStream { settings.write(it) } 23 | } 24 | view.dialog.setVisible(false) 25 | } 26 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/ChatMonitorController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class ChatMonitorController { 11 | @MVCMember @Nonnull 12 | ChatMonitorView view 13 | 14 | @ControllerAction 15 | void close() { 16 | view.window.setVisible(false) 17 | mvcGroup.destroy() 18 | } 19 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/CollectionWarningController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class CollectionWarningController { 11 | @MVCMember @Nonnull 12 | CollectionWarningModel model 13 | @MVCMember @Nonnull 14 | CollectionWarningView view 15 | 16 | @ControllerAction 17 | void unshare() { 18 | model.answer[0] = true 19 | 20 | if (view.rememberCheckbox.model.isSelected()) { 21 | model.settings.collectionWarning = false 22 | File propsFile = new File(model.home, "gui.properties") 23 | propsFile.withOutputStream { 24 | model.settings.write(it) 25 | } 26 | } 27 | 28 | cancel() 29 | } 30 | 31 | @ControllerAction 32 | void cancel() { 33 | view.dialog.setVisible(false) 34 | } 35 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/CollectionsToolController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import net.i2p.data.Base64 8 | 9 | import java.awt.Toolkit 10 | import java.awt.datatransfer.StringSelection 11 | 12 | import javax.annotation.Nonnull 13 | 14 | import com.muwire.core.SharedFile 15 | import com.muwire.core.collections.FileCollection 16 | import com.muwire.core.collections.UICollectionDeletedEvent 17 | import com.muwire.core.util.DataUtil 18 | 19 | @ArtifactProviderFor(GriffonController) 20 | class CollectionsToolController { 21 | @MVCMember @Nonnull 22 | CollectionsToolView view 23 | @MVCMember @Nonnull 24 | CollectionsToolModel model 25 | 26 | @ControllerAction 27 | void clearHits() { 28 | model.collection.hits.clear() 29 | model.hits.clear() 30 | view.hitsTable.model.fireTableDataChanged() 31 | } 32 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/DownloadPreviewController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class DownloadPreviewController { 11 | @MVCMember @Nonnull 12 | DownloadPreviewModel model 13 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/EventListController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class EventListController { 11 | @MVCMember @Nonnull 12 | EventListModel model 13 | 14 | @ControllerAction 15 | void click() { 16 | model.clickCount++ 17 | } 18 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/FeedConfigurationController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | import com.muwire.core.filefeeds.UIFeedConfigurationEvent 10 | 11 | @ArtifactProviderFor(GriffonController) 12 | class FeedConfigurationController { 13 | @MVCMember @Nonnull 14 | FeedConfigurationModel model 15 | @MVCMember @Nonnull 16 | FeedConfigurationView view 17 | 18 | @ControllerAction 19 | void save() { 20 | 21 | model.feed.setAutoDownload(view.autoDownloadCheckbox.model.isSelected()) 22 | model.feed.setSequential(view.sequentialCheckbox.model.isSelected()) 23 | model.feed.setItemsToKeep(Integer.parseInt(view.itemsToKeepField.text)) 24 | model.feed.setUpdateInterval(Long.parseLong(view.updateIntervalField.text) * 60000) 25 | 26 | model.core.eventBus.publish(new UIFeedConfigurationEvent(feed : model.feed)) 27 | 28 | cancel() 29 | } 30 | 31 | @ControllerAction 32 | void cancel() { 33 | view.dialog.setVisible(false) 34 | } 35 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/LibrarySyncController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | 8 | import javax.annotation.Nonnull 9 | 10 | @ArtifactProviderFor(GriffonController) 11 | class LibrarySyncController { 12 | 13 | @MVCMember @Nonnull 14 | LibrarySyncModel model 15 | @MVCMember @Nonnull 16 | LibrarySyncView view 17 | 18 | 19 | @ControllerAction 20 | void cancelScan() { 21 | model.cancelScan() 22 | view.scanCancelled() 23 | } 24 | 25 | @ControllerAction 26 | void cancel() { 27 | view.previewCancelled() 28 | } 29 | 30 | @ControllerAction 31 | void reindex() { 32 | view.startReindex() 33 | model.startReindex() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/MyFeedController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.SharedFile 4 | import com.muwire.core.filefeeds.UIFileUnpublishedEvent 5 | import griffon.core.artifact.GriffonController 6 | import griffon.core.controller.ControllerAction 7 | import griffon.inject.MVCMember 8 | import griffon.metadata.ArtifactProviderFor 9 | import javax.annotation.Nonnull 10 | 11 | @ArtifactProviderFor(GriffonController) 12 | class MyFeedController { 13 | @MVCMember @Nonnull 14 | MyFeedModel model 15 | @MVCMember @Nonnull 16 | MyFeedView view 17 | 18 | @ControllerAction 19 | void unpublish() { 20 | List toUnpublish = view.selectedItems() 21 | if (toUnpublish == null) 22 | return 23 | toUnpublish.each { 24 | it.unpublish() 25 | UIFileUnpublishedEvent event = new UIFileUnpublishedEvent(sf: it) 26 | model.core.getEventBus().publish(event) 27 | } 28 | model.items.removeAll(toUnpublish) 29 | model.itemsCount = model.items.size() 30 | view.refreshItemsTable() 31 | } 32 | 33 | @ControllerAction 34 | void close() { 35 | view.dialog.setVisible(false) 36 | } 37 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/PublishPreviewController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.SharedFile 4 | import com.muwire.core.filefeeds.UIFilePublishedEvent 5 | import griffon.core.artifact.GriffonController 6 | import griffon.core.controller.ControllerAction 7 | import griffon.inject.MVCMember 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | import javax.annotation.Nonnull 11 | 12 | @ArtifactProviderFor(GriffonController) 13 | class PublishPreviewController { 14 | 15 | @MVCMember @Nonnull 16 | PublishPreviewModel model 17 | @MVCMember @Nonnull 18 | PublishPreviewView view 19 | 20 | @ControllerAction 21 | void publish() { 22 | final long now = System.currentTimeMillis() 23 | for (SharedFile sf : model.toPublish) { 24 | sf.publish(now) 25 | model.core.eventBus.publish(new UIFilePublishedEvent(sf: sf)) 26 | } 27 | cancel() 28 | } 29 | 30 | @ControllerAction 31 | void cancel() { 32 | view.dialog.setVisible(false) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/SharedFileController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | import com.muwire.core.filecert.Certificate 10 | 11 | @ArtifactProviderFor(GriffonController) 12 | class SharedFileController { 13 | @MVCMember @Nonnull 14 | SharedFileView view 15 | @MVCMember @Nonnull 16 | SharedFileModel model 17 | 18 | @ControllerAction 19 | void showComment() { 20 | Certificate cert = view.getSelectedCertificate() 21 | if (cert == null || cert.comment == null) 22 | return 23 | 24 | def params = [:] 25 | params['text'] = cert.comment.name 26 | mvcGroup.createMVCGroup('show-comment',params).destroy() 27 | } 28 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/ShowCommentController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class ShowCommentController { 11 | @MVCMember @Nonnull 12 | ShowCommentView view 13 | 14 | @ControllerAction 15 | void dismiss() { 16 | view.dialog.setVisible(false) 17 | } 18 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/ShutdownWindowController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class ShutdownWindowController { 11 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/SystemStatusController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | import javax.annotation.Nonnull 8 | 9 | @ArtifactProviderFor(GriffonController) 10 | class SystemStatusController { 11 | @MVCMember @Nonnull 12 | SystemStatusModel model 13 | @MVCMember @Nonnull 14 | SystemStatusView view 15 | 16 | @ControllerAction 17 | void refresh() { 18 | 19 | long totalRam = Runtime.getRuntime().totalMemory() 20 | long usedRam = totalRam - Runtime.getRuntime().freeMemory() 21 | 22 | model.usedRam = usedRam 23 | model.totalRam = totalRam 24 | model.maxRam = Runtime.getRuntime().maxMemory() 25 | model.javaVendor = System.getProperty("java.vendor") 26 | model.javaVersion = System.getProperty("java.version") 27 | } 28 | 29 | @ControllerAction 30 | void close() { 31 | view.dialog.setVisible(false) 32 | } 33 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/TrustListController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.profile.MWProfileHeader 5 | import com.muwire.gui.profile.PersonaOrProfile 6 | import com.muwire.gui.profile.TrustPOP 7 | import com.muwire.gui.profile.ViewProfileHelper 8 | import griffon.core.artifact.GriffonController 9 | import griffon.core.controller.ControllerAction 10 | import griffon.inject.MVCMember 11 | import griffon.metadata.ArtifactProviderFor 12 | import javax.annotation.Nonnull 13 | import javax.swing.JOptionPane 14 | 15 | import com.muwire.core.EventBus 16 | import com.muwire.core.Persona 17 | import com.muwire.core.trust.TrustEvent 18 | import com.muwire.core.trust.TrustLevel 19 | 20 | @ArtifactProviderFor(GriffonController) 21 | class TrustListController { 22 | @MVCMember @Nonnull 23 | TrustListModel model 24 | @MVCMember @Nonnull 25 | TrustListView view 26 | 27 | Core core 28 | 29 | @ControllerAction 30 | void viewProfile() { 31 | int selectedRow = view.getSelectedRow() 32 | if (selectedRow < 0) 33 | return 34 | 35 | PersonaOrProfile pop = model.contacts[selectedRow] 36 | ViewProfileHelper.initViewProfileGroup(core, mvcGroup, pop) 37 | } 38 | 39 | @ControllerAction 40 | void close() { 41 | view.window.setVisible(false) 42 | mvcGroup.destroy() 43 | } 44 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/UpdateController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.RestartEvent 4 | import griffon.core.artifact.GriffonController 5 | import griffon.core.controller.ControllerAction 6 | import griffon.inject.MVCMember 7 | import griffon.metadata.ArtifactProviderFor 8 | import javax.annotation.Nonnull 9 | 10 | @ArtifactProviderFor(GriffonController) 11 | class UpdateController { 12 | @MVCMember @Nonnull 13 | UpdateView view 14 | @MVCMember @Nonnull 15 | UpdateModel model 16 | 17 | @ControllerAction 18 | void close() { 19 | view.dialog.setVisible(false) 20 | } 21 | 22 | @ControllerAction 23 | void restart() { 24 | model.core.eventBus.publish(new RestartEvent()) 25 | close() 26 | } 27 | 28 | @ControllerAction 29 | void search() { 30 | mvcGroup.parentGroup.controller.search(model.available.infoHash, "MuWire update") 31 | close() 32 | } 33 | } -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/contacts/ContactSelectorController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.contacts 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.metadata.ArtifactProviderFor 5 | 6 | @ArtifactProviderFor(GriffonController) 7 | class ContactSelectorController { 8 | } 9 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/resultdetails/CertificateListController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.resultdetails 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.metadata.ArtifactProviderFor 5 | 6 | @ArtifactProviderFor(GriffonController) 7 | class CertificateListController { 8 | } 9 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/resultdetails/CollectionListController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.resultdetails 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.metadata.ArtifactProviderFor 5 | 6 | @ArtifactProviderFor(GriffonController) 7 | class CollectionListController { 8 | } 9 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/resultdetails/ResultDetailsFrameController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.resultdetails 2 | 3 | import griffon.core.artifact.GriffonController 4 | import griffon.core.controller.ControllerAction 5 | import griffon.inject.MVCMember 6 | import griffon.metadata.ArtifactProviderFor 7 | 8 | import javax.annotation.Nonnull 9 | 10 | @ArtifactProviderFor(GriffonController) 11 | class ResultDetailsFrameController { 12 | @MVCMember @Nonnull 13 | ResultDetailsFrameView view 14 | 15 | @ControllerAction 16 | void close() { 17 | view.window.setVisible(false) 18 | mvcGroup.destroy() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gui/griffon-app/controllers/com/muwire/gui/tools/RuleWizardController.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.tools 2 | 3 | import com.muwire.core.content.ContentControlEvent 4 | import griffon.core.artifact.GriffonController 5 | import griffon.core.controller.ControllerAction 6 | import griffon.inject.MVCMember 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | import javax.annotation.Nonnull 10 | 11 | @ArtifactProviderFor(GriffonController) 12 | class RuleWizardController { 13 | @MVCMember @Nonnull 14 | RuleWizardModel model 15 | @MVCMember @Nonnull 16 | RuleWizardView view 17 | 18 | @ControllerAction 19 | void save() { 20 | def event = new ContentControlEvent(add: true, 21 | term: view.termField.text, 22 | name: view.nameField.text, 23 | regex: model.regex, 24 | action: model.action) 25 | model.core.eventBus.publish(event) 26 | cancel() 27 | } 28 | 29 | @ControllerAction 30 | void cancel() { 31 | view.dialog.setVisible(false) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gui/griffon-app/lifecycle/Shutdown.groovy: -------------------------------------------------------------------------------- 1 | 2 | import javax.annotation.Nonnull 3 | import javax.inject.Inject 4 | 5 | import org.codehaus.griffon.runtime.core.AbstractLifecycleHandler 6 | 7 | import com.muwire.core.Core 8 | 9 | import griffon.core.GriffonApplication 10 | import groovy.util.logging.Log 11 | 12 | @Log 13 | class Shutdown extends AbstractLifecycleHandler { 14 | @Inject 15 | Shutdown(@Nonnull GriffonApplication application) { 16 | super(application) 17 | } 18 | 19 | @Override 20 | void execute() { 21 | log.info("shutting down from lifecycle") 22 | Core core = application.context.get("core") 23 | core?.shutdown() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/AddCommentModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.SharedFile 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class AddCommentModel { 11 | List selectedFiles 12 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/AddContactModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class AddContactModel { 11 | Core core 12 | @Observable boolean trusted 13 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/CertificateControlModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class CertificateControlModel { 11 | def users = [] 12 | def certificates = [] 13 | 14 | Core core 15 | 16 | @Observable boolean showCommentActionEnabled 17 | 18 | void mvcGroupInit(Map args) { 19 | users.addAll(core.certificateManager.byIssuer.keySet()) 20 | } 21 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/CertificateWarningModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonModel 4 | import griffon.transform.Observable 5 | import griffon.metadata.ArtifactProviderFor 6 | 7 | @ArtifactProviderFor(GriffonModel) 8 | class CertificateWarningModel { 9 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/CloseWarningModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.annotation.Nonnull 4 | 5 | import griffon.core.artifact.GriffonController 6 | import griffon.core.artifact.GriffonModel 7 | import griffon.core.controller.ControllerAction 8 | import griffon.inject.MVCMember 9 | import griffon.metadata.ArtifactProviderFor 10 | import griffon.transform.Observable 11 | 12 | import javax.annotation.Nonnull 13 | 14 | @ArtifactProviderFor(GriffonModel) 15 | class CloseWarningModel { 16 | @Observable boolean closeWarning 17 | @Observable boolean exitOnClose 18 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/CollectionWarningModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.collections.FileCollection 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class CollectionWarningModel { 11 | String[] collections 12 | String fileName 13 | boolean [] answer 14 | UISettings settings 15 | File home 16 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/CollectionsToolModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.EventBus 4 | import com.muwire.core.SharedFile 5 | import com.muwire.core.collections.CollectionManager 6 | import com.muwire.core.collections.FileCollection 7 | import com.muwire.core.files.FileManager 8 | 9 | import griffon.core.artifact.GriffonModel 10 | import griffon.transform.Observable 11 | import griffon.metadata.ArtifactProviderFor 12 | 13 | @ArtifactProviderFor(GriffonModel) 14 | class CollectionsToolModel { 15 | FileCollection collection 16 | List hits = new ArrayList<>() 17 | 18 | void mvcGroupInit(Map args) { 19 | hits.addAll(collection.hits) 20 | } 21 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/DownloadPreviewModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.download.Downloader 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class DownloadPreviewModel { 11 | Downloader downloader 12 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/EventListModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.annotation.Nonnull 4 | import javax.inject.Inject 5 | import javax.inject.Named 6 | 7 | import com.muwire.core.Core 8 | 9 | import griffon.core.artifact.GriffonModel 10 | import griffon.core.GriffonApplication 11 | import griffon.inject.Contextual 12 | import griffon.inject.MVCMember 13 | import griffon.transform.Observable 14 | import griffon.metadata.ArtifactProviderFor 15 | 16 | @ArtifactProviderFor(GriffonModel) 17 | class EventListModel { 18 | @Inject @Nonnull GriffonApplication application 19 | @Observable boolean coreInitialized = false 20 | 21 | void mvcGroupInit(Map args) { 22 | application.addPropertyChangeListener("core", {e -> 23 | coreInitialized = (e.getNewValue() != null) 24 | }) 25 | } 26 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/FeedConfigurationModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.filefeeds.Feed 5 | 6 | import griffon.core.artifact.GriffonModel 7 | import griffon.transform.Observable 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class FeedConfigurationModel { 12 | Core core 13 | Feed feed 14 | 15 | @Observable boolean autoDownload 16 | @Observable boolean sequential 17 | @Observable int updateInterval 18 | @Observable int itemsToKeep 19 | 20 | void mvcGroupInit(Map args) { 21 | autoDownload = feed.isAutoDownload() 22 | sequential = feed.isSequential() 23 | updateInterval = feed.getUpdateInterval() / 60000 24 | itemsToKeep = feed.getItemsToKeep() 25 | } 26 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/FetchCertificatesModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.InfoHash 4 | import com.muwire.core.Persona 5 | import com.muwire.core.filecert.CertificateFetchStatus 6 | import com.muwire.core.filefeeds.FeedItem 7 | import com.muwire.core.search.UIResultEvent 8 | 9 | import griffon.core.artifact.GriffonModel 10 | import griffon.transform.Observable 11 | import griffon.metadata.ArtifactProviderFor 12 | 13 | @ArtifactProviderFor(GriffonModel) 14 | class FetchCertificatesModel { 15 | Persona host 16 | InfoHash infoHash 17 | String name 18 | 19 | @Observable CertificateFetchStatus status 20 | @Observable int totalCertificates 21 | @Observable int certificateCount 22 | 23 | @Observable boolean importActionEnabled 24 | @Observable boolean showCommentActionEnabled 25 | 26 | def certificates = [] 27 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/I2PStatusModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.annotation.Nonnull 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.inject.MVCMember 7 | import griffon.transform.Observable 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class I2PStatusModel { 12 | @MVCMember @Nonnull 13 | I2PStatusController controller 14 | 15 | @Observable int ntcpConnections 16 | @Observable int ssuConnections 17 | @Observable String networkStatus 18 | @Observable boolean floodfill 19 | @Observable String myCountry 20 | @Observable boolean strictCountry 21 | @Observable int participatingTunnels 22 | @Observable int activePeers 23 | @Observable int receiveBps 24 | @Observable int sendBps 25 | @Observable int participatingBW 26 | 27 | void mvcGroupInit(Map args) { 28 | controller.refresh() 29 | } 30 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/MuWireStatusModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.annotation.Nonnull 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.inject.MVCMember 7 | import griffon.transform.Observable 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class MuWireStatusModel { 12 | 13 | @MVCMember @Nonnull 14 | MuWireStatusController controller 15 | 16 | @Observable int incomingConnections 17 | @Observable int outgoingConnections 18 | @Observable int knownHosts 19 | @Observable int failingHosts 20 | @Observable int hopelessHosts 21 | @Observable int sharedFiles 22 | @Observable int downloads 23 | @Observable int browsed 24 | 25 | void mvcGroupInit(Map args) { 26 | controller.refresh() 27 | } 28 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/MyFeedModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.SharedFile 4 | 5 | import javax.annotation.Nonnull 6 | 7 | import com.muwire.core.Core 8 | 9 | import griffon.core.artifact.GriffonModel 10 | import griffon.inject.MVCMember 11 | import griffon.transform.Observable 12 | import griffon.metadata.ArtifactProviderFor 13 | 14 | @ArtifactProviderFor(GriffonModel) 15 | class MyFeedModel { 16 | 17 | @MVCMember @Nonnull 18 | MyFeedView view 19 | 20 | List items = [] 21 | 22 | Core core 23 | 24 | @Observable boolean unpublishActionEnabled 25 | @Observable int itemsCount 26 | 27 | void mvcGroupInit(Map map) { 28 | items.addAll(core.getFileManager().getPublishedSince(0)) 29 | itemsCount = items.size() 30 | } 31 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/PublishPreviewModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.SharedFile 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.metadata.ArtifactProviderFor 7 | 8 | import java.util.function.Predicate 9 | import java.util.stream.Collectors 10 | import java.util.stream.Stream 11 | 12 | @ArtifactProviderFor(GriffonModel) 13 | class PublishPreviewModel { 14 | 15 | 16 | Core core 17 | List requested 18 | 19 | SharedFile[] toPublish, alreadyPublished 20 | 21 | void mvcGroupInit(Map attributes) { 22 | Stream stream = requested.stream() 23 | if (requested.size() > 1000) 24 | stream = stream.parallel() 25 | def map = stream. 26 | collect(Collectors.partitioningBy({it.isPublished()} as Predicate)) 27 | toPublish = map.get(false).toArray(new SharedFile[0]) 28 | alreadyPublished = map.get(true).toArray(new SharedFile[0]) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/SharedFileModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.InfoHash 5 | import com.muwire.core.SharedFile 6 | 7 | import griffon.core.artifact.GriffonModel 8 | import griffon.transform.Observable 9 | import griffon.metadata.ArtifactProviderFor 10 | 11 | @ArtifactProviderFor(GriffonModel) 12 | class SharedFileModel { 13 | SharedFile sf 14 | Core core 15 | 16 | def searchers = [] 17 | def downloaders = [] 18 | def certificates = [] 19 | 20 | @Observable boolean showCommentActionEnabled 21 | 22 | public void mvcGroupInit(Map args) { 23 | searchers.addAll(sf.getSearches()) 24 | downloaders.addAll(sf.getDownloaders()) 25 | certificates.addAll(core.certificateManager.byInfoHash.getOrDefault(new InfoHash(sf.getRoot()),[])) 26 | } 27 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/ShowCommentModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.search.UIResultEvent 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.transform.Observable 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class ShowCommentModel { 11 | String name 12 | String text 13 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/ShutdownWindowModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonModel 4 | import griffon.transform.Observable 5 | import griffon.metadata.ArtifactProviderFor 6 | 7 | @ArtifactProviderFor(GriffonModel) 8 | class ShutdownWindowModel { 9 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/SignModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.artifact.GriffonModel 4 | import griffon.transform.Observable 5 | import griffon.metadata.ArtifactProviderFor 6 | 7 | @ArtifactProviderFor(GriffonModel) 8 | class SignModel { 9 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/SystemStatusModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.annotation.Nonnull 4 | 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.inject.MVCMember 7 | import griffon.transform.Observable 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class SystemStatusModel { 12 | @MVCMember @Nonnull 13 | SystemStatusController controller 14 | 15 | @Observable String javaVendor 16 | @Observable String javaVersion 17 | @Observable long usedRam 18 | @Observable long totalRam 19 | @Observable long maxRam 20 | 21 | void mvcGroupInit(Map args) { 22 | controller.refresh() 23 | } 24 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/TrustListModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.trust.RemoteTrustList 4 | import com.muwire.core.trust.TrustLevel 5 | import com.muwire.core.trust.TrustService 6 | import com.muwire.core.trust.TrustService.TrustEntry 7 | import com.muwire.gui.profile.TrustPOP 8 | import griffon.core.artifact.GriffonModel 9 | import griffon.transform.Observable 10 | import griffon.metadata.ArtifactProviderFor 11 | 12 | @ArtifactProviderFor(GriffonModel) 13 | class TrustListModel { 14 | RemoteTrustList trustList 15 | TrustService trustService 16 | 17 | List contacts 18 | 19 | void mvcGroupInit(Map args) { 20 | contacts = trustList.good.collect {new RemoteTrustPOP(it, TrustLevel.TRUSTED)} 21 | contacts.addAll(trustList.bad.collect {new RemoteTrustPOP(it, TrustLevel.DISTRUSTED)}) 22 | } 23 | 24 | private static class RemoteTrustPOP extends TrustPOP { 25 | final TrustLevel level 26 | RemoteTrustPOP(TrustEntry entry, TrustLevel level) { 27 | super(entry) 28 | this.level = level 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/UpdateModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.update.UpdateAvailableEvent 5 | import com.muwire.core.update.UpdateDownloadedEvent 6 | 7 | import griffon.core.artifact.GriffonModel 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class UpdateModel { 12 | Core core 13 | UpdateAvailableEvent available 14 | UpdateDownloadedEvent downloaded 15 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/WatchedDirectoryModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.Persona 5 | import com.muwire.core.files.directories.Visibility 6 | import com.muwire.core.files.directories.WatchedDirectory 7 | import com.muwire.gui.profile.PersonaOrProfile 8 | import com.muwire.gui.profile.PersonaPOP 9 | import com.muwire.gui.profile.ProfileHeaderPOP 10 | import griffon.core.artifact.GriffonModel 11 | import griffon.transform.Observable 12 | import griffon.metadata.ArtifactProviderFor 13 | 14 | @ArtifactProviderFor(GriffonModel) 15 | class WatchedDirectoryModel { 16 | Core core 17 | WatchedDirectory directory 18 | 19 | @Observable boolean autoWatch 20 | @Observable int syncInterval 21 | @Observable Visibility visibility 22 | Set allowedContacts = new HashSet<>() 23 | 24 | void mvcGroupInit(Map args) { 25 | autoWatch = directory.autoWatch 26 | syncInterval = directory.syncInterval 27 | visibility = directory.visibility 28 | if (directory.customVisibilityHeaders != null) 29 | allowedContacts.addAll(directory.customVisibilityHeaders.collect {new ProfileHeaderPOP(it)}) 30 | if (directory.customVisibility != null) 31 | allowedContacts.addAll(directory.customVisibility.collect {new PersonaPOP(it)}) 32 | } 33 | } -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/chat/ChatFavoritesModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.chat 2 | 3 | import griffon.core.artifact.GriffonModel 4 | import griffon.metadata.ArtifactProviderFor 5 | 6 | @ArtifactProviderFor(GriffonModel) 7 | class ChatFavoritesModel { 8 | 9 | ChatFavorites chatFavorites 10 | } 11 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/contacts/ContactSelectorModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.contacts 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.Persona 5 | import com.muwire.gui.profile.PersonaOrProfile 6 | import com.muwire.gui.profile.PersonaPOP 7 | import griffon.core.artifact.GriffonModel 8 | import griffon.inject.MVCMember 9 | import griffon.metadata.ArtifactProviderFor 10 | 11 | import javax.annotation.Nonnull 12 | import javax.swing.Icon 13 | 14 | @ArtifactProviderFor(GriffonModel) 15 | class ContactSelectorModel { 16 | Core core 17 | Set contacts 18 | Set contactsPOP 19 | 20 | Set allContacts = new HashSet<>() 21 | 22 | void mvcGroupInit(Map args) { 23 | if (contacts != null) { 24 | contacts.each {allContacts.add(new PersonaPOP(it))} 25 | } 26 | if (contactsPOP != null) { 27 | allContacts.addAll(contactsPOP) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/profile/EditProfileModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.profile.MWProfileImageFormat 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.inject.MVCMember 7 | import griffon.metadata.ArtifactProviderFor 8 | 9 | import javax.annotation.Nonnull 10 | 11 | @ArtifactProviderFor(GriffonModel) 12 | class EditProfileModel { 13 | @MVCMember @Nonnull 14 | EditProfileView view 15 | @MVCMember @Nonnull 16 | EditProfileController controller 17 | 18 | Core core 19 | byte [] imageData, thumbnailData 20 | MWProfileImageFormat format 21 | } 22 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/resultdetails/ResultDetailsFrameModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.resultdetails 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.Persona 5 | import com.muwire.core.search.UIResultEvent 6 | import com.muwire.gui.profile.PersonaOrProfile 7 | import griffon.core.artifact.GriffonModel 8 | import griffon.metadata.ArtifactProviderFor 9 | 10 | @ArtifactProviderFor(GriffonModel) 11 | class ResultDetailsFrameModel { 12 | 13 | Core core 14 | UIResultEvent resultEvent 15 | Collection senders 16 | String uuid 17 | } 18 | -------------------------------------------------------------------------------- /gui/griffon-app/models/com/muwire/gui/tools/RuleWizardModel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.tools 2 | 3 | import com.muwire.core.Core 4 | import com.muwire.core.content.MatchAction 5 | import griffon.core.artifact.GriffonModel 6 | import griffon.metadata.ArtifactProviderFor 7 | import griffon.transform.Observable 8 | 9 | @ArtifactProviderFor(GriffonModel) 10 | class RuleWizardModel { 11 | Core core 12 | 13 | @Observable boolean regex 14 | @Observable MatchAction action = MatchAction.RECORD 15 | } 16 | -------------------------------------------------------------------------------- /gui/griffon-app/resources/MuWire-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/MuWire-128x128.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/MuWire-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/MuWire-16x16.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/MuWire-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/MuWire-32x32.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/MuWire-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/MuWire-48x48.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/MuWire-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/MuWire-64x64.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/application.properties: -------------------------------------------------------------------------------- 1 | application.name=MuWire 2 | 3 | # this version is for display purposes only 4 | application.version=0.8.14 5 | 6 | # set this to 0 if this is not a beta 7 | application.beta=2 8 | 9 | # this is the version the core gets initialized with 10 | application.coreVersion=0.8.13 11 | 12 | 13 | build.date=${build_date} 14 | build.time=${build_time} 15 | build.revision=${build_revision} 16 | -------------------------------------------------------------------------------- /gui/griffon-app/resources/close_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/close_tab.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/comment.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/connections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/connections.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/copy.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/distrusted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/distrusted.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/down_arrow.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/edit_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/edit_profile.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/email.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/griffon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/griffon.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/i2plogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/i2plogo.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/neutral.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/outbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/outbox.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/resources.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/resources.properties -------------------------------------------------------------------------------- /gui/griffon-app/resources/restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/restart.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/search.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/trusted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/trusted.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/up_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/up_arrow.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/update.png -------------------------------------------------------------------------------- /gui/griffon-app/resources/yes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/gui/griffon-app/resources/yes.png -------------------------------------------------------------------------------- /gui/shadow/services/griffon.core.injection.Module: -------------------------------------------------------------------------------- 1 | # Generated by org.kordamp.jipsy.processor.service.ServiceProviderProcessor (0.4.1) 2 | # Tue, 6 Nov 2018 14:18:28 +0100 3 | org.codehaus.griffon.runtime.swing.SwingBuilderModule 4 | # Generated by org.kordamp.jipsy.processor.service.ServiceProviderProcessor (0.4.1) 5 | # Tue, 6 Nov 2018 14:16:08 +0100 6 | org.codehaus.griffon.runtime.groovy.GroovyModule 7 | # Generated by org.kordamp.jipsy.processor.service.ServiceProviderProcessor (0.4.1) 8 | # Tue, 6 Nov 2018 14:16:01 +0100 9 | org.codehaus.griffon.runtime.swing.SwingModule 10 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/ContentPanelIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class ContentPanelIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/EventListIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class EventListIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/I2PStatusIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class I2PStatusIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/MainFrameIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class MainFrameIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/MuWireStatusIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class MuWireStatusIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/OptionsIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class OptionsIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/SearchTabIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class SearchTabIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/integration-test/groovy/com/muwire/gui/TrustListIntegrationTest.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import griffon.core.test.GriffonFestRule 4 | import org.fest.swing.fixture.FrameFixture 5 | import org.junit.Rule 6 | import org.junit.Test 7 | 8 | import static org.junit.Assert.fail 9 | 10 | class TrustListIntegrationTest { 11 | static { 12 | System.setProperty('griffon.swing.edt.violations.check', 'true') 13 | System.setProperty('griffon.swing.edt.hang.monitor', 'true') 14 | } 15 | 16 | @Rule 17 | public final GriffonFestRule fest = new GriffonFestRule() 18 | 19 | private FrameFixture window 20 | 21 | @Test 22 | void smokeTest() { 23 | fail('Not implemented yet!') 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/DateRenderer.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.swing.JComponent 4 | import javax.swing.JTable 5 | import javax.swing.table.DefaultTableCellRenderer 6 | 7 | import net.i2p.data.DataHelper 8 | import static com.muwire.gui.Translator.trans 9 | 10 | class DateRenderer extends DefaultTableCellRenderer { 11 | DateRenderer(){ 12 | setHorizontalAlignment(CENTER) 13 | } 14 | 15 | JComponent getTableCellRendererComponent(JTable table, Object value, 16 | boolean isSelected, boolean hasFocus, int row, int column) { 17 | super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column) 18 | if (value == null) 19 | return this 20 | Long l = (Long) value 21 | String formatted 22 | if (l == 0) 23 | formatted = trans("NEVER") 24 | else 25 | formatted = DataHelper.formatTime(l) 26 | setText(formatted) 27 | if (isSelected) { 28 | setForeground(table.getSelectionForeground()) 29 | setBackground(table.getSelectionBackground()) 30 | } else { 31 | setForeground(table.getForeground()) 32 | setBackground(table.getBackground()) 33 | } 34 | this 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/DownloadPreviewer.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import java.awt.Desktop 4 | 5 | import javax.swing.JDialog 6 | import javax.swing.JOptionPane 7 | import javax.swing.SwingWorker 8 | 9 | import com.muwire.core.download.Downloader 10 | 11 | class DownloadPreviewer extends SwingWorker { 12 | 13 | private final Downloader downloader 14 | private final DownloadPreviewView view 15 | 16 | DownloadPreviewer(Downloader downloader, DownloadPreviewView view) { 17 | this.downloader = downloader 18 | this.view = view 19 | } 20 | 21 | @Override 22 | protected Object doInBackground() throws Exception { 23 | downloader.generatePreview() 24 | } 25 | 26 | @Override 27 | public void done() { 28 | File previewFile = get() 29 | view.dialog.setVisible(false) 30 | if (previewFile == null) 31 | JOptionPane.showMessageDialog(null, "Generating preview file failed", "Preview Failed", JOptionPane.ERROR_MESSAGE) 32 | else { 33 | try { 34 | Desktop.getDesktop().open(previewFile) 35 | } catch (IOException ignore) {} 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/DownloaderComparator.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.download.Downloader 4 | 5 | class DownloaderComparator implements Comparator{ 6 | 7 | @Override 8 | public int compare(Downloader o1, Downloader o2) { 9 | double d1 = o1.donePieces().toDouble() / o1.getNPieces() 10 | double d2 = o2.donePieces().toDouble() / o2.getNPieces() 11 | return Double.compare(d1, d2); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/InterimTreeNode.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | class InterimTreeNode { 4 | private final File file 5 | private final String toString 6 | InterimTreeNode(File file) { 7 | this.file = file 8 | this.toString = HTMLSanitizer.sanitize(file.getName()) 9 | } 10 | 11 | public File getFile() { 12 | return file; 13 | } 14 | 15 | 16 | public int hashCode() { 17 | file.hashCode() 18 | } 19 | 20 | public boolean equals(Object o) { 21 | if (!(o instanceof InterimTreeNode)) 22 | return false 23 | file == o.file 24 | } 25 | 26 | public String toString() { 27 | toString 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/Launcher.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import java.util.logging.Level 4 | import java.util.logging.LogManager 5 | 6 | import griffon.swing.SwingGriffonApplication 7 | import groovy.util.logging.Log 8 | 9 | @Log 10 | class Launcher { 11 | 12 | public static void main(String[] args) { 13 | if (System.getProperty("java.util.logging.config.file") == null) { 14 | log.info("No config file specified, so turning off most logging") 15 | def names = LogManager.getLogManager().getLoggerNames() 16 | while(names.hasMoreElements()) { 17 | def name = names.nextElement() 18 | LogManager.getLogManager().getLogger(name).setLevel(Level.SEVERE) 19 | } 20 | } 21 | 22 | SwingGriffonApplication.main(args) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/MWMessageStatus.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Persona 4 | import com.muwire.core.messenger.MWMessage 5 | import com.muwire.core.profile.MWProfileHeader 6 | import com.muwire.gui.profile.PersonaOrProfile 7 | import com.muwire.gui.profile.ThumbnailIcon 8 | 9 | import javax.swing.Icon 10 | 11 | class MWMessageStatus implements PersonaOrProfile { 12 | final MWMessage message 13 | private final MWProfileHeader profileHeader 14 | private boolean status 15 | private Icon icon 16 | MWMessageStatus(MWMessage message, boolean status, MWProfileHeader profileHeader) { 17 | this.message = message 18 | this.status = status 19 | this.profileHeader = profileHeader 20 | } 21 | 22 | int hashCode() { 23 | message.hashCode() 24 | } 25 | 26 | boolean equals(Object o) { 27 | MWMessageStatus other = (MWMessageStatus) o 28 | message.equals(other.message) 29 | } 30 | 31 | @Override 32 | Persona getPersona() { 33 | message.getSender() 34 | } 35 | 36 | @Override 37 | Icon getThumbnail() { 38 | if (profileHeader == null) 39 | return null 40 | if (icon == null) 41 | icon = new ThumbnailIcon(profileHeader.getThumbNail()) 42 | return icon 43 | } 44 | 45 | @Override 46 | MWProfileHeader getHeader() { 47 | profileHeader 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/MWMessageTransferable.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.messenger.MWMessage 4 | 5 | /** 6 | * Encapsulates a message being dragged and dropped from a folder. 7 | */ 8 | class MWMessageTransferable { 9 | MWMessage message 10 | String from 11 | } 12 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/MWTransferable.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import java.awt.datatransfer.DataFlavor 4 | import java.awt.datatransfer.Transferable 5 | import java.awt.datatransfer.UnsupportedFlavorException 6 | 7 | class MWTransferable implements Transferable { 8 | private final List data 9 | MWTransferable(List data) { 10 | this.data = data 11 | } 12 | 13 | @Override 14 | public DataFlavor[] getTransferDataFlavors() { 15 | CopyPasteSupport.FLAVORS 16 | } 17 | 18 | @Override 19 | public boolean isDataFlavorSupported(DataFlavor flavor) { 20 | flavor == CopyPasteSupport.LIST_FLAVOR 21 | } 22 | 23 | @Override 24 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 25 | if (flavor != CopyPasteSupport.LIST_FLAVOR) { 26 | return null 27 | } 28 | return data 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/PersonaComparator.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.Persona 4 | 5 | import java.text.Collator 6 | 7 | class PersonaComparator implements Comparator{ 8 | @Override 9 | int compare(Persona a, Persona b) { 10 | return Collator.getInstance().compare(a.getHumanReadableName(), b.getHumanReadableName()) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/ResultAndTargets.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.search.UIResultEvent 4 | 5 | class ResultAndTargets { 6 | final UIResultEvent resultEvent 7 | final File target, parent 8 | ResultAndTargets(UIResultEvent resultEvent, File target, File parent) { 9 | this.resultEvent = resultEvent 10 | this.target = target 11 | this.parent = parent 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/SearchField.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import java.awt.event.KeyEvent 4 | 5 | import javax.swing.JComboBox 6 | 7 | class SearchField extends JComboBox { 8 | SearchField(SearchFieldModel model) { 9 | super() 10 | setEditable(true) 11 | setModel(model) 12 | setEditor(new SearchFieldEditor(model, this)) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/SharedFileNameComparator.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.SharedFile 4 | 5 | import java.text.Collator 6 | 7 | class SharedFileNameComparator implements Comparator{ 8 | 9 | @Override 10 | int compare(SharedFile o1, SharedFile o2) { 11 | String path1 = o1.getFile().getAbsolutePath() 12 | String path2 = o2.getFile().getAbsolutePath() 13 | return Collator.getInstance().compare(path1, path2) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/SizeFormatter.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import java.text.DecimalFormat 4 | import java.text.FieldPosition 5 | 6 | class SizeFormatter { 7 | 8 | private static final DecimalFormat fmt = new DecimalFormat("##0.##") 9 | 10 | static void format(long value, StringBuffer sb) { 11 | sb.setLength(0) 12 | if (value < 1024) { 13 | sb.append(value).append(' ') 14 | return 15 | } 16 | 17 | double val = value 18 | int scale = 0 19 | while(val >= 1024) { 20 | scale++ 21 | val /= 1024d 22 | } 23 | 24 | fmt.format(val,sb, new FieldPosition(0)) 25 | sb.append(' ') 26 | switch(scale) { 27 | case 1 : sb.append('K'); break; 28 | case 2 : sb.append('M'); break; 29 | case 3 : sb.append('G'); break; 30 | case 4 : sb.append('T'); break; 31 | case 5 : sb.append('P'); break; 32 | case 6 : sb.append('E'); break; 33 | case 7 : sb.append('Z'); break; 34 | case 8 : sb.append('Y'); break; 35 | default : 36 | sb.append(' ') 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/TreeExpansions.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import javax.swing.event.TreeExpansionEvent 4 | import javax.swing.event.TreeExpansionListener 5 | import javax.swing.tree.TreePath 6 | 7 | class TreeExpansions implements TreeExpansionListener { 8 | boolean manualExpansion 9 | final Set expandedPaths = new HashSet<>() 10 | 11 | 12 | @Override 13 | public void treeExpanded(TreeExpansionEvent event) { 14 | manualExpansion = true 15 | expandedPaths.add(event.getPath()) 16 | } 17 | 18 | @Override 19 | public void treeCollapsed(TreeExpansionEvent event) { 20 | manualExpansion = true 21 | expandedPaths.remove(event.getPath()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/UIResultEventComparator.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui 2 | 3 | import com.muwire.core.search.UIResultEvent 4 | 5 | import java.text.Collator 6 | 7 | class UIResultEventComparator implements Comparator{ 8 | 9 | private final boolean fullPath 10 | UIResultEventComparator(boolean fullPath) { 11 | this.fullPath = fullPath 12 | } 13 | 14 | @Override 15 | int compare(UIResultEvent o1, UIResultEvent o2) { 16 | String s1,s2 17 | if (fullPath) { 18 | s1 = o1.getFullPath() 19 | s2 = o2.getFullPath() 20 | } else { 21 | s1 = o1.getName() 22 | s2 = o2.getName() 23 | } 24 | return Collator.getInstance().compare(s1, s2) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/chat/ChatFavorite.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.chat 2 | 3 | import com.muwire.core.Persona 4 | 5 | class ChatFavorite { 6 | final Persona address 7 | boolean autoConnect 8 | 9 | ChatFavorite(Persona address, boolean autoConnect) { 10 | this.address = address 11 | this.autoConnect = autoConnect 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/chat/CollectionLinkLabel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.chat 2 | 3 | import com.muwire.gui.HTMLSanitizer 4 | import com.muwire.gui.SizeFormatter 5 | import com.muwire.gui.UISettings 6 | import com.muwire.core.mulinks.CollectionMuLink 7 | import static com.muwire.gui.Translator.trans 8 | 9 | class CollectionLinkLabel extends MuLinkLabel { 10 | CollectionLinkLabel(CollectionMuLink link, UISettings settings, boolean border) { 11 | super(link, settings, border) 12 | } 13 | 14 | @Override 15 | protected String getVisibleText() { 16 | CollectionMuLink link = (CollectionMuLink) this.link 17 | 18 | StringBuffer sb = new StringBuffer() 19 | SizeFormatter.format(link.totalSize, sb) 20 | 21 | return link.name + " (" + link.numFiles + " " + trans("FILES") + 22 | " " + sb.toString() + trans("BYTES_SHORT") + ")" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/chat/FileLinkLabel.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.chat 2 | 3 | import com.muwire.gui.HTMLSanitizer 4 | import com.muwire.gui.SizeFormatter 5 | import com.muwire.gui.UISettings 6 | import com.muwire.core.mulinks.FileMuLink 7 | 8 | import static com.muwire.gui.Translator.trans 9 | 10 | class FileLinkLabel extends MuLinkLabel { 11 | 12 | FileLinkLabel(FileMuLink link, UISettings settings, boolean border) { 13 | super(link, settings, border) 14 | } 15 | 16 | protected String getVisibleText() { 17 | FileMuLink link = (FileMuLink) this.link 18 | 19 | StringBuffer sb = new StringBuffer() 20 | SizeFormatter.format(link.fileSize, sb) 21 | 22 | link.name + " (" + sb.toString() + trans("BYTES_SHORT") + ")" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/contacts/ContactChooser.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.contacts 2 | 3 | import com.muwire.gui.UISettings 4 | import com.muwire.gui.profile.PersonaOrProfile 5 | import com.muwire.gui.profile.PersonaOrProfileCellRenderer 6 | 7 | import javax.swing.JComboBox 8 | import javax.swing.JTextField 9 | 10 | class ContactChooser extends JComboBox{ 11 | private final ContactChooserEditor chooserEditor 12 | private final ContactChooserModel chooserModel 13 | ContactChooser(UISettings settings, ContactChooserModel model) { 14 | setModel(model) 15 | this.chooserModel = model 16 | chooserEditor = new ContactChooserEditor(model, this, settings) 17 | setEditor(chooserEditor) 18 | setRenderer(new PersonaOrProfileListCellRenderer(settings)) 19 | setEditable(true) 20 | } 21 | 22 | void loadPOPs(Set pops) { 23 | pops.each {chooserEditor.textPane.insertPOP(it)} 24 | } 25 | 26 | Set getSelectedPOPs() { 27 | Set rv = chooserEditor.textPane.getSelectedPOPs() 28 | def lastPOP = chooserEditor.getItem() 29 | if (lastPOP == null) 30 | return rv 31 | lastPOP = chooserModel.findByName(lastPOP.toString().trim()) 32 | if (lastPOP != null) 33 | rv << lastPOP 34 | rv 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/AbstractPOP.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | /** 4 | * Implementations of this class are useful for storing 5 | * in collections 6 | */ 7 | abstract class AbstractPOP implements PersonaOrProfile { 8 | 9 | int hashCode() { 10 | getPersona().hashCode() 11 | } 12 | 13 | boolean equals(Object o) { 14 | if (!(o instanceof PersonaOrProfile)) 15 | return false 16 | getPersona() == o.getPersona() 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/PersonaOrProfileComparator.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import java.text.Collator 4 | 5 | class PersonaOrProfileComparator implements Comparator{ 6 | int compare(PersonaOrProfile a, PersonaOrProfile b) { 7 | Collator.getInstance().compare(a.getPersona().getHumanReadableName(), b.getPersona().getHumanReadableName()) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/PersonaPOP.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.Persona 4 | 5 | import javax.swing.Icon 6 | 7 | /** 8 | * Implementation of PersonaAndProfile when only 9 | * a Persona is available. 10 | */ 11 | class PersonaPOP extends AbstractPOP { 12 | final Persona persona 13 | PersonaPOP(Persona persona) { 14 | this.persona = persona 15 | } 16 | 17 | Persona getPersona() { 18 | persona 19 | } 20 | 21 | @Override 22 | Icon getThumbnail() { 23 | return null 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/ProfileHeaderPOP.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.profile.MWProfileHeader 4 | 5 | import javax.swing.Icon 6 | 7 | /** 8 | * Implementation of PersonaOrProfile when only a 9 | * profile header is available. 10 | */ 11 | class ProfileHeaderPOP extends AbstractPOP { 12 | private final MWProfileHeader header 13 | private Icon icon 14 | ProfileHeaderPOP(MWProfileHeader header) { 15 | this.header = header 16 | } 17 | 18 | @Override 19 | Icon getThumbnail() { 20 | if (icon == null) { 21 | icon = new ThumbnailIcon(header.getThumbNail()) 22 | } 23 | return icon 24 | } 25 | 26 | @Override 27 | MWProfileHeader getHeader() { 28 | return header 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/ResultPOP.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.Persona 4 | import com.muwire.core.profile.MWProfileHeader 5 | import com.muwire.core.search.UIResultEvent 6 | import com.muwire.gui.HTMLSanitizer 7 | 8 | import javax.swing.Icon 9 | 10 | class ResultPOP implements PersonaOrProfile { 11 | final UIResultEvent event 12 | private Icon thumbNail 13 | ResultPOP(UIResultEvent event) { 14 | this.event = event 15 | } 16 | 17 | @Override 18 | Persona getPersona() { 19 | return event.sender 20 | } 21 | 22 | @Override 23 | Icon getThumbnail() { 24 | if (event.profileHeader == null) 25 | return null 26 | if (thumbNail == null) { 27 | thumbNail = new ThumbnailIcon(event.profileHeader.getThumbNail()) 28 | } 29 | thumbNail 30 | } 31 | 32 | @Override 33 | MWProfileHeader getHeader() { 34 | return event.profileHeader 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/TrustPOP.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.Persona 4 | import com.muwire.core.profile.MWProfile 5 | import com.muwire.core.profile.MWProfileHeader 6 | import com.muwire.core.trust.TrustLevel 7 | import com.muwire.core.trust.TrustService.TrustEntry 8 | import com.muwire.gui.HTMLSanitizer 9 | 10 | import javax.swing.Icon 11 | 12 | class TrustPOP implements PersonaOrProfile { 13 | private final TrustEntry trustEntry 14 | private Icon icon 15 | TrustPOP(TrustEntry trustEntry) { 16 | this.trustEntry = trustEntry 17 | } 18 | 19 | public String getReason() { 20 | return trustEntry.getReason() 21 | } 22 | 23 | @Override 24 | Persona getPersona() { 25 | return trustEntry.getPersona() 26 | } 27 | 28 | @Override 29 | Icon getThumbnail() { 30 | MWProfileHeader header = getHeader() 31 | if (header == null) 32 | return null 33 | if (icon == null) 34 | icon = new ThumbnailIcon(header.getThumbNail()) 35 | return icon 36 | } 37 | 38 | @Override 39 | public MWProfileHeader getHeader() { 40 | trustEntry.getProfileHeader() 41 | } 42 | 43 | @Override 44 | public MWProfile getProfile() { 45 | trustEntry.getProfile() 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/profile/ViewProfileHelper.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile 2 | 3 | import com.muwire.core.Core 4 | import griffon.core.mvc.MVCGroup 5 | 6 | class ViewProfileHelper { 7 | 8 | static void initViewProfileGroup(Core core, MVCGroup group, PersonaOrProfile pop) { 9 | UUID uuid = UUID.randomUUID() 10 | def params = [:] 11 | params.core = core 12 | params.persona = pop.getPersona() 13 | params.uuid = uuid 14 | params.profileTitle = pop.getTitle() 15 | params.profileHeader = pop.getHeader() 16 | params.profile = pop.getProfile() 17 | 18 | group.createMVCGroup("view-profile", uuid.toString(), params) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/win/PrioritySetter.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.win 2 | 3 | import com.sun.jna.platform.win32.BaseTSD 4 | import com.sun.jna.platform.win32.WinDef 5 | import com.sun.jna.platform.win32.WinNT.HANDLE 6 | 7 | class PrioritySetter { 8 | private static final HANDLE myProcess; 9 | static { 10 | myProcess = MWKernel32.INSTANCE.GetCurrentProcess() 11 | } 12 | 13 | static void enterBackgroundMode() { 14 | // 1. set BELOW_NORMAL 15 | MWKernel32.INSTANCE.SetPriorityClass(myProcess, new WinDef.DWORD(0x00004000L)) 16 | // 2. enter background mode 17 | MWKernel32.INSTANCE.SetPriorityClass(myProcess, new WinDef.DWORD(0x00100000)) 18 | // 3. increase the process working set to something reasonable 19 | def sizeT = new BaseTSD.SIZE_T(0x1L << 29) // 512 MB 20 | MWKernel32.INSTANCE.SetProcessWorkingSetSizeEx(myProcess, sizeT, sizeT, new WinDef.DWORD(0x00000008L)) 21 | } 22 | 23 | static void exitBackgroundMode() { 24 | // 1. exit background mode 25 | MWKernel32.INSTANCE.SetPriorityClass(myProcess, new WinDef.DWORD(0x00200000L)) 26 | // 2. set priority to normal 27 | MWKernel32.INSTANCE.SetPriorityClass(myProcess, new WinDef.DWORD(0x00000020L)) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/wizard/LastStep.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.wizard 2 | 3 | import com.muwire.core.MuWireSettings 4 | import static com.muwire.gui.Translator.trans 5 | 6 | class LastStep extends WizardStep { 7 | 8 | private final boolean embeddedRouterAvailable 9 | 10 | public LastStep(boolean embeddedRouterAvailable) { 11 | super("last", null) 12 | this.embeddedRouterAvailable = embeddedRouterAvailable 13 | } 14 | 15 | @Override 16 | protected void buildUI(FactoryBuilderSupport builder, def nextAction) { 17 | builder.panel(constraints: getConstraint()) { 18 | gridBagLayout() 19 | label(text: trans("WIZARD_COMPLETE"), constraints : gbc(gridx: 0, gridy: 0)) 20 | if (embeddedRouterAvailable) 21 | label(text : trans("LAUNCH_EMBEDDED_ROUTER"), constraints: gbc(gridx:0, gridy:1)) 22 | } 23 | } 24 | 25 | @Override 26 | protected List validate() { 27 | return null 28 | } 29 | 30 | @Override 31 | protected void apply(MuWireSettings muSettings, Properties i2pSettings) { 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gui/src/main/groovy/com/muwire/gui/wizard/WizardStep.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.wizard 2 | 3 | import com.muwire.core.MuWireSettings 4 | 5 | abstract class WizardStep { 6 | 7 | final String constraint 8 | final WizardDefaults defaults 9 | 10 | protected WizardStep(String constraint, WizardDefaults defaults) { 11 | this.constraint = constraint 12 | this.defaults = defaults 13 | } 14 | 15 | 16 | protected abstract void buildUI(FactoryBuilderSupport builder, def nextAction) 17 | 18 | /** 19 | * @return list of errors, null if validation is successful 20 | */ 21 | protected abstract List validate() 22 | 23 | protected abstract void apply(MuWireSettings muSettings, Properties i2pSettings) 24 | } 25 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/HTMLSanitizer.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui; 2 | 3 | public class HTMLSanitizer { 4 | 5 | public static String sanitize(String s) { 6 | if (s == null) 7 | return null; 8 | StringBuilder sb = new StringBuilder(s.length() * 2 + 26); 9 | sb.append(""); 10 | sb.append(escape(s)); 11 | sb.append(""); 12 | return sb.toString(); 13 | } 14 | 15 | public static String escape(String s) { 16 | if (s == null) 17 | return null; 18 | StringBuilder sb = new StringBuilder(s.length() * 2); 19 | for (int i = 0; i < s.length(); i++) { 20 | char c = s.charAt(i); 21 | switch(c) { 22 | case '&': sb.append("&"); break; 23 | case '\"': sb.append("""); break; 24 | case '<' : sb.append("<"); break; 25 | case '>' : sb.append(">"); break; 26 | case ' ' : sb.append(" "); break; 27 | default : 28 | sb.append(c); 29 | } 30 | } 31 | return sb.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/profile/ImagePanel.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.image.BufferedImage; 6 | 7 | public class ImagePanel extends JPanel { 8 | private BufferedImage image; 9 | 10 | public void setImage(BufferedImage image) { 11 | this.image = image; 12 | } 13 | 14 | @Override 15 | public void paint(Graphics graphics) { 16 | super.paint(graphics); 17 | if (image == null) 18 | return; 19 | 20 | Dimension dim = getSize(); 21 | graphics.clearRect(0,0,(int)dim.getWidth(), (int)dim.getHeight()); 22 | graphics.drawImage(image, 23 | (int)(dim.getWidth() / 2) - (image.getWidth() / 2), 24 | (int)(dim.getHeight() / 2) - (image.getHeight() / 2), 25 | null); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/profile/ImageScaler.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile; 2 | 3 | import java.awt.geom.AffineTransform; 4 | import java.awt.image.AffineTransformOp; 5 | import java.awt.image.BufferedImage; 6 | 7 | public class ImageScaler { 8 | 9 | public static BufferedImage scaleToMax(BufferedImage source) { 10 | return scale(source, ProfileConstants.MAX_IMAGE_SIZE); 11 | } 12 | 13 | public static BufferedImage scaleToThumbnail(BufferedImage source) { 14 | return scale(source, ProfileConstants.MAX_THUMBNAIL_SIZE); 15 | } 16 | 17 | private static BufferedImage scale(BufferedImage source, int maxSize) { 18 | double scale = 1.0; 19 | int maxDim = Math.max(source.getHeight(), source.getWidth()); 20 | if (maxDim <= maxSize) 21 | return source; 22 | scale = maxSize * 1.0 / maxDim; 23 | 24 | BufferedImage rv = new BufferedImage((int)(source.getWidth() * scale), 25 | (int)(source.getHeight() * scale), 26 | BufferedImage.TYPE_INT_ARGB); 27 | AffineTransform at = new AffineTransform(); 28 | at.scale(scale, scale); 29 | AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 30 | rv = op.filter(source, rv); 31 | return rv; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/profile/PersonaOrProfile.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile; 2 | 3 | import com.muwire.core.Persona; 4 | import com.muwire.core.profile.MWProfile; 5 | import com.muwire.core.profile.MWProfileHeader; 6 | import com.muwire.gui.HTMLSanitizer; 7 | 8 | import javax.swing.*; 9 | 10 | public interface PersonaOrProfile { 11 | default Persona getPersona() {return getHeader().getPersona();} 12 | 13 | Icon getThumbnail(); 14 | 15 | default String getTitle() { 16 | return HTMLSanitizer.sanitize(getRawTitle()); 17 | } 18 | 19 | default String getRawTitle() { 20 | MWProfileHeader header = getHeader(); 21 | if (header == null) 22 | return null; 23 | return header.getTitle(); 24 | } 25 | 26 | default MWProfileHeader getHeader() { 27 | MWProfile profile = getProfile(); 28 | if (profile == null) 29 | return null; 30 | return profile.getHeader(); 31 | } 32 | 33 | 34 | default MWProfile getProfile() { return null; } 35 | } 36 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/profile/ProfileConstants.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile; 2 | 3 | public class ProfileConstants { 4 | public static final int MAX_IMAGE_SIZE = 512; 5 | public static final int MAX_THUMBNAIL_SIZE = 24; 6 | } 7 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/profile/ThumbnailIcon.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.profile; 2 | 3 | import javax.imageio.ImageIO; 4 | import javax.swing.*; 5 | import java.awt.*; 6 | import java.awt.image.BufferedImage; 7 | import java.io.ByteArrayInputStream; 8 | import java.io.IOException; 9 | 10 | public class ThumbnailIcon implements Icon { 11 | 12 | BufferedImage image; 13 | 14 | public ThumbnailIcon(byte [] rawData) throws IOException { 15 | BufferedImage img = ImageIO.read(new ByteArrayInputStream(rawData)); 16 | image = ImageScaler.scaleToThumbnail(img); 17 | } 18 | 19 | @Override 20 | public void paintIcon(Component c, Graphics g, int x, int y) { 21 | ((Graphics2D)g).drawImage(image, x, y, null); 22 | } 23 | 24 | @Override 25 | public int getIconWidth() { 26 | return image.getWidth(); 27 | } 28 | 29 | @Override 30 | public int getIconHeight() { 31 | return image.getHeight(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gui/src/main/java/com/muwire/gui/win/MWKernel32.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui.win; 2 | 3 | import com.sun.jna.Native; 4 | import com.sun.jna.platform.win32.BaseTSD; 5 | import com.sun.jna.platform.win32.WinDef; 6 | import com.sun.jna.platform.win32.WinNT; 7 | import com.sun.jna.win32.StdCallLibrary; 8 | import com.sun.jna.win32.W32APIOptions; 9 | 10 | public interface MWKernel32 extends StdCallLibrary { 11 | 12 | MWKernel32 INSTANCE = Native.load("kernel32", MWKernel32.class, W32APIOptions.DEFAULT_OPTIONS); 13 | 14 | WinDef.BOOL SetPriorityClass(WinNT.HANDLE hProcess, WinDef.DWORD mask); 15 | WinNT.HANDLE GetCurrentProcess(); 16 | 17 | WinDef.BOOL SetProcessWorkingSetSizeEx(WinNT.HANDLE hProcess, 18 | BaseTSD.SIZE_T minSize, 19 | BaseTSD.SIZE_T maxSize, 20 | WinDef.DWORD flags); 21 | } 22 | -------------------------------------------------------------------------------- /gui/src/main/java/org/freedesktop/GetServerInformationTuple.java: -------------------------------------------------------------------------------- 1 | package org.freedesktop; 2 | 3 | import org.freedesktop.dbus.Tuple; 4 | import org.freedesktop.dbus.annotations.Position; 5 | 6 | /** 7 | * Auto-generated class. 8 | */ 9 | public class GetServerInformationTuple extends Tuple { 10 | @Position(0) 11 | private String arg_0; 12 | @Position(1) 13 | private String arg_1; 14 | @Position(2) 15 | private String arg_2; 16 | @Position(3) 17 | private String arg_3; 18 | 19 | public GetServerInformationTuple(String arg_0, String arg_1, String arg_2, String arg_3) { 20 | this.arg_0 = arg_0; 21 | this.arg_1 = arg_1; 22 | this.arg_2 = arg_2; 23 | this.arg_3 = arg_3; 24 | } 25 | 26 | public void setArg_0(String arg) { 27 | arg_0 = arg; 28 | } 29 | 30 | public String getArg_0() { 31 | return arg_0; 32 | } 33 | public void setArg_1(String arg) { 34 | arg_1 = arg; 35 | } 36 | 37 | public String getArg_1() { 38 | return arg_1; 39 | } 40 | public void setArg_2(String arg) { 41 | arg_2 = arg; 42 | } 43 | 44 | public String getArg_2() { 45 | return arg_2; 46 | } 47 | public void setArg_3(String arg) { 48 | arg_3 = arg; 49 | } 50 | 51 | public String getArg_3() { 52 | return arg_3; 53 | } 54 | 55 | 56 | } -------------------------------------------------------------------------------- /gui/src/test/java/com/muwire/gui/HTMLSanitizerTest.java: -------------------------------------------------------------------------------- 1 | package com.muwire.gui; 2 | 3 | import org.junit.Test; 4 | 5 | public class HTMLSanitizerTest { 6 | 7 | private static void assertSanitized(String raw, String sanitized) { 8 | assert HTMLSanitizer.sanitize(raw).equals("" + sanitized + ""); 9 | } 10 | @Test 11 | public void testNull() { 12 | assert HTMLSanitizer.sanitize(null) == null; 13 | } 14 | 15 | @Test 16 | public void testSingleChars() { 17 | assertSanitized("&", "&"); 18 | assertSanitized("\"","""); 19 | assertSanitized("<","<"); 20 | assertSanitized(">",">"); 21 | assertSanitized(" ", " "); 22 | } 23 | 24 | @Test 25 | public void testEvilHTMLDoubleQuote() { 26 | assertSanitized("", 27 | "<html><img src="my.tracking.server.com"/></html>"); 28 | } 29 | 30 | @Test 31 | public void textMixture() { 32 | assertSanitized("><\"&", "><"&"); 33 | } 34 | } -------------------------------------------------------------------------------- /host-cache/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin : 'application' 2 | mainClassName = 'com.muwire.hostcache.HostCache' 3 | applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties'] 4 | 5 | dependencies { 6 | implementation "net.i2p:i2p:${i2pVersion}" 7 | testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2' 8 | testImplementation 'junit:junit:4.12' 9 | testImplementation "org.codehaus.groovy:groovy-all:${groovyVersion}" 10 | } 11 | 12 | configurations.testImplementation { 13 | exclude group:'org.codehaus.groovy', module:'groovy-testng' 14 | } 15 | -------------------------------------------------------------------------------- /host-cache/scripts/count_total.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os,sys,json 4 | 5 | if len(sys.argv) < 2 : 6 | print("This script counts unique hosts in the MuWire network",file = sys.stderr) 7 | print("Pass the prefix of the files to analyse. For example:",file = sys.stderr) 8 | print("\"20200427\" will count unique hosts on 27th of April 2020",file = sys.stderr) 9 | print("\"202004\" will count unique hosts during all of April 2020",file = sys.stderr) 10 | sys.exit(1) 11 | 12 | day = sys.argv[1] 13 | files = os.listdir(".") 14 | files = [x for x in files if x.startswith(day)] 15 | 16 | hosts = set() 17 | 18 | for f in files: 19 | for line in open(f): 20 | host = json.loads(line) 21 | hosts.add(host["destination"]) 22 | 23 | print(len(hosts)) 24 | -------------------------------------------------------------------------------- /host-cache/src/main/groovy/com/muwire/hostcache/Host.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.hostcache 2 | 3 | class Host { 4 | 5 | def destination 6 | def verifyTime 7 | boolean leafSlots 8 | boolean peerSlots 9 | int verificationFailures 10 | 11 | public int hashCode() { 12 | return destination.hashCode() 13 | } 14 | 15 | public boolean equals(other) { 16 | return destination.equals(other.destination) 17 | } 18 | 19 | @Override 20 | public String toString() { 21 | "Host[b32:${destination.toBase32()} verifyTime:$verifyTime verificationFailures:$verificationFailures]" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /host-cache/src/main/groovy/com/muwire/hostcache/Pinger.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.hostcache 2 | 3 | import groovy.json.JsonOutput 4 | import groovy.util.logging.Log 5 | import net.i2p.client.I2PSession 6 | import net.i2p.client.SendMessageOptions 7 | import net.i2p.client.datagram.I2PDatagramMaker 8 | 9 | @Log 10 | class Pinger { 11 | 12 | final I2PSession session 13 | Pinger(I2PSession session) { 14 | this.session = session 15 | } 16 | 17 | def ping(host, uuid) { 18 | log.info("pinging $host with uuid:$uuid") 19 | def maker = new I2PDatagramMaker(session) 20 | def payload = new HashMap() 21 | payload.type = "CrawlerPing" 22 | payload.version = 1 23 | payload.uuid = uuid 24 | payload = JsonOutput.toJson(payload) 25 | payload = maker.makeI2PDatagram(payload.bytes) 26 | def options = new SendMessageOptions() 27 | options.setSendLeaseSet(true) 28 | session.sendMessage(host.destination, payload, 0, payload.length, I2PSession.PROTO_DATAGRAM, 0, 0, options) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /host-cache/src/test/groovy/com/muwire/hostcache/Destinations.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.hostcache 2 | 3 | import net.i2p.data.Destination 4 | 5 | class Destinations { 6 | 7 | Destination dest1 = new Destination("KvwWPKMSAtzf7Yruj8TQaHi2jaQpSNsXJskbpmSBTxkcYlDB2GllH~QBu-cs4FSYdaRmKDUUx7793jjnYJgTMbrjqeIL5-BTORZ09n6PUfhSejDpJjdkUxaV1OHRatfYs70RNBv7rvdj1-nXUow5tMfOJtoWVocUoKefUGFQFbJLDDkBqjm1kFyKFZv6m6S6YqXxBgVB1qYicooy67cNQF5HLUFtP15pk5fMDNGz5eNCjPfC~2Gp8FF~OpSy92HT0XN7uAMJykPcbdnWfcvVwqD7eS0K4XEnsqnMPLEiMAhqsugEFiFqtB3Wmm7UHVc03lcAfRhr1e2uZBNFTtM2Uol4MD5sCCKRZVHGcH-WGPSEz0BM5YO~Xi~dQ~N3NVud32PVzhh8xoGcAlhTqMqAbRJndCv-H6NflX90pYmbirCTIDOaR9758mThrqX0d4CwCn4jFXer52l8Qe8CErGoLuB-4LL~Gwrn7R1k7ZQc2PthkqeW8MfigyiN7hZVkul9AAAA") 8 | Destination dest2 = new Destination("KvwWPKMSAtzf7Yruj8TQaHi2jaQpSNsXJskbpmSBTxkcYlDB2GllH~QBu-cs4FSYdaRmKDUUx7793jjnYJgTMbrjqeIL5-BTORZ09n6PUfhSejDpJjdkUxaV1OHRatfYs70RNBv7rvdj1-nXUow5tMfOJtoWVocUoKefUGFQFbJLDDkBqjm1kFyKFZv6m6S6YqXxBgVB1qYicooy67cNQF5HLUFtP15pk5fMDNGz5eNCjPfC~2Gp8FF~OpSy92HT0XN7uAMJykPcbdnWfcvVwqD7eS0K4XEnsqnMPLEiMAhqsugEFiFqtB3Wmm7UHVc03lcAfRhr1e2uZBNFTtM2Uol4MD5sCCKRZVHGcH-WGPSEz0BM5YO~Xi~dQ~N3NVud32PVzhh8xoGcAlhTqMqAbRJndCv-H6NflX90pYmbirCTIDOaR9758mThrqX0d4CwCn4jFXer52l8Qe8CErGoLuB-4LL~Gwrn7R1k7ZQc2PthkqeW8MfigyiN7hZVkul8AAAA") 9 | } 10 | -------------------------------------------------------------------------------- /images/i2cp_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zlatinb/muwire/79c0da6d499f942c3189674ff47162be7a06a228/images/i2cp_config.png -------------------------------------------------------------------------------- /logging/0_logging.properties: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Default Logging Configuration File 3 | # 4 | # You can use a different file by specifying a filename 5 | # with the java.util.logging.config.file system property. 6 | # For example java -Djava.util.logging.config.file=myfile 7 | ############################################################ 8 | 9 | ############################################################ 10 | # Global properties 11 | ############################################################ 12 | 13 | # "handlers" specifies a comma separated list of log Handler 14 | # classes. These handlers will be installed during VM startup. 15 | # Note that these classes must be on the system classpath. 16 | # By default we only configure a ConsoleHandler, which will only 17 | # show messages at the INFO and above levels. 18 | handlers= java.util.logging.FileHandler 19 | 20 | # To also add the FileHandler, use the following line instead. 21 | #handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler 22 | 23 | # Default global logging level. 24 | # This specifies which kinds of events are logged across 25 | # all loggers. For any given facility this global level 26 | # can be overriden by a facility specific level 27 | # Note that the ConsoleHandler also has a separate level 28 | # setting to limit messages printed to the console. 29 | .level= OFF 30 | 31 | -------------------------------------------------------------------------------- /mwmodules/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":core") 3 | } 4 | -------------------------------------------------------------------------------- /mwmodules/src/main/groovy/QueryLogger.groovy: -------------------------------------------------------------------------------- 1 | import com.muwire.core.Core 2 | import com.muwire.core.MWModule 3 | import com.muwire.core.search.SearchEvent 4 | 5 | class QueryLogger implements MWModule { 6 | private final File dump = new File("searches.csv") 7 | 8 | void onSearchEvent(SearchEvent e) { 9 | dump.withWriterAppend("UTF-8", {writer -> 10 | String coalesced = String.join(" ", e.searchTerms) 11 | writer.append(String.format("%d,%s,%s\n", e.getTimestamp(), coalesced, e.persona.getHumanReadableName())) 12 | }) 13 | } 14 | 15 | @Override 16 | String getName() { 17 | "QueryLogger" 18 | } 19 | 20 | @Override 21 | void init(Core core) { 22 | core.getEventBus().register(SearchEvent.class, this) 23 | } 24 | 25 | @Override 26 | void start() { 27 | } 28 | 29 | @Override 30 | void stop() { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pinger/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'application' 2 | mainClassName = 'com.muwire.pinger.Pinger' 3 | dependencies { 4 | implementation "net.i2p:i2p:${i2pVersion}" 5 | } 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'pinger' 2 | include 'host-cache' 3 | include 'update-server' 4 | include 'core' 5 | include 'mwmodules' 6 | include 'gui' 7 | include 'cli' 8 | include 'cli-lanterna' 9 | 10 | // TODO: fix this on Gradle 7 11 | // include 'tracker' 12 | 13 | -------------------------------------------------------------------------------- /tracker/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | 3 | repositories { 4 | jcenter() 5 | mavenLocal() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0' 10 | } 11 | } 12 | 13 | plugins { 14 | id 'org.springframework.boot' version '2.2.6.RELEASE' 15 | } 16 | 17 | apply plugin : 'application' 18 | apply plugin : 'io.spring.dependency-management' 19 | 20 | application { 21 | mainClassName = 'com.muwire.tracker.Tracker' 22 | applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties','-Xmx256M',"-Dbuild.version=${project.version}"] 23 | applicationName = 'mwtrackerd' 24 | } 25 | 26 | apply plugin : 'com.github.johnrengelman.shadow' 27 | 28 | springBoot { 29 | buildInfo { 30 | properties { 31 | version = "${project.version}" 32 | name = "mwtrackerd" 33 | } 34 | } 35 | } 36 | 37 | dependencies { 38 | implementation project(":core") 39 | implementation 'com.github.briandilley.jsonrpc4j:jsonrpc4j:1.5.3' 40 | 41 | implementation 'org.springframework.boot:spring-boot-starter' 42 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 43 | implementation 'org.springframework.boot:spring-boot-starter-web' 44 | 45 | runtimeOnly 'javax.jws:jsr181-api:1.0-MR1' 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/Host.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker 2 | 3 | import com.muwire.core.Persona 4 | 5 | /** 6 | * A participant in a swarm. The same persona can be a member of multiple 7 | * swarms, but in that case it would have multiple Host objects 8 | */ 9 | class Host { 10 | final Persona persona 11 | long lastPinged 12 | long lastResponded 13 | int failures 14 | volatile String xHave 15 | 16 | Host(Persona persona) { 17 | this.persona = persona 18 | } 19 | 20 | boolean isExpired(long cutoff, int maxFailures) { 21 | lastPinged > lastResponded && lastResponded <= cutoff && failures >= maxFailures 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | "Host:[${persona.getHumanReadableName()} lastPinged:$lastPinged lastResponded:$lastResponded failures:$failures xHave:$xHave]" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/TrackRequest.java: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker; 2 | 3 | public class TrackRequest { 4 | String infoHash; 5 | 6 | @Override 7 | public String toString() { 8 | return "infoHash: " +infoHash; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/TrackerProperties.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties 4 | import org.springframework.stereotype.Component 5 | 6 | @Component 7 | @ConfigurationProperties("tracker") 8 | class TrackerProperties { 9 | 10 | final JsonRpc jsonRpc = new JsonRpc() 11 | 12 | public static class JsonRpc { 13 | InetAddress iface 14 | int port 15 | } 16 | 17 | final SwarmParameters swarmParameters = new SwarmParameters() 18 | 19 | public static class SwarmParameters { 20 | /** how often to kick of queries on the MW net, in hours */ 21 | int queryInterval = 1 22 | /** how many hosts to ping in parallel */ 23 | int pingParallel = 5 24 | /** interval of time between pinging the same host, in minutes */ 25 | int pingInterval = 15 26 | /** how long to wait before declaring a host is dead, in minutes */ 27 | int expiry = 60 28 | /** how long to wait for a host to respond to a ping, in seconds */ 29 | int pingTimeout = 20 30 | /** Do not expire a host until it has failed this many times */ 31 | int maxFailures = 3 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/TrackerService.java: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker; 2 | 3 | public interface TrackerService { 4 | public TrackerStatus status(); 5 | public void track(String infoHash); 6 | public boolean forget(String infoHash); 7 | public Swarm.Info info(String infoHash); 8 | } 9 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/TrackerStatus.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker 2 | 3 | class TrackerStatus { 4 | volatile String status 5 | int connections 6 | int swarms 7 | } 8 | -------------------------------------------------------------------------------- /tracker/src/main/groovy/com/muwire/tracker/WebServerConfiguration.groovy: -------------------------------------------------------------------------------- 1 | package com.muwire.tracker 2 | 3 | import org.springframework.boot.web.server.ConfigurableWebServerFactory 4 | import org.springframework.boot.web.server.WebServerFactoryCustomizer 5 | import org.springframework.stereotype.Component 6 | 7 | @Component 8 | class WebServerConfiguration implements WebServerFactoryCustomizer { 9 | 10 | private final TrackerProperties trackerProperties 11 | 12 | WebServerConfiguration(TrackerProperties trackerProperties) { 13 | this.trackerProperties = trackerProperties; 14 | } 15 | @Override 16 | public void customize(ConfigurableWebServerFactory factory) { 17 | factory.setAddress(trackerProperties.jsonRpc.getIface()) 18 | factory.setPort(trackerProperties.jsonRpc.port) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /update-server/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin : 'application' 2 | mainClassName = 'com.muwire.update.UpdateServer' 3 | applicationDefaultJvmArgs = ['-Djava.util.logging.config.file=logging.properties'] 4 | dependencies { 5 | implementation "net.i2p:i2p:${i2pVersion}" 6 | } 7 | --------------------------------------------------------------------------------