Skip to content

Commit

Permalink
Merge pull request #1 from Cybrarist/v2.1
Browse files Browse the repository at this point in the history
V2.1
  • Loading branch information
Cybrarist authored Jan 15, 2025
2 parents 234ef29 + c9f053e commit 581538d
Show file tree
Hide file tree
Showing 43 changed files with 3,696 additions and 2,382 deletions.
192 changes: 192 additions & 0 deletions Product.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
class Product {
name;
image;
price;
rate;
number_of_rates;
seller;
url;
update_product;
in_stock=true;
#token;

storage_promise;

constructor() {
this.storage_promise= this.get_storage_data()
}

/**
* urls on the server api.
* @returns {string}
*/

update_url () {
return `${this.url}/api/products/update`
};
get_product () {
return `${this.url}/api/products/get`
};
create_product () {
return `${this.url}/api/products/create`
};

/**
* get the data saved in the browser
* @returns {Promise<void>}
*/

async get_storage_data(){
var result= await browser.storage.sync.get()
this.#token= result.token;
this.url=result.url;
this.update_product=result.update_product;
}



async update_server_product(){
await this.storage_promise

if (!this.update_product)
return

fetch(this.update_url() ,{
method: 'POST',
headers:{
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${this.#token}`,
},
body:JSON.stringify({
url : window.location.href,
current_price: self.price
})
})
.catch(error => {
// Handle errors
console.log("Error:", error);
});
}

async get_product_data(){
await this.storage_promise

return fetch(this.get_product() ,{
method: 'POST',
headers:{
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${this.#token}`,
},
body:JSON.stringify({
url : window.location.href
})

})
.then((response) => {
return response.json();
})
.catch(error => {
// product doesn't exist in the system
});
}

submit_form(){
document.body.querySelector("#gray_layout").classList.add("show_flex")

fetch(this.create_product(), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${this.#token}`,
},
body: JSON.stringify({
url: window.location.href ,
name: this.name,
image: this.image,
notify_price: document.getElementById("notify_price").value,
official_seller: document.getElementById("official_seller").checked,
favourite: document.getElementById("favourite").checked,
stock_available: document.getElementById("stock_available").checked,
lowest_within: document.getElementById("lowest_within").value,
number_of_rates:this.number_of_rates ?? 0,
price:this?.price ?? 0,
})
})
.then(response => {
return response.json();
})
.then(data => {
if (data.errors)
add_notification_to_page('danger' , 'Something wrong Happened')
else
add_notification_to_page('success' ,
`<p> ${ data.message}</p>
<p>You can check it from the following link </p>
<p>
<a href='${data.link} '> ${data.link} </a>
</p>`
)

})
.catch(error => {
add_notification_to_page('danger' , 'Something wrong Happened here')
});
}

get_dom_product_details(){}

populate_dom_with_charts(){}


refresh_dom_all(){
product.get_dom_product_details()
product.update_server_product().then(response => {
console.log("updated server")
})
document
.querySelectorAll("#gray_layout , #discount_bandit_show, #chart , #all_stores_cards")
?.forEach((elem)=>{
elem.remove()
})

product.populate_dom_with_charts()

setTimeout(() => {
document.getElementById("submit_discount_form")
.addEventListener("click" , function (){
product.submit_form()
})
}, 2000);

product.get_product_data().then(response => {

})
}

}




let previousUrl = null;
const observer = new MutationObserver(function(mutations) {

current_url=new URL(location.href)

if (current_url.pathname !== previousUrl?.pathname) {
previousUrl = new URL(location.href);
product.refresh_dom_all()
}
});

const config = {subtree: true, childList: true};
observer.observe(document, config);




//share the url across all classes
var current_url = new URL(window.location.href);
80 changes: 80 additions & 0 deletions Stores/Amazon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
class Amazon extends Product {
constructor() {


super();
}

get_dom_product_details(){
this.name= document.getElementById("productTitle").textContent.trim()
this.price= document.getElementById("twister-plus-price-data-price")?.value ?? 0
this.image= document.querySelector(".imgTagWrapper img").src
this.number_of_rates=document.getElementById("acrCustomerReviewText")
?.textContent.split(" ")[0]
.replaceAll(",","")
.replaceAll("." , "")
.replaceAll("(" , "")
.replaceAll(")" , "")


}

populate_dom_with_charts() {

document.body.insertAdjacentHTML("afterbegin" , `<div id='gray_layout'
onclick="if (event.target === event.currentTarget) this.classList.remove('show_flex')">${get_global_form()}</div>`)

document.body.querySelector("#title_feature_div")
.insertAdjacentHTML('afterend', `<img id="discount_bandit_show"
src="${browser.runtime.getURL(`resources/images/bandit.png`)}"
onclick='document.body.querySelector("#gray_layout").classList.add("show_flex")'>`)

//add the chart and stores
var main_body=document.body.querySelector("#ppd")
main_body.insertAdjacentHTML("afterend" , "<div id='chart'></div>")
main_body.insertAdjacentHTML("afterend" , "<div id='all_stores_cards'></div>")
}

async get_product_data() {

super.get_product_data().then(data => {
if (!data)
return;

insert_chart_into_dom(data.series)

//add highest and lowest prices
document.getElementById("buybox")
.insertAdjacentHTML("afterbegin" ,
`<div class="lowest_price" > Lowest Price ${data.prices[data.current_store_id].lowest_price.toLocaleString()}</div>
<div class="highest_price" "> Highest Price ${data.prices[data.current_store_id].highest_price.toLocaleString()}</div>`
)

//add open in Discount Bandit
document.getElementById("submit.buy-now").insertAdjacentHTML("afterend" ,
`<a class="discount_bandit_button"
target="_blank"
href="${this.url}/products/${data.product_id}">
<img src="${browser.runtime.getURL(`resources/images/bandit.png`)}"
style="max-width: 20px" >
Discount Bandit
</a>`)

//add other stores available.
var stores_elements=document.getElementById("all_stores_cards");

for (const [store, value] of Object.entries(data.prices))
if (store != data.current_store_id)
stores_elements.insertAdjacentHTML("afterbegin", product_per_store_price_template(store,value))
})
}

}

//todo make product call class name dynamically
if ( current_url.host.includes('amazon.') && (current_url.pathname.includes("/dp/") || current_url.pathname.includes("/gp/product") ) ){
var product= new Amazon()
product.get_storage_data().then(r => {})
}


89 changes: 89 additions & 0 deletions Stores/Argos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
if (window.location.href.includes('argos.co.uk') ){

class Argos extends Product {
constructor() {
super();
}

get_dom_product_details(){
this.name= document.querySelectorAll('[data-test="product-title"]')[0].textContent.trim()
this.price= document.querySelectorAll('[data-test="product-price-primary"]')[0].getAttribute('content')
this.image= document.querySelectorAll('[data-test="component-media-gallery-thumbnails_thumbnail-0"] img')[0].src
this.number_of_rates= document.querySelectorAll('[itemProp="ratingCount"]')[0].textContent
}

populate_dom_with_charts() {

document.body.insertAdjacentHTML("afterbegin" , `<div id='gray_layout'
onclick="if (event.target === event.currentTarget) this.classList.remove('show_flex')">${get_global_form()}</div>`)



//add the chart and stores
setTimeout(() => {
document.querySelectorAll('[data-test="product-name"]')[0]
.insertAdjacentHTML('afterend', `<img id="discount_bandit_show"
src="${browser.runtime.getURL(`resources/images/bandit.png`)}"
onclick='document.body.querySelector("#gray_layout").classList.add("show_flex")'>`)


var main_body=document.getElementById("pdp-description")
main_body.insertAdjacentHTML("beforebegin" , "<div id='all_stores_cards'></div>")
main_body.insertAdjacentHTML("beforebegin" , "<div id='chart'></div>")
}, 2000);


}

async get_product_data() {

super.get_product_data().then(data => {

if (data){
//add highest and lowest prices
document.querySelectorAll("[data-test='product-price-primary']")[0]
.insertAdjacentHTML("afterbegin" ,
`<div class="lowest_price" > Lowest Price ${data.prices[data.current_store_id].lowest_price.toLocaleString()}</div>
<div class="highest_price" "> Highest Price ${data.prices[data.current_store_id].highest_price.toLocaleString()}</div>`
)


//add open in Discount Bandit
document.querySelectorAll("[data-test='add-trolley-button-wrapper']")[0]
.insertAdjacentHTML("afterend" ,
`<a class="discount_bandit_button"
target="_blank"
href="${this.url}/products/${data.product_id}">
<img src="${browser.runtime.getURL(`resources/images/bandit.png`)}"
style="max-width: 20px"
>
Discount Bandit</a>`
)
setTimeout(() => {

if (!data)
return;
insert_chart_into_dom(data.series)

var stores_elements=document.getElementById("all_stores_cards");
for (const [store, value] of Object.entries(data.prices))
if (store != data.current_store_id)
stores_elements.insertAdjacentHTML("afterbegin", product_per_store_price_template(store,value))

}, 3000);

}




//add other stores available.
})
}

}

var product= new Argos()

product.get_storage_data().then(r => {})
}
Loading

0 comments on commit 581538d

Please sign in to comment.