Where are the links to each media file in a whatsapp database - database

I want to organize an album with all the photos from a Whatsapp group.
With a rooted phone I have downloaded the unencrypted whatsapp databases to my computer.
With Sqliteman on Ubuntu I've looked around, specially in the msgstore.db and can't seem to find all of the links to the images of a particular group.
With the table "chat_list" I saw that a specific "key_remote_jid" value corresponded to the group I wanted and in the "messages" database I could use that "key_remote_jid" to get all the messages related to that group with something like:
select * from messages where key_remote_jid="53151151515-1515131313535#g.us";
Furthermore I can discard text messages in order to focus on the media I want (Photos and Videos mainly) by
select * from messages where key_remote_jid="53151151515-1515131313535#g.us" and not media_wa_type = 0;
And some of the images there have a filename under the column "media_name" but they are only the ones I have sent.
There is another table called "media_refs" which contains many paths of images and video but seems to only include files which have been forwarded to more than one chat and has a key which I haven't found how to relate to the "messages" table.
The group is rather old (dating back to 2013) and it seems likely the way whatsapp handles its database has changed through the years as there are some columns which are consistently {null} in the past and not in the most recent messages (like participant_hash) and the value key_id seems to change the format at some point.
However the Whatsapp app has no problem in showing me the a file from any moment in the past and giving me the option to open the actual file with a "Gallery"-type software, so the information is in my phone somewhere.
The point of all this is to basically have a backup I can work with and be able to delete the images from my phone and still have them organized in the same way they were shared in that group.

I found the link of Whatsapp Images in column thumb_image of table messages as a blob. You can view the blob in hex and look for the the strings which may looks like this Whatsapp Images\IMG-20130101-WA0001.jpg. I don't know exactly where Whatsapp store the links properly, but this works for me.
Here is how I managed to extract the links:
select
_id,
media_mime_type,
substr(
substr(thumb_image,instr(thumb_image,'IMG'),60)
,instr(substr(thumb_image,instr(thumb_image,'IMG'),23),'IMG')
,23)
from `messages`
where
`key_remote_jid` like '%<your desired contact>%'
and `media_mime_type` like '%image%';
I use DB Browser for SQLite to do this in Windows.

(Android) - what one is looking for is file_path within the table message_media. It points to files relative to /sdcard/WhatsApp/ and its message_row_id references the messages table pk _id. A where condition on the key_remote_jid of the group (<..>#g.us) should output all group image filepaths.
select mm.file_path
from messages m
join message_media mm on m._id = mm.message_row_id
where m.key_remote_jid = 'xyz#g.us'
and m.media_wa_type = 1; -- 1 = images
(thumbnail previews are stored as blob bytes in raw_data in the messages table itself)

Related

AzMonitor workbook to visualize data by city

One is able to group the number of page views by country, per this documentation. PFB KQL query.
pageViews | project client_CountryOrRegion, itemCount, client_City
However, visualizing by client_City doesn't work.
Is there a way one could group and visualize by the name of the city instead?
Workbooks itself doesn't currently have any built in mapping of city to lat/long, we only have that at the country/region level. (In the screenshots above, you told workbooks that a column of data has country information, but then you passed it cities, so it doesn't know of any countries named those things)
there are various ways to do it by using the externaldata operator in ADX/Log Analytics to have the database load, parse, and join with your other data. If you can get to lat/long, then you can tell workbooks to use that mode where you tell it which columns are lat and long and you'd have your points.
not the exact files you want, but in another example someone wanted to map from ip address to country, and in that example you'd add something like this to your query:
let geoData = externaldata
(network:string,geoname_id:string,continent_code:string,continent_name:string,
country_iso_code:string,country_name:string,is_anonymous_proxy:string,is_satellite_provider:string)
[#"https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv"] with (ignoreFirstRecord=true, format="csv");
geoData
| limit 10
in your real query you'd not have the limit, you'd use the kql join operator to do an intersection and you'd get your lat/long that way.

How to get the bounding coordinates for a US postal(zip) code?

Is there a service/API that will take a postal/zip code and return the bounding(perimeter) coordinates so I can build a Geometry object in a MS SQL database?
By bounding coordinates, I mean I would like to retrieve a list of GPS coordinates that construct a polygon that defines the US zip code.
An elaboration of my comment, that ZIP codes are not polygons....
We often think of ZIP codes as areas (polygons) because we say, "Oh, I live in this ZIP code..." which gives the impression of a containing region, and maybe the fact that ZIP stands for "Zone Improvement Plan" helps the false association with polygons.
In actuality, ZIP codes are lines which represent, in a sense, mail carrier routes. Geometrically, lines do not have area. Just as lines are strings of points along a coordinate plane, ZIP code lines are strings of delivery points in the abstract space of USPS-designated addresses.
They are not correlated to geographical coordinates. What you will find, though, is that they appear to be geographically oriented because it would be inefficient for carriers to have a route completely irrelevant of distance and location.
What is this "abstract space of USPS-designated addresses"? That's how I am describing the large and mysterious database of deliverable locations maintained by the US Postal Service. Addresses are not allotted based on geography, but on the routes that carriers travel which usually relates to streets and travelability.
Some 5-digit ZIP codes are only a single building, or a complex of buildings, or even a single floor of a building (yes, multiple zip codes can be at a single coordinate because their delivery points are layered vertically). Some of these -- among others -- are "unique" ZIPs. Companies and universities frequently get their own ZIP codes for marketing or organizational purposes. For instance, the ZIP code "12345" belongs to General Electric up in Schenectady, NY. (Edit: In a previous version of Google Maps, when you follow that link, you'd notice that the placement marker was hovering, because it points to a ZIP code, which is not a coordinate. While most US ZIP codes used to show a region on Google Maps, these types cannot because the USPS does not "own" them, so to speak, and they have no area.)
Just for fun, let's try verifying an address in a unique ZIP code. Head over to SmartyStreets and punch in a bogus address in 12345, like:
Street: 999 Sdf sdf
ZIP Code: 12345
When you try to verify that, notice that... it's VALID! Why? The USPS will deliver a piece to the receptacle for that unique ZIP code, but at that point, it's up to GE to distribute it. Pretty much anything internal to the ZIP code is irrelevant to the USPS, including the street address (technically "delivery line 1"). Many universities function in a similar manner. Here's more information regarding that.
Now, try the same bogus address, but without a ZIP code, and instead do the city/state:
Street: 999 Sdf sdf
City: Schenectady
State: NY
It doesn't validate. This is because even though Schenectady contains 12345, where the address is "valid," it geometrically intersects with the "real" ZIP codes for Schenectady.
Take another instance: military. Certain naval ships have their own ZIP codes. Military addresses are an entirely different class of addresses using the same namespace. Ships move. Geographical coordinates don't.
ZIP precision is another fun one. 5-digit ZIP codes are the least "precise" (though the term "specific" might be more meaningful here, since ZIP codes don't pinpoint anything). 7- and 9-digit ZIP codes are the most specific, often down to block or neighborhood-level in urban areas. But since each ZIP code is a different size, it's really hard to tell what actual distances you're talking.
A 9-digit ZIP code might be portioned to a floor of a building, so there you have overlapping ZIP codes for potentially hundreds of addresses.
Bottom line: ZIP codes don't, contrary to popular belief, provide geographical or boundary data. They vary widely and are actually quite un-helpful unless you're delivering mail or packages... but the USPS' job was to design efficient carrier routes, not partition the population into coordinate regions so much.
That's more the job of the census bureau. They've compiled a list of cartographic boundaries since ZIP codes are "convenient" to work with. To do this, they sectioned bunches of addresses into census blocks. Then, they aggregated USPS ZIP code data to find the relation between their census blocks (which has some rough coordinate data) and the ZIP codes. Thus, we have approximations of what it would look like to plot a line as a polygon. (Apparently, they converted a 1D line into a 2D polygon by transforming a 2D polygon based on its contents to fit linear data -- for each non-unique, regular ZIP code.)
From their website (link above):
A ZIP Code tabulation area (ZCTA) is a statistical geographic entity
that approximates the delivery area for a U.S. Postal Service
five-digit or three-digit ZIP Code. ZCTAs are aggregations of census
blocks that have the same predominant ZIP Code associated with the
addresses in the U.S. Census Bureau's Master Address File (MAF).
Three-digit ZCTA codes are applied to large contiguous areas for which
the U.S. Census Bureau does not have five-digit ZIP Code information
in its MAF. ZCTAs do not precisely depict ZIP Code delivery areas, and
do not include all ZIP Codes used for mail delivery. The U.S. Census
Bureau has established ZCTAs as a new geographic entity similar to,
but replacing, data tabulations for ZIP Codes undertaken in
conjunction with the 1990 and earlier censuses.
The USCB's dataset is incomplete, and at times inaccurate. Google still has holes in their data, too (the 12345 is a somewhat good example) -- but Google will patch it eventually by going over each address and ZIP code by hand. They do this already, but haven't made all their map data perfect quite yet. Naturally, access to this data is limited to API terms, and it's very expensive to raise these.
Phew. I'm beat. I hope that helps clarify things. Disclaimer: I used to be a developer at SmartyStreets. More information on geocoding with address data.
Even more information about ZIP codes.
What you are asking for is a service to provide "Free Zip code Geocoding". There are a few out there with varying quality. You're going to have a bad time coding something like this yourself because of a few reasons:
Zip codes can be assigned to a single building or to a post office.
Zip codes are NOT considered a polygonal area. Projecting Zip codes to a polygonal area will require you to make an educated guess where the boundary is between one zipcode and the next.
ZIP code address data specifies only a center location for the ZIP code. Zip code data provides the general vicinity of an address. Mailing addresses that exist between one zipcode and another can be in dispute on which zipcode it actually is in.
A mailing address may be physically closer to zipcode 11111, yet its official zip code is a more distant zip code point 11112.
Google Maps has a geocoding API:
The google maps API is client-side javascript. You can directly query the geocoding system from php using an http request. However, google maps only gives you what the United States Postal Service gives them. A point representing the center of the zipcode.
https://developers.google.com/maps/#Geocoding_Examples
map city/zipcode polygons using google maps
Thoughts on projecting a zipcode to its lat/long bounding box
There are approximately 43,000 ZIP Codes in the United States. This number fluctuates from month to month, depending on the number of changes made. The zipcodes used by the USPS are not represented as polygons and do not have hard and fast boundaries.
The USPS (United States Postal Service) is the authority that defines each zipcode lat/long. Any software which resolves a zipcode to a geographical location would be in need of weekly updates. One company called alignstar provides demographics and GIS data of zipcodes ( http://www.alignstar.com/data.html ).
Given a physical (mailing) address, find the geographical coordinates in order to display that location on a map.
If you want to reliably project what shape the zipcode is in, you are going to need to brute force it and ask: "give me every street address by zipcode", then paint boxes around those mis-shapen blobs. Then you can get a general feel for what geographical areas the zipcodes cover.
http://vterrain.org/Culture/geocoding.html
If you were to throw millions of mailing address points into an algorithm resolving every one to a lat/long, you might be able to build a rudimentary blob bounding box of that zipcode. You would have to re-run this algorithm and it would theoretically heal itself whenever the zipcode numbers move.
Other ideas
http://shop.delorme.com/OA_HTML/DELibeCCtpSctDspRte.jsp?section=10075
http://www.zip-codes.com/zip-code-map-boundary-data.asp
step 1:download cb_2018_us_zcta510_500k.zip
https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html
if you want to keep them in mysql
step 2: in your mysql create a db of named :spatialdata
run this command
ogr2ogr -f "MySQL" MYSQL:"spatialdata,host=localhost,user=root" -nln "map" -a_srs "EPSG:4683" cb_2018_us_zcta510_500k.shp -overwrite -addfields -fieldTypeToString All -lco ENGINE=MyISAM
i uploaded the file on github(https://github.com/sahilkashyap64/USA-zipcode-boundary/blob/master/USAspatialdata.zip)
In the your "spatialdata db" there will be 2 table named map & geometry_columns .
In 'map' there will be a column named "shape".
shape column is of type "geometry" and it contains polygon/multipolygon files
In 'geometry_columns' there will will be srid defined
how to check if point falls in the polygon
SELECT * FROM map WHERE ST_Contains( map.SHAPE, ST_GeomFromText( 'POINT(63.39550 -148.89730 )', 4683 ) )
and want to show boundary on a map
select zcta5ce10 as zipcode, ST_AsGeoJSON(SHAPE) sh from map where ST_Contains( map.SHAPE, ST_GeomFromText( 'POINT(34.1116 -85.6092 )', 4683 ) )
"ST_AsGeoJSON" this returns spatial data as geojson.
Use http://geojson.tools/
"HERE maps" to check the shape of geojson
if you want to generate topojson
mapshaper converts shapefile to topojson (no need to convert it to kml file)
npx -p mapshaper mapshaper-xl cb_2018_us_zcta510_500k.shp snap -simplify 0.1% -filter-fields ZCTA5CE10 -rename-fields zip=ZCTA5CE10 -o format=topojson cb_2018_us_zcta510_500k.json
If you want to convert shapefile to kml
`ogr2ogr -f KML tl_2019_us_zcta510.kml -mapFieldType Integer64=Real tl_2019_us_zcta510.shp
I have used mapbox gl to display 2 zipcodes
example: https://sahilkashyap64.github.io/USA-zipcode-boundary/
code :https://github.com/sahilkashyap64/USA-zipcode-boundary
SQL Server Solution
Download the Shape files from the US Census:
https://catalog.data.gov/dataset/2019-cartographic-boundary-shapefile-2010-zip-code-tabulation-areas-for-united-states-1-500000
I then found this repository to import the shape file to SQL Server, it was very fast and required no additional coding: https://github.com/xfischer/Shape2SqlServer
Then I could write my own script to find out which zip codes are in a polygon I created:
DECLARE #polygon GEOMETRY;
DECLARE #isValid bit = 0;
DECLARE #p nvarchar(2048) = 'POLYGON((-120.1547 39.2472,-120.3758 39.1950,-120.2124 38.7734,-119.6590 38.8162,-119.6342 39.3672,-120.1836 39.2525,-120.1547 39.2472))'
SET #polygon = GEOMETRY::STPolyFromText(#p,4326)
SET #isValid = #polygon.STIsValid()
IF (#isValid = 1)
SET #polygon = #polygon.MakeValid();
SET #isValid = #polygon.STIsValid()
IF (#isValid = 1)
BEGIN
SELECT * FROM cb_2019_us_zcta510_500k
WHERE geom.STIntersects(#polygon) = 1
END
ELSE
SELECT 'Polygon not valid'
I think this is what you need it uses US Census as repository: US Zipcode
Boundaries API: https://www.boundaries-io.com
Above API shows US Boundaries(GeoJson) by zipcode,city, and state. you should use the API programatically to handle large results.
Disclaimer,I work here
I think the world geoJson link and the google map geocode api can help you.
example: you can use the geocode api to code the zip,you will get the city,state,country,then,you search from the world and us geoJson get the boundry,I have an example of US State boundry,like dsdlink

How to match text in cmsplugin_text table to URL in Django CMS

We have created a site for a client using Django CMS and are approaching the launch date. There are a number of links to files on their old site. Doing a search of the cmsplugin_text table, I find 12 entries that contain the URL. There is no simple mapping to the new file download URL from the old download URL, so I need to find the pages these 12 entries appear on and tell our client so they can edit the page.
But the database is not easy to follow. So how do I go from the value of the cmsplugin_ptr_id column of the cmsplugin_text column to the URL of the page? I'm fairly sure that the cmsplugin_ptr_id is meant to line up with the id of the cms_cmsplugin table. That table also has parent_id, tree_id and placeholder_id, but I've kind of got lost at this point.
I'm happy to use either the database commands directly, or to use manage.py shell to do this.
Should have tried a bit harder before answering.
The steps that worked were to look in cms_page_placeholder for lines with the placeholder_id and look up the corresponding page_id. I could then look up the page in the admin at http://mysite.com/en/admin/cms/page/page_id and that page has a "View on site link".
The SQL statement I used was:
SELECT cpp.page_id
FROM cmsplugin_text AS cpt
LEFT JOIN cms_cmsplugin AS ccp ON cpt.cmsplugin_ptr_id = ccp.id
LEFT JOIN cms_page_placeholders AS cpp ON ccp.placeholder_id = cpp.placeholder_id
WHERE cpt.body like '%userfiles%';
Where userfiles was part of the path to the files on the old site.

When writing to an SQLite file in AppleScript 2.2 with application Database Events

I am making an AppleScript application with AppleScript 2.2 on Mac OS X 10.7 (Build: 11A511) Lion. What my application is doing is capturing the current iTunes song and storing it if the song is different from the last one. Then I told it to take the the current song and place it into an SQLite file using Database Events. Basically it is adding the current song to a new field, but when the song changes it says that there are no old fields and then writes the song (the process repeats...); I do have a save after it makes the field.
My code is as follows:
if currentsong is not equal to previous_song then
tell application "Database Events"
tell database "songlist"
set song to make new record with properties {name:"songs"}
set song_count to count fields
tell song
make new field with properties {name:currentsong, value:song_count + 1}
end tell
end tell
save database "songlist"
end tell
end if
It seems you're a little confused by records and fields. A database has records and a record has fields. In your code you are telling the database to count the fields... which is a problem because a database has records, not fields.
So change "fields" to "records" where you set the song_count. Also, if you want that count to be correct then put that line ahead of where you create the new record because you're trying to get the count before you add a new record.

Extracting SQLite database into text fields from specific row

I am trying to connect to a SQLite database and have a method that specifies a specific row from the database (the first column in the database is “ID” and is a primary key) then extract the information from a few other columns in that row and display them in text fields.
This will be used for a simple Trivia game I am making; I will later make a random method that will choose the row at random.
I have been struggling with this problem for several weeks and I have been through loads of tutorials but all of them deal with displaying the data in a table view, I want to display it simply on text fields in a View based app. I am fairly confused at this point so any help starting from loading the database to displaying the data in the text fields would be GREATLY APPRECIATED!
Thanks!
Link to libsqlite3.dylib (and import <sqlite3.h>) to access the power of SQLite. There are a number of lightweight Objective-C front ends and I suggest you pick one. In this example, I use fmdb (https://github.com/ccgus/fmdb) to read the names of people out of a previously created database:
NSString* docsdir = [NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString* dbpath = [docsdir stringByAppendingPathComponent:#"people.db"];
FMDatabase* db = [FMDatabase databaseWithPath:dbpath];
if (![db open]) {
NSLog(#"Ooops");
return;
}
FMResultSet *rs = [db executeQuery:#"select * from people"];
while ([rs next]) {
NSLog(#"%# %#",
[rs stringForColumn:#"firstname"],
[rs stringForColumn:#"lastname"]);
}
[db close];
/* output:
Snidely Whiplash
Dudley Doright
*/
That illustrates talking to the database; knowing SQL is up to you (and is a different topic). You can include a previously constructed SQLite file in your app bundle, but you can't write to it there; the solution is to copy it from your app bundle into another location, such as the Documents directory, before you start working with it.
Finally, to put strings into text fields (UITextField), set their text property. So for example instead of the while loop shown above, where I log the database results, I could use those results to set text field values:
myTextField.text = [rs stringForColumn:#"firstname"];
myOtherTextField.text = [rs stringForColumn:#"lastname"];

Resources