Dynamically generating Hudson custom workspace path - build

I'm trying to get a Hudson job to get built in a custom workspace path that is automatically generated using yyyyMMdd-HHmm. I can get the $BUILD_ID variable expanded as mentioned in bug 3997, and that seems to work fine. However, the workspace path is incorrect as it is of the format yyyy-MM-dd_HH-mm-ss. I've tried using the ZenTimestamp plugin v2.0.1, which changes the $BUILD_ID, but this only seems to take effect after the workspace is created.
Is there a method of defining a custom workspace in the manner that I want it?

You can use a groovy script to achieve that.
import hudson.model.*;
import hudson.util.*;
import java.util.*;
import java.text.*;
import java.io.*;
//Part 1 : Recover build parameter
AbstractBuild currentBuild = (AbstractBuild) Thread.currentThread().executable;
def envVars= currentBuild.properties.get("envVars");
def branchName = envVars["BRANCH_NAME"];
//Part 2 : Define new workspace Path
def newWorkspace = "C:\\Build\\"+branchName;
//Part 3 : Change current build workspace
def newWorspaceFilePath = new FilePath(new File(newWorkspace));
currentBuild.setWorkspace(newWorspaceFilePath);

Related

How to click on a element through Selenium Python

I'm trying to fetch data for facebook account using selenium browser python but can't able to find the which element I can look out for clicking on an export button.
See attached screenshot
I tried but it seems giving me an error for the class.
def login_facebook(self, username, password):
chrome_options = webdriver.ChromeOptions()
preference = {"download.default_directory": self.section_value[24]}
chrome_options.add_experimental_option("prefs", preference)
self.driver = webdriver.Chrome(self.section_value[20], chrome_options=chrome_options)
self.driver.get(self.section_value[25])
username_field = self.driver.find_element_by_id("email")
password_field = self.driver.find_element_by_id("pass")
username_field.send_keys(username)
self.driver.implicitly_wait(10)
password_field.send_keys(password)
self.driver.implicitly_wait(10)
self.driver.find_element_by_id("loginbutton").click()
self.driver.implicitly_wait(10)
self.driver.get("https://business.facebook.com/select/?next=https%3A%2F%2Fbusiness.facebook.com%2F")
self.driver.get("https://business.facebook.com/home/accounts?business_id=698597566882728")
self.driver.get("https://business.facebook.com/adsmanager/reporting/view?act="
"717590098609803&business_id=698597566882728&selected_report_id=23843123660810666")
# self.driver.get("https://business.facebook.com/adsmanager/manage/campaigns?act=717590098609803&business_id"
# "=698597566882728&tool=MANAGE_ADS&date={}-{}_{}%2Clast_month".format(self.last_month,
# self.first_day_month,
# self.last_day_month))
self.driver.find_element_by_id("export_button").click()
self.driver.implicitly_wait(10)
self.driver.find_element_by_class_name("_43rl").click()
self.driver.implicitly_wait(10)
Can you please let me know how can i click on Export button?
Well, I'm able to resolve it by using xpath.
Here is the solution
self.driver.find_element_by_xpath("//*[contains(#class, '_271k _271m _1qjd layerConfirm')]").click()
The element with text as Export is a dynamically generated element so to locate the element you have to induce WebDriverWait for the element to be clickable and you can use either of the locator strategies:
Using CSS_SELECTOR:
WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.layerConfirm>div[data-hover='tooltip'][data-tooltip-display='overflow']"))).click()
Using XPATH:
WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(#class, 'layerConfirm')]/div[#data-hover='tooltip' and text()='Export']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
to run automation scripts on applications like facebook, youtube quite a hard because they are huge coporations and their web applications are developed by the worlds best developers but its not impossible to run automation scripts sometimes elements are generated dynamically sometimes hidden or inactive you cant just go and click
one solution is you can do by click action by xpath realtive or absolute their is not id specified as "export_button" in resource file i think this might help you
you can also find element by class name or css selector as i see in screen shot the class name is present "_271K _271m _1qjd layerConfirm " you can perform click action on that

Airflow plugins, RBAC enabled Blueprint not working

We had our Airflow custom UI based on this link and it was working fine with Airflow 1.9.0.
Following this we upgraded to 1.10.1 and also enabled RBAC. Our custom UI stopped coming after this.
We followed this explanation note-on-role-based-views and tried to use our old UI templates with appbuilder_views. On the using the TestAppBuilderBaseView from /tests/plugins/test_plugin.py,
class TestAppBuilderBaseView(AppBuilderBaseView):
#expose("/")
def test(self):
return self.render("test_plugin/test.html", content="Hello galaxy!")
we get the menu and the link, but on clicking we get the error
object has no attribute 'render'
On changing this to
return self.render_template("test_plugin/test.html",content="Hello galaxy!")
we get the error
jinja2.exceptions.TemplateNotFound: test_plugin/test.html
I have tried all possible combination placing the templates folder and the html file, but still its the same error.
I do find some forums telling to enable debug on Blueprint. but I am not aware on how you can do that with Airflow
Any guidance on this please?.
Thanks in Advance
Jeenson
The version 1.10.0 when released had a bug that was not installing the plugins correctly in the new UI. This was fixed in the version 1.10.1, but the code example for plugins in Airflow documentation is broken.
I wrote a sample project to make the integration work, you can check it here: https://github.com/felipegasparini/airflow_plugin_rbac_test
But in short, you need to:
Import the BaseView from appbuilder correctly using:
from flask_appbuilder import BaseView as AppBuilderBaseView
Change the name of the method 'test' to 'list'
Set the template_folder property to point to where your templates are.
Something like this:
from airflow.plugins_manager import AirflowPlugin
from flask_appbuilder import BaseView as AppBuilderBaseView
class TestAppBuilderBaseView(AppBuilderBaseView):
template_folder = '/root/airflow/plugins/test_plugin/templates'
#expose("/")
def list(self):
return self.render_template("test.html", content="Hello galaxy!")
v_appbuilder_view = TestAppBuilderBaseView()
v_appbuilder_package = {"name": "Test View",
"category": "Test Plugin",
"view": v_appbuilder_view}
# Defining the plugin class
class AirflowTestPlugin(AirflowPlugin):
name = "test_plugin"
# operators = [PluginOperator]
# sensors = [PluginSensorOperator]
# hooks = [PluginHook]
# executors = [PluginExecutor]
# macros = [plugin_macro]
# admin_views = [v]
# flask_blueprints = [bp]
# menu_links = [ml]
appbuilder_views = [v_appbuilder_package]
# appbuilder_menu_items = [appbuilder_mitem]
I am also faced the same issue.
After including template folder in blueprint its picking up the correct folder and here is my working example.
Please keep the folder structure like below
Plugin
|_test_plugin
|_templates
|_test.html
test_plugin.py
test_plugin.py
from airflow.plugins_manager import AirflowPlugin
from flask import Blueprint
from flask_admin import BaseView, expose
from flask_admin.base import MenuLink
class TestView(BaseView):
#expose('/')
def test(self):
return self.render("test.html", content="Hello galaxy!")
v = TestView(category="Test Plugin", name="Test View")
blue_print_ = Blueprint("test_plugin",
__name__,
template_folder='templates')
class AirflowTestPlugin(AirflowPlugin):
name = "MenuLinks"
# operators = []
flask_blueprints = [blue_print_]
# hooks = []
# executors = []
admin_views = [v]
#appbuilder_views = [v_appbuilder_package]
fgasparini's answer is correct, but I also need to enable the RBAC setting
rbac = True
in airflow.cfg in order for flask_appbuilder to work with airflow, otherwise the menu won't show up.

Best way to update my django model coming from an external api source?

I am getting my data through requesting an api source, then I put it in my django model. However, data update daily.. so how can I update these data without rendering it everytime?
def index (request):
session = requests.Session()
df = session.get('https://api.coincap.io/v2/assets')
response= df.json()
coin = response['data']
final_result = coin.to_dict('records')
for coin in final_result:
obj, created = Coincap.objects.update_or_create(
symbol = coin['symbol'],
name = coin['name'],
defaults = {
'price': coin['priceUsd']
})
return render(request, '/home.html/')
Right now, I have to go to /home.html , if I want my data update. However, my goal is to later serialize it and make it REST api data, so I wouldn't touch django template anymore. Anyway for it to update internally once a day after i do manage.py runserver?
For those that are looking for an example:
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self,*args,**kwargs):
//Your request api here
for coin in final_result:
obj, created = Coincap.objects.update_or_create(
symbol = coin['symbol'],
name = coin['name'],
defaults = {
'price': coin['priceUsd']})
Then you run in with cron just as Nikita suggested.
One simple and common solution is to create a custom Django admin command and use Cron to run it at specified intervals. You can write a command's code to your liking and it can have access to all of the models, settings and other parts of your Django project.
You would put your code making a request and writing data to the DB, using your Django models, in your new Command class's handle() method (obviously request parameter is no longer needed). And then, if for example you have named your command update_some_data, you can run it as python manage.py update_some_data.
Assuming Cron exists and is running on the machine. Then you could setup Cron to run this command for you at specified intervals, for example create a file /etc/cron.d/your_app_name and put
0 4 * * * www-data /usr/local/bin/python /path/to/your/manage.py update_some_data >> /var/log/update_some_data.log 2>&1
This would make your update be done everyday at 04:00. If your command would provide any output, it will be written to /var/log/update_some_data.log file.
Of course this is just an example, so your server user running your app (www-data here) and path to the Python executable on the server (/usr/local/bin/python here) should be adjusted for particular use.
See links for further guidance.

Separate the dependency list ( requirements) from conanfile.py

We are planning to set up conan repositories for our C++ codes. We want to expose only the list of dependencies ( lib/version#user/channel) to the developers, not the logic we put in conanfile.py We are planning so, because we are creating a wrapper around conan which will have several logic and checks. This wrapper will be exposed to the users. They do not need to know the detailed logic and build steps.
Is there a way to implement the requirements ( dependency list ) outside conanfile.py, and make the list available to the users, so that they can choose which version of the library they want to use - something similar ( not same, though ) to pom.xml in maven world ?
The above answer from #amit-jaim is quite good. I would like to point a couple of further details:
It is necessary to exports the .list file, as it will be also used when the conanfile is used in the cache
The conanfile can be made a bit more pythonic
The code could be like:
from conans import ConanFile, load
class HelloConan(ConanFile):
name = "Hello"
version = "0.1"
exports = "deps.list"
def requirements(self):
for r in load("deps.list").splitlines():
self.requires(r)
If you want to be able to run conan create from directories other than the current conanfile then getting the current location of the conanfile would be necessary, something like:
def requirements(self):
f = os.path.join(os.path.dirname(__file__), "deps.list")
for r in load(f).splitlines():
self.requires(r)
I found 2 solutions :
Create a list of libraries to be used and then read that from requirements method :
localhost$ cat dependencies.list
lib1/0.0.1#user/stable
lib2/1.6.0#user/stable
lib3/1.5.0#suer/stable
Remember, there should not be any quote around the values, in the way we pass them to the self.requires() method. Now define the requirements method in conanfile.py in the following way :
def requirements(self):
try:
with open("/path/to/dependencies.list") as c:
line=c.readline()
while line:
self.requires(line)
line=c.readline()
except Exception as ex:
print(ex)
Define requirements method outside conanfile.py. Use this method if library dependency is conditional.
localhost$ cat requires.py
def requires(self):
self.requires("lib1/0.0.1#user/stable")
self.requires("lib2/2.6.0#user/stable")
if self.options.shared:
self.requires("lib3/1.5.0#user/stable")
else:
self.requires("lib3/1.5.1#user/stable")`
Then import the requires method and assign that to the requirements method in conan class, in the following way :
from conans import ConanFile, CMake, tools
from requires import requires
class HelloConan(ConanFile):
name = Hello
version = "0.0.1"
license = "LICENSE"
url = "URL"
description = "libHello, Version 0.0.1"
settings = "os", "compiler", "build_type", "arch"
....
....
Now instead of defining the requirements method with def requirements(self), do this :
requirements=requires
....
....
That's it !! conan install will get the library details, and if found in the registry, those will be installed !!

<unknown>.TargetPath can not be set

I'm attempting to write a script that can be deployed and remotely run on a number of target computers with the end result of having an existing shortcut replaced by one that runs the exact same program, but at high priority. Here is my script:
import os, winshell
from win32com.client import Dispatch
from comtypes.client import CreateObject
# from comtypes.gen import IWshRuntimeLibrary
desktop = winshell.desktop()
path = os.path.join(desktop, 'Test Short.lnk')
target = r'\%HOMEDRIVE%\\Apps\\Ellie Mae\\Encompass\\AppLauncher.exe'
wDir = r'\%HOMEDRIVE%\\Apps\\Ellie Mae\\Encompass'
icon = r'\%SystemRoot%\\Installer\\{3E9C4FBE-4E6C-4389-A4B3-4AE027D0BF2E}\\Icon3E9C4FBE2.ico'
shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
shortcut.TargetPath = target
shortcut.WorkingDirectory = wDir
shortcut.IconLocation = icon
shortcut.save()
I'm running into an Attribute error, as follows:
AttributeError: Property '<unknown>.TargetPath' can not be set.
For reference, here is where I got most of my code.
I attempted to search out an answer, and I came across this thread. However, following the accepted suggestion yields:
ImportError: cannot import name IWshRuntimeLibrary
My confusion comes from why I'm not able to set the TargetPath property to begin with. As happens so often, it seems as if the OP from the linked thread and I are the only two people reporting this problem. Does anyone know why that might be happening and what I can do to fix it?