亽野灬性zι浪

文章 评论 浏览 29

亽野灬性zι浪 2025-02-20 11:13:07

这是因为令牌缺少填充物。尝试一下

let encodedString = base64String.replace(/-/g, "+").replace(/_/g, "/");
switch (encodedString.length % 4) {
    case 0:
        break;
    case 2:
        encodedString += "==";
        break;
    case 3:
        encodedString += "=";
        break;
    default:
        throw createBrowserAuthError(
            BrowserAuthErrorCodes.invalidBase64String
        );
}
const binString = atob(encodedString);

This is because the token is missing the padding. Try this

let encodedString = base64String.replace(/-/g, "+").replace(/_/g, "/");
switch (encodedString.length % 4) {
    case 0:
        break;
    case 2:
        encodedString += "==";
        break;
    case 3:
        encodedString += "=";
        break;
    default:
        throw createBrowserAuthError(
            BrowserAuthErrorCodes.invalidBase64String
        );
}
const binString = atob(encodedString);

用ATOB在前端解码JWT令牌使我无法执行ATOB'在窗口上'错误

亽野灬性zι浪 2025-02-20 03:14:25

可能以一种或另一种方式上最常见的答案是:

awk -F',' 'NR==FNR{ids[$1]; next} $1 in ids' ids.csv data.csv > out.csv

这将比您现有的脚本快。

关于为什么您的原始脚本很慢,请参见 Why-is-Is-us-a-shell-shell-loop-to-to-tox-text-text-text-the-tossed-bad-practice

Probably the most common answer on this forum in one way or another:

awk -F',' 'NR==FNR{ids[$1]; next} $1 in ids' ids.csv data.csv > out.csv

That will be an order of magnitude faster than your existing script.

Regarding why your original script is slow, see why-is-using-a-shell-loop-to-process-text-considered-bad-practice.

如何使用BASH从另一个文件中的ID列表中快速过滤巨大的CSV文件?

亽野灬性zι浪 2025-02-20 01:28:35

您可以添加'./node_modules/sample-library-lib/esm2020/dypy/dhe.dhe.mjs'将此行添加到内容数组中。它应该解决问题。

You can add './node_modules/sample-library-lib/esm2020/**/*.mjs' this line to content array. It should fix the problem.

使用尾风的角库

亽野灬性zι浪 2025-02-19 21:23:33

根据我的理解,您想显示表单实例的值。您可以做:

form.instance.parent.name

From my understanding, you want to display the form instance's values. You can do:

form.instance.parent.name

使用Django模型表单时,如何在模板中访问模板中的外键相关字段

亽野灬性zι浪 2025-02-19 16:10:15

您似乎正在混淆一些问题。

为什么Akka有自己的RPC而不是HTTP。

答案是路由/可靠性。 Akka的目的是分布式分布式系统,当您进行RAW HTTP时,如何使所有消息保持正确的所有路线?另外,使用大量机器,您如何确保每次通话一次一次,仅在群集上一次发生一次?

为什么要与演员打扰?

演员是高度并发系统的模式。演员允许开发人员推理状态寿命和流程居住的地方,将它们分开,并允许演员运行时快速运行大量演员实例,而不必担心复杂的事物,例如“线程”和“线程安全”。

当您到达职业生涯的某个点时,您会发现“线程安全”非常难以正确。哎呀,我最喜欢的编程语言是一种以迫使您正确进行线程而闻名的语言。问题在于,如果没有一些系统的过程来编写代码,那么在完全不同的项目中,两个看似无关的代码行可能会产生难以复制的细微错误。

高度并发系统的另一个范式是功能性编程,但是与其相关的绩效惩罚。

TLDR

Actors模式旨在解决您在大型庞大的代码库中遇到的问题,许多非天然级别的开发人员同时使用数百台服务器运行。

You seem to be conflating a few issues.

Why does Akka have its own RPC instead of HTTP.

The answer is routing/reliability. Akka is meant to hugely distributed systems, and when you do raw HTTP, how do you keep all the routes correct for each message? Also, with huge numbers of machines, how do you ensure each call happens once and only once on your cluster?

Why bother with Actors?

Actors are a pattern for highly concurrent systems. Actors allow developers to reason where state lives and where processes live, separate them out, and allow the actor runtime to quickly run huge numbers of actor instances without worrying about complex things like "threads" and "thread-safety".

When you get to a certain point in your career, you will find that "thread-safety" is incredibly hard to do right. Heck, my favourite programming language is one that is famous for forcing you to do threading correctly. The problem is that, without some systematic process to write your code, two seemingly unrelated lines of code in completely different projects can produce subtle bugs that are hard to reproduce.

Another paradigm for highly concurrent systems is Functional Programming, that however has massive performance penalties associated with it.

TLDR

The Actors pattern is designed to solve problems you encounter in large sprawling codebases with many non-genius level developers working on it at the same time, running on hundreds of servers.

演员与HTTP

亽野灬性zι浪 2025-02-19 13:33:40

您问题的核心是:

结果对于小表来说是正确的,但是1000万行只会导致记忆错误,我正在寻找避免这种情况的方法。

遵循您的顶级问题语句,但使用较少通用的结构,我们可以做类似的事情:

def runQuery(dataLines):
    from collections import defaultdict
    pred = dict(zip(['follows','friendOf','likes','hasReview'],range(4)))
    tables = [defaultdict(list) for _ in pred]

    def encode(s):
        if s[-1].isdigit():
            i = 0
            while s[-1 - i].isdigit():
                i += 1
            return int(s[-i:])
        if any(s.endswith(k) for k in pred):
            return sum(v for k, v in pred.items() if s.endswith(k))
        return None
    
    for line in dataLines:
        if not line:
            continue
        subj, prop, *obj = line.rstrip('\n.').split('\t')
        obj = obj[0].rstrip()
        subj, prop, obj = [encode(s) for s in (subj, prop, obj)]
        if prop is not None:
            tables[prop][subj].append(obj)

    tables = [{k:tuple(v) for k, v in table.items()} for table in tables]
    #[print(list(pred.keys())[i], tables[i], sep='\n') for i in range(len(pred))]

    # create reverse index for subject, object where subject [user] follows object [user]
    object_of_follows = defaultdict(set)
    for k, v in tables[pred['follows']].items():
        for user in v:
            object_of_follows[user].add(k)
    # create reverse index for subject, object where subject [user] is friendOf object [user]
    object_of_friendOf = defaultdict(set)
    for k, v in tables[pred['friendOf']].items():
        if k in object_of_follows:
            for user in v:
                object_of_friendOf[user].add(k)
    # create reverse index for subject, object where subject [user] likes object [product]
    object_of_likes = defaultdict(set)
    for k, v in tables[pred['likes']].items():
        if k in object_of_friendOf:
            for product in v:
                object_of_likes[product].add(k)
    # create reverse index for subject, object where subject [product] hasReview object [review]
    object_of_hasReview = defaultdict(set)
    for k, v in tables[pred['hasReview']].items():
        if k in object_of_likes:
            for review in v:
                object_of_hasReview[review].add(k)

    def addToResult(result, e):
        d = object_of_hasReview[e]
        c = {y for x in d for y in object_of_likes[x]}
        b = {y for x in c for y in object_of_friendOf[x]}
        a = {y for x in b for y in object_of_follows[x]}
        toAdd = [(ax, bx, cx, dx, e) for dx in d for cx in c for bx in b for ax in a]
        result += toAdd

    result = []
    for e in object_of_hasReview:
        addToResult(result, e)
    print(f'result row count {len(result):,}')
    return result

说明:

  • 创建4个表的列表( conters,friendf,likes,likes,hasreview ),每个词典映射受对象元组的约束,
  • 创建4个反向索引( object_of_follows,object_of_friendof,object_of_likes, object_of_hasreview );例如:
    • object_of_follows 是一个dict,它映射每个用户中的对象都遵循 映射到一组用户,每个用户都是中的主题,请的代码>
      friendf at object_of_follows (换句话说,是中一个或多个主题的对象, conters
    • 等。
  • object_of_hasreview 中包含每个唯一结果的多个结果行 contrys.subject,closts.Object,object,friendsof.object,likes.object, hasreview.Object ,如查询中指定的
  • 返回所有此类爆炸行的列表。

1000万行的测试代码:

dataLines = []
numFollowers = 1000
numChildren = 10
overlapFactor = max(1, numChildren // 2)
def largerPowerOfTen(x):
    y = 1
    while x >= y:
        y *= 10
    return y

aCeil = largerPowerOfTen(numFollowers)
bCeil = largerPowerOfTen(aCeil * numChildren)
cCeil = largerPowerOfTen(bCeil * numChildren)
dCeil = largerPowerOfTen(cCeil * numChildren)
friendOf, likes = set(), set()
for a in range(numFollowers):
    for b in range(aCeil + a * overlapFactor, aCeil + a * overlapFactor + numChildren):
        dataLines.append(f'wsdbm:User{a}    wsdbm:follows   wsdbm:User{b} .\n')
        for c in range(bCeil + b * overlapFactor, bCeil + b * overlapFactor + numChildren):
            if (b,c) not in friendOf:
                dataLines.append(f'wsdbm:User{b}    wsdbm:friendOf  wsdbm:User{c} .\n')
                friendOf.add((b,c))
            for d in range(cCeil + c * overlapFactor, cCeil + c * overlapFactor + numChildren):
                if (c,d) not in likes:
                    dataLines.append(f'wsdbm:User{c}    wsdbm:likes wsdbm:Product{d} .\n')
                    likes.add((c,d))
                for e in range(dCeil * (d + 1), dCeil * (d + 1) + numChildren):
                    dataLines.append(f'wsdbm:Product{d} wsdbm:hasReview wsdbm:Review{e} .\n')

print(f'dataLines row count {len(dataLines):,}')

from timeit import timeit
n = 1
print(f'Timeit results:')
t = timeit(f"runQuery(dataLines)", setup=f"from __main__ import dataLines, runQuery", number=n) / n
print(f'======== runQuery ran in {t} seconds using {n} iterations')
'''
result = runQuery(dataLines)
print(f'result row count {len(result):,}')
print(f'{"follows.subject":>20}{"follows.object":>20}{"friendsOf.object":>20}{"likes.object":>20}{"hasReview.object":>20}')
[print(f'{a:20}{b:20}{c:20}{d:20}{e:20}') for a,b,c,d,e in result]
'''

输出:

dataLines row count 10,310,350
Timeit results:
result row count 12,398,500
======== runQuery ran in 81.53253880003467 seconds using 1 iterations

较小规模的样本运行中的输入/输出:

参数

numFollowers = 3
numChildren = 3
overlapFactor = 2

输入(存储在表中):

follows
{0: (10, 11, 12), 1: (12, 13, 14), 2: (14, 15, 16)}
friendOf
{10: (120, 121, 122), 11: (122, 123, 124), 12: (124, 125, 126), 13: (126, 127, 128), 14: (128, 129, 130), 15: (130, 131, 132), 16: (132, 133, 134)}
likes
{120: (1240, 1241, 1242), 121: (1242, 1243, 1244), 122: (1244, 1245, 1246), 123: (1246, 1247, 1248), 124: (1248, 1249, 1250), 125: (1250, 1251, 1252), 126: (1252, 1253, 1254), 127: (1254, 1255, 1256), 128: (1256, 1257, 1258), 129: (1258, 1259, 1260), 130: (1260, 1261, 1262), 131: (1262, 1263, 1264), 132: (1264, 1265, 1266), 133: (1266, 1267, 1268), 134: (1268, 1269, 1270)}
hasReview
{1240: (12410000, 12410001, 12410002), 1241: (12420000, 12420001, 12420002), 1242: (12430000, 12430001, 12430002, 12430000, 12430001, 12430002), 1243: (12440000, 12440001, 12440002), 1244: (12450000, 12450001, 12450002, 12450000, 12450001, 12450002, 12450000, 12450001, 12450002), 1245: (12460000, 12460001, 12460002, 12460000, 12460001, 12460002), 1246: (12470000, 12470001, 12470002, 12470000, 12470001, 12470002, 12470000, 12470001, 12470002), 1247: (12480000, 12480001, 12480002), 1248: (12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002), 1249: (12500000, 12500001, 12500002, 12500000, 12500001, 12500002, 12500000, 12500001, 12500002), 1250: (12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002), 1251: (12520000, 12520001, 12520002, 12520000, 12520001, 12520002), 1252: (12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002), 1253: (12540000, 12540001, 12540002, 12540000, 12540001, 12540002, 12540000, 12540001, 12540002), 1254: (12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002), 1255: (12560000, 12560001, 12560002), 1256: (12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002), 1257: (12580000, 12580001, 12580002, 12580000, 12580001, 12580002, 12580000, 12580001, 12580002), 1258: (12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002), 1259: (12600000, 12600001, 12600002, 12600000, 12600001, 12600002), 1260: (12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002), 1261: (12620000, 12620001, 12620002, 12620000, 12620001, 12620002, 12620000, 12620001, 12620002), 1262: (12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002), 1263: (12640000, 12640001, 12640002), 1264: (12650000, 12650001, 12650002, 12650000, 12650001, 12650002, 12650000, 12650001, 12650002), 1265: (12660000, 12660001, 12660002, 12660000, 12660001, 12660002), 1266: (12670000, 12670001, 12670002, 12670000, 12670001, 12670002, 12670000, 12670001, 12670002), 1267: (12680000, 12680001, 12680002), 1268: (12690000, 12690001, 12690002, 12690000, 12690001, 12690002), 1269: (12700000, 12700001, 12700002), 1270: (12710000, 12710001, 12710002)}

输出

result row count 351
     follows.subject      follows.object    friendsOf.object        likes.object    hasReview.object
                   0                  10                 120                1240            12410000
                   0                  10                 120                1240            12410001
                   0                  10                 120                1240            12410002
                   0                  10                 120                1241            12420000
                   0                  10                 120                1241            12420001
                   0                  10                 120                1241            12420002
                   0                  10                 120                1242            12430000
                   0                  10                 121                1242            12430000
                   0                  10                 120                1242            12430001
                   0                  10                 121                1242            12430001
                   0                  10                 120                1242            12430002
                   0                  10                 121                1242            12430002
                   0                  10                 121                1243            12440000
                   0                  10                 121                1243            12440001
                   0                  10                 121                1243            12440002
                   0                  10                 121                1244            12450000
                   0                  11                 121                1244            12450000
                   0                  10                 122                1244            12450000
                   0                  11                 122                1244            12450000
                   0                  10                 121                1244            12450001
                   0                  11                 121                1244            12450001
                   0                  10                 122                1244            12450001
                   0                  11                 122                1244            12450001
                   0                  10                 121                1244            12450002
                   0                  11                 121                1244            12450002

etc.

The core of your question is this:

The result is correct for small tables, but 10 million rows simply result in an Out of Memory Error and I am looking for ways to avoid this.

Following your top-level problem statement but with a less generic structure, we can do something like this:

def runQuery(dataLines):
    from collections import defaultdict
    pred = dict(zip(['follows','friendOf','likes','hasReview'],range(4)))
    tables = [defaultdict(list) for _ in pred]

    def encode(s):
        if s[-1].isdigit():
            i = 0
            while s[-1 - i].isdigit():
                i += 1
            return int(s[-i:])
        if any(s.endswith(k) for k in pred):
            return sum(v for k, v in pred.items() if s.endswith(k))
        return None
    
    for line in dataLines:
        if not line:
            continue
        subj, prop, *obj = line.rstrip('\n.').split('\t')
        obj = obj[0].rstrip()
        subj, prop, obj = [encode(s) for s in (subj, prop, obj)]
        if prop is not None:
            tables[prop][subj].append(obj)

    tables = [{k:tuple(v) for k, v in table.items()} for table in tables]
    #[print(list(pred.keys())[i], tables[i], sep='\n') for i in range(len(pred))]

    # create reverse index for subject, object where subject [user] follows object [user]
    object_of_follows = defaultdict(set)
    for k, v in tables[pred['follows']].items():
        for user in v:
            object_of_follows[user].add(k)
    # create reverse index for subject, object where subject [user] is friendOf object [user]
    object_of_friendOf = defaultdict(set)
    for k, v in tables[pred['friendOf']].items():
        if k in object_of_follows:
            for user in v:
                object_of_friendOf[user].add(k)
    # create reverse index for subject, object where subject [user] likes object [product]
    object_of_likes = defaultdict(set)
    for k, v in tables[pred['likes']].items():
        if k in object_of_friendOf:
            for product in v:
                object_of_likes[product].add(k)
    # create reverse index for subject, object where subject [product] hasReview object [review]
    object_of_hasReview = defaultdict(set)
    for k, v in tables[pred['hasReview']].items():
        if k in object_of_likes:
            for review in v:
                object_of_hasReview[review].add(k)

    def addToResult(result, e):
        d = object_of_hasReview[e]
        c = {y for x in d for y in object_of_likes[x]}
        b = {y for x in c for y in object_of_friendOf[x]}
        a = {y for x in b for y in object_of_follows[x]}
        toAdd = [(ax, bx, cx, dx, e) for dx in d for cx in c for bx in b for ax in a]
        result += toAdd

    result = []
    for e in object_of_hasReview:
        addToResult(result, e)
    print(f'result row count {len(result):,}')
    return result

Explanation:

  • Create a list of 4 tables (follows, friendOf, likes, hasReview), each a dictionary mapping subject to a tuple of objects
  • Create 4 reverse indexes (object_of_follows, object_of_friendOf, object_of_likes, object_of_hasReview); for example:
    • object_of_follows is a dict that maps each user that is an object in follows to a set of users, each of which is a subject in follows that follows the object
    • object_of_friendOf is a dict that maps each object (user) in friendOf to a set of users, each of which is a subject (user) associated with the object in friendOf and is in object_of_follows (in other words, is an object for one or more subjects in follows)
    • etc.
  • Explode each review that survived in object_of_hasReview into multiple result rows containing each unique result follows.subject, follows.object, friendsOf.object, likes.object, hasReview.object as specified in the query
  • Return the list of all such exploded rows.

Test code for 10 million lines:

dataLines = []
numFollowers = 1000
numChildren = 10
overlapFactor = max(1, numChildren // 2)
def largerPowerOfTen(x):
    y = 1
    while x >= y:
        y *= 10
    return y

aCeil = largerPowerOfTen(numFollowers)
bCeil = largerPowerOfTen(aCeil * numChildren)
cCeil = largerPowerOfTen(bCeil * numChildren)
dCeil = largerPowerOfTen(cCeil * numChildren)
friendOf, likes = set(), set()
for a in range(numFollowers):
    for b in range(aCeil + a * overlapFactor, aCeil + a * overlapFactor + numChildren):
        dataLines.append(f'wsdbm:User{a}    wsdbm:follows   wsdbm:User{b} .\n')
        for c in range(bCeil + b * overlapFactor, bCeil + b * overlapFactor + numChildren):
            if (b,c) not in friendOf:
                dataLines.append(f'wsdbm:User{b}    wsdbm:friendOf  wsdbm:User{c} .\n')
                friendOf.add((b,c))
            for d in range(cCeil + c * overlapFactor, cCeil + c * overlapFactor + numChildren):
                if (c,d) not in likes:
                    dataLines.append(f'wsdbm:User{c}    wsdbm:likes wsdbm:Product{d} .\n')
                    likes.add((c,d))
                for e in range(dCeil * (d + 1), dCeil * (d + 1) + numChildren):
                    dataLines.append(f'wsdbm:Product{d} wsdbm:hasReview wsdbm:Review{e} .\n')

print(f'dataLines row count {len(dataLines):,}')

from timeit import timeit
n = 1
print(f'Timeit results:')
t = timeit(f"runQuery(dataLines)", setup=f"from __main__ import dataLines, runQuery", number=n) / n
print(f'======== runQuery ran in {t} seconds using {n} iterations')
'''
result = runQuery(dataLines)
print(f'result row count {len(result):,}')
print(f'{"follows.subject":>20}{"follows.object":>20}{"friendsOf.object":>20}{"likes.object":>20}{"hasReview.object":>20}')
[print(f'{a:20}{b:20}{c:20}{d:20}{e:20}') for a,b,c,d,e in result]
'''

Output:

dataLines row count 10,310,350
Timeit results:
result row count 12,398,500
======== runQuery ran in 81.53253880003467 seconds using 1 iterations

Here's input/output from a smaller-scale sample run:

Params

numFollowers = 3
numChildren = 3
overlapFactor = 2

Input (after storing in tables):

follows
{0: (10, 11, 12), 1: (12, 13, 14), 2: (14, 15, 16)}
friendOf
{10: (120, 121, 122), 11: (122, 123, 124), 12: (124, 125, 126), 13: (126, 127, 128), 14: (128, 129, 130), 15: (130, 131, 132), 16: (132, 133, 134)}
likes
{120: (1240, 1241, 1242), 121: (1242, 1243, 1244), 122: (1244, 1245, 1246), 123: (1246, 1247, 1248), 124: (1248, 1249, 1250), 125: (1250, 1251, 1252), 126: (1252, 1253, 1254), 127: (1254, 1255, 1256), 128: (1256, 1257, 1258), 129: (1258, 1259, 1260), 130: (1260, 1261, 1262), 131: (1262, 1263, 1264), 132: (1264, 1265, 1266), 133: (1266, 1267, 1268), 134: (1268, 1269, 1270)}
hasReview
{1240: (12410000, 12410001, 12410002), 1241: (12420000, 12420001, 12420002), 1242: (12430000, 12430001, 12430002, 12430000, 12430001, 12430002), 1243: (12440000, 12440001, 12440002), 1244: (12450000, 12450001, 12450002, 12450000, 12450001, 12450002, 12450000, 12450001, 12450002), 1245: (12460000, 12460001, 12460002, 12460000, 12460001, 12460002), 1246: (12470000, 12470001, 12470002, 12470000, 12470001, 12470002, 12470000, 12470001, 12470002), 1247: (12480000, 12480001, 12480002), 1248: (12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002, 12490000, 12490001, 12490002), 1249: (12500000, 12500001, 12500002, 12500000, 12500001, 12500002, 12500000, 12500001, 12500002), 1250: (12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002, 12510000, 12510001, 12510002), 1251: (12520000, 12520001, 12520002, 12520000, 12520001, 12520002), 1252: (12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002, 12530000, 12530001, 12530002), 1253: (12540000, 12540001, 12540002, 12540000, 12540001, 12540002, 12540000, 12540001, 12540002), 1254: (12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002, 12550000, 12550001, 12550002), 1255: (12560000, 12560001, 12560002), 1256: (12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002, 12570000, 12570001, 12570002), 1257: (12580000, 12580001, 12580002, 12580000, 12580001, 12580002, 12580000, 12580001, 12580002), 1258: (12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002, 12590000, 12590001, 12590002), 1259: (12600000, 12600001, 12600002, 12600000, 12600001, 12600002), 1260: (12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002, 12610000, 12610001, 12610002), 1261: (12620000, 12620001, 12620002, 12620000, 12620001, 12620002, 12620000, 12620001, 12620002), 1262: (12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002, 12630000, 12630001, 12630002), 1263: (12640000, 12640001, 12640002), 1264: (12650000, 12650001, 12650002, 12650000, 12650001, 12650002, 12650000, 12650001, 12650002), 1265: (12660000, 12660001, 12660002, 12660000, 12660001, 12660002), 1266: (12670000, 12670001, 12670002, 12670000, 12670001, 12670002, 12670000, 12670001, 12670002), 1267: (12680000, 12680001, 12680002), 1268: (12690000, 12690001, 12690002, 12690000, 12690001, 12690002), 1269: (12700000, 12700001, 12700002), 1270: (12710000, 12710001, 12710002)}

Output

result row count 351
     follows.subject      follows.object    friendsOf.object        likes.object    hasReview.object
                   0                  10                 120                1240            12410000
                   0                  10                 120                1240            12410001
                   0                  10                 120                1240            12410002
                   0                  10                 120                1241            12420000
                   0                  10                 120                1241            12420001
                   0                  10                 120                1241            12420002
                   0                  10                 120                1242            12430000
                   0                  10                 121                1242            12430000
                   0                  10                 120                1242            12430001
                   0                  10                 121                1242            12430001
                   0                  10                 120                1242            12430002
                   0                  10                 121                1242            12430002
                   0                  10                 121                1243            12440000
                   0                  10                 121                1243            12440001
                   0                  10                 121                1243            12440002
                   0                  10                 121                1244            12450000
                   0                  11                 121                1244            12450000
                   0                  10                 122                1244            12450000
                   0                  11                 122                1244            12450000
                   0                  10                 121                1244            12450001
                   0                  11                 121                1244            12450001
                   0                  10                 122                1244            12450001
                   0                  11                 122                1244            12450001
                   0                  10                 121                1244            12450002
                   0                  11                 121                1244            12450002

etc.

摆脱记忆错误以加入算法

亽野灬性zι浪 2025-02-19 10:50:40

如Willem提到的,您需要在 auth_user_model 内置 settings.py account> accounts.customeruser 模型中更新 auth_user_model 。此外,当您第一次运行迁移时,您将必须手动更新架构,Django将使用默认的 auth.user 进行多个外键等。请参阅docs 此处用于更改用户中间项目。

As Willem mentioned, you need to update your AUTH_USER_MODEL setting inside settings.py to accounts.CustomerUser model. In addition, you will have to update your schema manually as when you first run migrations, Django will use the default auth.User for multiple foreign keys etc. See the docs here for changing a user mid project.

django应用程序名称,但是安装了该应用程序

亽野灬性zι浪 2025-02-19 06:41:23

我创建了一个称为 termplot 的小包。

pip install termplot

import termplot
termplot.plot([1,2,3,4,-5,5,-4,-1,0,-10,-4,-2,3,5,8,10,12,10,8,7,6,5,4,3,2,1])

“

I created a small package called termplot that creates a vertical bar plot from a list.

pip install termplot

import termplot
termplot.plot([1,2,3,4,-5,5,-4,-1,0,-10,-4,-2,3,5,8,10,12,10,8,7,6,5,4,3,2,1])

picture

如何在终端中绘制图表

亽野灬性zι浪 2025-02-19 02:16:48

您可以做类似的事情:

$("label:contains('STATIC TEXT I CAN FIND')").closest('div').parent().next().find('ul').next().html()

$("div > div > div > ul > li:eq(1) > div > div").html();

You could do something like:

$("label:contains('STATIC TEXT I CAN FIND')").closest('div').parent().next().find('ul').next().html()

or

$("div > div > div > ul > li:eq(1) > div > div").html();

PAD jQuery-父母的兄弟姐妹的内部文字

亽野灬性zι浪 2025-02-18 21:37:08

按钮默认为 type =“ commitd” 内部表单中,如果您想要一个不触发提交的普通按钮,最简单的解决方案是明确设置prop type =“ button” 上。

此“闪烁错误”只是帖子后的页面重新加载

Buttons default to type="submit" inside forms, if you want a normal button that does not trigger the submit, the simplest solution is to explicitly set the prop type="button" on it.

This "flicker bug" is just the page reloading after the post

基于DOM元素单击的Next/路由器不同?

亽野灬性zι浪 2025-02-18 12:27:23

我认为您的实际代码可能存在几个问题。

首先,由于您使用表单登录的事实,请在定义过滤器链时尝试提供适当的配置,例如:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .cors().disable()
        .authorizeHttpRequests()
            .antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
            .anyRequest().authenticated()
            .and()
                .formLogin()
                    .loginPage("/login")
                     // Note the inclusion of the login processing url value
                    .loginProcessingUrl("/authenticate")
                     // One that you consider appropriate
                    .defaultSuccessUrl("/home")
                    .failureUrl("/login?error=true")
            .and().authenticationProvider(authProvider());
    return http.build();
}

如您所见,我们指出的是,您的控制器/都将处理登录页面登录映射:

@RequestMapping(value = "/login")
public String login(Model model) {
    return "login";
}

此外,我们指示/authenticate 是登录处理URL配置:这将激活您和Spring Security提供的所有身份验证内容,以验证用户的身份验证。

请注意,您还需要更改 login.html 页面,因为在当前实现中,用户名/密码表格也正在针对/login - 这可能是您在更新2中描述的问题的原因。在示例之后,该表单应针对/Authenticate

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <linl rel="stylesheet" th:href="@{/css/style.css}"></linl>
</head>
<body>
    <form method="post" th:action="@{/authenticate}">
        <input type="text" name="username" placeholder="Usuário">
        <input type="password" name="password" placeholder="Senha">
        <input type="submit" value="Entrar">
    </form>
    
    <script th:src="@{/js/script.js}"></script>
</body>
</html>

请注意,我们还包括一条路由,/home 在成功的身份验证后请求您的应用程序。 yu可以在 app 中定义类似:

@RequestMapping(value = "/home")
public String home(Model model) {
    return "home";
}

和简单的HTML测试页面, home.html

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
    Authenticated!!

    <script th:src="@{/js/script.js}"></script>
</body>
</html>

为了进行此工作,您应该在软件中更改一份其他部分。根据您定义代码的方式,当Spring Security尝试阅读您的 usuario GrantedAuthorities Hibernate将发布众所周知的未能懒惰地初始化角色集合。 。,因为在当前实施中,您正在阅读数据库中存储的凭据,但没有会话:

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<Autorizacao> lista = new ArrayList<Autorizacao>();
    for(Credencial credencial : credenciais) {
        lista.addAll(credencial.getAutorizacoes());
    }
    return lista;
}

您可以以不同的方式解决问题,尤其是考虑使用@transactional ,而是一个直截了当的解决方案可能是引起的。

首先,修改您的 usuario 对象,并包含一个瞬态属性,用于存储授予弹簧安全的凭据:

package org.kleber.app.model.usuario;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;

import org.kleber.app.model.credencial.Credencial;
import org.kleber.app.model.Model;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
public class Usuario extends Model implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column
    String username;

    @Column
    String password;

    @Column
    String firstName;

    @Column
    String lastName;

    @Column
    String email;

    @ManyToMany
    List<Credencial> credenciais;

    @Transient
    Collection<? extends GrantedAuthority> authorities = Collections.emptySet();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Credencial> getCredenciais() {
        return credenciais;
    }

    public void setCredenciais(List<Credencial> credenciais) {
        this.credenciais = credenciais;
    }

    public boolean isEnabled() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }
}

下一步,在 usuariodao 中包含一个自定义方法主动 session

package org.kleber.app.model.usuario;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import org.kleber.app.model.Dao;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.kleber.app.model.credencial.Credencial;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class UsuarioDao extends Dao<Usuario> {
    UsuarioDao() {
        super(Usuario.class);
    }

    public Usuario findByUsername(String username) {
        EntityManager entityManager = getEntityManager();
        entityManager.getTransaction().begin();
        Usuario usuario = (Usuario) entityManager.createQuery("SELECT a FROM Usuario a WHERE a.username = :value").setParameter("value", username).getSingleResult();
        // Retrieve the credentials here
        // On the contrary, you will face: failed to lazily initialize a collection of role...
        // Please consider using @Transactional instead
        List<Credencial> credenciais = usuario.getCredenciais();
        List<Autorizacao> autorizacaos = new ArrayList<Autorizacao>();
        for(Credencial credencial : credenciais) {
            autorizacaos.addAll(credencial.getAutorizacoes());
        }
        usuario.setAuthorities(autorizacaos);
        entityManager.getTransaction().commit();
        entityManager.close();
        return usuario;
    }
}

,如我提到的那样,请考虑使用@transactional 和Spring内置的交易分界机制,而不是以这种方式独自处理交易。

最后,在您的 userDetailsS​​ervice 实现中用户用户此新方法:

@Bean
public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) {
            System.out.println("loadUserByUsername: " + username);
            return usuarioDao.findByUsername(username);
        }
    };
}

而不是在 usuariodao 中创建此新方法,也许更好的是,可能性是创建 uservice > @service 包装此 usuario 凭据初始化过程:此服务将被您的 userDetailsS​​ervice 实现。

为了完整性,这就是 app 类的结局,

package org.kleber.app;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.context.annotation.Bean;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;

import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.security.MessageDigest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.ui.Model;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.kleber.app.model.usuario.UsuarioDao;
import org.kleber.app.model.credencial.CredencialDao;
import org.kleber.app.model.usuario.Usuario;
import org.kleber.app.model.credencial.Credencial;

@SpringBootApplication
@Controller
public class App extends SpringBootServletInitializer {
  @Autowired
  UsuarioDao usuarioDao;

  @Autowired
  CredencialDao credencialDao;

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(App.class);
  }

  @Bean
  public SpringSecurityDialect springSecurityDialect() {
    return new SpringSecurityDialect();
  }

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .cors().disable()
        .authorizeHttpRequests()
        .antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage("/login")
        .loginProcessingUrl("/authenticate")
        .defaultSuccessUrl("/home")
        .failureUrl("/login?error=true")
        .and().authenticationProvider(authProvider());
    return http.build();
  }

  @Bean
  public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setPasswordEncoder(passwordEncoder());
    provider.setUserDetailsService(userDetailsService());
    return provider;
  }

  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
      @Override
      public UserDetails loadUserByUsername(String username) {
        System.out.println("loadUserByUsername: " + username);
        return usuarioDao.findByUsername(username);
      }
    };
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new PasswordEncoder() {
      @Override
      public String encode(CharSequence rawPassword) {
        try {
          MessageDigest md = MessageDigest.getInstance("MD5");
          md.update(rawPassword.toString().getBytes());
          byte[] digest = md.digest();

          StringBuilder sb = new StringBuilder();
          for (int i = 0; i < digest.length; i++)
            sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
          return sb.toString();
        } catch (Exception e) {
          return null;
        }
      }

      @Override
      public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return encodedPassword.equals(encode(rawPassword));
      }
    };
  }

  @RequestMapping(value = "/")
  public String index(Model model) {
    return "index";
  }

  @RequestMapping(value = "/home")
  public String home(Model model) {
    return "home";
  }

  @RequestMapping(value = "/login")
  public String login(Model model) {
    return "login";
  }

  @RequestMapping(value = "/register", method = RequestMethod.GET)
  public String register(Model model) {
    model.addAttribute("obj", new Usuario());
    return "register";
  }

  @RequestMapping(value = "/register", method = RequestMethod.POST)
  public String register(@ModelAttribute Usuario usuario) {
    try {
      usuario.setPassword(passwordEncoder().encode(usuario.getPassword()));
      usuario.setCredenciais(new ArrayList<Credencial>());
      usuario.getCredenciais().add(credencialDao.findBy("nome", "USER").get(0));
      usuarioDao.insert(usuario);
      return "login";
    } catch (Exception e) {
      e.printStackTrace();
      return "register";
    }
  }
}

可能会以不同的方式进行改进,但是建议的设置应允许您成功访问应用程序:

I think there could be several issues with your actual code.

First, due to the fact you are using form login, please, try providing the appropriate configuration when defining your filter chain, for example:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .cors().disable()
        .authorizeHttpRequests()
            .antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
            .anyRequest().authenticated()
            .and()
                .formLogin()
                    .loginPage("/login")
                     // Note the inclusion of the login processing url value
                    .loginProcessingUrl("/authenticate")
                     // One that you consider appropriate
                    .defaultSuccessUrl("/home")
                    .failureUrl("/login?error=true")
            .and().authenticationProvider(authProvider());
    return http.build();
}

As you can see, we are indicating that the login page will be handled by your controller /login mapping:

@RequestMapping(value = "/login")
public String login(Model model) {
    return "login";
}

In addition, we indicated /authenticate as the login processing url configuration: this will activate all the authentication stuff provided by you and Spring Security to authenticate your users.

Note that you need to change your login.html page as well, because in your current implementation the username/password form is being submitted as well against /login - this is probably the cause of the problem you described in your update #2. Following the example, the form should be submitted against /authenticate:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <linl rel="stylesheet" th:href="@{/css/style.css}"></linl>
</head>
<body>
    <form method="post" th:action="@{/authenticate}">
        <input type="text" name="username" placeholder="Usuário">
        <input type="password" name="password" placeholder="Senha">
        <input type="submit" value="Entrar">
    </form>
    
    <script th:src="@{/js/script.js}"></script>
</body>
</html>

Note that we included as well a route, /home to request your app after a successful authentication. Yu can define in App something like:

@RequestMapping(value = "/home")
public String home(Model model) {
    return "home";
}

And a simple HTML test page, home.html:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" th:href="@{/css/style.css}">
</head>
<body>
    Authenticated!!

    <script th:src="@{/js/script.js}"></script>
</body>
</html>

In order to make this work you should change an additional piece in your software. According to the way you defined your code, when Spring Security tries reading your Usuario GrantedAuthorities Hibernate will issue the well known failed to lazily initialize a collection of role... because in your current implementation you are reading the credentials stored in your database but there is no session:

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<Autorizacao> lista = new ArrayList<Autorizacao>();
    for(Credencial credencial : credenciais) {
        lista.addAll(credencial.getAutorizacoes());
    }
    return lista;
}

You can probably solve the issue in different ways, especially consider using @Transactional, but one straight forward solution could be the folllowing.

First, modify your Usuario object and include a transient property for storing the Spring Security granted credentials:

package org.kleber.app.model.usuario;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Transient;

import org.kleber.app.model.credencial.Credencial;
import org.kleber.app.model.Model;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
public class Usuario extends Model implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column
    String username;

    @Column
    String password;

    @Column
    String firstName;

    @Column
    String lastName;

    @Column
    String email;

    @ManyToMany
    List<Credencial> credenciais;

    @Transient
    Collection<? extends GrantedAuthority> authorities = Collections.emptySet();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Credencial> getCredenciais() {
        return credenciais;
    }

    public void setCredenciais(List<Credencial> credenciais) {
        this.credenciais = credenciais;
    }

    public boolean isEnabled() {
        return true;
    }

    public boolean isCredentialsNonExpired() {
        return true;
    }

    public boolean isAccountNonExpired() {
        return true;
    }

    public boolean isAccountNonLocked() {
        return true;
    }

    public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }
}

Next, include a custom method in UsuarioDao in order to obtain the credentials when you have an active Session:

package org.kleber.app.model.usuario;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import org.kleber.app.model.Dao;
import org.kleber.app.model.autorizacao.Autorizacao;
import org.kleber.app.model.credencial.Credencial;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class UsuarioDao extends Dao<Usuario> {
    UsuarioDao() {
        super(Usuario.class);
    }

    public Usuario findByUsername(String username) {
        EntityManager entityManager = getEntityManager();
        entityManager.getTransaction().begin();
        Usuario usuario = (Usuario) entityManager.createQuery("SELECT a FROM Usuario a WHERE a.username = :value").setParameter("value", username).getSingleResult();
        // Retrieve the credentials here
        // On the contrary, you will face: failed to lazily initialize a collection of role...
        // Please consider using @Transactional instead
        List<Credencial> credenciais = usuario.getCredenciais();
        List<Autorizacao> autorizacaos = new ArrayList<Autorizacao>();
        for(Credencial credencial : credenciais) {
            autorizacaos.addAll(credencial.getAutorizacoes());
        }
        usuario.setAuthorities(autorizacaos);
        entityManager.getTransaction().commit();
        entityManager.close();
        return usuario;
    }
}

Please, as I mentioned, consider use @Transactional and Spring built-in transaction demarcation mechanisms instead of handling your transactions on your own in this way.

Finally, user this new method in your UserDetailsService implementation:

@Bean
public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
        @Override
        public UserDetails loadUserByUsername(String username) {
            System.out.println("loadUserByUsername: " + username);
            return usuarioDao.findByUsername(username);
        }
    };
}

Instead of creating this new method in UsuarioDao another, perhaps better, possibility would be creating a UserService @Service that wrap this Usuario and Credentials initialization process: this service would be then the one used by your UserDetailsService implementation.

For completeness, this is how the App class would end looking like:

package org.kleber.app;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

import org.springframework.context.annotation.Bean;
import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect;

import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.security.MessageDigest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.ui.Model;

import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.kleber.app.model.usuario.UsuarioDao;
import org.kleber.app.model.credencial.CredencialDao;
import org.kleber.app.model.usuario.Usuario;
import org.kleber.app.model.credencial.Credencial;

@SpringBootApplication
@Controller
public class App extends SpringBootServletInitializer {
  @Autowired
  UsuarioDao usuarioDao;

  @Autowired
  CredencialDao credencialDao;

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(App.class);
  }

  @Bean
  public SpringSecurityDialect springSecurityDialect() {
    return new SpringSecurityDialect();
  }

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .cors().disable()
        .authorizeHttpRequests()
        .antMatchers("/", "/login", "/logout", "/register", "/error", "/css/**", "/js/**", "/img/**").permitAll()
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage("/login")
        .loginProcessingUrl("/authenticate")
        .defaultSuccessUrl("/home")
        .failureUrl("/login?error=true")
        .and().authenticationProvider(authProvider());
    return http.build();
  }

  @Bean
  public DaoAuthenticationProvider authProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setPasswordEncoder(passwordEncoder());
    provider.setUserDetailsService(userDetailsService());
    return provider;
  }

  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailsService() {
      @Override
      public UserDetails loadUserByUsername(String username) {
        System.out.println("loadUserByUsername: " + username);
        return usuarioDao.findByUsername(username);
      }
    };
  }

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new PasswordEncoder() {
      @Override
      public String encode(CharSequence rawPassword) {
        try {
          MessageDigest md = MessageDigest.getInstance("MD5");
          md.update(rawPassword.toString().getBytes());
          byte[] digest = md.digest();

          StringBuilder sb = new StringBuilder();
          for (int i = 0; i < digest.length; i++)
            sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1));
          return sb.toString();
        } catch (Exception e) {
          return null;
        }
      }

      @Override
      public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return encodedPassword.equals(encode(rawPassword));
      }
    };
  }

  @RequestMapping(value = "/")
  public String index(Model model) {
    return "index";
  }

  @RequestMapping(value = "/home")
  public String home(Model model) {
    return "home";
  }

  @RequestMapping(value = "/login")
  public String login(Model model) {
    return "login";
  }

  @RequestMapping(value = "/register", method = RequestMethod.GET)
  public String register(Model model) {
    model.addAttribute("obj", new Usuario());
    return "register";
  }

  @RequestMapping(value = "/register", method = RequestMethod.POST)
  public String register(@ModelAttribute Usuario usuario) {
    try {
      usuario.setPassword(passwordEncoder().encode(usuario.getPassword()));
      usuario.setCredenciais(new ArrayList<Credencial>());
      usuario.getCredenciais().add(credencialDao.findBy("nome", "USER").get(0));
      usuarioDao.insert(usuario);
      return "login";
    } catch (Exception e) {
      e.printStackTrace();
      return "register";
    }
  }
}

Probably it could be improved in different ways, but the suggested setup should allow you to successfully access your app:

welcome page

如何覆盖Spring-boot Project的默认userDetailsservice和passwordencoder

亽野灬性zι浪 2025-02-18 10:09:43

Spring具有 @scheduled 注释。有几种配置它的方法,一种方法是像Unix Cron作业一样配置它。

例如:

@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
 
    long now = System.currentTimeMillis() / 1000;
    System.out.println(
      "schedule tasks using cron jobs - " + now);
}

此处的任务计划在每个月的15天在上午10:15执行。

但是,也有一种方法可以在运行时动态配置延迟或速率,例如这样(取自baeldung.com):

@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {

    @Autowired
    private TickService tickService;

    @Bean
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
          new Runnable() {
              @Override
              public void run() {
                  tickService.tick();
              }
          },
          new Trigger() {
              @Override
              public Date nextExecutionTime(TriggerContext context) {
                  Optional<Date> lastCompletionTime =
                    Optional.ofNullable(context.lastCompletionTime());
                  Instant nextExecutionTime =
                    lastCompletionTime.orElseGet(Date::new).toInstant()
                      .plusMillis(tickService.getDelay());
                  return Date.from(nextExecutionTime);
              }
          }
        );
    }

}

即时NextExecution Time = ... 可以用自己的逻辑代替设置下一个执行时间,就像从数组中解析时间一样。

看一下有关它的贝尔登教程: https://wwww.baeldung-com/spring-spring-scheduled -tasks

也请在这里查看cron符号: https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html

Spring has the @Scheduled annotation. There a several ways to configure it, one way is to configure it like unix cron job.

For example like this:

@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
 
    long now = System.currentTimeMillis() / 1000;
    System.out.println(
      "schedule tasks using cron jobs - " + now);
}

The task here is scheduled to be executed at 10:15 AM on the 15th day of every month.

But there a also ways to configure the delay or rate dynamically at Runtime, for example like this (taken from baeldung.com):

@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {

    @Autowired
    private TickService tickService;

    @Bean
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
          new Runnable() {
              @Override
              public void run() {
                  tickService.tick();
              }
          },
          new Trigger() {
              @Override
              public Date nextExecutionTime(TriggerContext context) {
                  Optional<Date> lastCompletionTime =
                    Optional.ofNullable(context.lastCompletionTime());
                  Instant nextExecutionTime =
                    lastCompletionTime.orElseGet(Date::new).toInstant()
                      .plusMillis(tickService.getDelay());
                  return Date.from(nextExecutionTime);
              }
          }
        );
    }

}

The line Instant nextExecutionTime = ... could be replaced with your own logic for setting the next execution time, like parsing the times from your array.

Take look at this baeldung tutorial about it: https://www.baeldung.com/spring-scheduled-tasks

Also take look here for the cron notation: https://www.netiq.com/documentation/cloud-manager-2-5/ncm-reference/data/bexyssf.html

如何在某些时间窗口中运行方法

亽野灬性zι浪 2025-02-18 07:18:37

注意:这个答案已经过时了。它适用于Python 2使用 new 模块,该模块在2008年进行了弃用

有python内置功能setattr和getAttr。可以用来设置和获取类的属性。

一个简短的例子:

>>> from new import  classobj

>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class

>>> setattr(obj, 'attr1', 10)

>>> setattr(obj, 'attr2', 20)

>>> getattr(obj, 'attr1')
10

>>> getattr(obj, 'attr2')
20

Note: This answer is very outdated. It applies to Python 2 using the new module that was deprecated in 2008.

There is python built in functions setattr and getattr. Which can used to set and get the attribute of an class.

A brief example:

>>> from new import  classobj

>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class

>>> setattr(obj, 'attr1', 10)

>>> setattr(obj, 'attr2', 20)

>>> getattr(obj, 'attr1')
10

>>> getattr(obj, 'attr2')
20

如何访问(获取或设置)对象属性给定的字符串与该属性的名称相对应

亽野灬性zι浪 2025-02-18 04:37:04

我看不到您正在初始化目录,如此 post

const bucket = gcs.bucket(object.bucket);
const filePath = object.name;
const fileName = filePath.split('/').pop();
const thumbFileName = 'thumb_' + fileName;

const workingDir = join(tmpdir(), `${object.name.split('/')[0]}/`);//new
const tmpFilePath = join(workingDir, fileName);
const tmpThumbPath = join(workingDir, thumbFileName);

await fs.ensureDir(workingDir);

另外,请考虑,如果您使用两个函数,则不会共享/tmp 目录,因为每个功能都有自己的。这是 Dogn> DOUG Stevenson 。在相同的答案中,有一个很好的解释视频,有关本地和全球范围以及如何使用TMP目录:

云功能仅允许一个功能一次在特定服务器实例中运行。在具有不同 /TMP空间的不同服务器实例上并行运行的功能。每个函数调用彼此完全隔离。您应该始终清理您在 /tmp中编写的文件,以免它们积累并导致服务器实例随着时间的推移而用完。< /p>

我建议使用 Google Cloud Storage扩展了云功能以实现您目标。

I was not able to see you are initializing the directory as suggested in this post:

const bucket = gcs.bucket(object.bucket);
const filePath = object.name;
const fileName = filePath.split('/').pop();
const thumbFileName = 'thumb_' + fileName;

const workingDir = join(tmpdir(), `${object.name.split('/')[0]}/`);//new
const tmpFilePath = join(workingDir, fileName);
const tmpThumbPath = join(workingDir, thumbFileName);

await fs.ensureDir(workingDir);

Also, please consider that if you are using two functions, the /tmp directory would not be shared as each one has its own. Here is an explanation from Doug Stevenson. In the same answer, there is a very well explained video about local and global scopes and how to use the tmp directory:

Cloud Functions only allows one function to run at a time in a particular server instance. Functions running in parallel run on different server instances, which have different /tmp spaces. Each function invocation runs in complete isolation from each other. You should always clean up files you write in /tmp so that they don't accumulate and cause a server instance to run out of memory over time.

I would suggest using Google Cloud Storage extended with Cloud Functions to achieve your goal.

在firebase函数中以 /tmp编写文件不起作用

亽野灬性zι浪 2025-02-18 03:54:18

如此其他答案

  • set merge 将始终用您通过的数据覆盖数据,而
  • Update 是专门设计的,可以使您有可能执行文档的部分更新,而无需创建您的代码不准备处理的不完整文档。请检查 this 答案,以及 this scenario。

这就是 nick-wnick 在他的评论

这是另一个答案更好地解释了每个选项的用例:

  • set 没有 MERGE 将覆盖文档或创建它,如果它不存在
  • set 带有 MERGE 将在文档中更新字段,或者如果不存在,则创建它
  • 更新将更新字段,但是如果文档不存在,将失败
  • 创建将创建文档,但是如果文档已经存在
  • ,则会失败


,您应该使用 ,如下:

您可以按照以下示例显示的数字字段值递增或降低数字字段值。增量操作增加或降低了字段的当前值。

  //原子上将城市人口增加50。  
washingtonref.update({ 
   人口:firebase.firestore.fieldvalue.Increment(50)  
});
 

另请参见:

As shown on this other answer:

  • set merge will always override the data with the data you pass, while
  • update is specifically designed to give you the possibility to perform a partial update of a document without the possibility of creating incomplete documents that your code isn't otherwise prepared to handle. Please check this answer, as well as this scenario.

This is what nick-w-nick explains in his comment.

This another answer explains better the use case for each option:

  • set without merge will overwrite a document or create it if it doesn't exist yet
  • set with merge will update fields in the document or create it if it doesn't exists
  • update will update fields but will fail if the document doesn't exist
  • create will create the document but fail if the document already exists

For the expected result you explained in your comment, you should be using an increment operation, as follows:

You can increment or decrement a numeric field value as shown in the following example. An increment operation increases or decreases the current value of a field by the given amount.

// Atomically increment the population of the city by 50.  
washingtonRef.update({ 
   population: firebase.firestore.FieldValue.increment(50)  
});

See also:

Cloud Firestore合并true不工作在nodejs中

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文