Skip to content

Commit

Permalink
Refactor to not handle state in service.
Browse files Browse the repository at this point in the history
  • Loading branch information
dkocher committed Nov 25, 2024
1 parent d0eb6ff commit fdb7768
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,41 @@

public class FinderProgressIconService implements IconService {

private NSProgress progress;

@Override
public boolean set(final Local file, final TransferProgress progress) {
if(TransferStatus.UNKNOWN_LENGTH == progress.getSize()) {
return false;
}
if(TransferStatus.UNKNOWN_LENGTH == progress.getTransferred()) {
return false;
public Icon get(final Local file) {
return new FinderProgressIcon(file);
}

private static final class FinderProgressIcon implements Icon {
private final NSProgress progress;

public FinderProgressIcon(final Local file) {
progress = NSProgress.discreteProgressWithTotalUnitCount(0L);
progress.setKind(NSProgress.NSProgressKindFile);
progress.setCancellable(false);
progress.setPausable(false);
progress.setFileOperationKind(NSProgress.NSProgressFileOperationKindDownloading);
progress.setFileURL(NSURL.fileURLWithPath(file.getAbsolute()));
progress.publish();
}
if(null == this.progress) {
this.progress = NSProgress.progressWithTotalUnitCount(progress.getSize());
this.progress.setKind(NSProgress.NSProgressKindFile);
this.progress.setCancellable(false);
this.progress.setPausable(false);
this.progress.setFileOperationKind(NSProgress.NSProgressFileOperationKindDownloading);
this.progress.setFileURL(NSURL.fileURLWithPath(file.getAbsolute()));
this.progress.publish();

@Override
public boolean update(final TransferProgress status) {
if(TransferStatus.UNKNOWN_LENGTH == status.getSize()) {
return false;
}
if(TransferStatus.UNKNOWN_LENGTH == status.getTransferred()) {
return false;
}
progress.setTotalUnitCount(status.getSize());
progress.setCompletedUnitCount(status.getTransferred());
return true;
}
this.progress.setCompletedUnitCount(progress.getTransferred());
return true;
}

@Override
public boolean remove(final Local file) {
if(null == progress) {
return false;
@Override
public boolean remove() {
progress.unpublish();
return true;
}
progress.unpublish();
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,36 @@

public final class WorkspaceIconService implements IconService {

private final NSWorkspace workspace = NSWorkspace.sharedWorkspace();
private static final NSWorkspace workspace = NSWorkspace.sharedWorkspace();

// An integer between 0 and 9
private int step = 0;
@Override
public Icon get(final Local file) {
return new Icon() {
// An integer between 0 and 9
private int step = 0;

@Override
public boolean update(final TransferProgress progress) {
if(progress.getSize() > PreferencesFactory.get().getLong("queue.download.icon.threshold")) {
final int fraction = new BigDecimal(progress.getTransferred()).divide(new BigDecimal(progress.getSize()), 1, RoundingMode.DOWN).multiply(BigDecimal.TEN).intValue();
if(fraction >= step) {
// Another 10 percent of the file has been transferred
return WorkspaceIconService.update(file, IconCacheFactory.<NSImage>get().iconNamed(String.format("download%d.icns", step = fraction)));
}
return false;
}
return false;
}

@Override
public boolean remove() {
// The Finder will display the default icon for this file type
return WorkspaceIconService.update(file, null);
}
};
}

public boolean update(final Local file, final NSImage icon) {
public static boolean update(final Local file, final NSImage icon) {
synchronized(NSWorkspace.class) {
// Specify 0 if you want to generate icons in all available icon representation formats
if(workspace.setIcon_forFile_options(icon, file.getAbsolute(), new NSUInteger(0))) {
Expand All @@ -45,23 +69,4 @@ public boolean update(final Local file, final NSImage icon) {
return false;
}
}

@Override
public boolean set(final Local file, final TransferProgress progress) {
if(progress.getSize() > PreferencesFactory.get().getLong("queue.download.icon.threshold")) {
final int fraction = new BigDecimal(progress.getTransferred()).divide(new BigDecimal(progress.getSize()), 1, RoundingMode.DOWN).multiply(BigDecimal.TEN).intValue();
if(fraction >= step) {
// Another 10 percent of the file has been transferred
return this.update(file, IconCacheFactory.<NSImage>get().iconNamed(String.format("download%d.icns", step = fraction)));
}
return false;
}
return false;
}

@Override
public boolean remove(final Local file) {
// The Finder will display the default icon for this file type
return this.update(file, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,42 +28,27 @@
public class WorkspaceIconServiceTest {

@Test
public void testSetProgressNoFile() {
final WorkspaceIconService s = new WorkspaceIconService();
public void testUpdateProgressNoFile() {
final Local file = new Local(PreferencesFactory.get().getProperty("tmp.dir"),
UUID.randomUUID().toString());
assertFalse(s.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
assertFalse(WorkspaceIconService.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
}

@Test
public void testSetProgressFolder() throws Exception {
final WorkspaceIconService s = new WorkspaceIconService();
public void testUpdateProgressFolder() throws Exception {
final Local file = new Local(PreferencesFactory.get().getProperty("tmp.dir"),
UUID.randomUUID().toString());
new DefaultLocalDirectoryFeature().mkdir(file);
assertTrue(s.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
assertTrue(WorkspaceIconService.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
}

@Test
public void testSetProgress() throws Exception {
final WorkspaceIconService s = new WorkspaceIconService();
public void testUpdateProgress() throws Exception {
final Local file = new Local(PreferencesFactory.get().getProperty("tmp.dir"),
UUID.randomUUID().toString());
LocalTouchFactory.get().touch(file);
assertTrue(s.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
file.delete();
}

@Test
public void testRemove() throws Exception {
final WorkspaceIconService s = new WorkspaceIconService();
final Local file = new Local(PreferencesFactory.get().getProperty("tmp.dir"),
UUID.randomUUID().toString());
assertFalse(s.remove(file));
LocalTouchFactory.get().touch(file);
assertFalse(s.remove(file));
assertTrue(s.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
assertTrue(s.remove(file));
assertTrue(WorkspaceIconService.update(file, NSImage.imageWithContentsOfFile("../../img/download0.icns")));
file.delete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,21 @@
import ch.cyberduck.core.transfer.TransferProgress;

public final class DisabledIconService implements IconService {
@Override
public boolean set(final Local file, final TransferProgress progress) {
return false;
}

private static final Icon disabled = new Icon() {
@Override
public boolean update(final TransferProgress progress) {
return false;
}

@Override
public boolean remove() {
return false;
}
};

@Override
public boolean remove(final Local file) {
return false;
public Icon get(final Local file) {
return disabled;
}
}
29 changes: 19 additions & 10 deletions core/src/main/java/ch/cyberduck/core/local/IconService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,27 @@
import ch.cyberduck.core.transfer.TransferProgress;

public interface IconService {
/**
* @param file File
* @param progress Transfer status with transferred bytes set in offset
* @return True if icon is set
*/
boolean set(Local file, TransferProgress progress);

/**
* Remove custom icon
* Get icon updater to track progress
*
* @param file File
* @return True if icon is set
* @param file Local file
* @return Updater to send continious progress updates to
*/
boolean remove(Local file);
Icon get(Local file);

interface Icon {
/**
* @param progress Transfer status with transferred bytes set in offset
* @return True if icon is set
*/
boolean update(TransferProgress progress);

/**
* Remove custom icon
*
* @return True if icon is set
*/
boolean remove();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public class DisabledProxyFinder implements ProxyFinder {
@Override
public Proxy find(final String target) {
return Proxy.DIRECT;
// return new Proxy(Proxy.Type.HTTPS, "127.0.0.1", 9090);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,12 @@ public void transfer(final Session<?> source, final Session<?> destination, fina
}
// Transfer
final Download download = source.getFeature(Download.class);
final IconService icon = IconServiceFactory.get();
final IconService.Icon icon = IconServiceFactory.get().get(local);
download.download(file, local, bandwidth, this.options.icon ?
new IconServiceStreamListener(icon, listener, segment, local) : listener, segment, prompt);
new IconServiceStreamListener(icon, listener, segment) : listener, segment, prompt);
// Remove custom icon if complete
if(segment.isComplete()) {
icon.remove(local);
icon.remove();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,26 @@
* feedback@cyberduck.ch
*/

import ch.cyberduck.core.Local;
import ch.cyberduck.core.io.DelegateStreamListener;
import ch.cyberduck.core.BytecountStreamListener;
import ch.cyberduck.core.io.StreamListener;
import ch.cyberduck.core.local.IconService;
import ch.cyberduck.core.transfer.TransferProgress;
import ch.cyberduck.core.transfer.TransferStatus;

public class IconServiceStreamListener extends DelegateStreamListener {
public class IconServiceStreamListener extends BytecountStreamListener {

private final IconService icon;
private final IconService.Icon icon;
private final TransferStatus status;
private final Local file;

public IconServiceStreamListener(final IconService icon, final StreamListener delegate, final TransferStatus status, final Local file) {
public IconServiceStreamListener(final IconService.Icon icon, final StreamListener delegate, final TransferStatus status) {
super(delegate);
this.icon = icon;
this.status = status;
this.file = file;
}

@Override
public void sent(final long bytes) {
super.sent(bytes);
icon.set(file, new TransferProgress(status.getLength(), bytes));
icon.update(new TransferProgress(status.getLength(), this.getSent()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
import ch.cyberduck.core.transfer.Transfer;
import ch.cyberduck.core.transfer.TransferItem;
import ch.cyberduck.core.transfer.TransferProgress;
import ch.cyberduck.core.transfer.TransferStatus;
import ch.cyberduck.core.transfer.UploadTransfer;
import ch.cyberduck.core.transfer.download.DownloadFilterOptions;
import ch.cyberduck.ui.browser.BrowserColumn;
Expand Down Expand Up @@ -649,7 +648,7 @@ public NSArray namesOfPromisedFilesDroppedAtDestination(final NSURL url) {
try {
LocalTouchFactory.get().touch(file);
if(options.icon) {
IconServiceFactory.get().set(file, new TransferProgress(0L, 0L));
IconServiceFactory.get().get(file).update(new TransferProgress(0L, 0L));
}
}
catch(AccessDeniedException e) {
Expand Down
25 changes: 10 additions & 15 deletions s3/src/main/java/ch/cyberduck/core/s3/S3UrlProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,7 @@
* Bug fixes, suggestions and comments should be sent to feedback@cyberduck.ch
*/

import ch.cyberduck.core.DescriptiveUrl;
import ch.cyberduck.core.DescriptiveUrlBag;
import ch.cyberduck.core.HostPasswordStore;
import ch.cyberduck.core.HostWebUrlProvider;
import ch.cyberduck.core.LocaleFactory;
import ch.cyberduck.core.PasswordStoreFactory;
import ch.cyberduck.core.Path;
import ch.cyberduck.core.PathContainerService;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.SimplePathPredicate;
import ch.cyberduck.core.URIEncoder;
import ch.cyberduck.core.UrlProvider;
import ch.cyberduck.core.UserDateFormatterFactory;
import ch.cyberduck.core.*;
import ch.cyberduck.core.cdn.Distribution;
import ch.cyberduck.core.cdn.DistributionUrlProvider;
import ch.cyberduck.core.preferences.HostPreferences;
Expand Down Expand Up @@ -201,9 +189,16 @@ public PresignedUrl(final Path file, final Calendar expiry) {

@Override
public String getUrl() {
final String secret = store.findLoginPassword(session.getHost());
final String secret;
final Credentials credentials = CredentialsConfiguratorFactory.get(session.getHost().getProtocol()).configure(session.getHost());
if(credentials.isPasswordAuthentication()) {
secret = credentials.getPassword();
}
else {
secret = store.findLoginPassword(session.getHost());
}
if(StringUtils.isBlank(secret)) {
log.warn("No secret found in password store required to sign temporary URL");
log.error("No secret found in password store required to sign temporary URL");
return DescriptiveUrl.EMPTY.getUrl();
}
String region = session.getHost().getRegion();
Expand Down

0 comments on commit fdb7768

Please sign in to comment.