I am trying to write a gradle code to save file versions to a meta property file. then if version updated, download new version and update the property file to avoid download again if version not updated.
Below code basic function works but two minor issues:
every time run ./gradle demo command, the first line in versions.txt will update a timestamp, I would like to disable it but not sure how.
Sometimes the item no version change will move location (e.g move from line 10 to line 15). That means the sequence of items in property file not stable. I would like only the version changed item get updated each time.
import groovy.json.JsonBuilder
apply plugin: 'java'
public String getDownloadedVersion(verFile,key) {
String value = null;
Properties prop = new Properties();
FileInputStream is = new FileInputStream(verFile);
prop.load(is);
value = prop.getProperty(key);
is.close();
return value
}
public void writeDownloadedVersion(verFile,key,value) {
Properties verProp = new Properties();
FileInputStream verInputStream;
FileOutputStream verOutputStream;
try {
if( verFile.exists() ) {
verInputStream = new FileInputStream(verFile)
verProp.load(verInputStream);
verInputStream.close();
}
verOutputStream = new FileOutputStream(verFile);
verProp.setProperty(key, value);
verProp.store(verOutputStream, null);
verOutputStream.close();
} catch(IOException e) {
System.out.println("exception " + e)
e.printStackTrace();
}
}
public boolean version_changed(verFile,file,version) {
def localVersion = getDownloadedVersion(verFile,file)
def found = false
if (localVersion != version) {
found = true
}
return found
}
tasks.register('demo') {
def fileLst = [
["abc","3.0"],
["def","4.0"],
["ghi","5.0"],
["jkl","2.0"],
["mno","1.0"],
["pqr","2.0"],
["stu","5.0"],
["vwx","2.0"],
]
doLast {
def verFile = new File(".", "versions.txt");
fileLst.each {file, version ->
if (version_changed(verFile,file,version)) {
System.out.println(file + " " + version)
//download version
writeDownloadedVersion(verFile,file,version)
}
}
}
}
Sample version.txt file:
#Thu Apr 28 16:40:02 CDT 2022
jkl=2.0
mno=1.0
pqr=2.0
abc=3.0
stu=5.0
def=4.0
vwx=2.0
ghi=5.0
If any other better solution, please help comment!
Related
I need to check current version of Installed Application and Playstore application version. If it is not same app should navigate to Playstore .
im using xam.Plugin.LatestVersion(2.1.0) To get the latestversion number of application from play console. unfortunately not getting latest version number of application from play store. The below code im using.
private async void ChekAppVersion()
{
try
{
latestVersionNumber = await CrossLatestVersion.Current.GetLatestVersionNumber();
installedVersionNumber = CrossLatestVersion.Current.InstalledVersionNumber;
if (installedVersionNumber != latestVersionNumber)
{
await DisplayAlert("New Version", "There is a new version of this app available. Please update now?", "Ok");
await CrossLatestVersion.Current.OpenAppInStore();
ChekAppVersion();
}
else
{
}
}
catch (Exception ex)
{
}
}
Im getting the installedVersionNumber, but im unable to get the latestVersionNumber(Playstore).
Please help on this.
They have removed the version from div, now it's displayed with js, but data is still there inside a <script> tag. My current fixed code is:
private bool _lockCheckUpdates;
public async Task<bool> CheckNeedUpdate()
{
if (Connectivity.NetworkAccess != NetworkAccess.Internet || _lockCheckUpdates)
return false;
_lockCheckUpdates = true;
try
{
HttpClient myClient = CreateClient();
if (Device.RuntimePlatform == Device.Android)
{
var bundle = "com.todo.app"; //ANDROID BUNDLE NAME HERE
string url = $"https://play.google.com/store/apps/details?id={bundle}&hl=en";
string raw = await myClient.GetStringAsync(new Uri(url));
var doc = new HtmlDocument();
doc.LoadHtml(raw);
var scripts = doc.DocumentNode.Descendants()
.Where(n => n.Name == "script" && n.InnerText.Contains("AF_initDataCallback({key: 'ds:4'"))
.ToArray();
var script = scripts.First().InnerText;
var engine = new Jurassic.ScriptEngine();
var eval = "(function() { var AF_initDataCallback = function(p) { return p.data[1][2][140][0][0][0]; }; return " + script + " })()";
var result = engine.Evaluate(eval);
//var json = JSONObject.Stringify(engine, result); //for debug, check in browser console with JSON.parse(json)
var remote = $"{result}".ToDouble();
var local = App.Version.ToDouble();
return local < remote;
}
else if (Device.RuntimePlatform == Device.iOS)
{
var bundle = "com.todo.app";//iOS BUNDLE NAME HERE
string url = $"http://itunes.apple.com/lookup?bundleId={bundle}";
string raw = await myClient.GetStringAsync(new Uri(url));
var dto = JsonConvert.DeserializeObject<AppStoreRecord>(raw);
double local = App.Version.ToDouble();
if (dto.ResultCount > 0)
{
double remote = dto.Results[0].Version.ToDouble();
return remote > local;
}
}
}
catch (Exception e)
{
Logger.Error("CheckNeedUpdate", e);
}
finally
{
_lockCheckUpdates = false;
}
return false;
}
Using nugets
Jurassic to evaluate the script on page,
HtmlAgilityPack to parse html,
Xamarin.Essentials to check if we are online,
and AppoMobi.Specials for .ToDouble() etc
I hope this could also be useful to fix https://github.com/edsnider/latestversionplugin/issues/43 :)
The plugin you are using no longer works for Android https://github.com/edsnider/latestversionplugin/issues/43
You will need to find a new way to get the desired information.
PR has been made on this plugin... it works again ;-)
What is the correct way to write a gradle task which downloads a .jar(or any other) file from artifactory to project directory(if file does not already exists)?
For example, I have a project with path /root/project with file /root/project/build.gradle inside. I want to download generator.jar from artifactory (com/company/project/generator/1.0) to /root/project directory if /root/project/generator.jar is not present.
tasks.register("downloadGeneratorJar") {
group = 'Download'
description = 'Downloads generator.jar'
doLast {
def f = new File('generator.jar')
if (!f.exists()) {
URL artifactoryUrl = new URL('myurl')
HttpURLConnection myURLConnection = (HttpURLConnection)artifactoryUrl.openConnection()
String userCredentials = gradle.ext.developerUser + ":" + gradle.ext.developerPassword
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()))
myURLConnection.setRequestProperty ("Authorization", basicAuth)
InputStream is = myURLConnection.getInputStream()
new FileOutputStream(f).withCloseable { outputStream ->
int read
byte[] bytes = new byte[1024]
while ((read = is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read)
}
}
}
}
}
I am using AEM 6.1 with Maven as the build manager. I have updated the .m2 local folder with the unobfuscated UberJar provided by Adobe. I am getting the following error:
ERROR [JobHandler: /etc/workflow/instances/server0/2016-07-15/model_157685507700064:/content/myApp/testing/wf_test01]
com.adobe.granite.workflow.core.job.JobHandler Process implementation
not found: com.myApp.workflow.ActivatemyAppPageProcess
com.adobe.granite.workflow.WorkflowException: Process implementation
not found: com.myApp.workflow.ActivatemyAppPageProcess at
com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:197)
at
com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.java:232)
at
org.apache.sling.event.impl.jobs.JobConsumerManager$JobConsumerWrapper.process(JobConsumerManager.java:512)
at
org.apache.sling.event.impl.jobs.queues.JobRunner.run(JobRunner.java:205)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
The UberJar does not seem to have the com.adobe.granite.workflow.core.job package. Is there any way to resolve this issue?
The .execute method for the process step ActivatemyAppPageProcess:
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException {
Session participantSession = null;
Session replicationSession = null;
// ResourceResolver resourceResolver = null;
try {
log.info("Inside ActivatemyAppPageProcess ");
Session session = workflowSession.getSession();
if (replicateAsParticipant(args)) {
String approverId = resolveParticipantId(workItem, workflowSession);
if (approverId != null) {
participantSession = getParticipantSession(approverId, workflowSession);
}
}
if (participantSession != null)
replicationSession = participantSession;
else {
replicationSession = session;
}
WorkflowData data = workItem.getWorkflowData();
String path = null;
String type = data.getPayloadType();
if ((type.equals("JCR_PATH")) && (data.getPayload() != null)) {
String payloadData = (String) data.getPayload();
if (session.itemExists(payloadData))
path = payloadData;
}
else if ((data.getPayload() != null) && (type.equals("JCR_UUID"))) {
Node node = session.getNodeByUUID((String) data.getPayload());
path = node.getPath();
}
ReplicationOptions opts = null;
String rev = (String) data.getMetaDataMap().get("resourceVersion", String.class);
if (rev != null) {
opts = new ReplicationOptions();
opts.setRevision(rev);
}
opts = prepareOptions(opts);
if (path != null) {
ResourceCollection rcCollection =
ResourceCollectionUtil
.getResourceCollection(
(Node) this.admin.getItem(path),
(ResourceCollectionManager) this.rcManager);
boolean isWFPackage = isWorkflowPackage(path, resolverFactory, workflowSession);
List<String> paths = getPaths(path, rcCollection);
for (String aPath : paths)
if (canReplicate(replicationSession, aPath)) {
if (opts != null) {
if (isWFPackage) {
setRevisionForPage(aPath, opts, data);
}
this.replicator
.replicate(replicationSession,
getReplicationType(),
aPath,
opts);
} else {
this.replicator
.replicate(replicationSession,
getReplicationType(),
aPath);
}
} else {
log.debug(session.getUserID() + " is not allowed to replicate " + "this page/asset " + aPath + ". Issuing request for 'replication");
Dictionary properties = new Hashtable();
properties.put("path", aPath);
properties.put("replicationType", getReplicationType());
properties.put("userId", session.getUserID());
Event event = new Event("com/day/cq/wcm/workflow/req/for/activation", properties);
this.eventAdmin.sendEvent(event);
}
} else {
log.warn("Cannot activate page or asset because path is null for this workitem: " + workItem.toString());
}
} catch (RepositoryException e) {
throw new WorkflowException(e);
} catch (ReplicationException e) {
throw new WorkflowException(e);
} finally {
if ((participantSession != null) && (participantSession.isLive())) {
participantSession.logout();
participantSession = null;
}
}
}
com.adobe.granite.workflow.core.job is not exported in AEM at all. That means, you cannot use it because it is invisible to your code.
The com.adobe.granite.workflow.core bundle does only export com.adobe.granite.workflow.core.event.
If you work with the AEM workflows, you should stick to the com.adobe.granite.workflow.api bundle.
The following packages are exported in this bundle and therefore useable:
com.adobe.granite.workflow,version=1.0.0
com.adobe.granite.workflow.collection,version=1.1.0
com.adobe.granite.workflow.collection.util,version=1.0.0
com.adobe.granite.workflow.event,version=1.0.0
com.adobe.granite.workflow.exec,version=1.0.0
com.adobe.granite.workflow.exec.filter,version=1.0.0
com.adobe.granite.workflow.job,version=1.0.0
com.adobe.granite.workflow.launcher,version=1.0.0
com.adobe.granite.workflow.metadata,version=1.0.0
com.adobe.granite.workflow.model,version=1.0.0
com.adobe.granite.workflow.rule,version=1.0.0
com.adobe.granite.workflow.serialization,version=1.0.0
com.adobe.granite.workflow.status,version=1.0.0
Even if the uber.jar has the packages , if you look on your AEM instance on /system/console/bundles and click on the com.adobe.granite.workflow.core package, you will see that in "exported packages" there is no com.adobe.granite.workflow.core.job available. So even if your IDE, Maven and/or Jenkins can handle it, AEM will not be able to execute your code.
In AEM you can only use packages that are exported in one of the available bundles or that are included in your bundle - what would be a bad idea. You would then have two versions of the same code and that will lead to further problems.
Having seen the code I would say there's another problem here. And solving that one will help you get rid off the other one, too.
You try to start another WF (request for activation) for a path that is already used in a workflow.
You have to terminate the current workflow instance to be able to do this.
An example for a clean way to do this would be:
Workflow workflow = workItem.getWorkflow();
WorkflowData wfData = workflow.getWorkflowData();
workflowSession.terminateWorkflow(workflow);
Map<String, Object> paramMap = new HashMap<String, Object>();
if (!StringUtils.isEmpty(data.getNextParticipantUid())) {
paramMap.put("nextParticipant", "admin");
}
workflowSession.startWorkflow(
workflowSession.getModel(WORKFLOW_MODEL_PATH, wfData, paramMap);
The possible reason for the error could be that your workflow process com.myApp.workflow.ActivatemyAppPageProcess service/component is not active because of which its not bound to JobHandler's list of available processes thus causing this exception.
Can you check in /system/console/components that your custom process component is active? If not then you will have to resolve the dependency which is causing the service/component to be not available.
I am new to CRM and I have created a new AutoNumber plugin (actually modified an existing plugin).
I am having issues getting this plugin to work on the CRM side.
I have created the plugin, and I have created a CREATE step. I am confused with the IMAGE creation, and how I need to go about doing this.
Also, I am using the localContext.Trace and I am not sure where to view this information.
Can anyone help me with understanding the exact steps I need to follow to implement this plugin. I will include my code here in case I am doing something wrong. Again, this was a working plugin and I just modified it. I tried to follow the pattern used by the previous developer.
FYI -- I have purchased the CRM Solution Manager utility to help with the deployment process, but still not having any luck.
Thanks in advance for your time.
Here is the code..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IccPlugin.ProxyClasses;
using IccPlugin.ProxyClasses.ProxyClasses;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace IccPlugin {
public class ProgramReportAutoNumber : PluginBase {
private readonly string imageAlias = "ProgramReport";
private new_programreport preImage { get; set; }
private new_programreport postImage { get; set; }
private new_programreport targetEntity { get; set; }
private readonly string imageAlias_program = "Program";
private new_program preImage_program { get; set; }
private new_program postImage_program { get; set; }
private new_program targetEntity_program { get; set; }
public ProgramReportAutoNumber(string unsecure, string secure)
: base(typeof(ProgramReportAutoNumber), unsecure, secure) {
base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PreOperation, "Create", "new_programreport", new Action<LocalPluginContext>(Execute)));
//base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Update", "new_programreport", new Action<LocalPluginContext>(Execute)));
//base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Delete", "new_programreport", new Action<LocalPluginContext>(Execute)));
}
protected void Execute(LocalPluginContext localContext) {
if (localContext == null) {
throw new ArgumentNullException("localContext");
}
IPluginExecutionContext context = localContext.PluginExecutionContext;
if (context.PreEntityImages.Contains(imageAlias) && (context.PreEntityImages[imageAlias] is Entity)) {
preImage = new new_programreport((Entity)context.PreEntityImages[imageAlias]);
}
if (context.PostEntityImages.Contains(imageAlias) && (context.PostEntityImages[imageAlias] is Entity)) {
postImage = new new_programreport((Entity)context.PostEntityImages[imageAlias]);
}
if (context.PreEntityImages.Contains(imageAlias_program) && (context.PreEntityImages[imageAlias_program] is Entity)) {
preImage_program = new new_program((Entity)context.PreEntityImages[imageAlias_program]);
}
if (context.PostEntityImages.Contains(imageAlias_program) && (context.PostEntityImages[imageAlias_program] is Entity)) {
postImage_program = new new_program((Entity)context.PostEntityImages[imageAlias_program]);
}
if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity)) {
targetEntity = new new_programreport((Entity)context.InputParameters["Target"]);
}
switch (context.MessageName) {
case "Create":
HandleCreate(localContext);
break;
case "Update":
HandleUpdate(localContext);
break;
case "Delete":
HandleDelete(localContext);
break;
default:
throw new ArgumentException("Invalid Message Name: " + context.MessageName);
}
}
private void HandleDelete(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleDelete");
try {
if (preImage == null) {
throw new Exception("IccPlugin.ProgramReport.AutoNumber.HandleDelete: preImage is null, unable to process the delete message.");
}
// TODO: Add code here to implement delete message.
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleDelete: Exception while processing the delete message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleDelete");
}
return;
}
private void HandleUpdate(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");
if (preImage == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the pre-operation image using alias" + imageAlias;
localContext.Trace(msg);
throw new Exception(msg);
}
if (postImage == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the post-operation image using alias" + imageAlias;
localContext.Trace(msg);
throw new Exception(msg);
}
if (preImage_program == null) {
string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the pre-operation image using alias" + imageAlias_program;
localContext.Trace(msg);
throw new Exception(msg);
}
if (postImage_program == null) {
string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the post-operation image using alias" + imageAlias_program;
localContext.Trace(msg);
throw new Exception(msg);
}
try {
// TODO: Add code here to implement update message.
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleUpdate: Exception while processing the update message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");
}
return;
}
private void HandleCreate(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleCreate");
if (targetEntity == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleCreate : The Create step is not registered correctly. Unable to retrieve the target entity using alias Target.";
localContext.Trace(msg);
throw new Exception(msg);
}
try {
// if the target entity does not have the new_filenumber attribute set we will set it now.
if (targetEntity.new_filenumber != null && targetEntity.new_filenumber != "") {
// log a warning message and do not change this value.
localContext.Trace("The Program Report being created already has a value for File Number, skipping the auto number assignment for this field.");
} else {
SetFileNumber(localContext);
}
if (targetEntity.new_name != null && targetEntity.new_name != "") {
localContext.Trace("The Program Report being created already has a value for Report Number, skipping the auto number assignment for this field.");
} else {
SetReportNumber(localContext);
}
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleCreate: Exception while processing the create message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleCreate");
}
return;
}
private void SetFileNumber(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
string s_new_filenumberformat = string.Empty;
string s_new_reportnumberprefix = string.Empty;
string s_new_filenumbercode = string.Empty;
try {
IOrganizationService service = localContext.OrganizationService;
string fileNumberValue = "";
emds_autonumbersequence fileNumberSequence = null;
// ##################################################################################################
// 05/02/2013 -- BEP -- Code added for the following change to the auto-number for file numbering
// ##################################################################################################
// 1 - Year/Month/Sequence
// [Year]-[Month]-[Sequence] = [Year] is the current year / [Month] is the current month / [Sequence] is a number series for each Year & Month and resets to 1 when the Month changes
// 2 - Year/PMG/Sequence - PMG
// [Year]-[PMGProductType][Sequence] = [Year] is the current year / [PMGProductType] is 1st letter from the PMG Product Type on the Program Report / [Sequence] is a single number series for this Format
// 3 - Year/Letter/Sequence - ESL,VAR
// [Year]-[FileCode][Sequence] = [Year] is the current year / [FileCode] is from a new field on the Program entity / [Sequence] is a number series for each Format & File Code
// ##################################################################################################
localContext.Trace("Look at the File Number Format to determine which format to use for the Auto-Number, will default to 1 if not set");
if (targetEntity_program.new_filenumberformat.ToString() != "") {
localContext.Trace("A value was set for the new_filenumberformat field, so we will be using this value.");
s_new_filenumberformat = targetEntity_program.new_filenumberformat.ToString();
} else {
localContext.Trace("A value was NOT set for the new_filenumberformat field, so we will be using 1 as the default.");
s_new_filenumberformat = "1";
}
localContext.Trace("File Number Format Being Used = " + s_new_filenumberformat);
switch (s_new_filenumberformat) {
case "1":
#region File Format #1
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), DateTime.Now.ToString("MM"));
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_1 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_1.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_1 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_1);
if (lFileNumberSequences_1 == null || lFileNumberSequences_1.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = fileNumberValue;
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_1[0];
}
// ###############################################################################
// 05/02/2013 -- BEP -- Changed the format from "###" to be "##" for seq number
// ###############################################################################
fileNumberValue = String.Format("{0}-{1:00}", fileNumberValue, fileNumberSequence.emds_index);
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
case "2":
#region File Format #2
if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
} else {
localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
s_new_reportnumberprefix = "P";
}
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_reportnumberprefix);
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_2 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_2.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, "PMG");
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_2 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_2);
if (lFileNumberSequences_2 == null || lFileNumberSequences_2.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = "PMG";
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_2[0];
}
fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
case "3":
#region File Format #3
if (targetEntity_program.new_filenumbercode != null && targetEntity_program.new_filenumbercode != "") {
localContext.Trace("A value was set for the new_filenumbercode field, so we will be using this value.");
s_new_filenumbercode = targetEntity_program.new_filenumbercode;
} else {
localContext.Trace("A value was NOT set for the new_filenumbercode field, so we will be using L as the default.");
s_new_filenumbercode = "l";
}
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_filenumbercode);
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_3 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_3.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_3 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_3);
if (lFileNumberSequences_3 == null || lFileNumberSequences_3.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = fileNumberValue;
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_3[0];
}
fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
default:
break;
}
targetEntity.new_filenumber = fileNumberValue;
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetFileNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
}
}
private void SetReportNumber(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
string s_new_reportnumberprefix = string.Empty;
try {
IOrganizationService service = localContext.OrganizationService;
string reportNumberValue = "";
emds_autonumbersequence reportNumberSequence = null;
// ##################################################################################################
// 05/02/2013 -- BEP -- Code added for the following change to the auto-number for file numbering
// ##################################################################################################
// Currently the plugin uses the GP Class Id as the prefix for the Report Number.
// It now needs to use the Report Number Prefix field.
// ##################################################################################################
if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
} else {
localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
s_new_reportnumberprefix = "P";
}
localContext.Trace("Building QueryExpression to retrieve parent new_program record.");
// #################################################################################
// 05/02/2013 -- BEP -- The above code replaces the need to pull the GP Class ID
// #################################################################################
//new_program program = targetEntity.new_programid.RetrieveProxy<new_program>(service, new ColumnSet(true));
// going to assume that we were able to get the parent program record. If not an exception will be thrown.
// could add a check here and throw our own detailed exception if needed.
reportNumberValue = String.Format("{0}", s_new_reportnumberprefix); // using Trim just to be safe.
// now lets get the sequence record for this Report Number Prefix
QueryExpression qeReportNumberSequence = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeReportNumberSequence.ColumnSet = new ColumnSet(true);
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_name);
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, reportNumberValue);
localContext.Trace("Getting Report Number sequence record.");
List<emds_autonumbersequence> lReportNumberSequences = service.RetrieveProxies<emds_autonumbersequence>(qeReportNumberSequence);
if (lReportNumberSequences == null || lReportNumberSequences.Count == 0) {
localContext.Trace("No Report Number sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
reportNumberSequence = new emds_autonumbersequence();
reportNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_name;
reportNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
reportNumberSequence.emds_index = 1;
reportNumberSequence.emds_prefix = reportNumberValue;
reportNumberSequence.emds_name = String.Format("Report Number Sequence For Report Number Prefix: {0}", reportNumberValue);
reportNumberSequence.Create(service);
} else {
localContext.Trace("A Report Number sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
reportNumberSequence = lReportNumberSequences[0];
}
reportNumberValue = String.Format("{0}-{1}", reportNumberValue, reportNumberSequence.emds_index);
reportNumberSequence.emds_index++;
reportNumberSequence.Update(service);
targetEntity.new_name = reportNumberValue;
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetReportNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
}
}
}
}
This is specifically to response to:
I am using the localContext.Trace and I am not sure where to view this
information
From the MSDN; Debug a Plug-In - Logging and Tracing
During execution and only when that plug-in passes an exception back
to the platform at run-time, tracing information is displayed to the
user. For a synchronous registered plug-in, the tracing information is
displayed in a dialog box of the Microsoft Dynamics CRM web
application. For an asynchronous registered plug-in, the tracing
information is shown in the Details area of the System Job form in the
web application.
I'm looking for a simple solution, on how to Unlist (delete) a package from Nuget library with all of it's versions.
I'm asking this, because manually I can do this 1 version at a time for 1 package. And I have lots of packages with ~20+ versions each ..
Please help.
I know this is old, but the nuget "delete" command is still not implemented, so I needed a solution. Perhaps someone can still benefit from this. I created a Command-line program and added the Nuget package Headless. Then, the code is:
class Program
{
static void Main(string[] args)
{
List<PostEntry> parameters = new List<PostEntry>();
using (var browser = new Browser())
{
var loginPage = browser.GoTo<LoginPage>();
parameters.Clear();
parameters.Add(new PostEntry("SignIn.UserNameOrEmail", "yournugetusername"));
parameters.Add(new PostEntry("SignIn.Password", "yournugetpassword"));
parameters.Add(new PostEntry("ReturnUrl", "/"));
parameters.Add(new PostEntry("LinkingAccount", "false"));
parameters.Add(new PostEntry("__RequestVerificationToken", loginPage.Find<HtmlElement>().ById("signIn").Find<HtmlInput>().ByName("__RequestVerificationToken").Value));
browser.PostTo(parameters, new Uri("https://www.nuget.org/users/account/SignIn"));
Console.WriteLine("logged in");
var cont = true;
while (cont)
{
var packagesPage = browser.GoTo<PackagesPage>();
Console.WriteLine("at packages page");
var links = packagesPage.Find<HtmlElement>()
.ById("published")
.Find<HtmlLink>()
.AllByPredicate(o => o.GetAttribute("title") == "Delete"
&& (o.Href.Contains("/IdOfPackageIWantToDelete/")
|| o.Href.Contains("/IdOfAnotherPackageIWantToDelete/")));
cont = links.Count() >= 1;
if (links.Any())
{
var htmlLink = links.First();
var linkPage = htmlLink.Href;
Console.WriteLine(linkPage);
var deletePackagePage = htmlLink.Click();
parameters.Clear();
parameters.Add(new PostEntry("Listed", "false"));
parameters.Add(new PostEntry("__RequestVerificationToken", deletePackagePage.Find<HtmlElement>().ById("body").Find<HtmlInput>().ByName("__RequestVerificationToken").Value));
browser.PostTo(parameters, new Uri("https://www.nuget.org" + linkPage));
Console.WriteLine("delete submitted");
}
}
}
Console.WriteLine("Hit any key to quit");
Console.ReadKey();
}
public class LoginPage : HtmlPage
{
public override Uri TargetLocation
{
get { return new Uri("https://www.nuget.org/users/account/LogOn?returnUrl=%2F"); }
}
}
public class PackagesPage : HtmlPage
{
public override Uri TargetLocation
{
get { return new Uri("https://www.nuget.org/account/Packages"); }
}
}
}
It will take a little while to run, but it does the trick.
You could write a batch script to call nuget delete, iterating over all your packages - see http://docs.nuget.org/docs/reference/command-line-reference#Delete_Command
e.g.
nuget delete MyPackage 1.1 -NoPrompt
nuget delete MyPackage 1.2 -NoPrompt
etc. Pretty straightforward with grep or a search/replace in a text editor.
You can do this with PowerShell, here is a function:
function Remove-AllNuGetPackageVersions($PackageId, $ApiKey)
{
$lower = $PackageId.ToLowerInvariant();
$json = Invoke-WebRequest -Uri "https://api.nuget.org/v3-flatcontainer/$lower/index.json" | ConvertFrom-Json
foreach($version in $json.versions)
{
Write-Host "Unlisting $PackageId, Ver $version"
Invoke-Expression "nuget delete $PackageId $version $ApiKey -source https://api.nuget.org/v3/index.json -NonInteractive"
}
}
If you are hosting your own nuget gallery, you could execute the following SQL query against the nuget database:
select 'nuget delete ' + pr.Id + ' ' + p.Version + ' {ApiKey} -source {Source} -noninteractive' from Packages p
join PackageRegistrations pr
on p.PackageRegistrationKey = pr.[Key]
where pr.Id = '{PackageId}' AND
p.Listed = 1
Replace {ApiKey}, {Source} and {PackageId} with your own values, I then placed the results in a batch file adjacent to nuget.exe and executed.
You can use a combination of tools by creating a simple console application.
Create a new Console application and install the package "Nuget.Core".
Add the following method to get a list of all package versions:
private static IEnumerable<IPackage> GetListedPackages(string packageID)
{
var repo = PackageRepositoryFactory.Default.CreateRepository("https://packages.nuget.org/api/v2");
var packages = from package in repo.FindPackagesById(packageID)
where package.IsListed()
select package;
return packages;
}
Then copy nuget.exe from the ".nuget" folder in one of your projects into the console application project (add it in the solution explorer and make sure that it's copied to the output directory)
Next create a new method which uses nuget.exe to unlist the package version:
private static string UnlistPackage(IPackage package, string apiKey)
{
var arguments = $"delete {package.Id} {package.Version} -ApiKey {apiKey} -NonInteractive";
var psi = new ProcessStartInfo("nuget.exe", arguments)
{
RedirectStandardOutput = true,
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
UseShellExecute = false
};
var process = Process.Start(psi);
process.WaitForExit();
return process.StandardOutput.ReadToEnd();
}
Finally change Main method so it gets a list and removes all versions:
private static void Main(string[] args)
{
var packageID = "yourPackageName";
var apiKey = "yourKeyFromNugetOrg";
var packages = GetListedPackages(packageID);
foreach (var package in packages)
{
Console.WriteLine("Unlisting package " + package);
var output = UnlistPackage(package, apiKey);
Console.WriteLine(output);
}
Console.Write("Completed. Press ENTER to quit.");
Console.ReadLine();
}
source: http://blog.gauffin.org/2016/09/how-to-remove-a-package-from-nuget-org/