parent
945d63e4ea
commit
5ebdab42e5
|
@ -1,12 +1,6 @@
|
|||
# Reset Your IDE Eval Information
|
||||
|
||||
1. Download and install plugin from [Release Page](https://gitee.com/pengzhile/ide-eval-resetter/releases).
|
||||
2. Click `Help` or `Get Help` -> `Reset IDE Eval` menu.
|
||||
2. Click `Help` or `Get Help` -> `Eval Reset` menu.
|
||||
3. Restart your IDE.
|
||||
4. Now you have another 30 days eval time :)
|
||||
|
||||
------------------------------------------
|
||||
|
||||
### Alternative
|
||||
|
||||
* Or run script in the [reset_eval](https://gitee.com/pengzhile/ide-eval-resetter/tree/master/reset_eval) folder directly.
|
||||
|
|
19
build.gradle
19
build.gradle
|
@ -1,10 +1,13 @@
|
|||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.21'
|
||||
id 'org.jetbrains.intellij' version '0.5.0'
|
||||
}
|
||||
|
||||
group 'io.zhile.research.intellij'
|
||||
version '1.0.5'
|
||||
version '2.0.0'
|
||||
|
||||
sourceCompatibility = 1.7
|
||||
targetCompatibility = 1.7
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -14,17 +17,21 @@ dependencies {
|
|||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
}
|
||||
|
||||
buildPlugin {
|
||||
buildSearchableOptions.enabled = false
|
||||
}
|
||||
|
||||
// See https://github.com/JetBrains/gradle-intellij-plugin/
|
||||
intellij {
|
||||
// localPath "${System.properties['user.home']}/Applications/IntelliJ IDEA.app"
|
||||
// alternativeIdePath localPath
|
||||
|
||||
version "2020.2.3"
|
||||
type "IU"
|
||||
}
|
||||
|
||||
patchPluginXml {
|
||||
changeNotes """
|
||||
release v2.0.0
|
||||
1. add ui
|
||||
2. more stable and accurate
|
||||
release v1.0.5
|
||||
1. update for 2020.2.x
|
||||
release v1.0.4
|
||||
|
@ -34,6 +41,6 @@ patchPluginXml {
|
|||
release v1.0.2
|
||||
1. compatibility fix"""
|
||||
|
||||
sinceBuild "162"
|
||||
sinceBuild "145.258"
|
||||
untilBuild null
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
#!/bin/bash
|
||||
# reset jetbrains ide evals v1.0.5
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
JB_PRODUCTS="IntelliJIdea CLion PhpStorm GoLand PyCharm WebStorm Rider DataGrip RubyMine AppCode"
|
||||
|
||||
if [ "$OS_NAME" == "Darwin" ]; then
|
||||
echo 'macOS:'
|
||||
|
||||
for PRD in $JB_PRODUCTS; do
|
||||
rm -rf ~/Library/Preferences/"${PRD}"*/eval
|
||||
sed -i '' '/name="evlsprt.*"/d' ~/Library/Preferences/"${PRD}"*/options/other.xml >/dev/null 2>&1
|
||||
rm -rf ~/Library/Application\ Support/JetBrains/"${PRD}"*/eval
|
||||
sed -i '' '/name="evlsprt.*"/d' ~/Library/Application\ Support/JetBrains/"${PRD}"*/options/other.xml >/dev/null 2>&1
|
||||
done
|
||||
|
||||
rm -rf ~/Library/Preferences/jetbrains.*.*.plist
|
||||
plutil -remove "/.JetBrains\.UserIdOnMachine" ~/Library/Preferences/com.apple.java.util.prefs.plist >/dev/null
|
||||
plutil -remove "/.jetbrains/.user_id_on_machine" ~/Library/Preferences/com.apple.java.util.prefs.plist >/dev/null
|
||||
plutil -remove "/.jetbrains/.device_id" ~/Library/Preferences/com.apple.java.util.prefs.plist >/dev/null
|
||||
elif [ "$OS_NAME" == "Linux" ]; then
|
||||
echo 'Linux:'
|
||||
|
||||
for PRD in $JB_PRODUCTS; do
|
||||
rm -rf ~/."${PRD}"*/config/eval
|
||||
sed -i '/name="evlsprt.*"/d' ~/."${PRD}"*/config/options/other.xml >/dev/null 2>&1
|
||||
rm -rf ~/.config/JetBrains/"${PRD}"*/eval
|
||||
sed -i '/name="evlsprt.*"/d' ~/.config/JetBrains/"${PRD}"*/options/other.xml >/dev/null 2>&1
|
||||
done
|
||||
|
||||
sed -i '/key="JetBrains\.UserIdOnMachine"/d' ~/.java/.userPrefs/prefs.xml
|
||||
sed -i '/key="device_id"/d' ~/.java/.userPrefs/jetbrains/prefs.xml
|
||||
sed -i '/key="user_id_on_machine"/d' ~/.java/.userPrefs/jetbrains/prefs.xml
|
||||
find ~/.java/.userPrefs/jetbrains/ -name "evlsprt*" -type d -exec rm -rf {} \; >/dev/null 2>&1
|
||||
else
|
||||
echo 'unsupport'
|
||||
exit
|
||||
fi
|
||||
|
||||
echo 'done.'
|
|
@ -1,62 +0,0 @@
|
|||
' reset jetbrains ide evals v1.0.5
|
||||
Set oShell = CreateObject("WScript.Shell")
|
||||
Set oFS = CreateObject("Scripting.FileSystemObject")
|
||||
sHomeFolder = oShell.ExpandEnvironmentStrings("%USERPROFILE%")
|
||||
sJBDataFolder = oShell.ExpandEnvironmentStrings("%APPDATA%") + "\JetBrains"
|
||||
|
||||
Set re = New RegExp
|
||||
re.Global = True
|
||||
re.IgnoreCase = True
|
||||
re.Pattern = "\.?(IntelliJIdea|GoLand|CLion|PyCharm|DataGrip|RubyMine|AppCode|PhpStorm|WebStorm|Rider).*"
|
||||
|
||||
Sub removeEval(ByVal file, ByVal sEvalPath)
|
||||
bMatch = re.Test(file.Name)
|
||||
If Not bMatch Then
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
If oFS.FolderExists(sEvalPath) Then
|
||||
oFS.DeleteFolder sEvalPath, True
|
||||
End If
|
||||
|
||||
content = ""
|
||||
otherFile = oFS.GetParentFolderName(sEvalPath) + "\options\other.xml"
|
||||
If oFS.FileExists(otherFile) Then
|
||||
Set txtStream = oFS.OpenTextFile(otherFile, 1, False)
|
||||
Do While Not txtStream.AtEndOfStream
|
||||
line = txtStream.ReadLine
|
||||
If InStr(line, "name=""evlsprt") = 0 Then
|
||||
content = content + line + vbLf
|
||||
End If
|
||||
Loop
|
||||
txtStream.Close
|
||||
|
||||
Set txtStream = oFS.OpenTextFile(otherFile, 2, False)
|
||||
txtStream.Write content
|
||||
txtStream.Close
|
||||
End If
|
||||
End Sub
|
||||
|
||||
If oFS.FolderExists(sHomeFolder) Then
|
||||
For Each oFile In oFS.GetFolder(sHomeFolder).SubFolders
|
||||
removeEval oFile, sHomeFolder + "\" + oFile.Name + "\config\eval"
|
||||
Next
|
||||
End If
|
||||
|
||||
If oFS.FolderExists(sJBDataFolder) Then
|
||||
For Each oFile In oFS.GetFolder(sJBDataFolder).SubFolders
|
||||
removeEval oFile, sJBDataFolder + "\" + oFile.Name + "\eval"
|
||||
Next
|
||||
End If
|
||||
|
||||
On Error Resume Next
|
||||
oShell.RegDelete "HKEY_CURRENT_USER\Software\JavaSoft\Prefs\/Jet/Brains./User/Id/On/Machine"
|
||||
oShell.RegDelete "HKEY_CURRENT_USER\Software\JavaSoft\Prefs\jetbrains\device_id"
|
||||
oShell.RegDelete "HKEY_CURRENT_USER\Software\JavaSoft\Prefs\jetbrains\user_id_on_machine"
|
||||
oShell.RegDelete "HKEY_CURRENT_USER\Software\JavaSoft\Prefs\jetbrains\"
|
||||
oFs.DeleteFile sJBDataFolder + "\bl"
|
||||
oFs.DeleteFile sJBDataFolder + "\crl"
|
||||
oFs.DeleteFile sJBDataFolder + "\PermanentUserId"
|
||||
oFs.DeleteFile sJBDataFolder + "\PermanentDeviceId"
|
||||
|
||||
MsgBox "done"
|
|
@ -1,69 +0,0 @@
|
|||
package io.zhile.research.intellij;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import io.zhile.research.intellij.action.ResetAction;
|
||||
import io.zhile.research.intellij.helper.Constants;
|
||||
import io.zhile.research.intellij.helper.NotificationHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class MainComponent implements ApplicationComponent {
|
||||
private static final long RESET_PERIOD = 2160000000L; // 25 days
|
||||
|
||||
public void initComponent() {
|
||||
Preferences prefs = Preferences.userRoot().node(Constants.PLUGIN_NAME);
|
||||
long lastResetTime = prefs.getLong(Constants.PRODUCT_NAME + Constants.PRODUCT_HASH, 0L);
|
||||
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (lastResetTime > 0) {
|
||||
Date date = new Date(lastResetTime);
|
||||
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
NotificationHelper.showInfo(null, "The last reset time: " + format.format(date));
|
||||
}
|
||||
|
||||
new ResetTimerTask(lastResetTime).run();
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
protected static class ResetTimerTask extends TimerTask {
|
||||
private final long lastResetTime;
|
||||
|
||||
public ResetTimerTask(long lastResetTime) {
|
||||
this.lastResetTime = lastResetTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (System.currentTimeMillis() - lastResetTime > RESET_PERIOD) {
|
||||
String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
|
||||
Notification notification = NotificationHelper.NOTIFICATION_GROUP.createNotification(Constants.PLUGIN_NAME, null, message, NotificationType.INFORMATION);
|
||||
notification.addAction(new ResetAction());
|
||||
notification.notify(null);
|
||||
}
|
||||
|
||||
new Timer().schedule(new ResetTimerTask(lastResetTime), 3600000); // 60 min
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
// for compatibility
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull
|
||||
String getComponentName() {
|
||||
return getClass().getName(); // for compatibility
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
package io.zhile.research.intellij.action;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationInfoEx;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import io.zhile.research.intellij.helper.Constants;
|
||||
import io.zhile.research.intellij.helper.NotificationHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Scanner;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class ResetAction extends AnAction {
|
||||
private static final String OLD_MACHINE_ID_KEY = "JetBrains.UserIdOnMachine";
|
||||
private static final String NEW_MACHINE_ID_KEY = "user_id_on_machine";
|
||||
private static final String DEVICE_ID_KEY = "device_id";
|
||||
private static final String DEFAULT_COMPANY_NAME = "jetbrains";
|
||||
|
||||
public ResetAction() {
|
||||
super("Reset " + Constants.PRODUCT_NAME + "'s Eval", "Reset my IDE eval information", AllIcons.General.Reset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
|
||||
Project project = anActionEvent.getProject();
|
||||
File evalFile = getEvalFile();
|
||||
if (evalFile.exists()) {
|
||||
if (!FileUtil.delete(evalFile)) {
|
||||
NotificationHelper.showError(project, "Remove eval folder failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
File optionsFile = getOptionsFile();
|
||||
if (optionsFile.exists()) {
|
||||
try (Scanner scanner = new Scanner(optionsFile)) {
|
||||
StringBuilder sbContent = new StringBuilder();
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
if (!line.contains("name=\"evlsprt")) {
|
||||
sbContent.append(line).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
Files.write(Paths.get(optionsFile.toURI()), sbContent.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
NotificationHelper.showError(project, e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
|
||||
|
||||
String companyName = appInfo.getShortCompanyName();
|
||||
String node = StringUtil.isEmptyOrSpaces(companyName) ? DEFAULT_COMPANY_NAME : companyName.toLowerCase();
|
||||
|
||||
Preferences prefsRoot = Preferences.userRoot();
|
||||
Preferences prefs = prefsRoot.node(node);
|
||||
|
||||
prefsRoot.remove(OLD_MACHINE_ID_KEY);
|
||||
prefs.remove(NEW_MACHINE_ID_KEY);
|
||||
prefs.remove(DEVICE_ID_KEY);
|
||||
|
||||
try {
|
||||
removeEvalNode(prefs);
|
||||
} catch (BackingStoreException e) {
|
||||
NotificationHelper.showError(project, "Remove evlsprt failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
Preferences.userRoot().node(Constants.PLUGIN_NAME).put(Constants.PRODUCT_NAME + Constants.PRODUCT_HASH, Long.toString(System.currentTimeMillis()));
|
||||
|
||||
if (appInfo.isVendorJetBrains() && SystemInfo.isWindows) {
|
||||
String[] names = new String[]{"PermanentUserId", "PermanentDeviceId"};
|
||||
for (String name : names) {
|
||||
if (deleteSharedFile(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NotificationHelper.showError(project, "Remove " + name + " file failed!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NotificationHelper.showInfo(project, "Reset successfully!\nPlease restart your IDE and enjoy it!");
|
||||
ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().restart());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDumbAware() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean deleteSharedFile(String fileName) {
|
||||
String appData = System.getenv("APPDATA");
|
||||
if (appData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
File dir = Paths.get(appData, "JetBrains", fileName).toFile();
|
||||
|
||||
return !dir.exists() || dir.delete();
|
||||
}
|
||||
|
||||
protected File getEvalFile() {
|
||||
String configPath = PathManager.getConfigPath();
|
||||
|
||||
return new File(configPath, "eval");
|
||||
}
|
||||
|
||||
protected File getOptionsFile() {
|
||||
String configPath = PathManager.getConfigPath();
|
||||
|
||||
return new File(new File(configPath, "options"), "other.xml");
|
||||
}
|
||||
|
||||
protected void removeEvalNode(Preferences prefs) throws BackingStoreException {
|
||||
String[] keys = prefs.childrenNames();
|
||||
if (keys.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : keys) {
|
||||
Preferences node = prefs.node(key);
|
||||
if (key.startsWith("evlsprt")) {
|
||||
node.removeNode();
|
||||
continue;
|
||||
}
|
||||
|
||||
removeEvalNode(node);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.zhile.research.intellij.ier.action;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import io.zhile.research.intellij.ier.component.ResetTimer;
|
||||
import io.zhile.research.intellij.ier.ui.dialog.MainDialog;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ResetAction extends AnAction implements DumbAware {
|
||||
public ResetAction() {
|
||||
super("Eval Reset", "Reset my IDE eval information", AllIcons.General.Reset);
|
||||
new ResetTimer().start(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
|
||||
Project project = anActionEvent.getProject();
|
||||
if (project == null) {
|
||||
MainDialog mainDialog = new MainDialog();
|
||||
mainDialog.show();
|
||||
} else {
|
||||
ToolWindowManager.getInstance(project).getToolWindow("Eval Reset").show(null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.zhile.research.intellij.ier.common;
|
||||
|
||||
public class RecordItem {
|
||||
private final RecordType type;
|
||||
private final String key;
|
||||
private final String value;
|
||||
|
||||
public RecordItem(RecordType type, String key, String value) {
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public RecordItem(RecordType type, String key) {
|
||||
this(type, key, null);
|
||||
}
|
||||
|
||||
public RecordType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.zhile.research.intellij.ier.common;
|
||||
|
||||
public enum RecordType {
|
||||
FILE("FILE"),
|
||||
PREFERENCE("PREFERENCE"),
|
||||
PROPERTY("PROPERTY");
|
||||
|
||||
private final String value;
|
||||
|
||||
RecordType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
package io.zhile.research.intellij.ier.common;
|
||||
|
||||
import com.intellij.ide.Prefs;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.ide.util.PropertiesComponentImpl;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import io.zhile.research.intellij.ier.helper.Constants;
|
||||
import io.zhile.research.intellij.ier.helper.NotificationHelper;
|
||||
import io.zhile.research.intellij.ier.helper.Reflection;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.Element;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
public class Resetter {
|
||||
private static final String DEFAULT_VENDOR = "jetbrains";
|
||||
private static final String OLD_MACHINE_ID_KEY = "JetBrains.UserIdOnMachine";
|
||||
private static final String NEW_MACHINE_ID_KEY = DEFAULT_VENDOR + ".user_id_on_machine";
|
||||
private static final String DEVICE_ID_KEY = DEFAULT_VENDOR + ".device_id";
|
||||
private static final String IDE_EVAL_PREFIX = DEFAULT_VENDOR + "/" + Constants.IDE_NAME_LOWER + "/" + Constants.IDE_HASH;
|
||||
private static final String EVAL_KEY = "evlsprt";
|
||||
|
||||
private static final PropertiesComponentImpl PROPS = (PropertiesComponentImpl) PropertiesComponent.getInstance();
|
||||
|
||||
public static List<RecordItem> getEvalRecords() {
|
||||
List<RecordItem> list = new ArrayList<>();
|
||||
|
||||
File evalDir = getEvalDir();
|
||||
if (evalDir.exists()) {
|
||||
for (File file : evalDir.listFiles()) {
|
||||
list.add(new RecordItem(RecordType.FILE, file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
Element state = PROPS.getState();
|
||||
if (state != null) {
|
||||
Attribute attrName, attrValue;
|
||||
String key, value;
|
||||
for (Element element : state.getChildren()) {
|
||||
if (!element.getName().equals("property")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
attrName = element.getAttribute("name");
|
||||
attrValue = element.getAttribute("value");
|
||||
if (attrName == null || attrValue == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
key = attrName.getValue();
|
||||
value = attrValue.getValue();
|
||||
if (key.startsWith(EVAL_KEY)) {
|
||||
list.add(new RecordItem(RecordType.PROPERTY, key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RecordItem[] prefsValue = new RecordItem[]{
|
||||
new RecordItem(RecordType.PREFERENCE, OLD_MACHINE_ID_KEY, Preferences.userRoot().get(OLD_MACHINE_ID_KEY, null)),
|
||||
new RecordItem(RecordType.PREFERENCE, NEW_MACHINE_ID_KEY, Prefs.get(NEW_MACHINE_ID_KEY, null)),
|
||||
new RecordItem(RecordType.PREFERENCE, DEVICE_ID_KEY, Prefs.get(DEVICE_ID_KEY, null)),
|
||||
};
|
||||
for (RecordItem item : prefsValue) {
|
||||
if (null == item.getValue()) {
|
||||
continue;
|
||||
}
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
try {
|
||||
List<String> prefsList = new ArrayList<>();
|
||||
getAllPrefsKeys(Preferences.userRoot().node(IDE_EVAL_PREFIX), prefsList);
|
||||
|
||||
Method methodGetProductCode = Reflection.getMethod(IdeaPluginDescriptor.class, "getProductCode");
|
||||
Method methodGetReleaseVersion = Reflection.getMethod(IdeaPluginDescriptor.class, "getReleaseVersion");
|
||||
if (null != methodGetProductCode && null != methodGetReleaseVersion) {
|
||||
for (IdeaPluginDescriptor descriptor : PluginManager.getPlugins()) {
|
||||
String productCode = (String) methodGetProductCode.invoke(descriptor);
|
||||
if (null == productCode || productCode.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int releaseVersion = (int) methodGetReleaseVersion.invoke(descriptor);
|
||||
getAllPrefsKeys(Preferences.userRoot().node(DEFAULT_VENDOR + "/" + productCode.toLowerCase() + "/" + releaseVersion), prefsList);
|
||||
}
|
||||
}
|
||||
|
||||
for (String key : prefsList) {
|
||||
if (!key.contains(EVAL_KEY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (key.startsWith("/")) {
|
||||
key = key.substring(1).replace('/', '.');
|
||||
}
|
||||
list.add(new RecordItem(RecordType.PREFERENCE, key, Prefs.get(key, null)));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NotificationHelper.showError(null, "List eval preferences failed!");
|
||||
}
|
||||
|
||||
if (SystemInfo.isWindows) {
|
||||
String[] names = new String[]{"PermanentUserId", "PermanentDeviceId"};
|
||||
for (String name : names) {
|
||||
File file = getSharedFile(name);
|
||||
|
||||
if (null != file && file.exists()) {
|
||||
list.add(new RecordItem(RecordType.FILE, file.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void reset(List<RecordItem> recordItems) {
|
||||
for (RecordItem item : recordItems) {
|
||||
reset(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reset(RecordItem recordItem) {
|
||||
RecordType type = recordItem.getType();
|
||||
String key = recordItem.getKey();
|
||||
switch (type) {
|
||||
case FILE:
|
||||
if (!FileUtil.delete(new File(key))) {
|
||||
NotificationHelper.showError(null, "Remove " + type.getValue() + " failed: " + key);
|
||||
}
|
||||
break;
|
||||
case PREFERENCE:
|
||||
if (OLD_MACHINE_ID_KEY.equals(key)) {
|
||||
Preferences.userRoot().remove(key);
|
||||
} else {
|
||||
Prefs.remove(key);
|
||||
}
|
||||
break;
|
||||
case PROPERTY:
|
||||
PROPS.unsetValue(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected static File getSharedFile(String fileName) {
|
||||
String appData = System.getenv("APPDATA");
|
||||
if (appData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Paths.get(appData, "JetBrains", fileName).toFile();
|
||||
}
|
||||
|
||||
protected static File getEvalDir() {
|
||||
String configPath = PathManager.getConfigPath();
|
||||
|
||||
return new File(configPath, "eval");
|
||||
}
|
||||
|
||||
protected static void getAllPrefsKeys(Preferences prefs, List<String> list) throws BackingStoreException {
|
||||
String[] childrenNames = prefs.childrenNames();
|
||||
if (childrenNames.length == 0) {
|
||||
for (String key : prefs.keys()) {
|
||||
list.add(prefs.absolutePath() + "/" + key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (String childName : childrenNames) {
|
||||
getAllPrefsKeys(prefs.node(childName), list);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package io.zhile.research.intellij.ier.component;
|
||||
|
||||
import com.intellij.ide.Prefs;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import io.zhile.research.intellij.ier.helper.Constants;
|
||||
import io.zhile.research.intellij.ier.helper.DateTime;
|
||||
import io.zhile.research.intellij.ier.helper.NotificationHelper;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ResetTimer {
|
||||
private static final long RESET_PERIOD = 2160000000L; // 25 days
|
||||
private static final String RESET_KEY = "Ide-Eval-Reset." + Constants.IDE_NAME_LOWER + "." + Constants.IDE_HASH;
|
||||
|
||||
public static long getLastResetTime() {
|
||||
return Prefs.getLong(RESET_KEY, 0L);
|
||||
}
|
||||
|
||||
public static void resetLastResetTime() {
|
||||
Prefs.putLong(RESET_KEY, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static String getLastResetTimeStr() {
|
||||
long lastResetTime = getLastResetTime();
|
||||
|
||||
return lastResetTime > 0 ? DateTime.getStringFromTimestamp(lastResetTime) : "not yet";
|
||||
}
|
||||
|
||||
public void start(final AnAction resetAction) {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
new ResetTimerTask(getLastResetTime(), resetAction).run();
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
protected static class ResetTimerTask extends TimerTask {
|
||||
private final long lastResetTime;
|
||||
private final AnAction resetAction;
|
||||
|
||||
public ResetTimerTask(long lastResetTime, AnAction resetAction) {
|
||||
this.lastResetTime = lastResetTime;
|
||||
this.resetAction = resetAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (System.currentTimeMillis() - lastResetTime > RESET_PERIOD) {
|
||||
String message = "It has been a long time since the last reset!\nWould you like to reset it again?";
|
||||
Notification notification = NotificationHelper.NOTIFICATION_GROUP.createNotification(Constants.PLUGIN_NAME, null, message, NotificationType.INFORMATION);
|
||||
notification.addAction(resetAction);
|
||||
notification.notify(null);
|
||||
}
|
||||
|
||||
new Timer().schedule(new ResetTimerTask(lastResetTime, resetAction), 3600000); // 60 min
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,17 @@
|
|||
package io.zhile.research.intellij.helper;
|
||||
package io.zhile.research.intellij.ier.helper;
|
||||
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.ide.plugins.cl.PluginClassLoader;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
|
||||
public class Constants {
|
||||
public static final PluginClassLoader CLASS_LOADER = (PluginClassLoader) Constants.class.getClassLoader();
|
||||
public static final PluginId PLUGIN_ID = CLASS_LOADER.getPluginId();
|
||||
public static final String PLUGIN_NAME = PluginManager.getPlugin(PLUGIN_ID).getName();
|
||||
public static final String PRODUCT_NAME = ApplicationNamesInfo.getInstance().getFullProductName();
|
||||
public static final String PRODUCT_HASH = Integer.toString(PathManager.getConfigPath().hashCode());
|
||||
public static final String IDE_NAME = ApplicationNamesInfo.getInstance().getProductName();
|
||||
public static final String IDE_NAME_LOWER = IDE_NAME.toLowerCase();
|
||||
public static final String IDE_HASH = Integer.toHexString(FileUtil.pathHashCode(PathManager.getHomePath()));
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package io.zhile.research.intellij.ier.helper;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class DateTime {
|
||||
public static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public static String getStringFromTimestamp(long timestamp) {
|
||||
Date date = new Date(timestamp);
|
||||
|
||||
return df.format(date);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.zhile.research.intellij.helper;
|
||||
package io.zhile.research.intellij.ier.helper;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.notification.Notification;
|
|
@ -0,0 +1,13 @@
|
|||
package io.zhile.research.intellij.ier.helper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Reflection {
|
||||
public static Method getMethod(Class<?> klass, String methodName, Class<?>... methodParameterTypes) {
|
||||
try {
|
||||
return klass.getMethod(methodName, methodParameterTypes);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package io.zhile.research.intellij.ier.listener;
|
||||
|
||||
import com.intellij.ide.plugins.DynamicPluginListener;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import io.zhile.research.intellij.ier.helper.NotificationHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PluginListener implements DynamicPluginListener {
|
||||
@Override
|
||||
public void pluginLoaded(@NotNull IdeaPluginDescriptor pluginDescriptor) {
|
||||
ActionManager.getInstance().getAction("io.zhile.research.intellij.ier.action.ResetAction");
|
||||
|
||||
NotificationHelper.showInfo(null, "Plugin installed successfully! Now enjoy it~");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.zhile.research.intellij.ier.tw;
|
||||
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowFactory;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import io.zhile.research.intellij.ier.ui.form.MainForm;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MainToolWindowFactory implements ToolWindowFactory, DumbAware {
|
||||
@Override
|
||||
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
|
||||
MainForm mainForm = new MainForm(null);
|
||||
Content content = ContentFactory.SERVICE.getInstance().createContent(mainForm.getContent(), "", true);
|
||||
toolWindow.getContentManager().addContent(content);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package io.zhile.research.intellij.ier.ui.dialog;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import io.zhile.research.intellij.ier.ui.form.MainForm;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class MainDialog extends DialogWrapper {
|
||||
public MainDialog() {
|
||||
super(true);
|
||||
init();
|
||||
setTitle("Eval Reset");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
MainForm mainForm = new MainForm(this);
|
||||
return mainForm.getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createSouthPanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="io.zhile.research.intellij.ier.ui.form.MainForm">
|
||||
<grid id="27dc6" binding="rootPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="c0103" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="0">
|
||||
<constraints border-constraint="North"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="aeaef" class="javax.swing.JLabel" binding="lblLastResetTimeLabel">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="Last Reset Time:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="782c3" class="javax.swing.JLabel" binding="lblLastResetTime">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="f8be5" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="2">
|
||||
<constraints border-constraint="South"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="382d3" class="javax.swing.JButton" binding="btnReloadList">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="⟳ Reload List"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7f8d9" class="javax.swing.JButton" binding="btnReset">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="Reset"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="60ebc" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="c9bb0" layout-manager="FlowLayout" hgap="5" vgap="5" flow-align="0">
|
||||
<constraints border-constraint="North"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="e7c88" class="javax.swing.JLabel" binding="lblFound">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<text value="Found:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="7c492" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="5" left="5" bottom="5" right="5"/>
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="1f2f8">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="empty"/>
|
||||
<children>
|
||||
<component id="5b0c2" class="javax.swing.JList" binding="lstMain">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<selectionMode value="0"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
|
@ -0,0 +1,100 @@
|
|||
package io.zhile.research.intellij.ier.ui.form;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import io.zhile.research.intellij.ier.common.RecordItem;
|
||||
import io.zhile.research.intellij.ier.common.Resetter;
|
||||
import io.zhile.research.intellij.ier.component.ResetTimer;
|
||||
import io.zhile.research.intellij.ier.helper.Constants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.List;
|
||||
|
||||
public class MainForm {
|
||||
private JPanel rootPanel;
|
||||
private JButton btnReset;
|
||||
private JList lstMain;
|
||||
private JLabel lblLastResetTime;
|
||||
private JButton btnReloadList;
|
||||
private JLabel lblFound;
|
||||
private JLabel lblLastResetTimeLabel;
|
||||
|
||||
private final DialogWrapper dialogWrapper;
|
||||
private final DefaultListModel<String> listModel = new DefaultListModel<>();
|
||||
|
||||
public MainForm(DialogWrapper dialogWrapper) {
|
||||
this.dialogWrapper = dialogWrapper;
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
boldFont(lblFound);
|
||||
boldFont(lblLastResetTimeLabel);
|
||||
|
||||
lblLastResetTime.setText(ResetTimer.getLastResetTimeStr());
|
||||
lstMain.setModel(listModel);
|
||||
|
||||
reloadRecordItems();
|
||||
btnReloadList.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
reloadRecordItems();
|
||||
}
|
||||
});
|
||||
|
||||
btnReset.setIcon(AllIcons.General.Reset);
|
||||
btnReset.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
resetEvalItems();
|
||||
}
|
||||
});
|
||||
|
||||
if (null != dialogWrapper) {
|
||||
dialogWrapper.getRootPane().setDefaultButton(btnReset);
|
||||
}
|
||||
|
||||
rootPanel.setMinimumSize(new Dimension(600, 240));
|
||||
return rootPanel;
|
||||
}
|
||||
|
||||
private void reloadRecordItems() {
|
||||
listModel.clear();
|
||||
|
||||
List<RecordItem> recordItemList = Resetter.getEvalRecords();
|
||||
for (RecordItem item : recordItemList) {
|
||||
listModel.addElement(item.getType().getValue() + ": \t" + item.getKey() + (null == item.getValue() ? "" : " = \t" + item.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
private void resetEvalItems() {
|
||||
Resetter.reset(Resetter.getEvalRecords());
|
||||
ResetTimer.resetLastResetTime();
|
||||
listModel.clear();
|
||||
|
||||
if (Messages.YES == Messages.showYesNoDialog("Reset successfully!\nWould like to restart your IDE?", Constants.PLUGIN_NAME, AllIcons.General.Reset)) {
|
||||
if (null != dialogWrapper) {
|
||||
dialogWrapper.close(0);
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().restart();
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
reloadRecordItems();
|
||||
}
|
||||
|
||||
private static void boldFont(Component component) {
|
||||
Font font = component.getFont();
|
||||
component.setFont(font.deriveFont(font.getStyle() | Font.BOLD));
|
||||
}
|
||||
}
|
|
@ -1,24 +1,30 @@
|
|||
<idea-plugin>
|
||||
<id>io.zhile.research.ide-eval-resetter</id>
|
||||
<name>ide-eval-resetter</name>
|
||||
<name>IDE Eval Reset</name>
|
||||
<vendor url="https://zhile.io">zhile.io</vendor>
|
||||
|
||||
<description><![CDATA[
|
||||
I can reset your IDE eval information.<br>
|
||||
<em>Click "Help" menu and select "Reset IDE Eval"</em>
|
||||
<em>Click "Help" menu and select "Eval Reset"</em>
|
||||
]]></description>
|
||||
|
||||
<depends>com.intellij.modules.lang</depends>
|
||||
<depends>com.intellij.modules.ultimate</depends>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<toolWindow id="Eval Reset" anchor="bottom" icon="AllIcons.General.Reset"
|
||||
factoryClass="io.zhile.research.intellij.ier.tw.MainToolWindowFactory"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action class="io.zhile.research.intellij.action.ResetAction" id="io.zhile.research.intellij.action.ResetAction">
|
||||
<action class="io.zhile.research.intellij.ier.action.ResetAction"
|
||||
id="io.zhile.research.intellij.ier.action.ResetAction">
|
||||
<add-to-group group-id="HelpMenu" anchor="last"/>
|
||||
<add-to-group group-id="WelcomeScreen.Documentation" anchor="last"/>
|
||||
</action>
|
||||
</actions>
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>io.zhile.research.intellij.MainComponent</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<applicationListeners>
|
||||
<listener class="io.zhile.research.intellij.ier.listener.PluginListener"
|
||||
topic="com.intellij.ide.plugins.DynamicPluginListener"/>
|
||||
</applicationListeners>
|
||||
</idea-plugin>
|
Loading…
Reference in New Issue