mirror of
https://github.com/mirror/jdownloader.git
synced 2024-11-23 20:19:50 +00:00
Updater
git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@15357 ebf7c1c2-ba36-0410-9fe8-c592906822b4
This commit is contained in:
parent
96db63f38f
commit
4129bbe17f
@ -252,29 +252,29 @@
|
||||
|
||||
|
||||
</fileset>
|
||||
<fileset dir="themes">
|
||||
<include name="themes/standard/org/jdownloader/images/dialog/**/*" />
|
||||
|
||||
<fileset dir="${dep.update}/themes">
|
||||
<include name="themes/standard/org/jdownloader/updater/**/*" />
|
||||
</fileset>
|
||||
<fileset dir="${dep.updateclient}/src">
|
||||
<include name="**/*.png" />
|
||||
|
||||
<include name="**/*.lng" />
|
||||
<include name="tbs.jar" />
|
||||
<include name="version.dat" />
|
||||
|
||||
</fileset>
|
||||
<fileset dir="${dep.update}/src">
|
||||
<include name="**/*.png" />
|
||||
|
||||
<include name="**/*.lng" />
|
||||
|
||||
</fileset>
|
||||
<fileset dir="src">
|
||||
<include name="**/*.lng" />
|
||||
<include name="**/*.png" />
|
||||
|
||||
</fileset>
|
||||
<fileset dir="${dep.awu}/src">
|
||||
<include name="**/*.lng" />
|
||||
<include name="**/*.png" />
|
||||
<include name="**/*.lng" />
|
||||
<include name="tbs.jar" />
|
||||
<include name="version.dat" />
|
||||
|
||||
</fileset>
|
||||
|
||||
</jar>
|
||||
@ -394,4 +394,7 @@
|
||||
<target name="withoutsign" depends="clean,compile,copy_res,jarMain,copy_compiled,jarReconnectOptionals,jarWebupdater,jarOptionals">
|
||||
<echo message="Finished." />
|
||||
</target>
|
||||
<target name="updater" depends="clean,compile,copy_compiled,jarWebupdater">
|
||||
<echo message="Finished." />
|
||||
</target>
|
||||
</project>
|
@ -868,7 +868,7 @@ public class DownloadWatchDog implements DownloadControllerListener, StateMachin
|
||||
public void run() {
|
||||
if (DownloadWatchDog.this.stateMachine.isFinal()) {
|
||||
/* downloadwatchdog was in stopped state, so reset it */
|
||||
DownloadWatchDog.this.stateMachine.reset();
|
||||
DownloadWatchDog.this.stateMachine.reset(false);
|
||||
}
|
||||
if (!DownloadWatchDog.this.stateMachine.isStartState()) {
|
||||
/* only allow to start when in FinalState(NOT_RUNNING) */
|
||||
|
@ -26,6 +26,7 @@ public class WebUpdate {
|
||||
* deaktiviert hat
|
||||
*/
|
||||
public static synchronized void doUpdateCheck(final boolean forceguiCall) {
|
||||
|
||||
JDUpdater.getInstance().startUpdate(!forceguiCall);
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,14 @@ import jd.plugins.ContainerStatus;
|
||||
import jd.plugins.DownloadLink;
|
||||
import jd.plugins.FilePackage;
|
||||
import jd.plugins.PluginsC;
|
||||
import jd.update.WebUpdater;
|
||||
import jd.utils.JDHexUtils;
|
||||
import jd.utils.JDUtilities;
|
||||
import jd.utils.locale.JDL;
|
||||
|
||||
import org.appwork.storage.config.JsonConfig;
|
||||
import org.appwork.utils.Hash;
|
||||
import org.appwork.utils.logging.Log;
|
||||
import org.jdownloader.update.WebupdateSettings;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@ -388,7 +389,7 @@ public class D extends PluginsC {
|
||||
br.getHeaders().put("rev", JDUtilities.getRevision());
|
||||
|
||||
//
|
||||
br.postPage(s9 + "", "destType=jdtc6&b=" + SubConfiguration.getConfig("WEBUPDATE").getStringProperty(WebUpdater.BRANCHINUSE) + "&srcType=dlc&data=" + bin + "&v=" + JDUtilities.getRevision());
|
||||
br.postPage(s9 + "", "destType=jdtc6&b=" + JsonConfig.create(WebupdateSettings.class).getBranchInUse() + "&srcType=dlc&data=" + bin + "&v=" + JDUtilities.getRevision());
|
||||
|
||||
// 3f69b642cc403506ff1ee7f22b23ce40
|
||||
// new byte[]{(byte) 0xef, (byte) 0xe9, (byte) 0x0a, (byte) 0x8e,
|
||||
|
@ -3337,4 +3337,13 @@ public interface GuiTranslation extends TranslateInterface {
|
||||
@Default(lngs = { "en" }, values = { "Filename %s1 does not match your Filetype Filter." })
|
||||
String TestAction_actionPerformed_nomatch_ext_(String input);
|
||||
|
||||
@Default(lngs = { "en" }, values = { "New Version found!" })
|
||||
String JDUpdater_start_updater_update_title();
|
||||
|
||||
@Default(lngs = { "en" }, values = { "JDownloader has to restart now to perform an update." })
|
||||
String JDUpdater_start_updater_update_msg();
|
||||
|
||||
@Default(lngs = { "en" }, values = { "Update & Restart now!" })
|
||||
String JDUpdater_start_restart_update_now_();
|
||||
|
||||
}
|
@ -21,6 +21,7 @@ import org.jdownloader.settings.AccountSettings;
|
||||
import org.jdownloader.settings.GeneralSettings;
|
||||
import org.jdownloader.settings.GraphicalUserInterfaceSettings;
|
||||
import org.jdownloader.settings.InternetConnectionSettings;
|
||||
import org.jdownloader.update.WebupdateSettings;
|
||||
|
||||
public class AdvancedConfigManager {
|
||||
private static final AdvancedConfigManager INSTANCE = new AdvancedConfigManager();
|
||||
@ -47,6 +48,7 @@ public class AdvancedConfigManager {
|
||||
register(JsonConfig.create(ReconnectConfig.class));
|
||||
register(JsonConfig.create(RemoteAPIConfig.class));
|
||||
register(JsonConfig.create(PackagizerSettings.class));
|
||||
register(JsonConfig.create(WebupdateSettings.class));
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,53 @@
|
||||
package org.jdownloader.update;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import jd.JDInitFlags;
|
||||
import jd.event.ControlEvent;
|
||||
import jd.event.ControlListener;
|
||||
import jd.gui.swing.SwingGui;
|
||||
import jd.utils.JDUtilities;
|
||||
|
||||
import org.appwork.resources.AWUTheme;
|
||||
import org.appwork.shutdown.ShutdownController;
|
||||
import org.appwork.shutdown.ShutdownEvent;
|
||||
import org.appwork.storage.JSonStorage;
|
||||
import org.appwork.storage.config.JsonConfig;
|
||||
import org.appwork.update.exchange.UpdatePackage;
|
||||
import org.appwork.update.updateclient.InstalledFile;
|
||||
import org.appwork.update.updateclient.Updater;
|
||||
import org.appwork.update.updateclient.UpdaterState;
|
||||
import org.appwork.update.updateclient.event.UpdaterEvent;
|
||||
import org.appwork.update.updateclient.event.UpdaterListener;
|
||||
import org.appwork.update.updateclient.http.ClientUpdateRequiredException;
|
||||
import org.appwork.utils.Application;
|
||||
import org.appwork.utils.Files;
|
||||
import org.appwork.utils.Hash;
|
||||
import org.appwork.utils.IO;
|
||||
import org.appwork.utils.formatter.SizeFormatter;
|
||||
import org.appwork.utils.locale._AWU;
|
||||
import org.appwork.utils.logging.Log;
|
||||
import org.appwork.utils.net.DownloadProgress;
|
||||
import org.appwork.utils.swing.EDTHelper;
|
||||
import org.appwork.utils.swing.EDTRunner;
|
||||
import org.appwork.utils.swing.dialog.Dialog;
|
||||
import org.appwork.utils.swing.dialog.DialogCanceledException;
|
||||
import org.appwork.utils.swing.dialog.DialogClosedException;
|
||||
import org.appwork.utils.swing.dialog.DialogNoAnswerException;
|
||||
import org.appwork.utils.swing.dialog.ProgressDialog;
|
||||
import org.appwork.utils.swing.dialog.ProgressDialog.ProgressGetter;
|
||||
import org.appwork.utils.zip.ZipIOException;
|
||||
import org.appwork.utils.zip.ZipIOReader;
|
||||
import org.jdownloader.gui.translate._GUI;
|
||||
import org.jdownloader.images.NewTheme;
|
||||
import org.jdownloader.update.gui.UpdateFoundDialog;
|
||||
import org.jdownloader.update.translate.T;
|
||||
|
||||
public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
public class JDUpdater extends Updater implements Runnable {
|
||||
private static final JDUpdater INSTANCE = new JDUpdater();
|
||||
|
||||
/**
|
||||
@ -39,12 +59,14 @@ public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
return JDUpdater.INSTANCE;
|
||||
}
|
||||
|
||||
private UpdaterGUI gui;
|
||||
private boolean silentCheck;
|
||||
private int waitingUpdates = 0;
|
||||
private boolean updateRunning = false;
|
||||
private Thread updaterThread;
|
||||
private Thread updateChecker;
|
||||
protected static final String UPDATE_INTERVAL = "UPDATEINTERVAL";
|
||||
|
||||
private UpdaterGUI gui;
|
||||
private boolean silentCheck;
|
||||
private int waitingUpdates = 0;
|
||||
private boolean updateRunning = false;
|
||||
private Thread updaterThread;
|
||||
private Thread updateChecker;
|
||||
|
||||
/**
|
||||
* unsynched access to gui. may return null
|
||||
@ -81,7 +103,23 @@ public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
super(new UpdaterHttpClientImpl(), new Options());
|
||||
getOptions().setDebug(JDInitFlags.SWITCH_DEBUG);
|
||||
|
||||
JDUtilities.getController().addControlListener(this);
|
||||
ShutdownController.getInstance().addShutdownEvent(new ShutdownEvent() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (updaterThread != null && updaterThread.isAlive()) {
|
||||
Log.L.warning("Interrupt Updater Thread because JDownloader exists");
|
||||
updaterThread.interrupt();
|
||||
new EDTRunner() {
|
||||
|
||||
@Override
|
||||
protected void runInEDT() {
|
||||
if (gui != null) gui.setVisible(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
this.getEventSender().addListener(new UpdaterListener() {
|
||||
|
||||
public void onUpdaterModuleStart(UpdaterEvent arg0) {
|
||||
@ -108,26 +146,174 @@ public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
Log.L.info(JSonStorage.toString(getFilesToRemove()));
|
||||
|
||||
}
|
||||
} else if (arg0 == stateError) {
|
||||
// Exception exc = getException();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onStateEnter(UpdaterState arg0) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* getVersion should be -1 here. Usually the server checks the version
|
||||
* number and blocks the call of we call with an outdated version. This is
|
||||
* used for the standalon updater. the standalone updater will update itself
|
||||
* in this case. JDUpdater is used in JD, not as standalon. We do not want
|
||||
* to get updater exceptions, so we set version to -1 to ignore this.
|
||||
*/
|
||||
@Override
|
||||
public int getVersion() {
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// protected int getProtocolVersion() {
|
||||
// return 4;
|
||||
// }
|
||||
|
||||
public void start() throws Exception {
|
||||
|
||||
try {
|
||||
super.start();
|
||||
} catch (ClientUpdateRequiredException e) {
|
||||
UpdaterGUI myGui = getExistingGUI();
|
||||
if (myGui != null) {
|
||||
myGui.setVisible(false);
|
||||
}
|
||||
try {
|
||||
Dialog.getInstance().showConfirmDialog(0, _GUI._.JDUpdater_start_updater_update_title(), _GUI._.JDUpdater_start_updater_update_msg(), NewTheme.I().getIcon("puzzle", 32), _GUI._.JDUpdater_start_restart_update_now_(), null);
|
||||
doUpdaterUpdate(e);
|
||||
} catch (DialogNoAnswerException e1) {
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
if (isInterrupted()) { throw new InterruptedException(e.getMessage()); }
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public File downloadSelfUpdate(final ClientUpdateRequiredException e2) throws Exception, ZipIOException, ZipException, IOException {
|
||||
final String url = e2.getUrl();
|
||||
final String hash = e2.getHash();
|
||||
final File file = Application.getResource("tmp/" + hash + ".zip");
|
||||
|
||||
if (!file.exists() || Hash.getSHA256(file).equals(hash)) {
|
||||
if (file.exists() && !file.delete()) { throw new Exception(T._.could_not_update_updater()); }
|
||||
file.delete();
|
||||
downloadInDialog(file, url, hash);
|
||||
}
|
||||
final ZipIOReader zip = new ZipIOReader(file);
|
||||
final File dest = Application.getResource("tmp/update/self");
|
||||
Files.deleteRecursiv(dest);
|
||||
dest.mkdirs();
|
||||
zip.extractTo(dest);
|
||||
file.delete();
|
||||
file.deleteOnExit();
|
||||
return dest;
|
||||
}
|
||||
|
||||
public void downloadInDialog(final File file, final String url, final String hash) throws Exception {
|
||||
if (file.exists()) { throw new Exception("File exists"); }
|
||||
file.getParentFile().mkdirs();
|
||||
Exception ret = null;
|
||||
|
||||
ret = new EDTHelper<Exception>() {
|
||||
|
||||
@Override
|
||||
public Exception edtRun() {
|
||||
try {
|
||||
|
||||
final DownloadProgress progress = new DownloadProgress();
|
||||
final ProgressGetter pg = new ProgressGetter() {
|
||||
|
||||
private long loaded = 0;
|
||||
private long total = 0;
|
||||
|
||||
public int getProgress() {
|
||||
|
||||
this.total = progress.getTotal();
|
||||
this.loaded = progress.getLoaded();
|
||||
if (this.total == 0) { return 0; }
|
||||
return (int) (this.loaded * 100 / this.total);
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
this.total = progress.getTotal();
|
||||
this.loaded = progress.getLoaded();
|
||||
if (this.total <= 0) { return _AWU.T.connecting(); }
|
||||
return _AWU.T.progress(SizeFormatter.formatBytes(this.loaded), SizeFormatter.formatBytes(this.total), this.loaded * 10000f / this.total / 100.0);
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
getHttpClient().download(file, url, progress);
|
||||
System.out.println("Download finished");
|
||||
}
|
||||
|
||||
};
|
||||
final ProgressDialog dialog = new ProgressDialog(pg, Dialog.BUTTONS_HIDE_CANCEL | Dialog.BUTTONS_HIDE_OK, _AWU.T.download_title(), _AWU.T.download_msg(), AWUTheme.getInstance().getIcon("download", 32)) {
|
||||
|
||||
@Override
|
||||
public boolean closeAllowed() {
|
||||
|
||||
Dialog.getInstance().showMessageDialog(_AWU.T.please_wait());
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Dialog.getInstance().showDialog(dialog);
|
||||
} catch (final Exception e) {
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}.getReturnValue();
|
||||
|
||||
if (hash != null && !hash.equalsIgnoreCase(Hash.getSHA256(file))) {
|
||||
//
|
||||
throw new Exception("Hash Mismatch");
|
||||
}
|
||||
if (ret != null) { throw ret; }
|
||||
}
|
||||
|
||||
private void doUpdaterUpdate(ClientUpdateRequiredException e) {
|
||||
try {
|
||||
|
||||
File updaterUpdatesFolder = downloadSelfUpdate(e);
|
||||
final File bootStrapper = Application.getResource("tbs.jar");
|
||||
bootStrapper.delete();
|
||||
IO.writeToFile(bootStrapper, IO.readURL(Application.getRessourceURL("tbs.jar")));
|
||||
ShutdownController.getInstance().addShutdownEvent(new RestartEvent(updaterUpdatesFolder, new String[] {}) {
|
||||
protected String getRestartingJar() {
|
||||
return "Updater.jar";
|
||||
}
|
||||
});
|
||||
ShutdownController.getInstance().requestShutdown();
|
||||
|
||||
} catch (ZipException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (ZipIOException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBranchInUse(String branch) {
|
||||
getOptions().setBranch(branch);
|
||||
|
||||
JsonConfig.create(WebupdateSettings.class).setBranch(branch);
|
||||
JsonConfig.create(WebupdateSettings.class).setBranchInUse(branch);
|
||||
|
||||
}
|
||||
|
||||
public void startUpdate(final boolean silentCheck) {
|
||||
@ -156,6 +342,7 @@ public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
this.silentCheck = silentCheck;
|
||||
|
||||
updaterThread = new Thread(this);
|
||||
updaterThread.setName("UpdaterThread");
|
||||
this.setThread(updaterThread);
|
||||
updaterThread.start();
|
||||
|
||||
@ -350,19 +537,22 @@ public class JDUpdater extends Updater implements Runnable, ControlListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void controlEvent(ControlEvent event) {
|
||||
// interrupt updater if jd exists
|
||||
if (ControlEvent.CONTROL_SYSTEM_EXIT == event.getEventID()) {
|
||||
interrupt();
|
||||
new EDTRunner() {
|
||||
public void startChecker() {
|
||||
updateChecker = new Thread("UpdateChecker") {
|
||||
public void run() {
|
||||
startUpdate(true);
|
||||
while (true) {
|
||||
try {
|
||||
|
||||
@Override
|
||||
protected void runInEDT() {
|
||||
if (gui != null) gui.setVisible(false);
|
||||
Thread.sleep(JsonConfig.create(WebupdateSettings.class).getUpdateInterval());
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
startUpdate(true);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
updateChecker.start();
|
||||
}
|
||||
|
||||
public boolean hasWaitingUpdates() {
|
||||
|
@ -16,18 +16,17 @@ import javax.swing.WindowConstants;
|
||||
import jd.gui.swing.jdgui.JDGui;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.appwork.resources.AWUTheme;
|
||||
import org.appwork.update.updateclient.UpdaterState;
|
||||
import org.appwork.update.updateclient.event.UpdaterEvent;
|
||||
import org.appwork.update.updateclient.event.UpdaterListener;
|
||||
import org.appwork.update.updateclient.gui.UpdaterCoreGui;
|
||||
import org.appwork.utils.images.IconIO;
|
||||
import org.appwork.utils.locale._AWU;
|
||||
import org.appwork.utils.swing.EDTRunner;
|
||||
import org.appwork.utils.swing.SwingUtils;
|
||||
import org.appwork.utils.swing.dialog.Dialog;
|
||||
import org.appwork.utils.swing.dialog.DialogCanceledException;
|
||||
import org.appwork.utils.swing.dialog.DialogClosedException;
|
||||
import org.jdownloader.update.gui.JDStandaloneUpdaterGui;
|
||||
import org.jdownloader.update.translate.T;
|
||||
|
||||
public class UpdaterGUI extends JFrame implements ActionListener, UpdaterListener {
|
||||
@ -112,10 +111,10 @@ public class UpdaterGUI extends JFrame implements ActionListener, UpdaterListene
|
||||
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
final ArrayList<Image> list = new ArrayList<Image>();
|
||||
|
||||
list.add(IconIO.getImage(JDStandaloneUpdaterGui.class.getResource("resource/updaterIcon128.png")));
|
||||
list.add(IconIO.getImage(JDStandaloneUpdaterGui.class.getResource("resource/updaterIcon64.png")));
|
||||
list.add(IconIO.getImage(JDStandaloneUpdaterGui.class.getResource("resource/updaterIcon32.png")));
|
||||
list.add(IconIO.getImage(JDStandaloneUpdaterGui.class.getResource("resource/updaterIcon16.png")));
|
||||
list.add(AWUTheme.I().getImage("updatericon", 64));
|
||||
list.add(AWUTheme.I().getImage("updatericon", 48));
|
||||
list.add(AWUTheme.I().getImage("updatericon", 32));
|
||||
list.add(AWUTheme.I().getImage("updatericon", 16));
|
||||
setIconImages(list);
|
||||
layoutGUI();
|
||||
|
||||
@ -289,6 +288,14 @@ public class UpdaterGUI extends JFrame implements ActionListener, UpdaterListene
|
||||
onNoUpdates();
|
||||
}
|
||||
|
||||
} else if (JDUpdater.getInstance().isFailed()) {
|
||||
new EDTRunner() {
|
||||
|
||||
@Override
|
||||
protected void runInEDT() {
|
||||
cancel.setText(T._.exit());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
24
src/org/jdownloader/update/WebupdateSettings.java
Normal file
24
src/org/jdownloader/update/WebupdateSettings.java
Normal file
@ -0,0 +1,24 @@
|
||||
package org.jdownloader.update;
|
||||
|
||||
import org.appwork.storage.config.ConfigInterface;
|
||||
import org.appwork.storage.config.annotations.AboutConfig;
|
||||
import org.appwork.storage.config.annotations.DefaultLongValue;
|
||||
import org.appwork.storage.config.annotations.Description;
|
||||
|
||||
public interface WebupdateSettings extends ConfigInterface {
|
||||
|
||||
void setBranch(String branch);
|
||||
|
||||
String getBranch();
|
||||
|
||||
void setBranchInUse(String branch);
|
||||
|
||||
String getBranchInUse();
|
||||
|
||||
@DefaultLongValue(30 * 60 * 1000)
|
||||
@AboutConfig
|
||||
@Description("[MS] How often shall JD do a silent Updatecheck.")
|
||||
long getUpdateInterval();
|
||||
|
||||
void setUpdateInterval(long intervalMS);
|
||||
}
|
BIN
themes/themes/standard/org/jdownloader/images/puzzle.png
Normal file
BIN
themes/themes/standard/org/jdownloader/images/puzzle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
BIN
themes/themes/standard/org/jdownloader/images/updaterIcon0.png
Normal file
BIN
themes/themes/standard/org/jdownloader/images/updaterIcon0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
themes/themes/standard/org/jdownloader/images/updaterIcon100.png
Normal file
BIN
themes/themes/standard/org/jdownloader/images/updaterIcon100.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
themes/themes/standard/org/jdownloader/images/updatericon.png
Normal file
BIN
themes/themes/standard/org/jdownloader/images/updatericon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
Reference in New Issue
Block a user