How to modify user datas inserted in sharedpreference before it's saved? - android-preferences

I would like to know if there is a simple way to modify a user data inserted in sharepreference before it's saved.
To be clear, I insert a code in my settings (preference), and I would like to crypt that code (for more security) then save it in sharepreference. When I read the preferences, I can decrypt that code, it's easy, but how to crypt it before preferences save it ?
I have several ideas :
1. make my own preferences and save it in a file or data base, but I would prefer to use sharepreference,
2. when exiting preferences (back key), read code inserted, crypt it, then save it, but lot of actions !
I'm looking for a better solution directly when I insert the code.
If you have a solution, thank you for your help

I think the better way is the second one.
create a new class (crypted_code) with a layout containing the editText box to read the code,
adding a public boolean onKeyDown(int keyCode, #NonNull KeyEvent event) to detect back key,
then save the code after crypting it :
code = crypt(code);
SharedPreferences mgr = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = mgr.edit();
editor.putString("code", code);
editor.apply();
finish();

Related

making discord bot command to store message content (python)

So this is my first time coding an actual project that isn't a small coding task. I've got a bot that runs and responds to a message if it says "hello". I've read the API documentation up and down and really only have a vague understanding of it and I'm not sure how to implement it.
My question right now is how would I go about creating a command that takes informationn from a message the command is replying to (sender's name, message content) and stores it as an object. Also, what would be the best way to store that information?
I want to learn while doing this and not just have the answers handed to me ofc, but I feel very lost. Not sure where to even begin.
I tried to find tutorials on coding discord bots that would have similar functions to what I want to do, but can't find anything.
Intro :
Hi NyssaDuke !
First of all, prefer to paste your code instead of a picture. It's easier for us to take your code and try to produce what you wish.
In second, I see an "issue" in your code since you declare twice the bot. You can specify the intents when you declare your bot as bot = commands.Bot(command_prefix="!", intents=intents)
Finally, as stated by #stijndcl , it's against TOS, but I will try to answer you at my best.
filesystem
My bot needs to store data, like users ID, language, and contents relative to a game, to get contacted further. Since we can have a quite big load of requests in a small time, I prefered to use a file to store instead of a list that would disappear on crash, and file allow us to make statistics later. So I decided to use pytables that you can get via pip install pytables. It looks like a small DB in a single file. The file format is HDF5.
Let say we want to create a table containing user name and user id in a file :
import tables
class CUsers (tables.IsDescription) :
user_name = StringCol(32)
user_id = IntCol()
with tables.open_file("UsersTable.h5", mode="w") as h5file :
groupUser = h5file.create_group("/", "Users", "users entries")
tableUser = h5file.create_table(groupUser, "Users", CUsers, "users table")
We have now a file UsersTable.h5 that has an internal table located in root/Users/Users that is accepting CUsers objects, where, therefore, user_name and user_id are the columns of that table.
getting user info and storing it
Let's now code a function that will register user infos, and i'll call it register. We will get the required data from the Context that is passed with the command, and we'll store it in file.
#bot.command(name='register')
async def FuncRegister (ctx) :
with tables.open_file("UsersTable.h5", mode="a") as h5file :
tableUser = h5file.root.Users.Users
particle = tableUser.row
particle['user_name'] = str(ctx.author)
particle['user_id'] = ctx.author.id
particle.append()
tableUser.flush()
The last two lines are sending the particle, that is the active row, so that is an object CUsers, into the file.
An issue I got here is that special characters in a nickname can make the code bug. It's true for "é", "ü", etc, but also cyrillic characters. What I did to counter is to encode the user name into bytes, you can do it by :
particle['user_name'] = str(ctx.author).encode()
reading file
It is where it starts to be interesting. The HFS5 file allows you to use kind of sql statements. Something you have to take in mind is that strings in the file are UTF-8 encoded, so when you extract them, you have to call for .decode(utf-8). Let's now code a function where a user can remove its entry, based on its id :
#bot.command(name="remove")
async def FuncRemove(ctx) :
with tables.open_file("UsersTable.h5", mode="a") as h5file :
tableUser = h5file.root.Users.Users
positions = tableUser.get_where_list("(user_id == '%d')" % ctx.author.id)
nameuser = tableUser[positions[0]]['user_name'].decode('utf-8')
tableUser.remove_row(positions[0])
.get_where_list() returns a list of positions in the file, that I later address to find the right position in the table.
bot.fetch_user(id)
If possible, prefer saving ID over name, as it complicates the code with encode() and decode(), and that bots have access to a wonderful function that is fetch_user(). Let's code a last function that will get you the last entry in your table, and with the id, print the username with the fetch method :
#bot.command(name="last")
async def FuncLast(ctx) :
with tables.open_file("UsersTable.h5", mode="r") as h5file :
tableUser = h5file.root.Users.Users
lastUserIndex = len(tableUser) - 1
iduser = tableUser[lastUserIndex]['user_id']
member = await bot.fetch_user(iduser)
await ctx.send(member.display_name)
For further documentation, check the manual of discord.py, this link to context in particular.

Create a method that convert a List<SObject> to a Map<SObjectField, SObject> with SObjectField as method parameter, any suggestions?

global with sharing class test1 {
global Map<SObjectField, SObject> ConvertMap(List<SObject> listToConvert){
List<SObject> listToConvert = new List<SObject>;
Map<SObjectField, SObject> mapTest = new Map<SObjectField, SObject>;
mapTest.putAll(listToConvert);
return mapTest;
}
I've written this code, but it doesn't respect the request 'cause I can't put SObjectField as method parameter since the Map won't recognize the variable.
Does anyone have suggestions on how to do it?
Thank you in advance.
Do you really need SobjectField as map keys? the special class? If you're fine with strings as keys then there's a builtin, getPopulatedFieldsAsMap()
If you absolutely need SobjectField (I don't even know if it's serializable and can be passed to integrations, LWC etc)... You'd have to loop and marry the results to something like
Schema.describeSObjects(new List<String>{'Account'})[0].fields.getMap()

Save Images in Room Database

I want to save small images in my room database and I have two issues:
How do I save an image in my database?
How do I save multiple images in my database?
I tried saving a bitmap in the way recommended by the developers page (https://developer.android.com/training/data-storage/room/defining-data)
#Parcelize
#Entity(tableName = "image_table")
data class ImgMod(
#PrimaryKey(autoGenerate = true)
var invoiceId: Long = 0L,
#ColumnInfo(name = "image")
var single_img: Bitmap?
): Parcelable
However, I receive the following error:
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
Secondly, I would like to save multiple images in one database entry. But I receive the same error with the following snippets:
#ColumnInfo(name = "imageList")
var img_list: ArrayList<BitMap>
or decoded bitmap as a String
#ColumnInfo(name = "imageList")
var decoded_img_list: ArrayList<String>
I am sorry if this is a very basic question. But how do I have to configure the database/process the data to an image list?
Thank you in advance,
rot8
A very simple way to get images into the database (although I personally discourage it) would be to base-64 encode the bitmaps into a String and put it into a row of the database.
Take in account that bitmaps are very memory heavy; and base64 encoding something increases it's size some more so be careful when loading a bunch of images... I do also think Room and SQLite supports binary data as blobs, so you could just declare a column as ByteArray and it should just work.
What I've been doing in my projects is to write them into the internal or external storage of my app and then store the reference Uri as a String to later be able to retrieve the image from disk.
Something that I discourage even more is to stuff more than one value per row; having a list of stuff inside a coulmn in SQL is definetely not a pattern you should follow. Creating a "join" table should be simple enough or simply an extra column you could use to group them by should be easy enough, right?

Document status that depend on the user type object

I have the following objects: L1User, L2User, L3User (all inherits from User) and Document.
Every user can create the document but depending on the user type, the document will have a different status. So in case it's L1User, the document will be created with L1 status and so on:
Solution 1
Please note that after document is created, it will be saved in the database, so it should be natural to have a method create_document(User user) in Document object. In the method body I could check which type is the user and set manually appropriate status. Such approach seems rather not OOP to me.
Solution 2
Ok, so the next approach would be to have all users implement a common method (say create_document(Document doc)) which will set a status associated with the user and save the document in the database. My doubt here is that the document should be saved in it's own class, not the user.
Solution 3
So the final approach would similar to the above, except that the user will return modified document object to it's create_document(User user) method and save will be performed there. The definition of the method would be like this:
create_document(User user)
{
this = user.create_document(this);
this->save();
}
It also doesn't seems right to me...
Can anyone suggest a better approach?
I think that both Solutions 2 and 3 are ok from the OO point of view, since you are properly delegating the status assignment to the user object (contrary to solution 1, whare you are basically doing a switch based on the user type). Whether to choose 2 or 3 is more a matter of personal tastes.
However, I have a doubt: why do you pass a document to a create_document() method? I would go for a message name that best describes what it does. For example, in solution 3 (the one I like the most) I would go for:
Document>>create_document(User user)
{
this = user.create_document();
this->save();
}
and then
L1User>>create_document()
{
return new Document('L1');
}
or
Document>>create_document(User user)
{
this = new Document()
this = user.set_document_type(this);
this->save();
}
and then
L1User>>set_document_type(document)
{
document.setType('L1');
}
Edit: I kept thinking about this and there is actually a fourth solution. However the following approach works only if the status of a document doesn't change through its lifetime and you can map the DB field with a getter instead of a property. Since the document already knows the user and the status depends on the user, you can just delegate:
Document>>getStatus()
{
return this.user.getDocumentStatus();
}
HTH

Retrieving Specific Active Directory Record Attributes using C#

I've been asked to set up a process which monitors the active directory, specifically certain accounts, to check that they are not locked so that should this happen, the support team can get an early warning.
I've found some code to get me started which basically sets up requests and adds them to a notification queue. This event is then assigned to a change event and has an ObjectChangedEventArgs object passed to it.
Currently, it iterates through the attributes and writes them to a text file, as so:
private static void NotifierObjectChanged(object sender,
ObjectChangedEventArgs e)
{
if (e.ResultEntry.Attributes.AttributeNames == null)
{
return;
}
// write the data for the user to a text file...
using (var file = new StreamWriter(#"C:\Temp\UserDataLog.txt", true))
{
file.WriteLine("{0} {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString());
foreach (string attrib in e.ResultEntry.Attributes.AttributeNames)
{
foreach (object item in e.ResultEntry.Attributes[attrib].GetValues(typeof(string)))
{
file.WriteLine("{0}: {1}", attrib, item);
}
}
}
}
What I'd like is to check the object and if a specific field, such as name, is a specific value, then check to see if the IsAccountLocked attribute is True, otherwise skip the record and wait until the next notification comes in. I'm struggling how to access specific attributes of the ResultEntry without having to iterate through them all.
I hope this makes sense - please ask if I can provide any additional information.
Thanks
Martin
This could get gnarly depending upon your exact business requirements. If you want to talk in more detail ping me offline and I'm happy to help over email/phone/IM.
So the first thing I'd note is that depending upon what the query looks like before this, this could be quite expensive or error prone (ie missing results). This worries me somewhat as most sample code out there gets this wrong. :) How are you getting things that have changed? While this sounds simple, this is actually a somewhat tricky question in directory land, given the semantics supported by AD and the fact that it is a multi-master system where writes happen all over the place (and replicate in after the fact).
Other variables would be things like how often you're going to run this, how large the data set could be in AD, and so on.
AD has some APIs built to help you here (the big one that comes to mind is called DirSync) but this can be somewhat complicated if you haven't used it before. This is where the "ping me offline" part comes in.
To your exact question, I'm assuming your result is actually a SearchResultEntry (if not I can revise, tell me what you have in hand). If that is the case then you'll find an Attributes field hanging off of that guy, and from there there is AttributeNames and Values. I think you'll see how it works from there if you have Values in hand, for example:
foreach (var attr in sre.Attributes.Values)
{
var da = (DirectoryAttribute)attr;
Console.WriteLine(da.Name);
foreach (var val in da.GetValues(typeof(byte[])))
{
// Handle a byte[] val ...
}
}
As I said, if you have something other than a SearchResultEntry in hand, let us know and I can revise the code sample.

Resources