Handling Multiple Images with ColdFusion and MySQL - mysql

This is an architecture question, but its solution lies in ColdFusion and MySQL structure--or at least I believe so.
I have a products table in my database, and each product can have any number of screen-shots. My current method to display product screen-shots is the following:
I have a single folder where all screen-shots associated with all products are contained. All screen-shots are named exactly the same as their productID in the database, plus a prefix.
For example: Screen-shots of a product whose productID is 15 are found in the folder images, with the name 15_screen1.jpg, 15_screen2.jpg, etc...
In my ColdFusion page I have hard-coded the image path into the HTML (images/); the image name is broken into two parts; part one is dynamically generated using the productID from the query; and part two is a prefix, and is hard-coded. For example:
<img src"/images/#QueryName.productID#_screen1.jpg">
<img src"/images/#QueryName.productID#_screen2.jpg"> etc...
This method works, but it has several limitations the biggest listed bellow:
I have to hard-code the exact number of screen-shots in my HTML template. This means the number of screen shots I can display will always be the same. This does not work if one product has 10 screen shots, and another has 5.
I have to hard-code image prefixes into my HTML. For example, I can have up to five types of screen-shots associated with one product: productID=15 may have 15_screen1.jpg, 15_screen2.jpg, and 15_FrontCover.jpg, 15_BackCover.jpg, and 15_Backthumb.jpg, etc...
I thought about creating a paths column in my products table, but that meant creating several hundreds of folders for each product, something that also does not seem efficient.
Does anyone have any suggestions or ideas on the correct method to approach this problem?
Many thanks!

How about...
use an Image table, one product to many images (with optional sortOrder column?), and use imageID as the jpeg file name?
update:
Have a ImageClass table, many Image to one ImageClass.
Image
-----
ID
productID
imageClassID (FK to ImageClass)
Use back-end business logic to enforce the some classes can only have one image.
Or... if you really want to enforce some classes can only one image, then can go for a more complex design:
Product
------
ID
name
...
frontCoverImageID
backCoverImageID
frontThumbImageID
backThumbImageID
Image
-----
ID
productID
isScreenShot (bit) // optional, but easier to query later...
However, I like the first one better since you can have as many classes you see fit later, without refactoring the DB.

Keeping information on how many and what images in the database is definitely the way to go.
Barring that, if you want to use naming conventions to associate images with products, and the number of images is arbitrary, then it's probably a better idea to create one folder per product:
/images/products/{SKU1}/frontview.jpg
/images/products/{SKU1}/sideview.jpg
/images/products/{SKU2}/frontview.jpg
and so forth. Then use <cfdirectory> to collect the images for a given product. You might also want to name your images 00_frontview.jpg, 01_sideview.jpg and such so that you can sort and control what order they'll display on the page.

use the cfdirectory tags to inspect the filesystem:
<!--- get a query resultset of images in filesystem --->
<cfdirectory action="list" name="images" directory="images">
<!--- get images for specific product --->
<cfquery name="productImages" dbtype="query">
select *
from images
where name like '#productid#%'
</cfquery>
<cfoutput query="productImages">
<img src="#productimages.directory#/#productimages.name#" />
</cfoutput>
You could even try using the filter attribute to cfdirectory to try and omit the QoQ

Related

How to use where clause to get the output on the basis of the length of Character's in it

So the thing is that I have the following question:
Display the column Brand from the table clothing where length(Brand)=10.
So I used the query: select Brand from clothing where length(Brand)=10;
This gives me the out put as an empty set, so I checked my table to see if it was actually supposed to give an empty set and the answer was no.
So if anyone would be able to tell what's going wrong then that would be of great help
The images for the table and the input I tried are given below.
Table image and the input I gave

How to scrape text based on a specific link with BeautifulSoup?

I'm trying to scrape text from a website, but specifically only the text that's linked to with one of two specific links, and then additionally scrape another text string that follows shortly after it.
The second text string is easy to scrape because it includes a unique class I can target, so I've already gotten that working, but I haven't been able to successfully scrape the first text (with the one of two specific links).
I found this SO question ( Find specific link w/ beautifulsoup ) and tried to implement variations of that, but wasn't able to get it to work.
Here's a snippet of the HTML code I'm trying to scrape. This patter recurs repeatedly over the course of each page I'm scraping:
<em>[女孩]</em> 寻找2003年出生2004年失踪贵州省黔西南布依族苗族自治州贞丰县珉谷镇锅底冲 黄冬冬289179
The two parts I'm trying to scrape and then store together in a list are the two Chinese-language text strings.
The first of these, 女孩, which means female, is the one I haven't been able to scrape successfully.
This is always preceded by one of these two links:
forum.php?mod=forumdisplay&fid=191&filter=typeid&typeid=19 (Female)
forum.php?mod=forumdisplay&fid=191&filter=typeid&typeid=15 (Male)
I've tested a whole bunch of different things, including things like:
gender_containers = soup.find_all('a', href = 'forum.php?mod=forumdisplay&fid=191&filter=typeid&typeid=19')
print(gender_containers.get_text())
But for everything I've tried, I keep getting errors like:
ResultSet object has no attribute 'get_text'. You're probably treating a list of items like a single item. Did you call find_all() when you meant to call find()?
I think that I'm not successfully finding those links to grab the text, but my rudimentary Python skills thus far have failed me in figuring out how to make it happen.
What I want to have happen ultimately is to scrape each page such that the two strings in this code (女孩 and 寻找2003年出生2004年失踪贵州省...)
<em>[女孩]</em> 寻找2003年出生2004年失踪贵州省黔西南布依族苗族自治州贞丰县珉谷镇锅底冲 黄冬冬289179
...are scraped as two separate variables so that I can store them as two items in a list and then iterate down to the next instance of this code, scrape those two text snippets and store them as another list, etc. I'm building a list of list in which I want each row/nested list to contain two strings: the gender (女孩 or 男孩)and then the longer string, which has a lot more variation.
(But currently I have working code that scrapes and stores that, I just haven't been able to get the gender part to work.)
Sounds like you could use attribute = value css selector with $ ends with operator
If there can only be one occurrence per page
soup.select_one("[href$='typeid=19'], [href$='typeid=15']").text
This is assuming those typeid=19 or typeid=15 only occur at the end of the strings of interest. The "," between the two in the selector is to allow for matching on either.
You could additionally handle possibility of not being present as follows:
from bs4 import BeautifulSoup
html ='''<em>[女孩]</em> 寻找2003年出生2004年失踪贵州省黔西南布依族苗族自治州贞丰县珉谷镇锅底冲 黄冬冬289179'''
soup=BeautifulSoup(html,'html.parser')
gender = soup.select_one("[href$='typeid=19'], [href$='typeid=15']").text if soup.select_one("[href$='typeid=19'], [href$='typeid=15']") is not None else 'Not found'
print(gender)
Multiple values:
genders = [item.text for item in soup.select_one("[href$='typeid=19'], [href$='typeid=15']")]
Try the following code.
from bs4 import BeautifulSoup
data='''<em>[女孩]</em> 寻找2003年出生2004年失踪贵州省黔西南布依族苗族自治州贞丰县珉谷镇锅底冲 黄冬冬289179'''
soup=BeautifulSoup(data,'html.parser')
print(soup.select_one('em').text)
OutPut:
[女孩]

Cesium - Modify infobox contents

I have n polygons with ids "test-1-1", "test-1-2" .... "test-1-n" which represent a single logical entity. Format of id can be generalized as < entity_name>-< entity_id>-< i>, where i is added to distinguish ids of multiple polygons.
My query here is, I want to display only "test" when any of these polygons is clicked. Currently id of selected polygon is displayed in info-box.
Is there any cesium way to do this? I would not prefer manipulating the strings at runtime.
A Cesium Entity has three fields of interest to the InfoBox (the thing that pops up when an Entity is selected).
entity.id - Each entity in a dataSource is required to have a unique id (a GUID will be auto-generated if no ID is supplied at creation). It is an arbitrary string and does not need to be human-friendly.
entity.name - This is the human-friendly name of the Entity. It does not need to be unique, you may have as many duplicate names as you like. It is half a line or less of plain text (not HTML).
entity.description - This is a sandboxed HTML description of the entity, and can span multiple paragraphs or include tables and other styling.
The InfoBox will attempt to show entity.name on its title bar by default, and will only fall back to show entity.id in the title bar if name is missing (because name is optional, id is not).
The body of the InfoBox only appears below the title bar if entity.description is set (otherwise only the bar is shown). The description is rendered with a sandboxed iframe (to offer some resistance to cross-site scripting for apps that display user-supplied entity descriptions).
I have n polygons with ids "test-1-1", "test-1-2" .... "test-1-n" ...
For this case, I would keep the existing ids, and set name to be the string you wish to see in the InfoBox popup. Multiple entities can have the same name but not the same id.

Trouble with Xpath in Google Spreadsheets (ImportXML)

This is a great site, and I've already had a lot of questions answered simply by scrolling and searching through other postings. Unfortunately, I can't seem to track down an answer that specifically helps this problem, and figured I would try posting and looking for help-
I'm using ImportXML and google spreadsheets to 'scrape'a few product descriptions from a retail site. It's been working fine for the most part, and I have done it in 2 ways:
1) Specific call to the description part of a post:
=ImportXML(A1,"//div[#class='desc']")
2) Call to the entire 'product Card', which also returns info such as product title, price, time posted, and places these items in adjacent cells in my Google spreadsheet:
=ImportXML(A1,"//div[#class='productCard']")
Both have worked fine, but I've ran into a different problem using each method. If I can resolve even one of these problems, then I'll happily scrap the other method, I just need one of them to work. The problems are:
Method 1) The website prohibits sellers from including contact information in product postings-- when they include an email address anyways, the site automatically blocks it, so that in the posting it simply appears as "...you can reach me at [obscured]" or something like that. The [obscured] appears in a different colour text and is obviously treated differently somehow. When I scrape these descriptions using Method 1, ImportXML appears to get 'bumped' when it hits the word [obscured], and it passed the remaining text from that product description to the next cell over in my spreadsheet. This ruins the entire organization of the sheet, and I'd like to find a way where I can get ImportXML to just ignore the [obscured], and still place the entire text of the product description in one cell.
Method 2) My call for the entire 'product Card' is as follows:
=ImportXML(A1,"//div[#class='productCard']")
As mentioned, this works fine (for most products), and I don't mind the additional info (price, date, etc.) being posted in adjacent cells.
However, the website also allows certain products to be 'featured', where they appear in a different colour box on the site, and are therefore more likely to get a buyer's attention.
Using this method, the 'featured' products are not scraped or imported into my spreadsheet, but are simply passed over.
The source code (on actual site) (via 'inspect element' in Safari) for both the description (Method 1) and product card (Method 2) look as follows (for a normal product (a) and a featured product (b)):
(a)
<div id="productSearchResults">
<div class="productCard tracked">
<div>...</div>
<div class="stats">...</div>
<div class="desc collapsed descFull">...</div>
</div>
(b)
<div id="productSearchResults">
<div class="productCard featured tracked">
<div>...</div>
<div class="stats">...</div>
<div class="desc collapsed descFull">...</div>
</div>
You can see in both (a) an (b) the 'desc' class that I call in Method 1, which seems to work fine.
From my reading on this site, I think I've learned that a given class can't have more than one word, and therefore the use of "desc collapsed descFull" and "productCard tracked" and "productCard featured tracked" don't represent classes with 3, 2 and 3 words in the title, but instead cases where multiple classes have been assigned?
Regardless, the call to 'desc' (Method 1) works fine and seems to get all descriptions.
In method 2 therefore, I would have thought that a call to 'productCard' would get the info for all products, both featured and regular, as 'featured' is an extra class assigned to some 'productCard's. If I call all 'productCard's, shouldn't the normal AND featured ones be returned? This is currently not the case. I've tried calling just 'tracked' and just 'featured' as classes, and neither returns anything, so my logic that they are their own class equivalent to 'productCard' may be flawed.
In summary, the 'desc' call in Method 1 works fine, and even gets descriptions for 'featured' products. However, when contact information is included in the description and is displayed as [obscured] it bumps my data into the next cell in the spreadsheet, immediately following the word. This throws off and ruins all organization.
In Method 2, I am not getting the featured products at all, which greatly weakens what I am trying to do. Can either (or both!) of these problems be fixed??
Thanks so so much for any help you can give me.
***UPDATE: As seen in the comments below, use of the 'contain' as suggested improved Method 2 by retrieving both regular and featured products. However, featured product cards have extra text elements, and since the entire card is being scraped in this method, featured products do not match the cell alignment that regular products do. If there is a way to fix Method 1, this would therefore be much better.
As outlined in the comments below, the [obscured] text appears in a 'span' that follows underneath/indented from the
<div class="desc descFull collapsed"
as
<span class="obscureText">[obscured]</span>
Is there any way that I can import the 'desc's as I have been, but tell the XPath to essentially 'ignore' the [obscured] span, or at least deal with it in a way that doesn't make description text immediately after [obscured] appear one cell over?
Thanks so much everyone!
You can wrap your function with the concatenate()-function to make sure it all shows up in one cell:
=concatenate(ImportXML(A1,"//div[#class='productCard']"))

best way to pull pictures for an item, from a separate table, in django

Im having a hard time deciding what is the best way to pull pictures from a separate table, for a certain item.
In django, I have two tables:
class item(models.Model):
title..
descr..
class item_pic(models.Model):
item=models.ForeignKey(item)
pic=models.ImageField...
Im displaying the item.title and item.descr in a div, and in the same div I want to pull the pictures.
So far I've tried creating a template filter like item|getPics which returns a list of the pics for that item.
{% for pic in item|getPics %} <img src="/uploads/{{pic.pic}}"> {%endfor%}
In the end I got rid of this since it was firing too many sql queries
Right now I finished pulling the pictures through ajax, the only downside here is that the images take some time to appear. And I assume is the same number of sql queries (only that django debug toolbar doesnt see them since they are fired up in the background).
How would you approach this? Thanks for any tips!
You should use select_related() (docs) to get the image objects together with the items.
It would look like this:
item = item.objects.select_related().get(...)
This means you won't get additional database queries when you're retrieving the item_pics.
As a final note, it's better to capitalize the names of classes as this is convention in Python/Django.